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