at 17.09-beta 365 lines 16 kB view raw
1diff -u pam_ssh_agent_auth-0.10.3-orig/iterate_ssh_agent_keys.c pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2--- pam_ssh_agent_auth-0.10.3-orig/iterate_ssh_agent_keys.c 2016-11-12 19:24:32.000000000 -0800 3+++ pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.c 2017-03-02 23:47:18.012203283 -0800 4@@ -176,7 +176,7 @@ 5 return; 6 } 7 8-int 9+const char * 10 pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename) 11 { 12 Buffer session_id2 = { 0 }; 13@@ -184,7 +184,7 @@ 14 Key *key; 15 AuthenticationConnection *ac; 16 char *comment; 17- uint8_t retval = 0; 18+ const char *key_file = 0; 19 uid_t uid = getpwnam(ruser)->pw_uid; 20 21 OpenSSL_add_all_digests(); 22@@ -199,13 +199,11 @@ 23 id->key = key; 24 id->filename = comment; 25 id->ac = ac; 26- if(userauth_pubkey_from_id(ruser, id, &session_id2)) { 27- retval = 1; 28- } 29+ key_file = userauth_pubkey_from_id(ruser, id, &session_id2); 30 pamsshagentauth_xfree(id->filename); 31 pamsshagentauth_key_free(id->key); 32 pamsshagentauth_xfree(id); 33- if(retval == 1) 34+ if(key_file) 35 break; 36 } 37 } 38@@ -217,5 +215,5 @@ 39 } 40 /* pamsshagentauth_xfree(session_id2); */ 41 EVP_cleanup(); 42- return retval; 43+ return key_file; 44 } 45diff -u pam_ssh_agent_auth-0.10.3-orig/iterate_ssh_agent_keys.h pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.h 46--- pam_ssh_agent_auth-0.10.3-orig/iterate_ssh_agent_keys.h 2016-11-12 19:24:32.000000000 -0800 47+++ pam_ssh_agent_auth-0.10.3/iterate_ssh_agent_keys.h 2017-03-02 23:48:06.345803339 -0800 48@@ -31,6 +31,6 @@ 49 #ifndef _ITERATE_SSH_AGENT_KEYS_H 50 #define _ITERATE_SSH_AGENT_KEYS_H 51 52-int pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename); 53+const char * pamsshagentauth_find_authorized_keys(const char * user, const char * ruser, const char * servicename); 54 55 #endif 56diff -u pam_ssh_agent_auth-0.10.3-orig/pam_ssh_agent_auth.c pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c 57--- pam_ssh_agent_auth-0.10.3-orig/pam_ssh_agent_auth.c 2016-11-12 19:24:32.000000000 -0800 58+++ pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.c 2017-03-02 23:51:57.642669946 -0800 59@@ -61,7 +61,6 @@ 60 #define strncasecmp_literal(A,B) strncasecmp( A, B, sizeof(B) - 1) 61 #define UNUSED(expr) do { (void)(expr); } while (0) 62 63-char *authorized_keys_file = NULL; 64 uint8_t allow_user_owned_authorized_keys_file = 0; 65 char *authorized_keys_command = NULL; 66 char *authorized_keys_command_user = NULL; 67@@ -171,15 +170,13 @@ 68 goto cleanexit; 69 } 70 71- if(authorized_keys_file_input && user) { 72- /* 73- * user is the name of the target-user, and so must be used for validating the authorized_keys file 74- */ 75- parse_authorized_key_file(user, authorized_keys_file_input); 76- } else { 77- pamsshagentauth_verbose("Using default file=/etc/security/authorized_keys"); 78- authorized_keys_file = pamsshagentauth_xstrdup("/etc/security/authorized_keys"); 79- } 80+ if (!authorized_keys_file_input || !user) 81+ authorized_keys_file_input = "/etc/security/authorized_keys"; 82+ 83+ /* 84+ * user is the name of the target-user, and so must be used for validating the authorized_keys file 85+ */ 86+ parse_authorized_key_files(user, authorized_keys_file_input); 87 88 /* 89 * PAM_USER and PAM_RUSER do not necessarily have to get set by the calling application, and we may be unable to divine the latter. 90@@ -187,16 +184,17 @@ 91 */ 92 93 if(user && strlen(ruser) > 0) { 94- pamsshagentauth_verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); 95+ pamsshagentauth_verbose("Attempting authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file_input); 96 97 /* 98 * this pw_uid is used to validate the SSH_AUTH_SOCK, and so must be the uid of the ruser invoking the program, not the target-user 99 */ 100- if(pamsshagentauth_find_authorized_keys(user, ruser, servicename)) { /* getpwnam(ruser)->pw_uid)) { */ 101- pamsshagentauth_logit("Authenticated: `%s' as `%s' using %s", ruser, user, authorized_keys_file); 102+ const char *key_file; 103+ if((key_file = pamsshagentauth_find_authorized_keys(user, ruser, servicename))) { /* getpwnam(ruser)->pw_uid)) { */ 104+ pamsshagentauth_logit("Authenticated: `%s' as `%s' using %s", ruser, user, key_file); 105 retval = PAM_SUCCESS; 106 } else { 107- pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file); 108+ pamsshagentauth_logit("Failed Authentication: `%s' as `%s' using %s", ruser, user, authorized_keys_file_input); 109 } 110 } else { 111 pamsshagentauth_logit("No %s specified, cannot continue with this form of authentication", (user) ? "ruser" : "user" ); 112@@ -208,7 +206,7 @@ 113 free(__progname); 114 #endif 115 116- free(authorized_keys_file); 117+ free_authorized_key_files(); 118 119 return retval; 120 } 121diff -u pam_ssh_agent_auth-0.10.3-orig/pam_ssh_agent_auth.pod pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.pod 122--- pam_ssh_agent_auth-0.10.3-orig/pam_ssh_agent_auth.pod 2016-11-12 19:24:32.000000000 -0800 123+++ pam_ssh_agent_auth-0.10.3/pam_ssh_agent_auth.pod 2017-03-02 23:52:28.914857449 -0800 124@@ -31,7 +31,7 @@ 125 126 =item file=<path to authorized_keys> 127 128-Specify the path to the authorized_keys file(s) you would like to use for authentication. Subject to tilde and % EXPANSIONS (below) 129+Specify the path(s) to the authorized_keys file(s) you would like to use for authentication. Subject to tilde and % EXPANSIONS (below). Paths are separated using colons. 130 131 =item allow_user_owned_authorized_keys_file 132 133diff -u pam_ssh_agent_auth-0.10.3-orig/pam_user_authorized_keys.c pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c 134--- pam_ssh_agent_auth-0.10.3-orig/pam_user_authorized_keys.c 2016-11-12 19:24:32.000000000 -0800 135+++ pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.c 2017-03-03 00:07:45.201322570 -0800 136@@ -79,8 +79,12 @@ 137 138 #include "identity.h" 139 #include "pam_user_key_allowed2.h" 140+#include "pam_user_authorized_keys.h" 141 142-extern char *authorized_keys_file; 143+#define MAX_AUTHORIZED_KEY_FILES 16 144+ 145+char *authorized_keys_files[MAX_AUTHORIZED_KEY_FILES]; 146+unsigned int nr_authorized_keys_files = 0; 147 148 extern char *authorized_keys_command; 149 150@@ -91,79 +95,88 @@ 151 uid_t authorized_keys_file_allowed_owner_uid; 152 153 void 154-parse_authorized_key_file(const char *user, 155- const char *authorized_keys_file_input) 156+parse_authorized_key_files(const char *user, 157+ const char *authorized_keys_file_input) 158 { 159- char fqdn[HOST_NAME_MAX] = ""; 160+ const char *pos = authorized_keys_file_input; 161 char hostname[HOST_NAME_MAX] = ""; 162- char auth_keys_file_buf[4096] = ""; 163- char *slash_ptr = NULL; 164- char owner_uname[128] = ""; 165- size_t owner_uname_len = 0; 166- 167- /* 168- * temporary copy, so that both tilde expansion and percent expansion both 169- * get to apply to the path 170- */ 171- strncat(auth_keys_file_buf, authorized_keys_file_input, 172- sizeof(auth_keys_file_buf) - 1); 173+ char fqdn[HOST_NAME_MAX] = ""; 174 175- if(allow_user_owned_authorized_keys_file) 176- authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; 177+#if HAVE_GETHOSTNAME 178+ *hostname = '\0'; 179+ gethostname(fqdn, HOST_NAME_MAX); 180+ strncat(hostname, fqdn, strcspn(fqdn,".")); 181+#endif 182 183- if(*auth_keys_file_buf == '~') { 184- if(*(auth_keys_file_buf + 1) == '/') { 185- authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; 186+ while (pos) { 187+ const char *colon = strchr(pos, ':'); 188+ char auth_keys_file_buf[4096] = ""; 189+ char *slash_ptr = NULL; 190+ char owner_uname[128] = ""; 191+ size_t owner_uname_len = 0; 192+ 193+ strncat(auth_keys_file_buf, pos, sizeof(auth_keys_file_buf) - 1); 194+ if (colon) { 195+ auth_keys_file_buf[colon - pos] = 0; 196+ pos = colon + 1; 197 } else { 198- slash_ptr = strchr(auth_keys_file_buf, '/'); 199- if(!slash_ptr) 200- pamsshagentauth_fatal 201- ("cannot expand tilde in path without a `/'"); 202- 203- owner_uname_len = slash_ptr - auth_keys_file_buf - 1; 204- if(owner_uname_len > (sizeof(owner_uname) - 1)) 205- pamsshagentauth_fatal("Username too long"); 206- 207- strncat(owner_uname, auth_keys_file_buf + 1, owner_uname_len); 208- if(!authorized_keys_file_allowed_owner_uid) 209- authorized_keys_file_allowed_owner_uid = 210- getpwnam(owner_uname)->pw_uid; 211+ pos = 0; 212+ } 213+ 214+ if(allow_user_owned_authorized_keys_file) 215+ authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; 216+ 217+ if(*auth_keys_file_buf == '~') { 218+ if(*(auth_keys_file_buf+1) == '/') { 219+ authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; 220+ } 221+ else { 222+ slash_ptr = strchr(auth_keys_file_buf,'/'); 223+ if(!slash_ptr) 224+ pamsshagentauth_fatal("cannot expand tilde in path without a `/'"); 225+ 226+ owner_uname_len = slash_ptr - auth_keys_file_buf - 1; 227+ if(owner_uname_len > (sizeof(owner_uname) - 1) ) 228+ pamsshagentauth_fatal("Username too long"); 229+ 230+ strncat(owner_uname, auth_keys_file_buf + 1, owner_uname_len); 231+ if(!authorized_keys_file_allowed_owner_uid) 232+ authorized_keys_file_allowed_owner_uid = getpwnam(owner_uname)->pw_uid; 233+ } 234+ char *tmp = pamsshagentauth_tilde_expand_filename(auth_keys_file_buf, authorized_keys_file_allowed_owner_uid); 235+ strncpy(auth_keys_file_buf, tmp, sizeof(auth_keys_file_buf) - 1 ); 236+ pamsshagentauth_xfree(tmp); 237 } 238- authorized_keys_file = 239- pamsshagentauth_tilde_expand_filename(auth_keys_file_buf, 240- authorized_keys_file_allowed_owner_uid); 241- strncpy(auth_keys_file_buf, authorized_keys_file, 242- sizeof(auth_keys_file_buf) - 1); 243- pamsshagentauth_xfree(authorized_keys_file) /* when we 244- percent_expand 245- later, we'd step 246- on this, so free 247- it immediately */ ; 248- } 249 250- if(strstr(auth_keys_file_buf, "%h")) { 251- authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; 252+ if(strstr(auth_keys_file_buf, "%h")) { 253+ authorized_keys_file_allowed_owner_uid = getpwnam(user)->pw_uid; 254+ } 255+ 256+ if (nr_authorized_keys_files >= MAX_AUTHORIZED_KEY_FILES) 257+ pamsshagentauth_fatal("Too many authorized key files"); 258+ authorized_keys_files[nr_authorized_keys_files++] = 259+ pamsshagentauth_percent_expand(auth_keys_file_buf, "h", getpwnam(user)->pw_dir, "H", hostname, "f", fqdn, "u", user, NULL); 260 } 261-#if HAVE_GETHOSTNAME 262- *hostname = '\0'; 263- gethostname(fqdn, HOST_NAME_MAX); 264- strncat(hostname, fqdn, strcspn(fqdn, ".")); 265-#endif 266- authorized_keys_file = 267- pamsshagentauth_percent_expand(auth_keys_file_buf, "h", 268- getpwnam(user)->pw_dir, "H", hostname, 269- "f", fqdn, "u", user, NULL); 270 } 271 272-int 273+void 274+free_authorized_key_files() 275+{ 276+ unsigned int n; 277+ for (n = 0; n < nr_authorized_keys_files; n++) 278+ free(authorized_keys_files[n]); 279+ nr_authorized_keys_files = 0; 280+} 281+ 282+const char * 283 pam_user_key_allowed(const char *ruser, Key * key) 284 { 285- return 286- pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid), 287- key, authorized_keys_file) 288- || pamsshagentauth_user_key_allowed2(getpwuid(0), key, 289- authorized_keys_file) 290- || pamsshagentauth_user_key_command_allowed2(authorized_keys_command, 291- authorized_keys_command_user, 292- getpwnam(ruser), key); 293+ unsigned int n; 294+ for (n = 0; n < nr_authorized_keys_files; n++) { 295+ if (pamsshagentauth_user_key_allowed2(getpwuid(authorized_keys_file_allowed_owner_uid), key, authorized_keys_files[n]) 296+ || pamsshagentauth_user_key_allowed2(getpwuid(0), key, authorized_keys_files[n]) 297+ || pamsshagentauth_user_key_command_allowed2(authorized_keys_command, authorized_keys_command_user, getpwnam(ruser), key)) 298+ return authorized_keys_files[n]; 299+ } 300+ return 0; 301 } 302diff -u pam_ssh_agent_auth-0.10.3-orig/pam_user_authorized_keys.h pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h 303--- pam_ssh_agent_auth-0.10.3-orig/pam_user_authorized_keys.h 2016-11-12 19:24:32.000000000 -0800 304+++ pam_ssh_agent_auth-0.10.3/pam_user_authorized_keys.h 2017-03-03 00:09:17.256064914 -0800 305@@ -28,11 +28,12 @@ 306 */ 307 308 309-#ifndef _PAM_USER_KEY_ALLOWED_H 310-#define _PAM_USER_KEY_ALLOWED_H 311+#ifndef _PAM_USER_AUTHORIZED_KEYS_H 312+#define _PAM_USER_AUTHORIZED_KEYS_H 313 314 #include "identity.h" 315-int pam_user_key_allowed(const char *, Key *); 316-void parse_authorized_key_file(const char *, const char *); 317+const char * pam_user_key_allowed(const char *, Key *); 318+void parse_authorized_key_files(const char *, const char *); 319+void free_authorized_key_files(); 320 321 #endif 322diff -u pam_ssh_agent_auth-0.10.3-orig/userauth_pubkey_from_id.c pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c 323--- pam_ssh_agent_auth-0.10.3-orig/userauth_pubkey_from_id.c 2016-11-12 19:24:32.000000000 -0800 324+++ pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.c 2017-03-03 00:10:33.163545380 -0800 325@@ -52,7 +52,7 @@ 326 extern uint8_t session_id_len; 327 */ 328 329-int 330+const char * 331 userauth_pubkey_from_id(const char *ruser, Identity * id, Buffer * session_id2) 332 { 333 Buffer b = { 0 }; 334@@ -60,11 +60,12 @@ 335 u_char *pkblob = NULL, *sig = NULL; 336 u_int blen = 0, slen = 0; 337 int authenticated = 0; 338+ const char *key_file; 339 340 pkalg = (char *) key_ssh_name(id->key); 341 342 /* first test if this key is even allowed */ 343- if(! pam_user_key_allowed(ruser, id->key)) 344+ if(!(key_file = pam_user_key_allowed(ruser, id->key))) 345 goto user_auth_clean_exit; 346 347 if(pamsshagentauth_key_to_blob(id->key, &pkblob, &blen) == 0) 348@@ -97,5 +98,5 @@ 349 if(pkblob != NULL) 350 pamsshagentauth_xfree(pkblob); 351 CRYPTO_cleanup_all_ex_data(); 352- return authenticated; 353+ return authenticated ? key_file : 0; 354 } 355diff -u pam_ssh_agent_auth-0.10.3-orig/userauth_pubkey_from_id.h pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h 356--- pam_ssh_agent_auth-0.10.3-orig/userauth_pubkey_from_id.h 2016-11-12 19:24:32.000000000 -0800 357+++ pam_ssh_agent_auth-0.10.3/userauth_pubkey_from_id.h 2017-03-03 00:10:59.067046872 -0800 358@@ -32,6 +32,6 @@ 359 #define _USERAUTH_PUBKEY_FROM_ID_H 360 361 #include <identity.h> 362-int userauth_pubkey_from_id(const char *, Identity *, Buffer *); 363+const char * userauth_pubkey_from_id(const char *, Identity *, Buffer *); 364 365 #endif