[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#560148: patch



tags 560148 patch
thanks

Please find the patch attached. It changes the behaviour to allow
multiple instances of the AuthorizedKeysFile option and should also
maintain the behaviour of the AuthorizedKeysFile2 option.

It is overly tested for the ssh2 part. But the ssh1 part only builds.

Bastian

-- 
Deflector shields just came on, Captain.
Description: Upstream changes introduced in version 1:5.1p1-8multiauthfile1
 This patch has been created by dpkg-source during the package build.
 Here's the last changelog entry, hopefully it gives details on why
 those changes were made:
 .
 openssh (1:5.1p1-8multiauthfile1) UNRELEASED; urgency=low
 .
   * Support multiple AuthorizedKeysFile entries.
 .
 The person named in the Author field signed this changelog entry.
Author: Bastian Blank <waldi@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- openssh-5.1p1.orig/servconf.c
+++ openssh-5.1p1/servconf.c
@@ -123,8 +123,8 @@ initialize_server_options(ServerOptions 
 	options->use_dns = -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;
+	options->set_authorized_keys_file2 = 0;
 	options->num_accept_env = 0;
 	options->permit_tun = -1;
 	options->num_permitted_opens = -1;
@@ -256,15 +256,18 @@ fill_default_server_options(ServerOption
 		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) {
+		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;
+	}
+	else if (options->num_authorized_keys_files == 1 &&
+	    options->set_authorized_keys_file2) {
+		/* We only had AuthorizedKeysFile2 set */
+		options->authorized_keys_files[options->num_authorized_keys_files++] =
+		    _PATH_SSH_USER_PERMITTED_KEYS;
 	}
-	if (options->authorized_keys_file == NULL)
-		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
 	if (options->permit_tun == -1)
 		options->permit_tun = SSH_TUNMODE_NO;
 
@@ -1203,11 +1206,14 @@ process_server_config_line(ServerOptions
 	 *
 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
 	 */
-	case sAuthorizedKeysFile:
 	case sAuthorizedKeysFile2:
-		charptr = (opcode == sAuthorizedKeysFile) ?
-		    &options->authorized_keys_file :
-		    &options->authorized_keys_file2;
+		options->set_authorized_keys_file2 = 1;
+	case sAuthorizedKeysFile:
+		intptr = &options->num_authorized_keys_files;
+		if (*intptr >= MAX_AUTHORIZEDKEYSFILES)
+			fatal("%s line %d: too many authorized keys files specified (max %d).",
+			    filename, linenum, MAX_AUTHORIZEDKEYSFILES);
+		charptr = &options->authorized_keys_files[*intptr];
 		goto parse_filename;
 
 	case sClientAliveInterval:
@@ -1629,8 +1635,8 @@ dump_config(ServerOptions *o)
 	dump_cfg_string(sCiphers, o->ciphers);
 	dump_cfg_string(sMacs, o->macs);
 	dump_cfg_string(sBanner, o->banner);
-	dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
-	dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
+	dump_cfg_strarray(sAuthorizedKeysFile, o->num_authorized_keys_files,
+	     o->authorized_keys_files);
 	dump_cfg_string(sForceCommand, o->adm_forced_command);
 
 	/* string arguments requiring a lookup */
--- openssh-5.1p1.orig/auth.c
+++ openssh-5.1p1/auth.c
@@ -326,7 +326,7 @@ auth_root_allowed(char *method)
  *
  * This returns a buffer allocated by xmalloc.
  */
-static char *
+char *
 expand_authorized_keys(const char *filename, struct passwd *pw)
 {
 	char *file, ret[MAXPATHLEN];
@@ -349,18 +349,6 @@ expand_authorized_keys(const char *filen
 	return (xstrdup(ret));
 }
 
-char *
-authorized_keys_file(struct passwd *pw)
-{
-	return expand_authorized_keys(options.authorized_keys_file, pw);
-}
-
-char *
-authorized_keys_file2(struct passwd *pw)
-{
-	return expand_authorized_keys(options.authorized_keys_file2, pw);
-}
-
 /* return ok if key exists in sysfile or userfile */
 HostStatus
 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
--- openssh-5.1p1.orig/auth-rsa.c
+++ openssh-5.1p1/auth-rsa.c
@@ -165,8 +165,8 @@ auth_rsa_challenge_dialog(Key *key)
  * return key if login is allowed, NULL otherwise
  */
 
-int
-auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+static int
+auth_rsa_key_allowed2(const char *filename, struct passwd *pw, BIGNUM *client_n, Key **rkey)
 {
 	char line[SSH_MAX_PUBKEY_BYTES], *file;
 	int allowed = 0;
@@ -175,18 +175,11 @@ auth_rsa_key_allowed(struct passwd *pw, 
 	u_long linenum = 0;
 	Key *key;
 
-	/* 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);
-	f = auth_openkeyfile(file, pw, options.strict_modes);
-	if (!f) {
-		xfree(file);
-		restore_uid();
-		return (0);
-	}
+	debug("trying public RSA key file %s", filename);
+	f = auth_openkeyfile(filename, pw, options.strict_modes);
+	if (!f)
+		return 0;
 
 	/* Flag indicating whether the key is allowed. */
 	allowed = 0;
@@ -262,11 +255,7 @@ auth_rsa_key_allowed(struct passwd *pw, 
 		break;
 	}
 
-	/* Restore the privileged uid. */
-	restore_uid();
-
 	/* Close the file. */
-	xfree(file);
 	fclose(f);
 
 	/* return key if allowed */
@@ -277,6 +266,30 @@ auth_rsa_key_allowed(struct passwd *pw, 
 	return (allowed);
 }
 
+int
+auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+{
+	int i;
+	int allowed = 0;
+	char *file;
+
+	/* Temporarily use the user's uid. */
+	temporarily_use_uid(pw);
+
+	for (i = 0; i < options.num_authorized_keys_files; i++) {
+		file = expand_authorized_keys(options.authorized_keys_files[i], pw);
+		allowed = auth_openkeyfile(file, pw, options.strict_modes);
+		xfree(file);
+		if (allowed)
+			break;
+	}
+
+	/* Restore the privileged uid. */
+	restore_uid();
+
+	return allowed;
+}
+
 /*
  * Performs the RSA authentication dialog with the client.  This returns
  * 0 if the client could not be authenticated, and 1 if authentication was
--- openssh-5.1p1.orig/sshd_config.5
+++ openssh-5.1p1/sshd_config.5
@@ -180,8 +180,9 @@ in
 .Xr ssh_config 5
 for more information on patterns.
 .It Cm AuthorizedKeysFile
-Specifies the file that contains the public keys that can be used
+Specifies a file that contains public keys that can be used
 for user authentication.
+It is possible to have multiple files specified.
 .Cm AuthorizedKeysFile
 may contain tokens of the form %T which are substituted during connection
 setup.
--- openssh-5.1p1.orig/auth.h
+++ openssh-5.1p1/auth.h
@@ -165,8 +165,7 @@ char	*get_challenge(Authctxt *);
 int	verify_response(Authctxt *, const char *);
 void	abandon_challenge_response(Authctxt *);
 
-char	*authorized_keys_file(struct passwd *);
-char	*authorized_keys_file2(struct passwd *);
+char	*expand_authorized_keys(const char *filename, struct passwd *);
 
 FILE	*auth_openkeyfile(const char *, struct passwd *, int);
 
--- openssh-5.1p1.orig/servconf.h
+++ openssh-5.1p1/servconf.h
@@ -26,6 +26,7 @@
 #define MAX_HOSTKEYS		256	/* Max # hostkeys. */
 #define MAX_ACCEPT_ENV		256	/* Max # of env vars. */
 #define MAX_MATCH_GROUPS	256	/* Max # of groups for Match. */
+#define MAX_AUTHORIZEDKEYSFILES	256	/* Max # authorized keys files. */
 
 /* permit_root_login */
 #define	PERMIT_NOT_SET		-1
@@ -140,8 +141,9 @@ typedef struct {
 					 * disconnect the session
 					 */
 
-	char   *authorized_keys_file;	/* File containing public keys */
-	char   *authorized_keys_file2;
+	char   *authorized_keys_files[MAX_AUTHORIZEDKEYSFILES];	/* Files containing public keys */
+	int	num_authorized_keys_files;	/* Number of files for authorized keys. */
+	int	set_authorized_keys_file2;	/* Marker if backup files was set. */
 
 	char   *adm_forced_command;
 
--- openssh-5.1p1.orig/auth2-pubkey.c
+++ openssh-5.1p1/auth2-pubkey.c
@@ -255,23 +255,21 @@ user_key_allowed2(struct passwd *pw, Key
 int
 user_key_allowed(struct passwd *pw, Key *key)
 {
-	int success;
+	int i, success;
 	char *file;
 
 	if (reject_blacklisted_key(key, 0) == 1)
 		return 0;
 
-	file = authorized_keys_file(pw);
-	success = user_key_allowed2(pw, key, file);
-	xfree(file);
-	if (success)
-		return success;
+	for (i = 0; i < options.num_authorized_keys_files; i++) {
+		file = expand_authorized_keys(options.authorized_keys_files[i], 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);
-	return success;
+	return 0;
 }
 
 Authmethod method_pubkey = {

Attachment: signature.asc
Description: Digital signature


Reply to: