Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.62
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.62 ! markus 26: RCSID("$OpenBSD: sshconnect2.c,v 1.61 2001/04/03 19:53:29 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.57 provos 49: #include "dh.h"
1.17 markus 50: #include "authfd.h"
1.37 markus 51: #include "log.h"
52: #include "readconf.h"
53: #include "readpass.h"
1.53 markus 54: #include "match.h"
1.61 markus 55: #include "dispatch.h"
1.22 provos 56:
1.1 markus 57: /* import */
58: extern char *client_version_string;
59: extern char *server_version_string;
60: extern Options options;
61:
62: /*
63: * SSH2 key exchange
64: */
65:
1.32 markus 66: u_char *session_id2 = NULL;
1.1 markus 67: int session_id2_len = 0;
68:
1.61 markus 69: char *xxx_host;
70: struct sockaddr *xxx_hostaddr;
71:
72: int
73: check_host_key_callback(Key *hostkey)
74: {
75: check_host_key(xxx_host, xxx_hostaddr, hostkey,
76: options.user_hostfile2, options.system_hostfile2);
77: return 0;
78: }
79:
1.1 markus 80: void
1.22 provos 81: ssh_kex2(char *host, struct sockaddr *hostaddr)
82: {
83: Kex *kex;
1.61 markus 84:
85: xxx_host = host;
86: xxx_hostaddr = hostaddr;
1.22 provos 87:
1.29 markus 88: if (options.ciphers == (char *)-1) {
89: log("No valid ciphers for protocol version 2 given, using defaults.");
90: options.ciphers = NULL;
1.24 markus 91: }
1.22 provos 92: if (options.ciphers != NULL) {
93: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
94: myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
95: }
1.60 stevesk 96: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
97: compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
98: myproposal[PROPOSAL_ENC_ALGS_STOC] =
99: compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
1.22 provos 100: if (options.compression) {
1.47 markus 101: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.22 provos 102: myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
103: } else {
1.47 markus 104: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.22 provos 105: myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
1.47 markus 106: }
107: if (options.macs != NULL) {
108: myproposal[PROPOSAL_MAC_ALGS_CTOS] =
109: myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
1.22 provos 110: }
111:
1.61 markus 112: kex = kex_start(myproposal);
113: kex->client_version_string=client_version_string;
114: kex->server_version_string=server_version_string;
115: kex->check_host_key=&check_host_key_callback;
1.22 provos 116:
1.61 markus 117: /* start key exchange */
118: dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
1.62 ! markus 119:
! 120: session_id2 = kex->session_id;
! 121: session_id2_len = kex->session_id_len;
1.22 provos 122:
123: #ifdef DEBUG_KEXDH
124: /* send 1st encrypted/maced/compressed message */
125: packet_start(SSH2_MSG_IGNORE);
126: packet_put_cstring("markus");
127: packet_send();
128: packet_write_wait();
129: #endif
1.61 markus 130: debug("done: ssh_kex2.");
1.1 markus 131: }
1.11 markus 132:
1.1 markus 133: /*
134: * Authenticate user
135: */
1.20 markus 136:
137: typedef struct Authctxt Authctxt;
138: typedef struct Authmethod Authmethod;
139:
140: typedef int sign_cb_fn(
141: Authctxt *authctxt, Key *key,
1.32 markus 142: u_char **sigp, int *lenp, u_char *data, int datalen);
1.20 markus 143:
144: struct Authctxt {
145: const char *server_user;
146: const char *host;
147: const char *service;
148: AuthenticationConnection *agent;
1.23 markus 149: Authmethod *method;
1.20 markus 150: int success;
1.51 markus 151: char *authlist;
152: Key *last_key;
153: sign_cb_fn *last_key_sign;
154: int last_key_hint;
1.20 markus 155: };
156: struct Authmethod {
157: char *name; /* string to compare against server's list */
158: int (*userauth)(Authctxt *authctxt);
159: int *enabled; /* flag in option struct that enables method */
160: int *batch_flag; /* flag in option struct that disables method */
161: };
162:
163: void input_userauth_success(int type, int plen, void *ctxt);
164: void input_userauth_failure(int type, int plen, void *ctxt);
1.35 markus 165: void input_userauth_banner(int type, int plen, void *ctxt);
1.20 markus 166: void input_userauth_error(int type, int plen, void *ctxt);
1.23 markus 167: void input_userauth_info_req(int type, int plen, void *ctxt);
1.51 markus 168: void input_userauth_pk_ok(int type, int plen, void *ctxt);
1.23 markus 169:
170: int userauth_none(Authctxt *authctxt);
1.20 markus 171: int userauth_pubkey(Authctxt *authctxt);
172: int userauth_passwd(Authctxt *authctxt);
1.23 markus 173: int userauth_kbdint(Authctxt *authctxt);
1.20 markus 174:
1.51 markus 175: void userauth(Authctxt *authctxt, char *authlist);
176:
177: int
178: sign_and_send_pubkey(Authctxt *authctxt, Key *k,
179: sign_cb_fn *sign_callback);
180: void clear_auth_state(Authctxt *authctxt);
181:
1.23 markus 182: Authmethod *authmethod_get(char *authlist);
183: Authmethod *authmethod_lookup(const char *name);
1.53 markus 184: char *authmethods_get(void);
1.20 markus 185:
186: Authmethod authmethods[] = {
187: {"publickey",
188: userauth_pubkey,
1.28 markus 189: &options.pubkey_authentication,
1.20 markus 190: NULL},
191: {"password",
192: userauth_passwd,
193: &options.password_authentication,
194: &options.batch_mode},
1.23 markus 195: {"keyboard-interactive",
196: userauth_kbdint,
197: &options.kbd_interactive_authentication,
198: &options.batch_mode},
199: {"none",
200: userauth_none,
201: NULL,
202: NULL},
1.20 markus 203: {NULL, NULL, NULL, NULL}
204: };
205:
206: void
207: ssh_userauth2(const char *server_user, char *host)
208: {
209: Authctxt authctxt;
210: int type;
211: int plen;
1.61 markus 212: int i;
1.39 markus 213:
214: if (options.challenge_reponse_authentication)
215: options.kbd_interactive_authentication = 1;
1.20 markus 216:
217: debug("send SSH2_MSG_SERVICE_REQUEST");
218: packet_start(SSH2_MSG_SERVICE_REQUEST);
219: packet_put_cstring("ssh-userauth");
220: packet_send();
221: packet_write_wait();
222: type = packet_read(&plen);
223: if (type != SSH2_MSG_SERVICE_ACCEPT) {
224: fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
225: }
226: if (packet_remaining() > 0) {
227: char *reply = packet_get_string(&plen);
228: debug("service_accept: %s", reply);
229: xfree(reply);
230: } else {
231: debug("buggy server: service_accept w/o service");
232: }
233: packet_done();
234: debug("got SSH2_MSG_SERVICE_ACCEPT");
235:
1.53 markus 236: if (options.preferred_authentications == NULL)
237: options.preferred_authentications = authmethods_get();
238:
1.20 markus 239: /* setup authentication context */
240: authctxt.agent = ssh_get_authentication_connection();
241: authctxt.server_user = server_user;
242: authctxt.host = host;
243: authctxt.service = "ssh-connection"; /* service name */
244: authctxt.success = 0;
1.23 markus 245: authctxt.method = authmethod_lookup("none");
1.51 markus 246: authctxt.authlist = NULL;
1.23 markus 247: if (authctxt.method == NULL)
248: fatal("ssh_userauth2: internal error: cannot send userauth none request");
1.20 markus 249:
250: /* initial userauth request */
1.23 markus 251: userauth_none(&authctxt);
1.20 markus 252:
1.61 markus 253: //dispatch_init(&input_userauth_error);
254: for (i = 50; i <= 254; i++) {
255: dispatch_set(i, &input_userauth_error);
256: }
1.20 markus 257: dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
258: dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
1.35 markus 259: dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
1.20 markus 260: dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
261:
262: if (authctxt.agent != NULL)
263: ssh_close_authentication_connection(authctxt.agent);
264:
1.34 markus 265: debug("ssh-userauth2 successful: method %s", authctxt.method->name);
1.20 markus 266: }
267: void
1.51 markus 268: userauth(Authctxt *authctxt, char *authlist)
269: {
270: if (authlist == NULL) {
271: authlist = authctxt->authlist;
272: } else {
273: if (authctxt->authlist)
274: xfree(authctxt->authlist);
275: authctxt->authlist = authlist;
276: }
277: for (;;) {
278: Authmethod *method = authmethod_get(authlist);
279: if (method == NULL)
280: fatal("Permission denied (%s).", authlist);
281: authctxt->method = method;
282: if (method->userauth(authctxt) != 0) {
283: debug2("we sent a %s packet, wait for reply", method->name);
284: break;
285: } else {
286: debug2("we did not send a packet, disable method");
287: method->enabled = NULL;
288: }
289: }
290: }
291: void
1.20 markus 292: input_userauth_error(int type, int plen, void *ctxt)
293: {
1.35 markus 294: fatal("input_userauth_error: bad message during authentication: "
295: "type %d", type);
296: }
297: void
298: input_userauth_banner(int type, int plen, void *ctxt)
299: {
300: char *msg, *lang;
301: debug3("input_userauth_banner");
302: msg = packet_get_string(NULL);
303: lang = packet_get_string(NULL);
304: fprintf(stderr, "%s", msg);
305: xfree(msg);
306: xfree(lang);
1.20 markus 307: }
308: void
309: input_userauth_success(int type, int plen, void *ctxt)
310: {
311: Authctxt *authctxt = ctxt;
312: if (authctxt == NULL)
313: fatal("input_userauth_success: no authentication context");
1.51 markus 314: if (authctxt->authlist)
315: xfree(authctxt->authlist);
316: clear_auth_state(authctxt);
1.20 markus 317: authctxt->success = 1; /* break out */
318: }
319: void
320: input_userauth_failure(int type, int plen, void *ctxt)
321: {
322: Authctxt *authctxt = ctxt;
323: char *authlist = NULL;
324: int partial;
325:
326: if (authctxt == NULL)
327: fatal("input_userauth_failure: no authentication context");
328:
1.23 markus 329: authlist = packet_get_string(NULL);
1.20 markus 330: partial = packet_get_char();
331: packet_done();
332:
333: if (partial != 0)
1.45 markus 334: log("Authenticated with partial success.");
1.20 markus 335: debug("authentications that can continue: %s", authlist);
336:
1.51 markus 337: clear_auth_state(authctxt);
338: userauth(authctxt, authlist);
339: }
340: void
341: input_userauth_pk_ok(int type, int plen, void *ctxt)
342: {
343: Authctxt *authctxt = ctxt;
344: Key *key = NULL;
345: Buffer b;
346: int alen, blen, pktype, sent = 0;
1.54 markus 347: char *pkalg, *pkblob, *fp;
1.51 markus 348:
349: if (authctxt == NULL)
350: fatal("input_userauth_pk_ok: no authentication context");
351: if (datafellows & SSH_BUG_PKOK) {
352: /* this is similar to SSH_BUG_PKAUTH */
353: debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
354: pkblob = packet_get_string(&blen);
355: buffer_init(&b);
356: buffer_append(&b, pkblob, blen);
357: pkalg = buffer_get_string(&b, &alen);
358: buffer_free(&b);
359: } else {
360: pkalg = packet_get_string(&alen);
361: pkblob = packet_get_string(&blen);
362: }
363: packet_done();
364:
365: debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
366: pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
367:
368: do {
369: if (authctxt->last_key == NULL ||
370: authctxt->last_key_sign == NULL) {
371: debug("no last key or no sign cb");
372: break;
373: }
374: if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
375: debug("unknown pkalg %s", pkalg);
376: break;
377: }
378: if ((key = key_from_blob(pkblob, blen)) == NULL) {
379: debug("no key from blob. pkalg %s", pkalg);
380: break;
381: }
1.54 markus 382: fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
383: debug2("input_userauth_pk_ok: fp %s", fp);
384: xfree(fp);
1.51 markus 385: if (!key_equal(key, authctxt->last_key)) {
386: debug("key != last_key");
1.20 markus 387: break;
388: }
1.51 markus 389: sent = sign_and_send_pubkey(authctxt, key,
390: authctxt->last_key_sign);
391: } while(0);
392:
393: if (key != NULL)
394: key_free(key);
395: xfree(pkalg);
396: xfree(pkblob);
397:
398: /* unregister */
399: clear_auth_state(authctxt);
400: dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
401:
402: /* try another method if we did not send a packet*/
403: if (sent == 0)
404: userauth(authctxt, NULL);
405:
1.20 markus 406: }
407:
1.1 markus 408: int
1.23 markus 409: userauth_none(Authctxt *authctxt)
410: {
411: /* initial userauth request */
412: packet_start(SSH2_MSG_USERAUTH_REQUEST);
413: packet_put_cstring(authctxt->server_user);
414: packet_put_cstring(authctxt->service);
415: packet_put_cstring(authctxt->method->name);
416: packet_send();
417: return 1;
418: }
419:
420: int
1.20 markus 421: userauth_passwd(Authctxt *authctxt)
1.1 markus 422: {
1.6 markus 423: static int attempt = 0;
1.1 markus 424: char prompt[80];
425: char *password;
1.6 markus 426:
1.13 todd 427: if (attempt++ >= options.number_of_password_prompts)
1.6 markus 428: return 0;
1.13 todd 429:
430: if(attempt != 1)
431: error("Permission denied, please try again.");
1.1 markus 432:
1.43 itojun 433: snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1.20 markus 434: authctxt->server_user, authctxt->host);
1.1 markus 435: password = read_passphrase(prompt, 0);
436: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 437: packet_put_cstring(authctxt->server_user);
438: packet_put_cstring(authctxt->service);
1.23 markus 439: packet_put_cstring(authctxt->method->name);
1.1 markus 440: packet_put_char(0);
1.49 markus 441: packet_put_cstring(password);
1.1 markus 442: memset(password, 0, strlen(password));
443: xfree(password);
1.49 markus 444: packet_inject_ignore(64);
1.1 markus 445: packet_send();
446: return 1;
447: }
448:
1.51 markus 449: void
450: clear_auth_state(Authctxt *authctxt)
451: {
452: /* XXX clear authentication state */
453: if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
454: debug3("clear_auth_state: key_free %p", authctxt->last_key);
455: key_free(authctxt->last_key);
456: }
457: authctxt->last_key = NULL;
458: authctxt->last_key_hint = -2;
459: authctxt->last_key_sign = NULL;
460: }
461:
1.17 markus 462: int
1.20 markus 463: sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
1.1 markus 464: {
465: Buffer b;
1.32 markus 466: u_char *blob, *signature;
1.1 markus 467: int bloblen, slen;
1.14 markus 468: int skip = 0;
1.17 markus 469: int ret = -1;
1.23 markus 470: int have_sig = 1;
1.1 markus 471:
1.30 markus 472: debug3("sign_and_send_pubkey");
1.51 markus 473:
1.28 markus 474: if (key_to_blob(k, &blob, &bloblen) == 0) {
475: /* we cannot handle this key */
1.30 markus 476: debug3("sign_and_send_pubkey: cannot handle key");
1.28 markus 477: return 0;
478: }
1.1 markus 479: /* data to be signed */
480: buffer_init(&b);
1.26 markus 481: if (datafellows & SSH_OLD_SESSIONID) {
482: buffer_append(&b, session_id2, session_id2_len);
1.41 stevesk 483: skip = session_id2_len;
1.26 markus 484: } else {
1.14 markus 485: buffer_put_string(&b, session_id2, session_id2_len);
486: skip = buffer_len(&b);
487: }
1.1 markus 488: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 489: buffer_put_cstring(&b, authctxt->server_user);
1.10 markus 490: buffer_put_cstring(&b,
1.30 markus 491: datafellows & SSH_BUG_PKSERVICE ?
1.10 markus 492: "ssh-userauth" :
1.20 markus 493: authctxt->service);
1.30 markus 494: if (datafellows & SSH_BUG_PKAUTH) {
495: buffer_put_char(&b, have_sig);
496: } else {
497: buffer_put_cstring(&b, authctxt->method->name);
498: buffer_put_char(&b, have_sig);
1.41 stevesk 499: buffer_put_cstring(&b, key_ssh_name(k));
1.30 markus 500: }
1.1 markus 501: buffer_put_string(&b, blob, bloblen);
502:
503: /* generate signature */
1.51 markus 504: ret = (*sign_callback)(authctxt, k, &signature, &slen,
505: buffer_ptr(&b), buffer_len(&b));
1.17 markus 506: if (ret == -1) {
507: xfree(blob);
508: buffer_free(&b);
509: return 0;
510: }
1.28 markus 511: #ifdef DEBUG_PK
1.1 markus 512: buffer_dump(&b);
513: #endif
1.30 markus 514: if (datafellows & SSH_BUG_PKSERVICE) {
1.10 markus 515: buffer_clear(&b);
516: buffer_append(&b, session_id2, session_id2_len);
1.51 markus 517: skip = session_id2_len;
1.10 markus 518: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 519: buffer_put_cstring(&b, authctxt->server_user);
520: buffer_put_cstring(&b, authctxt->service);
1.23 markus 521: buffer_put_cstring(&b, authctxt->method->name);
522: buffer_put_char(&b, have_sig);
1.30 markus 523: if (!(datafellows & SSH_BUG_PKAUTH))
1.41 stevesk 524: buffer_put_cstring(&b, key_ssh_name(k));
1.10 markus 525: buffer_put_string(&b, blob, bloblen);
526: }
527: xfree(blob);
1.51 markus 528:
1.1 markus 529: /* append signature */
530: buffer_put_string(&b, signature, slen);
531: xfree(signature);
532:
533: /* skip session id and packet type */
1.14 markus 534: if (buffer_len(&b) < skip + 1)
1.20 markus 535: fatal("userauth_pubkey: internal error");
1.14 markus 536: buffer_consume(&b, skip + 1);
1.1 markus 537:
538: /* put remaining data from buffer into packet */
539: packet_start(SSH2_MSG_USERAUTH_REQUEST);
540: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
541: buffer_free(&b);
542: packet_send();
1.17 markus 543:
544: return 1;
1.16 markus 545: }
546:
1.51 markus 547: int
548: send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
549: int hint)
1.20 markus 550: {
1.51 markus 551: u_char *blob;
552: int bloblen, have_sig = 0;
1.20 markus 553:
1.51 markus 554: debug3("send_pubkey_test");
1.16 markus 555:
1.51 markus 556: if (key_to_blob(k, &blob, &bloblen) == 0) {
557: /* we cannot handle this key */
558: debug3("send_pubkey_test: cannot handle key");
1.16 markus 559: return 0;
560: }
1.51 markus 561: /* register callback for USERAUTH_PK_OK message */
562: authctxt->last_key_sign = sign_callback;
563: authctxt->last_key_hint = hint;
564: authctxt->last_key = k;
565: dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
566:
567: packet_start(SSH2_MSG_USERAUTH_REQUEST);
568: packet_put_cstring(authctxt->server_user);
569: packet_put_cstring(authctxt->service);
570: packet_put_cstring(authctxt->method->name);
571: packet_put_char(have_sig);
572: if (!(datafellows & SSH_BUG_PKAUTH))
573: packet_put_cstring(key_ssh_name(k));
574: packet_put_string(blob, bloblen);
575: xfree(blob);
576: packet_send();
577: return 1;
578: }
579:
580: Key *
581: load_identity_file(char *filename)
582: {
583: Key *private;
584: char prompt[300], *passphrase;
1.56 markus 585: int quit, i;
1.52 markus 586: struct stat st;
1.16 markus 587:
1.52 markus 588: if (stat(filename, &st) < 0) {
589: debug3("no such identity: %s", filename);
590: return NULL;
591: }
1.56 markus 592: private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
593: if (private == NULL) {
594: if (options.batch_mode)
1.51 markus 595: return NULL;
1.16 markus 596: snprintf(prompt, sizeof prompt,
1.28 markus 597: "Enter passphrase for key '%.100s': ", filename);
1.20 markus 598: for (i = 0; i < options.number_of_password_prompts; i++) {
599: passphrase = read_passphrase(prompt, 0);
600: if (strcmp(passphrase, "") != 0) {
1.56 markus 601: private = key_load_private_type(KEY_UNSPEC, filename,
602: passphrase, NULL);
1.51 markus 603: quit = 0;
1.20 markus 604: } else {
605: debug2("no passphrase given, try next key");
1.51 markus 606: quit = 1;
1.20 markus 607: }
608: memset(passphrase, 0, strlen(passphrase));
609: xfree(passphrase);
1.56 markus 610: if (private != NULL || quit)
1.20 markus 611: break;
612: debug2("bad passphrase given, try again...");
1.16 markus 613: }
614: }
1.51 markus 615: return private;
616: }
617:
618: int
619: identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
620: u_char *data, int datalen)
621: {
622: Key *private;
623: int idx, ret;
624:
625: idx = authctxt->last_key_hint;
626: if (idx < 0)
627: return -1;
628: private = load_identity_file(options.identity_files[idx]);
629: if (private == NULL)
630: return -1;
631: ret = key_sign(private, sigp, lenp, data, datalen);
632: key_free(private);
1.17 markus 633: return ret;
634: }
635:
1.32 markus 636: int agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
637: u_char *data, int datalen)
1.17 markus 638: {
1.20 markus 639: return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
1.17 markus 640: }
641:
1.51 markus 642: int key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
643: u_char *data, int datalen)
644: {
645: return key_sign(key, sigp, lenp, data, datalen);
646: }
647:
1.17 markus 648: int
1.20 markus 649: userauth_pubkey_agent(Authctxt *authctxt)
1.17 markus 650: {
651: static int called = 0;
1.28 markus 652: int ret = 0;
1.17 markus 653: char *comment;
654: Key *k;
655:
656: if (called == 0) {
1.28 markus 657: if (ssh_get_num_identities(authctxt->agent, 2) == 0)
658: debug2("userauth_pubkey_agent: no keys at all");
1.20 markus 659: called = 1;
1.17 markus 660: }
1.28 markus 661: k = ssh_get_next_identity(authctxt->agent, &comment, 2);
1.20 markus 662: if (k == NULL) {
1.28 markus 663: debug2("userauth_pubkey_agent: no more keys");
664: } else {
1.51 markus 665: debug("userauth_pubkey_agent: testing agent key %s", comment);
1.28 markus 666: xfree(comment);
1.51 markus 667: ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
668: if (ret == 0)
669: key_free(k);
1.20 markus 670: }
1.28 markus 671: if (ret == 0)
672: debug2("userauth_pubkey_agent: no message sent");
1.17 markus 673: return ret;
1.1 markus 674: }
675:
1.20 markus 676: int
677: userauth_pubkey(Authctxt *authctxt)
678: {
679: static int idx = 0;
680: int sent = 0;
1.51 markus 681: Key *key;
682: char *filename;
1.20 markus 683:
1.28 markus 684: if (authctxt->agent != NULL) {
685: do {
686: sent = userauth_pubkey_agent(authctxt);
687: } while(!sent && authctxt->agent->howmany > 0);
688: }
689: while (!sent && idx < options.num_identity_files) {
1.51 markus 690: key = options.identity_keys[idx];
691: filename = options.identity_files[idx];
692: if (key == NULL) {
693: debug("try privkey: %s", filename);
694: key = load_identity_file(filename);
695: if (key != NULL) {
696: sent = sign_and_send_pubkey(authctxt, key,
697: key_sign_cb);
698: key_free(key);
699: }
700: } else if (key->type != KEY_RSA1) {
701: debug("try pubkey: %s", filename);
702: sent = send_pubkey_test(authctxt, key,
703: identity_sign_cb, idx);
704: }
1.28 markus 705: idx++;
706: }
1.20 markus 707: return sent;
708: }
709:
1.23 markus 710: /*
711: * Send userauth request message specifying keyboard-interactive method.
712: */
713: int
714: userauth_kbdint(Authctxt *authctxt)
715: {
716: static int attempt = 0;
717:
718: if (attempt++ >= options.number_of_password_prompts)
719: return 0;
720:
721: debug2("userauth_kbdint");
722: packet_start(SSH2_MSG_USERAUTH_REQUEST);
723: packet_put_cstring(authctxt->server_user);
724: packet_put_cstring(authctxt->service);
725: packet_put_cstring(authctxt->method->name);
726: packet_put_cstring(""); /* lang */
727: packet_put_cstring(options.kbd_interactive_devices ?
728: options.kbd_interactive_devices : "");
729: packet_send();
730:
731: dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
732: return 1;
733: }
734:
735: /*
1.46 markus 736: * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1.23 markus 737: */
738: void
739: input_userauth_info_req(int type, int plen, void *ctxt)
740: {
741: Authctxt *authctxt = ctxt;
1.46 markus 742: char *name, *inst, *lang, *prompt, *response;
1.32 markus 743: u_int num_prompts, i;
1.23 markus 744: int echo = 0;
745:
746: debug2("input_userauth_info_req");
747:
748: if (authctxt == NULL)
749: fatal("input_userauth_info_req: no authentication context");
750:
751: name = packet_get_string(NULL);
752: inst = packet_get_string(NULL);
753: lang = packet_get_string(NULL);
754: if (strlen(name) > 0)
755: cli_mesg(name);
756: if (strlen(inst) > 0)
757: cli_mesg(inst);
1.46 markus 758: xfree(name);
1.23 markus 759: xfree(inst);
1.46 markus 760: xfree(lang);
1.23 markus 761:
762: num_prompts = packet_get_int();
763: /*
764: * Begin to build info response packet based on prompts requested.
765: * We commit to providing the correct number of responses, so if
766: * further on we run into a problem that prevents this, we have to
767: * be sure and clean this up and send a correct error response.
768: */
769: packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
770: packet_put_int(num_prompts);
771:
772: for (i = 0; i < num_prompts; i++) {
773: prompt = packet_get_string(NULL);
774: echo = packet_get_char();
775:
776: response = cli_prompt(prompt, echo);
777:
1.49 markus 778: packet_put_cstring(response);
1.23 markus 779: memset(response, 0, strlen(response));
780: xfree(response);
781: xfree(prompt);
782: }
783: packet_done(); /* done with parsing incoming message. */
784:
1.49 markus 785: packet_inject_ignore(64);
1.23 markus 786: packet_send();
787: }
1.20 markus 788:
789: /* find auth method */
790:
791: /*
792: * given auth method name, if configurable options permit this method fill
793: * in auth_ident field and return true, otherwise return false.
794: */
795: int
796: authmethod_is_enabled(Authmethod *method)
797: {
798: if (method == NULL)
799: return 0;
800: /* return false if options indicate this method is disabled */
801: if (method->enabled == NULL || *method->enabled == 0)
802: return 0;
803: /* return false if batch mode is enabled but method needs interactive mode */
804: if (method->batch_flag != NULL && *method->batch_flag != 0)
805: return 0;
806: return 1;
807: }
808:
809: Authmethod *
810: authmethod_lookup(const char *name)
1.1 markus 811: {
1.20 markus 812: Authmethod *method = NULL;
813: if (name != NULL)
814: for (method = authmethods; method->name != NULL; method++)
815: if (strcmp(name, method->name) == 0)
816: return method;
817: debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
818: return NULL;
819: }
1.1 markus 820:
1.53 markus 821: /* XXX internal state */
822: static Authmethod *current = NULL;
823: static char *supported = NULL;
824: static char *preferred = NULL;
1.20 markus 825: /*
826: * Given the authentication method list sent by the server, return the
827: * next method we should try. If the server initially sends a nil list,
1.53 markus 828: * use a built-in default list.
1.41 stevesk 829: */
1.20 markus 830: Authmethod *
831: authmethod_get(char *authlist)
832: {
1.53 markus 833:
834: char *name = NULL;
835: int next;
1.41 stevesk 836:
1.20 markus 837: /* Use a suitable default if we're passed a nil list. */
838: if (authlist == NULL || strlen(authlist) == 0)
1.53 markus 839: authlist = options.preferred_authentications;
1.20 markus 840:
1.53 markus 841: if (supported == NULL || strcmp(authlist, supported) != 0) {
842: debug3("start over, passed a different list %s", authlist);
843: if (supported != NULL)
844: xfree(supported);
845: supported = xstrdup(authlist);
846: preferred = options.preferred_authentications;
847: debug3("preferred %s", preferred);
848: current = NULL;
849: } else if (current != NULL && authmethod_is_enabled(current))
850: return current;
1.20 markus 851:
1.53 markus 852: for (;;) {
853: if ((name = match_list(preferred, supported, &next)) == NULL) {
854: debug("no more auth methods to try");
855: current = NULL;
856: return NULL;
857: }
858: preferred += next;
1.23 markus 859: debug3("authmethod_lookup %s", name);
1.53 markus 860: debug3("remaining preferred: %s", preferred);
861: if ((current = authmethod_lookup(name)) != NULL &&
862: authmethod_is_enabled(current)) {
1.23 markus 863: debug3("authmethod_is_enabled %s", name);
1.53 markus 864: debug("next auth method to try is %s", name);
865: return current;
1.23 markus 866: }
1.1 markus 867: }
1.53 markus 868: }
1.1 markus 869:
1.27 provos 870:
1.53 markus 871: #define DELIM ","
872: char *
873: authmethods_get(void)
874: {
875: Authmethod *method = NULL;
876: char buf[1024];
1.27 provos 877:
1.53 markus 878: buf[0] = '\0';
879: for (method = authmethods; method->name != NULL; method++) {
880: if (authmethod_is_enabled(method)) {
881: if (buf[0] != '\0')
882: strlcat(buf, DELIM, sizeof buf);
883: strlcat(buf, method->name, sizeof buf);
884: }
885: }
886: return xstrdup(buf);
1.1 markus 887: }