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 <[email protected]>

---
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 via email to