mirror of
https://github.com/boltgolt/howdy.git
synced 2024-09-19 09:51:19 +02:00
refactor: improve structure
This commit is contained in:
parent
8b6b257668
commit
b53d48e43d
1 changed files with 68 additions and 59 deletions
125
src/pam/main.cc
125
src/pam/main.cc
|
@ -42,12 +42,6 @@
|
||||||
#include "main.hh"
|
#include "main.hh"
|
||||||
#include "optional_task.hh"
|
#include "optional_task.hh"
|
||||||
|
|
||||||
// Should be defined by the build system
|
|
||||||
#ifndef GETTEXT_PACKAGE
|
|
||||||
#define GETTEXT_PACKAGE "pam_howdy"
|
|
||||||
#define LOCALEDIR "/usr/local/share/locales"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const auto DEFAULT_TIMEOUT =
|
const auto DEFAULT_TIMEOUT =
|
||||||
std::chrono::duration<int, std::chrono::milliseconds::period>(100);
|
std::chrono::duration<int, std::chrono::milliseconds::period>(100);
|
||||||
const auto MAX_RETRIES = 5;
|
const auto MAX_RETRIES = 5;
|
||||||
|
@ -138,59 +132,13 @@ auto howdy_status(char *username, int status, const INIReader &reader,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main function, runs the identification and authentication
|
* Check if Howdy should be enabled according to the configuration and the
|
||||||
* @param pamh The handle to interface directly with PAM
|
* environment.
|
||||||
* @param flags Flags passed on to us by PAM, XORed
|
* @param reader INI configuration
|
||||||
* @param argc Amount of rules in the PAM config (disregared)
|
* @return Returns PAM_AUTHINFO_UNAVAIL if it shouldn't be enabled,
|
||||||
* @param argv Options defined in the PAM config
|
* PAM_SUCCESS otherwise
|
||||||
* @param auth_tok True if we should ask for a password too
|
|
||||||
* @return Returns a PAM return code
|
|
||||||
*/
|
*/
|
||||||
auto identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
auto check_enabled(const INIReader &reader) -> int {
|
||||||
bool auth_tok) -> int {
|
|
||||||
INIReader reader("/lib/security/howdy/config.ini");
|
|
||||||
// Open the system log so we can write to it
|
|
||||||
openlog("pam_howdy", 0, LOG_AUTHPRIV);
|
|
||||||
|
|
||||||
Workaround workaround =
|
|
||||||
get_workaround(reader.GetString("core", "workaround", "input"));
|
|
||||||
|
|
||||||
// We ask for the password if the function requires it and if a workaround is
|
|
||||||
// set
|
|
||||||
auth_tok = auth_tok && workaround != Workaround::Off;
|
|
||||||
|
|
||||||
// Will contain the responses from PAM functions
|
|
||||||
int pam_res = PAM_IGNORE;
|
|
||||||
|
|
||||||
// Will contain PAM conversation structure
|
|
||||||
struct pam_conv *conv = nullptr;
|
|
||||||
const void **conv_ptr =
|
|
||||||
const_cast<const void **>(reinterpret_cast<void **>(&conv));
|
|
||||||
|
|
||||||
// Try to get the conversation function and error out if we can't
|
|
||||||
if ((pam_res = pam_get_item(pamh, PAM_CONV, conv_ptr)) != PAM_SUCCESS) {
|
|
||||||
syslog(LOG_ERR, "Failed to acquire conversation");
|
|
||||||
return pam_res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap the PAM conversation function in our own, easier function
|
|
||||||
auto conv_function = [conv](int msg_type, const char *msg_str) {
|
|
||||||
const struct pam_message msg = {.msg_style = msg_type, .msg = msg_str};
|
|
||||||
const struct pam_message *msgp = &msg;
|
|
||||||
|
|
||||||
struct pam_response res = {};
|
|
||||||
struct pam_response *resp = &res;
|
|
||||||
|
|
||||||
return conv->conv(1, &msgp, &resp, conv->appdata_ptr);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Error out if we could not read the config file
|
|
||||||
if (reader.ParseError() != 0) {
|
|
||||||
syslog(LOG_ERR, "Failed to parse the configuration file: %d",
|
|
||||||
reader.ParseError());
|
|
||||||
return PAM_SYSTEM_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop executing if Howdy has been disabled in the config
|
// Stop executing if Howdy has been disabled in the config
|
||||||
if (reader.GetBoolean("core", "disabled", false)) {
|
if (reader.GetBoolean("core", "disabled", false)) {
|
||||||
syslog(LOG_INFO, "Skipped authentication, Howdy is disabled");
|
syslog(LOG_INFO, "Skipped authentication, Howdy is disabled");
|
||||||
|
@ -236,6 +184,66 @@ auto identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
||||||
globfree(&glob_result);
|
globfree(&glob_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main function, runs the identification and authentication
|
||||||
|
* @param pamh The handle to interface directly with PAM
|
||||||
|
* @param flags Flags passed on to us by PAM, XORed
|
||||||
|
* @param argc Amount of rules in the PAM config (disregared)
|
||||||
|
* @param argv Options defined in the PAM config
|
||||||
|
* @param auth_tok True if we should ask for a password too
|
||||||
|
* @return Returns a PAM return code
|
||||||
|
*/
|
||||||
|
auto identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
||||||
|
bool auth_tok) -> int {
|
||||||
|
INIReader reader("/lib/security/howdy/config.ini");
|
||||||
|
openlog("pam_howdy", 0, LOG_AUTHPRIV);
|
||||||
|
|
||||||
|
// Error out if we could not read the config file
|
||||||
|
if (reader.ParseError() != 0) {
|
||||||
|
syslog(LOG_ERR, "Failed to parse the configuration file: %d",
|
||||||
|
reader.ParseError());
|
||||||
|
return PAM_SYSTEM_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will contain the responses from PAM functions
|
||||||
|
int pam_res = PAM_IGNORE;
|
||||||
|
|
||||||
|
// Check if we shoud continue
|
||||||
|
if ((pam_res = check_enabled(reader)) != PAM_SUCCESS) {
|
||||||
|
return pam_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Workaround workaround =
|
||||||
|
get_workaround(reader.GetString("core", "workaround", "input"));
|
||||||
|
|
||||||
|
// We ask for the password if the function requires it and if a workaround is
|
||||||
|
// set
|
||||||
|
auth_tok = auth_tok && workaround != Workaround::Off;
|
||||||
|
|
||||||
|
// Will contain PAM conversation structure
|
||||||
|
struct pam_conv *conv = nullptr;
|
||||||
|
const void **conv_ptr =
|
||||||
|
const_cast<const void **>(reinterpret_cast<void **>(&conv));
|
||||||
|
|
||||||
|
if ((pam_res = pam_get_item(pamh, PAM_CONV, conv_ptr)) != PAM_SUCCESS) {
|
||||||
|
syslog(LOG_ERR, "Failed to acquire conversation");
|
||||||
|
return pam_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the PAM conversation function in our own, easier function
|
||||||
|
auto conv_function = [conv](int msg_type, const char *msg_str) {
|
||||||
|
const struct pam_message msg = {.msg_style = msg_type, .msg = msg_str};
|
||||||
|
const struct pam_message *msgp = &msg;
|
||||||
|
|
||||||
|
struct pam_response res = {};
|
||||||
|
struct pam_response *resp = &res;
|
||||||
|
|
||||||
|
return conv->conv(1, &msgp, &resp, conv->appdata_ptr);
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize gettext
|
// Initialize gettext
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
||||||
|
@ -381,6 +389,7 @@ auto identify(pam_handle_t *pamh, int flags, int argc, const char **argv,
|
||||||
// input wasn't focused or if the uinput device failed to send keypress)
|
// input wasn't focused or if the uinput device failed to send keypress)
|
||||||
pass_task.stop(false);
|
pass_task.stop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = child_task.get();
|
int status = child_task.get();
|
||||||
|
|
||||||
return howdy_status(username, status, reader, conv_function);
|
return howdy_status(username, status, reader, conv_function);
|
||||||
|
|
Loading…
Reference in a new issue