sshconnect2.c revision 99063
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.105 2002/06/23 03:30:17 deraadt Exp $");
27RCSID("$FreeBSD: head/crypto/openssh/sshconnect2.c 99063 2002-06-29 11:48:59Z 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}
303
304void
305input_userauth_error(int type, u_int32_t seq, void *ctxt)
306{
307	fatal("input_userauth_error: bad message during authentication: "
308	   "type %d", type);
309}
310
311void
312input_userauth_banner(int type, u_int32_t seq, void *ctxt)
313{
314	char *msg, *lang;
315	debug3("input_userauth_banner");
316	msg = packet_get_string(NULL);
317	lang = packet_get_string(NULL);
318	fprintf(stderr, "%s", msg);
319	xfree(msg);
320	xfree(lang);
321}
322
323void
324input_userauth_success(int type, u_int32_t seq, void *ctxt)
325{
326	Authctxt *authctxt = ctxt;
327	if (authctxt == NULL)
328		fatal("input_userauth_success: no authentication context");
329	if (authctxt->authlist)
330		xfree(authctxt->authlist);
331	clear_auth_state(authctxt);
332	authctxt->success = 1;			/* break out */
333}
334
335void
336input_userauth_failure(int type, u_int32_t seq, void *ctxt)
337{
338	Authctxt *authctxt = ctxt;
339	char *authlist = NULL;
340	int partial;
341
342	if (authctxt == NULL)
343		fatal("input_userauth_failure: no authentication context");
344
345	authlist = packet_get_string(NULL);
346	partial = packet_get_char();
347	packet_check_eom();
348
349	if (partial != 0)
350		log("Authenticated with partial success.");
351	debug("authentications that can continue: %s", authlist);
352
353	clear_auth_state(authctxt);
354	userauth(authctxt, authlist);
355}
356void
357input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
358{
359	Authctxt *authctxt = ctxt;
360	Key *key = NULL;
361	Buffer b;
362	int pktype, sent = 0;
363	u_int alen, blen;
364	char *pkalg, *fp;
365	u_char *pkblob;
366
367	if (authctxt == NULL)
368		fatal("input_userauth_pk_ok: no authentication context");
369	if (datafellows & SSH_BUG_PKOK) {
370		/* this is similar to SSH_BUG_PKAUTH */
371		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
372		pkblob = packet_get_string(&blen);
373		buffer_init(&b);
374		buffer_append(&b, pkblob, blen);
375		pkalg = buffer_get_string(&b, &alen);
376		buffer_free(&b);
377	} else {
378		pkalg = packet_get_string(&alen);
379		pkblob = packet_get_string(&blen);
380	}
381	packet_check_eom();
382
383	debug("input_userauth_pk_ok: pkalg %s blen %u lastkey %p hint %d",
384	    pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
385
386	do {
387		if (authctxt->last_key == NULL ||
388		    authctxt->last_key_sign == NULL) {
389			debug("no last key or no sign cb");
390			break;
391		}
392		if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
393			debug("unknown pkalg %s", pkalg);
394			break;
395		}
396		if ((key = key_from_blob(pkblob, blen)) == NULL) {
397			debug("no key from blob. pkalg %s", pkalg);
398			break;
399		}
400		if (key->type != pktype) {
401			error("input_userauth_pk_ok: type mismatch "
402			    "for decoded key (received %d, expected %d)",
403			    key->type, pktype);
404			break;
405		}
406		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
407		debug2("input_userauth_pk_ok: fp %s", fp);
408		xfree(fp);
409		if (!key_equal(key, authctxt->last_key)) {
410			debug("key != last_key");
411			break;
412		}
413		sent = sign_and_send_pubkey(authctxt, key,
414		   authctxt->last_key_sign);
415	} while (0);
416
417	if (key != NULL)
418		key_free(key);
419	xfree(pkalg);
420	xfree(pkblob);
421
422	/* unregister */
423	clear_auth_state(authctxt);
424	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
425
426	/* try another method if we did not send a packet*/
427	if (sent == 0)
428		userauth(authctxt, NULL);
429
430}
431
432int
433userauth_none(Authctxt *authctxt)
434{
435	/* initial userauth request */
436	packet_start(SSH2_MSG_USERAUTH_REQUEST);
437	packet_put_cstring(authctxt->server_user);
438	packet_put_cstring(authctxt->service);
439	packet_put_cstring(authctxt->method->name);
440	packet_send();
441	return 1;
442}
443
444int
445userauth_passwd(Authctxt *authctxt)
446{
447	static int attempt = 0;
448	char prompt[150];
449	char *password;
450
451	if (attempt++ >= options.number_of_password_prompts)
452		return 0;
453
454	if (attempt != 1)
455		error("Permission denied, please try again.");
456
457	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
458	    authctxt->server_user, authctxt->host);
459	password = read_passphrase(prompt, 0);
460	packet_start(SSH2_MSG_USERAUTH_REQUEST);
461	packet_put_cstring(authctxt->server_user);
462	packet_put_cstring(authctxt->service);
463	packet_put_cstring(authctxt->method->name);
464	packet_put_char(0);
465	packet_put_cstring(password);
466	memset(password, 0, strlen(password));
467	xfree(password);
468	packet_add_padding(64);
469	packet_send();
470
471	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
472	    &input_userauth_passwd_changereq);
473
474	return 1;
475}
476/*
477 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
478 */
479void
480input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
481{
482	Authctxt *authctxt = ctxt;
483	char *info, *lang, *password = NULL, *retype = NULL;
484	char prompt[150];
485
486	debug2("input_userauth_passwd_changereq");
487
488	if (authctxt == NULL)
489		fatal("input_userauth_passwd_changereq: "
490		    "no authentication context");
491
492	info = packet_get_string(NULL);
493	lang = packet_get_string(NULL);
494	if (strlen(info) > 0)
495		log("%s", info);
496	xfree(info);
497	xfree(lang);
498	packet_start(SSH2_MSG_USERAUTH_REQUEST);
499	packet_put_cstring(authctxt->server_user);
500	packet_put_cstring(authctxt->service);
501	packet_put_cstring(authctxt->method->name);
502	packet_put_char(1);			/* additional info */
503	snprintf(prompt, sizeof(prompt),
504	    "Enter %.30s@%.128s's old password: ",
505	    authctxt->server_user, authctxt->host);
506	password = read_passphrase(prompt, 0);
507	packet_put_cstring(password);
508	memset(password, 0, strlen(password));
509	xfree(password);
510	password = NULL;
511	while (password == NULL) {
512		snprintf(prompt, sizeof(prompt),
513		    "Enter %.30s@%.128s's new password: ",
514		    authctxt->server_user, authctxt->host);
515		password = read_passphrase(prompt, RP_ALLOW_EOF);
516		if (password == NULL) {
517			/* bail out */
518			return;
519		}
520		snprintf(prompt, sizeof(prompt),
521		    "Retype %.30s@%.128s's new password: ",
522		    authctxt->server_user, authctxt->host);
523		retype = read_passphrase(prompt, 0);
524		if (strcmp(password, retype) != 0) {
525			memset(password, 0, strlen(password));
526			xfree(password);
527			log("Mismatch; try again, EOF to quit.");
528			password = NULL;
529		}
530		memset(retype, 0, strlen(retype));
531		xfree(retype);
532	}
533	packet_put_cstring(password);
534	memset(password, 0, strlen(password));
535	xfree(password);
536	packet_add_padding(64);
537	packet_send();
538
539	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
540	    &input_userauth_passwd_changereq);
541}
542
543static void
544clear_auth_state(Authctxt *authctxt)
545{
546	/* XXX clear authentication state */
547	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
548
549	if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
550		debug3("clear_auth_state: key_free %p", authctxt->last_key);
551		key_free(authctxt->last_key);
552	}
553	authctxt->last_key = NULL;
554	authctxt->last_key_hint = -2;
555	authctxt->last_key_sign = NULL;
556}
557
558static int
559sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
560{
561	Buffer b;
562	u_char *blob, *signature;
563	u_int bloblen, slen;
564	int skip = 0;
565	int ret = -1;
566	int have_sig = 1;
567
568	debug3("sign_and_send_pubkey");
569
570	if (key_to_blob(k, &blob, &bloblen) == 0) {
571		/* we cannot handle this key */
572		debug3("sign_and_send_pubkey: cannot handle key");
573		return 0;
574	}
575	/* data to be signed */
576	buffer_init(&b);
577	if (datafellows & SSH_OLD_SESSIONID) {
578		buffer_append(&b, session_id2, session_id2_len);
579		skip = session_id2_len;
580	} else {
581		buffer_put_string(&b, session_id2, session_id2_len);
582		skip = buffer_len(&b);
583	}
584	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
585	buffer_put_cstring(&b, authctxt->server_user);
586	buffer_put_cstring(&b,
587	    datafellows & SSH_BUG_PKSERVICE ?
588	    "ssh-userauth" :
589	    authctxt->service);
590	if (datafellows & SSH_BUG_PKAUTH) {
591		buffer_put_char(&b, have_sig);
592	} else {
593		buffer_put_cstring(&b, authctxt->method->name);
594		buffer_put_char(&b, have_sig);
595		buffer_put_cstring(&b, key_ssh_name(k));
596	}
597	buffer_put_string(&b, blob, bloblen);
598
599	/* generate signature */
600	ret = (*sign_callback)(authctxt, k, &signature, &slen,
601	    buffer_ptr(&b), buffer_len(&b));
602	if (ret == -1) {
603		xfree(blob);
604		buffer_free(&b);
605		return 0;
606	}
607#ifdef DEBUG_PK
608	buffer_dump(&b);
609#endif
610	if (datafellows & SSH_BUG_PKSERVICE) {
611		buffer_clear(&b);
612		buffer_append(&b, session_id2, session_id2_len);
613		skip = session_id2_len;
614		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
615		buffer_put_cstring(&b, authctxt->server_user);
616		buffer_put_cstring(&b, authctxt->service);
617		buffer_put_cstring(&b, authctxt->method->name);
618		buffer_put_char(&b, have_sig);
619		if (!(datafellows & SSH_BUG_PKAUTH))
620			buffer_put_cstring(&b, key_ssh_name(k));
621		buffer_put_string(&b, blob, bloblen);
622	}
623	xfree(blob);
624
625	/* append signature */
626	buffer_put_string(&b, signature, slen);
627	xfree(signature);
628
629	/* skip session id and packet type */
630	if (buffer_len(&b) < skip + 1)
631		fatal("userauth_pubkey: internal error");
632	buffer_consume(&b, skip + 1);
633
634	/* put remaining data from buffer into packet */
635	packet_start(SSH2_MSG_USERAUTH_REQUEST);
636	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
637	buffer_free(&b);
638	packet_send();
639
640	return 1;
641}
642
643static int
644send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
645    int hint)
646{
647	u_char *blob;
648	u_int bloblen, have_sig = 0;
649
650	debug3("send_pubkey_test");
651
652	if (key_to_blob(k, &blob, &bloblen) == 0) {
653		/* we cannot handle this key */
654		debug3("send_pubkey_test: cannot handle key");
655		return 0;
656	}
657	/* register callback for USERAUTH_PK_OK message */
658	authctxt->last_key_sign = sign_callback;
659	authctxt->last_key_hint = hint;
660	authctxt->last_key = k;
661	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
662
663	packet_start(SSH2_MSG_USERAUTH_REQUEST);
664	packet_put_cstring(authctxt->server_user);
665	packet_put_cstring(authctxt->service);
666	packet_put_cstring(authctxt->method->name);
667	packet_put_char(have_sig);
668	if (!(datafellows & SSH_BUG_PKAUTH))
669		packet_put_cstring(key_ssh_name(k));
670	packet_put_string(blob, bloblen);
671	xfree(blob);
672	packet_send();
673	return 1;
674}
675
676static Key *
677load_identity_file(char *filename)
678{
679	Key *private;
680	char prompt[300], *passphrase;
681	int quit, i;
682	struct stat st;
683
684	if (stat(filename, &st) < 0) {
685		debug3("no such identity: %s", filename);
686		return NULL;
687	}
688	private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
689	if (private == NULL) {
690		if (options.batch_mode)
691			return NULL;
692		snprintf(prompt, sizeof prompt,
693		    "Enter passphrase for key '%.100s': ", filename);
694		for (i = 0; i < options.number_of_password_prompts; i++) {
695			passphrase = read_passphrase(prompt, 0);
696			if (strcmp(passphrase, "") != 0) {
697				private = key_load_private_type(KEY_UNSPEC, filename,
698				    passphrase, NULL);
699				quit = 0;
700			} else {
701				debug2("no passphrase given, try next key");
702				quit = 1;
703			}
704			memset(passphrase, 0, strlen(passphrase));
705			xfree(passphrase);
706			if (private != NULL || quit)
707				break;
708			debug2("bad passphrase given, try again...");
709		}
710	}
711	return private;
712}
713
714static int
715identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
716    u_char *data, u_int datalen)
717{
718	Key *private;
719	int idx, ret;
720
721	idx = authctxt->last_key_hint;
722	if (idx < 0)
723		return -1;
724
725	/* private key is stored in external hardware */
726	if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
727		return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
728
729	private = load_identity_file(options.identity_files[idx]);
730	if (private == NULL)
731		return -1;
732	ret = key_sign(private, sigp, lenp, data, datalen);
733	key_free(private);
734	return ret;
735}
736
737static int
738agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
739    u_char *data, u_int datalen)
740{
741	return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
742}
743
744static int
745key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
746    u_char *data, u_int datalen)
747{
748	return key_sign(key, sigp, lenp, data, datalen);
749}
750
751static int
752userauth_pubkey_agent(Authctxt *authctxt)
753{
754	static int called = 0;
755	int ret = 0;
756	char *comment;
757	Key *k;
758
759	if (called == 0) {
760		if (ssh_get_num_identities(authctxt->agent, 2) == 0)
761			debug2("userauth_pubkey_agent: no keys at all");
762		called = 1;
763	}
764	k = ssh_get_next_identity(authctxt->agent, &comment, 2);
765	if (k == NULL) {
766		debug2("userauth_pubkey_agent: no more keys");
767	} else {
768		debug("userauth_pubkey_agent: testing agent key %s", comment);
769		xfree(comment);
770		ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
771		if (ret == 0)
772			key_free(k);
773	}
774	if (ret == 0)
775		debug2("userauth_pubkey_agent: no message sent");
776	return ret;
777}
778
779int
780userauth_pubkey(Authctxt *authctxt)
781{
782	static int idx = 0;
783	int sent = 0;
784	Key *key;
785	char *filename;
786
787	if (authctxt->agent != NULL) {
788		do {
789			sent = userauth_pubkey_agent(authctxt);
790		} while (!sent && authctxt->agent->howmany > 0);
791	}
792	while (!sent && idx < options.num_identity_files) {
793		key = options.identity_keys[idx];
794		filename = options.identity_files[idx];
795		if (key == NULL) {
796			debug("try privkey: %s", filename);
797			key = load_identity_file(filename);
798			if (key != NULL) {
799				sent = sign_and_send_pubkey(authctxt, key,
800				    key_sign_cb);
801				key_free(key);
802			}
803		} else if (key->type != KEY_RSA1) {
804			debug("try pubkey: %s", filename);
805			sent = send_pubkey_test(authctxt, key,
806			    identity_sign_cb, idx);
807		}
808		idx++;
809	}
810	return sent;
811}
812
813/*
814 * Send userauth request message specifying keyboard-interactive method.
815 */
816int
817userauth_kbdint(Authctxt *authctxt)
818{
819	static int attempt = 0;
820
821	if (attempt++ >= options.number_of_password_prompts)
822		return 0;
823	/* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
824	if (attempt > 1 && !authctxt->info_req_seen) {
825		debug3("userauth_kbdint: disable: no info_req_seen");
826		dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
827		return 0;
828	}
829
830	debug2("userauth_kbdint");
831	packet_start(SSH2_MSG_USERAUTH_REQUEST);
832	packet_put_cstring(authctxt->server_user);
833	packet_put_cstring(authctxt->service);
834	packet_put_cstring(authctxt->method->name);
835	packet_put_cstring("");					/* lang */
836	packet_put_cstring(options.kbd_interactive_devices ?
837	    options.kbd_interactive_devices : "");
838	packet_send();
839
840	dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
841	return 1;
842}
843
844/*
845 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
846 */
847void
848input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
849{
850	Authctxt *authctxt = ctxt;
851	char *name, *inst, *lang, *prompt, *response;
852	u_int num_prompts, i;
853	int echo = 0;
854
855	debug2("input_userauth_info_req");
856
857	if (authctxt == NULL)
858		fatal("input_userauth_info_req: no authentication context");
859
860	authctxt->info_req_seen = 1;
861
862	name = packet_get_string(NULL);
863	inst = packet_get_string(NULL);
864	lang = packet_get_string(NULL);
865	if (strlen(name) > 0)
866		log("%s", name);
867	if (strlen(inst) > 0)
868		log("%s", inst);
869	xfree(name);
870	xfree(inst);
871	xfree(lang);
872
873	num_prompts = packet_get_int();
874	/*
875	 * Begin to build info response packet based on prompts requested.
876	 * We commit to providing the correct number of responses, so if
877	 * further on we run into a problem that prevents this, we have to
878	 * be sure and clean this up and send a correct error response.
879	 */
880	packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
881	packet_put_int(num_prompts);
882
883	debug2("input_userauth_info_req: num_prompts %d", num_prompts);
884	for (i = 0; i < num_prompts; i++) {
885		prompt = packet_get_string(NULL);
886		echo = packet_get_char();
887
888		response = read_passphrase(prompt, echo ? RP_ECHO : 0);
889
890		packet_put_cstring(response);
891		memset(response, 0, strlen(response));
892		xfree(response);
893		xfree(prompt);
894	}
895	packet_check_eom(); /* done with parsing incoming message. */
896
897	packet_add_padding(64);
898	packet_send();
899}
900
901static int
902ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
903    u_char *data, u_int datalen)
904{
905	Buffer b;
906	struct stat st;
907	pid_t pid;
908	int to[2], from[2], status, version = 2;
909
910	debug("ssh_keysign called");
911
912	if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
913		error("ssh_keysign: no installed: %s", strerror(errno));
914		return -1;
915	}
916	if (fflush(stdout) != 0)
917		error("ssh_keysign: fflush: %s", strerror(errno));
918	if (pipe(to) < 0) {
919		error("ssh_keysign: pipe: %s", strerror(errno));
920		return -1;
921	}
922	if (pipe(from) < 0) {
923		error("ssh_keysign: pipe: %s", strerror(errno));
924		return -1;
925	}
926	if ((pid = fork()) < 0) {
927		error("ssh_keysign: fork: %s", strerror(errno));
928		return -1;
929	}
930	if (pid == 0) {
931		seteuid(getuid());
932		setuid(getuid());
933		close(from[0]);
934		if (dup2(from[1], STDOUT_FILENO) < 0)
935			fatal("ssh_keysign: dup2: %s", strerror(errno));
936		close(to[1]);
937		if (dup2(to[0], STDIN_FILENO) < 0)
938			fatal("ssh_keysign: dup2: %s", strerror(errno));
939		close(from[1]);
940		close(to[0]);
941		execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
942		fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
943		    strerror(errno));
944	}
945	close(from[1]);
946	close(to[0]);
947
948	buffer_init(&b);
949	buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
950	buffer_put_string(&b, data, datalen);
951	msg_send(to[1], version, &b);
952
953	if (msg_recv(from[0], &b) < 0) {
954		error("ssh_keysign: no reply");
955		buffer_clear(&b);
956		return -1;
957	}
958	close(from[0]);
959	close(to[1]);
960
961	while (waitpid(pid, &status, 0) < 0)
962		if (errno != EINTR)
963			break;
964
965	if (buffer_get_char(&b) != version) {
966		error("ssh_keysign: bad version");
967		buffer_clear(&b);
968		return -1;
969	}
970	*sigp = buffer_get_string(&b, lenp);
971	buffer_clear(&b);
972
973	return 0;
974}
975
976int
977userauth_hostbased(Authctxt *authctxt)
978{
979	Key *private = NULL;
980	Sensitive *sensitive = authctxt->sensitive;
981	Buffer b;
982	u_char *signature, *blob;
983	char *chost, *pkalg, *p;
984	const char *service;
985	u_int blen, slen;
986	int ok, i, len, found = 0;
987
988	/* check for a useful key */
989	for (i = 0; i < sensitive->nkeys; i++) {
990		private = sensitive->keys[i];
991		if (private && private->type != KEY_RSA1) {
992			found = 1;
993			/* we take and free the key */
994			sensitive->keys[i] = NULL;
995			break;
996		}
997	}
998	if (!found) {
999		debug("userauth_hostbased: no more client hostkeys");
1000		return 0;
1001	}
1002	if (key_to_blob(private, &blob, &blen) == 0) {
1003		key_free(private);
1004		return 0;
1005	}
1006	/* figure out a name for the client host */
1007	p = get_local_name(packet_get_connection_in());
1008	if (p == NULL) {
1009		error("userauth_hostbased: cannot get local ipaddr/name");
1010		key_free(private);
1011		return 0;
1012	}
1013	len = strlen(p) + 2;
1014	chost = xmalloc(len);
1015	strlcpy(chost, p, len);
1016	strlcat(chost, ".", len);
1017	debug2("userauth_hostbased: chost %s", chost);
1018
1019	service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
1020	    authctxt->service;
1021	pkalg = xstrdup(key_ssh_name(private));
1022	buffer_init(&b);
1023	/* construct data */
1024	buffer_put_string(&b, session_id2, session_id2_len);
1025	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
1026	buffer_put_cstring(&b, authctxt->server_user);
1027	buffer_put_cstring(&b, service);
1028	buffer_put_cstring(&b, authctxt->method->name);
1029	buffer_put_cstring(&b, pkalg);
1030	buffer_put_string(&b, blob, blen);
1031	buffer_put_cstring(&b, chost);
1032	buffer_put_cstring(&b, authctxt->local_user);
1033#ifdef DEBUG_PK
1034	buffer_dump(&b);
1035#endif
1036	if (sensitive->external_keysign)
1037		ok = ssh_keysign(private, &signature, &slen,
1038		    buffer_ptr(&b), buffer_len(&b));
1039	else
1040		ok = key_sign(private, &signature, &slen,
1041		    buffer_ptr(&b), buffer_len(&b));
1042	key_free(private);
1043	buffer_free(&b);
1044	if (ok != 0) {
1045		error("key_sign failed");
1046		xfree(chost);
1047		xfree(pkalg);
1048		return 0;
1049	}
1050	packet_start(SSH2_MSG_USERAUTH_REQUEST);
1051	packet_put_cstring(authctxt->server_user);
1052	packet_put_cstring(authctxt->service);
1053	packet_put_cstring(authctxt->method->name);
1054	packet_put_cstring(pkalg);
1055	packet_put_string(blob, blen);
1056	packet_put_cstring(chost);
1057	packet_put_cstring(authctxt->local_user);
1058	packet_put_string(signature, slen);
1059	memset(signature, 's', slen);
1060	xfree(signature);
1061	xfree(chost);
1062	xfree(pkalg);
1063
1064	packet_send();
1065	return 1;
1066}
1067
1068/* find auth method */
1069
1070/*
1071 * given auth method name, if configurable options permit this method fill
1072 * in auth_ident field and return true, otherwise return false.
1073 */
1074static int
1075authmethod_is_enabled(Authmethod *method)
1076{
1077	if (method == NULL)
1078		return 0;
1079	/* return false if options indicate this method is disabled */
1080	if  (method->enabled == NULL || *method->enabled == 0)
1081		return 0;
1082	/* return false if batch mode is enabled but method needs interactive mode */
1083	if  (method->batch_flag != NULL && *method->batch_flag != 0)
1084		return 0;
1085	return 1;
1086}
1087
1088static Authmethod *
1089authmethod_lookup(const char *name)
1090{
1091	Authmethod *method = NULL;
1092	if (name != NULL)
1093		for (method = authmethods; method->name != NULL; method++)
1094			if (strcmp(name, method->name) == 0)
1095				return method;
1096	debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
1097	return NULL;
1098}
1099
1100/* XXX internal state */
1101static Authmethod *current = NULL;
1102static char *supported = NULL;
1103static char *preferred = NULL;
1104
1105/*
1106 * Given the authentication method list sent by the server, return the
1107 * next method we should try.  If the server initially sends a nil list,
1108 * use a built-in default list.
1109 */
1110static Authmethod *
1111authmethod_get(char *authlist)
1112{
1113
1114	char *name = NULL;
1115	u_int next;
1116
1117	/* Use a suitable default if we're passed a nil list.  */
1118	if (authlist == NULL || strlen(authlist) == 0)
1119		authlist = options.preferred_authentications;
1120
1121	if (supported == NULL || strcmp(authlist, supported) != 0) {
1122		debug3("start over, passed a different list %s", authlist);
1123		if (supported != NULL)
1124			xfree(supported);
1125		supported = xstrdup(authlist);
1126		preferred = options.preferred_authentications;
1127		debug3("preferred %s", preferred);
1128		current = NULL;
1129	} else if (current != NULL && authmethod_is_enabled(current))
1130		return current;
1131
1132	for (;;) {
1133		if ((name = match_list(preferred, supported, &next)) == NULL) {
1134			debug("no more auth methods to try");
1135			current = NULL;
1136			return NULL;
1137		}
1138		preferred += next;
1139		debug3("authmethod_lookup %s", name);
1140		debug3("remaining preferred: %s", preferred);
1141		if ((current = authmethod_lookup(name)) != NULL &&
1142		    authmethod_is_enabled(current)) {
1143			debug3("authmethod_is_enabled %s", name);
1144			debug("next auth method to try is %s", name);
1145			return current;
1146		}
1147	}
1148}
1149
1150static char *
1151authmethods_get(void)
1152{
1153	Authmethod *method = NULL;
1154	Buffer b;
1155	char *list;
1156
1157	buffer_init(&b);
1158	for (method = authmethods; method->name != NULL; method++) {
1159		if (authmethod_is_enabled(method)) {
1160			if (buffer_len(&b) > 0)
1161				buffer_append(&b, ",", 1);
1162			buffer_append(&b, method->name, strlen(method->name));
1163		}
1164	}
1165	buffer_append(&b, "\0", 1);
1166	list = xstrdup(buffer_ptr(&b));
1167	buffer_free(&b);
1168	return list;
1169}
1170