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