Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.216
1.216 ! djm 1: /* $OpenBSD: sshconnect2.c,v 1.215 2015/01/15 11:04:36 djm Exp $ */
1.1 markus 2: /*
3: * Copyright (c) 2000 Markus Friedl. All rights reserved.
1.170 djm 4: * Copyright (c) 2008 Damien Miller. All rights reserved.
1.1 markus 5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
1.145 stevesk 27: #include <sys/types.h>
1.160 deraadt 28: #include <sys/socket.h>
1.145 stevesk 29: #include <sys/wait.h>
1.144 stevesk 30: #include <sys/queue.h>
1.146 stevesk 31: #include <sys/stat.h>
1.156 stevesk 32:
33: #include <errno.h>
1.174 dtucker 34: #include <fcntl.h>
1.164 jolan 35: #include <netdb.h>
1.159 stevesk 36: #include <stdio.h>
1.158 stevesk 37: #include <string.h>
1.160 deraadt 38: #include <signal.h>
39: #include <pwd.h>
1.157 stevesk 40: #include <unistd.h>
1.166 djm 41: #include <vis.h>
1.1 markus 42:
1.160 deraadt 43: #include "xmalloc.h"
1.1 markus 44: #include "ssh.h"
1.37 markus 45: #include "ssh2.h"
1.1 markus 46: #include "buffer.h"
47: #include "packet.h"
48: #include "compat.h"
1.37 markus 49: #include "cipher.h"
1.160 deraadt 50: #include "key.h"
1.1 markus 51: #include "kex.h"
52: #include "myproposal.h"
53: #include "sshconnect.h"
54: #include "authfile.h"
1.57 provos 55: #include "dh.h"
1.17 markus 56: #include "authfd.h"
1.37 markus 57: #include "log.h"
1.210 millert 58: #include "misc.h"
1.37 markus 59: #include "readconf.h"
1.53 markus 60: #include "match.h"
1.61 markus 61: #include "dispatch.h"
1.68 markus 62: #include "canohost.h"
1.100 markus 63: #include "msg.h"
64: #include "pathnames.h"
1.154 markus 65: #include "uidswap.h"
1.186 djm 66: #include "hostfile.h"
1.214 djm 67: #include "ssherr.h"
1.22 provos 68:
1.121 markus 69: #ifdef GSSAPI
70: #include "ssh-gss.h"
71: #endif
72:
1.1 markus 73: /* import */
74: extern char *client_version_string;
75: extern char *server_version_string;
76: extern Options options;
77:
78: /*
79: * SSH2 key exchange
80: */
81:
1.32 markus 82: u_char *session_id2 = NULL;
1.120 markus 83: u_int session_id2_len = 0;
1.1 markus 84:
1.61 markus 85: char *xxx_host;
86: struct sockaddr *xxx_hostaddr;
87:
1.63 markus 88: Kex *xxx_kex = NULL;
89:
1.76 itojun 90: static int
1.75 markus 91: verify_host_key_callback(Key *hostkey)
1.61 markus 92: {
1.75 markus 93: if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
1.83 markus 94: fatal("Host key verification failed.");
1.61 markus 95: return 0;
96: }
97:
1.186 djm 98: static char *
99: order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port)
100: {
101: char *oavail, *avail, *first, *last, *alg, *hostname, *ret;
102: size_t maxlen;
103: struct hostkeys *hostkeys;
104: int ktype;
1.188 djm 105: u_int i;
1.186 djm 106:
107: /* Find all hostkeys for this hostname */
108: get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL);
109: hostkeys = init_hostkeys();
1.188 djm 110: for (i = 0; i < options.num_user_hostfiles; i++)
111: load_hostkeys(hostkeys, hostname, options.user_hostfiles[i]);
112: for (i = 0; i < options.num_system_hostfiles; i++)
113: load_hostkeys(hostkeys, hostname, options.system_hostfiles[i]);
1.186 djm 114:
115: oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG);
116: maxlen = strlen(avail) + 1;
117: first = xmalloc(maxlen);
118: last = xmalloc(maxlen);
119: *first = *last = '\0';
120:
121: #define ALG_APPEND(to, from) \
122: do { \
123: if (*to != '\0') \
124: strlcat(to, ",", maxlen); \
125: strlcat(to, from, maxlen); \
126: } while (0)
127:
128: while ((alg = strsep(&avail, ",")) && *alg != '\0') {
1.214 djm 129: if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
1.186 djm 130: fatal("%s: unknown alg %s", __func__, alg);
131: if (lookup_key_in_hostkeys_by_type(hostkeys,
1.214 djm 132: sshkey_type_plain(ktype), NULL))
1.186 djm 133: ALG_APPEND(first, alg);
134: else
135: ALG_APPEND(last, alg);
136: }
137: #undef ALG_APPEND
1.216 ! djm 138: xasprintf(&ret, "%s%s%s", first,
! 139: (*first == '\0' || *last == '\0') ? "" : ",", last);
1.186 djm 140: if (*first != '\0')
141: debug3("%s: prefer hostkeyalgs: %s", __func__, first);
142:
1.197 djm 143: free(first);
144: free(last);
145: free(hostname);
146: free(oavail);
1.186 djm 147: free_hostkeys(hostkeys);
148:
149: return ret;
150: }
151:
1.1 markus 152: void
1.186 djm 153: ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
1.22 provos 154: {
1.205 markus 155: char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
1.22 provos 156: Kex *kex;
1.61 markus 157:
158: xxx_host = host;
159: xxx_hostaddr = hostaddr;
1.22 provos 160:
1.29 markus 161: if (options.ciphers == (char *)-1) {
1.116 itojun 162: logit("No valid ciphers for protocol version 2 given, using defaults.");
1.29 markus 163: options.ciphers = NULL;
1.24 markus 164: }
1.22 provos 165: if (options.ciphers != NULL) {
166: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
167: myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
168: }
1.60 stevesk 169: myproposal[PROPOSAL_ENC_ALGS_CTOS] =
170: compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
171: myproposal[PROPOSAL_ENC_ALGS_STOC] =
172: compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
1.22 provos 173: if (options.compression) {
1.47 markus 174: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.141 markus 175: myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none";
1.22 provos 176: } else {
1.47 markus 177: myproposal[PROPOSAL_COMP_ALGS_CTOS] =
1.141 markus 178: myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
1.47 markus 179: }
180: if (options.macs != NULL) {
181: myproposal[PROPOSAL_MAC_ALGS_CTOS] =
182: myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
1.22 provos 183: }
1.70 markus 184: if (options.hostkeyalgorithms != NULL)
1.88 deraadt 185: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
1.200 djm 186: compat_pkalg_proposal(options.hostkeyalgorithms);
1.186 djm 187: else {
188: /* Prefer algorithms that we already have keys for */
189: myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
1.200 djm 190: compat_pkalg_proposal(
191: order_hostkeyalgs(host, hostaddr, port));
1.186 djm 192: }
1.185 djm 193: if (options.kex_algorithms != NULL)
194: myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
1.206 djm 195: myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
196: myproposal[PROPOSAL_KEX_ALGS]);
1.115 markus 197:
1.196 dtucker 198: if (options.rekey_limit || options.rekey_interval)
199: packet_set_rekey_limits((u_int32_t)options.rekey_limit,
200: (time_t)options.rekey_interval);
1.22 provos 201:
1.65 markus 202: /* start key exchange */
1.64 markus 203: kex = kex_setup(myproposal);
1.207 markus 204: #ifdef WITH_OPENSSL
1.111 markus 205: kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
1.138 djm 206: kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
1.111 markus 207: kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
1.147 djm 208: kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
1.184 djm 209: kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
1.207 markus 210: #endif
1.199 markus 211: kex->kex[KEX_C25519_SHA256] = kexc25519_client;
1.61 markus 212: kex->client_version_string=client_version_string;
213: kex->server_version_string=server_version_string;
1.75 markus 214: kex->verify_host_key=&verify_host_key_callback;
1.63 markus 215:
216: xxx_kex = kex;
1.22 provos 217:
1.66 markus 218: dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
1.173 andreas 219:
220: if (options.use_roaming && !kex->roaming) {
221: debug("Roaming not allowed by server");
222: options.use_roaming = 0;
223: }
1.62 markus 224:
225: session_id2 = kex->session_id;
226: session_id2_len = kex->session_id_len;
1.22 provos 227:
228: #ifdef DEBUG_KEXDH
229: /* send 1st encrypted/maced/compressed message */
230: packet_start(SSH2_MSG_IGNORE);
231: packet_put_cstring("markus");
232: packet_send();
233: packet_write_wait();
234: #endif
1.1 markus 235: }
1.11 markus 236:
1.1 markus 237: /*
238: * Authenticate user
239: */
1.20 markus 240:
1.214 djm 241: typedef struct cauthctxt Authctxt;
242: typedef struct cauthmethod Authmethod;
1.117 markus 243: typedef struct identity Identity;
244: typedef struct idlist Idlist;
1.20 markus 245:
1.117 markus 246: struct identity {
247: TAILQ_ENTRY(identity) next;
1.214 djm 248: int agent_fd; /* >=0 if agent supports key */
249: struct sshkey *key; /* public/private key */
1.117 markus 250: char *filename; /* comment for agent-only keys */
251: int tried;
252: int isprivate; /* key points to the private key */
1.191 dtucker 253: int userprovided;
1.117 markus 254: };
255: TAILQ_HEAD(idlist, identity);
1.20 markus 256:
1.214 djm 257: struct cauthctxt {
1.20 markus 258: const char *server_user;
1.68 markus 259: const char *local_user;
1.20 markus 260: const char *host;
261: const char *service;
1.214 djm 262: struct cauthmethod *method;
1.183 djm 263: sig_atomic_t success;
1.51 markus 264: char *authlist;
1.214 djm 265: int attempt;
1.68 markus 266: /* pubkey */
1.214 djm 267: struct idlist keys;
268: int agent_fd;
1.68 markus 269: /* hostbased */
1.100 markus 270: Sensitive *sensitive;
1.82 markus 271: /* kbd-interactive */
272: int info_req_seen;
1.121 markus 273: /* generic */
274: void *methoddata;
1.20 markus 275: };
1.214 djm 276:
277: struct cauthmethod {
1.20 markus 278: char *name; /* string to compare against server's list */
279: int (*userauth)(Authctxt *authctxt);
1.170 djm 280: void (*cleanup)(Authctxt *authctxt);
1.20 markus 281: int *enabled; /* flag in option struct that enables method */
282: int *batch_flag; /* flag in option struct that disables method */
283: };
284:
1.92 markus 285: void input_userauth_success(int, u_int32_t, void *);
1.172 djm 286: void input_userauth_success_unexpected(int, u_int32_t, void *);
1.92 markus 287: void input_userauth_failure(int, u_int32_t, void *);
288: void input_userauth_banner(int, u_int32_t, void *);
289: void input_userauth_error(int, u_int32_t, void *);
290: void input_userauth_info_req(int, u_int32_t, void *);
291: void input_userauth_pk_ok(int, u_int32_t, void *);
1.99 markus 292: void input_userauth_passwd_changereq(int, u_int32_t, void *);
1.86 itojun 293:
294: int userauth_none(Authctxt *);
295: int userauth_pubkey(Authctxt *);
296: int userauth_passwd(Authctxt *);
297: int userauth_kbdint(Authctxt *);
298: int userauth_hostbased(Authctxt *);
1.20 markus 299:
1.121 markus 300: #ifdef GSSAPI
301: int userauth_gssapi(Authctxt *authctxt);
302: void input_gssapi_response(int type, u_int32_t, void *);
303: void input_gssapi_token(int type, u_int32_t, void *);
304: void input_gssapi_hash(int type, u_int32_t, void *);
305: void input_gssapi_error(int, u_int32_t, void *);
306: void input_gssapi_errtok(int, u_int32_t, void *);
307: #endif
308:
1.86 itojun 309: void userauth(Authctxt *, char *);
1.51 markus 310:
1.117 markus 311: static int sign_and_send_pubkey(Authctxt *, Identity *);
312: static void pubkey_prepare(Authctxt *);
313: static void pubkey_cleanup(Authctxt *);
1.191 dtucker 314: static Key *load_identity_file(char *, int);
1.76 itojun 315:
316: static Authmethod *authmethod_get(char *authlist);
317: static Authmethod *authmethod_lookup(const char *name);
318: static char *authmethods_get(void);
1.20 markus 319:
320: Authmethod authmethods[] = {
1.121 markus 321: #ifdef GSSAPI
1.132 markus 322: {"gssapi-with-mic",
1.121 markus 323: userauth_gssapi,
1.170 djm 324: NULL,
1.121 markus 325: &options.gss_authentication,
326: NULL},
327: #endif
1.81 markus 328: {"hostbased",
329: userauth_hostbased,
1.170 djm 330: NULL,
1.81 markus 331: &options.hostbased_authentication,
332: NULL},
1.20 markus 333: {"publickey",
334: userauth_pubkey,
1.170 djm 335: NULL,
1.28 markus 336: &options.pubkey_authentication,
1.20 markus 337: NULL},
1.81 markus 338: {"keyboard-interactive",
339: userauth_kbdint,
1.170 djm 340: NULL,
1.81 markus 341: &options.kbd_interactive_authentication,
342: &options.batch_mode},
1.20 markus 343: {"password",
344: userauth_passwd,
1.170 djm 345: NULL,
1.20 markus 346: &options.password_authentication,
1.23 markus 347: &options.batch_mode},
348: {"none",
349: userauth_none,
350: NULL,
1.170 djm 351: NULL,
1.23 markus 352: NULL},
1.170 djm 353: {NULL, NULL, NULL, NULL, NULL}
1.20 markus 354: };
355:
356: void
1.68 markus 357: ssh_userauth2(const char *local_user, const char *server_user, char *host,
1.100 markus 358: Sensitive *sensitive)
1.20 markus 359: {
360: Authctxt authctxt;
361: int type;
1.39 markus 362:
1.73 markus 363: if (options.challenge_response_authentication)
1.39 markus 364: options.kbd_interactive_authentication = 1;
1.20 markus 365:
366: packet_start(SSH2_MSG_SERVICE_REQUEST);
367: packet_put_cstring("ssh-userauth");
368: packet_send();
1.108 markus 369: debug("SSH2_MSG_SERVICE_REQUEST sent");
1.20 markus 370: packet_write_wait();
1.91 markus 371: type = packet_read();
1.108 markus 372: if (type != SSH2_MSG_SERVICE_ACCEPT)
373: fatal("Server denied authentication request: %d", type);
1.20 markus 374: if (packet_remaining() > 0) {
1.91 markus 375: char *reply = packet_get_string(NULL);
1.108 markus 376: debug2("service_accept: %s", reply);
1.197 djm 377: free(reply);
1.20 markus 378: } else {
1.109 markus 379: debug2("buggy server: service_accept w/o service");
1.20 markus 380: }
1.90 markus 381: packet_check_eom();
1.108 markus 382: debug("SSH2_MSG_SERVICE_ACCEPT received");
1.20 markus 383:
1.53 markus 384: if (options.preferred_authentications == NULL)
385: options.preferred_authentications = authmethods_get();
386:
1.20 markus 387: /* setup authentication context */
1.82 markus 388: memset(&authctxt, 0, sizeof(authctxt));
1.117 markus 389: pubkey_prepare(&authctxt);
1.20 markus 390: authctxt.server_user = server_user;
1.68 markus 391: authctxt.local_user = local_user;
1.20 markus 392: authctxt.host = host;
393: authctxt.service = "ssh-connection"; /* service name */
394: authctxt.success = 0;
1.23 markus 395: authctxt.method = authmethod_lookup("none");
1.51 markus 396: authctxt.authlist = NULL;
1.121 markus 397: authctxt.methoddata = NULL;
1.100 markus 398: authctxt.sensitive = sensitive;
1.82 markus 399: authctxt.info_req_seen = 0;
1.215 djm 400: authctxt.agent_fd = -1;
1.23 markus 401: if (authctxt.method == NULL)
402: fatal("ssh_userauth2: internal error: cannot send userauth none request");
1.20 markus 403:
404: /* initial userauth request */
1.23 markus 405: userauth_none(&authctxt);
1.20 markus 406:
1.65 markus 407: dispatch_init(&input_userauth_error);
1.20 markus 408: dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
409: dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
1.35 markus 410: dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
1.20 markus 411: dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */
412:
1.117 markus 413: pubkey_cleanup(&authctxt);
1.119 markus 414: dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
415:
1.109 markus 416: debug("Authentication succeeded (%s).", authctxt.method->name);
1.20 markus 417: }
1.119 markus 418:
1.20 markus 419: void
1.51 markus 420: userauth(Authctxt *authctxt, char *authlist)
421: {
1.170 djm 422: if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
423: authctxt->method->cleanup(authctxt);
424:
1.197 djm 425: free(authctxt->methoddata);
426: authctxt->methoddata = NULL;
1.51 markus 427: if (authlist == NULL) {
428: authlist = authctxt->authlist;
429: } else {
1.197 djm 430: free(authctxt->authlist);
1.51 markus 431: authctxt->authlist = authlist;
432: }
433: for (;;) {
434: Authmethod *method = authmethod_get(authlist);
435: if (method == NULL)
436: fatal("Permission denied (%s).", authlist);
437: authctxt->method = method;
1.119 markus 438:
439: /* reset the per method handler */
440: dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,
441: SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);
442:
443: /* and try new method */
1.51 markus 444: if (method->userauth(authctxt) != 0) {
445: debug2("we sent a %s packet, wait for reply", method->name);
446: break;
447: } else {
448: debug2("we did not send a packet, disable method");
449: method->enabled = NULL;
450: }
451: }
452: }
1.105 deraadt 453:
1.169 djm 454: /* ARGSUSED */
1.51 markus 455: void
1.92 markus 456: input_userauth_error(int type, u_int32_t seq, void *ctxt)
1.20 markus 457: {
1.35 markus 458: fatal("input_userauth_error: bad message during authentication: "
1.140 djm 459: "type %d", type);
1.35 markus 460: }
1.105 deraadt 461:
1.169 djm 462: /* ARGSUSED */
1.35 markus 463: void
1.92 markus 464: input_userauth_banner(int type, u_int32_t seq, void *ctxt)
1.35 markus 465: {
1.166 djm 466: char *msg, *raw, *lang;
467: u_int len;
1.126 deraadt 468:
1.35 markus 469: debug3("input_userauth_banner");
1.166 djm 470: raw = packet_get_string(&len);
1.35 markus 471: lang = packet_get_string(NULL);
1.167 markus 472: if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) {
1.166 djm 473: if (len > 65536)
474: len = 65536;
1.168 deraadt 475: msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
1.177 dtucker 476: strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
1.125 dtucker 477: fprintf(stderr, "%s", msg);
1.197 djm 478: free(msg);
1.166 djm 479: }
1.197 djm 480: free(raw);
481: free(lang);
1.20 markus 482: }
1.105 deraadt 483:
1.169 djm 484: /* ARGSUSED */
1.20 markus 485: void
1.92 markus 486: input_userauth_success(int type, u_int32_t seq, void *ctxt)
1.20 markus 487: {
488: Authctxt *authctxt = ctxt;
1.172 djm 489:
1.20 markus 490: if (authctxt == NULL)
491: fatal("input_userauth_success: no authentication context");
1.197 djm 492: free(authctxt->authlist);
493: authctxt->authlist = NULL;
1.172 djm 494: if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
495: authctxt->method->cleanup(authctxt);
1.197 djm 496: free(authctxt->methoddata);
497: authctxt->methoddata = NULL;
1.20 markus 498: authctxt->success = 1; /* break out */
499: }
1.105 deraadt 500:
1.172 djm 501: void
502: input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt)
503: {
504: Authctxt *authctxt = ctxt;
505:
506: if (authctxt == NULL)
507: fatal("%s: no authentication context", __func__);
508:
509: fatal("Unexpected authentication success during %s.",
510: authctxt->method->name);
511: }
512:
1.169 djm 513: /* ARGSUSED */
1.20 markus 514: void
1.92 markus 515: input_userauth_failure(int type, u_int32_t seq, void *ctxt)
1.20 markus 516: {
517: Authctxt *authctxt = ctxt;
518: char *authlist = NULL;
519: int partial;
520:
521: if (authctxt == NULL)
522: fatal("input_userauth_failure: no authentication context");
523:
1.23 markus 524: authlist = packet_get_string(NULL);
1.20 markus 525: partial = packet_get_char();
1.90 markus 526: packet_check_eom();
1.20 markus 527:
1.193 markus 528: if (partial != 0) {
1.116 itojun 529: logit("Authenticated with partial success.");
1.193 markus 530: /* reset state */
531: pubkey_cleanup(authctxt);
532: pubkey_prepare(authctxt);
533: }
1.109 markus 534: debug("Authentications that can continue: %s", authlist);
1.20 markus 535:
1.51 markus 536: userauth(authctxt, authlist);
537: }
1.169 djm 538:
539: /* ARGSUSED */
1.51 markus 540: void
1.92 markus 541: input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
1.51 markus 542: {
543: Authctxt *authctxt = ctxt;
544: Key *key = NULL;
1.117 markus 545: Identity *id = NULL;
1.51 markus 546: Buffer b;
1.96 markus 547: int pktype, sent = 0;
548: u_int alen, blen;
549: char *pkalg, *fp;
550: u_char *pkblob;
1.51 markus 551:
552: if (authctxt == NULL)
553: fatal("input_userauth_pk_ok: no authentication context");
554: if (datafellows & SSH_BUG_PKOK) {
555: /* this is similar to SSH_BUG_PKAUTH */
556: debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
557: pkblob = packet_get_string(&blen);
558: buffer_init(&b);
559: buffer_append(&b, pkblob, blen);
560: pkalg = buffer_get_string(&b, &alen);
561: buffer_free(&b);
562: } else {
563: pkalg = packet_get_string(&alen);
564: pkblob = packet_get_string(&blen);
565: }
1.90 markus 566: packet_check_eom();
1.51 markus 567:
1.117 markus 568: debug("Server accepts key: pkalg %s blen %u", pkalg, blen);
1.51 markus 569:
1.117 markus 570: if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
571: debug("unknown pkalg %s", pkalg);
572: goto done;
573: }
574: if ((key = key_from_blob(pkblob, blen)) == NULL) {
575: debug("no key from blob. pkalg %s", pkalg);
576: goto done;
577: }
578: if (key->type != pktype) {
579: error("input_userauth_pk_ok: type mismatch "
580: "for decoded key (received %d, expected %d)",
581: key->type, pktype);
582: goto done;
583: }
1.214 djm 584: fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT);
1.117 markus 585: debug2("input_userauth_pk_ok: fp %s", fp);
1.197 djm 586: free(fp);
1.117 markus 587:
1.127 markus 588: /*
589: * search keys in the reverse order, because last candidate has been
590: * moved to the end of the queue. this also avoids confusion by
591: * duplicate keys
592: */
1.136 henning 593: TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {
1.117 markus 594: if (key_equal(key, id->key)) {
595: sent = sign_and_send_pubkey(authctxt, id);
1.51 markus 596: break;
597: }
1.117 markus 598: }
599: done:
1.51 markus 600: if (key != NULL)
601: key_free(key);
1.197 djm 602: free(pkalg);
603: free(pkblob);
1.51 markus 604:
1.106 deraadt 605: /* try another method if we did not send a packet */
1.51 markus 606: if (sent == 0)
607: userauth(authctxt, NULL);
1.20 markus 608: }
1.121 markus 609:
610: #ifdef GSSAPI
1.133 djm 611: int
1.121 markus 612: userauth_gssapi(Authctxt *authctxt)
613: {
614: Gssctxt *gssctxt = NULL;
1.128 avsm 615: static gss_OID_set gss_supported = NULL;
1.139 djm 616: static u_int mech = 0;
1.121 markus 617: OM_uint32 min;
618: int ok = 0;
619:
620: /* Try one GSSAPI method at a time, rather than sending them all at
621: * once. */
622:
1.128 avsm 623: if (gss_supported == NULL)
624: gss_indicate_mechs(&min, &gss_supported);
1.121 markus 625:
626: /* Check to see if the mechanism is usable before we offer it */
1.128 avsm 627: while (mech < gss_supported->count && !ok) {
1.121 markus 628: /* My DER encoding requires length<128 */
1.128 avsm 629: if (gss_supported->elements[mech].length < 128 &&
1.161 djm 630: ssh_gssapi_check_mechanism(&gssctxt,
631: &gss_supported->elements[mech], authctxt->host)) {
1.121 markus 632: ok = 1; /* Mechanism works */
633: } else {
634: mech++;
635: }
636: }
637:
1.161 djm 638: if (!ok)
1.139 djm 639: return 0;
1.121 markus 640:
641: authctxt->methoddata=(void *)gssctxt;
642:
643: packet_start(SSH2_MSG_USERAUTH_REQUEST);
644: packet_put_cstring(authctxt->server_user);
645: packet_put_cstring(authctxt->service);
646: packet_put_cstring(authctxt->method->name);
647:
648: packet_put_int(1);
649:
1.129 markus 650: packet_put_int((gss_supported->elements[mech].length) + 2);
651: packet_put_char(SSH_GSS_OIDTYPE);
652: packet_put_char(gss_supported->elements[mech].length);
653: packet_put_raw(gss_supported->elements[mech].elements,
654: gss_supported->elements[mech].length);
1.121 markus 655:
656: packet_send();
657:
658: dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
659: dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
660: dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
661: dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
662:
663: mech++; /* Move along to next candidate */
664:
665: return 1;
666: }
667:
1.130 markus 668: static OM_uint32
669: process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
670: {
671: Authctxt *authctxt = ctxt;
672: Gssctxt *gssctxt = authctxt->methoddata;
673: gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
1.142 djm 674: gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
675: gss_buffer_desc gssbuf;
1.132 markus 676: OM_uint32 status, ms, flags;
677: Buffer b;
1.133 djm 678:
1.130 markus 679: status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
1.132 markus 680: recv_tok, &send_tok, &flags);
1.130 markus 681:
682: if (send_tok.length > 0) {
683: if (GSS_ERROR(status))
684: packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
685: else
686: packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
1.133 djm 687:
1.130 markus 688: packet_put_string(send_tok.value, send_tok.length);
689: packet_send();
690: gss_release_buffer(&ms, &send_tok);
691: }
1.133 djm 692:
1.130 markus 693: if (status == GSS_S_COMPLETE) {
1.132 markus 694: /* send either complete or MIC, depending on mechanism */
695: if (!(flags & GSS_C_INTEG_FLAG)) {
696: packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
697: packet_send();
698: } else {
699: ssh_gssapi_buildmic(&b, authctxt->server_user,
700: authctxt->service, "gssapi-with-mic");
701:
702: gssbuf.value = buffer_ptr(&b);
703: gssbuf.length = buffer_len(&b);
1.133 djm 704:
1.132 markus 705: status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
1.133 djm 706:
1.132 markus 707: if (!GSS_ERROR(status)) {
708: packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
709: packet_put_string(mic.value, mic.length);
1.133 djm 710:
1.132 markus 711: packet_send();
712: }
1.133 djm 713:
1.132 markus 714: buffer_free(&b);
715: gss_release_buffer(&ms, &mic);
1.133 djm 716: }
1.130 markus 717: }
1.133 djm 718:
1.130 markus 719: return status;
720: }
721:
1.169 djm 722: /* ARGSUSED */
1.121 markus 723: void
724: input_gssapi_response(int type, u_int32_t plen, void *ctxt)
725: {
726: Authctxt *authctxt = ctxt;
727: Gssctxt *gssctxt;
728: int oidlen;
729: char *oidv;
730:
731: if (authctxt == NULL)
732: fatal("input_gssapi_response: no authentication context");
733: gssctxt = authctxt->methoddata;
734:
735: /* Setup our OID */
736: oidv = packet_get_string(&oidlen);
737:
1.129 markus 738: if (oidlen <= 2 ||
739: oidv[0] != SSH_GSS_OIDTYPE ||
740: oidv[1] != oidlen - 2) {
1.197 djm 741: free(oidv);
1.129 markus 742: debug("Badly encoded mechanism OID received");
743: userauth(authctxt, NULL);
744: return;
1.121 markus 745: }
1.129 markus 746:
747: if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2))
748: fatal("Server returned different OID than expected");
1.121 markus 749:
750: packet_check_eom();
751:
1.197 djm 752: free(oidv);
1.121 markus 753:
1.130 markus 754: if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {
1.121 markus 755: /* Start again with next method on list */
756: debug("Trying to start again");
757: userauth(authctxt, NULL);
758: return;
759: }
760: }
761:
1.169 djm 762: /* ARGSUSED */
1.121 markus 763: void
764: input_gssapi_token(int type, u_int32_t plen, void *ctxt)
765: {
766: Authctxt *authctxt = ctxt;
767: gss_buffer_desc recv_tok;
1.130 markus 768: OM_uint32 status;
1.121 markus 769: u_int slen;
770:
771: if (authctxt == NULL)
772: fatal("input_gssapi_response: no authentication context");
773:
774: recv_tok.value = packet_get_string(&slen);
775: recv_tok.length = slen; /* safe typecast */
776:
777: packet_check_eom();
778:
1.130 markus 779: status = process_gssapi_token(ctxt, &recv_tok);
1.121 markus 780:
1.197 djm 781: free(recv_tok.value);
1.121 markus 782:
783: if (GSS_ERROR(status)) {
784: /* Start again with the next method in the list */
785: userauth(authctxt, NULL);
786: return;
787: }
788: }
789:
1.169 djm 790: /* ARGSUSED */
1.121 markus 791: void
792: input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
793: {
794: Authctxt *authctxt = ctxt;
795: Gssctxt *gssctxt;
796: gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
797: gss_buffer_desc recv_tok;
1.194 djm 798: OM_uint32 ms;
1.123 deraadt 799: u_int len;
1.121 markus 800:
801: if (authctxt == NULL)
802: fatal("input_gssapi_response: no authentication context");
803: gssctxt = authctxt->methoddata;
804:
1.123 deraadt 805: recv_tok.value = packet_get_string(&len);
806: recv_tok.length = len;
1.121 markus 807:
808: packet_check_eom();
809:
810: /* Stick it into GSSAPI and see what it says */
1.194 djm 811: (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
1.140 djm 812: &recv_tok, &send_tok, NULL);
1.121 markus 813:
1.197 djm 814: free(recv_tok.value);
1.121 markus 815: gss_release_buffer(&ms, &send_tok);
816:
817: /* Server will be returning a failed packet after this one */
818: }
819:
1.169 djm 820: /* ARGSUSED */
1.121 markus 821: void
822: input_gssapi_error(int type, u_int32_t plen, void *ctxt)
823: {
824: char *msg;
825: char *lang;
826:
1.194 djm 827: /* maj */(void)packet_get_int();
828: /* min */(void)packet_get_int();
1.121 markus 829: msg=packet_get_string(NULL);
830: lang=packet_get_string(NULL);
831:
832: packet_check_eom();
833:
1.143 stevesk 834: debug("Server GSSAPI Error:\n%s", msg);
1.197 djm 835: free(msg);
836: free(lang);
1.121 markus 837: }
838: #endif /* GSSAPI */
1.20 markus 839:
1.1 markus 840: int
1.23 markus 841: userauth_none(Authctxt *authctxt)
842: {
843: /* initial userauth request */
844: packet_start(SSH2_MSG_USERAUTH_REQUEST);
845: packet_put_cstring(authctxt->server_user);
846: packet_put_cstring(authctxt->service);
847: packet_put_cstring(authctxt->method->name);
848: packet_send();
849: return 1;
850: }
851:
852: int
1.20 markus 853: userauth_passwd(Authctxt *authctxt)
1.1 markus 854: {
1.6 markus 855: static int attempt = 0;
1.99 markus 856: char prompt[150];
1.1 markus 857: char *password;
1.175 dtucker 858: const char *host = options.host_key_alias ? options.host_key_alias :
859: authctxt->host;
1.6 markus 860:
1.13 todd 861: if (attempt++ >= options.number_of_password_prompts)
1.6 markus 862: return 0;
1.13 todd 863:
1.87 deraadt 864: if (attempt != 1)
1.13 todd 865: error("Permission denied, please try again.");
1.1 markus 866:
1.43 itojun 867: snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
1.175 dtucker 868: authctxt->server_user, host);
1.1 markus 869: password = read_passphrase(prompt, 0);
870: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 871: packet_put_cstring(authctxt->server_user);
872: packet_put_cstring(authctxt->service);
1.23 markus 873: packet_put_cstring(authctxt->method->name);
1.1 markus 874: packet_put_char(0);
1.49 markus 875: packet_put_cstring(password);
1.204 djm 876: explicit_bzero(password, strlen(password));
1.197 djm 877: free(password);
1.85 markus 878: packet_add_padding(64);
1.1 markus 879: packet_send();
1.99 markus 880:
1.104 deraadt 881: dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
1.99 markus 882: &input_userauth_passwd_changereq);
883:
1.1 markus 884: return 1;
885: }
1.169 djm 886:
1.99 markus 887: /*
888: * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
889: */
1.169 djm 890: /* ARGSUSED */
1.99 markus 891: void
1.153 djm 892: input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
1.99 markus 893: {
894: Authctxt *authctxt = ctxt;
895: char *info, *lang, *password = NULL, *retype = NULL;
896: char prompt[150];
1.175 dtucker 897: const char *host = options.host_key_alias ? options.host_key_alias :
898: authctxt->host;
1.99 markus 899:
900: debug2("input_userauth_passwd_changereq");
901:
902: if (authctxt == NULL)
903: fatal("input_userauth_passwd_changereq: "
904: "no authentication context");
905:
906: info = packet_get_string(NULL);
907: lang = packet_get_string(NULL);
908: if (strlen(info) > 0)
1.116 itojun 909: logit("%s", info);
1.197 djm 910: free(info);
911: free(lang);
1.99 markus 912: packet_start(SSH2_MSG_USERAUTH_REQUEST);
913: packet_put_cstring(authctxt->server_user);
914: packet_put_cstring(authctxt->service);
915: packet_put_cstring(authctxt->method->name);
916: packet_put_char(1); /* additional info */
1.104 deraadt 917: snprintf(prompt, sizeof(prompt),
1.99 markus 918: "Enter %.30s@%.128s's old password: ",
1.175 dtucker 919: authctxt->server_user, host);
1.99 markus 920: password = read_passphrase(prompt, 0);
921: packet_put_cstring(password);
1.204 djm 922: explicit_bzero(password, strlen(password));
1.197 djm 923: free(password);
1.99 markus 924: password = NULL;
925: while (password == NULL) {
1.104 deraadt 926: snprintf(prompt, sizeof(prompt),
1.99 markus 927: "Enter %.30s@%.128s's new password: ",
1.175 dtucker 928: authctxt->server_user, host);
1.99 markus 929: password = read_passphrase(prompt, RP_ALLOW_EOF);
930: if (password == NULL) {
931: /* bail out */
932: return;
933: }
1.104 deraadt 934: snprintf(prompt, sizeof(prompt),
1.99 markus 935: "Retype %.30s@%.128s's new password: ",
1.175 dtucker 936: authctxt->server_user, host);
1.99 markus 937: retype = read_passphrase(prompt, 0);
938: if (strcmp(password, retype) != 0) {
1.204 djm 939: explicit_bzero(password, strlen(password));
1.197 djm 940: free(password);
1.116 itojun 941: logit("Mismatch; try again, EOF to quit.");
1.99 markus 942: password = NULL;
943: }
1.204 djm 944: explicit_bzero(retype, strlen(retype));
1.197 djm 945: free(retype);
1.99 markus 946: }
947: packet_put_cstring(password);
1.204 djm 948: explicit_bzero(password, strlen(password));
1.197 djm 949: free(password);
1.99 markus 950: packet_add_padding(64);
951: packet_send();
1.104 deraadt 952:
953: dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
1.99 markus 954: &input_userauth_passwd_changereq);
1.117 markus 955: }
956:
957: static int
1.214 djm 958: identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
959: const u_char *data, size_t datalen, u_int compat)
1.117 markus 960: {
961: Key *prv;
962: int ret;
1.99 markus 963:
1.117 markus 964: /* the agent supports this key */
1.214 djm 965: if (id->agent_fd)
966: return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp,
967: data, datalen, compat);
968:
1.117 markus 969: /*
970: * we have already loaded the private key or
971: * the private key is stored in external hardware
972: */
1.209 djm 973: if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
1.214 djm 974: return (sshkey_sign(id->key, sigp, lenp, data, datalen,
975: compat));
1.117 markus 976: /* load the private key from the file */
1.191 dtucker 977: if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)
1.214 djm 978: return (-1); /* XXX return decent error code */
979: ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat);
980: sshkey_free(prv);
1.117 markus 981: return (ret);
1.51 markus 982: }
983:
1.76 itojun 984: static int
1.117 markus 985: sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1.1 markus 986: {
987: Buffer b;
1.32 markus 988: u_char *blob, *signature;
1.214 djm 989: u_int bloblen;
990: size_t slen;
1.120 markus 991: u_int skip = 0;
1.17 markus 992: int ret = -1;
1.23 markus 993: int have_sig = 1;
1.182 djm 994: char *fp;
1.1 markus 995:
1.212 djm 996: fp = key_fingerprint(id->key, options.fingerprint_hash, SSH_FP_DEFAULT);
1.182 djm 997: debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp);
1.197 djm 998: free(fp);
1.51 markus 999:
1.117 markus 1000: if (key_to_blob(id->key, &blob, &bloblen) == 0) {
1.28 markus 1001: /* we cannot handle this key */
1.30 markus 1002: debug3("sign_and_send_pubkey: cannot handle key");
1.28 markus 1003: return 0;
1004: }
1.1 markus 1005: /* data to be signed */
1006: buffer_init(&b);
1.26 markus 1007: if (datafellows & SSH_OLD_SESSIONID) {
1008: buffer_append(&b, session_id2, session_id2_len);
1.41 stevesk 1009: skip = session_id2_len;
1.26 markus 1010: } else {
1.14 markus 1011: buffer_put_string(&b, session_id2, session_id2_len);
1012: skip = buffer_len(&b);
1013: }
1.1 markus 1014: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 1015: buffer_put_cstring(&b, authctxt->server_user);
1.10 markus 1016: buffer_put_cstring(&b,
1.30 markus 1017: datafellows & SSH_BUG_PKSERVICE ?
1.10 markus 1018: "ssh-userauth" :
1.20 markus 1019: authctxt->service);
1.30 markus 1020: if (datafellows & SSH_BUG_PKAUTH) {
1021: buffer_put_char(&b, have_sig);
1022: } else {
1023: buffer_put_cstring(&b, authctxt->method->name);
1024: buffer_put_char(&b, have_sig);
1.117 markus 1025: buffer_put_cstring(&b, key_ssh_name(id->key));
1.30 markus 1026: }
1.1 markus 1027: buffer_put_string(&b, blob, bloblen);
1028:
1029: /* generate signature */
1.117 markus 1030: ret = identity_sign(id, &signature, &slen,
1.214 djm 1031: buffer_ptr(&b), buffer_len(&b), datafellows);
1032: if (ret != 0) {
1.197 djm 1033: free(blob);
1.17 markus 1034: buffer_free(&b);
1035: return 0;
1036: }
1.28 markus 1037: #ifdef DEBUG_PK
1.1 markus 1038: buffer_dump(&b);
1039: #endif
1.30 markus 1040: if (datafellows & SSH_BUG_PKSERVICE) {
1.10 markus 1041: buffer_clear(&b);
1042: buffer_append(&b, session_id2, session_id2_len);
1.51 markus 1043: skip = session_id2_len;
1.10 markus 1044: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1.20 markus 1045: buffer_put_cstring(&b, authctxt->server_user);
1046: buffer_put_cstring(&b, authctxt->service);
1.23 markus 1047: buffer_put_cstring(&b, authctxt->method->name);
1048: buffer_put_char(&b, have_sig);
1.30 markus 1049: if (!(datafellows & SSH_BUG_PKAUTH))
1.117 markus 1050: buffer_put_cstring(&b, key_ssh_name(id->key));
1.10 markus 1051: buffer_put_string(&b, blob, bloblen);
1052: }
1.197 djm 1053: free(blob);
1.51 markus 1054:
1.1 markus 1055: /* append signature */
1056: buffer_put_string(&b, signature, slen);
1.197 djm 1057: free(signature);
1.1 markus 1058:
1059: /* skip session id and packet type */
1.14 markus 1060: if (buffer_len(&b) < skip + 1)
1.20 markus 1061: fatal("userauth_pubkey: internal error");
1.14 markus 1062: buffer_consume(&b, skip + 1);
1.1 markus 1063:
1064: /* put remaining data from buffer into packet */
1065: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1066: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
1067: buffer_free(&b);
1068: packet_send();
1.17 markus 1069:
1070: return 1;
1.16 markus 1071: }
1072:
1.76 itojun 1073: static int
1.117 markus 1074: send_pubkey_test(Authctxt *authctxt, Identity *id)
1.20 markus 1075: {
1.51 markus 1076: u_char *blob;
1.97 markus 1077: u_int bloblen, have_sig = 0;
1.20 markus 1078:
1.51 markus 1079: debug3("send_pubkey_test");
1.16 markus 1080:
1.117 markus 1081: if (key_to_blob(id->key, &blob, &bloblen) == 0) {
1.51 markus 1082: /* we cannot handle this key */
1083: debug3("send_pubkey_test: cannot handle key");
1.16 markus 1084: return 0;
1085: }
1.51 markus 1086: /* register callback for USERAUTH_PK_OK message */
1087: dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
1088:
1089: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1090: packet_put_cstring(authctxt->server_user);
1091: packet_put_cstring(authctxt->service);
1092: packet_put_cstring(authctxt->method->name);
1093: packet_put_char(have_sig);
1094: if (!(datafellows & SSH_BUG_PKAUTH))
1.117 markus 1095: packet_put_cstring(key_ssh_name(id->key));
1.51 markus 1096: packet_put_string(blob, bloblen);
1.197 djm 1097: free(blob);
1.51 markus 1098: packet_send();
1099: return 1;
1100: }
1101:
1.76 itojun 1102: static Key *
1.191 dtucker 1103: load_identity_file(char *filename, int userprovided)
1.51 markus 1104: {
1105: Key *private;
1106: char prompt[300], *passphrase;
1.215 djm 1107: int r, perm_ok = 0, quit = 0, i;
1.52 markus 1108: struct stat st;
1.16 markus 1109:
1.52 markus 1110: if (stat(filename, &st) < 0) {
1.191 dtucker 1111: (userprovided ? logit : debug3)("no such identity: %s: %s",
1112: filename, strerror(errno));
1.52 markus 1113: return NULL;
1114: }
1.214 djm 1115: snprintf(prompt, sizeof prompt,
1116: "Enter passphrase for key '%.100s': ", filename);
1117: for (i = 0; i <= options.number_of_password_prompts; i++) {
1118: if (i == 0)
1119: passphrase = "";
1120: else {
1.20 markus 1121: passphrase = read_passphrase(prompt, 0);
1.214 djm 1122: if (*passphrase == '\0') {
1.20 markus 1123: debug2("no passphrase given, try next key");
1.214 djm 1124: free(passphrase);
1125: break;
1126: }
1127: }
1128: switch ((r = sshkey_load_private_type(KEY_UNSPEC, filename,
1129: passphrase, &private, NULL, &perm_ok))) {
1130: case 0:
1131: break;
1132: case SSH_ERR_KEY_WRONG_PASSPHRASE:
1133: if (options.batch_mode) {
1134: quit = 1;
1135: break;
1136: }
1.215 djm 1137: if (i != 0)
1138: debug2("bad passphrase given, try again...");
1.214 djm 1139: break;
1140: case SSH_ERR_SYSTEM_ERROR:
1141: if (errno == ENOENT) {
1142: debug2("Load key \"%s\": %s",
1143: filename, ssh_err(r));
1.51 markus 1144: quit = 1;
1.214 djm 1145: break;
1.20 markus 1146: }
1.214 djm 1147: /* FALLTHROUGH */
1148: default:
1149: error("Load key \"%s\": %s", filename, ssh_err(r));
1150: quit = 1;
1151: break;
1152: }
1153: if (i > 0) {
1.204 djm 1154: explicit_bzero(passphrase, strlen(passphrase));
1.197 djm 1155: free(passphrase);
1.16 markus 1156: }
1.214 djm 1157: if (private != NULL || quit)
1158: break;
1.16 markus 1159: }
1.51 markus 1160: return private;
1161: }
1162:
1.117 markus 1163: /*
1164: * try keys in the following order:
1165: * 1. agent keys that are found in the config file
1166: * 2. other agent keys
1167: * 3. keys that are only listed in the config file
1168: */
1169: static void
1170: pubkey_prepare(Authctxt *authctxt)
1.51 markus 1171: {
1.214 djm 1172: struct identity *id, *id2, *tmp;
1173: struct idlist agent, files, *preferred;
1174: struct sshkey *key;
1175: int agent_fd, i, r, found;
1176: size_t j;
1177: struct ssh_identitylist *idlist;
1.51 markus 1178:
1.117 markus 1179: TAILQ_INIT(&agent); /* keys from the agent */
1180: TAILQ_INIT(&files); /* keys from the config file */
1181: preferred = &authctxt->keys;
1182: TAILQ_INIT(preferred); /* preferred order of keys */
1183:
1.190 djm 1184: /* list of keys stored in the filesystem and PKCS#11 */
1.117 markus 1185: for (i = 0; i < options.num_identity_files; i++) {
1186: key = options.identity_keys[i];
1187: if (key && key->type == KEY_RSA1)
1.180 djm 1188: continue;
1189: if (key && key->cert && key->cert->type != SSH2_CERT_TYPE_USER)
1.117 markus 1190: continue;
1191: options.identity_keys[i] = NULL;
1.150 djm 1192: id = xcalloc(1, sizeof(*id));
1.117 markus 1193: id->key = key;
1194: id->filename = xstrdup(options.identity_files[i]);
1.192 dtucker 1195: id->userprovided = options.identity_file_userprovided[i];
1.117 markus 1196: TAILQ_INSERT_TAIL(&files, id, next);
1.190 djm 1197: }
1198: /* Prefer PKCS11 keys that are explicitly listed */
1199: TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
1.209 djm 1200: if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0)
1.190 djm 1201: continue;
1202: found = 0;
1203: TAILQ_FOREACH(id2, &files, next) {
1204: if (id2->key == NULL ||
1.209 djm 1205: (id2->key->flags & SSHKEY_FLAG_EXT) == 0)
1.190 djm 1206: continue;
1.214 djm 1207: if (sshkey_equal(id->key, id2->key)) {
1.190 djm 1208: TAILQ_REMOVE(&files, id, next);
1209: TAILQ_INSERT_TAIL(preferred, id, next);
1210: found = 1;
1211: break;
1212: }
1213: }
1214: /* If IdentitiesOnly set and key not found then don't use it */
1215: if (!found && options.identities_only) {
1216: TAILQ_REMOVE(&files, id, next);
1.203 tedu 1217: explicit_bzero(id, sizeof(*id));
1.190 djm 1218: free(id);
1219: }
1.117 markus 1220: }
1221: /* list of keys supported by the agent */
1.214 djm 1222: if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) {
1223: if (r != SSH_ERR_AGENT_NOT_PRESENT)
1224: debug("%s: ssh_get_authentication_socket: %s",
1225: __func__, ssh_err(r));
1226: } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) {
1227: if (r != SSH_ERR_AGENT_NO_IDENTITIES)
1228: debug("%s: ssh_fetch_identitylist: %s",
1229: __func__, ssh_err(r));
1230: } else {
1231: for (j = 0; j < idlist->nkeys; j++) {
1.117 markus 1232: found = 0;
1233: TAILQ_FOREACH(id, &files, next) {
1.214 djm 1234: /*
1235: * agent keys from the config file are
1236: * preferred
1237: */
1238: if (sshkey_equal(idlist->keys[j], id->key)) {
1.117 markus 1239: TAILQ_REMOVE(&files, id, next);
1240: TAILQ_INSERT_TAIL(preferred, id, next);
1.214 djm 1241: id->agent_fd = agent_fd;
1.117 markus 1242: found = 1;
1243: break;
1244: }
1245: }
1.135 markus 1246: if (!found && !options.identities_only) {
1.150 djm 1247: id = xcalloc(1, sizeof(*id));
1.214 djm 1248: /* XXX "steals" key/comment from idlist */
1249: id->key = idlist->keys[j];
1250: id->filename = idlist->comments[j];
1251: idlist->keys[j] = NULL;
1252: idlist->comments[j] = NULL;
1253: id->agent_fd = agent_fd;
1.117 markus 1254: TAILQ_INSERT_TAIL(&agent, id, next);
1255: }
1256: }
1.214 djm 1257: ssh_free_identitylist(idlist);
1.117 markus 1258: /* append remaining agent keys */
1259: for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) {
1260: TAILQ_REMOVE(&agent, id, next);
1261: TAILQ_INSERT_TAIL(preferred, id, next);
1262: }
1.214 djm 1263: authctxt->agent_fd = agent_fd;
1.117 markus 1264: }
1265: /* append remaining keys from the config file */
1266: for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) {
1267: TAILQ_REMOVE(&files, id, next);
1268: TAILQ_INSERT_TAIL(preferred, id, next);
1269: }
1270: TAILQ_FOREACH(id, preferred, next) {
1.191 dtucker 1271: debug2("key: %s (%p),%s", id->filename, id->key,
1272: id->userprovided ? " explicit" : "");
1.117 markus 1273: }
1.17 markus 1274: }
1275:
1.117 markus 1276: static void
1277: pubkey_cleanup(Authctxt *authctxt)
1.51 markus 1278: {
1.117 markus 1279: Identity *id;
1.51 markus 1280:
1.214 djm 1281: if (authctxt->agent_fd != -1)
1282: ssh_close_authentication_socket(authctxt->agent_fd);
1.117 markus 1283: for (id = TAILQ_FIRST(&authctxt->keys); id;
1284: id = TAILQ_FIRST(&authctxt->keys)) {
1285: TAILQ_REMOVE(&authctxt->keys, id, next);
1286: if (id->key)
1.214 djm 1287: sshkey_free(id->key);
1.197 djm 1288: free(id->filename);
1289: free(id);
1.117 markus 1290: }
1.1 markus 1291: }
1292:
1.20 markus 1293: int
1294: userauth_pubkey(Authctxt *authctxt)
1295: {
1.117 markus 1296: Identity *id;
1.20 markus 1297: int sent = 0;
1298:
1.117 markus 1299: while ((id = TAILQ_FIRST(&authctxt->keys))) {
1300: if (id->tried++)
1301: return (0);
1.127 markus 1302: /* move key to the end of the queue */
1.117 markus 1303: TAILQ_REMOVE(&authctxt->keys, id, next);
1304: TAILQ_INSERT_TAIL(&authctxt->keys, id, next);
1305: /*
1306: * send a test message if we have the public key. for
1307: * encrypted keys we cannot do this and have to load the
1308: * private key instead
1309: */
1.200 djm 1310: if (id->key != NULL) {
1311: if (key_type_plain(id->key->type) == KEY_RSA &&
1312: (datafellows & SSH_BUG_RSASIGMD5) != 0) {
1313: debug("Skipped %s key %s for RSA/MD5 server",
1314: key_type(id->key), id->filename);
1315: } else if (id->key->type != KEY_RSA1) {
1316: debug("Offering %s public key: %s",
1317: key_type(id->key), id->filename);
1318: sent = send_pubkey_test(authctxt, id);
1319: }
1320: } else {
1.117 markus 1321: debug("Trying private key: %s", id->filename);
1.191 dtucker 1322: id->key = load_identity_file(id->filename,
1323: id->userprovided);
1.117 markus 1324: if (id->key != NULL) {
1325: id->isprivate = 1;
1.200 djm 1326: if (key_type_plain(id->key->type) == KEY_RSA &&
1327: (datafellows & SSH_BUG_RSASIGMD5) != 0) {
1328: debug("Skipped %s key %s for RSA/MD5 "
1329: "server", key_type(id->key),
1330: id->filename);
1331: } else {
1332: sent = sign_and_send_pubkey(
1333: authctxt, id);
1334: }
1.117 markus 1335: key_free(id->key);
1336: id->key = NULL;
1.51 markus 1337: }
1338: }
1.117 markus 1339: if (sent)
1340: return (sent);
1.28 markus 1341: }
1.117 markus 1342: return (0);
1.20 markus 1343: }
1344:
1.23 markus 1345: /*
1346: * Send userauth request message specifying keyboard-interactive method.
1347: */
1348: int
1349: userauth_kbdint(Authctxt *authctxt)
1350: {
1351: static int attempt = 0;
1352:
1353: if (attempt++ >= options.number_of_password_prompts)
1354: return 0;
1.82 markus 1355: /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
1356: if (attempt > 1 && !authctxt->info_req_seen) {
1357: debug3("userauth_kbdint: disable: no info_req_seen");
1358: dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
1359: return 0;
1360: }
1.23 markus 1361:
1362: debug2("userauth_kbdint");
1363: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1364: packet_put_cstring(authctxt->server_user);
1365: packet_put_cstring(authctxt->service);
1366: packet_put_cstring(authctxt->method->name);
1367: packet_put_cstring(""); /* lang */
1368: packet_put_cstring(options.kbd_interactive_devices ?
1369: options.kbd_interactive_devices : "");
1370: packet_send();
1371:
1372: dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
1373: return 1;
1374: }
1375:
1376: /*
1.46 markus 1377: * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
1.23 markus 1378: */
1379: void
1.92 markus 1380: input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
1.23 markus 1381: {
1382: Authctxt *authctxt = ctxt;
1.46 markus 1383: char *name, *inst, *lang, *prompt, *response;
1.32 markus 1384: u_int num_prompts, i;
1.23 markus 1385: int echo = 0;
1386:
1387: debug2("input_userauth_info_req");
1388:
1389: if (authctxt == NULL)
1390: fatal("input_userauth_info_req: no authentication context");
1.82 markus 1391:
1392: authctxt->info_req_seen = 1;
1.23 markus 1393:
1394: name = packet_get_string(NULL);
1395: inst = packet_get_string(NULL);
1396: lang = packet_get_string(NULL);
1397: if (strlen(name) > 0)
1.116 itojun 1398: logit("%s", name);
1.23 markus 1399: if (strlen(inst) > 0)
1.116 itojun 1400: logit("%s", inst);
1.197 djm 1401: free(name);
1402: free(inst);
1403: free(lang);
1.23 markus 1404:
1405: num_prompts = packet_get_int();
1406: /*
1407: * Begin to build info response packet based on prompts requested.
1408: * We commit to providing the correct number of responses, so if
1409: * further on we run into a problem that prevents this, we have to
1410: * be sure and clean this up and send a correct error response.
1411: */
1412: packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
1413: packet_put_int(num_prompts);
1414:
1.73 markus 1415: debug2("input_userauth_info_req: num_prompts %d", num_prompts);
1.23 markus 1416: for (i = 0; i < num_prompts; i++) {
1417: prompt = packet_get_string(NULL);
1418: echo = packet_get_char();
1419:
1.77 markus 1420: response = read_passphrase(prompt, echo ? RP_ECHO : 0);
1.23 markus 1421:
1.49 markus 1422: packet_put_cstring(response);
1.204 djm 1423: explicit_bzero(response, strlen(response));
1.197 djm 1424: free(response);
1425: free(prompt);
1.23 markus 1426: }
1.90 markus 1427: packet_check_eom(); /* done with parsing incoming message. */
1.23 markus 1428:
1.85 markus 1429: packet_add_padding(64);
1.23 markus 1430: packet_send();
1.68 markus 1431: }
1432:
1.100 markus 1433: static int
1.105 deraadt 1434: ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
1.100 markus 1435: u_char *data, u_int datalen)
1436: {
1437: Buffer b;
1.101 markus 1438: struct stat st;
1.100 markus 1439: pid_t pid;
1.103 markus 1440: int to[2], from[2], status, version = 2;
1.100 markus 1441:
1.109 markus 1442: debug2("ssh_keysign called");
1.100 markus 1443:
1.101 markus 1444: if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
1.179 dtucker 1445: error("ssh_keysign: not installed: %s", strerror(errno));
1.101 markus 1446: return -1;
1447: }
1.100 markus 1448: if (fflush(stdout) != 0)
1449: error("ssh_keysign: fflush: %s", strerror(errno));
1450: if (pipe(to) < 0) {
1451: error("ssh_keysign: pipe: %s", strerror(errno));
1452: return -1;
1453: }
1454: if (pipe(from) < 0) {
1455: error("ssh_keysign: pipe: %s", strerror(errno));
1456: return -1;
1457: }
1458: if ((pid = fork()) < 0) {
1459: error("ssh_keysign: fork: %s", strerror(errno));
1460: return -1;
1461: }
1462: if (pid == 0) {
1.174 dtucker 1463: /* keep the socket on exec */
1464: fcntl(packet_get_connection_in(), F_SETFD, 0);
1.155 markus 1465: permanently_drop_suid(getuid());
1.100 markus 1466: close(from[0]);
1467: if (dup2(from[1], STDOUT_FILENO) < 0)
1468: fatal("ssh_keysign: dup2: %s", strerror(errno));
1469: close(to[1]);
1470: if (dup2(to[0], STDIN_FILENO) < 0)
1471: fatal("ssh_keysign: dup2: %s", strerror(errno));
1.103 markus 1472: close(from[1]);
1473: close(to[0]);
1.102 markus 1474: execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
1.100 markus 1475: fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
1476: strerror(errno));
1477: }
1478: close(from[1]);
1479: close(to[0]);
1480:
1481: buffer_init(&b);
1.103 markus 1482: buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
1.100 markus 1483: buffer_put_string(&b, data, datalen);
1.131 djm 1484: if (ssh_msg_send(to[1], version, &b) == -1)
1485: fatal("ssh_keysign: couldn't send request");
1.100 markus 1486:
1.110 djm 1487: if (ssh_msg_recv(from[0], &b) < 0) {
1.101 markus 1488: error("ssh_keysign: no reply");
1.134 markus 1489: buffer_free(&b);
1.100 markus 1490: return -1;
1491: }
1.101 markus 1492: close(from[0]);
1493: close(to[1]);
1494:
1.103 markus 1495: while (waitpid(pid, &status, 0) < 0)
1496: if (errno != EINTR)
1497: break;
1.101 markus 1498:
1.100 markus 1499: if (buffer_get_char(&b) != version) {
1.101 markus 1500: error("ssh_keysign: bad version");
1.134 markus 1501: buffer_free(&b);
1.100 markus 1502: return -1;
1503: }
1504: *sigp = buffer_get_string(&b, lenp);
1.134 markus 1505: buffer_free(&b);
1.100 markus 1506:
1507: return 0;
1508: }
1509:
1.68 markus 1510: int
1511: userauth_hostbased(Authctxt *authctxt)
1512: {
1513: Key *private = NULL;
1.100 markus 1514: Sensitive *sensitive = authctxt->sensitive;
1.68 markus 1515: Buffer b;
1516: u_char *signature, *blob;
1.179 dtucker 1517: char *chost, *pkalg, *p;
1.72 markus 1518: const char *service;
1.68 markus 1519: u_int blen, slen;
1.176 dtucker 1520: int ok, i, found = 0;
1.213 djm 1521:
1522: /* XXX provide some way to allow user to specify key types attempted */
1.68 markus 1523:
1524: /* check for a useful key */
1.100 markus 1525: for (i = 0; i < sensitive->nkeys; i++) {
1526: private = sensitive->keys[i];
1.68 markus 1527: if (private && private->type != KEY_RSA1) {
1528: found = 1;
1529: /* we take and free the key */
1.100 markus 1530: sensitive->keys[i] = NULL;
1.68 markus 1531: break;
1532: }
1533: }
1534: if (!found) {
1.109 markus 1535: debug("No more client hostkeys for hostbased authentication.");
1.68 markus 1536: return 0;
1537: }
1.211 djm 1538:
1539: debug("%s: trying hostkey type %s", __func__, key_type(private));
1540:
1.68 markus 1541: if (key_to_blob(private, &blob, &blen) == 0) {
1542: key_free(private);
1543: return 0;
1544: }
1.211 djm 1545:
1.84 markus 1546: /* figure out a name for the client host */
1.179 dtucker 1547: p = get_local_name(packet_get_connection_in());
1.84 markus 1548: if (p == NULL) {
1549: error("userauth_hostbased: cannot get local ipaddr/name");
1550: key_free(private);
1.197 djm 1551: free(blob);
1.84 markus 1552: return 0;
1553: }
1.150 djm 1554: xasprintf(&chost, "%s.", p);
1.84 markus 1555: debug2("userauth_hostbased: chost %s", chost);
1.197 djm 1556: free(p);
1.84 markus 1557:
1.72 markus 1558: service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1559: authctxt->service;
1.68 markus 1560: pkalg = xstrdup(key_ssh_name(private));
1561: buffer_init(&b);
1562: /* construct data */
1.72 markus 1563: buffer_put_string(&b, session_id2, session_id2_len);
1.68 markus 1564: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1565: buffer_put_cstring(&b, authctxt->server_user);
1.72 markus 1566: buffer_put_cstring(&b, service);
1.68 markus 1567: buffer_put_cstring(&b, authctxt->method->name);
1568: buffer_put_cstring(&b, pkalg);
1569: buffer_put_string(&b, blob, blen);
1570: buffer_put_cstring(&b, chost);
1571: buffer_put_cstring(&b, authctxt->local_user);
1572: #ifdef DEBUG_PK
1573: buffer_dump(&b);
1574: #endif
1.100 markus 1575: if (sensitive->external_keysign)
1576: ok = ssh_keysign(private, &signature, &slen,
1577: buffer_ptr(&b), buffer_len(&b));
1578: else
1579: ok = key_sign(private, &signature, &slen,
1580: buffer_ptr(&b), buffer_len(&b));
1.68 markus 1581: key_free(private);
1582: buffer_free(&b);
1583: if (ok != 0) {
1584: error("key_sign failed");
1.197 djm 1585: free(chost);
1586: free(pkalg);
1587: free(blob);
1.68 markus 1588: return 0;
1589: }
1590: packet_start(SSH2_MSG_USERAUTH_REQUEST);
1591: packet_put_cstring(authctxt->server_user);
1592: packet_put_cstring(authctxt->service);
1593: packet_put_cstring(authctxt->method->name);
1594: packet_put_cstring(pkalg);
1595: packet_put_string(blob, blen);
1596: packet_put_cstring(chost);
1597: packet_put_cstring(authctxt->local_user);
1598: packet_put_string(signature, slen);
1.204 djm 1599: explicit_bzero(signature, slen);
1.197 djm 1600: free(signature);
1601: free(chost);
1602: free(pkalg);
1603: free(blob);
1.68 markus 1604:
1605: packet_send();
1606: return 1;
1.23 markus 1607: }
1.170 djm 1608:
1.20 markus 1609: /* find auth method */
1610:
1611: /*
1612: * given auth method name, if configurable options permit this method fill
1613: * in auth_ident field and return true, otherwise return false.
1614: */
1.76 itojun 1615: static int
1.20 markus 1616: authmethod_is_enabled(Authmethod *method)
1617: {
1618: if (method == NULL)
1619: return 0;
1620: /* return false if options indicate this method is disabled */
1621: if (method->enabled == NULL || *method->enabled == 0)
1622: return 0;
1623: /* return false if batch mode is enabled but method needs interactive mode */
1624: if (method->batch_flag != NULL && *method->batch_flag != 0)
1625: return 0;
1626: return 1;
1627: }
1628:
1.76 itojun 1629: static Authmethod *
1.20 markus 1630: authmethod_lookup(const char *name)
1.1 markus 1631: {
1.20 markus 1632: Authmethod *method = NULL;
1633: if (name != NULL)
1634: for (method = authmethods; method->name != NULL; method++)
1635: if (strcmp(name, method->name) == 0)
1636: return method;
1637: debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1638: return NULL;
1639: }
1.1 markus 1640:
1.53 markus 1641: /* XXX internal state */
1642: static Authmethod *current = NULL;
1643: static char *supported = NULL;
1644: static char *preferred = NULL;
1.105 deraadt 1645:
1.20 markus 1646: /*
1647: * Given the authentication method list sent by the server, return the
1648: * next method we should try. If the server initially sends a nil list,
1.67 markus 1649: * use a built-in default list.
1.41 stevesk 1650: */
1.76 itojun 1651: static Authmethod *
1.20 markus 1652: authmethod_get(char *authlist)
1653: {
1.53 markus 1654: char *name = NULL;
1.97 markus 1655: u_int next;
1.41 stevesk 1656:
1.20 markus 1657: /* Use a suitable default if we're passed a nil list. */
1658: if (authlist == NULL || strlen(authlist) == 0)
1.53 markus 1659: authlist = options.preferred_authentications;
1.20 markus 1660:
1.53 markus 1661: if (supported == NULL || strcmp(authlist, supported) != 0) {
1662: debug3("start over, passed a different list %s", authlist);
1.197 djm 1663: free(supported);
1.53 markus 1664: supported = xstrdup(authlist);
1665: preferred = options.preferred_authentications;
1666: debug3("preferred %s", preferred);
1667: current = NULL;
1668: } else if (current != NULL && authmethod_is_enabled(current))
1669: return current;
1.20 markus 1670:
1.53 markus 1671: for (;;) {
1672: if ((name = match_list(preferred, supported, &next)) == NULL) {
1.109 markus 1673: debug("No more authentication methods to try.");
1.53 markus 1674: current = NULL;
1675: return NULL;
1676: }
1677: preferred += next;
1.23 markus 1678: debug3("authmethod_lookup %s", name);
1.53 markus 1679: debug3("remaining preferred: %s", preferred);
1680: if ((current = authmethod_lookup(name)) != NULL &&
1681: authmethod_is_enabled(current)) {
1.23 markus 1682: debug3("authmethod_is_enabled %s", name);
1.109 markus 1683: debug("Next authentication method: %s", name);
1.197 djm 1684: free(name);
1.53 markus 1685: return current;
1.23 markus 1686: }
1.198 dtucker 1687: free(name);
1.1 markus 1688: }
1.53 markus 1689: }
1.1 markus 1690:
1.79 stevesk 1691: static char *
1.53 markus 1692: authmethods_get(void)
1693: {
1694: Authmethod *method = NULL;
1.93 markus 1695: Buffer b;
1696: char *list;
1.27 provos 1697:
1.93 markus 1698: buffer_init(&b);
1.53 markus 1699: for (method = authmethods; method->name != NULL; method++) {
1700: if (authmethod_is_enabled(method)) {
1.93 markus 1701: if (buffer_len(&b) > 0)
1702: buffer_append(&b, ",", 1);
1703: buffer_append(&b, method->name, strlen(method->name));
1.53 markus 1704: }
1705: }
1.93 markus 1706: buffer_append(&b, "\0", 1);
1707: list = xstrdup(buffer_ptr(&b));
1708: buffer_free(&b);
1709: return list;
1.1 markus 1710: }
1.170 djm 1711: