Remove uinput

Signed-off-by: MusiKid <musikid@outlook.com>
This commit is contained in:
MusiKid 2021-01-18 14:46:59 +01:00 committed by musikid
parent beee0590ed
commit 50d52ec423
No known key found for this signature in database
GPG key ID: 7567D43648C6E2F4
3 changed files with 116 additions and 69 deletions

View file

@ -25,7 +25,6 @@ import _thread as thread
from i18n import _ from i18n import _
from recorders.video_capture import VideoCapture from recorders.video_capture import VideoCapture
from evdev import UInput, ecodes as e
def exit(code=None): def exit(code=None):
"""Exit while closeing howdy-gtk properly""" """Exit while closeing howdy-gtk properly"""
@ -374,21 +373,6 @@ while True:
"clahe": clahe "clahe": clahe
}) })
# Press enter key
if config.getboolean("experimental", "confirm"):
pipe_fd = int(os.getenv("PIPE_FD"))
pipe = os.fdopen(pipe_fd, 'w')
pipe.write('\255')
enter_cap = {
e.EV_KEY: [e.KEY_ENTER]
}
device = UInput(enter_cap)
device.write(e.EV_KEY, e.KEY_ENTER, 1)
device.syn()
device.write(e.EV_KEY, e.KEY_ENTER, 0)
device.syn()
# End peacefully # End peacefully
exit(0) exit(0)

View file

@ -5,5 +5,5 @@
```sh ```sh
meson setup build -Dinih:with_INIReader=true meson setup build -Dinih:with_INIReader=true
meson compile build meson compile build
sudo mv build/libpam_howdy.so /lib/security/ sudo mv build/libpam_howdy.so /lib/security/pam_howdy.so
``` ```

View file

@ -3,6 +3,7 @@
#include <cstdlib> #include <cstdlib>
#include <glob.h> #include <glob.h>
#include <poll.h> #include <poll.h>
#include <pthread.h>
#include <spawn.h> #include <spawn.h>
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/signalfd.h> #include <sys/signalfd.h>
@ -21,6 +22,7 @@
#include <iostream> #include <iostream>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <mutex>
#include <string> #include <string>
#include <system_error> #include <system_error>
#include <thread> #include <thread>
@ -35,28 +37,31 @@
using namespace std; using namespace std;
enum class Type { Howdy, Pam };
int on_howdy_auth(int code, function<int(int, const char *)> conv_function) { int on_howdy_auth(int code, function<int(int, const char *)> conv_function) {
if (WIFEXITED(code)) {
switch (code) { code = WEXITSTATUS(code);
case 10: switch (code) {
conv_function(PAM_ERROR_MSG, "There is no face model known"); case 10:
syslog(LOG_NOTICE, "Failure, no face model known"); conv_function(PAM_ERROR_MSG, "There is no face model known");
break; syslog(LOG_NOTICE, "Failure, no face model known");
case 11: break;
syslog(LOG_INFO, "Failure, timeout reached"); case 11:
break; syslog(LOG_INFO, "Failure, timeout reached");
case 12: break;
syslog(LOG_INFO, "Failure, general abort"); case 12:
break; syslog(LOG_INFO, "Failure, general abort");
case 13: break;
syslog(LOG_INFO, "Failure, image too dark"); case 13:
break; syslog(LOG_INFO, "Failure, image too dark");
default: break;
conv_function(PAM_ERROR_MSG, default:
string("Unknown error:" + to_string(code)).c_str()); conv_function(PAM_ERROR_MSG,
syslog(LOG_INFO, "Failure, unknown error %d", code); string("Unknown error:" + to_string(code)).c_str());
syslog(LOG_INFO, "Failure, unknown error %d", code);
}
} }
return PAM_AUTH_ERR; return PAM_AUTH_ERR;
} }
@ -74,10 +79,10 @@ int send_message(function<int(int, const struct pam_message **,
return conv(1, &msgp, &resp_, nullptr); return conv(1, &msgp, &resp_, nullptr);
} }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, int identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
const char **argv) { bool auth_tok) {
INIReader reader("/lib/security/howdy/config.ini"); INIReader reader("/lib/security/howdy/config.ini");
openlog("[PAM_HOWDY]", 0, LOG_AUTHPRIV); openlog("pam_howdy.so", 0, LOG_AUTHPRIV);
struct pam_conv *conv = nullptr; struct pam_conv *conv = nullptr;
int pam_res = PAM_IGNORE; int pam_res = PAM_IGNORE;
@ -89,7 +94,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
} }
auto conv_function = auto conv_function =
bind(send_message, (*conv->conv), placeholders::_1, placeholders::_2); bind(send_message, conv->conv, placeholders::_1, placeholders::_2);
if (reader.ParseError() < 0) { if (reader.ParseError() < 0) {
syslog(LOG_ERR, "Failed to parse the configuration"); syslog(LOG_ERR, "Failed to parse the configuration");
@ -146,57 +151,115 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
syslog(LOG_ERR, "Failed to get username"); syslog(LOG_ERR, "Failed to get username");
return pam_res; return pam_res;
} }
string user(user_ptr);
posix_spawn_file_actions_t file_actions; posix_spawn_file_actions_t file_actions;
posix_spawn_file_actions_init(&file_actions); posix_spawn_file_actions_init(&file_actions);
posix_spawn_file_actions_addclose(&file_actions, STDOUT_FILENO); posix_spawn_file_actions_addclose(&file_actions, STDOUT_FILENO);
posix_spawn_file_actions_addclose(&file_actions, STDERR_FILENO); posix_spawn_file_actions_addclose(&file_actions, STDERR_FILENO);
vector<const char *> args{"python", "/lib/security/howdy/compare.py", const char *const args[] = {"python", "/lib/security/howdy/compare.py",
user.c_str(), nullptr}; user_ptr, nullptr};
pid_t child_pid; pid_t child_pid;
if (posix_spawnp(&child_pid, "python", &file_actions, nullptr, if (posix_spawnp(&child_pid, "python", &file_actions, nullptr,
(char *const *)args.data(), nullptr) < 0) { (char *const *)args, nullptr) < 0) {
syslog(LOG_ERR, "Can't spawn the howdy process: %s", strerror(errno)); syslog(LOG_ERR, "Can't spawn the howdy process: %s", strerror(errno));
return PAM_SYSTEM_ERR; return PAM_SYSTEM_ERR;
} }
std::mutex m;
std::condition_variable cv;
Type t;
packaged_task<int()> child_task([&] { packaged_task<int()> child_task([&] {
int status; int status;
wait(&status); wait(&status);
{
unique_lock<mutex> lk(m);
t = Type::Howdy;
}
cv.notify_all();
return status; return status;
}); });
auto child_future = child_task.get_future(); auto child_future = child_task.get_future();
thread child_thread(move(child_task)); thread child_thread(move(child_task));
auto pass_future = async(launch::async, [&] { packaged_task<int()> pass_task([&] {
char *auth_tok_ptr = nullptr; char *auth_tok_ptr = nullptr;
int pam_res = pam_get_authtok(pamh, PAM_AUTHTOK, int pam_res = pam_get_authtok(pamh, PAM_AUTHTOK,
(const char **)&auth_tok_ptr, nullptr); (const char **)&auth_tok_ptr, nullptr);
return make_pair(auth_tok_ptr, pam_res); {
}); unique_lock<mutex> lk(m);
t = Type::Pam;
auto pass = pass_future.get();
if (child_future.wait_for(1.5s) == future_status::timeout) {
kill(child_pid, SIGTERM);
}
child_thread.join();
int howdy_status = child_future.get();
if (howdy_status == 0) {
if (!reader.GetBoolean("section", "no_confirmation", true)) {
string identify_msg("Identified face as " + user);
conv_function(PAM_TEXT_INFO, identify_msg.c_str());
} }
cv.notify_all();
return pam_res;
});
auto pass_future = pass_task.get_future();
thread pass_thread;
if (auth_tok) {
pass_thread = thread(move(pass_task));
}
syslog(LOG_INFO, "Login approved"); {
return PAM_SUCCESS; unique_lock<mutex> lk(m);
} else if ((get<int>(pass) == PAM_SUCCESS && get<char *>(pass) != nullptr && cv.wait(lk);
!string(get<char *>(pass)).empty()) || }
WIFSIGNALED(howdy_status)) {
return PAM_IGNORE; if (t == Type::Howdy) {
if (auth_tok) {
auto native_hd = pass_thread.native_handle();
pthread_cancel(native_hd);
pass_thread.join();
}
child_thread.join();
int howdy_status = child_future.get();
if (howdy_status == 0) {
if (!reader.GetBoolean("section", "no_confirmation", true)) {
string identify_msg("Identified face as " + string(user_ptr));
conv_function(PAM_TEXT_INFO, identify_msg.c_str());
}
syslog(LOG_INFO, "Login approved");
return PAM_SUCCESS;
} else {
return on_howdy_auth(howdy_status, conv_function);
}
} else { } else {
return on_howdy_auth(howdy_status, conv_function); kill(child_pid, SIGTERM);
child_thread.join();
pass_thread.join();
auto pam_res = pass_future.get();
if (pam_res != PAM_SUCCESS)
return pam_res;
return PAM_IGNORE;
} }
} }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
const char **argv) {
return identify(pamh, flags, argc, argv, true);
}
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
const char **argv) {
return identify(pamh, flags, argc, argv, false);
}
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc,
const char **argv) {
return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
const char **argv) {
return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc,
const char **argv) {
return PAM_IGNORE;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
const char **argv) {
return PAM_IGNORE;
}