Remove uinput
Signed-off-by: MusiKid <musikid@outlook.com>
This commit is contained in:
parent
beee0590ed
commit
50d52ec423
3 changed files with 116 additions and 69 deletions
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
```
|
```
|
||||||
|
|
|
||||||
167
src/pam/main.cc
167
src/pam/main.cc
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue