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