]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2001/03/10 17:51:04
authormouring <mouring>
Sun, 11 Mar 2001 01:49:19 +0000 (01:49 +0000)
committermouring <mouring>
Sun, 11 Mar 2001 01:49:19 +0000 (01:49 +0000)
     [kex.c match.c match.h readconf.c readconf.h sshconnect2.c]
     add PreferredAuthentications

ChangeLog
kex.c
match.c
match.h
readconf.c
readconf.h
sshconnect2.c

index 89d5ccd39be2cb35ee1e625e51ae40c0b1ec0e8d..a309e41e4e8de024b8226107e30f01b9644fa7be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
      handle password padding (newer OSU is fixed)
  - tim@mindrot.org 2001/03/10 16:33:42 [configure.in Makefile.in sshd_config]
    make sure $bindir is in USER_PATH so scp will work
+ - OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2001/03/10 17:51:04
+     [kex.c match.c match.h readconf.c readconf.h sshconnect2.c]
+     add PreferredAuthentications
 
 20010310
  - OpenBSD CVS Sync
diff --git a/kex.c b/kex.c
index 308ffb1b66f320547045c3f18aeea5005cc2b98a..78e108e90c157e5b14dce622b099631be0c82f9e 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.22 2001/03/05 17:17:20 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.23 2001/03/10 17:51:04 markus Exp $");
 
 #include <openssl/crypto.h>
 #include <openssl/bio.h>
@@ -42,6 +42,7 @@ RCSID("$OpenBSD: kex.c,v 1.22 2001/03/05 17:17:20 markus Exp $");
 #include "key.h"
 #include "log.h"
 #include "mac.h"
+#include "match.h"
 
 #define KEX_COOKIE_LEN 16
 
@@ -372,49 +373,10 @@ derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret)
        return digest;
 }
 
-#define NKEYS  6
-
-#define        MAX_PROP        20
-#define        SEP     ","
-
-char *
-get_match(char *client, char *server)
-{
-       char *sproposals[MAX_PROP];
-       char *c, *s, *p, *ret, *cp, *sp;
-       int i, j, nproposals;
-
-       c = cp = xstrdup(client);
-       s = sp = xstrdup(server);
-
-       for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
-            (p = strsep(&sp, SEP)), i++) {
-               if (i < MAX_PROP)
-                       sproposals[i] = p;
-               else
-                       break;
-       }
-       nproposals = i;
-
-       for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
-            (p = strsep(&cp, SEP)), i++) {
-               for (j = 0; j < nproposals; j++) {
-                       if (strcmp(p, sproposals[j]) == 0) {
-                               ret = xstrdup(p);
-                               xfree(c);
-                               xfree(s);
-                               return ret;
-                       }
-               }
-       }
-       xfree(c);
-       xfree(s);
-       return NULL;
-}
 void
 choose_enc(Enc *enc, char *client, char *server)
 {
-       char *name = get_match(client, server);
+       char *name = match_list(client, server, NULL);
        if (name == NULL)
                fatal("no matching cipher found: client %s server %s", client, server);
        enc->cipher = cipher_by_name(name);
@@ -428,7 +390,7 @@ choose_enc(Enc *enc, char *client, char *server)
 void
 choose_mac(Mac *mac, char *client, char *server)
 {
-       char *name = get_match(client, server);
+       char *name = match_list(client, server, NULL);
        if (name == NULL)
                fatal("no matching mac found: client %s server %s", client, server);
        if (mac_init(mac, name) < 0)
@@ -443,7 +405,7 @@ choose_mac(Mac *mac, char *client, char *server)
 void
 choose_comp(Comp *comp, char *client, char *server)
 {
-       char *name = get_match(client, server);
+       char *name = match_list(client, server, NULL);
        if (name == NULL)
                fatal("no matching comp found: client %s server %s", client, server);
        if (strcmp(name, "zlib") == 0) {
@@ -458,7 +420,7 @@ choose_comp(Comp *comp, char *client, char *server)
 void
 choose_kex(Kex *k, char *client, char *server)
 {
-       k->name = get_match(client, server);
+       k->name = match_list(client, server, NULL);
        if (k->name == NULL)
                fatal("no kex alg");
        if (strcmp(k->name, KEX_DH1) == 0) {
@@ -471,7 +433,7 @@ choose_kex(Kex *k, char *client, char *server)
 void
 choose_hostkeyalg(Kex *k, char *client, char *server)
 {
-       char *hostkeyalg = get_match(client, server);
+       char *hostkeyalg = match_list(client, server, NULL);
        if (hostkeyalg == NULL)
                fatal("no hostkey alg");
        k->hostkey_type = key_type_from_name(hostkeyalg);
@@ -524,6 +486,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
        return k;
 }
 
+#define NKEYS  6
 int
 kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret)
 {
diff --git a/match.c b/match.c
index 81030da6a707833055818da56cecdc6ec75f9c71..ebb562ab3fc0e2fe0ae6c58ba4e6e14e07922897 100644 (file)
--- a/match.c
+++ b/match.c
  * incompatible with the protocol description in the RFC file, it must be
  * called by a name other than "ssh" or "Secure Shell".
  */
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include "includes.h"
-RCSID("$OpenBSD: match.c,v 1.11 2001/01/21 19:05:52 markus Exp $");
+RCSID("$OpenBSD: match.c,v 1.12 2001/03/10 17:51:04 markus Exp $");
 
 #include "match.h"
+#include "xmalloc.h"
 
 /*
  * Returns true if the given string matches the pattern (which may contain ?
@@ -137,3 +161,46 @@ match_hostname(const char *host, const char *pattern, u_int len)
         */
        return got_positive;
 }
+
+
+#define        MAX_PROP        20
+#define        SEP     ","
+char *
+match_list(const char *client, const char *server, u_int *next)
+{
+       char *sproposals[MAX_PROP];
+       char *c, *s, *p, *ret, *cp, *sp;
+       int i, j, nproposals;
+
+       c = cp = xstrdup(client);
+       s = sp = xstrdup(server);
+
+       for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
+            (p = strsep(&sp, SEP)), i++) {
+               if (i < MAX_PROP)
+                       sproposals[i] = p;
+               else
+                       break;
+       }
+       nproposals = i;
+
+       for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
+            (p = strsep(&cp, SEP)), i++) {
+               for (j = 0; j < nproposals; j++) {
+                       if (strcmp(p, sproposals[j]) == 0) {
+                               ret = xstrdup(p);
+                               if (next != NULL)
+                                       *next = (cp == NULL) ?
+                                           strlen(c) : cp - c;
+                               xfree(c);
+                               xfree(s);
+                               return ret;
+                       }
+               }
+       }
+       if (next != NULL)
+               *next = strlen(c);
+       xfree(c);
+       xfree(s);
+       return NULL;
+}
diff --git a/match.h b/match.h
index 285ad55f01bd5f115c57123b284d15bd2ee01588..09c931168da9b877726bfd853c12bd1029b2e2fc 100644 (file)
--- a/match.h
+++ b/match.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: match.h,v 1.6 2001/01/29 01:58:17 niklas Exp $        */
+/*     $OpenBSD: match.h,v 1.7 2001/03/10 17:51:04 markus Exp $        */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -30,4 +30,10 @@ int     match_pattern(const char *s, const char *pattern);
  */
 int     match_hostname(const char *host, const char *pattern, u_int len);
 
+/*
+ * Returns first item from client-list that is also supported by server-list,
+ * caller must xfree() returned string.
+ */
+char   *match_list(const char *client, const char *server, u_int *next);
+
 #endif
index 2b29814763cf00af3f6d8f70ddd1f77888dfae2c..33d40e8c3b854754182e4126423d9610a3108c5e 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.66 2001/03/10 12:53:52 deraadt Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.67 2001/03/10 17:51:04 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -109,7 +109,8 @@ typedef enum {
        oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
        oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
        oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
-       oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias
+       oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
+       oPreferredAuthentications
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -171,6 +172,7 @@ static struct {
        { "keepalive", oKeepAlives },
        { "numberofpasswordprompts", oNumberOfPasswordPrompts },
        { "loglevel", oLogLevel },
+       { "preferredauthentications", oPreferredAuthentications },
        { NULL, 0 }
 };
 
@@ -446,6 +448,10 @@ parse_string:
                charptr = &options->host_key_alias;
                goto parse_string;
 
+       case oPreferredAuthentications:
+               charptr = &options->preferred_authentications;
+               goto parse_string;
+
        case oProxyCommand:
                charptr = &options->proxy_command;
                string = xstrdup("");
@@ -722,6 +728,7 @@ initialize_options(Options * options)
        options->num_local_forwards = 0;
        options->num_remote_forwards = 0;
        options->log_level = (LogLevel) - 1;
+       options->preferred_authentications = NULL;
 }
 
 /*
@@ -837,4 +844,5 @@ fill_default_options(Options * options)
        /* options->user will be set in the main program if appropriate */
        /* options->hostname will be set in the main program if appropriate */
        /* options->host_key_alias should not be set by default */
+       /* options->preferred_authentications will be set in ssh */
 }
index 97615620e78302fcb7382d151d22d226f49b90fd..55babe80eadc87c9ccb6ff7807edad001641d94b 100644 (file)
@@ -11,7 +11,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: readconf.h,v 1.27 2001/03/08 21:42:32 markus Exp $"); */
+/* RCSID("$OpenBSD: readconf.h,v 1.28 2001/03/10 17:51:04 markus Exp $"); */
 
 #ifndef READCONF_H
 #define READCONF_H
@@ -82,6 +82,7 @@ typedef struct {
        char   *user_hostfile;  /* Path for $HOME/.ssh/known_hosts. */
        char   *system_hostfile2;
        char   *user_hostfile2;
+       char   *preferred_authentications;
 
        int     num_identity_files;     /* Number of files for RSA/DSA identities. */
        char   *identity_files[SSH_MAX_IDENTITY_FILES];
index 646bb18f326b50e7cb2f7a115833fa6efd6f9e86..19d079bd3983d9626b8b6c7b2117628af3dd34fe 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.53 2001/03/10 17:51:04 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/md5.h>
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $");
 #include "log.h"
 #include "readconf.h"
 #include "readpass.h"
+#include "match.h"
 
 void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
 void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
@@ -498,9 +499,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k,
     sign_cb_fn *sign_callback);
 void   clear_auth_state(Authctxt *authctxt);
 
-void   authmethod_clear(void);
 Authmethod *authmethod_get(char *authlist);
 Authmethod *authmethod_lookup(const char *name);
+char *authmethods_get(void);
 
 Authmethod authmethods[] = {
        {"publickey",
@@ -551,6 +552,9 @@ ssh_userauth2(const char *server_user, char *host)
        packet_done();
        debug("got SSH2_MSG_SERVICE_ACCEPT");
 
+       if (options.preferred_authentications == NULL)
+               options.preferred_authentications = authmethods_get();
+
        /* setup authentication context */
        authctxt.agent = ssh_get_authentication_connection();
        authctxt.server_user = server_user;
@@ -561,7 +565,6 @@ ssh_userauth2(const char *server_user, char *host)
        authctxt.authlist = NULL;
        if (authctxt.method == NULL)
                fatal("ssh_userauth2: internal error: cannot send userauth none request");
-       authmethod_clear();
 
        /* initial userauth request */
        userauth_none(&authctxt);
@@ -1106,39 +1109,6 @@ input_userauth_info_req(int type, int plen, void *ctxt)
 
 /* find auth method */
 
-#define        DELIM   ","
-
-static char *def_authlist = "publickey,password";
-static char *authlist_current = NULL;   /* clean copy used for comparison */
-static char *authname_current = NULL;   /* last used auth method */
-static char *authlist_working = NULL;   /* copy that gets modified by strtok_r() */
-static char *authlist_state = NULL;     /* state variable for strtok_r() */
-
-/*
- * Before starting to use a new authentication method list sent by the
- * server, reset internal variables.  This should also be called when
- * finished processing server list to free resources.
- */
-void
-authmethod_clear(void)
-{
-       if (authlist_current != NULL) {
-               xfree(authlist_current);
-               authlist_current = NULL;
-       }
-       if (authlist_working != NULL) {
-               xfree(authlist_working);
-               authlist_working = NULL;
-       }
-       if (authname_current != NULL) {
-               xfree(authname_current);
-               authname_current = NULL;
-       }
-       if (authlist_state != NULL)
-               authlist_state = NULL;
-       return;
-}
-
 /*
  * given auth method name, if configurable options permit this method fill
  * in auth_ident field and return true, otherwise return false.
@@ -1169,62 +1139,70 @@ authmethod_lookup(const char *name)
        return NULL;
 }
 
+/* XXX internal state */
+static Authmethod *current = NULL;
+static char *supported = NULL;
+static char *preferred = NULL;
 /*
  * Given the authentication method list sent by the server, return the
  * next method we should try.  If the server initially sends a nil list,
- * use a built-in default list.  If the server sends a nil list after
- * previously sending a valid list, continue using the list originally
- * sent.
+ * use a built-in default list. 
  */
-
 Authmethod *
 authmethod_get(char *authlist)
 {
-       char *name = NULL, *authname_old;
-       Authmethod *method = NULL;
+
+       char *name = NULL;
+       int next;
 
        /* Use a suitable default if we're passed a nil list.  */
        if (authlist == NULL || strlen(authlist) == 0)
-               authlist = def_authlist;
-
-       if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
-               /* start over if passed a different list */
-               debug3("start over, passed a different list");
-               authmethod_clear();
-               authlist_current = xstrdup(authlist);
-               authlist_working = xstrdup(authlist);
-               name = strtok_r(authlist_working, DELIM, &authlist_state);
-       } else {
-               /*
-                * try to use previously used authentication method
-                * or continue to use previously passed list
-                */
-               name = (authname_current != NULL) ?
-                   authname_current : strtok_r(NULL, DELIM, &authlist_state);
-       }
+               authlist = options.preferred_authentications;
+
+       if (supported == NULL || strcmp(authlist, supported) != 0) {
+               debug3("start over, passed a different list %s", authlist);
+               if (supported != NULL)
+                       xfree(supported);
+               supported = xstrdup(authlist);
+               preferred = options.preferred_authentications;
+               debug3("preferred %s", preferred);
+               current = NULL;
+       } else if (current != NULL && authmethod_is_enabled(current))
+               return current;
 
-       while (name != NULL) {
+       for (;;) {
+               if ((name = match_list(preferred, supported, &next)) == NULL) {
+                       debug("no more auth methods to try");
+                       current = NULL;
+                       return NULL;
+               }
+               preferred += next;
                debug3("authmethod_lookup %s", name);
-               method = authmethod_lookup(name);
-               if (method != NULL && authmethod_is_enabled(method)) {
+               debug3("remaining preferred: %s", preferred);
+               if ((current = authmethod_lookup(name)) != NULL &&
+                   authmethod_is_enabled(current)) {
                        debug3("authmethod_is_enabled %s", name);
-                       break;
+                       debug("next auth method to try is %s", name);
+                       return current;
                }
-               name = strtok_r(NULL, DELIM, &authlist_state);
-               method = NULL;
-       }
-
-       authname_old = authname_current;
-       if (method != NULL) {
-               debug("next auth method to try is %s", name);
-               authname_current = xstrdup(name);
-       } else {
-               debug("no more auth methods to try");
-               authname_current = NULL;
        }
+}
 
-       if (authname_old != NULL)
-               xfree(authname_old);
 
-       return (method);
+#define        DELIM   ","
+char *
+authmethods_get(void)
+{
+       Authmethod *method = NULL;
+       char buf[1024];
+
+       buf[0] = '\0';
+       for (method = authmethods; method->name != NULL; method++) {
+               if (authmethod_is_enabled(method)) {
+                       if (buf[0] != '\0')
+                               strlcat(buf, DELIM, sizeof buf);
+                       strlcat(buf, method->name, sizeof buf);
+               }
+       }
+       return xstrdup(buf);
 }
This page took 0.40711 seconds and 5 git commands to generate.