[PATCH] Add multiple AuthorizedKeyFiles options

Mike Bristow mike.bristow at thus.net
Wed Jan 23 22:12:27 EST 2002


Hi,

We'd like to run sshd with a configuration morally equivilent to:

# stuff ...
AuthorizedKeysFile	/var/db/keys-distributed-by-security-team/%u
AuthorizedKeysFile	%h/.ssh/authorized_keys
# be backwards compatable for a bit longer yet
AuthorizedKeysFile	%h/.ssh/authorized_keys2
# more stuff ...

The following patch (against the cvs source) turns the authorizedkeysfile
statement in sshd.conf into one which populates a list of such
files.

I've also turned "authorizedkeysfile2" into an alias for
"authorizedkeysfile" (but perhaps it out to be deprecated instead).

Does this look OK to folk?  If so, I'll make the approprate changes
to the manual pages and re-submit (via bugzilla, the mailing list,
or whatever is the Right Thing To Do).

-- 
Mike Bristow, embonpointful, but not managerial, damnit.
-------------- next part --------------
Index: auth-rsa.c
===================================================================
RCS file: /cvs/openssh/auth-rsa.c,v
retrieving revision 1.41
diff -u -r1.41 auth-rsa.c
--- auth-rsa.c	22 Jan 2002 12:16:33 -0000	1.41
+++ auth-rsa.c	23 Jan 2002 11:11:28 -0000
@@ -58,6 +58,8 @@
  * our challenge; returns zero if the client gives a wrong answer.
  */
 
+static int auth_rsa_file(struct passwd *pw, BIGNUM *client_n, char *file);
+
 int
 auth_rsa_challenge_dialog(RSA *pk)
 {
@@ -122,11 +124,33 @@
  * 0 if the client could not be authenticated, and 1 if authentication was
  * successful.  This may exit if there is a serious protocol violation.
  */
+int 
+auth_rsa(struct passwd *pw, BIGNUM *client_n) {
+	char *file;
+	int authorized = 0;
+	int authfileno = 0;
+
+	/* no user given */
+	if (pw == NULL)
+		return 0;
+
+	/* Iterate over all authorized keys files. */
+	while ( (file = authorized_keys_file(pw, authfileno++)) != NULL) {
+		debug("trying public RSA key file %s", file);
+		authorized = auth_rsa_file(pw, client_n, file);
+		xfree(file);
+		if (authorized == 1) {
+		    	return 1;
+		}
+	}
+	return 0;
+}
 
+/* Do the hard work in authenticating the client */
 int
-auth_rsa(struct passwd *pw, BIGNUM *client_n)
+auth_rsa_file(struct passwd *pw, BIGNUM *client_n, char *file)
 {
-	char line[8192], *file;
+	char line[8192];
 	int authenticated;
 	u_int bits;
 	FILE *f;
@@ -142,15 +166,10 @@
 	/* Temporarily use the user's uid. */
 	temporarily_use_uid(pw);
 
-	/* The authorized keys. */
-	file = authorized_keys_file(pw);
-	debug("trying public RSA key file %s", file);
-
 	/* Fail quietly if file does not exist */
 	if (stat(file, &st) < 0) {
 		/* Restore the privileged uid. */
 		restore_uid();
-		xfree(file);
 		return 0;
 	}
 	/* Open the file containing the authorized keys. */
@@ -160,12 +179,10 @@
 		restore_uid();
 		packet_send_debug("Could not open %.900s for reading.", file);
 		packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
-		xfree(file);
 		return 0;
 	}
 	if (options.strict_modes &&
 	    secure_filename(f, file, pw, line, sizeof(line)) != 0) {
-		xfree(file);
 		fclose(f);
 		log("Authentication refused: %s", line);
 		packet_send_debug("Authentication refused: %s", line);
@@ -271,7 +288,6 @@
 	restore_uid();
 
 	/* Close the file. */
-	xfree(file);
 	fclose(f);
 
 	key_free(key);
Index: auth.c
===================================================================
RCS file: /cvs/openssh/auth.c,v
retrieving revision 1.41
diff -u -r1.41 auth.c
--- auth.c	21 Dec 2001 03:45:47 -0000	1.41
+++ auth.c	23 Jan 2002 11:11:28 -0000
@@ -296,15 +296,11 @@
 }
 
 char *
-authorized_keys_file(struct passwd *pw)
+authorized_keys_file(struct passwd *pw, int n)
 {
-	return expand_filename(options.authorized_keys_file, pw);
-}
-
-char *
-authorized_keys_file2(struct passwd *pw)
-{
-	return expand_filename(options.authorized_keys_file2, pw);
+	if (n >= options.num_authorized_keys_files)
+		return NULL;
+	return expand_filename(options.authorized_keys_files[n], pw);
 }
 
 /* return ok if key exists in sysfile or userfile */
Index: auth.h
===================================================================
RCS file: /cvs/openssh/auth.h,v
retrieving revision 1.27
diff -u -r1.27 auth.h
--- auth.h	22 Jan 2002 12:11:02 -0000	1.27
+++ auth.h	23 Jan 2002 11:11:28 -0000
@@ -139,8 +139,7 @@
 struct passwd * auth_get_user(void);
 
 char	*expand_filename(const char *, struct passwd *);
-char	*authorized_keys_file(struct passwd *);
-char	*authorized_keys_file2(struct passwd *);
+char	*authorized_keys_file(struct passwd *, int n);
 
 int
 secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
Index: auth2.c
===================================================================
RCS file: /cvs/openssh/auth2.c,v
retrieving revision 1.87
diff -u -r1.87 auth2.c
--- auth2.c	22 Jan 2002 12:26:40 -0000	1.87
+++ auth2.c	23 Jan 2002 11:11:28 -0000
@@ -720,17 +720,15 @@
 {
 	int success;
 	char *file;
+	int authfileno = 0;
 
-	file = authorized_keys_file(pw);
-	success = user_key_allowed2(pw, key, file);
-	xfree(file);
-	if (success)
-		return success;
-
-	/* try suffix "2" for backward compat, too */
-	file = authorized_keys_file2(pw);
-	success = user_key_allowed2(pw, key, file);
-	xfree(file);
+	/* Iterate over all authorized_keys_files */
+	while ( (file = authorized_keys_file(pw, authfileno++) ) != NULL) {
+		success = user_key_allowed2(pw, key, file);
+		xfree(file);
+		if (success)
+			return success;
+	}
 	return success;
 }
 
Index: servconf.c
===================================================================
RCS file: /cvs/openssh/servconf.c,v
retrieving revision 1.74
diff -u -r1.74 servconf.c
--- servconf.c	22 Jan 2002 12:35:12 -0000	1.74
+++ servconf.c	23 Jan 2002 11:11:29 -0000
@@ -107,8 +107,7 @@
 	options->reverse_mapping_check = -1;
 	options->client_alive_interval = -1;
 	options->client_alive_count_max = -1;
-	options->authorized_keys_file = NULL;
-	options->authorized_keys_file2 = NULL;
+	options->num_authorized_keys_files = 0;
 }
 
 void
@@ -223,15 +222,11 @@
 		options->client_alive_interval = 0;
 	if (options->client_alive_count_max == -1)
 		options->client_alive_count_max = 3;
-	if (options->authorized_keys_file2 == NULL) {
-		/* authorized_keys_file2 falls back to authorized_keys_file */
-		if (options->authorized_keys_file != NULL)
-			options->authorized_keys_file2 = options->authorized_keys_file;
-		else
-			options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2;
+	if (options->num_authorized_keys_files == 0) {
+	    	/* fill default authorized keys files */
+		options->authorized_keys_files[options->num_authorized_keys_files++] = _PATH_SSH_USER_PERMITTED_KEYS;
+		options->authorized_keys_files[options->num_authorized_keys_files++] = _PATH_SSH_USER_PERMITTED_KEYS2;	
 	}
-	if (options->authorized_keys_file == NULL)
-		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
 }
 
 /* Keyword tokens. */
@@ -263,7 +258,7 @@
 	sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
 	sBanner, sReverseMappingCheck, sHostbasedAuthentication,
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
-	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
+	sClientAliveCountMax, sAuthorizedKeysFile,
 	sDeprecated
 } ServerOpCodes;
 
@@ -336,7 +331,7 @@
 	{ "clientaliveinterval", sClientAliveInterval },
 	{ "clientalivecountmax", sClientAliveCountMax },
 	{ "authorizedkeysfile", sAuthorizedKeysFile },
-	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
+	{ "authorizedkeysfile2", sAuthorizedKeysFile },
 	{ NULL, sBadOption }
 };
 
@@ -834,10 +829,13 @@
 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
 	 */
 	case sAuthorizedKeysFile:
-	case sAuthorizedKeysFile2:
-		charptr = (opcode == sAuthorizedKeysFile ) ?
-		    &options->authorized_keys_file :
-		    &options->authorized_keys_file2;
+			intptr = &options->num_authorized_keys_files;
+			if (*intptr >= MAX_AUTHKEYFILES)
+				fatal("%s line %d: too many authorized keys "
+				      "files specified (max %d).",
+				      filename, linenum, MAX_AUTHKEYFILES);
+
+			charptr = &options->authorized_keys_files[*intptr];
 		goto parse_filename;
 
 	case sClientAliveInterval:
Index: servconf.h
===================================================================
RCS file: /cvs/openssh/servconf.h,v
retrieving revision 1.42
diff -u -r1.42 servconf.h
--- servconf.h	21 Dec 2001 03:45:49 -0000	1.42
+++ servconf.h	23 Jan 2002 11:11:29 -0000
@@ -24,6 +24,7 @@
 #define MAX_DENY_GROUPS		256	/* Max # groups on deny list. */
 #define MAX_SUBSYSTEMS		256	/* Max # subsystems. */
 #define MAX_HOSTKEYS		256	/* Max # hostkeys. */
+#define MAX_AUTHKEYFILES	256     /* Max # authorized_keys statements */
 
 /* permit_root_login */
 #define	PERMIT_NOT_SET		-1
@@ -126,8 +127,12 @@
 					 * disconnect the session
 					 */
 
-	char   *authorized_keys_file;	/* File containing public keys */
-	char   *authorized_keys_file2;
+
+	char   *authorized_keys_files[MAX_AUTHKEYFILES]; /* 
+							  * Files containing 
+							  * public keys 
+							  */
+        int     num_authorized_keys_files;
 	int	pam_authentication_via_kbd_int;
 
 }       ServerOptions;


More information about the openssh-unix-dev mailing list