summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-03-11 01:49:19 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-03-11 01:49:19 +0000
commitb9be60a722a8ae24affe68e07ef8557d00992648 (patch)
treeabbd82106ed9c6278bd49e357f74193036241bdd
parent7f283fcc944a8726ec610d5a11339b28fa75cd94 (diff)
- markus@cvs.openbsd.org 2001/03/10 17:51:04
[kex.c match.c match.h readconf.c readconf.h sshconnect2.c] add PreferredAuthentications
-rw-r--r--ChangeLog6
-rw-r--r--kex.c53
-rw-r--r--match.c69
-rw-r--r--match.h8
-rw-r--r--readconf.c12
-rw-r--r--readconf.h3
-rw-r--r--sshconnect2.c132
7 files changed, 155 insertions, 128 deletions
diff --git a/ChangeLog b/ChangeLog
index 9b33999ad..311236139 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,10 @@
15 handle password padding (newer OSU is fixed) 15 handle password padding (newer OSU is fixed)
16 - tim@mindrot.org 2001/03/10 16:33:42 [configure.in Makefile.in sshd_config] 16 - tim@mindrot.org 2001/03/10 16:33:42 [configure.in Makefile.in sshd_config]
17 make sure $bindir is in USER_PATH so scp will work 17 make sure $bindir is in USER_PATH so scp will work
18 - OpenBSD CVS Sync
19 - markus@cvs.openbsd.org 2001/03/10 17:51:04
20 [kex.c match.c match.h readconf.c readconf.h sshconnect2.c]
21 add PreferredAuthentications
18 22
1920010310 2320010310
20 - OpenBSD CVS Sync 24 - OpenBSD CVS Sync
@@ -4486,4 +4490,4 @@
4486 - Wrote replacements for strlcpy and mkdtemp 4490 - Wrote replacements for strlcpy and mkdtemp
4487 - Released 1.0pre1 4491 - Released 1.0pre1
4488 4492
4489$Id: ChangeLog,v 1.938 2001/03/11 00:52:25 tim Exp $ 4493$Id: ChangeLog,v 1.939 2001/03/11 01:49:19 mouring Exp $
diff --git a/kex.c b/kex.c
index 308ffb1b6..78e108e90 100644
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kex.c,v 1.22 2001/03/05 17:17:20 markus Exp $"); 26RCSID("$OpenBSD: kex.c,v 1.23 2001/03/10 17:51:04 markus Exp $");
27 27
28#include <openssl/crypto.h> 28#include <openssl/crypto.h>
29#include <openssl/bio.h> 29#include <openssl/bio.h>
@@ -42,6 +42,7 @@ RCSID("$OpenBSD: kex.c,v 1.22 2001/03/05 17:17:20 markus Exp $");
42#include "key.h" 42#include "key.h"
43#include "log.h" 43#include "log.h"
44#include "mac.h" 44#include "mac.h"
45#include "match.h"
45 46
46#define KEX_COOKIE_LEN 16 47#define KEX_COOKIE_LEN 16
47 48
@@ -372,49 +373,10 @@ derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret)
372 return digest; 373 return digest;
373} 374}
374 375
375#define NKEYS 6
376
377#define MAX_PROP 20
378#define SEP ","
379
380char *
381get_match(char *client, char *server)
382{
383 char *sproposals[MAX_PROP];
384 char *c, *s, *p, *ret, *cp, *sp;
385 int i, j, nproposals;
386
387 c = cp = xstrdup(client);
388 s = sp = xstrdup(server);
389
390 for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
391 (p = strsep(&sp, SEP)), i++) {
392 if (i < MAX_PROP)
393 sproposals[i] = p;
394 else
395 break;
396 }
397 nproposals = i;
398
399 for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
400 (p = strsep(&cp, SEP)), i++) {
401 for (j = 0; j < nproposals; j++) {
402 if (strcmp(p, sproposals[j]) == 0) {
403 ret = xstrdup(p);
404 xfree(c);
405 xfree(s);
406 return ret;
407 }
408 }
409 }
410 xfree(c);
411 xfree(s);
412 return NULL;
413}
414void 376void
415choose_enc(Enc *enc, char *client, char *server) 377choose_enc(Enc *enc, char *client, char *server)
416{ 378{
417 char *name = get_match(client, server); 379 char *name = match_list(client, server, NULL);
418 if (name == NULL) 380 if (name == NULL)
419 fatal("no matching cipher found: client %s server %s", client, server); 381 fatal("no matching cipher found: client %s server %s", client, server);
420 enc->cipher = cipher_by_name(name); 382 enc->cipher = cipher_by_name(name);
@@ -428,7 +390,7 @@ choose_enc(Enc *enc, char *client, char *server)
428void 390void
429choose_mac(Mac *mac, char *client, char *server) 391choose_mac(Mac *mac, char *client, char *server)
430{ 392{
431 char *name = get_match(client, server); 393 char *name = match_list(client, server, NULL);
432 if (name == NULL) 394 if (name == NULL)
433 fatal("no matching mac found: client %s server %s", client, server); 395 fatal("no matching mac found: client %s server %s", client, server);
434 if (mac_init(mac, name) < 0) 396 if (mac_init(mac, name) < 0)
@@ -443,7 +405,7 @@ choose_mac(Mac *mac, char *client, char *server)
443void 405void
444choose_comp(Comp *comp, char *client, char *server) 406choose_comp(Comp *comp, char *client, char *server)
445{ 407{
446 char *name = get_match(client, server); 408 char *name = match_list(client, server, NULL);
447 if (name == NULL) 409 if (name == NULL)
448 fatal("no matching comp found: client %s server %s", client, server); 410 fatal("no matching comp found: client %s server %s", client, server);
449 if (strcmp(name, "zlib") == 0) { 411 if (strcmp(name, "zlib") == 0) {
@@ -458,7 +420,7 @@ choose_comp(Comp *comp, char *client, char *server)
458void 420void
459choose_kex(Kex *k, char *client, char *server) 421choose_kex(Kex *k, char *client, char *server)
460{ 422{
461 k->name = get_match(client, server); 423 k->name = match_list(client, server, NULL);
462 if (k->name == NULL) 424 if (k->name == NULL)
463 fatal("no kex alg"); 425 fatal("no kex alg");
464 if (strcmp(k->name, KEX_DH1) == 0) { 426 if (strcmp(k->name, KEX_DH1) == 0) {
@@ -471,7 +433,7 @@ choose_kex(Kex *k, char *client, char *server)
471void 433void
472choose_hostkeyalg(Kex *k, char *client, char *server) 434choose_hostkeyalg(Kex *k, char *client, char *server)
473{ 435{
474 char *hostkeyalg = get_match(client, server); 436 char *hostkeyalg = match_list(client, server, NULL);
475 if (hostkeyalg == NULL) 437 if (hostkeyalg == NULL)
476 fatal("no hostkey alg"); 438 fatal("no hostkey alg");
477 k->hostkey_type = key_type_from_name(hostkeyalg); 439 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
524 return k; 486 return k;
525} 487}
526 488
489#define NKEYS 6
527int 490int
528kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret) 491kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret)
529{ 492{
diff --git a/match.c b/match.c
index 81030da6a..ebb562ab3 100644
--- a/match.c
+++ b/match.c
@@ -10,11 +10,35 @@
10 * incompatible with the protocol description in the RFC file, it must be 10 * incompatible with the protocol description in the RFC file, it must be
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13/*
14 * Copyright (c) 2000 Markus Friedl. All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
13 36
14#include "includes.h" 37#include "includes.h"
15RCSID("$OpenBSD: match.c,v 1.11 2001/01/21 19:05:52 markus Exp $"); 38RCSID("$OpenBSD: match.c,v 1.12 2001/03/10 17:51:04 markus Exp $");
16 39
17#include "match.h" 40#include "match.h"
41#include "xmalloc.h"
18 42
19/* 43/*
20 * Returns true if the given string matches the pattern (which may contain ? 44 * 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)
137 */ 161 */
138 return got_positive; 162 return got_positive;
139} 163}
164
165
166#define MAX_PROP 20
167#define SEP ","
168char *
169match_list(const char *client, const char *server, u_int *next)
170{
171 char *sproposals[MAX_PROP];
172 char *c, *s, *p, *ret, *cp, *sp;
173 int i, j, nproposals;
174
175 c = cp = xstrdup(client);
176 s = sp = xstrdup(server);
177
178 for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
179 (p = strsep(&sp, SEP)), i++) {
180 if (i < MAX_PROP)
181 sproposals[i] = p;
182 else
183 break;
184 }
185 nproposals = i;
186
187 for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
188 (p = strsep(&cp, SEP)), i++) {
189 for (j = 0; j < nproposals; j++) {
190 if (strcmp(p, sproposals[j]) == 0) {
191 ret = xstrdup(p);
192 if (next != NULL)
193 *next = (cp == NULL) ?
194 strlen(c) : cp - c;
195 xfree(c);
196 xfree(s);
197 return ret;
198 }
199 }
200 }
201 if (next != NULL)
202 *next = strlen(c);
203 xfree(c);
204 xfree(s);
205 return NULL;
206}
diff --git a/match.h b/match.h
index 285ad55f0..09c931168 100644
--- a/match.h
+++ b/match.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: match.h,v 1.6 2001/01/29 01:58:17 niklas Exp $ */ 1/* $OpenBSD: match.h,v 1.7 2001/03/10 17:51:04 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -30,4 +30,10 @@ int match_pattern(const char *s, const char *pattern);
30 */ 30 */
31int match_hostname(const char *host, const char *pattern, u_int len); 31int match_hostname(const char *host, const char *pattern, u_int len);
32 32
33/*
34 * Returns first item from client-list that is also supported by server-list,
35 * caller must xfree() returned string.
36 */
37char *match_list(const char *client, const char *server, u_int *next);
38
33#endif 39#endif
diff --git a/readconf.c b/readconf.c
index 2b2981476..33d40e8c3 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.66 2001/03/10 12:53:52 deraadt Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.67 2001/03/10 17:51:04 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -109,7 +109,8 @@ typedef enum {
109 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, 109 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias 112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
113 oPreferredAuthentications
113} OpCodes; 114} OpCodes;
114 115
115/* Textual representations of the tokens. */ 116/* Textual representations of the tokens. */
@@ -171,6 +172,7 @@ static struct {
171 { "keepalive", oKeepAlives }, 172 { "keepalive", oKeepAlives },
172 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 173 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
173 { "loglevel", oLogLevel }, 174 { "loglevel", oLogLevel },
175 { "preferredauthentications", oPreferredAuthentications },
174 { NULL, 0 } 176 { NULL, 0 }
175}; 177};
176 178
@@ -446,6 +448,10 @@ parse_string:
446 charptr = &options->host_key_alias; 448 charptr = &options->host_key_alias;
447 goto parse_string; 449 goto parse_string;
448 450
451 case oPreferredAuthentications:
452 charptr = &options->preferred_authentications;
453 goto parse_string;
454
449 case oProxyCommand: 455 case oProxyCommand:
450 charptr = &options->proxy_command; 456 charptr = &options->proxy_command;
451 string = xstrdup(""); 457 string = xstrdup("");
@@ -722,6 +728,7 @@ initialize_options(Options * options)
722 options->num_local_forwards = 0; 728 options->num_local_forwards = 0;
723 options->num_remote_forwards = 0; 729 options->num_remote_forwards = 0;
724 options->log_level = (LogLevel) - 1; 730 options->log_level = (LogLevel) - 1;
731 options->preferred_authentications = NULL;
725} 732}
726 733
727/* 734/*
@@ -837,4 +844,5 @@ fill_default_options(Options * options)
837 /* options->user will be set in the main program if appropriate */ 844 /* options->user will be set in the main program if appropriate */
838 /* options->hostname will be set in the main program if appropriate */ 845 /* options->hostname will be set in the main program if appropriate */
839 /* options->host_key_alias should not be set by default */ 846 /* options->host_key_alias should not be set by default */
847 /* options->preferred_authentications will be set in ssh */
840} 848}
diff --git a/readconf.h b/readconf.h
index 97615620e..55babe80e 100644
--- a/readconf.h
+++ b/readconf.h
@@ -11,7 +11,7 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: readconf.h,v 1.27 2001/03/08 21:42:32 markus Exp $"); */ 14/* RCSID("$OpenBSD: readconf.h,v 1.28 2001/03/10 17:51:04 markus Exp $"); */
15 15
16#ifndef READCONF_H 16#ifndef READCONF_H
17#define READCONF_H 17#define READCONF_H
@@ -82,6 +82,7 @@ typedef struct {
82 char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */ 82 char *user_hostfile; /* Path for $HOME/.ssh/known_hosts. */
83 char *system_hostfile2; 83 char *system_hostfile2;
84 char *user_hostfile2; 84 char *user_hostfile2;
85 char *preferred_authentications;
85 86
86 int num_identity_files; /* Number of files for RSA/DSA identities. */ 87 int num_identity_files; /* Number of files for RSA/DSA identities. */
87 char *identity_files[SSH_MAX_IDENTITY_FILES]; 88 char *identity_files[SSH_MAX_IDENTITY_FILES];
diff --git a/sshconnect2.c b/sshconnect2.c
index 646bb18f3..19d079bd3 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.53 2001/03/10 17:51:04 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/md5.h> 29#include <openssl/md5.h>
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $");
51#include "log.h" 51#include "log.h"
52#include "readconf.h" 52#include "readconf.h"
53#include "readpass.h" 53#include "readpass.h"
54#include "match.h"
54 55
55void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); 56void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
56void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); 57void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
@@ -498,9 +499,9 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k,
498 sign_cb_fn *sign_callback); 499 sign_cb_fn *sign_callback);
499void clear_auth_state(Authctxt *authctxt); 500void clear_auth_state(Authctxt *authctxt);
500 501
501void authmethod_clear(void);
502Authmethod *authmethod_get(char *authlist); 502Authmethod *authmethod_get(char *authlist);
503Authmethod *authmethod_lookup(const char *name); 503Authmethod *authmethod_lookup(const char *name);
504char *authmethods_get(void);
504 505
505Authmethod authmethods[] = { 506Authmethod authmethods[] = {
506 {"publickey", 507 {"publickey",
@@ -551,6 +552,9 @@ ssh_userauth2(const char *server_user, char *host)
551 packet_done(); 552 packet_done();
552 debug("got SSH2_MSG_SERVICE_ACCEPT"); 553 debug("got SSH2_MSG_SERVICE_ACCEPT");
553 554
555 if (options.preferred_authentications == NULL)
556 options.preferred_authentications = authmethods_get();
557
554 /* setup authentication context */ 558 /* setup authentication context */
555 authctxt.agent = ssh_get_authentication_connection(); 559 authctxt.agent = ssh_get_authentication_connection();
556 authctxt.server_user = server_user; 560 authctxt.server_user = server_user;
@@ -561,7 +565,6 @@ ssh_userauth2(const char *server_user, char *host)
561 authctxt.authlist = NULL; 565 authctxt.authlist = NULL;
562 if (authctxt.method == NULL) 566 if (authctxt.method == NULL)
563 fatal("ssh_userauth2: internal error: cannot send userauth none request"); 567 fatal("ssh_userauth2: internal error: cannot send userauth none request");
564 authmethod_clear();
565 568
566 /* initial userauth request */ 569 /* initial userauth request */
567 userauth_none(&authctxt); 570 userauth_none(&authctxt);
@@ -1106,39 +1109,6 @@ input_userauth_info_req(int type, int plen, void *ctxt)
1106 1109
1107/* find auth method */ 1110/* find auth method */
1108 1111
1109#define DELIM ","
1110
1111static char *def_authlist = "publickey,password";
1112static char *authlist_current = NULL; /* clean copy used for comparison */
1113static char *authname_current = NULL; /* last used auth method */
1114static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */
1115static char *authlist_state = NULL; /* state variable for strtok_r() */
1116
1117/*
1118 * Before starting to use a new authentication method list sent by the
1119 * server, reset internal variables. This should also be called when
1120 * finished processing server list to free resources.
1121 */
1122void
1123authmethod_clear(void)
1124{
1125 if (authlist_current != NULL) {
1126 xfree(authlist_current);
1127 authlist_current = NULL;
1128 }
1129 if (authlist_working != NULL) {
1130 xfree(authlist_working);
1131 authlist_working = NULL;
1132 }
1133 if (authname_current != NULL) {
1134 xfree(authname_current);
1135 authname_current = NULL;
1136 }
1137 if (authlist_state != NULL)
1138 authlist_state = NULL;
1139 return;
1140}
1141
1142/* 1112/*
1143 * given auth method name, if configurable options permit this method fill 1113 * given auth method name, if configurable options permit this method fill
1144 * in auth_ident field and return true, otherwise return false. 1114 * in auth_ident field and return true, otherwise return false.
@@ -1169,62 +1139,70 @@ authmethod_lookup(const char *name)
1169 return NULL; 1139 return NULL;
1170} 1140}
1171 1141
1142/* XXX internal state */
1143static Authmethod *current = NULL;
1144static char *supported = NULL;
1145static char *preferred = NULL;
1172/* 1146/*
1173 * Given the authentication method list sent by the server, return the 1147 * Given the authentication method list sent by the server, return the
1174 * next method we should try. If the server initially sends a nil list, 1148 * next method we should try. If the server initially sends a nil list,
1175 * use a built-in default list. If the server sends a nil list after 1149 * use a built-in default list.
1176 * previously sending a valid list, continue using the list originally
1177 * sent.
1178 */ 1150 */
1179
1180Authmethod * 1151Authmethod *
1181authmethod_get(char *authlist) 1152authmethod_get(char *authlist)
1182{ 1153{
1183 char *name = NULL, *authname_old; 1154
1184 Authmethod *method = NULL; 1155 char *name = NULL;
1156 int next;
1185 1157
1186 /* Use a suitable default if we're passed a nil list. */ 1158 /* Use a suitable default if we're passed a nil list. */
1187 if (authlist == NULL || strlen(authlist) == 0) 1159 if (authlist == NULL || strlen(authlist) == 0)
1188 authlist = def_authlist; 1160 authlist = options.preferred_authentications;
1189 1161
1190 if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) { 1162 if (supported == NULL || strcmp(authlist, supported) != 0) {
1191 /* start over if passed a different list */ 1163 debug3("start over, passed a different list %s", authlist);
1192 debug3("start over, passed a different list"); 1164 if (supported != NULL)
1193 authmethod_clear(); 1165 xfree(supported);
1194 authlist_current = xstrdup(authlist); 1166 supported = xstrdup(authlist);
1195 authlist_working = xstrdup(authlist); 1167 preferred = options.preferred_authentications;
1196 name = strtok_r(authlist_working, DELIM, &authlist_state); 1168 debug3("preferred %s", preferred);
1197 } else { 1169 current = NULL;
1198 /* 1170 } else if (current != NULL && authmethod_is_enabled(current))
1199 * try to use previously used authentication method 1171 return current;
1200 * or continue to use previously passed list
1201 */
1202 name = (authname_current != NULL) ?
1203 authname_current : strtok_r(NULL, DELIM, &authlist_state);
1204 }
1205 1172
1206 while (name != NULL) { 1173 for (;;) {
1174 if ((name = match_list(preferred, supported, &next)) == NULL) {
1175 debug("no more auth methods to try");
1176 current = NULL;
1177 return NULL;
1178 }
1179 preferred += next;
1207 debug3("authmethod_lookup %s", name); 1180 debug3("authmethod_lookup %s", name);
1208 method = authmethod_lookup(name); 1181 debug3("remaining preferred: %s", preferred);
1209 if (method != NULL && authmethod_is_enabled(method)) { 1182 if ((current = authmethod_lookup(name)) != NULL &&
1183 authmethod_is_enabled(current)) {
1210 debug3("authmethod_is_enabled %s", name); 1184 debug3("authmethod_is_enabled %s", name);
1211 break; 1185 debug("next auth method to try is %s", name);
1186 return current;
1212 } 1187 }
1213 name = strtok_r(NULL, DELIM, &authlist_state);
1214 method = NULL;
1215 }
1216
1217 authname_old = authname_current;
1218 if (method != NULL) {
1219 debug("next auth method to try is %s", name);
1220 authname_current = xstrdup(name);
1221 } else {
1222 debug("no more auth methods to try");
1223 authname_current = NULL;
1224 } 1188 }
1189}
1225 1190
1226 if (authname_old != NULL)
1227 xfree(authname_old);
1228 1191
1229 return (method); 1192#define DELIM ","
1193char *
1194authmethods_get(void)
1195{
1196 Authmethod *method = NULL;
1197 char buf[1024];
1198
1199 buf[0] = '\0';
1200 for (method = authmethods; method->name != NULL; method++) {
1201 if (authmethod_is_enabled(method)) {
1202 if (buf[0] != '\0')
1203 strlcat(buf, DELIM, sizeof buf);
1204 strlcat(buf, method->name, sizeof buf);
1205 }
1206 }
1207 return xstrdup(buf);
1230} 1208}