Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.119
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.119 ! markus 26: RCSID("$OpenBSD: sshconnect2.c,v 1.118 2003/05/14 02:15:47 markus Exp $");
1.118 markus 27:
28: #ifdef KRB5
29: #include <krb5.h>
30: #endif
1.1 markus 31:
32: #include "ssh.h"
1.37 markus 33: #include "ssh2.h"
1.1 markus 34: #include "xmalloc.h"
35: #include "buffer.h"
36: #include "packet.h"
37: #include "compat.h"
38: #include "bufaux.h"
1.37 markus 39: #include "cipher.h"
1.1 markus 40: #include "kex.h"
41: #include "myproposal.h"
42: #include "sshconnect.h"
43: #include "authfile.h"
1.57 provos 44: #include "dh.h"
1.17 markus 45: #include "authfd.h"
1.37 markus 46: #include "log.h"
47: #include "readconf.h"
48: #include "readpass.h"
1.53 markus 49: #include "match.h"
1.61 markus 50: #include "dispatch.h"
1.68 markus 51: #include "canohost.h"
1.100 markus 52: #include "msg.h"
53: #include "pathnames.h"
1.22 provos 54:
1.1 markus 55: /* import */
56: extern char *client_version_string;
57: extern char *server_version_string;
58: extern Options options;
59:
60: /*
61: * SSH2 key exchange
62: */
63:
1.32 markus 64: u_char *session_id2 = NULL;
1.1 markus 65: int session_id2_len = 0;
66:
1.61 markus 67: char *xxx_host;
68: struct sockaddr *xxx_hostaddr;
69:
1.63 markus 70: Kex *xxx_kex = NULL;
71:
1.76 itojun 72: static int
1.75 markus 73: verify_host_key_callback(Key *hostkey)
1.61 markus 74: {
1.75 markus 75: if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
1.83 markus 76: fatal("Host key verification failed.");
1.61 markus 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) {
1.116 itojun 89: logit("No valid ciphers for protocol version 2 given, using defaults.");
1.29 markus 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.107 markus 102: myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
1.22 provos 103: } else {
1.47 markus 104: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.107 markus 105: myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
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: }
1.70 markus 111: if (options.hostkeyalgorithms != NULL)
1.88 deraadt 112: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
1.70 markus 113: options.hostkeyalgorithms;
1.115 markus 114:
115: if (options.rekey_limit)
116: packet_set_rekey_limit(options.rekey_limit);
1.22 provos 117:
1.65 markus 118: /* start key exchange */
1.64 markus 119: kex = kex_setup(myproposal);
1.111 markus 120: kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
121: kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
1.61 markus 122: kex->client_version_string=client_version_string;
123: kex->server_version_string=server_version_string;
1.75 markus 124: kex->verify_host_key=&verify_host_key_callback;
1.63 markus 125:
126: xxx_kex = kex;
1.22 provos 127:
1.66 markus 128: dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
1.62 markus 129:
130: session_id2 = kex->session_id;
131: session_id2_len = kex->session_id_len;
1.22 provos 132:
133: #ifdef DEBUG_KEXDH
134: /* send 1st encrypted/maced/compressed message */
135: packet_start(SSH2_MSG_IGNORE);
136: packet_put_cstring("markus");
137: packet_send();
138: packet_write_wait();
139: #endif
1.1 markus 140: }
1.11 markus 141:
1.1 markus 142: /*
143: * Authenticate user
144: */
1.20 markus 145:
146: typedef struct Authctxt Authctxt;
147: typedef struct Authmethod Authmethod;
1.117 markus 148: typedef struct identity Identity;
149: typedef struct idlist Idlist;
1.20 markus 150:
1.117 markus 151: struct identity {
152: TAILQ_ENTRY(identity) next;
153: AuthenticationConnection *ac; /* set if agent supports key */
154: Key *key; /* public/private key */
155: char *filename; /* comment for agent-only keys */
156: int tried;
157: int isprivate; /* key points to the private key */
158: };
159: TAILQ_HEAD(idlist, identity);
1.20 markus 160:
161: struct Authctxt {
162: const char *server_user;
1.68 markus 163: const char *local_user;
1.20 markus 164: const char *host;
165: const char *service;
1.23 markus 166: Authmethod *method;
1.20 markus 167: int success;
1.51 markus 168: char *authlist;
1.68 markus 169: /* pubkey */
1.117 markus 170: Idlist keys;
1.68 markus 171: AuthenticationConnection *agent;
172: /* hostbased */
1.100 markus 173: Sensitive *sensitive;
1.82 markus 174: /* kbd-interactive */
175: int info_req_seen;
1.20 markus 176: };
177: struct Authmethod {
178: char *name; /* string to compare against server's list */
179: int (*userauth)(Authctxt *authctxt);
180: int *enabled; /* flag in option struct that enables method */
181: int *batch_flag; /* flag in option struct that disables method */
182: };
183:
1.92 markus 184: void input_userauth_success(int, u_int32_t, void *);
185: void input_userauth_failure(int, u_int32_t, void *);
186: void input_userauth_banner(int, u_int32_t, void *);
187: void input_userauth_error(int, u_int32_t, void *);
188: void input_userauth_info_req(int, u_int32_t, void *);
189: void input_userauth_pk_ok(int, u_int32_t, void *);
1.99 markus 190: void input_userauth_passwd_changereq(int, u_int32_t, void *);
1.86 itojun 191:
192: int userauth_none(Authctxt *);
193: int userauth_pubkey(Authctxt *);
194: int userauth_passwd(Authctxt *);
195: int userauth_kbdint(Authctxt *);
196: int userauth_hostbased(Authctxt *);
1.118 markus 197: int userauth_kerberos(Authctxt *);
1.20 markus 198:
1.86 itojun 199: void userauth(Authctxt *, char *);
1.51 markus 200:
1.117 markus 201: static int sign_and_send_pubkey(Authctxt *, Identity *);
202: static void pubkey_prepare(Authctxt *);
203: static void pubkey_cleanup(Authctxt *);
204: static Key *load_identity_file(char *);
1.76 itojun 205:
206: static Authmethod *authmethod_get(char *authlist);
207: static Authmethod *authmethod_lookup(const char *name);
208: static char *authmethods_get(void);
1.20 markus 209:
210: Authmethod authmethods[] = {
1.81 markus 211: {"hostbased",
212: userauth_hostbased,
213: &options.hostbased_authentication,
214: NULL},
1.118 markus 215: #if KRB5
216: {"kerberos-2@ssh.com",
217: userauth_kerberos,
218: &options.kerberos_authentication,
219: NULL},
220: #endif
1.20 markus 221: {"publickey",
222: userauth_pubkey,
1.28 markus 223: &options.pubkey_authentication,
1.20 markus 224: NULL},
1.81 markus 225: {"keyboard-interactive",
226: userauth_kbdint,
227: &options.kbd_interactive_authentication,
228: &options.batch_mode},
1.20 markus 229: {"password",
230: userauth_passwd,
231: &options.password_authentication,
1.23 markus 232: &options.batch_mode},
233: {"none",
234: userauth_none,
235: NULL,
236: NULL},
1.20 markus 237: {NULL, NULL, NULL, NULL}
238: };
239:
240: void
1.68 markus 241: ssh_userauth2(const char *local_user, const char *server_user, char *host,
1.100 markus 242: Sensitive *sensitive)
1.20 markus 243: {
244: Authctxt authctxt;
245: int type;
1.39 markus 246:
1.73 markus 247: if (options.challenge_response_authentication)
1.39 markus 248: options.kbd_interactive_authentication = 1;
1.20 markus 249:
250: packet_start(SSH2_MSG_SERVICE_REQUEST);
251: packet_put_cstring("ssh-userauth");
252: packet_send();
1.108 markus 253: debug("SSH2_MSG_SERVICE_REQUEST sent");
1.20 markus 254: packet_write_wait();
1.91 markus 255: type = packet_read();
1.108 markus 256: if (type != SSH2_MSG_SERVICE_ACCEPT)
257: fatal("Server denied authentication request: %d", type);
1.20 markus 258: if (packet_remaining() > 0) {
1.91 markus 259: char *reply = packet_get_string(NULL);
1.108 markus 260: debug2("service_accept: %s", reply);
1.20 markus 261: xfree(reply);
262: } else {
1.109 markus 263: debug2("buggy server: service_accept w/o service");
1.20 markus 264: }
1.90 markus 265: packet_check_eom();
1.108 markus 266: debug("SSH2_MSG_SERVICE_ACCEPT received");
1.20 markus 267:
1.53 markus 268: if (options.preferred_authentications == NULL)
269: options.preferred_authentications = authmethods_get();
270:
1.20 markus 271: /* setup authentication context */
1.82 markus 272: memset(&authctxt, 0, sizeof(authctxt));
1.117 markus 273: pubkey_prepare(&authctxt);
1.20 markus 274: authctxt.server_user = server_user;
1.68 markus 275: authctxt.local_user = local_user;
1.20 markus 276: authctxt.host = host;
277: authctxt.service = "ssh-connection"; /* service name */
278: authctxt.success = 0;
1.23 markus 279: authctxt.method = authmethod_lookup("none");
1.51 markus 280: authctxt.authlist = NULL;
1.100 markus 281: authctxt.sensitive = sensitive;
1.82 markus 282: authctxt.info_req_seen = 0;
1.23 markus 283: if (authctxt.method == NULL)
284: fatal("ssh_userauth2: internal error: cannot send userauth none request");
1.20 markus 285:
286: /* initial userauth request */
1.23 markus 287: userauth_none(&authctxt);
1.20 markus 288:
1.65 markus 289: dispatch_init(&input_userauth_error);
1.20 markus 290: dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
291: dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
1.35 markus 292: dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
1.20 markus 293: dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
294:
1.117 markus 295: pubkey_cleanup(&authctxt);
1.119 ! markus 296: dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
! 297:
1.109 markus 298: debug("Authentication succeeded (%s).", authctxt.method->name);
1.20 markus 299: }
1.119 ! markus 300:
1.20 markus 301: void
1.51 markus 302: userauth(Authctxt *authctxt, char *authlist)
303: {
304: if (authlist == NULL) {
305: authlist = authctxt->authlist;
306: } else {
307: if (authctxt->authlist)
308: xfree(authctxt->authlist);
309: authctxt->authlist = authlist;
310: }
311: for (;;) {
312: Authmethod *method = authmethod_get(authlist);
313: if (method == NULL)
314: fatal("Permission denied (%s).", authlist);
315: authctxt->method = method;
1.119 ! markus 316:
! 317: /* reset the per method handler */
! 318: dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,
! 319: SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);
! 320:
! 321: /* and try new method */
1.51 markus 322: if (method->userauth(authctxt) != 0) {
323: debug2("we sent a %s packet, wait for reply", method->name);
324: break;
325: } else {
326: debug2("we did not send a packet, disable method");
327: method->enabled = NULL;
328: }
329: }
330: }
1.105 deraadt 331:
1.51 markus 332: void
1.92 markus 333: input_userauth_error(int type, u_int32_t seq, void *ctxt)
1.20 markus 334: {
1.35 markus 335: fatal("input_userauth_error: bad message during authentication: "
336: "type %d", type);
337: }
1.105 deraadt 338:
1.35 markus 339: void
1.92 markus 340: input_userauth_banner(int type, u_int32_t seq, void *ctxt)
1.35 markus 341: {
342: char *msg, *lang;
343: debug3("input_userauth_banner");
344: msg = packet_get_string(NULL);
345: lang = packet_get_string(NULL);
346: fprintf(stderr, "%s", msg);
347: xfree(msg);
348: xfree(lang);
1.20 markus 349: }
1.105 deraadt 350:
1.20 markus 351: void
1.92 markus 352: input_userauth_success(int type, u_int32_t seq, void *ctxt)
1.20 markus 353: {
354: Authctxt *authctxt = ctxt;
355: if (authctxt == NULL)
356: fatal("input_userauth_success: no authentication context");
1.51 markus 357: if (authctxt->authlist)
358: xfree(authctxt->authlist);
1.20 markus 359: authctxt->success = 1; /* break out */
360: }
1.105 deraadt 361:
1.20 markus 362: void
1.92 markus 363: input_userauth_failure(int type, u_int32_t seq, void *ctxt)
1.20 markus 364: {
365: Authctxt *authctxt = ctxt;
366: char *authlist = NULL;
367: int partial;
368:
369: if (authctxt == NULL)
370: fatal("input_userauth_failure: no authentication context");
371:
1.23 markus 372: authlist = packet_get_string(NULL);
1.20 markus 373: partial = packet_get_char();
1.90 markus 374: packet_check_eom();
1.20 markus 375:
376: if (partial != 0)
1.116 itojun 377: logit("Authenticated with partial success.");
1.109 markus 378: debug("Authentications that can continue: %s", authlist);
1.20 markus 379:
1.51 markus 380: userauth(authctxt, authlist);
381: }
382: void
1.92 markus 383: input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
1.51 markus 384: {
385: Authctxt *authctxt = ctxt;
386: Key *key = NULL;
1.117 markus 387: Identity *id = NULL;
1.51 markus 388: Buffer b;
1.96 markus 389: int pktype, sent = 0;
390: u_int alen, blen;
391: char *pkalg, *fp;
392: u_char *pkblob;
1.51 markus 393:
394: if (authctxt == NULL)
395: fatal("input_userauth_pk_ok: no authentication context");
396: if (datafellows & SSH_BUG_PKOK) {
397: /* this is similar to SSH_BUG_PKAUTH */
398: debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
399: pkblob = packet_get_string(&blen);
400: buffer_init(&b);
401: buffer_append(&b, pkblob, blen);
402: pkalg = buffer_get_string(&b, &alen);
403: buffer_free(&b);
404: } else {
405: pkalg = packet_get_string(&alen);
406: pkblob = packet_get_string(&blen);
407: }
1.90 markus 408: packet_check_eom();
1.51 markus 409:
1.117 markus 410: debug("Server accepts key: pkalg %s blen %u", pkalg, blen);
1.51 markus 411:
1.117 markus 412: if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
413: debug("unknown pkalg %s", pkalg);
414: goto done;
415: }
416: if ((key = key_from_blob(pkblob, blen)) == NULL) {
417: debug("no key from blob. pkalg %s", pkalg);
418: goto done;
419: }
420: if (key->type != pktype) {
421: error("input_userauth_pk_ok: type mismatch "
422: "for decoded key (received %d, expected %d)",
423: key->type, pktype);
424: goto done;
425: }
426: fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
427: debug2("input_userauth_pk_ok: fp %s", fp);
428: xfree(fp);
429:
430: TAILQ_FOREACH(id, &authctxt->keys, next) {
431: if (key_equal(key, id->key)) {
432: sent = sign_and_send_pubkey(authctxt, id);
1.51 markus 433: break;
434: }
1.117 markus 435: }
436: done:
1.51 markus 437: if (key != NULL)
438: key_free(key);
439: xfree(pkalg);
440: xfree(pkblob);
441:
1.106 deraadt 442: /* try another method if we did not send a packet */
1.51 markus 443: if (sent == 0)
444: userauth(authctxt, NULL);
1.20 markus 445: }
446:
1.1 markus 447: int
1.23 markus 448: userauth_none(Authctxt *authctxt)
449: {
450: /* initial userauth request */
451: packet_start(SSH2_MSG_USERAUTH_REQUEST);
452: packet_put_cstring(authctxt->server_user);
453: packet_put_cstring(authctxt->service);
454: packet_put_cstring(authctxt->method->name);
455: packet_send();
456: return 1;
457: }
458:
459: int
1.20 markus 460: userauth_passwd(Authctxt *authctxt)
1.1 markus 461: {
1.6 markus 462: static int attempt = 0;
1.99 markus 463: char prompt[150];
1.1 markus 464: char *password;
1.6 markus 465:
1.13 todd 466: if (attempt++ >= options.number_of_password_prompts)
1.6 markus 467: return 0;
1.13 todd 468:
1.87 deraadt 469: if (attempt != 1)
1.13 todd 470: error("Permission denied, please try again.");
1.1 markus 471:
1.43 itojun 472: snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1.20 markus 473: authctxt->server_user, authctxt->host);
1.1 markus 474: password = read_passphrase(prompt, 0);
475: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 476: packet_put_cstring(authctxt->server_user);
477: packet_put_cstring(authctxt->service);
1.23 markus 478: packet_put_cstring(authctxt->method->name);
1.1 markus 479: packet_put_char(0);
1.49 markus 480: packet_put_cstring(password);
1.1 markus 481: memset(password, 0, strlen(password));
482: xfree(password);
1.85 markus 483: packet_add_padding(64);
1.1 markus 484: packet_send();
1.99 markus 485:
1.104 deraadt 486: dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
1.99 markus 487: &input_userauth_passwd_changereq);
488:
1.1 markus 489: return 1;
490: }
1.99 markus 491: /*
492: * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
493: */
494: void
495: input_userauth_passwd_changereq(int type, uint32_t seqnr, void *ctxt)
496: {
497: Authctxt *authctxt = ctxt;
498: char *info, *lang, *password = NULL, *retype = NULL;
499: char prompt[150];
500:
501: debug2("input_userauth_passwd_changereq");
502:
503: if (authctxt == NULL)
504: fatal("input_userauth_passwd_changereq: "
505: "no authentication context");
506:
507: info = packet_get_string(NULL);
508: lang = packet_get_string(NULL);
509: if (strlen(info) > 0)
1.116 itojun 510: logit("%s", info);
1.99 markus 511: xfree(info);
512: xfree(lang);
513: packet_start(SSH2_MSG_USERAUTH_REQUEST);
514: packet_put_cstring(authctxt->server_user);
515: packet_put_cstring(authctxt->service);
516: packet_put_cstring(authctxt->method->name);
517: packet_put_char(1); /* additional info */
1.104 deraadt 518: snprintf(prompt, sizeof(prompt),
1.99 markus 519: "Enter %.30s@%.128s's old password: ",
520: authctxt->server_user, authctxt->host);
521: password = read_passphrase(prompt, 0);
522: packet_put_cstring(password);
523: memset(password, 0, strlen(password));
524: xfree(password);
525: password = NULL;
526: while (password == NULL) {
1.104 deraadt 527: snprintf(prompt, sizeof(prompt),
1.99 markus 528: "Enter %.30s@%.128s's new password: ",
529: authctxt->server_user, authctxt->host);
530: password = read_passphrase(prompt, RP_ALLOW_EOF);
531: if (password == NULL) {
532: /* bail out */
533: return;
534: }
1.104 deraadt 535: snprintf(prompt, sizeof(prompt),
1.99 markus 536: "Retype %.30s@%.128s's new password: ",
537: authctxt->server_user, authctxt->host);
538: retype = read_passphrase(prompt, 0);
539: if (strcmp(password, retype) != 0) {
540: memset(password, 0, strlen(password));
541: xfree(password);
1.116 itojun 542: logit("Mismatch; try again, EOF to quit.");
1.99 markus 543: password = NULL;
544: }
545: memset(retype, 0, strlen(retype));
546: xfree(retype);
547: }
548: packet_put_cstring(password);
549: memset(password, 0, strlen(password));
550: xfree(password);
551: packet_add_padding(64);
552: packet_send();
1.104 deraadt 553:
554: dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
1.99 markus 555: &input_userauth_passwd_changereq);
1.117 markus 556: }
557:
558: static int
559: identity_sign(Identity *id, u_char **sigp, u_int *lenp,
560: u_char *data, u_int datalen)
561: {
562: Key *prv;
563: int ret;
1.99 markus 564:
1.117 markus 565: /* the agent supports this key */
566: if (id->ac)
567: return (ssh_agent_sign(id->ac, id->key, sigp, lenp,
568: data, datalen));
569: /*
570: * we have already loaded the private key or
571: * the private key is stored in external hardware
572: */
573: if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
574: return (key_sign(id->key, sigp, lenp, data, datalen));
575: /* load the private key from the file */
576: if ((prv = load_identity_file(id->filename)) == NULL)
577: return (-1);
578: ret = key_sign(prv, sigp, lenp, data, datalen);
579: key_free(prv);
580: return (ret);
1.51 markus 581: }
582:
1.76 itojun 583: static int
1.117 markus 584: sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1.1 markus 585: {
586: Buffer b;
1.32 markus 587: u_char *blob, *signature;
1.96 markus 588: u_int bloblen, slen;
1.14 markus 589: int skip = 0;
1.17 markus 590: int ret = -1;
1.23 markus 591: int have_sig = 1;
1.1 markus 592:
1.30 markus 593: debug3("sign_and_send_pubkey");
1.51 markus 594:
1.117 markus 595: if (key_to_blob(id->key, &blob, &bloblen) == 0) {
1.28 markus 596: /* we cannot handle this key */
1.30 markus 597: debug3("sign_and_send_pubkey: cannot handle key");
1.28 markus 598: return 0;
599: }
1.1 markus 600: /* data to be signed */
601: buffer_init(&b);
1.26 markus 602: if (datafellows & SSH_OLD_SESSIONID) {
603: buffer_append(&b, session_id2, session_id2_len);
1.41 stevesk 604: skip = session_id2_len;
1.26 markus 605: } else {
1.14 markus 606: buffer_put_string(&b, session_id2, session_id2_len);
607: skip = buffer_len(&b);
608: }
1.1 markus 609: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 610: buffer_put_cstring(&b, authctxt->server_user);
1.10 markus 611: buffer_put_cstring(&b,
1.30 markus 612: datafellows & SSH_BUG_PKSERVICE ?
1.10 markus 613: "ssh-userauth" :
1.20 markus 614: authctxt->service);
1.30 markus 615: if (datafellows & SSH_BUG_PKAUTH) {
616: buffer_put_char(&b, have_sig);
617: } else {
618: buffer_put_cstring(&b, authctxt->method->name);
619: buffer_put_char(&b, have_sig);
1.117 markus 620: buffer_put_cstring(&b, key_ssh_name(id->key));
1.30 markus 621: }
1.1 markus 622: buffer_put_string(&b, blob, bloblen);
623:
624: /* generate signature */
1.117 markus 625: ret = identity_sign(id, &signature, &slen,
1.51 markus 626: buffer_ptr(&b), buffer_len(&b));
1.17 markus 627: if (ret == -1) {
628: xfree(blob);
629: buffer_free(&b);
630: return 0;
631: }
1.28 markus 632: #ifdef DEBUG_PK
1.1 markus 633: buffer_dump(&b);
634: #endif
1.30 markus 635: if (datafellows & SSH_BUG_PKSERVICE) {
1.10 markus 636: buffer_clear(&b);
637: buffer_append(&b, session_id2, session_id2_len);
1.51 markus 638: skip = session_id2_len;
1.10 markus 639: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 640: buffer_put_cstring(&b, authctxt->server_user);
641: buffer_put_cstring(&b, authctxt->service);
1.23 markus 642: buffer_put_cstring(&b, authctxt->method->name);
643: buffer_put_char(&b, have_sig);
1.30 markus 644: if (!(datafellows & SSH_BUG_PKAUTH))
1.117 markus 645: buffer_put_cstring(&b, key_ssh_name(id->key));
1.10 markus 646: buffer_put_string(&b, blob, bloblen);
647: }
648: xfree(blob);
1.51 markus 649:
1.1 markus 650: /* append signature */
651: buffer_put_string(&b, signature, slen);
652: xfree(signature);
653:
654: /* skip session id and packet type */
1.14 markus 655: if (buffer_len(&b) < skip + 1)
1.20 markus 656: fatal("userauth_pubkey: internal error");
1.14 markus 657: buffer_consume(&b, skip + 1);
1.1 markus 658:
659: /* put remaining data from buffer into packet */
660: packet_start(SSH2_MSG_USERAUTH_REQUEST);
661: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
662: buffer_free(&b);
663: packet_send();
1.17 markus 664:
665: return 1;
1.16 markus 666: }
667:
1.76 itojun 668: static int
1.117 markus 669: send_pubkey_test(Authctxt *authctxt, Identity *id)
1.20 markus 670: {
1.51 markus 671: u_char *blob;
1.97 markus 672: u_int bloblen, have_sig = 0;
1.20 markus 673:
1.51 markus 674: debug3("send_pubkey_test");
1.16 markus 675:
1.117 markus 676: if (key_to_blob(id->key, &blob, &bloblen) == 0) {
1.51 markus 677: /* we cannot handle this key */
678: debug3("send_pubkey_test: cannot handle key");
1.16 markus 679: return 0;
680: }
1.51 markus 681: /* register callback for USERAUTH_PK_OK message */
682: dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
683:
684: packet_start(SSH2_MSG_USERAUTH_REQUEST);
685: packet_put_cstring(authctxt->server_user);
686: packet_put_cstring(authctxt->service);
687: packet_put_cstring(authctxt->method->name);
688: packet_put_char(have_sig);
689: if (!(datafellows & SSH_BUG_PKAUTH))
1.117 markus 690: packet_put_cstring(key_ssh_name(id->key));
1.51 markus 691: packet_put_string(blob, bloblen);
692: xfree(blob);
693: packet_send();
694: return 1;
695: }
696:
1.76 itojun 697: static Key *
1.51 markus 698: load_identity_file(char *filename)
699: {
700: Key *private;
701: char prompt[300], *passphrase;
1.56 markus 702: int quit, i;
1.52 markus 703: struct stat st;
1.16 markus 704:
1.52 markus 705: if (stat(filename, &st) < 0) {
706: debug3("no such identity: %s", filename);
707: return NULL;
708: }
1.56 markus 709: private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
710: if (private == NULL) {
711: if (options.batch_mode)
1.51 markus 712: return NULL;
1.16 markus 713: snprintf(prompt, sizeof prompt,
1.88 deraadt 714: "Enter passphrase for key '%.100s': ", filename);
1.20 markus 715: for (i = 0; i < options.number_of_password_prompts; i++) {
716: passphrase = read_passphrase(prompt, 0);
717: if (strcmp(passphrase, "") != 0) {
1.56 markus 718: private = key_load_private_type(KEY_UNSPEC, filename,
719: passphrase, NULL);
1.51 markus 720: quit = 0;
1.20 markus 721: } else {
722: debug2("no passphrase given, try next key");
1.51 markus 723: quit = 1;
1.20 markus 724: }
725: memset(passphrase, 0, strlen(passphrase));
726: xfree(passphrase);
1.56 markus 727: if (private != NULL || quit)
1.20 markus 728: break;
729: debug2("bad passphrase given, try again...");
1.16 markus 730: }
731: }
1.51 markus 732: return private;
733: }
734:
1.117 markus 735: /*
736: * try keys in the following order:
737: * 1. agent keys that are found in the config file
738: * 2. other agent keys
739: * 3. keys that are only listed in the config file
740: */
741: static void
742: pubkey_prepare(Authctxt *authctxt)
1.51 markus 743: {
1.117 markus 744: Identity *id;
745: Idlist agent, files, *preferred;
746: Key *key;
747: AuthenticationConnection *ac;
748: char *comment;
749: int i, found;
1.51 markus 750:
1.117 markus 751: TAILQ_INIT(&agent); /* keys from the agent */
752: TAILQ_INIT(&files); /* keys from the config file */
753: preferred = &authctxt->keys;
754: TAILQ_INIT(preferred); /* preferred order of keys */
755:
756: /* list of keys stored in the filesystem */
757: for (i = 0; i < options.num_identity_files; i++) {
758: key = options.identity_keys[i];
759: if (key && key->type == KEY_RSA1)
760: continue;
761: options.identity_keys[i] = NULL;
762: id = xmalloc(sizeof(*id));
763: memset(id, 0, sizeof(*id));
764: id->key = key;
765: id->filename = xstrdup(options.identity_files[i]);
766: TAILQ_INSERT_TAIL(&files, id, next);
767: }
768: /* list of keys supported by the agent */
769: if ((ac = ssh_get_authentication_connection())) {
770: for (key = ssh_get_first_identity(ac, &comment, 2);
771: key != NULL;
772: key = ssh_get_next_identity(ac, &comment, 2)) {
773: found = 0;
774: TAILQ_FOREACH(id, &files, next) {
775: /* agent keys from the config file are preferred */
776: if (key_equal(key, id->key)) {
777: key_free(key);
778: xfree(comment);
779: TAILQ_REMOVE(&files, id, next);
780: TAILQ_INSERT_TAIL(preferred, id, next);
781: id->ac = ac;
782: found = 1;
783: break;
784: }
785: }
786: if (!found) {
787: id = xmalloc(sizeof(*id));
788: memset(id, 0, sizeof(*id));
789: id->key = key;
790: id->filename = comment;
791: id->ac = ac;
792: TAILQ_INSERT_TAIL(&agent, id, next);
793: }
794: }
795: /* append remaining agent keys */
796: for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {
797: TAILQ_REMOVE(&agent, id, next);
798: TAILQ_INSERT_TAIL(preferred, id, next);
799: }
800: authctxt->agent = ac;
801: }
802: /* append remaining keys from the config file */
803: for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
804: TAILQ_REMOVE(&files, id, next);
805: TAILQ_INSERT_TAIL(preferred, id, next);
806: }
807: TAILQ_FOREACH(id, preferred, next) {
808: debug2("key: %s (%p)", id->filename, id->key);
809: }
1.17 markus 810: }
811:
1.117 markus 812: static void
813: pubkey_cleanup(Authctxt *authctxt)
1.51 markus 814: {
1.117 markus 815: Identity *id;
1.51 markus 816:
1.117 markus 817: if (authctxt->agent != NULL)
818: ssh_close_authentication_connection(authctxt->agent);
819: for (id = TAILQ_FIRST(&authctxt->keys); id;
820: id = TAILQ_FIRST(&authctxt->keys)) {
821: TAILQ_REMOVE(&authctxt->keys, id, next);
822: if (id->key)
823: key_free(id->key);
824: if (id->filename)
825: xfree(id->filename);
826: xfree(id);
827: }
1.1 markus 828: }
829:
1.20 markus 830: int
831: userauth_pubkey(Authctxt *authctxt)
832: {
1.117 markus 833: Identity *id;
1.20 markus 834: int sent = 0;
835:
1.117 markus 836: while ((id = TAILQ_FIRST(&authctxt->keys))) {
837: if (id->tried++)
838: return (0);
839: TAILQ_REMOVE(&authctxt->keys, id, next);
840: TAILQ_INSERT_TAIL(&authctxt->keys, id, next);
841: /*
842: * send a test message if we have the public key. for
843: * encrypted keys we cannot do this and have to load the
844: * private key instead
845: */
846: if (id->key && id->key->type != KEY_RSA1) {
847: debug("Offering public key: %s", id->filename);
848: sent = send_pubkey_test(authctxt, id);
849: } else if (id->key == NULL) {
850: debug("Trying private key: %s", id->filename);
851: id->key = load_identity_file(id->filename);
852: if (id->key != NULL) {
853: id->isprivate = 1;
854: sent = sign_and_send_pubkey(authctxt, id);
855: key_free(id->key);
856: id->key = NULL;
1.51 markus 857: }
858: }
1.117 markus 859: if (sent)
860: return (sent);
1.28 markus 861: }
1.117 markus 862: return (0);
1.20 markus 863: }
864:
1.23 markus 865: /*
866: * Send userauth request message specifying keyboard-interactive method.
867: */
868: int
869: userauth_kbdint(Authctxt *authctxt)
870: {
871: static int attempt = 0;
872:
873: if (attempt++ >= options.number_of_password_prompts)
874: return 0;
1.82 markus 875: /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
876: if (attempt > 1 && !authctxt->info_req_seen) {
877: debug3("userauth_kbdint: disable: no info_req_seen");
878: dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
879: return 0;
880: }
1.23 markus 881:
882: debug2("userauth_kbdint");
883: packet_start(SSH2_MSG_USERAUTH_REQUEST);
884: packet_put_cstring(authctxt->server_user);
885: packet_put_cstring(authctxt->service);
886: packet_put_cstring(authctxt->method->name);
887: packet_put_cstring(""); /* lang */
888: packet_put_cstring(options.kbd_interactive_devices ?
889: options.kbd_interactive_devices : "");
890: packet_send();
891:
892: dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
893: return 1;
894: }
895:
896: /*
1.46 markus 897: * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1.23 markus 898: */
899: void
1.92 markus 900: input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
1.23 markus 901: {
902: Authctxt *authctxt = ctxt;
1.46 markus 903: char *name, *inst, *lang, *prompt, *response;
1.32 markus 904: u_int num_prompts, i;
1.23 markus 905: int echo = 0;
906:
907: debug2("input_userauth_info_req");
908:
909: if (authctxt == NULL)
910: fatal("input_userauth_info_req: no authentication context");
1.82 markus 911:
912: authctxt->info_req_seen = 1;
1.23 markus 913:
914: name = packet_get_string(NULL);
915: inst = packet_get_string(NULL);
916: lang = packet_get_string(NULL);
917: if (strlen(name) > 0)
1.116 itojun 918: logit("%s", name);
1.23 markus 919: if (strlen(inst) > 0)
1.116 itojun 920: logit("%s", inst);
1.46 markus 921: xfree(name);
1.23 markus 922: xfree(inst);
1.46 markus 923: xfree(lang);
1.23 markus 924:
925: num_prompts = packet_get_int();
926: /*
927: * Begin to build info response packet based on prompts requested.
928: * We commit to providing the correct number of responses, so if
929: * further on we run into a problem that prevents this, we have to
930: * be sure and clean this up and send a correct error response.
931: */
932: packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
933: packet_put_int(num_prompts);
934:
1.73 markus 935: debug2("input_userauth_info_req: num_prompts %d", num_prompts);
1.23 markus 936: for (i = 0; i < num_prompts; i++) {
937: prompt = packet_get_string(NULL);
938: echo = packet_get_char();
939:
1.77 markus 940: response = read_passphrase(prompt, echo ? RP_ECHO : 0);
1.23 markus 941:
1.49 markus 942: packet_put_cstring(response);
1.23 markus 943: memset(response, 0, strlen(response));
944: xfree(response);
945: xfree(prompt);
946: }
1.90 markus 947: packet_check_eom(); /* done with parsing incoming message. */
1.23 markus 948:
1.85 markus 949: packet_add_padding(64);
1.23 markus 950: packet_send();
1.68 markus 951: }
952:
1.100 markus 953: static int
1.105 deraadt 954: ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
1.100 markus 955: u_char *data, u_int datalen)
956: {
957: Buffer b;
1.101 markus 958: struct stat st;
1.100 markus 959: pid_t pid;
1.103 markus 960: int to[2], from[2], status, version = 2;
1.100 markus 961:
1.109 markus 962: debug2("ssh_keysign called");
1.100 markus 963:
1.101 markus 964: if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
965: error("ssh_keysign: no installed: %s", strerror(errno));
966: return -1;
967: }
1.100 markus 968: if (fflush(stdout) != 0)
969: error("ssh_keysign: fflush: %s", strerror(errno));
970: if (pipe(to) < 0) {
971: error("ssh_keysign: pipe: %s", strerror(errno));
972: return -1;
973: }
974: if (pipe(from) < 0) {
975: error("ssh_keysign: pipe: %s", strerror(errno));
976: return -1;
977: }
978: if ((pid = fork()) < 0) {
979: error("ssh_keysign: fork: %s", strerror(errno));
980: return -1;
981: }
982: if (pid == 0) {
983: seteuid(getuid());
984: setuid(getuid());
985: close(from[0]);
986: if (dup2(from[1], STDOUT_FILENO) < 0)
987: fatal("ssh_keysign: dup2: %s", strerror(errno));
988: close(to[1]);
989: if (dup2(to[0], STDIN_FILENO) < 0)
990: fatal("ssh_keysign: dup2: %s", strerror(errno));
1.103 markus 991: close(from[1]);
992: close(to[0]);
1.102 markus 993: execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
1.100 markus 994: fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
995: strerror(errno));
996: }
997: close(from[1]);
998: close(to[0]);
999:
1000: buffer_init(&b);
1.103 markus 1001: buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
1.100 markus 1002: buffer_put_string(&b, data, datalen);
1.110 djm 1003: ssh_msg_send(to[1], version, &b);
1.100 markus 1004:
1.110 djm 1005: if (ssh_msg_recv(from[0], &b) < 0) {
1.101 markus 1006: error("ssh_keysign: no reply");
1.100 markus 1007: buffer_clear(&b);
1008: return -1;
1009: }
1.101 markus 1010: close(from[0]);
1011: close(to[1]);
1012:
1.103 markus 1013: while (waitpid(pid, &status, 0) < 0)
1014: if (errno != EINTR)
1015: break;
1.101 markus 1016:
1.100 markus 1017: if (buffer_get_char(&b) != version) {
1.101 markus 1018: error("ssh_keysign: bad version");
1.100 markus 1019: buffer_clear(&b);
1020: return -1;
1021: }
1022: *sigp = buffer_get_string(&b, lenp);
1023: buffer_clear(&b);
1024:
1025: return 0;
1026: }
1027:
1.68 markus 1028: int
1029: userauth_hostbased(Authctxt *authctxt)
1030: {
1031: Key *private = NULL;
1.100 markus 1032: Sensitive *sensitive = authctxt->sensitive;
1.68 markus 1033: Buffer b;
1034: u_char *signature, *blob;
1035: char *chost, *pkalg, *p;
1.72 markus 1036: const char *service;
1.68 markus 1037: u_int blen, slen;
1.71 markus 1038: int ok, i, len, found = 0;
1.68 markus 1039:
1040: /* check for a useful key */
1.100 markus 1041: for (i = 0; i < sensitive->nkeys; i++) {
1042: private = sensitive->keys[i];
1.68 markus 1043: if (private && private->type != KEY_RSA1) {
1044: found = 1;
1045: /* we take and free the key */
1.100 markus 1046: sensitive->keys[i] = NULL;
1.68 markus 1047: break;
1048: }
1049: }
1050: if (!found) {
1.109 markus 1051: debug("No more client hostkeys for hostbased authentication.");
1.68 markus 1052: return 0;
1053: }
1054: if (key_to_blob(private, &blob, &blen) == 0) {
1055: key_free(private);
1056: return 0;
1057: }
1.84 markus 1058: /* figure out a name for the client host */
1059: p = get_local_name(packet_get_connection_in());
1060: if (p == NULL) {
1061: error("userauth_hostbased: cannot get local ipaddr/name");
1062: key_free(private);
1063: return 0;
1064: }
1065: len = strlen(p) + 2;
1066: chost = xmalloc(len);
1067: strlcpy(chost, p, len);
1068: strlcat(chost, ".", len);
1069: debug2("userauth_hostbased: chost %s", chost);
1.112 markus 1070: xfree(p);
1.84 markus 1071:
1.72 markus 1072: service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1073: authctxt->service;
1.68 markus 1074: pkalg = xstrdup(key_ssh_name(private));
1075: buffer_init(&b);
1076: /* construct data */
1.72 markus 1077: buffer_put_string(&b, session_id2, session_id2_len);
1.68 markus 1078: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1079: buffer_put_cstring(&b, authctxt->server_user);
1.72 markus 1080: buffer_put_cstring(&b, service);
1.68 markus 1081: buffer_put_cstring(&b, authctxt->method->name);
1082: buffer_put_cstring(&b, pkalg);
1083: buffer_put_string(&b, blob, blen);
1084: buffer_put_cstring(&b, chost);
1085: buffer_put_cstring(&b, authctxt->local_user);
1086: #ifdef DEBUG_PK
1087: buffer_dump(&b);
1088: #endif
1.100 markus 1089: if (sensitive->external_keysign)
1090: ok = ssh_keysign(private, &signature, &slen,
1091: buffer_ptr(&b), buffer_len(&b));
1092: else
1093: ok = key_sign(private, &signature, &slen,
1094: buffer_ptr(&b), buffer_len(&b));
1.68 markus 1095: key_free(private);
1096: buffer_free(&b);
1097: if (ok != 0) {
1098: error("key_sign failed");
1099: xfree(chost);
1100: xfree(pkalg);
1101: return 0;
1102: }
1103: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1104: packet_put_cstring(authctxt->server_user);
1105: packet_put_cstring(authctxt->service);
1106: packet_put_cstring(authctxt->method->name);
1107: packet_put_cstring(pkalg);
1108: packet_put_string(blob, blen);
1109: packet_put_cstring(chost);
1110: packet_put_cstring(authctxt->local_user);
1111: packet_put_string(signature, slen);
1112: memset(signature, 's', slen);
1113: xfree(signature);
1114: xfree(chost);
1115: xfree(pkalg);
1116:
1117: packet_send();
1118: return 1;
1.23 markus 1119: }
1.118 markus 1120:
1121: #if KRB5
1122: static int
1123: ssh_krb5_helper(krb5_data *ap)
1124: {
1125: krb5_context xcontext = NULL; /* XXX share with ssh1 */
1126: krb5_auth_context xauth_context = NULL;
1127:
1128: krb5_context *context;
1129: krb5_auth_context *auth_context;
1130: krb5_error_code problem;
1131: const char *tkfile;
1132: struct stat buf;
1133: krb5_ccache ccache = NULL;
1134: const char *remotehost;
1135: int ret;
1136:
1137: memset(ap, 0, sizeof(*ap));
1138:
1139: context = &xcontext;
1140: auth_context = &xauth_context;
1141:
1142: problem = krb5_init_context(context);
1143: if (problem) {
1144: debug("Kerberos v5: krb5_init_context failed");
1145: ret = 0;
1146: goto out;
1147: }
1148:
1149: tkfile = krb5_cc_default_name(*context);
1150: if (strncmp(tkfile, "FILE:", 5) == 0)
1151: tkfile += 5;
1152:
1153: if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
1154: debug("Kerberos v5: could not get default ccache (permission denied).");
1155: ret = 0;
1156: goto out;
1157: }
1158:
1159: problem = krb5_cc_default(*context, &ccache);
1160: if (problem) {
1161: debug("Kerberos v5: krb5_cc_default failed: %s",
1162: krb5_get_err_text(*context, problem));
1163: ret = 0;
1164: goto out;
1165: }
1166:
1167: remotehost = get_canonical_hostname(1);
1168:
1169: problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
1170: "host", remotehost, NULL, ccache, ap);
1171: if (problem) {
1172: debug("Kerberos v5: krb5_mk_req failed: %s",
1173: krb5_get_err_text(*context, problem));
1174: ret = 0;
1175: goto out;
1176: }
1177: ret = 1;
1178:
1179: out:
1180: if (ccache != NULL)
1181: krb5_cc_close(*context, ccache);
1182: if (*auth_context)
1183: krb5_auth_con_free(*context, *auth_context);
1184: if (*context)
1185: krb5_free_context(*context);
1186: return (ret);
1187: }
1188:
1189: int
1190: userauth_kerberos(Authctxt *authctxt)
1191: {
1192: krb5_data ap;
1193:
1194: if (ssh_krb5_helper(&ap) == 0)
1195: return (0);
1196:
1197: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1198: packet_put_cstring(authctxt->server_user);
1199: packet_put_cstring(authctxt->service);
1200: packet_put_cstring(authctxt->method->name);
1201: packet_put_string(ap.data, ap.length);
1202: packet_send();
1203:
1204: krb5_data_free(&ap);
1205: return (1);
1206: }
1207: #endif
1.20 markus 1208:
1209: /* find auth method */
1210:
1211: /*
1212: * given auth method name, if configurable options permit this method fill
1213: * in auth_ident field and return true, otherwise return false.
1214: */
1.76 itojun 1215: static int
1.20 markus 1216: authmethod_is_enabled(Authmethod *method)
1217: {
1218: if (method == NULL)
1219: return 0;
1220: /* return false if options indicate this method is disabled */
1221: if (method->enabled == NULL || *method->enabled == 0)
1222: return 0;
1223: /* return false if batch mode is enabled but method needs interactive mode */
1224: if (method->batch_flag != NULL && *method->batch_flag != 0)
1225: return 0;
1226: return 1;
1227: }
1228:
1.76 itojun 1229: static Authmethod *
1.20 markus 1230: authmethod_lookup(const char *name)
1.1 markus 1231: {
1.20 markus 1232: Authmethod *method = NULL;
1233: if (name != NULL)
1234: for (method = authmethods; method->name != NULL; method++)
1235: if (strcmp(name, method->name) == 0)
1236: return method;
1237: debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1238: return NULL;
1239: }
1.1 markus 1240:
1.53 markus 1241: /* XXX internal state */
1242: static Authmethod *current = NULL;
1243: static char *supported = NULL;
1244: static char *preferred = NULL;
1.105 deraadt 1245:
1.20 markus 1246: /*
1247: * Given the authentication method list sent by the server, return the
1248: * next method we should try. If the server initially sends a nil list,
1.67 markus 1249: * use a built-in default list.
1.41 stevesk 1250: */
1.76 itojun 1251: static Authmethod *
1.20 markus 1252: authmethod_get(char *authlist)
1253: {
1.53 markus 1254: char *name = NULL;
1.97 markus 1255: u_int next;
1.41 stevesk 1256:
1.20 markus 1257: /* Use a suitable default if we're passed a nil list. */
1258: if (authlist == NULL || strlen(authlist) == 0)
1.53 markus 1259: authlist = options.preferred_authentications;
1.20 markus 1260:
1.53 markus 1261: if (supported == NULL || strcmp(authlist, supported) != 0) {
1262: debug3("start over, passed a different list %s", authlist);
1263: if (supported != NULL)
1264: xfree(supported);
1265: supported = xstrdup(authlist);
1266: preferred = options.preferred_authentications;
1267: debug3("preferred %s", preferred);
1268: current = NULL;
1269: } else if (current != NULL && authmethod_is_enabled(current))
1270: return current;
1.20 markus 1271:
1.53 markus 1272: for (;;) {
1273: if ((name = match_list(preferred, supported, &next)) == NULL) {
1.109 markus 1274: debug("No more authentication methods to try.");
1.53 markus 1275: current = NULL;
1276: return NULL;
1277: }
1278: preferred += next;
1.23 markus 1279: debug3("authmethod_lookup %s", name);
1.53 markus 1280: debug3("remaining preferred: %s", preferred);
1281: if ((current = authmethod_lookup(name)) != NULL &&
1282: authmethod_is_enabled(current)) {
1.23 markus 1283: debug3("authmethod_is_enabled %s", name);
1.109 markus 1284: debug("Next authentication method: %s", name);
1.53 markus 1285: return current;
1.23 markus 1286: }
1.1 markus 1287: }
1.53 markus 1288: }
1.1 markus 1289:
1.79 stevesk 1290: static char *
1.53 markus 1291: authmethods_get(void)
1292: {
1293: Authmethod *method = NULL;
1.93 markus 1294: Buffer b;
1295: char *list;
1.27 provos 1296:
1.93 markus 1297: buffer_init(&b);
1.53 markus 1298: for (method = authmethods; method->name != NULL; method++) {
1299: if (authmethod_is_enabled(method)) {
1.93 markus 1300: if (buffer_len(&b) > 0)
1301: buffer_append(&b, ",", 1);
1302: buffer_append(&b, method->name, strlen(method->name));
1.53 markus 1303: }
1304: }
1.93 markus 1305: buffer_append(&b, "\0", 1);
1306: list = xstrdup(buffer_ptr(&b));
1307: buffer_free(&b);
1308: return list;
1.1 markus 1309: }