diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-03-11 01:49:19 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-03-11 01:49:19 +0000 |
commit | b9be60a722a8ae24affe68e07ef8557d00992648 (patch) | |
tree | abbd82106ed9c6278bd49e357f74193036241bdd | |
parent | 7f283fcc944a8726ec610d5a11339b28fa75cd94 (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-- | ChangeLog | 6 | ||||
-rw-r--r-- | kex.c | 53 | ||||
-rw-r--r-- | match.c | 69 | ||||
-rw-r--r-- | match.h | 8 | ||||
-rw-r--r-- | readconf.c | 12 | ||||
-rw-r--r-- | readconf.h | 3 | ||||
-rw-r--r-- | sshconnect2.c | 132 |
7 files changed, 155 insertions, 128 deletions
@@ -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 | ||
19 | 20010310 | 23 | 20010310 |
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 $ |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: kex.c,v 1.22 2001/03/05 17:17:20 markus Exp $"); | 26 | RCSID("$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 | |||
380 | char * | ||
381 | get_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 | } | ||
414 | void | 376 | void |
415 | choose_enc(Enc *enc, char *client, char *server) | 377 | choose_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) | |||
428 | void | 390 | void |
429 | choose_mac(Mac *mac, char *client, char *server) | 391 | choose_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) | |||
443 | void | 405 | void |
444 | choose_comp(Comp *comp, char *client, char *server) | 406 | choose_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) | |||
458 | void | 420 | void |
459 | choose_kex(Kex *k, char *client, char *server) | 421 | choose_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) | |||
471 | void | 433 | void |
472 | choose_hostkeyalg(Kex *k, char *client, char *server) | 434 | choose_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 | ||
527 | int | 490 | int |
528 | kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret) | 491 | kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret) |
529 | { | 492 | { |
@@ -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" |
15 | RCSID("$OpenBSD: match.c,v 1.11 2001/01/21 19:05:52 markus Exp $"); | 38 | RCSID("$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 "," | ||
168 | char * | ||
169 | match_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 | } | ||
@@ -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 | */ |
31 | int match_hostname(const char *host, const char *pattern, u_int len); | 31 | int 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 | */ | ||
37 | char *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" |
15 | RCSID("$OpenBSD: readconf.c,v 1.66 2001/03/10 12:53:52 deraadt Exp $"); | 15 | RCSID("$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" |
26 | RCSID("$OpenBSD: sshconnect2.c,v 1.52 2001/03/10 12:48:27 markus Exp $"); | 26 | RCSID("$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 | ||
55 | void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); | 56 | void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); |
56 | void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *); | 57 | void 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); |
499 | void clear_auth_state(Authctxt *authctxt); | 500 | void clear_auth_state(Authctxt *authctxt); |
500 | 501 | ||
501 | void authmethod_clear(void); | ||
502 | Authmethod *authmethod_get(char *authlist); | 502 | Authmethod *authmethod_get(char *authlist); |
503 | Authmethod *authmethod_lookup(const char *name); | 503 | Authmethod *authmethod_lookup(const char *name); |
504 | char *authmethods_get(void); | ||
504 | 505 | ||
505 | Authmethod authmethods[] = { | 506 | Authmethod 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 | |||
1111 | static char *def_authlist = "publickey,password"; | ||
1112 | static char *authlist_current = NULL; /* clean copy used for comparison */ | ||
1113 | static char *authname_current = NULL; /* last used auth method */ | ||
1114 | static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */ | ||
1115 | static 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 | */ | ||
1122 | void | ||
1123 | authmethod_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 */ | ||
1143 | static Authmethod *current = NULL; | ||
1144 | static char *supported = NULL; | ||
1145 | static 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 | |||
1180 | Authmethod * | 1151 | Authmethod * |
1181 | authmethod_get(char *authlist) | 1152 | authmethod_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 "," |
1193 | char * | ||
1194 | authmethods_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 | } |