Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.51
1.1 markus 1: /*
2: * Copyright (c) 2000 Markus Friedl. All rights reserved.
3: *
4: * Redistribution and use in source and binary forms, with or without
5: * modification, are permitted provided that the following conditions
6: * are met:
7: * 1. Redistributions of source code must retain the above copyright
8: * notice, this list of conditions and the following disclaimer.
9: * 2. Redistributions in binary form must reproduce the above copyright
10: * notice, this list of conditions and the following disclaimer in the
11: * documentation and/or other materials provided with the distribution.
12: *
13: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23: */
24:
25: #include "includes.h"
1.51 ! markus 26: RCSID("$OpenBSD: sshconnect2.c,v 1.50 2001/03/05 17:17:21 markus Exp $");
1.1 markus 27:
28: #include <openssl/bn.h>
29: #include <openssl/md5.h>
30: #include <openssl/dh.h>
31: #include <openssl/hmac.h>
32:
33: #include "ssh.h"
1.37 markus 34: #include "ssh2.h"
1.1 markus 35: #include "xmalloc.h"
36: #include "rsa.h"
37: #include "buffer.h"
38: #include "packet.h"
39: #include "uidswap.h"
40: #include "compat.h"
41: #include "bufaux.h"
1.37 markus 42: #include "cipher.h"
1.1 markus 43: #include "kex.h"
44: #include "myproposal.h"
45: #include "key.h"
46: #include "sshconnect.h"
47: #include "authfile.h"
1.23 markus 48: #include "cli.h"
1.20 markus 49: #include "dispatch.h"
1.17 markus 50: #include "authfd.h"
1.37 markus 51: #include "log.h"
52: #include "readconf.h"
53: #include "readpass.h"
1.1 markus 54:
1.22 provos 55: void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
56: void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
57:
1.1 markus 58: /* import */
59: extern char *client_version_string;
60: extern char *server_version_string;
61: extern Options options;
62:
63: /*
64: * SSH2 key exchange
65: */
66:
1.32 markus 67: u_char *session_id2 = NULL;
1.1 markus 68: int session_id2_len = 0;
69:
70: void
1.22 provos 71: ssh_kex2(char *host, struct sockaddr *hostaddr)
72: {
73: int i, plen;
74: Kex *kex;
75: Buffer *client_kexinit, *server_kexinit;
76: char *sprop[PROPOSAL_MAX];
77:
1.29 markus 78: if (options.ciphers == (char *)-1) {
79: log("No valid ciphers for protocol version 2 given, using defaults.");
80: options.ciphers = NULL;
1.24 markus 81: }
1.22 provos 82: if (options.ciphers != NULL) {
83: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
84: myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
85: }
86: if (options.compression) {
1.47 markus 87: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.22 provos 88: myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
89: } else {
1.47 markus 90: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.22 provos 91: myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
1.47 markus 92: }
93: if (options.macs != NULL) {
94: myproposal[PROPOSAL_MAC_ALGS_CTOS] =
95: myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
1.22 provos 96: }
97:
98: /* buffers with raw kexinit messages */
99: server_kexinit = xmalloc(sizeof(*server_kexinit));
100: buffer_init(server_kexinit);
101: client_kexinit = kex_init(myproposal);
102:
103: /* algorithm negotiation */
104: kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
105: kex = kex_choose_conf(myproposal, sprop, 0);
106: for (i = 0; i < PROPOSAL_MAX; i++)
107: xfree(sprop[i]);
108:
109: /* server authentication and session key agreement */
110: switch(kex->kex_type) {
111: case DH_GRP1_SHA1:
112: ssh_dh1_client(kex, host, hostaddr,
113: client_kexinit, server_kexinit);
114: break;
115: case DH_GEX_SHA1:
116: ssh_dhgex_client(kex, host, hostaddr, client_kexinit,
117: server_kexinit);
118: break;
119: default:
120: fatal("Unsupported key exchange %d", kex->kex_type);
121: }
122:
123: buffer_free(client_kexinit);
124: buffer_free(server_kexinit);
125: xfree(client_kexinit);
126: xfree(server_kexinit);
127:
128: debug("Wait SSH2_MSG_NEWKEYS.");
129: packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
130: packet_done();
131: debug("GOT SSH2_MSG_NEWKEYS.");
132:
133: debug("send SSH2_MSG_NEWKEYS.");
134: packet_start(SSH2_MSG_NEWKEYS);
135: packet_send();
136: packet_write_wait();
137: debug("done: send SSH2_MSG_NEWKEYS.");
138:
139: #ifdef DEBUG_KEXDH
140: /* send 1st encrypted/maced/compressed message */
141: packet_start(SSH2_MSG_IGNORE);
142: packet_put_cstring("markus");
143: packet_send();
144: packet_write_wait();
145: #endif
146: debug("done: KEX2.");
147: }
148:
149: /* diffie-hellman-group1-sha1 */
150:
151: void
1.41 stevesk 152: ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
1.22 provos 153: Buffer *client_kexinit, Buffer *server_kexinit)
1.1 markus 154: {
1.19 markus 155: #ifdef DEBUG_KEXDH
156: int i;
157: #endif
1.11 markus 158: int plen, dlen;
1.32 markus 159: u_int klen, kout;
1.1 markus 160: char *signature = NULL;
1.32 markus 161: u_int slen;
1.1 markus 162: char *server_host_key_blob = NULL;
163: Key *server_host_key;
1.32 markus 164: u_int sbloblen;
1.1 markus 165: DH *dh;
166: BIGNUM *dh_server_pub = 0;
167: BIGNUM *shared_secret = 0;
1.32 markus 168: u_char *kbuf;
169: u_char *hash;
1.1 markus 170:
171: debug("Sending SSH2_MSG_KEXDH_INIT.");
172: /* generate and send 'e', client DH public key */
173: dh = dh_new_group1();
1.50 markus 174: dh_gen_key(dh, kex->we_need * 8);
1.1 markus 175: packet_start(SSH2_MSG_KEXDH_INIT);
176: packet_put_bignum2(dh->pub_key);
177: packet_send();
178: packet_write_wait();
179:
180: #ifdef DEBUG_KEXDH
181: fprintf(stderr, "\np= ");
1.19 markus 182: BN_print_fp(stderr, dh->p);
1.1 markus 183: fprintf(stderr, "\ng= ");
1.19 markus 184: BN_print_fp(stderr, dh->g);
1.1 markus 185: fprintf(stderr, "\npub= ");
1.19 markus 186: BN_print_fp(stderr, dh->pub_key);
1.1 markus 187: fprintf(stderr, "\n");
188: DHparams_print_fp(stderr, dh);
189: #endif
190:
191: debug("Wait SSH2_MSG_KEXDH_REPLY.");
192:
1.11 markus 193: packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
1.1 markus 194:
195: debug("Got SSH2_MSG_KEXDH_REPLY.");
196:
197: /* key, cert */
198: server_host_key_blob = packet_get_string(&sbloblen);
1.28 markus 199: server_host_key = key_from_blob(server_host_key_blob, sbloblen);
1.1 markus 200: if (server_host_key == NULL)
201: fatal("cannot decode server_host_key_blob");
202:
203: check_host_key(host, hostaddr, server_host_key,
1.22 provos 204: options.user_hostfile2, options.system_hostfile2);
1.1 markus 205:
206: /* DH paramter f, server public DH key */
207: dh_server_pub = BN_new();
208: if (dh_server_pub == NULL)
209: fatal("dh_server_pub == NULL");
210: packet_get_bignum2(dh_server_pub, &dlen);
211:
212: #ifdef DEBUG_KEXDH
213: fprintf(stderr, "\ndh_server_pub= ");
1.19 markus 214: BN_print_fp(stderr, dh_server_pub);
1.1 markus 215: fprintf(stderr, "\n");
216: debug("bits %d", BN_num_bits(dh_server_pub));
217: #endif
218:
219: /* signed H */
220: signature = packet_get_string(&slen);
221: packet_done();
222:
223: if (!dh_pub_is_valid(dh, dh_server_pub))
224: packet_disconnect("bad server public DH value");
225:
226: klen = DH_size(dh);
227: kbuf = xmalloc(klen);
228: kout = DH_compute_key(kbuf, dh_server_pub, dh);
229: #ifdef DEBUG_KEXDH
230: debug("shared secret: len %d/%d", klen, kout);
231: fprintf(stderr, "shared secret == ");
232: for (i = 0; i< kout; i++)
233: fprintf(stderr, "%02x", (kbuf[i])&0xff);
234: fprintf(stderr, "\n");
235: #endif
236: shared_secret = BN_new();
237:
238: BN_bin2bn(kbuf, kout, shared_secret);
239: memset(kbuf, 0, klen);
240: xfree(kbuf);
241:
242: /* calc and verify H */
243: hash = kex_hash(
244: client_version_string,
245: server_version_string,
246: buffer_ptr(client_kexinit), buffer_len(client_kexinit),
247: buffer_ptr(server_kexinit), buffer_len(server_kexinit),
248: server_host_key_blob, sbloblen,
249: dh->pub_key,
250: dh_server_pub,
251: shared_secret
252: );
1.3 markus 253: xfree(server_host_key_blob);
1.11 markus 254: DH_free(dh);
1.38 stevesk 255: BN_free(dh_server_pub);
1.1 markus 256: #ifdef DEBUG_KEXDH
257: fprintf(stderr, "hash == ");
258: for (i = 0; i< 20; i++)
259: fprintf(stderr, "%02x", (hash[i])&0xff);
260: fprintf(stderr, "\n");
261: #endif
1.32 markus 262: if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
1.28 markus 263: fatal("key_verify failed for server_host_key");
1.1 markus 264: key_free(server_host_key);
1.38 stevesk 265: xfree(signature);
1.1 markus 266:
267: kex_derive_keys(kex, hash, shared_secret);
1.38 stevesk 268: BN_clear_free(shared_secret);
1.1 markus 269: packet_set_kex(kex);
270:
271: /* save session id */
272: session_id2_len = 20;
273: session_id2 = xmalloc(session_id2_len);
274: memcpy(session_id2, hash, session_id2_len);
1.11 markus 275: }
276:
1.22 provos 277: /* diffie-hellman-group-exchange-sha1 */
278:
279: /*
280: * Estimates the group order for a Diffie-Hellman group that has an
281: * attack complexity approximately the same as O(2**bits). Estimate
282: * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
283: */
284:
285: int
286: dh_estimate(int bits)
287: {
1.41 stevesk 288:
1.22 provos 289: if (bits < 64)
290: return (512); /* O(2**63) */
291: if (bits < 128)
292: return (1024); /* O(2**86) */
293: if (bits < 192)
294: return (2048); /* O(2**116) */
295: return (4096); /* O(2**156) */
296: }
297:
1.11 markus 298: void
1.22 provos 299: ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
300: Buffer *client_kexinit, Buffer *server_kexinit)
1.11 markus 301: {
1.22 provos 302: #ifdef DEBUG_KEXDH
303: int i;
304: #endif
305: int plen, dlen;
1.32 markus 306: u_int klen, kout;
1.22 provos 307: char *signature = NULL;
1.32 markus 308: u_int slen, nbits;
1.22 provos 309: char *server_host_key_blob = NULL;
310: Key *server_host_key;
1.32 markus 311: u_int sbloblen;
1.22 provos 312: DH *dh;
313: BIGNUM *dh_server_pub = 0;
314: BIGNUM *shared_secret = 0;
315: BIGNUM *p = 0, *g = 0;
1.32 markus 316: u_char *kbuf;
317: u_char *hash;
1.22 provos 318:
1.50 markus 319: nbits = dh_estimate(kex->we_need * 8);
1.22 provos 320:
321: debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
322: packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
323: packet_put_int(nbits);
324: packet_send();
325: packet_write_wait();
1.11 markus 326:
1.22 provos 327: #ifdef DEBUG_KEXDH
328: fprintf(stderr, "\nnbits = %d", nbits);
329: #endif
1.11 markus 330:
1.22 provos 331: debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
1.11 markus 332:
1.22 provos 333: packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
1.11 markus 334:
1.22 provos 335: debug("Got SSH2_MSG_KEX_DH_GEX_GROUP.");
1.11 markus 336:
1.22 provos 337: if ((p = BN_new()) == NULL)
338: fatal("BN_new");
339: packet_get_bignum2(p, &dlen);
340: if ((g = BN_new()) == NULL)
341: fatal("BN_new");
342: packet_get_bignum2(g, &dlen);
1.36 stevesk 343: dh = dh_new_group(g, p);
1.31 provos 344:
1.50 markus 345: dh_gen_key(dh, kex->we_need * 8);
1.1 markus 346:
1.22 provos 347: #ifdef DEBUG_KEXDH
348: fprintf(stderr, "\np= ");
349: BN_print_fp(stderr, dh->p);
350: fprintf(stderr, "\ng= ");
351: BN_print_fp(stderr, dh->g);
352: fprintf(stderr, "\npub= ");
353: BN_print_fp(stderr, dh->pub_key);
354: fprintf(stderr, "\n");
355: DHparams_print_fp(stderr, dh);
356: #endif
1.1 markus 357:
1.22 provos 358: debug("Sending SSH2_MSG_KEX_DH_GEX_INIT.");
359: /* generate and send 'e', client DH public key */
360: packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
361: packet_put_bignum2(dh->pub_key);
1.1 markus 362: packet_send();
363: packet_write_wait();
364:
1.22 provos 365: debug("Wait SSH2_MSG_KEX_DH_GEX_REPLY.");
366:
367: packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
368:
369: debug("Got SSH2_MSG_KEXDH_REPLY.");
370:
371: /* key, cert */
372: server_host_key_blob = packet_get_string(&sbloblen);
1.28 markus 373: server_host_key = key_from_blob(server_host_key_blob, sbloblen);
1.22 provos 374: if (server_host_key == NULL)
375: fatal("cannot decode server_host_key_blob");
376:
377: check_host_key(host, hostaddr, server_host_key,
378: options.user_hostfile2, options.system_hostfile2);
379:
380: /* DH paramter f, server public DH key */
381: dh_server_pub = BN_new();
382: if (dh_server_pub == NULL)
383: fatal("dh_server_pub == NULL");
384: packet_get_bignum2(dh_server_pub, &dlen);
385:
386: #ifdef DEBUG_KEXDH
387: fprintf(stderr, "\ndh_server_pub= ");
388: BN_print_fp(stderr, dh_server_pub);
389: fprintf(stderr, "\n");
390: debug("bits %d", BN_num_bits(dh_server_pub));
391: #endif
392:
393: /* signed H */
394: signature = packet_get_string(&slen);
395: packet_done();
396:
397: if (!dh_pub_is_valid(dh, dh_server_pub))
398: packet_disconnect("bad server public DH value");
399:
400: klen = DH_size(dh);
401: kbuf = xmalloc(klen);
402: kout = DH_compute_key(kbuf, dh_server_pub, dh);
403: #ifdef DEBUG_KEXDH
404: debug("shared secret: len %d/%d", klen, kout);
405: fprintf(stderr, "shared secret == ");
406: for (i = 0; i< kout; i++)
407: fprintf(stderr, "%02x", (kbuf[i])&0xff);
408: fprintf(stderr, "\n");
409: #endif
410: shared_secret = BN_new();
411:
412: BN_bin2bn(kbuf, kout, shared_secret);
413: memset(kbuf, 0, klen);
414: xfree(kbuf);
415:
416: /* calc and verify H */
417: hash = kex_hash_gex(
418: client_version_string,
419: server_version_string,
420: buffer_ptr(client_kexinit), buffer_len(client_kexinit),
421: buffer_ptr(server_kexinit), buffer_len(server_kexinit),
422: server_host_key_blob, sbloblen,
1.41 stevesk 423: nbits, dh->p, dh->g,
1.22 provos 424: dh->pub_key,
425: dh_server_pub,
426: shared_secret
427: );
428: xfree(server_host_key_blob);
429: DH_free(dh);
1.38 stevesk 430: BN_free(dh_server_pub);
1.1 markus 431: #ifdef DEBUG_KEXDH
1.22 provos 432: fprintf(stderr, "hash == ");
433: for (i = 0; i< 20; i++)
434: fprintf(stderr, "%02x", (hash[i])&0xff);
435: fprintf(stderr, "\n");
1.1 markus 436: #endif
1.32 markus 437: if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
1.28 markus 438: fatal("key_verify failed for server_host_key");
1.22 provos 439: key_free(server_host_key);
1.38 stevesk 440: xfree(signature);
1.22 provos 441:
442: kex_derive_keys(kex, hash, shared_secret);
1.38 stevesk 443: BN_clear_free(shared_secret);
1.22 provos 444: packet_set_kex(kex);
445:
446: /* save session id */
447: session_id2_len = 20;
448: session_id2 = xmalloc(session_id2_len);
449: memcpy(session_id2, hash, session_id2_len);
1.1 markus 450: }
1.11 markus 451:
1.1 markus 452: /*
453: * Authenticate user
454: */
1.20 markus 455:
456: typedef struct Authctxt Authctxt;
457: typedef struct Authmethod Authmethod;
458:
459: typedef int sign_cb_fn(
460: Authctxt *authctxt, Key *key,
1.32 markus 461: u_char **sigp, int *lenp, u_char *data, int datalen);
1.20 markus 462:
463: struct Authctxt {
464: const char *server_user;
465: const char *host;
466: const char *service;
467: AuthenticationConnection *agent;
1.23 markus 468: Authmethod *method;
1.20 markus 469: int success;
1.51 ! markus 470: char *authlist;
! 471: Key *last_key;
! 472: sign_cb_fn *last_key_sign;
! 473: int last_key_hint;
1.20 markus 474: };
475: struct Authmethod {
476: char *name; /* string to compare against server's list */
477: int (*userauth)(Authctxt *authctxt);
478: int *enabled; /* flag in option struct that enables method */
479: int *batch_flag; /* flag in option struct that disables method */
480: };
481:
482: void input_userauth_success(int type, int plen, void *ctxt);
483: void input_userauth_failure(int type, int plen, void *ctxt);
1.35 markus 484: void input_userauth_banner(int type, int plen, void *ctxt);
1.20 markus 485: void input_userauth_error(int type, int plen, void *ctxt);
1.23 markus 486: void input_userauth_info_req(int type, int plen, void *ctxt);
1.51 ! markus 487: void input_userauth_pk_ok(int type, int plen, void *ctxt);
1.23 markus 488:
489: int userauth_none(Authctxt *authctxt);
1.20 markus 490: int userauth_pubkey(Authctxt *authctxt);
491: int userauth_passwd(Authctxt *authctxt);
1.23 markus 492: int userauth_kbdint(Authctxt *authctxt);
1.20 markus 493:
1.51 ! markus 494: void userauth(Authctxt *authctxt, char *authlist);
! 495:
! 496: int
! 497: sign_and_send_pubkey(Authctxt *authctxt, Key *k,
! 498: sign_cb_fn *sign_callback);
! 499: void clear_auth_state(Authctxt *authctxt);
! 500:
1.33 markus 501: void authmethod_clear(void);
1.23 markus 502: Authmethod *authmethod_get(char *authlist);
503: Authmethod *authmethod_lookup(const char *name);
1.20 markus 504:
505: Authmethod authmethods[] = {
506: {"publickey",
507: userauth_pubkey,
1.28 markus 508: &options.pubkey_authentication,
1.20 markus 509: NULL},
510: {"password",
511: userauth_passwd,
512: &options.password_authentication,
513: &options.batch_mode},
1.23 markus 514: {"keyboard-interactive",
515: userauth_kbdint,
516: &options.kbd_interactive_authentication,
517: &options.batch_mode},
518: {"none",
519: userauth_none,
520: NULL,
521: NULL},
1.20 markus 522: {NULL, NULL, NULL, NULL}
523: };
524:
525: void
526: ssh_userauth2(const char *server_user, char *host)
527: {
528: Authctxt authctxt;
529: int type;
530: int plen;
1.39 markus 531:
532: if (options.challenge_reponse_authentication)
533: options.kbd_interactive_authentication = 1;
1.20 markus 534:
535: debug("send SSH2_MSG_SERVICE_REQUEST");
536: packet_start(SSH2_MSG_SERVICE_REQUEST);
537: packet_put_cstring("ssh-userauth");
538: packet_send();
539: packet_write_wait();
540: type = packet_read(&plen);
541: if (type != SSH2_MSG_SERVICE_ACCEPT) {
542: fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
543: }
544: if (packet_remaining() > 0) {
545: char *reply = packet_get_string(&plen);
546: debug("service_accept: %s", reply);
547: xfree(reply);
548: } else {
549: debug("buggy server: service_accept w/o service");
550: }
551: packet_done();
552: debug("got SSH2_MSG_SERVICE_ACCEPT");
553:
554: /* setup authentication context */
555: authctxt.agent = ssh_get_authentication_connection();
556: authctxt.server_user = server_user;
557: authctxt.host = host;
558: authctxt.service = "ssh-connection"; /* service name */
559: authctxt.success = 0;
1.23 markus 560: authctxt.method = authmethod_lookup("none");
1.51 ! markus 561: authctxt.authlist = NULL;
1.23 markus 562: if (authctxt.method == NULL)
563: fatal("ssh_userauth2: internal error: cannot send userauth none request");
564: authmethod_clear();
1.20 markus 565:
566: /* initial userauth request */
1.23 markus 567: userauth_none(&authctxt);
1.20 markus 568:
569: dispatch_init(&input_userauth_error);
570: dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
571: dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
1.35 markus 572: dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
1.20 markus 573: dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
574:
575: if (authctxt.agent != NULL)
576: ssh_close_authentication_connection(authctxt.agent);
577:
1.34 markus 578: debug("ssh-userauth2 successful: method %s", authctxt.method->name);
1.20 markus 579: }
580: void
1.51 ! markus 581: userauth(Authctxt *authctxt, char *authlist)
! 582: {
! 583: if (authlist == NULL) {
! 584: authlist = authctxt->authlist;
! 585: } else {
! 586: if (authctxt->authlist)
! 587: xfree(authctxt->authlist);
! 588: authctxt->authlist = authlist;
! 589: }
! 590: for (;;) {
! 591: Authmethod *method = authmethod_get(authlist);
! 592: if (method == NULL)
! 593: fatal("Permission denied (%s).", authlist);
! 594: authctxt->method = method;
! 595: if (method->userauth(authctxt) != 0) {
! 596: debug2("we sent a %s packet, wait for reply", method->name);
! 597: break;
! 598: } else {
! 599: debug2("we did not send a packet, disable method");
! 600: method->enabled = NULL;
! 601: }
! 602: }
! 603: }
! 604: void
1.20 markus 605: input_userauth_error(int type, int plen, void *ctxt)
606: {
1.35 markus 607: fatal("input_userauth_error: bad message during authentication: "
608: "type %d", type);
609: }
610: void
611: input_userauth_banner(int type, int plen, void *ctxt)
612: {
613: char *msg, *lang;
614: debug3("input_userauth_banner");
615: msg = packet_get_string(NULL);
616: lang = packet_get_string(NULL);
617: fprintf(stderr, "%s", msg);
618: xfree(msg);
619: xfree(lang);
1.20 markus 620: }
621: void
622: input_userauth_success(int type, int plen, void *ctxt)
623: {
624: Authctxt *authctxt = ctxt;
625: if (authctxt == NULL)
626: fatal("input_userauth_success: no authentication context");
1.51 ! markus 627: if (authctxt->authlist)
! 628: xfree(authctxt->authlist);
! 629: clear_auth_state(authctxt);
1.20 markus 630: authctxt->success = 1; /* break out */
631: }
632: void
633: input_userauth_failure(int type, int plen, void *ctxt)
634: {
635: Authctxt *authctxt = ctxt;
636: char *authlist = NULL;
637: int partial;
638:
639: if (authctxt == NULL)
640: fatal("input_userauth_failure: no authentication context");
641:
1.23 markus 642: authlist = packet_get_string(NULL);
1.20 markus 643: partial = packet_get_char();
644: packet_done();
645:
646: if (partial != 0)
1.45 markus 647: log("Authenticated with partial success.");
1.20 markus 648: debug("authentications that can continue: %s", authlist);
649:
1.51 ! markus 650: clear_auth_state(authctxt);
! 651: userauth(authctxt, authlist);
! 652: }
! 653: void
! 654: input_userauth_pk_ok(int type, int plen, void *ctxt)
! 655: {
! 656: Authctxt *authctxt = ctxt;
! 657: Key *key = NULL;
! 658: Buffer b;
! 659: int alen, blen, pktype, sent = 0;
! 660: char *pkalg, *pkblob;
! 661:
! 662: if (authctxt == NULL)
! 663: fatal("input_userauth_pk_ok: no authentication context");
! 664: if (datafellows & SSH_BUG_PKOK) {
! 665: /* this is similar to SSH_BUG_PKAUTH */
! 666: debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
! 667: pkblob = packet_get_string(&blen);
! 668: buffer_init(&b);
! 669: buffer_append(&b, pkblob, blen);
! 670: pkalg = buffer_get_string(&b, &alen);
! 671: buffer_free(&b);
! 672: } else {
! 673: pkalg = packet_get_string(&alen);
! 674: pkblob = packet_get_string(&blen);
! 675: }
! 676: packet_done();
! 677:
! 678: debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
! 679: pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
! 680:
! 681: do {
! 682: if (authctxt->last_key == NULL ||
! 683: authctxt->last_key_sign == NULL) {
! 684: debug("no last key or no sign cb");
! 685: break;
! 686: }
! 687: debug2("last_key %s", key_fingerprint(authctxt->last_key));
! 688: if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
! 689: debug("unknown pkalg %s", pkalg);
! 690: break;
! 691: }
! 692: if ((key = key_from_blob(pkblob, blen)) == NULL) {
! 693: debug("no key from blob. pkalg %s", pkalg);
! 694: break;
! 695: }
! 696: debug2("input_userauth_pk_ok: fp %s", key_fingerprint(key));
! 697: if (!key_equal(key, authctxt->last_key)) {
! 698: debug("key != last_key");
1.20 markus 699: break;
700: }
1.51 ! markus 701: sent = sign_and_send_pubkey(authctxt, key,
! 702: authctxt->last_key_sign);
! 703: } while(0);
! 704:
! 705: if (key != NULL)
! 706: key_free(key);
! 707: xfree(pkalg);
! 708: xfree(pkblob);
! 709:
! 710: /* unregister */
! 711: clear_auth_state(authctxt);
! 712: dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
! 713:
! 714: /* try another method if we did not send a packet*/
! 715: if (sent == 0)
! 716: userauth(authctxt, NULL);
! 717:
1.20 markus 718: }
719:
1.1 markus 720: int
1.23 markus 721: userauth_none(Authctxt *authctxt)
722: {
723: /* initial userauth request */
724: packet_start(SSH2_MSG_USERAUTH_REQUEST);
725: packet_put_cstring(authctxt->server_user);
726: packet_put_cstring(authctxt->service);
727: packet_put_cstring(authctxt->method->name);
728: packet_send();
729: return 1;
730: }
731:
732: int
1.20 markus 733: userauth_passwd(Authctxt *authctxt)
1.1 markus 734: {
1.6 markus 735: static int attempt = 0;
1.1 markus 736: char prompt[80];
737: char *password;
1.6 markus 738:
1.13 todd 739: if (attempt++ >= options.number_of_password_prompts)
1.6 markus 740: return 0;
1.13 todd 741:
742: if(attempt != 1)
743: error("Permission denied, please try again.");
1.1 markus 744:
1.43 itojun 745: snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1.20 markus 746: authctxt->server_user, authctxt->host);
1.1 markus 747: password = read_passphrase(prompt, 0);
748: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 749: packet_put_cstring(authctxt->server_user);
750: packet_put_cstring(authctxt->service);
1.23 markus 751: packet_put_cstring(authctxt->method->name);
1.1 markus 752: packet_put_char(0);
1.49 markus 753: packet_put_cstring(password);
1.1 markus 754: memset(password, 0, strlen(password));
755: xfree(password);
1.49 markus 756: packet_inject_ignore(64);
1.1 markus 757: packet_send();
758: return 1;
759: }
760:
1.51 ! markus 761: void
! 762: clear_auth_state(Authctxt *authctxt)
! 763: {
! 764: /* XXX clear authentication state */
! 765: if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
! 766: debug3("clear_auth_state: key_free %p", authctxt->last_key);
! 767: key_free(authctxt->last_key);
! 768: }
! 769: authctxt->last_key = NULL;
! 770: authctxt->last_key_hint = -2;
! 771: authctxt->last_key_sign = NULL;
! 772: }
! 773:
1.17 markus 774: int
1.20 markus 775: sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
1.1 markus 776: {
777: Buffer b;
1.32 markus 778: u_char *blob, *signature;
1.1 markus 779: int bloblen, slen;
1.14 markus 780: int skip = 0;
1.17 markus 781: int ret = -1;
1.23 markus 782: int have_sig = 1;
1.1 markus 783:
1.30 markus 784: debug3("sign_and_send_pubkey");
1.51 ! markus 785:
1.28 markus 786: if (key_to_blob(k, &blob, &bloblen) == 0) {
787: /* we cannot handle this key */
1.30 markus 788: debug3("sign_and_send_pubkey: cannot handle key");
1.28 markus 789: return 0;
790: }
1.1 markus 791: /* data to be signed */
792: buffer_init(&b);
1.26 markus 793: if (datafellows & SSH_OLD_SESSIONID) {
794: buffer_append(&b, session_id2, session_id2_len);
1.41 stevesk 795: skip = session_id2_len;
1.26 markus 796: } else {
1.14 markus 797: buffer_put_string(&b, session_id2, session_id2_len);
798: skip = buffer_len(&b);
799: }
1.1 markus 800: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 801: buffer_put_cstring(&b, authctxt->server_user);
1.10 markus 802: buffer_put_cstring(&b,
1.30 markus 803: datafellows & SSH_BUG_PKSERVICE ?
1.10 markus 804: "ssh-userauth" :
1.20 markus 805: authctxt->service);
1.30 markus 806: if (datafellows & SSH_BUG_PKAUTH) {
807: buffer_put_char(&b, have_sig);
808: } else {
809: buffer_put_cstring(&b, authctxt->method->name);
810: buffer_put_char(&b, have_sig);
1.41 stevesk 811: buffer_put_cstring(&b, key_ssh_name(k));
1.30 markus 812: }
1.1 markus 813: buffer_put_string(&b, blob, bloblen);
814:
815: /* generate signature */
1.51 ! markus 816: ret = (*sign_callback)(authctxt, k, &signature, &slen,
! 817: buffer_ptr(&b), buffer_len(&b));
1.17 markus 818: if (ret == -1) {
819: xfree(blob);
820: buffer_free(&b);
821: return 0;
822: }
1.28 markus 823: #ifdef DEBUG_PK
1.1 markus 824: buffer_dump(&b);
825: #endif
1.30 markus 826: if (datafellows & SSH_BUG_PKSERVICE) {
1.10 markus 827: buffer_clear(&b);
828: buffer_append(&b, session_id2, session_id2_len);
1.51 ! markus 829: skip = session_id2_len;
1.10 markus 830: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 831: buffer_put_cstring(&b, authctxt->server_user);
832: buffer_put_cstring(&b, authctxt->service);
1.23 markus 833: buffer_put_cstring(&b, authctxt->method->name);
834: buffer_put_char(&b, have_sig);
1.30 markus 835: if (!(datafellows & SSH_BUG_PKAUTH))
1.41 stevesk 836: buffer_put_cstring(&b, key_ssh_name(k));
1.10 markus 837: buffer_put_string(&b, blob, bloblen);
838: }
839: xfree(blob);
1.51 ! markus 840:
1.1 markus 841: /* append signature */
842: buffer_put_string(&b, signature, slen);
843: xfree(signature);
844:
845: /* skip session id and packet type */
1.14 markus 846: if (buffer_len(&b) < skip + 1)
1.20 markus 847: fatal("userauth_pubkey: internal error");
1.14 markus 848: buffer_consume(&b, skip + 1);
1.1 markus 849:
850: /* put remaining data from buffer into packet */
851: packet_start(SSH2_MSG_USERAUTH_REQUEST);
852: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
853: buffer_free(&b);
854: packet_send();
1.17 markus 855:
856: return 1;
1.16 markus 857: }
858:
1.51 ! markus 859: int
! 860: send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
! 861: int hint)
1.20 markus 862: {
1.51 ! markus 863: u_char *blob;
! 864: int bloblen, have_sig = 0;
1.20 markus 865:
1.51 ! markus 866: debug3("send_pubkey_test");
1.16 markus 867:
1.51 ! markus 868: if (key_to_blob(k, &blob, &bloblen) == 0) {
! 869: /* we cannot handle this key */
! 870: debug3("send_pubkey_test: cannot handle key");
1.16 markus 871: return 0;
872: }
1.51 ! markus 873: /* register callback for USERAUTH_PK_OK message */
! 874: authctxt->last_key_sign = sign_callback;
! 875: authctxt->last_key_hint = hint;
! 876: authctxt->last_key = k;
! 877: dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
! 878:
! 879: packet_start(SSH2_MSG_USERAUTH_REQUEST);
! 880: packet_put_cstring(authctxt->server_user);
! 881: packet_put_cstring(authctxt->service);
! 882: packet_put_cstring(authctxt->method->name);
! 883: packet_put_char(have_sig);
! 884: if (!(datafellows & SSH_BUG_PKAUTH))
! 885: packet_put_cstring(key_ssh_name(k));
! 886: packet_put_string(blob, bloblen);
! 887: xfree(blob);
! 888: packet_send();
! 889: return 1;
! 890: }
! 891:
! 892: Key *
! 893: load_identity_file(char *filename)
! 894: {
! 895: Key *private;
! 896: char prompt[300], *passphrase;
! 897: int success = 0, quit, i;
1.16 markus 898:
1.51 ! markus 899: private = key_new(KEY_UNSPEC);
! 900: if (!load_private_key(filename, "", private, NULL)) {
1.42 markus 901: if (options.batch_mode) {
1.51 ! markus 902: key_free(private);
! 903: return NULL;
1.42 markus 904: }
1.16 markus 905: snprintf(prompt, sizeof prompt,
1.28 markus 906: "Enter passphrase for key '%.100s': ", filename);
1.20 markus 907: for (i = 0; i < options.number_of_password_prompts; i++) {
908: passphrase = read_passphrase(prompt, 0);
909: if (strcmp(passphrase, "") != 0) {
1.51 ! markus 910: success = load_private_key(filename,
! 911: passphrase, private, NULL);
! 912: quit = 0;
1.20 markus 913: } else {
914: debug2("no passphrase given, try next key");
1.51 ! markus 915: quit = 1;
1.20 markus 916: }
917: memset(passphrase, 0, strlen(passphrase));
918: xfree(passphrase);
1.51 ! markus 919: if (success || quit)
1.20 markus 920: break;
921: debug2("bad passphrase given, try again...");
922: }
1.16 markus 923: if (!success) {
1.51 ! markus 924: key_free(private);
! 925: return NULL;
1.16 markus 926: }
927: }
1.51 ! markus 928: return private;
! 929: }
! 930:
! 931: int
! 932: identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
! 933: u_char *data, int datalen)
! 934: {
! 935: Key *private;
! 936: int idx, ret;
! 937:
! 938: idx = authctxt->last_key_hint;
! 939: if (idx < 0)
! 940: return -1;
! 941: private = load_identity_file(options.identity_files[idx]);
! 942: if (private == NULL)
! 943: return -1;
! 944: ret = key_sign(private, sigp, lenp, data, datalen);
! 945: key_free(private);
1.17 markus 946: return ret;
947: }
948:
1.32 markus 949: int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
950: u_char *data, int datalen)
1.17 markus 951: {
1.20 markus 952: return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
1.17 markus 953: }
954:
1.51 ! markus 955: int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
! 956: u_char *data, int datalen)
! 957: {
! 958: return key_sign(key, sigp, lenp, data, datalen);
! 959: }
! 960:
1.17 markus 961: int
1.20 markus 962: userauth_pubkey_agent(Authctxt *authctxt)
1.17 markus 963: {
964: static int called = 0;
1.28 markus 965: int ret = 0;
1.17 markus 966: char *comment;
967: Key *k;
968:
969: if (called == 0) {
1.28 markus 970: if (ssh_get_num_identities(authctxt->agent, 2) == 0)
971: debug2("userauth_pubkey_agent: no keys at all");
1.20 markus 972: called = 1;
1.17 markus 973: }
1.28 markus 974: k = ssh_get_next_identity(authctxt->agent, &comment, 2);
1.20 markus 975: if (k == NULL) {
1.28 markus 976: debug2("userauth_pubkey_agent: no more keys");
977: } else {
1.51 ! markus 978: debug("userauth_pubkey_agent: testing agent key %s", comment);
1.28 markus 979: xfree(comment);
1.51 ! markus 980: ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
! 981: if (ret == 0)
! 982: key_free(k);
1.20 markus 983: }
1.28 markus 984: if (ret == 0)
985: debug2("userauth_pubkey_agent: no message sent");
1.17 markus 986: return ret;
1.1 markus 987: }
988:
1.20 markus 989: int
990: userauth_pubkey(Authctxt *authctxt)
991: {
992: static int idx = 0;
993: int sent = 0;
1.51 ! markus 994: Key *key;
! 995: char *filename;
1.20 markus 996:
1.28 markus 997: if (authctxt->agent != NULL) {
998: do {
999: sent = userauth_pubkey_agent(authctxt);
1000: } while(!sent && authctxt->agent->howmany > 0);
1001: }
1002: while (!sent && idx < options.num_identity_files) {
1.51 ! markus 1003: key = options.identity_keys[idx];
! 1004: filename = options.identity_files[idx];
! 1005: if (key == NULL) {
! 1006: debug("try privkey: %s", filename);
! 1007: key = load_identity_file(filename);
! 1008: if (key != NULL) {
! 1009: sent = sign_and_send_pubkey(authctxt, key,
! 1010: key_sign_cb);
! 1011: key_free(key);
! 1012: }
! 1013: } else if (key->type != KEY_RSA1) {
! 1014: debug("try pubkey: %s", filename);
! 1015: sent = send_pubkey_test(authctxt, key,
! 1016: identity_sign_cb, idx);
! 1017: }
1.28 markus 1018: idx++;
1019: }
1.20 markus 1020: return sent;
1021: }
1022:
1.23 markus 1023: /*
1024: * Send userauth request message specifying keyboard-interactive method.
1025: */
1026: int
1027: userauth_kbdint(Authctxt *authctxt)
1028: {
1029: static int attempt = 0;
1030:
1031: if (attempt++ >= options.number_of_password_prompts)
1032: return 0;
1033:
1034: debug2("userauth_kbdint");
1035: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1036: packet_put_cstring(authctxt->server_user);
1037: packet_put_cstring(authctxt->service);
1038: packet_put_cstring(authctxt->method->name);
1039: packet_put_cstring(""); /* lang */
1040: packet_put_cstring(options.kbd_interactive_devices ?
1041: options.kbd_interactive_devices : "");
1042: packet_send();
1043:
1044: dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
1045: return 1;
1046: }
1047:
1048: /*
1.46 markus 1049: * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1.23 markus 1050: */
1051: void
1052: input_userauth_info_req(int type, int plen, void *ctxt)
1053: {
1054: Authctxt *authctxt = ctxt;
1.46 markus 1055: char *name, *inst, *lang, *prompt, *response;
1.32 markus 1056: u_int num_prompts, i;
1.23 markus 1057: int echo = 0;
1058:
1059: debug2("input_userauth_info_req");
1060:
1061: if (authctxt == NULL)
1062: fatal("input_userauth_info_req: no authentication context");
1063:
1064: name = packet_get_string(NULL);
1065: inst = packet_get_string(NULL);
1066: lang = packet_get_string(NULL);
1067: if (strlen(name) > 0)
1068: cli_mesg(name);
1069: if (strlen(inst) > 0)
1070: cli_mesg(inst);
1.46 markus 1071: xfree(name);
1.23 markus 1072: xfree(inst);
1.46 markus 1073: xfree(lang);
1.23 markus 1074:
1075: num_prompts = packet_get_int();
1076: /*
1077: * Begin to build info response packet based on prompts requested.
1078: * We commit to providing the correct number of responses, so if
1079: * further on we run into a problem that prevents this, we have to
1080: * be sure and clean this up and send a correct error response.
1081: */
1082: packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
1083: packet_put_int(num_prompts);
1084:
1085: for (i = 0; i < num_prompts; i++) {
1086: prompt = packet_get_string(NULL);
1087: echo = packet_get_char();
1088:
1089: response = cli_prompt(prompt, echo);
1090:
1.49 markus 1091: packet_put_cstring(response);
1.23 markus 1092: memset(response, 0, strlen(response));
1093: xfree(response);
1094: xfree(prompt);
1095: }
1096: packet_done(); /* done with parsing incoming message. */
1097:
1.49 markus 1098: packet_inject_ignore(64);
1.23 markus 1099: packet_send();
1100: }
1.20 markus 1101:
1102: /* find auth method */
1103:
1104: #define DELIM ","
1105:
1106: static char *def_authlist = "publickey,password";
1107: static char *authlist_current = NULL; /* clean copy used for comparison */
1108: static char *authname_current = NULL; /* last used auth method */
1109: static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */
1110: static char *authlist_state = NULL; /* state variable for strtok_r() */
1111:
1112: /*
1113: * Before starting to use a new authentication method list sent by the
1114: * server, reset internal variables. This should also be called when
1115: * finished processing server list to free resources.
1116: */
1.1 markus 1117: void
1.33 markus 1118: authmethod_clear(void)
1.20 markus 1119: {
1120: if (authlist_current != NULL) {
1121: xfree(authlist_current);
1122: authlist_current = NULL;
1123: }
1124: if (authlist_working != NULL) {
1125: xfree(authlist_working);
1126: authlist_working = NULL;
1127: }
1128: if (authname_current != NULL) {
1129: xfree(authname_current);
1.44 markus 1130: authname_current = NULL;
1.20 markus 1131: }
1132: if (authlist_state != NULL)
1133: authlist_state = NULL;
1134: return;
1135: }
1136:
1137: /*
1138: * given auth method name, if configurable options permit this method fill
1139: * in auth_ident field and return true, otherwise return false.
1140: */
1141: int
1142: authmethod_is_enabled(Authmethod *method)
1143: {
1144: if (method == NULL)
1145: return 0;
1146: /* return false if options indicate this method is disabled */
1147: if (method->enabled == NULL || *method->enabled == 0)
1148: return 0;
1149: /* return false if batch mode is enabled but method needs interactive mode */
1150: if (method->batch_flag != NULL && *method->batch_flag != 0)
1151: return 0;
1152: return 1;
1153: }
1154:
1155: Authmethod *
1156: authmethod_lookup(const char *name)
1.1 markus 1157: {
1.20 markus 1158: Authmethod *method = NULL;
1159: if (name != NULL)
1160: for (method = authmethods; method->name != NULL; method++)
1161: if (strcmp(name, method->name) == 0)
1162: return method;
1163: debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1164: return NULL;
1165: }
1.1 markus 1166:
1.20 markus 1167: /*
1168: * Given the authentication method list sent by the server, return the
1169: * next method we should try. If the server initially sends a nil list,
1170: * use a built-in default list. If the server sends a nil list after
1171: * previously sending a valid list, continue using the list originally
1172: * sent.
1.41 stevesk 1173: */
1.1 markus 1174:
1.20 markus 1175: Authmethod *
1176: authmethod_get(char *authlist)
1177: {
1.27 provos 1178: char *name = NULL, *authname_old;
1.20 markus 1179: Authmethod *method = NULL;
1.41 stevesk 1180:
1.20 markus 1181: /* Use a suitable default if we're passed a nil list. */
1182: if (authlist == NULL || strlen(authlist) == 0)
1183: authlist = def_authlist;
1184:
1185: if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
1186: /* start over if passed a different list */
1.23 markus 1187: debug3("start over, passed a different list");
1.20 markus 1188: authmethod_clear();
1189: authlist_current = xstrdup(authlist);
1190: authlist_working = xstrdup(authlist);
1191: name = strtok_r(authlist_working, DELIM, &authlist_state);
1192: } else {
1193: /*
1194: * try to use previously used authentication method
1195: * or continue to use previously passed list
1196: */
1197: name = (authname_current != NULL) ?
1198: authname_current : strtok_r(NULL, DELIM, &authlist_state);
1.1 markus 1199: }
1.20 markus 1200:
1201: while (name != NULL) {
1.23 markus 1202: debug3("authmethod_lookup %s", name);
1.20 markus 1203: method = authmethod_lookup(name);
1.23 markus 1204: if (method != NULL && authmethod_is_enabled(method)) {
1205: debug3("authmethod_is_enabled %s", name);
1.20 markus 1206: break;
1.23 markus 1207: }
1.20 markus 1208: name = strtok_r(NULL, DELIM, &authlist_state);
1.23 markus 1209: method = NULL;
1.1 markus 1210: }
1211:
1.27 provos 1212: authname_old = authname_current;
1.23 markus 1213: if (method != NULL) {
1.20 markus 1214: debug("next auth method to try is %s", name);
1215: authname_current = xstrdup(name);
1216: } else {
1217: debug("no more auth methods to try");
1218: authname_current = NULL;
1.1 markus 1219: }
1.27 provos 1220:
1221: if (authname_old != NULL)
1222: xfree(authname_old);
1223:
1224: return (method);
1.1 markus 1225: }