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