sshconnect2.c revision 98684
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"
26RCSID("$OpenBSD: sshconnect2.c,v 1.104 2002/06/19 00:27:55 deraadt Exp $");
27RCSID("$FreeBSD: head/crypto/openssh/sshconnect2.c 98684 2002-06-23 16:09:08Z des $");
28
29#include "ssh.h"
30#include "ssh2.h"
31#include "xmalloc.h"
32#include "buffer.h"
33#include "packet.h"
34#include "compat.h"
35#include "bufaux.h"
36#include "cipher.h"
37#include "kex.h"
38#include "myproposal.h"
39#include "sshconnect.h"
40#include "authfile.h"
41#include "dh.h"
42#include "authfd.h"
43#include "log.h"
44#include "readconf.h"
45#include "readpass.h"
46#include "match.h"
47#include "dispatch.h"
48#include "canohost.h"
49#include "msg.h"
50#include "pathnames.h"
51
52/* import */
53extern char *client_version_string;
54extern char *server_version_string;
55extern Options options;
56
57/*
58 * SSH2 key exchange
59 */
60
61u_char *session_id2 = NULL;
62int session_id2_len = 0;
63
64char *xxx_host;
65struct sockaddr *xxx_hostaddr;
66
67Kex *xxx_kex = NULL;
68
69static int
70verify_host_key_callback(Key *hostkey)
71{
72	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
73		fatal("Host key verification failed.");
74	return 0;
75}
76
77void
78ssh_kex2(char *host, struct sockaddr *hostaddr)
79{
80	Kex *kex;
81
82	xxx_host = host;
83	xxx_hostaddr = hostaddr;
84
85	if (options.ciphers == (char *)-1) {
86		log("No valid ciphers for protocol version 2 given, using defaults.");
87		options.ciphers = NULL;
88	}
89	if (options.ciphers != NULL) {
90		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
91		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
92	}
93	myproposal[PROPOSAL_ENC_ALGS_CTOS] =
94	    compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
95	myproposal[PROPOSAL_ENC_ALGS_STOC] =
96	    compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
97	if (options.compression) {
98		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
99		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
100	} else {
101		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
102		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
103	}
104	if (options.macs != NULL) {
105		myproposal[PROPOSAL_MAC_ALGS_CTOS] =
106		myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
107	}
108	if (options.hostkeyalgorithms != NULL)
109		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
110		    options.hostkeyalgorithms;
111
112	/* start key exchange */
113	kex = kex_setup(myproposal);
114	kex->client_version_string=client_version_string;
115	kex->server_version_string=server_version_string;
116	kex->verify_host_key=&verify_host_key_callback;
117
118	xxx_kex = kex;
119
120	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
121
122	session_id2 = kex->session_id;
123	session_id2_len = kex->session_id_len;
124
125#ifdef DEBUG_KEXDH
126	/* send 1st encrypted/maced/compressed message */
127	packet_start(SSH2_MSG_IGNORE);
128	packet_put_cstring("markus");
129	packet_send();
130	packet_write_wait();
131#endif
132	debug("done: ssh_kex2.");
133}
134
135/*
136 * Authenticate user
137 */
138
139typedef struct Authctxt Authctxt;
140typedef struct Authmethod Authmethod;
141
142typedef int sign_cb_fn(
143    Authctxt *authctxt, Key *key,
144    u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
145
146struct Authctxt {
147	const char *server_user;
148	const char *local_user;
149	const char *host;
150	const char *service;
151	Authmethod *method;
152	int success;
153	char *authlist;
154	/* pubkey */
155	Key *last_key;
156	sign_cb_fn *last_key_sign;
157	int last_key_hint;
158	AuthenticationConnection *agent;
159	/* hostbased */
160	Sensitive *sensitive;
161	/* kbd-interactive */
162	int info_req_seen;
163};
164struct Authmethod {
165	char	*name;		/* string to compare against server's list */
166	int	(*userauth)(Authctxt *authctxt);
167	int	*enabled;	/* flag in option struct that enables method */
168	int	*batch_flag;	/* flag in option struct that disables method */
169};
170
171void	input_userauth_success(int, u_int32_t, void *);
172void	input_userauth_failure(int, u_int32_t, void *);
173void	input_userauth_banner(int, u_int32_t, void *);
174void	input_userauth_error(int, u_int32_t, void *);
175void	input_userauth_info_req(int, u_int32_t, void *);
176void	input_userauth_pk_ok(int, u_int32_t, void *);
177void	input_userauth_passwd_changereq(int, u_int32_t, void *);
178
179int	userauth_none(Authctxt *);
180int	userauth_pubkey(Authctxt *);
181int	userauth_passwd(Authctxt *);
182int	userauth_kbdint(Authctxt *);
183int	userauth_hostbased(Authctxt *);
184
185void	userauth(Authctxt *, char *);
186
187static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
188static void clear_auth_state(Authctxt *);
189
190static Authmethod *authmethod_get(char *authlist);
191static Authmethod *authmethod_lookup(const char *name);
192static char *authmethods_get(void);
193
194Authmethod authmethods[] = {
195	{"hostbased",
196		userauth_hostbased,
197		&options.hostbased_authentication,
198		NULL},
199	{"publickey",
200		userauth_pubkey,
201		&options.pubkey_authentication,
202		NULL},
203	{"keyboard-interactive",
204		userauth_kbdint,
205		&options.kbd_interactive_authentication,
206		&options.batch_mode},
207	{"password",
208		userauth_passwd,
209		&options.password_authentication,
210		&options.batch_mode},
211	{"none",
212		userauth_none,
213		NULL,
214		NULL},
215	{NULL, NULL, NULL, NULL}
216};
217
218void
219ssh_userauth2(const char *local_user, const char *server_user, char *host,
220    Sensitive *sensitive)
221{
222	Authctxt authctxt;
223	int type;
224
225	if (options.challenge_response_authentication)
226		options.kbd_interactive_authentication = 1;
227
228	debug("send SSH2_MSG_SERVICE_REQUEST");
229	packet_start(SSH2_MSG_SERVICE_REQUEST);
230	packet_put_cstring("ssh-userauth");
231	packet_send();
232	packet_write_wait();
233	type = packet_read();
234	if (type != SSH2_MSG_SERVICE_ACCEPT) {
235		fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
236	}
237	if (packet_remaining() > 0) {
238		char *reply = packet_get_string(NULL);
239		debug("service_accept: %s", reply);
240		xfree(reply);
241	} else {
242		debug("buggy server: service_accept w/o service");
243	}
244	packet_check_eom();
245	debug("got SSH2_MSG_SERVICE_ACCEPT");
246
247	if (options.preferred_authentications == NULL)
248		options.preferred_authentications = authmethods_get();
249
250	/* setup authentication context */
251	memset(&authctxt, 0, sizeof(authctxt));
252	authctxt.agent = ssh_get_authentication_connection();
253	authctxt.server_user = server_user;
254	authctxt.local_user = local_user;
255	authctxt.host = host;
256	authctxt.service = "ssh-connection";		/* service name */
257	authctxt.success = 0;
258	authctxt.method = authmethod_lookup("none");
259	authctxt.authlist = NULL;
260	authctxt.sensitive = sensitive;
261	authctxt.info_req_seen = 0;
262	if (authctxt.method == NULL)
263		fatal("ssh_userauth2: internal error: cannot send userauth none request");
264
265	/* initial userauth request */
266	userauth_none(&authctxt);
267
268	dispatch_init(&input_userauth_error);
269	dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
270	dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
271	dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner);
272	dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);	/* loop until success */
273
274	if (authctxt.agent != NULL)
275		ssh_close_authentication_connection(authctxt.agent);
276
277	debug("ssh-userauth2 successful: method %s", authctxt.method->name);
278}
279void
280userauth(Authctxt *authctxt, char *authlist)
281{
282	if (authlist == NULL) {
283		authlist = authctxt->authlist;
284	} else {
285		if (authctxt->authlist)
286			xfree(authctxt->authlist);
287		authctxt->authlist = authlist;
288	}
289	for (;;) {
290		Authmethod *method = authmethod_get(authlist);
291		if (method == NULL)
292			fatal("Permission denied (%s).", authlist);
293		authctxt->method = method;
294		if (method->userauth(authctxt) != 0) {
295			debug2("we sent a %s packet, wait for reply", method->name);
296			break;
297		} else {
298			debug2("we did not send a packet, disable method");
299			method->enabled = NULL;
300		}
301	}
302}
303void
304input_userauth_error(int type, u_int32_t seq, void *ctxt)
305{
306	fatal("input_userauth_error: bad message during authentication: "
307	   "type %d", type);
308}
309void
310input_userauth_banner(int type, u_int32_t seq, void *ctxt)
311{
312	char *msg, *lang;
313	debug3("input_userauth_banner");
314	msg = packet_get_string(NULL);
315	lang = packet_get_string(NULL);
316	fprintf(stderr, "%s", msg);
317	xfree(msg);
318	xfree(lang);
319}
320void
321input_userauth_success(int type, u_int32_t seq, void *ctxt)
322{
323	Authctxt *authctxt = ctxt;
324	if (authctxt == NULL)
325		fatal("input_userauth_success: no authentication context");
326	if (authctxt->authlist)
327		xfree(authctxt->authlist);
328	clear_auth_state(authctxt);
329	authctxt->success = 1;			/* break out */
330}
331void
332input_userauth_failure(int type, u_int32_t seq, void *ctxt)
333{
334	Authctxt *authctxt = ctxt;
335	char *authlist = NULL;
336	int partial;
337
338	if (authctxt == NULL)
339		fatal("input_userauth_failure: no authentication context");
340
341	authlist = packet_get_string(NULL);
342	partial = packet_get_char();
343	packet_check_eom();
344
345	if (partial != 0)
346		log("Authenticated with partial success.");
347	debug("authentications that can continue: %s", authlist);
348
349	clear_auth_state(authctxt);
350	userauth(authctxt, authlist);
351}
352void
353input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
354{
355	Authctxt *authctxt = ctxt;
356	Key *key = NULL;
357	Buffer b;
358	int pktype, sent = 0;
359	u_int alen, blen;
360	char *pkalg, *fp;
361	u_char *pkblob;
362
363	if (authctxt == NULL)
364		fatal("input_userauth_pk_ok: no authentication context");
365	if (datafellows & SSH_BUG_PKOK) {
366		/* this is similar to SSH_BUG_PKAUTH */
367		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
368		pkblob = packet_get_string(&blen);
369		buffer_init(&b);
370		buffer_append(&b, pkblob, blen);
371		pkalg = buffer_get_string(&b, &alen);
372		buffer_free(&b);
373	} else {
374		pkalg = packet_get_string(&alen);
375		pkblob = packet_get_string(&blen);
376	}
377	packet_check_eom();
378
379	debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
380	    pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
381
382	do {
383		if (authctxt->last_key == NULL ||
384		    authctxt->last_key_sign == NULL) {
385			debug("no last key or no sign cb");
386			break;
387		}
388		if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
389			debug("unknown pkalg %s", pkalg);
390			break;
391		}
392		if ((key = key_from_blob(pkblob, blen)) == NULL) {
393			debug("no key from blob. pkalg %s", pkalg);
394			break;
395		}
396		if (key->type != pktype) {
397			error("input_userauth_pk_ok: type mismatch "
398			    "for decoded key (received %d, expected %d)",
399			    key->type, pktype);
400			break;
401		}
402		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
403		debug2("input_userauth_pk_ok: fp %s", fp);
404		xfree(fp);
405		if (!key_equal(key, authctxt->last_key)) {
406			debug("key != last_key");
407			break;
408		}
409		sent = sign_and_send_pubkey(authctxt, key,
410		   authctxt->last_key_sign);
411	} while (0);
412
413	if (key != NULL)
414		key_free(key);
415	xfree(pkalg);
416	xfree(pkblob);
417
418	/* unregister */
419	clear_auth_state(authctxt);
420	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
421
422	/* try another method if we did not send a packet*/
423	if (sent == 0)
424		userauth(authctxt, NULL);
425
426}
427
428int
429userauth_none(Authctxt *authctxt)
430{
431	/* initial userauth request */
432	packet_start(SSH2_MSG_USERAUTH_REQUEST);
433	packet_put_cstring(authctxt->server_user);
434	packet_put_cstring(authctxt->service);
435	packet_put_cstring(authctxt->method->name);
436	packet_send();
437	return 1;
438}
439
440int
441userauth_passwd(Authctxt *authctxt)
442{
443	static int attempt = 0;
444	char prompt[150];
445	char *password;
446
447	if (attempt++ >= options.number_of_password_prompts)
448		return 0;
449
450	if (attempt != 1)
451		error("Permission denied, please try again.");
452
453	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
454	    authctxt->server_user, authctxt->host);
455	password = read_passphrase(prompt, 0);
456	packet_start(SSH2_MSG_USERAUTH_REQUEST);
457	packet_put_cstring(authctxt->server_user);
458	packet_put_cstring(authctxt->service);
459	packet_put_cstring(authctxt->method->name);
460	packet_put_char(0);
461	packet_put_cstring(password);
462	memset(password, 0, strlen(password));
463	xfree(password);
464	packet_add_padding(64);
465	packet_send();
466
467	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
468	    &input_userauth_passwd_changereq);
469
470	return 1;
471}
472/*
473 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
474 */
475void
476input_userauth_passwd_changereq(int type, uint32_t seqnr, void *ctxt)
477{
478	Authctxt *authctxt = ctxt;
479	char *info, *lang, *password = NULL, *retype = NULL;
480	char prompt[150];
481
482	debug2("input_userauth_passwd_changereq");
483
484	if (authctxt == NULL)
485		fatal("input_userauth_passwd_changereq: "
486		    "no authentication context");
487
488	info = packet_get_string(NULL);
489	lang = packet_get_string(NULL);
490	if (strlen(info) > 0)
491		log("%s", info);
492	xfree(info);
493	xfree(lang);
494	packet_start(SSH2_MSG_USERAUTH_REQUEST);
495	packet_put_cstring(authctxt->server_user);
496	packet_put_cstring(authctxt->service);
497	packet_put_cstring(authctxt->method->name);
498	packet_put_char(1);			/* additional info */
499	snprintf(prompt, sizeof(prompt),
500	    "Enter %.30s@%.128s's old password: ",
501	    authctxt->server_user, authctxt->host);
502	password = read_passphrase(prompt, 0);
503	packet_put_cstring(password);
504	memset(password, 0, strlen(password));
505	xfree(password);
506	password = NULL;
507	while (password == NULL) {
508		snprintf(prompt, sizeof(prompt),
509		    "Enter %.30s@%.128s's new password: ",
510		    authctxt->server_user, authctxt->host);
511		password = read_passphrase(prompt, RP_ALLOW_EOF);
512		if (password == NULL) {
513			/* bail out */
514			return;
515		}
516		snprintf(prompt, sizeof(prompt),
517		    "Retype %.30s@%.128s's new password: ",
518		    authctxt->server_user, authctxt->host);
519		retype = read_passphrase(prompt, 0);
520		if (strcmp(password, retype) != 0) {
521			memset(password, 0, strlen(password));
522			xfree(password);
523			log("Mismatch; try again, EOF to quit.");
524			password = NULL;
525		}
526		memset(retype, 0, strlen(retype));
527		xfree(retype);
528	}
529	packet_put_cstring(password);
530	memset(password, 0, strlen(password));
531	xfree(password);
532	packet_add_padding(64);
533	packet_send();
534
535	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
536	    &input_userauth_passwd_changereq);
537}
538
539static void
540clear_auth_state(Authctxt *authctxt)
541{
542	/* XXX clear authentication state */
543	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
544
545	if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
546		debug3("clear_auth_state: key_free %p", authctxt->last_key);
547		key_free(authctxt->last_key);
548	}
549	authctxt->last_key = NULL;
550	authctxt->last_key_hint = -2;
551	authctxt->last_key_sign = NULL;
552}
553
554static int
555sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
556{
557	Buffer b;
558	u_char *blob, *signature;
559	u_int bloblen, slen;
560	int skip = 0;
561	int ret = -1;
562	int have_sig = 1;
563
564	debug3("sign_and_send_pubkey");
565
566	if (key_to_blob(k, &blob, &bloblen) == 0) {
567		/* we cannot handle this key */
568		debug3("sign_and_send_pubkey: cannot handle key");
569		return 0;
570	}
571	/* data to be signed */
572	buffer_init(&b);
573	if (datafellows & SSH_OLD_SESSIONID) {
574		buffer_append(&b, session_id2, session_id2_len);
575		skip = session_id2_len;
576	} else {
577		buffer_put_string(&b, session_id2, session_id2_len);
578		skip = buffer_len(&b);
579	}
580	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
581	buffer_put_cstring(&b, authctxt->server_user);
582	buffer_put_cstring(&b,
583	    datafellows & SSH_BUG_PKSERVICE ?
584	    "ssh-userauth" :
585	    authctxt->service);
586	if (datafellows & SSH_BUG_PKAUTH) {
587		buffer_put_char(&b, have_sig);
588	} else {
589		buffer_put_cstring(&b, authctxt->method->name);
590		buffer_put_char(&b, have_sig);
591		buffer_put_cstring(&b, key_ssh_name(k));
592	}
593	buffer_put_string(&b, blob, bloblen);
594
595	/* generate signature */
596	ret = (*sign_callback)(authctxt, k, &signature, &slen,
597	    buffer_ptr(&b), buffer_len(&b));
598	if (ret == -1) {
599		xfree(blob);
600		buffer_free(&b);
601		return 0;
602	}
603#ifdef DEBUG_PK
604	buffer_dump(&b);
605#endif
606	if (datafellows & SSH_BUG_PKSERVICE) {
607		buffer_clear(&b);
608		buffer_append(&b, session_id2, session_id2_len);
609		skip = session_id2_len;
610		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
611		buffer_put_cstring(&b, authctxt->server_user);
612		buffer_put_cstring(&b, authctxt->service);
613		buffer_put_cstring(&b, authctxt->method->name);
614		buffer_put_char(&b, have_sig);
615		if (!(datafellows & SSH_BUG_PKAUTH))
616			buffer_put_cstring(&b, key_ssh_name(k));
617		buffer_put_string(&b, blob, bloblen);
618	}
619	xfree(blob);
620
621	/* append signature */
622	buffer_put_string(&b, signature, slen);
623	xfree(signature);
624
625	/* skip session id and packet type */
626	if (buffer_len(&b) < skip + 1)
627		fatal("userauth_pubkey: internal error");
628	buffer_consume(&b, skip + 1);
629
630	/* put remaining data from buffer into packet */
631	packet_start(SSH2_MSG_USERAUTH_REQUEST);
632	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
633	buffer_free(&b);
634	packet_send();
635
636	return 1;
637}
638
639static int
640send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
641    int hint)
642{
643	u_char *blob;
644	u_int bloblen, have_sig = 0;
645
646	debug3("send_pubkey_test");
647
648	if (key_to_blob(k, &blob, &bloblen) == 0) {
649		/* we cannot handle this key */
650		debug3("send_pubkey_test: cannot handle key");
651		return 0;
652	}
653	/* register callback for USERAUTH_PK_OK message */
654	authctxt->last_key_sign = sign_callback;
655	authctxt->last_key_hint = hint;
656	authctxt->last_key = k;
657	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
658
659	packet_start(SSH2_MSG_USERAUTH_REQUEST);
660	packet_put_cstring(authctxt->server_user);
661	packet_put_cstring(authctxt->service);
662	packet_put_cstring(authctxt->method->name);
663	packet_put_char(have_sig);
664	if (!(datafellows & SSH_BUG_PKAUTH))
665		packet_put_cstring(key_ssh_name(k));
666	packet_put_string(blob, bloblen);
667	xfree(blob);
668	packet_send();
669	return 1;
670}
671
672static Key *
673load_identity_file(char *filename)
674{
675	Key *private;
676	char prompt[300], *passphrase;
677	int quit, i;
678	struct stat st;
679
680	if (stat(filename, &st) < 0) {
681		debug3("no such identity: %s", filename);
682		return NULL;
683	}
684	private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
685	if (private == NULL) {
686		if (options.batch_mode)
687			return NULL;
688		snprintf(prompt, sizeof prompt,
689		    "Enter passphrase for key '%.100s': ", filename);
690		for (i = 0; i < options.number_of_password_prompts; i++) {
691			passphrase = read_passphrase(prompt, 0);
692			if (strcmp(passphrase, "") != 0) {
693				private = key_load_private_type(KEY_UNSPEC, filename,
694				    passphrase, NULL);
695				quit = 0;
696			} else {
697				debug2("no passphrase given, try next key");
698				quit = 1;
699			}
700			memset(passphrase, 0, strlen(passphrase));
701			xfree(passphrase);
702			if (private != NULL || quit)
703				break;
704			debug2("bad passphrase given, try again...");
705		}
706	}
707	return private;
708}
709
710static int
711identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
712    u_char *data, u_int datalen)
713{
714	Key *private;
715	int idx, ret;
716
717	idx = authctxt->last_key_hint;
718	if (idx < 0)
719		return -1;
720
721	/* private key is stored in external hardware */
722	if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
723		return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
724
725	private = load_identity_file(options.identity_files[idx]);
726	if (private == NULL)
727		return -1;
728	ret = key_sign(private, sigp, lenp, data, datalen);
729	key_free(private);
730	return ret;
731}
732
733static int
734agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
735    u_char *data, u_int datalen)
736{
737	return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
738}
739
740static int
741key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
742    u_char *data, u_int datalen)
743{
744	return key_sign(key, sigp, lenp, data, datalen);
745}
746
747static int
748userauth_pubkey_agent(Authctxt *authctxt)
749{
750	static int called = 0;
751	int ret = 0;
752	char *comment;
753	Key *k;
754
755	if (called == 0) {
756		if (ssh_get_num_identities(authctxt->agent, 2) == 0)
757			debug2("userauth_pubkey_agent: no keys at all");
758		called = 1;
759	}
760	k = ssh_get_next_identity(authctxt->agent, &comment, 2);
761	if (k == NULL) {
762		debug2("userauth_pubkey_agent: no more keys");
763	} else {
764		debug("userauth_pubkey_agent: testing agent key %s", comment);
765		xfree(comment);
766		ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
767		if (ret == 0)
768			key_free(k);
769	}
770	if (ret == 0)
771		debug2("userauth_pubkey_agent: no message sent");
772	return ret;
773}
774
775int
776userauth_pubkey(Authctxt *authctxt)
777{
778	static int idx = 0;
779	int sent = 0;
780	Key *key;
781	char *filename;
782
783	if (authctxt->agent != NULL) {
784		do {
785			sent = userauth_pubkey_agent(authctxt);
786		} while (!sent && authctxt->agent->howmany > 0);
787	}
788	while (!sent && idx < options.num_identity_files) {
789		key = options.identity_keys[idx];
790		filename = options.identity_files[idx];
791		if (key == NULL) {
792			debug("try privkey: %s", filename);
793			key = load_identity_file(filename);
794			if (key != NULL) {
795				sent = sign_and_send_pubkey(authctxt, key,
796				    key_sign_cb);
797				key_free(key);
798			}
799		} else if (key->type != KEY_RSA1) {
800			debug("try pubkey: %s", filename);
801			sent = send_pubkey_test(authctxt, key,
802			    identity_sign_cb, idx);
803		}
804		idx++;
805	}
806	return sent;
807}
808
809/*
810 * Send userauth request message specifying keyboard-interactive method.
811 */
812int
813userauth_kbdint(Authctxt *authctxt)
814{
815	static int attempt = 0;
816
817	if (attempt++ >= options.number_of_password_prompts)
818		return 0;
819	/* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
820	if (attempt > 1 && !authctxt->info_req_seen) {
821		debug3("userauth_kbdint: disable: no info_req_seen");
822		dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
823		return 0;
824	}
825
826	debug2("userauth_kbdint");
827	packet_start(SSH2_MSG_USERAUTH_REQUEST);
828	packet_put_cstring(authctxt->server_user);
829	packet_put_cstring(authctxt->service);
830	packet_put_cstring(authctxt->method->name);
831	packet_put_cstring("");					/* lang */
832	packet_put_cstring(options.kbd_interactive_devices ?
833	    options.kbd_interactive_devices : "");
834	packet_send();
835
836	dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
837	return 1;
838}
839
840/*
841 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
842 */
843void
844input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
845{
846	Authctxt *authctxt = ctxt;
847	char *name, *inst, *lang, *prompt, *response;
848	u_int num_prompts, i;
849	int echo = 0;
850
851	debug2("input_userauth_info_req");
852
853	if (authctxt == NULL)
854		fatal("input_userauth_info_req: no authentication context");
855
856	authctxt->info_req_seen = 1;
857
858	name = packet_get_string(NULL);
859	inst = packet_get_string(NULL);
860	lang = packet_get_string(NULL);
861	if (strlen(name) > 0)
862		log("%s", name);
863	if (strlen(inst) > 0)
864		log("%s", inst);
865	xfree(name);
866	xfree(inst);
867	xfree(lang);
868
869	num_prompts = packet_get_int();
870	/*
871	 * Begin to build info response packet based on prompts requested.
872	 * We commit to providing the correct number of responses, so if
873	 * further on we run into a problem that prevents this, we have to
874	 * be sure and clean this up and send a correct error response.
875	 */
876	packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
877	packet_put_int(num_prompts);
878
879	debug2("input_userauth_info_req: num_prompts %d", num_prompts);
880	for (i = 0; i < num_prompts; i++) {
881		prompt = packet_get_string(NULL);
882		echo = packet_get_char();
883
884		response = read_passphrase(prompt, echo ? RP_ECHO : 0);
885
886		packet_put_cstring(response);
887		memset(response, 0, strlen(response));
888		xfree(response);
889		xfree(prompt);
890	}
891	packet_check_eom(); /* done with parsing incoming message. */
892
893	packet_add_padding(64);
894	packet_send();
895}
896
897static int
898ssh_keysign(
899    Key *key,
900    u_char **sigp, u_int *lenp,
901    u_char *data, u_int datalen)
902{
903	Buffer b;
904	struct stat st;
905	pid_t pid;
906	int to[2], from[2], status, version = 2;
907
908	debug("ssh_keysign called");
909
910	if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
911		error("ssh_keysign: no installed: %s", strerror(errno));
912		return -1;
913	}
914	if (fflush(stdout) != 0)
915		error("ssh_keysign: fflush: %s", strerror(errno));
916	if (pipe(to) < 0) {
917		error("ssh_keysign: pipe: %s", strerror(errno));
918		return -1;
919	}
920	if (pipe(from) < 0) {
921		error("ssh_keysign: pipe: %s", strerror(errno));
922		return -1;
923	}
924	if ((pid = fork()) < 0) {
925		error("ssh_keysign: fork: %s", strerror(errno));
926		return -1;
927	}
928	if (pid == 0) {
929		seteuid(getuid());
930		setuid(getuid());
931		close(from[0]);
932		if (dup2(from[1], STDOUT_FILENO) < 0)
933			fatal("ssh_keysign: dup2: %s", strerror(errno));
934		close(to[1]);
935		if (dup2(to[0], STDIN_FILENO) < 0)
936			fatal("ssh_keysign: dup2: %s", strerror(errno));
937		close(from[1]);
938		close(to[0]);
939		execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
940		fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
941		    strerror(errno));
942	}
943	close(from[1]);
944	close(to[0]);
945
946	buffer_init(&b);
947	buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
948	buffer_put_string(&b, data, datalen);
949	msg_send(to[1], version, &b);
950
951	if (msg_recv(from[0], &b) < 0) {
952		error("ssh_keysign: no reply");
953		buffer_clear(&b);
954		return -1;
955	}
956	close(from[0]);
957	close(to[1]);
958
959	while (waitpid(pid, &status, 0) < 0)
960		if (errno != EINTR)
961			break;
962
963	if (buffer_get_char(&b) != version) {
964		error("ssh_keysign: bad version");
965		buffer_clear(&b);
966		return -1;
967	}
968	*sigp = buffer_get_string(&b, lenp);
969	buffer_clear(&b);
970
971	return 0;
972}
973
974int
975userauth_hostbased(Authctxt *authctxt)
976{
977	Key *private = NULL;
978	Sensitive *sensitive = authctxt->sensitive;
979	Buffer b;
980	u_char *signature, *blob;
981	char *chost, *pkalg, *p;
982	const char *service;
983	u_int blen, slen;
984	int ok, i, len, found = 0;
985
986	/* check for a useful key */
987	for (i = 0; i < sensitive->nkeys; i++) {
988		private = sensitive->keys[i];
989		if (private && private->type != KEY_RSA1) {
990			found = 1;
991			/* we take and free the key */
992			sensitive->keys[i] = NULL;
993			break;
994		}
995	}
996	if (!found) {
997		debug("userauth_hostbased: no more client hostkeys");
998		return 0;
999	}
1000	if (key_to_blob(private, &blob, &blen) == 0) {
1001		key_free(private);
1002		return 0;
1003	}
1004	/* figure out a name for the client host */
1005	p = get_local_name(packet_get_connection_in());
1006	if (p == NULL) {
1007		error("userauth_hostbased: cannot get local ipaddr/name");
1008		key_free(private);
1009		return 0;
1010	}
1011	len = strlen(p) + 2;
1012	chost = xmalloc(len);
1013	strlcpy(chost, p, len);
1014	strlcat(chost, ".", len);
1015	debug2("userauth_hostbased: chost %s", chost);
1016
1017	service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1018	    authctxt->service;
1019	pkalg = xstrdup(key_ssh_name(private));
1020	buffer_init(&b);
1021	/* construct data */
1022	buffer_put_string(&b, session_id2, session_id2_len);
1023	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1024	buffer_put_cstring(&b, authctxt->server_user);
1025	buffer_put_cstring(&b, service);
1026	buffer_put_cstring(&b, authctxt->method->name);
1027	buffer_put_cstring(&b, pkalg);
1028	buffer_put_string(&b, blob, blen);
1029	buffer_put_cstring(&b, chost);
1030	buffer_put_cstring(&b, authctxt->local_user);
1031#ifdef DEBUG_PK
1032	buffer_dump(&b);
1033#endif
1034	if (sensitive->external_keysign)
1035		ok = ssh_keysign(private, &signature, &slen,
1036		    buffer_ptr(&b), buffer_len(&b));
1037	else
1038		ok = key_sign(private, &signature, &slen,
1039		    buffer_ptr(&b), buffer_len(&b));
1040	key_free(private);
1041	buffer_free(&b);
1042	if (ok != 0) {
1043		error("key_sign failed");
1044		xfree(chost);
1045		xfree(pkalg);
1046		return 0;
1047	}
1048	packet_start(SSH2_MSG_USERAUTH_REQUEST);
1049	packet_put_cstring(authctxt->server_user);
1050	packet_put_cstring(authctxt->service);
1051	packet_put_cstring(authctxt->method->name);
1052	packet_put_cstring(pkalg);
1053	packet_put_string(blob, blen);
1054	packet_put_cstring(chost);
1055	packet_put_cstring(authctxt->local_user);
1056	packet_put_string(signature, slen);
1057	memset(signature, 's', slen);
1058	xfree(signature);
1059	xfree(chost);
1060	xfree(pkalg);
1061
1062	packet_send();
1063	return 1;
1064}
1065
1066/* find auth method */
1067
1068/*
1069 * given auth method name, if configurable options permit this method fill
1070 * in auth_ident field and return true, otherwise return false.
1071 */
1072static int
1073authmethod_is_enabled(Authmethod *method)
1074{
1075	if (method == NULL)
1076		return 0;
1077	/* return false if options indicate this method is disabled */
1078	if  (method->enabled == NULL || *method->enabled == 0)
1079		return 0;
1080	/* return false if batch mode is enabled but method needs interactive mode */
1081	if  (method->batch_flag != NULL && *method->batch_flag != 0)
1082		return 0;
1083	return 1;
1084}
1085
1086static Authmethod *
1087authmethod_lookup(const char *name)
1088{
1089	Authmethod *method = NULL;
1090	if (name != NULL)
1091		for (method = authmethods; method->name != NULL; method++)
1092			if (strcmp(name, method->name) == 0)
1093				return method;
1094	debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1095	return NULL;
1096}
1097
1098/* XXX internal state */
1099static Authmethod *current = NULL;
1100static char *supported = NULL;
1101static char *preferred = NULL;
1102/*
1103 * Given the authentication method list sent by the server, return the
1104 * next method we should try.  If the server initially sends a nil list,
1105 * use a built-in default list.
1106 */
1107static Authmethod *
1108authmethod_get(char *authlist)
1109{
1110
1111	char *name = NULL;
1112	u_int next;
1113
1114	/* Use a suitable default if we're passed a nil list.  */
1115	if (authlist == NULL || strlen(authlist) == 0)
1116		authlist = options.preferred_authentications;
1117
1118	if (supported == NULL || strcmp(authlist, supported) != 0) {
1119		debug3("start over, passed a different list %s", authlist);
1120		if (supported != NULL)
1121			xfree(supported);
1122		supported = xstrdup(authlist);
1123		preferred = options.preferred_authentications;
1124		debug3("preferred %s", preferred);
1125		current = NULL;
1126	} else if (current != NULL && authmethod_is_enabled(current))
1127		return current;
1128
1129	for (;;) {
1130		if ((name = match_list(preferred, supported, &next)) == NULL) {
1131			debug("no more auth methods to try");
1132			current = NULL;
1133			return NULL;
1134		}
1135		preferred += next;
1136		debug3("authmethod_lookup %s", name);
1137		debug3("remaining preferred: %s", preferred);
1138		if ((current = authmethod_lookup(name)) != NULL &&
1139		    authmethod_is_enabled(current)) {
1140			debug3("authmethod_is_enabled %s", name);
1141			debug("next auth method to try is %s", name);
1142			return current;
1143		}
1144	}
1145}
1146
1147static char *
1148authmethods_get(void)
1149{
1150	Authmethod *method = NULL;
1151	Buffer b;
1152	char *list;
1153
1154	buffer_init(&b);
1155	for (method = authmethods; method->name != NULL; method++) {
1156		if (authmethod_is_enabled(method)) {
1157			if (buffer_len(&b) > 0)
1158				buffer_append(&b, ",", 1);
1159			buffer_append(&b, method->name, strlen(method->name));
1160		}
1161	}
1162	buffer_append(&b, "\0", 1);
1163	list = xstrdup(buffer_ptr(&b));
1164	buffer_free(&b);
1165	return list;
1166}
1167