sshconnect2.c revision 69588
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.27 2000/10/19 16:45:16 provos Exp $");
27
28#include <openssl/bn.h>
29#include <openssl/rsa.h>
30#include <openssl/dsa.h>
31#include <openssl/md5.h>
32#include <openssl/dh.h>
33#include <openssl/hmac.h>
34
35#include "ssh.h"
36#include "xmalloc.h"
37#include "rsa.h"
38#include "buffer.h"
39#include "packet.h"
40#include "uidswap.h"
41#include "compat.h"
42#include "readconf.h"
43#include "bufaux.h"
44#include "ssh2.h"
45#include "kex.h"
46#include "myproposal.h"
47#include "key.h"
48#include "dsa.h"
49#include "sshconnect.h"
50#include "authfile.h"
51#include "cli.h"
52#include "dispatch.h"
53#include "authfd.h"
54
55void ssh_dh1_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
56void ssh_dhgex_client(Kex *, char *, struct sockaddr *, Buffer *, Buffer *);
57
58/* import */
59extern char *client_version_string;
60extern char *server_version_string;
61extern Options options;
62
63/*
64 * SSH2 key exchange
65 */
66
67unsigned char *session_id2 = NULL;
68int session_id2_len = 0;
69
70void
71ssh_kex2(char *host, struct sockaddr *hostaddr)
72{
73	int i, plen;
74	Kex *kex;
75	Buffer *client_kexinit, *server_kexinit;
76	char *sprop[PROPOSAL_MAX];
77
78	if (options.ciphers == NULL) {
79		if (options.cipher == SSH_CIPHER_3DES) {
80			options.ciphers = "3des-cbc";
81		} else if (options.cipher == SSH_CIPHER_BLOWFISH) {
82			options.ciphers = "blowfish-cbc";
83		} else if (options.cipher == SSH_CIPHER_DES) {
84			fatal("cipher DES not supported for protocol version 2");
85		}
86	}
87	if (options.ciphers != NULL) {
88		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
89		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
90	}
91	if (options.compression) {
92		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
93		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
94	} else {
95		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
96		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
97	}
98
99	/* buffers with raw kexinit messages */
100	server_kexinit = xmalloc(sizeof(*server_kexinit));
101	buffer_init(server_kexinit);
102	client_kexinit = kex_init(myproposal);
103
104	/* algorithm negotiation */
105	kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
106	kex = kex_choose_conf(myproposal, sprop, 0);
107	for (i = 0; i < PROPOSAL_MAX; i++)
108		xfree(sprop[i]);
109
110	/* server authentication and session key agreement */
111	switch(kex->kex_type) {
112	case DH_GRP1_SHA1:
113		ssh_dh1_client(kex, host, hostaddr,
114			       client_kexinit, server_kexinit);
115		break;
116	case DH_GEX_SHA1:
117		ssh_dhgex_client(kex, host, hostaddr, client_kexinit,
118				 server_kexinit);
119		break;
120	default:
121		fatal("Unsupported key exchange %d", kex->kex_type);
122	}
123
124	buffer_free(client_kexinit);
125	buffer_free(server_kexinit);
126	xfree(client_kexinit);
127	xfree(server_kexinit);
128
129	debug("Wait SSH2_MSG_NEWKEYS.");
130	packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
131	packet_done();
132	debug("GOT SSH2_MSG_NEWKEYS.");
133
134	debug("send SSH2_MSG_NEWKEYS.");
135	packet_start(SSH2_MSG_NEWKEYS);
136	packet_send();
137	packet_write_wait();
138	debug("done: send SSH2_MSG_NEWKEYS.");
139
140#ifdef DEBUG_KEXDH
141	/* send 1st encrypted/maced/compressed message */
142	packet_start(SSH2_MSG_IGNORE);
143	packet_put_cstring("markus");
144	packet_send();
145	packet_write_wait();
146#endif
147	debug("done: KEX2.");
148}
149
150/* diffie-hellman-group1-sha1 */
151
152void
153ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
154	       Buffer *client_kexinit, Buffer *server_kexinit)
155{
156#ifdef DEBUG_KEXDH
157	int i;
158#endif
159	int plen, dlen;
160	unsigned int klen, kout;
161	char *signature = NULL;
162	unsigned int slen;
163	char *server_host_key_blob = NULL;
164	Key *server_host_key;
165	unsigned int sbloblen;
166	DH *dh;
167	BIGNUM *dh_server_pub = 0;
168	BIGNUM *shared_secret = 0;
169	unsigned char *kbuf;
170	unsigned char *hash;
171
172	debug("Sending SSH2_MSG_KEXDH_INIT.");
173	/* generate and send 'e', client DH public key */
174	dh = dh_new_group1();
175	packet_start(SSH2_MSG_KEXDH_INIT);
176	packet_put_bignum2(dh->pub_key);
177	packet_send();
178	packet_write_wait();
179
180#ifdef DEBUG_KEXDH
181	fprintf(stderr, "\np= ");
182	BN_print_fp(stderr, dh->p);
183	fprintf(stderr, "\ng= ");
184	BN_print_fp(stderr, dh->g);
185	fprintf(stderr, "\npub= ");
186	BN_print_fp(stderr, dh->pub_key);
187	fprintf(stderr, "\n");
188	DHparams_print_fp(stderr, dh);
189#endif
190
191	debug("Wait SSH2_MSG_KEXDH_REPLY.");
192
193	packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
194
195	debug("Got SSH2_MSG_KEXDH_REPLY.");
196
197	/* key, cert */
198	server_host_key_blob = packet_get_string(&sbloblen);
199	server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
200	if (server_host_key == NULL)
201		fatal("cannot decode server_host_key_blob");
202
203	check_host_key(host, hostaddr, server_host_key,
204		       options.user_hostfile2, options.system_hostfile2);
205
206	/* DH paramter f, server public DH key */
207	dh_server_pub = BN_new();
208	if (dh_server_pub == NULL)
209		fatal("dh_server_pub == NULL");
210	packet_get_bignum2(dh_server_pub, &dlen);
211
212#ifdef DEBUG_KEXDH
213	fprintf(stderr, "\ndh_server_pub= ");
214	BN_print_fp(stderr, dh_server_pub);
215	fprintf(stderr, "\n");
216	debug("bits %d", BN_num_bits(dh_server_pub));
217#endif
218
219	/* signed H */
220	signature = packet_get_string(&slen);
221	packet_done();
222
223	if (!dh_pub_is_valid(dh, dh_server_pub))
224		packet_disconnect("bad server public DH value");
225
226	klen = DH_size(dh);
227	kbuf = xmalloc(klen);
228	kout = DH_compute_key(kbuf, dh_server_pub, dh);
229#ifdef DEBUG_KEXDH
230	debug("shared secret: len %d/%d", klen, kout);
231	fprintf(stderr, "shared secret == ");
232	for (i = 0; i< kout; i++)
233		fprintf(stderr, "%02x", (kbuf[i])&0xff);
234	fprintf(stderr, "\n");
235#endif
236	shared_secret = BN_new();
237
238	BN_bin2bn(kbuf, kout, shared_secret);
239	memset(kbuf, 0, klen);
240	xfree(kbuf);
241
242	/* calc and verify H */
243	hash = kex_hash(
244	    client_version_string,
245	    server_version_string,
246	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),
247	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),
248	    server_host_key_blob, sbloblen,
249	    dh->pub_key,
250	    dh_server_pub,
251	    shared_secret
252	);
253	xfree(server_host_key_blob);
254	DH_free(dh);
255#ifdef DEBUG_KEXDH
256	fprintf(stderr, "hash == ");
257	for (i = 0; i< 20; i++)
258		fprintf(stderr, "%02x", (hash[i])&0xff);
259	fprintf(stderr, "\n");
260#endif
261	if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
262		fatal("dsa_verify failed for server_host_key");
263	key_free(server_host_key);
264
265	kex_derive_keys(kex, hash, shared_secret);
266	packet_set_kex(kex);
267
268	/* save session id */
269	session_id2_len = 20;
270	session_id2 = xmalloc(session_id2_len);
271	memcpy(session_id2, hash, session_id2_len);
272}
273
274/* diffie-hellman-group-exchange-sha1 */
275
276/*
277 * Estimates the group order for a Diffie-Hellman group that has an
278 * attack complexity approximately the same as O(2**bits).  Estimate
279 * with:  O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
280 */
281
282int
283dh_estimate(int bits)
284{
285
286	if (bits < 64)
287		return (512);	/* O(2**63) */
288	if (bits < 128)
289		return (1024);	/* O(2**86) */
290	if (bits < 192)
291		return (2048);	/* O(2**116) */
292	return (4096);		/* O(2**156) */
293}
294
295void
296ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
297		 Buffer *client_kexinit, Buffer *server_kexinit)
298{
299#ifdef DEBUG_KEXDH
300	int i;
301#endif
302	int plen, dlen;
303	unsigned int klen, kout;
304	char *signature = NULL;
305	unsigned int slen, nbits;
306	char *server_host_key_blob = NULL;
307	Key *server_host_key;
308	unsigned int sbloblen;
309	DH *dh;
310	BIGNUM *dh_server_pub = 0;
311	BIGNUM *shared_secret = 0;
312	BIGNUM *p = 0, *g = 0;
313	unsigned char *kbuf;
314	unsigned char *hash;
315
316	nbits = dh_estimate(kex->enc[MODE_OUT].cipher->key_len * 8);
317
318	debug("Sending SSH2_MSG_KEX_DH_GEX_REQUEST.");
319	packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST);
320	packet_put_int(nbits);
321	packet_send();
322	packet_write_wait();
323
324#ifdef DEBUG_KEXDH
325	fprintf(stderr, "\nnbits = %d", nbits);
326#endif
327
328	debug("Wait SSH2_MSG_KEX_DH_GEX_GROUP.");
329
330	packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
331
332	debug("Got SSH2_MSG_KEX_DH_GEX_GROUP.");
333
334	if ((p = BN_new()) == NULL)
335		fatal("BN_new");
336	packet_get_bignum2(p, &dlen);
337	if ((g = BN_new()) == NULL)
338		fatal("BN_new");
339	packet_get_bignum2(g, &dlen);
340	if ((dh = dh_new_group(g, p)) == NULL)
341		fatal("dh_new_group");
342
343#ifdef DEBUG_KEXDH
344	fprintf(stderr, "\np= ");
345	BN_print_fp(stderr, dh->p);
346	fprintf(stderr, "\ng= ");
347	BN_print_fp(stderr, dh->g);
348	fprintf(stderr, "\npub= ");
349	BN_print_fp(stderr, dh->pub_key);
350	fprintf(stderr, "\n");
351	DHparams_print_fp(stderr, dh);
352#endif
353
354	debug("Sending SSH2_MSG_KEX_DH_GEX_INIT.");
355	/* generate and send 'e', client DH public key */
356	packet_start(SSH2_MSG_KEX_DH_GEX_INIT);
357	packet_put_bignum2(dh->pub_key);
358	packet_send();
359	packet_write_wait();
360
361	debug("Wait SSH2_MSG_KEX_DH_GEX_REPLY.");
362
363	packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
364
365	debug("Got SSH2_MSG_KEXDH_REPLY.");
366
367	/* key, cert */
368	server_host_key_blob = packet_get_string(&sbloblen);
369	server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
370	if (server_host_key == NULL)
371		fatal("cannot decode server_host_key_blob");
372
373	check_host_key(host, hostaddr, server_host_key,
374		       options.user_hostfile2, options.system_hostfile2);
375
376	/* DH paramter f, server public DH key */
377	dh_server_pub = BN_new();
378	if (dh_server_pub == NULL)
379		fatal("dh_server_pub == NULL");
380	packet_get_bignum2(dh_server_pub, &dlen);
381
382#ifdef DEBUG_KEXDH
383	fprintf(stderr, "\ndh_server_pub= ");
384	BN_print_fp(stderr, dh_server_pub);
385	fprintf(stderr, "\n");
386	debug("bits %d", BN_num_bits(dh_server_pub));
387#endif
388
389	/* signed H */
390	signature = packet_get_string(&slen);
391	packet_done();
392
393	if (!dh_pub_is_valid(dh, dh_server_pub))
394		packet_disconnect("bad server public DH value");
395
396	klen = DH_size(dh);
397	kbuf = xmalloc(klen);
398	kout = DH_compute_key(kbuf, dh_server_pub, dh);
399#ifdef DEBUG_KEXDH
400	debug("shared secret: len %d/%d", klen, kout);
401	fprintf(stderr, "shared secret == ");
402	for (i = 0; i< kout; i++)
403		fprintf(stderr, "%02x", (kbuf[i])&0xff);
404	fprintf(stderr, "\n");
405#endif
406	shared_secret = BN_new();
407
408	BN_bin2bn(kbuf, kout, shared_secret);
409	memset(kbuf, 0, klen);
410	xfree(kbuf);
411
412	/* calc and verify H */
413	hash = kex_hash_gex(
414	    client_version_string,
415	    server_version_string,
416	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),
417	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),
418	    server_host_key_blob, sbloblen,
419	    nbits, dh->p, dh->g,
420	    dh->pub_key,
421	    dh_server_pub,
422	    shared_secret
423	);
424	xfree(server_host_key_blob);
425	DH_free(dh);
426#ifdef DEBUG_KEXDH
427	fprintf(stderr, "hash == ");
428	for (i = 0; i< 20; i++)
429		fprintf(stderr, "%02x", (hash[i])&0xff);
430	fprintf(stderr, "\n");
431#endif
432	if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
433		fatal("dsa_verify failed for server_host_key");
434	key_free(server_host_key);
435
436	kex_derive_keys(kex, hash, shared_secret);
437	packet_set_kex(kex);
438
439	/* save session id */
440	session_id2_len = 20;
441	session_id2 = xmalloc(session_id2_len);
442	memcpy(session_id2, hash, session_id2_len);
443}
444
445/*
446 * Authenticate user
447 */
448
449typedef struct Authctxt Authctxt;
450typedef struct Authmethod Authmethod;
451
452typedef int sign_cb_fn(
453    Authctxt *authctxt, Key *key,
454    unsigned char **sigp, int *lenp, unsigned char *data, int datalen);
455
456struct Authctxt {
457	const char *server_user;
458	const char *host;
459	const char *service;
460	AuthenticationConnection *agent;
461	Authmethod *method;
462	int success;
463};
464struct Authmethod {
465	char	*name;		/* string to compare against server's list */
466	int	(*userauth)(Authctxt *authctxt);
467	int	*enabled;	/* flag in option struct that enables method */
468	int	*batch_flag;	/* flag in option struct that disables method */
469};
470
471void	input_userauth_success(int type, int plen, void *ctxt);
472void	input_userauth_failure(int type, int plen, void *ctxt);
473void	input_userauth_error(int type, int plen, void *ctxt);
474void	input_userauth_info_req(int type, int plen, void *ctxt);
475
476int	userauth_none(Authctxt *authctxt);
477int	userauth_pubkey(Authctxt *authctxt);
478int	userauth_passwd(Authctxt *authctxt);
479int	userauth_kbdint(Authctxt *authctxt);
480
481void	authmethod_clear();
482Authmethod *authmethod_get(char *authlist);
483Authmethod *authmethod_lookup(const char *name);
484
485Authmethod authmethods[] = {
486	{"publickey",
487		userauth_pubkey,
488		&options.dsa_authentication,
489		NULL},
490	{"password",
491		userauth_passwd,
492		&options.password_authentication,
493		&options.batch_mode},
494	{"keyboard-interactive",
495		userauth_kbdint,
496		&options.kbd_interactive_authentication,
497		&options.batch_mode},
498	{"none",
499		userauth_none,
500		NULL,
501		NULL},
502	{NULL, NULL, NULL, NULL}
503};
504
505void
506ssh_userauth2(const char *server_user, char *host)
507{
508	Authctxt authctxt;
509	int type;
510	int plen;
511
512	debug("send SSH2_MSG_SERVICE_REQUEST");
513	packet_start(SSH2_MSG_SERVICE_REQUEST);
514	packet_put_cstring("ssh-userauth");
515	packet_send();
516	packet_write_wait();
517	type = packet_read(&plen);
518	if (type != SSH2_MSG_SERVICE_ACCEPT) {
519		fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
520	}
521	if (packet_remaining() > 0) {
522		char *reply = packet_get_string(&plen);
523		debug("service_accept: %s", reply);
524		xfree(reply);
525		packet_done();
526	} else {
527		debug("buggy server: service_accept w/o service");
528	}
529	packet_done();
530	debug("got SSH2_MSG_SERVICE_ACCEPT");
531
532	/* setup authentication context */
533	authctxt.agent = ssh_get_authentication_connection();
534	authctxt.server_user = server_user;
535	authctxt.host = host;
536	authctxt.service = "ssh-connection";		/* service name */
537	authctxt.success = 0;
538	authctxt.method = authmethod_lookup("none");
539	if (authctxt.method == NULL)
540		fatal("ssh_userauth2: internal error: cannot send userauth none request");
541	authmethod_clear();
542
543	/* initial userauth request */
544	userauth_none(&authctxt);
545
546	dispatch_init(&input_userauth_error);
547	dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);
548	dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure);
549	dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt);	/* loop until success */
550
551	if (authctxt.agent != NULL)
552		ssh_close_authentication_connection(authctxt.agent);
553
554	debug("ssh-userauth2 successfull: method %s", authctxt.method->name);
555}
556void
557input_userauth_error(int type, int plen, void *ctxt)
558{
559	fatal("input_userauth_error: bad message during authentication");
560}
561void
562input_userauth_success(int type, int plen, void *ctxt)
563{
564	Authctxt *authctxt = ctxt;
565	if (authctxt == NULL)
566		fatal("input_userauth_success: no authentication context");
567	authctxt->success = 1;			/* break out */
568}
569void
570input_userauth_failure(int type, int plen, void *ctxt)
571{
572	Authmethod *method = NULL;
573	Authctxt *authctxt = ctxt;
574	char *authlist = NULL;
575	int partial;
576
577	if (authctxt == NULL)
578		fatal("input_userauth_failure: no authentication context");
579
580	authlist = packet_get_string(NULL);
581	partial = packet_get_char();
582	packet_done();
583
584	if (partial != 0)
585		debug("partial success");
586	debug("authentications that can continue: %s", authlist);
587
588	for (;;) {
589		method = authmethod_get(authlist);
590		if (method == NULL)
591                        fatal("Unable to find an authentication method");
592		authctxt->method = method;
593		if (method->userauth(authctxt) != 0) {
594			debug2("we sent a %s packet, wait for reply", method->name);
595			break;
596		} else {
597			debug2("we did not send a packet, disable method");
598			method->enabled = NULL;
599		}
600	}
601	xfree(authlist);
602}
603
604int
605userauth_none(Authctxt *authctxt)
606{
607	/* initial userauth request */
608	packet_start(SSH2_MSG_USERAUTH_REQUEST);
609	packet_put_cstring(authctxt->server_user);
610	packet_put_cstring(authctxt->service);
611	packet_put_cstring(authctxt->method->name);
612	packet_send();
613	packet_write_wait();
614	return 1;
615}
616
617int
618userauth_passwd(Authctxt *authctxt)
619{
620	static int attempt = 0;
621	char prompt[80];
622	char *password;
623
624	if (attempt++ >= options.number_of_password_prompts)
625		return 0;
626
627	if(attempt != 1)
628		error("Permission denied, please try again.");
629
630	snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
631	    authctxt->server_user, authctxt->host);
632	password = read_passphrase(prompt, 0);
633	packet_start(SSH2_MSG_USERAUTH_REQUEST);
634	packet_put_cstring(authctxt->server_user);
635	packet_put_cstring(authctxt->service);
636	packet_put_cstring(authctxt->method->name);
637	packet_put_char(0);
638	packet_put_cstring(password);
639	memset(password, 0, strlen(password));
640	xfree(password);
641	packet_send();
642	packet_write_wait();
643	return 1;
644}
645
646int
647sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
648{
649	Buffer b;
650	unsigned char *blob, *signature;
651	int bloblen, slen;
652	int skip = 0;
653	int ret = -1;
654	int have_sig = 1;
655
656	dsa_make_key_blob(k, &blob, &bloblen);
657
658	/* data to be signed */
659	buffer_init(&b);
660	if (datafellows & SSH_OLD_SESSIONID) {
661		buffer_append(&b, session_id2, session_id2_len);
662		skip = session_id2_len;
663	} else {
664		buffer_put_string(&b, session_id2, session_id2_len);
665		skip = buffer_len(&b);
666	}
667	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
668	buffer_put_cstring(&b, authctxt->server_user);
669	buffer_put_cstring(&b,
670	    datafellows & SSH_BUG_PUBKEYAUTH ?
671	    "ssh-userauth" :
672	    authctxt->service);
673	buffer_put_cstring(&b, authctxt->method->name);
674	buffer_put_char(&b, have_sig);
675	buffer_put_cstring(&b, KEX_DSS);
676	buffer_put_string(&b, blob, bloblen);
677
678	/* generate signature */
679	ret = (*sign_callback)(authctxt, k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
680	if (ret == -1) {
681		xfree(blob);
682		buffer_free(&b);
683		return 0;
684	}
685#ifdef DEBUG_DSS
686	buffer_dump(&b);
687#endif
688	if (datafellows & SSH_BUG_PUBKEYAUTH) {
689		buffer_clear(&b);
690		buffer_append(&b, session_id2, session_id2_len);
691		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
692		buffer_put_cstring(&b, authctxt->server_user);
693		buffer_put_cstring(&b, authctxt->service);
694		buffer_put_cstring(&b, authctxt->method->name);
695		buffer_put_char(&b, have_sig);
696		buffer_put_cstring(&b, KEX_DSS);
697		buffer_put_string(&b, blob, bloblen);
698	}
699	xfree(blob);
700	/* append signature */
701	buffer_put_string(&b, signature, slen);
702	xfree(signature);
703
704	/* skip session id and packet type */
705	if (buffer_len(&b) < skip + 1)
706		fatal("userauth_pubkey: internal error");
707	buffer_consume(&b, skip + 1);
708
709	/* put remaining data from buffer into packet */
710	packet_start(SSH2_MSG_USERAUTH_REQUEST);
711	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
712	buffer_free(&b);
713
714	/* send */
715	packet_send();
716	packet_write_wait();
717
718	return 1;
719}
720
721/* sign callback */
722int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
723    unsigned char *data, int datalen)
724{
725	return dsa_sign(key, sigp, lenp, data, datalen);
726}
727
728int
729userauth_pubkey_identity(Authctxt *authctxt, char *filename)
730{
731	Key *k;
732	int i, ret, try_next;
733	struct stat st;
734
735	if (stat(filename, &st) != 0) {
736		debug("key does not exist: %s", filename);
737		return 0;
738	}
739	debug("try pubkey: %s", filename);
740
741	k = key_new(KEY_DSA);
742	if (!load_private_key(filename, "", k, NULL)) {
743		int success = 0;
744		char *passphrase;
745		char prompt[300];
746		snprintf(prompt, sizeof prompt,
747		     "Enter passphrase for %s key '%.100s': ",
748		     key_type(k), filename);
749		for (i = 0; i < options.number_of_password_prompts; i++) {
750			passphrase = read_passphrase(prompt, 0);
751			if (strcmp(passphrase, "") != 0) {
752				success = load_private_key(filename, passphrase, k, NULL);
753				try_next = 0;
754			} else {
755				debug2("no passphrase given, try next key");
756				try_next = 1;
757			}
758			memset(passphrase, 0, strlen(passphrase));
759			xfree(passphrase);
760			if (success || try_next)
761				break;
762			debug2("bad passphrase given, try again...");
763		}
764		if (!success) {
765			key_free(k);
766			return 0;
767		}
768	}
769	ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);
770	key_free(k);
771	return ret;
772}
773
774/* sign callback */
775int agent_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
776    unsigned char *data, int datalen)
777{
778	return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
779}
780
781int
782userauth_pubkey_agent(Authctxt *authctxt)
783{
784	static int called = 0;
785	char *comment;
786	Key *k;
787	int ret;
788
789	if (called == 0) {
790		k = ssh_get_first_identity(authctxt->agent, &comment, 2);
791		called = 1;
792	} else {
793		k = ssh_get_next_identity(authctxt->agent, &comment, 2);
794	}
795	if (k == NULL) {
796		debug2("no more DSA keys from agent");
797		return 0;
798	}
799	debug("trying DSA agent key %s", comment);
800	xfree(comment);
801	ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
802	key_free(k);
803	return ret;
804}
805
806int
807userauth_pubkey(Authctxt *authctxt)
808{
809	static int idx = 0;
810	int sent = 0;
811
812	if (authctxt->agent != NULL)
813		sent = userauth_pubkey_agent(authctxt);
814	while (sent == 0 && idx < options.num_identity_files2)
815		sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);
816	return sent;
817}
818
819/*
820 * Send userauth request message specifying keyboard-interactive method.
821 */
822int
823userauth_kbdint(Authctxt *authctxt)
824{
825	static int attempt = 0;
826
827	if (attempt++ >= options.number_of_password_prompts)
828		return 0;
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	packet_write_wait();
840
841	dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
842	return 1;
843}
844
845/*
846 * parse SSH2_MSG_USERAUTH_INFO_REQUEST, prompt user and send
847 * SSH2_MSG_USERAUTH_INFO_RESPONSE
848 */
849void
850input_userauth_info_req(int type, int plen, void *ctxt)
851{
852	Authctxt *authctxt = ctxt;
853	char *name = NULL;
854	char *inst = NULL;
855	char *lang = NULL;
856	char *prompt = NULL;
857	char *response = NULL;
858	unsigned int num_prompts, i;
859	int echo = 0;
860
861	debug2("input_userauth_info_req");
862
863	if (authctxt == NULL)
864		fatal("input_userauth_info_req: no authentication context");
865
866	name = packet_get_string(NULL);
867	inst = packet_get_string(NULL);
868	lang = packet_get_string(NULL);
869
870	if (strlen(name) > 0)
871		cli_mesg(name);
872	xfree(name);
873
874	if (strlen(inst) > 0)
875		cli_mesg(inst);
876	xfree(inst);
877	xfree(lang); 				/* unused */
878
879	num_prompts = packet_get_int();
880	/*
881	 * Begin to build info response packet based on prompts requested.
882	 * We commit to providing the correct number of responses, so if
883	 * further on we run into a problem that prevents this, we have to
884	 * be sure and clean this up and send a correct error response.
885	 */
886	packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
887	packet_put_int(num_prompts);
888
889	for (i = 0; i < num_prompts; i++) {
890		prompt = packet_get_string(NULL);
891		echo = packet_get_char();
892
893		response = cli_prompt(prompt, echo);
894
895		packet_put_cstring(response);
896		memset(response, 0, strlen(response));
897		xfree(response);
898		xfree(prompt);
899	}
900	packet_done(); /* done with parsing incoming message. */
901
902	packet_send();
903	packet_write_wait();
904}
905
906/* find auth method */
907
908#define	DELIM	","
909
910static char *def_authlist = "publickey,password";
911static char *authlist_current = NULL;	 /* clean copy used for comparison */
912static char *authname_current = NULL;	 /* last used auth method */
913static char *authlist_working = NULL;	 /* copy that gets modified by strtok_r() */
914static char *authlist_state = NULL;	 /* state variable for strtok_r() */
915
916/*
917 * Before starting to use a new authentication method list sent by the
918 * server, reset internal variables.  This should also be called when
919 * finished processing server list to free resources.
920 */
921void
922authmethod_clear()
923{
924	if (authlist_current != NULL) {
925		xfree(authlist_current);
926		authlist_current = NULL;
927	}
928	if (authlist_working != NULL) {
929		xfree(authlist_working);
930		authlist_working = NULL;
931	}
932	if (authname_current != NULL) {
933		xfree(authname_current);
934		authlist_state = NULL;
935	}
936	if (authlist_state != NULL)
937		authlist_state = NULL;
938	return;
939}
940
941/*
942 * given auth method name, if configurable options permit this method fill
943 * in auth_ident field and return true, otherwise return false.
944 */
945int
946authmethod_is_enabled(Authmethod *method)
947{
948	if (method == NULL)
949		return 0;
950	/* return false if options indicate this method is disabled */
951	if  (method->enabled == NULL || *method->enabled == 0)
952		return 0;
953	/* return false if batch mode is enabled but method needs interactive mode */
954	if  (method->batch_flag != NULL && *method->batch_flag != 0)
955		return 0;
956	return 1;
957}
958
959Authmethod *
960authmethod_lookup(const char *name)
961{
962	Authmethod *method = NULL;
963	if (name != NULL)
964		for (method = authmethods; method->name != NULL; method++)
965			if (strcmp(name, method->name) == 0)
966				return method;
967	debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
968	return NULL;
969}
970
971/*
972 * Given the authentication method list sent by the server, return the
973 * next method we should try.  If the server initially sends a nil list,
974 * use a built-in default list.  If the server sends a nil list after
975 * previously sending a valid list, continue using the list originally
976 * sent.
977 */
978
979Authmethod *
980authmethod_get(char *authlist)
981{
982	char *name = NULL, *authname_old;
983	Authmethod *method = NULL;
984
985	/* Use a suitable default if we're passed a nil list.  */
986	if (authlist == NULL || strlen(authlist) == 0)
987		authlist = def_authlist;
988
989	if (authlist_current == NULL || strcmp(authlist, authlist_current) != 0) {
990		/* start over if passed a different list */
991		debug3("start over, passed a different list");
992		authmethod_clear();
993		authlist_current = xstrdup(authlist);
994		authlist_working = xstrdup(authlist);
995		name = strtok_r(authlist_working, DELIM, &authlist_state);
996	} else {
997		/*
998		 * try to use previously used authentication method
999		 * or continue to use previously passed list
1000		 */
1001		name = (authname_current != NULL) ?
1002		    authname_current : strtok_r(NULL, DELIM, &authlist_state);
1003	}
1004
1005	while (name != NULL) {
1006		debug3("authmethod_lookup %s", name);
1007		method = authmethod_lookup(name);
1008		if (method != NULL && authmethod_is_enabled(method)) {
1009			debug3("authmethod_is_enabled %s", name);
1010			break;
1011		}
1012		name = strtok_r(NULL, DELIM, &authlist_state);
1013		method = NULL;
1014	}
1015
1016	authname_old = authname_current;
1017	if (method != NULL) {
1018		debug("next auth method to try is %s", name);
1019		authname_current = xstrdup(name);
1020	} else {
1021		debug("no more auth methods to try");
1022		authname_current = NULL;
1023	}
1024
1025	if (authname_old != NULL)
1026		xfree(authname_old);
1027
1028	return (method);
1029}
1030