From 906a8f749b4c7a4ea17b4e0b3810683383565afc Mon Sep 17 00:00:00 2001 From: Sayafdine Said Date: Wed, 10 Apr 2024 10:00:13 +0200 Subject: [PATCH] fix(pam): use environ variable when getenv doesn't work On some programs like sudo, getenv doesn't return the environment variable value. --- README.md | 2 +- howdy/src/pam/main.cc | 16 ++++------------ howdy/src/pam/main.hh | 27 +++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 48de5d49..8410bfc0 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ To install them on Debian/Ubuntu for example: sudo apt-get update && sudo apt-get install -y \ python3 python3-pip python3-setuptools python3-wheel \ cmake make build-essential \ -libpam0g-dev libinih-dev libevdev-dev \ +libpam0g-dev libinih-dev libevdev-dev python3-opencv \ python3-dev libopencv-dev ``` diff --git a/howdy/src/pam/main.cc b/howdy/src/pam/main.cc index d1b8e347..20a972c3 100644 --- a/howdy/src/pam/main.cc +++ b/howdy/src/pam/main.cc @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -16,22 +15,15 @@ #include #include -#include #include #include #include #include #include #include -#include -#include -#include #include #include -#include -#include #include -#include #include @@ -42,7 +34,7 @@ #include "enter_device.hh" #include "main.hh" #include "optional_task.hh" -#include "paths.hh" +#include const auto DEFAULT_TIMEOUT = std::chrono::duration(100); @@ -139,7 +131,7 @@ auto howdy_status(char *username, int status, const INIReader &config, * @return Returns PAM_AUTHINFO_UNAVAIL if it shouldn't be enabled, * PAM_SUCCESS otherwise */ -auto check_enabled(const INIReader &config, const char* username) -> int { +auto check_enabled(const INIReader &config, const char *username) -> int { // Stop executing if Howdy has been disabled in the config if (config.GetBoolean("core", "disabled", false)) { syslog(LOG_INFO, "Skipped authentication, Howdy is disabled"); @@ -148,8 +140,8 @@ auto check_enabled(const INIReader &config, const char* username) -> int { // Stop if we're in a remote shell and configured to exit if (config.GetBoolean("core", "abort_if_ssh", true)) { - if (getenv("SSH_CONNECTION") != nullptr || - getenv("SSH_CLIENT") != nullptr || getenv("SSHD_OPTS") != nullptr) { + if (checkenv("SSH_CONNECTION") || checkenv("SSH_CLIENT") || + checkenv("SSH_TTY") || checkenv("SSHD_OPTS")) { syslog(LOG_INFO, "Skipped authentication, SSH session detected"); return PAM_AUTHINFO_UNAVAIL; } diff --git a/howdy/src/pam/main.hh b/howdy/src/pam/main.hh index 30716bbb..dc112e2e 100644 --- a/howdy/src/pam/main.hh +++ b/howdy/src/pam/main.hh @@ -1,7 +1,9 @@ #ifndef MAIN_H_ #define MAIN_H_ +#include #include +#include enum class ConfirmationType { Unset, Howdy, Pam }; @@ -29,4 +31,29 @@ inline auto get_workaround(const std::string &workaround) -> Workaround { return Workaround::Off; } +/** + * Check if an environment variable exists either in the environ array or using + * getenv. + * @param name The name of the environment variable. + * @return The value of the environment variable or nullptr if it doesn't exist + * or environ is nullptr. + * @note This function was created because `getenv` wasn't working properly in + * some contexts (like sudo). + */ +auto checkenv(const char *name) -> bool { + if (std::getenv(name) != nullptr) { + return true; + } + + auto len = strlen(name); + + for (char **env = environ; *env != nullptr; env++) { + if (strncmp(*env, name, len) == 0) { + return true; + } + } + + return false; +} + #endif // MAIN_H_