Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.22
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.22 ! provos 26: RCSID("$OpenBSD: sshconnect2.c,v 1.21 2000/09/27 21:41:34 markus Exp $");
1.1 markus 27:
28: #include <openssl/bn.h>
29: #include <openssl/rsa.h>
30: #include <openssl/dsa.h>
31: #include <openssl/md5.h>
32: #include <openssl/dh.h>
33: #include <openssl/hmac.h>
34:
35: #include "ssh.h"
36: #include "xmalloc.h"
37: #include "rsa.h"
38: #include "buffer.h"
39: #include "packet.h"
40: #include "cipher.h"
41: #include "uidswap.h"
42: #include "compat.h"
43: #include "readconf.h"
44: #include "bufaux.h"
45: #include "ssh2.h"
46: #include "kex.h"
47: #include "myproposal.h"
48: #include "key.h"
49: #include "dsa.h"
50: #include "sshconnect.h"
51: #include "authfile.h"
1.20 markus 52: #include "dispatch.h"
1.17 markus 53: #include "authfd.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:
67: unsigned char *session_id2 = NULL;
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:
! 78: if (options.ciphers != NULL) {
! 79: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
! 80: myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
! 81: } else if (options.cipher == SSH_CIPHER_3DES) {
! 82: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
! 83: myproposal[PROPOSAL_ENC_ALGS_STOC] =
! 84: (char *) cipher_name(SSH_CIPHER_3DES_CBC);
! 85: } else if (options.cipher == SSH_CIPHER_BLOWFISH) {
! 86: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
! 87: myproposal[PROPOSAL_ENC_ALGS_STOC] =
! 88: (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
! 89: }
! 90: if (options.compression) {
! 91: myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
! 92: myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
! 93: } else {
! 94: myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
! 95: myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
! 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
! 152: ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
! 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.1 markus 159: unsigned int klen, kout;
160: char *signature = NULL;
161: unsigned int slen;
162: char *server_host_key_blob = NULL;
163: Key *server_host_key;
164: unsigned int sbloblen;
165: DH *dh;
166: BIGNUM *dh_server_pub = 0;
167: BIGNUM *shared_secret = 0;
168: unsigned char *kbuf;
169: unsigned char *hash;
170:
171: debug("Sending SSH2_MSG_KEXDH_INIT.");
172: /* generate and send 'e', client DH public key */
173: dh = dh_new_group1();
174: packet_start(SSH2_MSG_KEXDH_INIT);
175: packet_put_bignum2(dh->pub_key);
176: packet_send();
177: packet_write_wait();
178:
179: #ifdef DEBUG_KEXDH
180: fprintf(stderr, "\np= ");
1.19 markus 181: BN_print_fp(stderr, dh->p);
1.1 markus 182: fprintf(stderr, "\ng= ");
1.19 markus 183: BN_print_fp(stderr, dh->g);
1.1 markus 184: fprintf(stderr, "\npub= ");
1.19 markus 185: BN_print_fp(stderr, dh->pub_key);
1.1 markus 186: fprintf(stderr, "\n");
187: DHparams_print_fp(stderr, dh);
188: #endif
189:
190: debug("Wait SSH2_MSG_KEXDH_REPLY.");
191:
1.11 markus 192: packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
1.1 markus 193:
194: debug("Got SSH2_MSG_KEXDH_REPLY.");
195:
196: /* key, cert */
197: server_host_key_blob = packet_get_string(&sbloblen);
198: server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
199: if (server_host_key == NULL)
200: fatal("cannot decode server_host_key_blob");
201:
202: check_host_key(host, hostaddr, server_host_key,
1.22 ! provos 203: options.user_hostfile2, options.system_hostfile2);
1.1 markus 204:
205: /* DH paramter f, server public DH key */
206: dh_server_pub = BN_new();
207: if (dh_server_pub == NULL)
208: fatal("dh_server_pub == NULL");
209: packet_get_bignum2(dh_server_pub, &dlen);
210:
211: #ifdef DEBUG_KEXDH
212: fprintf(stderr, "\ndh_server_pub= ");
1.19 markus 213: BN_print_fp(stderr, dh_server_pub);
1.1 markus 214: fprintf(stderr, "\n");
215: debug("bits %d", BN_num_bits(dh_server_pub));
216: #endif
217:
218: /* signed H */
219: signature = packet_get_string(&slen);
220: packet_done();
221:
222: if (!dh_pub_is_valid(dh, dh_server_pub))
223: packet_disconnect("bad server public DH value");
224:
225: klen = DH_size(dh);
226: kbuf = xmalloc(klen);
227: kout = DH_compute_key(kbuf, dh_server_pub, dh);
228: #ifdef DEBUG_KEXDH
229: debug("shared secret: len %d/%d", klen, kout);
230: fprintf(stderr, "shared secret == ");
231: for (i = 0; i< kout; i++)
232: fprintf(stderr, "%02x", (kbuf[i])&0xff);
233: fprintf(stderr, "\n");
234: #endif
235: shared_secret = BN_new();
236:
237: BN_bin2bn(kbuf, kout, shared_secret);
238: memset(kbuf, 0, klen);
239: xfree(kbuf);
240:
241: /* calc and verify H */
242: hash = kex_hash(
243: client_version_string,
244: server_version_string,
245: buffer_ptr(client_kexinit), buffer_len(client_kexinit),
246: buffer_ptr(server_kexinit), buffer_len(server_kexinit),
247: server_host_key_blob, sbloblen,
248: dh->pub_key,
249: dh_server_pub,
250: shared_secret
251: );
1.3 markus 252: xfree(server_host_key_blob);
1.11 markus 253: DH_free(dh);
1.1 markus 254: #ifdef DEBUG_KEXDH
255: fprintf(stderr, "hash == ");
256: for (i = 0; i< 20; i++)
257: fprintf(stderr, "%02x", (hash[i])&0xff);
258: fprintf(stderr, "\n");
259: #endif
260: if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
261: fatal("dsa_verify failed for server_host_key");
262: key_free(server_host_key);
263:
264: kex_derive_keys(kex, hash, shared_secret);
265: packet_set_kex(kex);
266:
267: /* save session id */
268: session_id2_len = 20;
269: session_id2 = xmalloc(session_id2_len);
270: memcpy(session_id2, hash, session_id2_len);
1.11 markus 271: }
272:
1.22 ! provos 273: /* diffie-hellman-group-exchange-sha1 */
! 274:
! 275: /*
! 276: * Estimates the group order for a Diffie-Hellman group that has an
! 277: * attack complexity approximately the same as O(2**bits). Estimate
! 278: * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
! 279: */
! 280:
! 281: int
! 282: dh_estimate(int bits)
! 283: {
! 284:
! 285: if (bits < 64)
! 286: return (512); /* O(2**63) */
! 287: if (bits < 128)
! 288: return (1024); /* O(2**86) */
! 289: if (bits < 192)
! 290: return (2048); /* O(2**116) */
! 291: return (4096); /* O(2**156) */
! 292: }
! 293:
1.11 markus 294: void
1.22 ! provos 295: ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
! 296: Buffer *client_kexinit, Buffer *server_kexinit)
1.11 markus 297: {
1.22 ! provos 298: #ifdef DEBUG_KEXDH
! 299: int i;
! 300: #endif
! 301: int plen, dlen;
! 302: unsigned int klen, kout;
! 303: char *signature = NULL;
! 304: unsigned int slen, nbits;
! 305: char *server_host_key_blob = NULL;
! 306: Key *server_host_key;
! 307: unsigned int sbloblen;
! 308: DH *dh;
! 309: BIGNUM *dh_server_pub = 0;
! 310: BIGNUM *shared_secret = 0;
! 311: BIGNUM *p = 0, *g = 0;
! 312: unsigned char *kbuf;
! 313: unsigned char *hash;
! 314:
! 315: nbits = dh_estimate(kex->enc[MODE_OUT].key_len * 8);
! 316:
! 317: debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
! 318: packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
! 319: packet_put_int(nbits);
! 320: packet_send();
! 321: packet_write_wait();
1.11 markus 322:
1.22 ! provos 323: #ifdef DEBUG_KEXDH
! 324: fprintf(stderr, "\nnbits = %d", nbits);
! 325: #endif
1.11 markus 326:
1.22 ! provos 327: debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
1.11 markus 328:
1.22 ! provos 329: packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
1.11 markus 330:
1.22 ! provos 331: debug("Got SSH2_MSG_KEX_DH_GEX_GROUP.");
1.11 markus 332:
1.22 ! provos 333: if ((p = BN_new()) == NULL)
! 334: fatal("BN_new");
! 335: packet_get_bignum2(p, &dlen);
! 336: if ((g = BN_new()) == NULL)
! 337: fatal("BN_new");
! 338: packet_get_bignum2(g, &dlen);
! 339: if ((dh = dh_new_group(g, p)) == NULL)
! 340: fatal("dh_new_group");
1.1 markus 341:
1.22 ! provos 342: #ifdef DEBUG_KEXDH
! 343: fprintf(stderr, "\np= ");
! 344: BN_print_fp(stderr, dh->p);
! 345: fprintf(stderr, "\ng= ");
! 346: BN_print_fp(stderr, dh->g);
! 347: fprintf(stderr, "\npub= ");
! 348: BN_print_fp(stderr, dh->pub_key);
! 349: fprintf(stderr, "\n");
! 350: DHparams_print_fp(stderr, dh);
! 351: #endif
1.1 markus 352:
1.22 ! provos 353: debug("Sending SSH2_MSG_KEX_DH_GEX_INIT.");
! 354: /* generate and send 'e', client DH public key */
! 355: packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
! 356: packet_put_bignum2(dh->pub_key);
1.1 markus 357: packet_send();
358: packet_write_wait();
359:
1.22 ! provos 360: debug("Wait SSH2_MSG_KEX_DH_GEX_REPLY.");
! 361:
! 362: packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
! 363:
! 364: debug("Got SSH2_MSG_KEXDH_REPLY.");
! 365:
! 366: /* key, cert */
! 367: server_host_key_blob = packet_get_string(&sbloblen);
! 368: server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
! 369: if (server_host_key == NULL)
! 370: fatal("cannot decode server_host_key_blob");
! 371:
! 372: check_host_key(host, hostaddr, server_host_key,
! 373: options.user_hostfile2, options.system_hostfile2);
! 374:
! 375: /* DH paramter f, server public DH key */
! 376: dh_server_pub = BN_new();
! 377: if (dh_server_pub == NULL)
! 378: fatal("dh_server_pub == NULL");
! 379: packet_get_bignum2(dh_server_pub, &dlen);
! 380:
! 381: #ifdef DEBUG_KEXDH
! 382: fprintf(stderr, "\ndh_server_pub= ");
! 383: BN_print_fp(stderr, dh_server_pub);
! 384: fprintf(stderr, "\n");
! 385: debug("bits %d", BN_num_bits(dh_server_pub));
! 386: #endif
! 387:
! 388: /* signed H */
! 389: signature = packet_get_string(&slen);
! 390: packet_done();
! 391:
! 392: if (!dh_pub_is_valid(dh, dh_server_pub))
! 393: packet_disconnect("bad server public DH value");
! 394:
! 395: klen = DH_size(dh);
! 396: kbuf = xmalloc(klen);
! 397: kout = DH_compute_key(kbuf, dh_server_pub, dh);
! 398: #ifdef DEBUG_KEXDH
! 399: debug("shared secret: len %d/%d", klen, kout);
! 400: fprintf(stderr, "shared secret == ");
! 401: for (i = 0; i< kout; i++)
! 402: fprintf(stderr, "%02x", (kbuf[i])&0xff);
! 403: fprintf(stderr, "\n");
! 404: #endif
! 405: shared_secret = BN_new();
! 406:
! 407: BN_bin2bn(kbuf, kout, shared_secret);
! 408: memset(kbuf, 0, klen);
! 409: xfree(kbuf);
! 410:
! 411: /* calc and verify H */
! 412: hash = kex_hash_gex(
! 413: client_version_string,
! 414: server_version_string,
! 415: buffer_ptr(client_kexinit), buffer_len(client_kexinit),
! 416: buffer_ptr(server_kexinit), buffer_len(server_kexinit),
! 417: server_host_key_blob, sbloblen,
! 418: nbits, dh->p, dh->g,
! 419: dh->pub_key,
! 420: dh_server_pub,
! 421: shared_secret
! 422: );
! 423: xfree(server_host_key_blob);
! 424: DH_free(dh);
1.1 markus 425: #ifdef DEBUG_KEXDH
1.22 ! provos 426: fprintf(stderr, "hash == ");
! 427: for (i = 0; i< 20; i++)
! 428: fprintf(stderr, "%02x", (hash[i])&0xff);
! 429: fprintf(stderr, "\n");
1.1 markus 430: #endif
1.22 ! provos 431: if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
! 432: fatal("dsa_verify failed for server_host_key");
! 433: key_free(server_host_key);
! 434:
! 435: kex_derive_keys(kex, hash, shared_secret);
! 436: packet_set_kex(kex);
! 437:
! 438: /* save session id */
! 439: session_id2_len = 20;
! 440: session_id2 = xmalloc(session_id2_len);
! 441: memcpy(session_id2, hash, session_id2_len);
1.1 markus 442: }
1.11 markus 443:
1.1 markus 444: /*
445: * Authenticate user
446: */
1.20 markus 447:
448: typedef struct Authctxt Authctxt;
449: typedef struct Authmethod Authmethod;
450:
451: typedef int sign_cb_fn(
452: Authctxt *authctxt, Key *key,
453: unsigned char **sigp, int *lenp, unsigned char *data, int datalen);
454:
455: struct Authctxt {
456: const char *server_user;
457: const char *host;
458: const char *service;
459: AuthenticationConnection *agent;
460: int success;
461: Authmethod *method;
462: };
463: struct Authmethod {
464: char *name; /* string to compare against server's list */
465: int (*userauth)(Authctxt *authctxt);
466: int *enabled; /* flag in option struct that enables method */
467: int *batch_flag; /* flag in option struct that disables method */
468: };
469:
470: void input_userauth_success(int type, int plen, void *ctxt);
471: void input_userauth_failure(int type, int plen, void *ctxt);
472: void input_userauth_error(int type, int plen, void *ctxt);
473: int userauth_pubkey(Authctxt *authctxt);
474: int userauth_passwd(Authctxt *authctxt);
475:
476: void authmethod_clear();
477: Authmethod *authmethod_get(char *auth_list);
478:
479: Authmethod authmethods[] = {
480: {"publickey",
481: userauth_pubkey,
482: &options.dsa_authentication,
483: NULL},
484: {"password",
485: userauth_passwd,
486: &options.password_authentication,
487: &options.batch_mode},
488: {NULL, NULL, NULL, NULL}
489: };
490:
491: void
492: ssh_userauth2(const char *server_user, char *host)
493: {
494: Authctxt authctxt;
495: int type;
496: int plen;
497:
498: debug("send SSH2_MSG_SERVICE_REQUEST");
499: packet_start(SSH2_MSG_SERVICE_REQUEST);
500: packet_put_cstring("ssh-userauth");
501: packet_send();
502: packet_write_wait();
503: type = packet_read(&plen);
504: if (type != SSH2_MSG_SERVICE_ACCEPT) {
505: fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
506: }
507: if (packet_remaining() > 0) {
508: char *reply = packet_get_string(&plen);
509: debug("service_accept: %s", reply);
510: xfree(reply);
511: packet_done();
512: } else {
513: debug("buggy server: service_accept w/o service");
514: }
515: packet_done();
516: debug("got SSH2_MSG_SERVICE_ACCEPT");
517:
518: /* setup authentication context */
519: authctxt.agent = ssh_get_authentication_connection();
520: authctxt.server_user = server_user;
521: authctxt.host = host;
522: authctxt.service = "ssh-connection"; /* service name */
523: authctxt.success = 0;
524: authctxt.method = NULL;
525:
526: /* initial userauth request */
527: packet_start(SSH2_MSG_USERAUTH_REQUEST);
528: packet_put_cstring(authctxt.server_user);
529: packet_put_cstring(authctxt.service);
530: packet_put_cstring("none");
531: packet_send();
532: packet_write_wait();
533:
534: authmethod_clear();
535:
536: dispatch_init(&input_userauth_error);
537: dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
538: dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
539: dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
540:
541: if (authctxt.agent != NULL)
542: ssh_close_authentication_connection(authctxt.agent);
543:
544: debug("ssh-userauth2 successfull");
545: }
546: void
547: input_userauth_error(int type, int plen, void *ctxt)
548: {
549: fatal("input_userauth_error: bad message during authentication");
550: }
551: void
552: input_userauth_success(int type, int plen, void *ctxt)
553: {
554: Authctxt *authctxt = ctxt;
555: if (authctxt == NULL)
556: fatal("input_userauth_success: no authentication context");
557: authctxt->success = 1; /* break out */
558: }
559: void
560: input_userauth_failure(int type, int plen, void *ctxt)
561: {
562: Authmethod *method = NULL;
563: Authctxt *authctxt = ctxt;
564: char *authlist = NULL;
565: int partial;
566: int dlen;
567:
568: if (authctxt == NULL)
569: fatal("input_userauth_failure: no authentication context");
570:
571: authlist = packet_get_string(&dlen);
572: partial = packet_get_char();
573: packet_done();
574:
575: if (partial != 0)
576: debug("partial success");
577: debug("authentications that can continue: %s", authlist);
578:
579: for (;;) {
580: /* try old method or get next method */
581: method = authmethod_get(authlist);
582: if (method == NULL)
583: fatal("Unable to find an authentication method");
584: if (method->userauth(authctxt) != 0) {
585: debug2("we sent a packet, wait for reply");
586: break;
587: } else {
588: debug2("we did not send a packet, disable method");
589: method->enabled = NULL;
590: }
591: }
592: xfree(authlist);
593: }
594:
1.1 markus 595: int
1.20 markus 596: userauth_passwd(Authctxt *authctxt)
1.1 markus 597: {
1.6 markus 598: static int attempt = 0;
1.1 markus 599: char prompt[80];
600: char *password;
1.6 markus 601:
1.13 todd 602: if (attempt++ >= options.number_of_password_prompts)
1.6 markus 603: return 0;
1.13 todd 604:
605: if(attempt != 1)
606: error("Permission denied, please try again.");
1.1 markus 607:
608: snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
1.20 markus 609: authctxt->server_user, authctxt->host);
1.1 markus 610: password = read_passphrase(prompt, 0);
611: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 612: packet_put_cstring(authctxt->server_user);
613: packet_put_cstring(authctxt->service);
1.1 markus 614: packet_put_cstring("password");
615: packet_put_char(0);
616: packet_put_cstring(password);
617: memset(password, 0, strlen(password));
618: xfree(password);
619: packet_send();
620: packet_write_wait();
621: return 1;
622: }
623:
1.17 markus 624: int
1.20 markus 625: sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
1.1 markus 626: {
627: Buffer b;
628: unsigned char *blob, *signature;
629: int bloblen, slen;
1.14 markus 630: int skip = 0;
1.17 markus 631: int ret = -1;
1.1 markus 632:
633: dsa_make_key_blob(k, &blob, &bloblen);
634:
635: /* data to be signed */
636: buffer_init(&b);
1.14 markus 637: if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
638: buffer_put_string(&b, session_id2, session_id2_len);
639: skip = buffer_len(&b);
640: } else {
641: buffer_append(&b, session_id2, session_id2_len);
642: skip = session_id2_len;
643: }
1.1 markus 644: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 645: buffer_put_cstring(&b, authctxt->server_user);
1.10 markus 646: buffer_put_cstring(&b,
647: datafellows & SSH_BUG_PUBKEYAUTH ?
648: "ssh-userauth" :
1.20 markus 649: authctxt->service);
1.1 markus 650: buffer_put_cstring(&b, "publickey");
651: buffer_put_char(&b, 1);
652: buffer_put_cstring(&b, KEX_DSS);
653: buffer_put_string(&b, blob, bloblen);
654:
655: /* generate signature */
1.20 markus 656: ret = (*sign_callback)(authctxt, k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
1.17 markus 657: if (ret == -1) {
658: xfree(blob);
659: buffer_free(&b);
660: return 0;
661: }
1.1 markus 662: #ifdef DEBUG_DSS
663: buffer_dump(&b);
664: #endif
1.10 markus 665: if (datafellows & SSH_BUG_PUBKEYAUTH) {
666: buffer_clear(&b);
667: buffer_append(&b, session_id2, session_id2_len);
668: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 669: buffer_put_cstring(&b, authctxt->server_user);
670: buffer_put_cstring(&b, authctxt->service);
1.10 markus 671: buffer_put_cstring(&b, "publickey");
672: buffer_put_char(&b, 1);
673: buffer_put_cstring(&b, KEX_DSS);
674: buffer_put_string(&b, blob, bloblen);
675: }
676: xfree(blob);
1.1 markus 677: /* append signature */
678: buffer_put_string(&b, signature, slen);
679: xfree(signature);
680:
681: /* skip session id and packet type */
1.14 markus 682: if (buffer_len(&b) < skip + 1)
1.20 markus 683: fatal("userauth_pubkey: internal error");
1.14 markus 684: buffer_consume(&b, skip + 1);
1.1 markus 685:
686: /* put remaining data from buffer into packet */
687: packet_start(SSH2_MSG_USERAUTH_REQUEST);
688: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
689: buffer_free(&b);
690:
691: /* send */
692: packet_send();
693: packet_write_wait();
1.17 markus 694:
695: return 1;
1.16 markus 696: }
697:
1.20 markus 698: /* sign callback */
699: int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
700: unsigned char *data, int datalen)
701: {
702: return dsa_sign(key, sigp, lenp, data, datalen);
703: }
704:
1.16 markus 705: int
1.20 markus 706: userauth_pubkey_identity(Authctxt *authctxt, char *filename)
1.16 markus 707: {
708: Key *k;
1.20 markus 709: int i, ret, try_next;
1.16 markus 710: struct stat st;
711:
712: if (stat(filename, &st) != 0) {
713: debug("key does not exist: %s", filename);
714: return 0;
715: }
716: debug("try pubkey: %s", filename);
717:
718: k = key_new(KEY_DSA);
719: if (!load_private_key(filename, "", k, NULL)) {
720: int success = 0;
721: char *passphrase;
722: char prompt[300];
723: snprintf(prompt, sizeof prompt,
1.21 markus 724: "Enter passphrase for %s key '%.100s': ",
725: key_type(k), filename);
1.20 markus 726: for (i = 0; i < options.number_of_password_prompts; i++) {
727: passphrase = read_passphrase(prompt, 0);
728: if (strcmp(passphrase, "") != 0) {
729: success = load_private_key(filename, passphrase, k, NULL);
730: try_next = 0;
731: } else {
732: debug2("no passphrase given, try next key");
733: try_next = 1;
734: }
735: memset(passphrase, 0, strlen(passphrase));
736: xfree(passphrase);
737: if (success || try_next)
738: break;
739: debug2("bad passphrase given, try again...");
740: }
1.16 markus 741: if (!success) {
742: key_free(k);
743: return 0;
744: }
745: }
1.20 markus 746: ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);
1.17 markus 747: key_free(k);
748: return ret;
749: }
750:
1.20 markus 751: /* sign callback */
752: int agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
1.17 markus 753: unsigned char *data, int datalen)
754: {
1.20 markus 755: return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
1.17 markus 756: }
757:
758: int
1.20 markus 759: userauth_pubkey_agent(Authctxt *authctxt)
1.17 markus 760: {
761: static int called = 0;
762: char *comment;
763: Key *k;
764: int ret;
765:
766: if (called == 0) {
1.20 markus 767: k = ssh_get_first_identity(authctxt->agent, &comment, 2);
768: called = 1;
1.17 markus 769: } else {
1.20 markus 770: k = ssh_get_next_identity(authctxt->agent, &comment, 2);
1.17 markus 771: }
1.20 markus 772: if (k == NULL) {
773: debug2("no more DSA keys from agent");
1.17 markus 774: return 0;
1.20 markus 775: }
1.17 markus 776: debug("trying DSA agent key %s", comment);
777: xfree(comment);
1.20 markus 778: ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
1.17 markus 779: key_free(k);
780: return ret;
1.1 markus 781: }
782:
1.20 markus 783: int
784: userauth_pubkey(Authctxt *authctxt)
785: {
786: static int idx = 0;
787: int sent = 0;
788:
789: if (authctxt->agent != NULL)
790: sent = userauth_pubkey_agent(authctxt);
791: while (sent == 0 && idx < options.num_identity_files2)
792: sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);
793: return sent;
794: }
795:
796:
797: /* find auth method */
798:
799: #define DELIM ","
800:
801: static char *def_authlist = "publickey,password";
802: static char *authlist_current = NULL; /* clean copy used for comparison */
803: static char *authname_current = NULL; /* last used auth method */
804: static char *authlist_working = NULL; /* copy that gets modified by strtok_r() */
805: static char *authlist_state = NULL; /* state variable for strtok_r() */
806:
807: /*
808: * Before starting to use a new authentication method list sent by the
809: * server, reset internal variables. This should also be called when
810: * finished processing server list to free resources.
811: */
1.1 markus 812: void
1.20 markus 813: authmethod_clear()
814: {
815: if (authlist_current != NULL) {
816: xfree(authlist_current);
817: authlist_current = NULL;
818: }
819: if (authlist_working != NULL) {
820: xfree(authlist_working);
821: authlist_working = NULL;
822: }
823: if (authname_current != NULL) {
824: xfree(authname_current);
825: authlist_state = NULL;
826: }
827: if (authlist_state != NULL)
828: authlist_state = NULL;
829: return;
830: }
831:
832: /*
833: * given auth method name, if configurable options permit this method fill
834: * in auth_ident field and return true, otherwise return false.
835: */
836: int
837: authmethod_is_enabled(Authmethod *method)
838: {
839: if (method == NULL)
840: return 0;
841: /* return false if options indicate this method is disabled */
842: if (method->enabled == NULL || *method->enabled == 0)
843: return 0;
844: /* return false if batch mode is enabled but method needs interactive mode */
845: if (method->batch_flag != NULL && *method->batch_flag != 0)
846: return 0;
847: return 1;
848: }
849:
850: Authmethod *
851: authmethod_lookup(const char *name)
1.1 markus 852: {
1.20 markus 853: Authmethod *method = NULL;
854: if (name != NULL)
855: for (method = authmethods; method->name != NULL; method++)
856: if (strcmp(name, method->name) == 0)
857: return method;
858: debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
859: return NULL;
860: }
1.1 markus 861:
1.20 markus 862: /*
863: * Given the authentication method list sent by the server, return the
864: * next method we should try. If the server initially sends a nil list,
865: * use a built-in default list. If the server sends a nil list after
866: * previously sending a valid list, continue using the list originally
867: * sent.
868: */
1.1 markus 869:
1.20 markus 870: Authmethod *
871: authmethod_get(char *authlist)
872: {
873: char *name = NULL;
874: Authmethod *method = NULL;
875:
876: /* Use a suitable default if we're passed a nil list. */
877: if (authlist == NULL || strlen(authlist) == 0)
878: authlist = def_authlist;
879:
880: if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
881: /* start over if passed a different list */
882: authmethod_clear();
883: authlist_current = xstrdup(authlist);
884: authlist_working = xstrdup(authlist);
885: name = strtok_r(authlist_working, DELIM, &authlist_state);
886: } else {
887: /*
888: * try to use previously used authentication method
889: * or continue to use previously passed list
890: */
891: name = (authname_current != NULL) ?
892: authname_current : strtok_r(NULL, DELIM, &authlist_state);
1.1 markus 893: }
1.20 markus 894:
895: while (name != NULL) {
896: method = authmethod_lookup(name);
897: if (method != NULL && authmethod_is_enabled(method))
898: break;
899: name = strtok_r(NULL, DELIM, &authlist_state);
1.1 markus 900: }
901:
1.20 markus 902: if (authname_current != NULL)
903: xfree(authname_current);
1.1 markus 904:
1.20 markus 905: if (name != NULL) {
906: debug("next auth method to try is %s", name);
907: authname_current = xstrdup(name);
908: return method;
909: } else {
910: debug("no more auth methods to try");
911: authname_current = NULL;
912: return NULL;
1.1 markus 913: }
914: }