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