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