summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-09-23 17:15:56 +1100
committerDamien Miller <djm@mindrot.org>2000-09-23 17:15:56 +1100
commit62cee00753ef8ce31b322ce6a14318cb974e883d (patch)
tree9a4dedd152d4570a99744eb9f32fe7e70461edfc /sshconnect2.c
parentf056e23dd6f7fad96afb9e0f5a64dce4f6045cc7 (diff)
- (djm) OpenBSD CVS sync:
- markus@cvs.openbsd.org 2000/09/17 09:38:59 [sshconnect2.c sshd.c] fix DEBUG_KEXDH - markus@cvs.openbsd.org 2000/09/17 09:52:51 [sshconnect.c] yes no; ok niels@ - markus@cvs.openbsd.org 2000/09/21 04:55:11 [sshd.8] typo - markus@cvs.openbsd.org 2000/09/21 05:03:54 [serverloop.c] typo - markus@cvs.openbsd.org 2000/09/21 05:11:42 scp.c utime() to utimes(); mouring@pconline.com - markus@cvs.openbsd.org 2000/09/21 05:25:08 sshconnect2.c change login logic in ssh2, allows plugin of other auth methods - markus@cvs.openbsd.org 2000/09/21 05:25:35 [auth2.c channels.c channels.h clientloop.c dispatch.c dispatch.h] [serverloop.c] add context to dispatch_run - markus@cvs.openbsd.org 2000/09/21 05:07:52 authfd.c authfd.h ssh-agent.c bug compat for old ssh.com software
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c450
1 files changed, 326 insertions, 124 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index d225359d0..855833c06 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.18 2000/09/07 20:27:55 deraadt Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.20 2000/09/21 11:25:07 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/rsa.h> 29#include <openssl/rsa.h>
@@ -49,6 +49,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.18 2000/09/07 20:27:55 deraadt Exp $");
49#include "dsa.h" 49#include "dsa.h"
50#include "sshconnect.h" 50#include "sshconnect.h"
51#include "authfile.h" 51#include "authfile.h"
52#include "dispatch.h"
52#include "authfd.h" 53#include "authfd.h"
53 54
54/* import */ 55/* import */
@@ -67,6 +68,9 @@ void
67ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, 68ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
68 Buffer *client_kexinit, Buffer *server_kexinit) 69 Buffer *client_kexinit, Buffer *server_kexinit)
69{ 70{
71#ifdef DEBUG_KEXDH
72 int i;
73#endif
70 int plen, dlen; 74 int plen, dlen;
71 unsigned int klen, kout; 75 unsigned int klen, kout;
72 char *signature = NULL; 76 char *signature = NULL;
@@ -90,11 +94,11 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
90 94
91#ifdef DEBUG_KEXDH 95#ifdef DEBUG_KEXDH
92 fprintf(stderr, "\np= "); 96 fprintf(stderr, "\np= ");
93 bignum_print(dh->p); 97 BN_print_fp(stderr, dh->p);
94 fprintf(stderr, "\ng= "); 98 fprintf(stderr, "\ng= ");
95 bignum_print(dh->g); 99 BN_print_fp(stderr, dh->g);
96 fprintf(stderr, "\npub= "); 100 fprintf(stderr, "\npub= ");
97 bignum_print(dh->pub_key); 101 BN_print_fp(stderr, dh->pub_key);
98 fprintf(stderr, "\n"); 102 fprintf(stderr, "\n");
99 DHparams_print_fp(stderr, dh); 103 DHparams_print_fp(stderr, dh);
100#endif 104#endif
@@ -122,7 +126,7 @@ ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
122 126
123#ifdef DEBUG_KEXDH 127#ifdef DEBUG_KEXDH
124 fprintf(stderr, "\ndh_server_pub= "); 128 fprintf(stderr, "\ndh_server_pub= ");
125 bignum_print(dh_server_pub); 129 BN_print_fp(stderr, dh_server_pub);
126 fprintf(stderr, "\n"); 130 fprintf(stderr, "\n");
127 debug("bits %d", BN_num_bits(dh_server_pub)); 131 debug("bits %d", BN_num_bits(dh_server_pub));
128#endif 132#endif
@@ -253,8 +257,156 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
253/* 257/*
254 * Authenticate user 258 * Authenticate user
255 */ 259 */
260
261typedef struct Authctxt Authctxt;
262typedef struct Authmethod Authmethod;
263
264typedef int sign_cb_fn(
265 Authctxt *authctxt, Key *key,
266 unsigned char **sigp, int *lenp, unsigned char *data, int datalen);
267
268struct Authctxt {
269 const char *server_user;
270 const char *host;
271 const char *service;
272 AuthenticationConnection *agent;
273 int success;
274 Authmethod *method;
275};
276struct Authmethod {
277 char *name; /* string to compare against server's list */
278 int (*userauth)(Authctxt *authctxt);
279 int *enabled; /* flag in option struct that enables method */
280 int *batch_flag; /* flag in option struct that disables method */
281};
282
283void input_userauth_success(int type, int plen, void *ctxt);
284void input_userauth_failure(int type, int plen, void *ctxt);
285void input_userauth_error(int type, int plen, void *ctxt);
286int userauth_pubkey(Authctxt *authctxt);
287int userauth_passwd(Authctxt *authctxt);
288
289void authmethod_clear();
290Authmethod *authmethod_get(char *auth_list);
291
292Authmethod authmethods[] = {
293 {"publickey",
294 userauth_pubkey,
295 &options.dsa_authentication,
296 NULL},
297 {"password",
298 userauth_passwd,
299 &options.password_authentication,
300 &options.batch_mode},
301 {NULL, NULL, NULL, NULL}
302};
303
304void
305ssh_userauth2(const char *server_user, char *host)
306{
307 Authctxt authctxt;
308 int type;
309 int plen;
310
311 debug("send SSH2_MSG_SERVICE_REQUEST");
312 packet_start(SSH2_MSG_SERVICE_REQUEST);
313 packet_put_cstring("ssh-userauth");
314 packet_send();
315 packet_write_wait();
316 type = packet_read(&plen);
317 if (type != SSH2_MSG_SERVICE_ACCEPT) {
318 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
319 }
320 if (packet_remaining() > 0) {
321 char *reply = packet_get_string(&plen);
322 debug("service_accept: %s", reply);
323 xfree(reply);
324 packet_done();
325 } else {
326 debug("buggy server: service_accept w/o service");
327 }
328 packet_done();
329 debug("got SSH2_MSG_SERVICE_ACCEPT");
330
331 /* setup authentication context */
332 authctxt.agent = ssh_get_authentication_connection();
333 authctxt.server_user = server_user;
334 authctxt.host = host;
335 authctxt.service = "ssh-connection"; /* service name */
336 authctxt.success = 0;
337 authctxt.method = NULL;
338
339 /* initial userauth request */
340 packet_start(SSH2_MSG_USERAUTH_REQUEST);
341 packet_put_cstring(authctxt.server_user);
342 packet_put_cstring(authctxt.service);
343 packet_put_cstring("none");
344 packet_send();
345 packet_write_wait();
346
347 authmethod_clear();
348
349 dispatch_init(&input_userauth_error);
350 dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
351 dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
352 dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
353
354 if (authctxt.agent != NULL)
355 ssh_close_authentication_connection(authctxt.agent);
356
357 debug("ssh-userauth2 successfull");
358}
359void
360input_userauth_error(int type, int plen, void *ctxt)
361{
362 fatal("input_userauth_error: bad message during authentication");
363}
364void
365input_userauth_success(int type, int plen, void *ctxt)
366{
367 Authctxt *authctxt = ctxt;
368 if (authctxt == NULL)
369 fatal("input_userauth_success: no authentication context");
370 authctxt->success = 1; /* break out */
371}
372void
373input_userauth_failure(int type, int plen, void *ctxt)
374{
375 Authmethod *method = NULL;
376 Authctxt *authctxt = ctxt;
377 char *authlist = NULL;
378 int partial;
379 int dlen;
380
381 if (authctxt == NULL)
382 fatal("input_userauth_failure: no authentication context");
383
384 authlist = packet_get_string(&dlen);
385 partial = packet_get_char();
386 packet_done();
387
388 if (partial != 0)
389 debug("partial success");
390 debug("authentications that can continue: %s", authlist);
391
392 for (;;) {
393 /* try old method or get next method */
394 method = authmethod_get(authlist);
395 if (method == NULL)
396 fatal("Unable to find an authentication method");
397 if (method->userauth(authctxt) != 0) {
398 debug2("we sent a packet, wait for reply");
399 break;
400 } else {
401 debug2("we did not send a packet, disable method");
402 method->enabled = NULL;
403 }
404 }
405 xfree(authlist);
406}
407
256int 408int
257ssh2_try_passwd(const char *server_user, const char *host, const char *service) 409userauth_passwd(Authctxt *authctxt)
258{ 410{
259 static int attempt = 0; 411 static int attempt = 0;
260 char prompt[80]; 412 char prompt[80];
@@ -267,11 +419,11 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service)
267 error("Permission denied, please try again."); 419 error("Permission denied, please try again.");
268 420
269 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", 421 snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
270 server_user, host); 422 authctxt->server_user, authctxt->host);
271 password = read_passphrase(prompt, 0); 423 password = read_passphrase(prompt, 0);
272 packet_start(SSH2_MSG_USERAUTH_REQUEST); 424 packet_start(SSH2_MSG_USERAUTH_REQUEST);
273 packet_put_cstring(server_user); 425 packet_put_cstring(authctxt->server_user);
274 packet_put_cstring(service); 426 packet_put_cstring(authctxt->service);
275 packet_put_cstring("password"); 427 packet_put_cstring("password");
276 packet_put_char(0); 428 packet_put_char(0);
277 packet_put_cstring(password); 429 packet_put_cstring(password);
@@ -282,14 +434,8 @@ ssh2_try_passwd(const char *server_user, const char *host, const char *service)
282 return 1; 434 return 1;
283} 435}
284 436
285typedef int sign_fn(
286 Key *key,
287 unsigned char **sigp, int *lenp,
288 unsigned char *data, int datalen);
289
290int 437int
291ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign, 438sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
292 const char *server_user, const char *host, const char *service)
293{ 439{
294 Buffer b; 440 Buffer b;
295 unsigned char *blob, *signature; 441 unsigned char *blob, *signature;
@@ -309,18 +455,18 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
309 skip = session_id2_len; 455 skip = session_id2_len;
310 } 456 }
311 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 457 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
312 buffer_put_cstring(&b, server_user); 458 buffer_put_cstring(&b, authctxt->server_user);
313 buffer_put_cstring(&b, 459 buffer_put_cstring(&b,
314 datafellows & SSH_BUG_PUBKEYAUTH ? 460 datafellows & SSH_BUG_PUBKEYAUTH ?
315 "ssh-userauth" : 461 "ssh-userauth" :
316 service); 462 authctxt->service);
317 buffer_put_cstring(&b, "publickey"); 463 buffer_put_cstring(&b, "publickey");
318 buffer_put_char(&b, 1); 464 buffer_put_char(&b, 1);
319 buffer_put_cstring(&b, KEX_DSS); 465 buffer_put_cstring(&b, KEX_DSS);
320 buffer_put_string(&b, blob, bloblen); 466 buffer_put_string(&b, blob, bloblen);
321 467
322 /* generate signature */ 468 /* generate signature */
323 ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); 469 ret = (*sign_callback)(authctxt, k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
324 if (ret == -1) { 470 if (ret == -1) {
325 xfree(blob); 471 xfree(blob);
326 buffer_free(&b); 472 buffer_free(&b);
@@ -333,8 +479,8 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
333 buffer_clear(&b); 479 buffer_clear(&b);
334 buffer_append(&b, session_id2, session_id2_len); 480 buffer_append(&b, session_id2, session_id2_len);
335 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); 481 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
336 buffer_put_cstring(&b, server_user); 482 buffer_put_cstring(&b, authctxt->server_user);
337 buffer_put_cstring(&b, service); 483 buffer_put_cstring(&b, authctxt->service);
338 buffer_put_cstring(&b, "publickey"); 484 buffer_put_cstring(&b, "publickey");
339 buffer_put_char(&b, 1); 485 buffer_put_char(&b, 1);
340 buffer_put_cstring(&b, KEX_DSS); 486 buffer_put_cstring(&b, KEX_DSS);
@@ -347,7 +493,7 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
347 493
348 /* skip session id and packet type */ 494 /* skip session id and packet type */
349 if (buffer_len(&b) < skip + 1) 495 if (buffer_len(&b) < skip + 1)
350 fatal("ssh2_try_pubkey: internal error"); 496 fatal("userauth_pubkey: internal error");
351 buffer_consume(&b, skip + 1); 497 buffer_consume(&b, skip + 1);
352 498
353 /* put remaining data from buffer into packet */ 499 /* put remaining data from buffer into packet */
@@ -362,12 +508,18 @@ ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
362 return 1; 508 return 1;
363} 509}
364 510
511/* sign callback */
512int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
513 unsigned char *data, int datalen)
514{
515 return dsa_sign(key, sigp, lenp, data, datalen);
516}
517
365int 518int
366ssh2_try_pubkey(char *filename, 519userauth_pubkey_identity(Authctxt *authctxt, char *filename)
367 const char *server_user, const char *host, const char *service)
368{ 520{
369 Key *k; 521 Key *k;
370 int ret = 0; 522 int i, ret, try_next;
371 struct stat st; 523 struct stat st;
372 524
373 if (stat(filename, &st) != 0) { 525 if (stat(filename, &st) != 0) {
@@ -384,37 +536,40 @@ ssh2_try_pubkey(char *filename,
384 snprintf(prompt, sizeof prompt, 536 snprintf(prompt, sizeof prompt,
385 "Enter passphrase for DSA key '%.100s': ", 537 "Enter passphrase for DSA key '%.100s': ",
386 filename); 538 filename);
387 passphrase = read_passphrase(prompt, 0); 539 for (i = 0; i < options.number_of_password_prompts; i++) {
388 success = load_private_key(filename, passphrase, k, NULL); 540 passphrase = read_passphrase(prompt, 0);
389 memset(passphrase, 0, strlen(passphrase)); 541 if (strcmp(passphrase, "") != 0) {
390 xfree(passphrase); 542 success = load_private_key(filename, passphrase, k, NULL);
543 try_next = 0;
544 } else {
545 debug2("no passphrase given, try next key");
546 try_next = 1;
547 }
548 memset(passphrase, 0, strlen(passphrase));
549 xfree(passphrase);
550 if (success || try_next)
551 break;
552 debug2("bad passphrase given, try again...");
553 }
391 if (!success) { 554 if (!success) {
392 key_free(k); 555 key_free(k);
393 return 0; 556 return 0;
394 } 557 }
395 } 558 }
396 ret = ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service); 559 ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);
397 key_free(k); 560 key_free(k);
398 return ret; 561 return ret;
399} 562}
400 563
401int agent_sign( 564/* sign callback */
402 Key *key, 565int agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
403 unsigned char **sigp, int *lenp,
404 unsigned char *data, int datalen) 566 unsigned char *data, int datalen)
405{ 567{
406 int ret = -1; 568 return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
407 AuthenticationConnection *ac = ssh_get_authentication_connection();
408 if (ac != NULL) {
409 ret = ssh_agent_sign(ac, key, sigp, lenp, data, datalen);
410 ssh_close_authentication_connection(ac);
411 }
412 return ret;
413} 569}
414 570
415int 571int
416ssh2_try_agent(AuthenticationConnection *ac, 572userauth_pubkey_agent(Authctxt *authctxt)
417 const char *server_user, const char *host, const char *service)
418{ 573{
419 static int called = 0; 574 static int called = 0;
420 char *comment; 575 char *comment;
@@ -422,104 +577,151 @@ ssh2_try_agent(AuthenticationConnection *ac,
422 int ret; 577 int ret;
423 578
424 if (called == 0) { 579 if (called == 0) {
425 k = ssh_get_first_identity(ac, &comment, 2); 580 k = ssh_get_first_identity(authctxt->agent, &comment, 2);
426 called ++; 581 called = 1;
427 } else { 582 } else {
428 k = ssh_get_next_identity(ac, &comment, 2); 583 k = ssh_get_next_identity(authctxt->agent, &comment, 2);
429 } 584 }
430 if (k == NULL) 585 if (k == NULL) {
586 debug2("no more DSA keys from agent");
431 return 0; 587 return 0;
588 }
432 debug("trying DSA agent key %s", comment); 589 debug("trying DSA agent key %s", comment);
433 xfree(comment); 590 xfree(comment);
434 ret = ssh2_sign_and_send_pubkey(k, agent_sign, server_user, host, service); 591 ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
435 key_free(k); 592 key_free(k);
436 return ret; 593 return ret;
437} 594}
438 595
439void 596int
440ssh_userauth2(const char *server_user, char *host) 597userauth_pubkey(Authctxt *authctxt)
441{ 598{
442 AuthenticationConnection *ac = ssh_get_authentication_connection(); 599 static int idx = 0;
443 int type; 600 int sent = 0;
444 int plen; 601
445 int sent; 602 if (authctxt->agent != NULL)
446 unsigned int dlen; 603 sent = userauth_pubkey_agent(authctxt);
447 int partial; 604 while (sent == 0 && idx < options.num_identity_files2)
448 int i = 0; 605 sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);
449 char *auths; 606 return sent;
450 char *service = "ssh-connection"; /* service name */ 607}
451 608
452 debug("send SSH2_MSG_SERVICE_REQUEST");
453 packet_start(SSH2_MSG_SERVICE_REQUEST);
454 packet_put_cstring("ssh-userauth");
455 packet_send();
456 packet_write_wait();
457 609
458 type = packet_read(&plen); 610/* find auth method */
459 if (type != SSH2_MSG_SERVICE_ACCEPT) { 611
460 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); 612#define DELIM ","
613
614static char *def_authlist = "publickey,password";
615static char *authlist_current = NULL; /* clean copy used for comparison */
616static char *authname_current = NULL; /* last used auth method */
617static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */
618static char *authlist_state = NULL; /* state variable for strtok_r() */
619
620/*
621 * Before starting to use a new authentication method list sent by the
622 * server, reset internal variables. This should also be called when
623 * finished processing server list to free resources.
624 */
625void
626authmethod_clear()
627{
628 if (authlist_current != NULL) {
629 xfree(authlist_current);
630 authlist_current = NULL;
461 } 631 }
462 if (packet_remaining() > 0) { 632 if (authlist_working != NULL) {
463 char *reply = packet_get_string(&plen); 633 xfree(authlist_working);
464 debug("service_accept: %s", reply); 634 authlist_working = NULL;
465 xfree(reply);
466 } else {
467 /* payload empty for ssh-2.0.13 ?? */
468 debug("buggy server: service_accept w/o service");
469 } 635 }
470 packet_done(); 636 if (authname_current != NULL) {
471 debug("got SSH2_MSG_SERVICE_ACCEPT"); 637 xfree(authname_current);
638 authlist_state = NULL;
639 }
640 if (authlist_state != NULL)
641 authlist_state = NULL;
642 return;
643}
472 644
473 /* INITIAL request for auth */ 645/*
474 packet_start(SSH2_MSG_USERAUTH_REQUEST); 646 * given auth method name, if configurable options permit this method fill
475 packet_put_cstring(server_user); 647 * in auth_ident field and return true, otherwise return false.
476 packet_put_cstring(service); 648 */
477 packet_put_cstring("none"); 649int
478 packet_send(); 650authmethod_is_enabled(Authmethod *method)
479 packet_write_wait(); 651{
652 if (method == NULL)
653 return 0;
654 /* return false if options indicate this method is disabled */
655 if (method->enabled == NULL || *method->enabled == 0)
656 return 0;
657 /* return false if batch mode is enabled but method needs interactive mode */
658 if (method->batch_flag != NULL && *method->batch_flag != 0)
659 return 0;
660 return 1;
661}
480 662
481 for (;;) { 663Authmethod *
482 sent = 0; 664authmethod_lookup(const char *name)
483 type = packet_read(&plen); 665{
484 if (type == SSH2_MSG_USERAUTH_SUCCESS) 666 Authmethod *method = NULL;
667 if (name != NULL)
668 for (method = authmethods; method->name != NULL; method++)
669 if (strcmp(name, method->name) == 0)
670 return method;
671 debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
672 return NULL;
673}
674
675/*
676 * Given the authentication method list sent by the server, return the
677 * next method we should try. If the server initially sends a nil list,
678 * use a built-in default list. If the server sends a nil list after
679 * previously sending a valid list, continue using the list originally
680 * sent.
681 */
682
683Authmethod *
684authmethod_get(char *authlist)
685{
686 char *name = NULL;
687 Authmethod *method = NULL;
688
689 /* Use a suitable default if we're passed a nil list. */
690 if (authlist == NULL || strlen(authlist) == 0)
691 authlist = def_authlist;
692
693 if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
694 /* start over if passed a different list */
695 authmethod_clear();
696 authlist_current = xstrdup(authlist);
697 authlist_working = xstrdup(authlist);
698 name = strtok_r(authlist_working, DELIM, &authlist_state);
699 } else {
700 /*
701 * try to use previously used authentication method
702 * or continue to use previously passed list
703 */
704 name = (authname_current != NULL) ?
705 authname_current : strtok_r(NULL, DELIM, &authlist_state);
706 }
707
708 while (name != NULL) {
709 method = authmethod_lookup(name);
710 if (method != NULL && authmethod_is_enabled(method))
485 break; 711 break;
486 if (type != SSH2_MSG_USERAUTH_FAILURE) 712 name = strtok_r(NULL, DELIM, &authlist_state);
487 fatal("access denied: %d", type); 713 }
488 /* SSH2_MSG_USERAUTH_FAILURE means: try again */ 714
489 auths = packet_get_string(&dlen); 715 if (authname_current != NULL)
490 debug("authentications that can continue: %s", auths); 716 xfree(authname_current);
491 partial = packet_get_char(); 717
492 packet_done(); 718 if (name != NULL) {
493 if (partial) 719 debug("next auth method to try is %s", name);
494 debug("partial success"); 720 authname_current = xstrdup(name);
495 if (options.dsa_authentication && 721 return method;
496 strstr(auths, "publickey") != NULL) { 722 } else {
497 if (ac != NULL) 723 debug("no more auth methods to try");
498 sent = ssh2_try_agent(ac, 724 authname_current = NULL;
499 server_user, host, service); 725 return NULL;
500 if (!sent) {
501 while (i < options.num_identity_files2) {
502 sent = ssh2_try_pubkey(
503 options.identity_files2[i++],
504 server_user, host, service);
505 if (sent)
506 break;
507 }
508 }
509 }
510 if (!sent) {
511 if (options.password_authentication &&
512 !options.batch_mode &&
513 strstr(auths, "password") != NULL) {
514 sent = ssh2_try_passwd(server_user, host, service);
515 }
516 }
517 if (!sent)
518 fatal("Permission denied (%s).", auths);
519 xfree(auths);
520 } 726 }
521 if (ac != NULL)
522 ssh_close_authentication_connection(ac);
523 packet_done();
524 debug("ssh-userauth2 successfull");
525} 727}