sshconnect2.c revision 114426
176861Skris/*
276861Skris * Copyright (c) 2000 Markus Friedl.  All rights reserved.
376861Skris *
476861Skris * Redistribution and use in source and binary forms, with or without
576861Skris * modification, are permitted provided that the following conditions
676861Skris * are met:
776861Skris * 1. Redistributions of source code must retain the above copyright
876861Skris *    notice, this list of conditions and the following disclaimer.
996316Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1096316Sobrien *    notice, this list of conditions and the following disclaimer in the
11189801Srdivacky *    documentation and/or other materials provided with the distribution.
12189801Srdivacky *
13189801Srdivacky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14220863Sdim * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15161214Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16220863Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17161214Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18220863Sdim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19161214Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20220863Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21161214Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22220863Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23161214Sdes */
24198365Sru
25220863Sdim#include "includes.h"
26161214SdesRCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $");
27161214Sdes
2876861Skris#include "ssh.h"
29140359Sobrien#include "ssh2.h"
30124372Sru#include "xmalloc.h"
3199542Sobrien#include "buffer.h"
32124372Sru#include "packet.h"
3399542Sobrien#include "compat.h"
3476861Skris#include "bufaux.h"
35140359Sobrien#include "cipher.h"
36124372Sru#include "kex.h"
3776861Skris#include "myproposal.h"
38140359Sobrien#include "sshconnect.h"
39140361Sobrien#include "authfile.h"
40140361Sobrien#include "dh.h"
4187976Sobrien#include "authfd.h"
42140359Sobrien#include "log.h"
43140361Sobrien#include "readconf.h"
44204025Smarcel#include "readpass.h"
45204025Smarcel#include "match.h"
46204025Smarcel#include "dispatch.h"
47204025Smarcel#include "canohost.h"
4887976Sobrien#include "msg.h"
4994332Sobrien#include "pathnames.h"
50140359Sobrien
51201300Sed/* import */
52201300Sedextern char *client_version_string;
5394332Sobrienextern char *server_version_string;
54140359Sobrienextern Options options;
5588936Sdwmalone
5688936Sdwmalone/*
57124372Sru * SSH2 key exchange
5888936Sdwmalone */
59169723Skan
6076861Skrisu_char *session_id2 = NULL;
6176861Skrisint session_id2_len = 0;
6276861Skris
6376861Skrischar *xxx_host;
6476861Skrisstruct sockaddr *xxx_hostaddr;
6576861Skris
6676861SkrisKex *xxx_kex = NULL;
67124372Sru
68124372Srustatic int
6999542Sobrienverify_host_key_callback(Key *hostkey)
70124372Sru{
7199542Sobrien	if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1)
7276861Skris		fatal("Host key verification failed.");
7376861Skris	return 0;
74219368Spjd}
75219368Spjd
76219368Spjdvoid
7776861Skrisssh_kex2(char *host, struct sockaddr *hostaddr)
7876861Skris{
79163971Sjb	Kex *kex;
80163971Sjb
81163971Sjb	xxx_host = host;
82163971Sjb	xxx_hostaddr = hostaddr;
83220863Sdim
84220863Sdim	if (options.ciphers == (char *)-1) {
85180012Sru		log("No valid ciphers for protocol version 2 given, using defaults.");
86180012Sru		options.ciphers = NULL;
87180012Sru	}
88180012Sru	if (options.ciphers != NULL) {
89180012Sru		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
9076861Skris		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
9176861Skris	}
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,none";
99	} else {
100		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
101		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
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->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
114	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
115	kex->client_version_string=client_version_string;
116	kex->server_version_string=server_version_string;
117	kex->verify_host_key=&verify_host_key_callback;
118
119	xxx_kex = kex;
120
121	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
122
123	session_id2 = kex->session_id;
124	session_id2_len = kex->session_id_len;
125
126#ifdef DEBUG_KEXDH
127	/* send 1st encrypted/maced/compressed message */
128	packet_start(SSH2_MSG_IGNORE);
129	packet_put_cstring("markus");
130	packet_send();
131	packet_write_wait();
132#endif
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	packet_start(SSH2_MSG_SERVICE_REQUEST);
229	packet_put_cstring("ssh-userauth");
230	packet_send();
231	debug("SSH2_MSG_SERVICE_REQUEST sent");
232	packet_write_wait();
233	type = packet_read();
234	if (type != SSH2_MSG_SERVICE_ACCEPT)
235		fatal("Server denied authentication request: %d", type);
236	if (packet_remaining() > 0) {
237		char *reply = packet_get_string(NULL);
238		debug2("service_accept: %s", reply);
239		xfree(reply);
240	} else {
241		debug2("buggy server: service_accept w/o service");
242	}
243	packet_check_eom();
244	debug("SSH2_MSG_SERVICE_ACCEPT received");
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("Authentication succeeded (%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}
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}
309
310void
311input_userauth_banner(int type, u_int32_t seq, void *ctxt)
312{
313	char *msg, *lang;
314	debug3("input_userauth_banner");
315	msg = packet_get_string(NULL);
316	lang = packet_get_string(NULL);
317	fprintf(stderr, "%s", msg);
318	xfree(msg);
319	xfree(lang);
320}
321
322void
323input_userauth_success(int type, u_int32_t seq, void *ctxt)
324{
325	Authctxt *authctxt = ctxt;
326	if (authctxt == NULL)
327		fatal("input_userauth_success: no authentication context");
328	if (authctxt->authlist)
329		xfree(authctxt->authlist);
330	clear_auth_state(authctxt);
331	authctxt->success = 1;			/* break out */
332}
333
334void
335input_userauth_failure(int type, u_int32_t seq, void *ctxt)
336{
337	Authctxt *authctxt = ctxt;
338	char *authlist = NULL;
339	int partial;
340
341	if (authctxt == NULL)
342		fatal("input_userauth_failure: no authentication context");
343
344	authlist = packet_get_string(NULL);
345	partial = packet_get_char();
346	packet_check_eom();
347
348	if (partial != 0)
349		log("Authenticated with partial success.");
350	debug("Authentications that can continue: %s", authlist);
351
352	clear_auth_state(authctxt);
353	userauth(authctxt, authlist);
354}
355void
356input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
357{
358	Authctxt *authctxt = ctxt;
359	Key *key = NULL;
360	Buffer b;
361	int pktype, sent = 0;
362	u_int alen, blen;
363	char *pkalg, *fp;
364	u_char *pkblob;
365
366	if (authctxt == NULL)
367		fatal("input_userauth_pk_ok: no authentication context");
368	if (datafellows & SSH_BUG_PKOK) {
369		/* this is similar to SSH_BUG_PKAUTH */
370		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
371		pkblob = packet_get_string(&blen);
372		buffer_init(&b);
373		buffer_append(&b, pkblob, blen);
374		pkalg = buffer_get_string(&b, &alen);
375		buffer_free(&b);
376	} else {
377		pkalg = packet_get_string(&alen);
378		pkblob = packet_get_string(&blen);
379	}
380	packet_check_eom();
381
382	debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
383	    pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
384
385	do {
386		if (authctxt->last_key == NULL ||
387		    authctxt->last_key_sign == NULL) {
388			debug("no last key or no sign cb");
389			break;
390		}
391		if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
392			debug("unknown pkalg %s", pkalg);
393			break;
394		}
395		if ((key = key_from_blob(pkblob, blen)) == NULL) {
396			debug("no key from blob. pkalg %s", pkalg);
397			break;
398		}
399		if (key->type != pktype) {
400			error("input_userauth_pk_ok: type mismatch "
401			    "for decoded key (received %d, expected %d)",
402			    key->type, pktype);
403			break;
404		}
405		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
406		debug2("input_userauth_pk_ok: fp %s", fp);
407		xfree(fp);
408		if (!key_equal(key, authctxt->last_key)) {
409			debug("key != last_key");
410			break;
411		}
412		sent = sign_and_send_pubkey(authctxt, key,
413		   authctxt->last_key_sign);
414	} while (0);
415
416	if (key != NULL)
417		key_free(key);
418	xfree(pkalg);
419	xfree(pkblob);
420
421	/* unregister */
422	clear_auth_state(authctxt);
423	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);
424
425	/* try another method if we did not send a packet */
426	if (sent == 0)
427		userauth(authctxt, NULL);
428
429}
430
431int
432userauth_none(Authctxt *authctxt)
433{
434	/* initial userauth request */
435	packet_start(SSH2_MSG_USERAUTH_REQUEST);
436	packet_put_cstring(authctxt->server_user);
437	packet_put_cstring(authctxt->service);
438	packet_put_cstring(authctxt->method->name);
439	packet_send();
440	return 1;
441}
442
443int
444userauth_passwd(Authctxt *authctxt)
445{
446	static int attempt = 0;
447	char prompt[150];
448	char *password;
449
450	if (attempt++ >= options.number_of_password_prompts)
451		return 0;
452
453	if (attempt != 1)
454		error("Permission denied, please try again.");
455
456	snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
457	    authctxt->server_user, authctxt->host);
458	password = read_passphrase(prompt, 0);
459	packet_start(SSH2_MSG_USERAUTH_REQUEST);
460	packet_put_cstring(authctxt->server_user);
461	packet_put_cstring(authctxt->service);
462	packet_put_cstring(authctxt->method->name);
463	packet_put_char(0);
464	packet_put_cstring(password);
465	memset(password, 0, strlen(password));
466	xfree(password);
467	packet_add_padding(64);
468	packet_send();
469
470	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
471	    &input_userauth_passwd_changereq);
472
473	return 1;
474}
475/*
476 * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST
477 */
478void
479input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt)
480{
481	Authctxt *authctxt = ctxt;
482	char *info, *lang, *password = NULL, *retype = NULL;
483	char prompt[150];
484
485	debug2("input_userauth_passwd_changereq");
486
487	if (authctxt == NULL)
488		fatal("input_userauth_passwd_changereq: "
489		    "no authentication context");
490
491	info = packet_get_string(NULL);
492	lang = packet_get_string(NULL);
493	if (strlen(info) > 0)
494		log("%s", info);
495	xfree(info);
496	xfree(lang);
497	packet_start(SSH2_MSG_USERAUTH_REQUEST);
498	packet_put_cstring(authctxt->server_user);
499	packet_put_cstring(authctxt->service);
500	packet_put_cstring(authctxt->method->name);
501	packet_put_char(1);			/* additional info */
502	snprintf(prompt, sizeof(prompt),
503	    "Enter %.30s@%.128s's old password: ",
504	    authctxt->server_user, authctxt->host);
505	password = read_passphrase(prompt, 0);
506	packet_put_cstring(password);
507	memset(password, 0, strlen(password));
508	xfree(password);
509	password = NULL;
510	while (password == NULL) {
511		snprintf(prompt, sizeof(prompt),
512		    "Enter %.30s@%.128s's new password: ",
513		    authctxt->server_user, authctxt->host);
514		password = read_passphrase(prompt, RP_ALLOW_EOF);
515		if (password == NULL) {
516			/* bail out */
517			return;
518		}
519		snprintf(prompt, sizeof(prompt),
520		    "Retype %.30s@%.128s's new password: ",
521		    authctxt->server_user, authctxt->host);
522		retype = read_passphrase(prompt, 0);
523		if (strcmp(password, retype) != 0) {
524			memset(password, 0, strlen(password));
525			xfree(password);
526			log("Mismatch; try again, EOF to quit.");
527			password = NULL;
528		}
529		memset(retype, 0, strlen(retype));
530		xfree(retype);
531	}
532	packet_put_cstring(password);
533	memset(password, 0, strlen(password));
534	xfree(password);
535	packet_add_padding(64);
536	packet_send();
537
538	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
539	    &input_userauth_passwd_changereq);
540}
541
542static void
543clear_auth_state(Authctxt *authctxt)
544{
545	/* XXX clear authentication state */
546	dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL);
547
548	if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) {
549		debug3("clear_auth_state: key_free %p", authctxt->last_key);
550		key_free(authctxt->last_key);
551	}
552	authctxt->last_key = NULL;
553	authctxt->last_key_hint = -2;
554	authctxt->last_key_sign = NULL;
555}
556
557static int
558sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
559{
560	Buffer b;
561	u_char *blob, *signature;
562	u_int bloblen, slen;
563	int skip = 0;
564	int ret = -1;
565	int have_sig = 1;
566
567	debug3("sign_and_send_pubkey");
568
569	if (key_to_blob(k, &blob, &bloblen) == 0) {
570		/* we cannot handle this key */
571		debug3("sign_and_send_pubkey: cannot handle key");
572		return 0;
573	}
574	/* data to be signed */
575	buffer_init(&b);
576	if (datafellows & SSH_OLD_SESSIONID) {
577		buffer_append(&b, session_id2, session_id2_len);
578		skip = session_id2_len;
579	} else {
580		buffer_put_string(&b, session_id2, session_id2_len);
581		skip = buffer_len(&b);
582	}
583	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
584	buffer_put_cstring(&b, authctxt->server_user);
585	buffer_put_cstring(&b,
586	    datafellows & SSH_BUG_PKSERVICE ?
587	    "ssh-userauth" :
588	    authctxt->service);
589	if (datafellows & SSH_BUG_PKAUTH) {
590		buffer_put_char(&b, have_sig);
591	} else {
592		buffer_put_cstring(&b, authctxt->method->name);
593		buffer_put_char(&b, have_sig);
594		buffer_put_cstring(&b, key_ssh_name(k));
595	}
596	buffer_put_string(&b, blob, bloblen);
597
598	/* generate signature */
599	ret = (*sign_callback)(authctxt, k, &signature, &slen,
600	    buffer_ptr(&b), buffer_len(&b));
601	if (ret == -1) {
602		xfree(blob);
603		buffer_free(&b);
604		return 0;
605	}
606#ifdef DEBUG_PK
607	buffer_dump(&b);
608#endif
609	if (datafellows & SSH_BUG_PKSERVICE) {
610		buffer_clear(&b);
611		buffer_append(&b, session_id2, session_id2_len);
612		skip = session_id2_len;
613		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
614		buffer_put_cstring(&b, authctxt->server_user);
615		buffer_put_cstring(&b, authctxt->service);
616		buffer_put_cstring(&b, authctxt->method->name);
617		buffer_put_char(&b, have_sig);
618		if (!(datafellows & SSH_BUG_PKAUTH))
619			buffer_put_cstring(&b, key_ssh_name(k));
620		buffer_put_string(&b, blob, bloblen);
621	}
622	xfree(blob);
623
624	/* append signature */
625	buffer_put_string(&b, signature, slen);
626	xfree(signature);
627
628	/* skip session id and packet type */
629	if (buffer_len(&b) < skip + 1)
630		fatal("userauth_pubkey: internal error");
631	buffer_consume(&b, skip + 1);
632
633	/* put remaining data from buffer into packet */
634	packet_start(SSH2_MSG_USERAUTH_REQUEST);
635	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
636	buffer_free(&b);
637	packet_send();
638
639	return 1;
640}
641
642static int
643send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
644    int hint)
645{
646	u_char *blob;
647	u_int bloblen, have_sig = 0;
648
649	debug3("send_pubkey_test");
650
651	if (key_to_blob(k, &blob, &bloblen) == 0) {
652		/* we cannot handle this key */
653		debug3("send_pubkey_test: cannot handle key");
654		return 0;
655	}
656	/* register callback for USERAUTH_PK_OK message */
657	authctxt->last_key_sign = sign_callback;
658	authctxt->last_key_hint = hint;
659	authctxt->last_key = k;
660	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
661
662	packet_start(SSH2_MSG_USERAUTH_REQUEST);
663	packet_put_cstring(authctxt->server_user);
664	packet_put_cstring(authctxt->service);
665	packet_put_cstring(authctxt->method->name);
666	packet_put_char(have_sig);
667	if (!(datafellows & SSH_BUG_PKAUTH))
668		packet_put_cstring(key_ssh_name(k));
669	packet_put_string(blob, bloblen);
670	xfree(blob);
671	packet_send();
672	return 1;
673}
674
675static Key *
676load_identity_file(char *filename)
677{
678	Key *private;
679	char prompt[300], *passphrase;
680	int quit, i;
681	struct stat st;
682
683	if (stat(filename, &st) < 0) {
684		debug3("no such identity: %s", filename);
685		return NULL;
686	}
687	private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
688	if (private == NULL) {
689		if (options.batch_mode)
690			return NULL;
691		snprintf(prompt, sizeof prompt,
692		    "Enter passphrase for key '%.100s': ", filename);
693		for (i = 0; i < options.number_of_password_prompts; i++) {
694			passphrase = read_passphrase(prompt, 0);
695			if (strcmp(passphrase, "") != 0) {
696				private = key_load_private_type(KEY_UNSPEC, filename,
697				    passphrase, NULL);
698				quit = 0;
699			} else {
700				debug2("no passphrase given, try next key");
701				quit = 1;
702			}
703			memset(passphrase, 0, strlen(passphrase));
704			xfree(passphrase);
705			if (private != NULL || quit)
706				break;
707			debug2("bad passphrase given, try again...");
708		}
709	}
710	return private;
711}
712
713static int
714identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
715    u_char *data, u_int datalen)
716{
717	Key *private;
718	int idx, ret;
719
720	idx = authctxt->last_key_hint;
721	if (idx < 0)
722		return -1;
723
724	/* private key is stored in external hardware */
725	if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
726		return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
727
728	private = load_identity_file(options.identity_files[idx]);
729	if (private == NULL)
730		return -1;
731	ret = key_sign(private, sigp, lenp, data, datalen);
732	key_free(private);
733	return ret;
734}
735
736static int
737agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
738    u_char *data, u_int datalen)
739{
740	return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
741}
742
743static int
744key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
745    u_char *data, u_int datalen)
746{
747	return key_sign(key, sigp, lenp, data, datalen);
748}
749
750static int
751userauth_pubkey_agent(Authctxt *authctxt)
752{
753	static int called = 0;
754	int ret = 0;
755	char *comment;
756	Key *k;
757
758	if (called == 0) {
759		if (ssh_get_num_identities(authctxt->agent, 2) == 0)
760			debug2("userauth_pubkey_agent: no keys at all");
761		called = 1;
762	}
763	k = ssh_get_next_identity(authctxt->agent, &comment, 2);
764	if (k == NULL) {
765		debug2("userauth_pubkey_agent: no more keys");
766	} else {
767		debug("Offering agent key: %s", comment);
768		xfree(comment);
769		ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1);
770		if (ret == 0)
771			key_free(k);
772	}
773	if (ret == 0)
774		debug2("userauth_pubkey_agent: no message sent");
775	return ret;
776}
777
778int
779userauth_pubkey(Authctxt *authctxt)
780{
781	static int idx = 0;
782	int sent = 0;
783	Key *key;
784	char *filename;
785
786	if (authctxt->agent != NULL) {
787		do {
788			sent = userauth_pubkey_agent(authctxt);
789		} while (!sent && authctxt->agent->howmany > 0);
790	}
791	while (!sent && idx < options.num_identity_files) {
792		key = options.identity_keys[idx];
793		filename = options.identity_files[idx];
794		if (key == NULL) {
795			debug("Trying private key: %s", filename);
796			key = load_identity_file(filename);
797			if (key != NULL) {
798				sent = sign_and_send_pubkey(authctxt, key,
799				    key_sign_cb);
800				key_free(key);
801			}
802		} else if (key->type != KEY_RSA1) {
803			debug("Offering public key: %s", filename);
804			sent = send_pubkey_test(authctxt, key,
805			    identity_sign_cb, idx);
806		}
807		idx++;
808	}
809	return sent;
810}
811
812/*
813 * Send userauth request message specifying keyboard-interactive method.
814 */
815int
816userauth_kbdint(Authctxt *authctxt)
817{
818	static int attempt = 0;
819
820	if (attempt++ >= options.number_of_password_prompts)
821		return 0;
822	/* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
823	if (attempt > 1 && !authctxt->info_req_seen) {
824		debug3("userauth_kbdint: disable: no info_req_seen");
825		dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
826		return 0;
827	}
828
829	debug2("userauth_kbdint");
830	packet_start(SSH2_MSG_USERAUTH_REQUEST);
831	packet_put_cstring(authctxt->server_user);
832	packet_put_cstring(authctxt->service);
833	packet_put_cstring(authctxt->method->name);
834	packet_put_cstring("");					/* lang */
835	packet_put_cstring(options.kbd_interactive_devices ?
836	    options.kbd_interactive_devices : "");
837	packet_send();
838
839	dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
840	return 1;
841}
842
843/*
844 * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
845 */
846void
847input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
848{
849	Authctxt *authctxt = ctxt;
850	char *name, *inst, *lang, *prompt, *response;
851	u_int num_prompts, i;
852	int echo = 0;
853
854	debug2("input_userauth_info_req");
855
856	if (authctxt == NULL)
857		fatal("input_userauth_info_req: no authentication context");
858
859	authctxt->info_req_seen = 1;
860
861	name = packet_get_string(NULL);
862	inst = packet_get_string(NULL);
863	lang = packet_get_string(NULL);
864	if (strlen(name) > 0)
865		log("%s", name);
866	if (strlen(inst) > 0)
867		log("%s", inst);
868	xfree(name);
869	xfree(inst);
870	xfree(lang);
871
872	num_prompts = packet_get_int();
873	/*
874	 * Begin to build info response packet based on prompts requested.
875	 * We commit to providing the correct number of responses, so if
876	 * further on we run into a problem that prevents this, we have to
877	 * be sure and clean this up and send a correct error response.
878	 */
879	packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
880	packet_put_int(num_prompts);
881
882	debug2("input_userauth_info_req: num_prompts %d", num_prompts);
883	for (i = 0; i < num_prompts; i++) {
884		prompt = packet_get_string(NULL);
885		echo = packet_get_char();
886
887		response = read_passphrase(prompt, echo ? RP_ECHO : 0);
888
889		packet_put_cstring(response);
890		memset(response, 0, strlen(response));
891		xfree(response);
892		xfree(prompt);
893	}
894	packet_check_eom(); /* done with parsing incoming message. */
895
896	packet_add_padding(64);
897	packet_send();
898}
899
900static int
901ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
902    u_char *data, u_int datalen)
903{
904	Buffer b;
905	struct stat st;
906	pid_t pid;
907	int to[2], from[2], status, version = 2;
908
909	debug2("ssh_keysign called");
910
911	if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) {
912		error("ssh_keysign: no installed: %s", strerror(errno));
913		return -1;
914	}
915	if (fflush(stdout) != 0)
916		error("ssh_keysign: fflush: %s", strerror(errno));
917	if (pipe(to) < 0) {
918		error("ssh_keysign: pipe: %s", strerror(errno));
919		return -1;
920	}
921	if (pipe(from) < 0) {
922		error("ssh_keysign: pipe: %s", strerror(errno));
923		return -1;
924	}
925	if ((pid = fork()) < 0) {
926		error("ssh_keysign: fork: %s", strerror(errno));
927		return -1;
928	}
929	if (pid == 0) {
930		seteuid(getuid());
931		setuid(getuid());
932		close(from[0]);
933		if (dup2(from[1], STDOUT_FILENO) < 0)
934			fatal("ssh_keysign: dup2: %s", strerror(errno));
935		close(to[1]);
936		if (dup2(to[0], STDIN_FILENO) < 0)
937			fatal("ssh_keysign: dup2: %s", strerror(errno));
938		close(from[1]);
939		close(to[0]);
940		execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0);
941		fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN,
942		    strerror(errno));
943	}
944	close(from[1]);
945	close(to[0]);
946
947	buffer_init(&b);
948	buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
949	buffer_put_string(&b, data, datalen);
950	ssh_msg_send(to[1], version, &b);
951
952	if (ssh_msg_recv(from[0], &b) < 0) {
953		error("ssh_keysign: no reply");
954		buffer_clear(&b);
955		return -1;
956	}
957	close(from[0]);
958	close(to[1]);
959
960	while (waitpid(pid, &status, 0) < 0)
961		if (errno != EINTR)
962			break;
963
964	if (buffer_get_char(&b) != version) {
965		error("ssh_keysign: bad version");
966		buffer_clear(&b);
967		return -1;
968	}
969	*sigp = buffer_get_string(&b, lenp);
970	buffer_clear(&b);
971
972	return 0;
973}
974
975int
976userauth_hostbased(Authctxt *authctxt)
977{
978	Key *private = NULL;
979	Sensitive *sensitive = authctxt->sensitive;
980	Buffer b;
981	u_char *signature, *blob;
982	char *chost, *pkalg, *p;
983	const char *service;
984	u_int blen, slen;
985	int ok, i, len, found = 0;
986
987	/* check for a useful key */
988	for (i = 0; i < sensitive->nkeys; i++) {
989		private = sensitive->keys[i];
990		if (private && private->type != KEY_RSA1) {
991			found = 1;
992			/* we take and free the key */
993			sensitive->keys[i] = NULL;
994			break;
995		}
996	}
997	if (!found) {
998		debug("No more client hostkeys for hostbased authentication.");
999		return 0;
1000	}
1001	if (key_to_blob(private, &blob, &blen) == 0) {
1002		key_free(private);
1003		return 0;
1004	}
1005	/* figure out a name for the client host */
1006	p = get_local_name(packet_get_connection_in());
1007	if (p == NULL) {
1008		error("userauth_hostbased: cannot get local ipaddr/name");
1009		key_free(private);
1010		return 0;
1011	}
1012	len = strlen(p) + 2;
1013	chost = xmalloc(len);
1014	strlcpy(chost, p, len);
1015	strlcat(chost, ".", len);
1016	debug2("userauth_hostbased: chost %s", chost);
1017	xfree(p);
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	char *name = NULL;
1114	u_int next;
1115
1116	/* Use a suitable default if we're passed a nil list.  */
1117	if (authlist == NULL || strlen(authlist) == 0)
1118		authlist = options.preferred_authentications;
1119
1120	if (supported == NULL || strcmp(authlist, supported) != 0) {
1121		debug3("start over, passed a different list %s", authlist);
1122		if (supported != NULL)
1123			xfree(supported);
1124		supported = xstrdup(authlist);
1125		preferred = options.preferred_authentications;
1126		debug3("preferred %s", preferred);
1127		current = NULL;
1128	} else if (current != NULL && authmethod_is_enabled(current))
1129		return current;
1130
1131	for (;;) {
1132		if ((name = match_list(preferred, supported, &next)) == NULL) {
1133			debug("No more authentication methods to try.");
1134			current = NULL;
1135			return NULL;
1136		}
1137		preferred += next;
1138		debug3("authmethod_lookup %s", name);
1139		debug3("remaining preferred: %s", preferred);
1140		if ((current = authmethod_lookup(name)) != NULL &&
1141		    authmethod_is_enabled(current)) {
1142			debug3("authmethod_is_enabled %s", name);
1143			debug("Next authentication method: %s", name);
1144			return current;
1145		}
1146	}
1147}
1148
1149static char *
1150authmethods_get(void)
1151{
1152	Authmethod *method = NULL;
1153	Buffer b;
1154	char *list;
1155
1156	buffer_init(&b);
1157	for (method = authmethods; method->name != NULL; method++) {
1158		if (authmethod_is_enabled(method)) {
1159			if (buffer_len(&b) > 0)
1160				buffer_append(&b, ",", 1);
1161			buffer_append(&b, method->name, strlen(method->name));
1162		}
1163	}
1164	buffer_append(&b, "\0", 1);
1165	list = xstrdup(buffer_ptr(&b));
1166	buffer_free(&b);
1167	return list;
1168}
1169