From a2dfbaef2e7cbfe8d62daecc90bc0df575423d8f Mon Sep 17 00:00:00 2001 From: edward-p Date: Mon, 7 Feb 2022 02:46:22 +0800 Subject: [PATCH 1/6] add argument: default_ssh_auth_sock --- authfd.c | 10 +++++++++- pam_ssh_agent_auth.c | 4 ++++ pam_ssh_agent_auth.pod | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/authfd.c b/authfd.c index 01d1d89..a05e25b 100644 --- a/authfd.c +++ b/authfd.c @@ -71,6 +71,8 @@ #include "atomicio.h" #include "misc.h" +extern char *default_ssh_auth_sock; + static int agent_present = 0; /* helper */ @@ -110,6 +112,7 @@ ssh_get_authentication_socket(uid_t uid) struct stat sock_st; authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + authsocket = authsocket ? authsocket : default_ssh_auth_sock; if (!authsocket) return -1; @@ -220,7 +223,12 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply void ssh_close_authentication_socket(int sock) { - if (getenv(SSH_AUTHSOCKET_ENV_NAME)) + const char *authsocket; + + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + authsocket = authsocket ? authsocket : default_ssh_auth_sock; + + if (authsocket) close(sock); } diff --git a/pam_ssh_agent_auth.c b/pam_ssh_agent_auth.c index 1af81f5..a5c536f 100644 --- a/pam_ssh_agent_auth.c +++ b/pam_ssh_agent_auth.c @@ -66,6 +66,7 @@ char *authorized_keys_file = NULL; uint8_t allow_user_owned_authorized_keys_file = 0; char *authorized_keys_command = NULL; char *authorized_keys_command_user = NULL; +char *default_ssh_auth_sock = NULL; #if ! HAVE___PROGNAME || HAVE_BUNDLE char *__progname; @@ -125,6 +126,9 @@ pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) if(strncasecmp_literal(*argv_ptr, "authorized_keys_command_user=") == 0 ) { authorized_keys_command_user = *argv_ptr + sizeof("authorized_keys_command_user=") - 1; } + if(strncasecmp_literal(*argv_ptr, "default_ssh_auth_sock=") == 0 ) { + default_ssh_auth_sock = *argv_ptr + sizeof("default_ssh_auth_sock=") - 1; + } #ifdef ENABLE_SUDO_HACK if(strncasecmp_literal(*argv_ptr, "sudo_service_name=") == 0) { strncpy( sudo_service_name, *argv_ptr + sizeof("sudo_service_name=") - 1, sizeof(sudo_service_name) - 1); diff --git a/pam_ssh_agent_auth.pod b/pam_ssh_agent_auth.pod index b6a3792..838776a 100644 --- a/pam_ssh_agent_auth.pod +++ b/pam_ssh_agent_auth.pod @@ -73,6 +73,10 @@ This is ideally suited for use with sssd's sss_ssh_authorizedkeys, for authentic Specify a user to run the authorized_keys_command as. If this option is not specified, the authorized_keys_command will be run as the user being authenticated. +=item default_ssh_auth_sock=/path/to/ssh_auth_sock + +Specify a default SSH_AUTH_SOCK to use. Useful when logging in with a Display Manager (such as SDDM), in which case environment variables are hard to set. + =item debug A flag which enables verbose logging From 763ceec6fc35005f324862cd4ceffdde49d533c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Kov=C3=A1cs?= Date: Sun, 17 Jul 2022 12:43:59 +0200 Subject: [PATCH 2/6] added %u %h to default_ssh_auth_sock path --- pam_ssh_agent_auth.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pam_ssh_agent_auth.c b/pam_ssh_agent_auth.c index a5c536f..0752811 100644 --- a/pam_ssh_agent_auth.c +++ b/pam_ssh_agent_auth.c @@ -58,6 +58,7 @@ #include "pam_static_macros.h" #include "pam_user_authorized_keys.h" #include "userauth_pubkey_from_pam.h" +#include "misc.h" #define strncasecmp_literal(A,B) strncasecmp( A, B, sizeof(B) - 1) #define UNUSED(expr) do { (void)(expr); } while (0) @@ -177,6 +178,12 @@ pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) goto cleanexit; } + if(default_ssh_auth_sock && user) { + default_ssh_auth_sock = pamsshagentauth_percent_expand(default_ssh_auth_sock, + "h", getpwnam(user)->pw_dir, + "u", user, NULL); + } + if(authorized_keys_file_input && user) { /* * user is the name of the target-user, and so must be used for validating the authorized_keys file From d7865aae5db72d6bc8540a378dcb4cd8deb331b6 Mon Sep 17 00:00:00 2001 From: Edward P Date: Wed, 9 Nov 2022 09:55:32 +0800 Subject: [PATCH 3/6] allow %U for uid expansion in "default_ssh_auth_sock" --- pam_ssh_agent_auth.c | 8 ++++++++ pam_ssh_agent_auth.pod | 2 ++ 2 files changed, 10 insertions(+) diff --git a/pam_ssh_agent_auth.c b/pam_ssh_agent_auth.c index 0752811..196c963 100644 --- a/pam_ssh_agent_auth.c +++ b/pam_ssh_agent_auth.c @@ -179,9 +179,17 @@ pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) } if(default_ssh_auth_sock && user) { + uid_t uid = getpwnam(user)->pw_uid; + int length = snprintf( NULL, 0, "%u", uid); + char* uid_s = malloc( length + 1 ); + snprintf( uid_s, length + 1, "%u", uid); + default_ssh_auth_sock = pamsshagentauth_percent_expand(default_ssh_auth_sock, "h", getpwnam(user)->pw_dir, + "U", uid_s, "u", user, NULL); + + free(uid_s); } if(authorized_keys_file_input && user) { diff --git a/pam_ssh_agent_auth.pod b/pam_ssh_agent_auth.pod index 838776a..06da976 100644 --- a/pam_ssh_agent_auth.pod +++ b/pam_ssh_agent_auth.pod @@ -107,6 +107,8 @@ Automatically enables allow_user_owned_authorized_keys_file =item %H -- The short-hostname +=item %U -- Uid + =item %u -- Username =item %f -- FQDN From c8ee51479797a65b6c4b7a64a89a9db5b1c1aa6b Mon Sep 17 00:00:00 2001 From: edward-p Date: Fri, 11 Nov 2022 12:44:51 +0800 Subject: [PATCH 4/6] add ignore_env_ssh_auth_sock flag --- authfd.c | 5 +++-- pam_ssh_agent_auth.c | 5 +++++ pam_ssh_agent_auth.pod | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/authfd.c b/authfd.c index a05e25b..bb92fce 100644 --- a/authfd.c +++ b/authfd.c @@ -72,6 +72,7 @@ #include "misc.h" extern char *default_ssh_auth_sock; +extern uint8_t ignore_env_ssh_auth_sock; static int agent_present = 0; @@ -112,7 +113,7 @@ ssh_get_authentication_socket(uid_t uid) struct stat sock_st; authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); - authsocket = authsocket ? authsocket : default_ssh_auth_sock; + authsocket = authsocket && !ignore_env_ssh_auth_sock ? authsocket : default_ssh_auth_sock; if (!authsocket) return -1; @@ -226,7 +227,7 @@ ssh_close_authentication_socket(int sock) const char *authsocket; authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); - authsocket = authsocket ? authsocket : default_ssh_auth_sock; + authsocket = authsocket && !ignore_env_ssh_auth_sock ? authsocket : default_ssh_auth_sock; if (authsocket) close(sock); diff --git a/pam_ssh_agent_auth.c b/pam_ssh_agent_auth.c index 196c963..2ca05f4 100644 --- a/pam_ssh_agent_auth.c +++ b/pam_ssh_agent_auth.c @@ -28,6 +28,7 @@ */ #include "config.h" +#include #include #ifdef HAVE_SECURITY_PAM_APPL_H @@ -68,6 +69,7 @@ uint8_t allow_user_owned_authorized_keys_file = 0; char *authorized_keys_command = NULL; char *authorized_keys_command_user = NULL; char *default_ssh_auth_sock = NULL; +uint8_t ignore_env_ssh_auth_sock = 0; #if ! HAVE___PROGNAME || HAVE_BUNDLE char *__progname; @@ -130,6 +132,9 @@ pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) if(strncasecmp_literal(*argv_ptr, "default_ssh_auth_sock=") == 0 ) { default_ssh_auth_sock = *argv_ptr + sizeof("default_ssh_auth_sock=") - 1; } + if(strncasecmp_literal(*argv_ptr, "ignore_env_ssh_auth_sock") == 0) { + ignore_env_ssh_auth_sock = 1; + } #ifdef ENABLE_SUDO_HACK if(strncasecmp_literal(*argv_ptr, "sudo_service_name=") == 0) { strncpy( sudo_service_name, *argv_ptr + sizeof("sudo_service_name=") - 1, sizeof(sudo_service_name) - 1); diff --git a/pam_ssh_agent_auth.pod b/pam_ssh_agent_auth.pod index 06da976..633b20b 100644 --- a/pam_ssh_agent_auth.pod +++ b/pam_ssh_agent_auth.pod @@ -77,6 +77,10 @@ Specify a user to run the authorized_keys_command as. If this option is not spec Specify a default SSH_AUTH_SOCK to use. Useful when logging in with a Display Manager (such as SDDM), in which case environment variables are hard to set. +=item ignore_env_ssh_auth_sock + +A flag which makes SSH_AUTH_SOCK from environment variable ignored and fallback to default_ssh_auth_sock. + =item debug A flag which enables verbose logging From 6bae77fa78ec0859c1d1ffd7279ee83e8ca3526a Mon Sep 17 00:00:00 2001 From: edward-p Date: Fri, 11 Nov 2022 12:47:56 +0800 Subject: [PATCH 5/6] seteuid back to 0 when connect socket failed --- authfd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/authfd.c b/authfd.c index bb92fce..11978c9 100644 --- a/authfd.c +++ b/authfd.c @@ -157,6 +157,7 @@ ssh_get_authentication_socket(uid_t uid) close(sock); if(errno == EACCES) pamsshagentauth_fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid); + seteuid(0); return -1; } From 3c8ab96f3a292ba91b9473df544bffd06f764fad Mon Sep 17 00:00:00 2001 From: edward-p Date: Tue, 15 Nov 2022 09:40:49 +0800 Subject: [PATCH 6/6] Don't call seteuid if uid already matches --- authfd.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/authfd.c b/authfd.c index 11978c9..a15d85a 100644 --- a/authfd.c +++ b/authfd.c @@ -150,19 +150,22 @@ ssh_get_authentication_socket(uid_t uid) errno = 0; /* To ensure a race condition is not used to circumvent the stat above, we will temporarily drop UID to the caller */ - if (seteuid(uid) < 0) - return -1; + int seteuid_called = geteuid() != uid; + if (seteuid_called && seteuid(uid) < 0) + return -1; + if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) { close(sock); if(errno == EACCES) pamsshagentauth_fatal("MAJOR SECURITY WARNING: uid %lu made a deliberate and malicious attempt to open an agent socket owned by another user", (unsigned long) uid); - seteuid(0); + if(seteuid_called) + seteuid(0); return -1; } /* we now continue the regularly scheduled programming */ - if (seteuid(0) < 0) + if (seteuid_called && seteuid(0) < 0) return -1; agent_present = 1;