sshconnect2.c revision 65668
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.18 2000/09/07 20:27:55 deraadt 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 "cipher.h"
41#include "uidswap.h"
42#include "compat.h"
43#include "readconf.h"
44#include "bufaux.h"
45#include "ssh2.h"
46#include "kex.h"
47#include "myproposal.h"
48#include "key.h"
49#include "dsa.h"
50#include "sshconnect.h"
51#include "authfile.h"
52#include "authfd.h"
53
54/* import */
55extern char *client_version_string;
56extern char *server_version_string;
57extern Options options;
58
59/*
60 * SSH2 key exchange
61 */
62
63unsigned char *session_id2 = NULL;
64int session_id2_len = 0;
65
66void
67ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
68    Buffer *client_kexinit, Buffer *server_kexinit)
69{
70	int plen, dlen;
71	unsigned int klen, kout;
72	char *signature = NULL;
73	unsigned int slen;
74	char *server_host_key_blob = NULL;
75	Key *server_host_key;
76	unsigned int sbloblen;
77	DH *dh;
78	BIGNUM *dh_server_pub = 0;
79	BIGNUM *shared_secret = 0;
80	unsigned char *kbuf;
81	unsigned char *hash;
82
83	debug("Sending SSH2_MSG_KEXDH_INIT.");
84	/* generate and send 'e', client DH public key */
85	dh = dh_new_group1();
86	packet_start(SSH2_MSG_KEXDH_INIT);
87	packet_put_bignum2(dh->pub_key);
88	packet_send();
89	packet_write_wait();
90
91#ifdef DEBUG_KEXDH
92	fprintf(stderr, "\np= ");
93	bignum_print(dh->p);
94	fprintf(stderr, "\ng= ");
95	bignum_print(dh->g);
96	fprintf(stderr, "\npub= ");
97	bignum_print(dh->pub_key);
98	fprintf(stderr, "\n");
99	DHparams_print_fp(stderr, dh);
100#endif
101
102	debug("Wait SSH2_MSG_KEXDH_REPLY.");
103
104	packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
105
106	debug("Got SSH2_MSG_KEXDH_REPLY.");
107
108	/* key, cert */
109	server_host_key_blob = packet_get_string(&sbloblen);
110	server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
111	if (server_host_key == NULL)
112		fatal("cannot decode server_host_key_blob");
113
114	check_host_key(host, hostaddr, server_host_key,
115	    options.user_hostfile2, options.system_hostfile2);
116
117	/* DH paramter f, server public DH key */
118	dh_server_pub = BN_new();
119	if (dh_server_pub == NULL)
120		fatal("dh_server_pub == NULL");
121	packet_get_bignum2(dh_server_pub, &dlen);
122
123#ifdef DEBUG_KEXDH
124	fprintf(stderr, "\ndh_server_pub= ");
125	bignum_print(dh_server_pub);
126	fprintf(stderr, "\n");
127	debug("bits %d", BN_num_bits(dh_server_pub));
128#endif
129
130	/* signed H */
131	signature = packet_get_string(&slen);
132	packet_done();
133
134	if (!dh_pub_is_valid(dh, dh_server_pub))
135		packet_disconnect("bad server public DH value");
136
137	klen = DH_size(dh);
138	kbuf = xmalloc(klen);
139	kout = DH_compute_key(kbuf, dh_server_pub, dh);
140#ifdef DEBUG_KEXDH
141	debug("shared secret: len %d/%d", klen, kout);
142	fprintf(stderr, "shared secret == ");
143	for (i = 0; i< kout; i++)
144		fprintf(stderr, "%02x", (kbuf[i])&0xff);
145	fprintf(stderr, "\n");
146#endif
147	shared_secret = BN_new();
148
149	BN_bin2bn(kbuf, kout, shared_secret);
150	memset(kbuf, 0, klen);
151	xfree(kbuf);
152
153	/* calc and verify H */
154	hash = kex_hash(
155	    client_version_string,
156	    server_version_string,
157	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),
158	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),
159	    server_host_key_blob, sbloblen,
160	    dh->pub_key,
161	    dh_server_pub,
162	    shared_secret
163	);
164	xfree(server_host_key_blob);
165	DH_free(dh);
166#ifdef DEBUG_KEXDH
167	fprintf(stderr, "hash == ");
168	for (i = 0; i< 20; i++)
169		fprintf(stderr, "%02x", (hash[i])&0xff);
170	fprintf(stderr, "\n");
171#endif
172	if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
173		fatal("dsa_verify failed for server_host_key");
174	key_free(server_host_key);
175
176	kex_derive_keys(kex, hash, shared_secret);
177	packet_set_kex(kex);
178
179	/* save session id */
180	session_id2_len = 20;
181	session_id2 = xmalloc(session_id2_len);
182	memcpy(session_id2, hash, session_id2_len);
183}
184
185void
186ssh_kex2(char *host, struct sockaddr *hostaddr)
187{
188	int i, plen;
189	Kex *kex;
190	Buffer *client_kexinit, *server_kexinit;
191	char *sprop[PROPOSAL_MAX];
192
193	if (options.ciphers != NULL) {
194		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
195		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
196	} else if (options.cipher == SSH_CIPHER_3DES) {
197		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
198		myproposal[PROPOSAL_ENC_ALGS_STOC] =
199		    (char *) cipher_name(SSH_CIPHER_3DES_CBC);
200	} else if (options.cipher == SSH_CIPHER_BLOWFISH) {
201		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
202		myproposal[PROPOSAL_ENC_ALGS_STOC] =
203		    (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
204	}
205	if (options.compression) {
206		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
207		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
208	} else {
209		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
210		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
211	}
212
213	/* buffers with raw kexinit messages */
214	server_kexinit = xmalloc(sizeof(*server_kexinit));
215	buffer_init(server_kexinit);
216	client_kexinit = kex_init(myproposal);
217
218	/* algorithm negotiation */
219	kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
220	kex = kex_choose_conf(myproposal, sprop, 0);
221	for (i = 0; i < PROPOSAL_MAX; i++)
222		xfree(sprop[i]);
223
224	/* server authentication and session key agreement */
225	ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit);
226
227	buffer_free(client_kexinit);
228	buffer_free(server_kexinit);
229	xfree(client_kexinit);
230	xfree(server_kexinit);
231
232	debug("Wait SSH2_MSG_NEWKEYS.");
233	packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
234	packet_done();
235	debug("GOT SSH2_MSG_NEWKEYS.");
236
237	debug("send SSH2_MSG_NEWKEYS.");
238	packet_start(SSH2_MSG_NEWKEYS);
239	packet_send();
240	packet_write_wait();
241	debug("done: send SSH2_MSG_NEWKEYS.");
242
243#ifdef DEBUG_KEXDH
244	/* send 1st encrypted/maced/compressed message */
245	packet_start(SSH2_MSG_IGNORE);
246	packet_put_cstring("markus");
247	packet_send();
248	packet_write_wait();
249#endif
250	debug("done: KEX2.");
251}
252
253/*
254 * Authenticate user
255 */
256int
257ssh2_try_passwd(const char *server_user, const char *host, const char *service)
258{
259	static int attempt = 0;
260	char prompt[80];
261	char *password;
262
263	if (attempt++ >= options.number_of_password_prompts)
264		return 0;
265
266	if(attempt != 1)
267		error("Permission denied, please try again.");
268
269	snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
270	    server_user, host);
271	password = read_passphrase(prompt, 0);
272	packet_start(SSH2_MSG_USERAUTH_REQUEST);
273	packet_put_cstring(server_user);
274	packet_put_cstring(service);
275	packet_put_cstring("password");
276	packet_put_char(0);
277	packet_put_cstring(password);
278	memset(password, 0, strlen(password));
279	xfree(password);
280	packet_send();
281	packet_write_wait();
282	return 1;
283}
284
285typedef int sign_fn(
286    Key *key,
287    unsigned char **sigp, int *lenp,
288    unsigned char *data, int datalen);
289
290int
291ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
292    const char *server_user, const char *host, const char *service)
293{
294	Buffer b;
295	unsigned char *blob, *signature;
296	int bloblen, slen;
297	int skip = 0;
298	int ret = -1;
299
300	dsa_make_key_blob(k, &blob, &bloblen);
301
302	/* data to be signed */
303	buffer_init(&b);
304	if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
305		buffer_put_string(&b, session_id2, session_id2_len);
306		skip = buffer_len(&b);
307	} else {
308		buffer_append(&b, session_id2, session_id2_len);
309		skip = session_id2_len;
310	}
311	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
312	buffer_put_cstring(&b, server_user);
313	buffer_put_cstring(&b,
314	    datafellows & SSH_BUG_PUBKEYAUTH ?
315	    "ssh-userauth" :
316	    service);
317	buffer_put_cstring(&b, "publickey");
318	buffer_put_char(&b, 1);
319	buffer_put_cstring(&b, KEX_DSS);
320	buffer_put_string(&b, blob, bloblen);
321
322	/* generate signature */
323	ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
324	if (ret == -1) {
325		xfree(blob);
326		buffer_free(&b);
327		return 0;
328	}
329#ifdef DEBUG_DSS
330	buffer_dump(&b);
331#endif
332	if (datafellows & SSH_BUG_PUBKEYAUTH) {
333		buffer_clear(&b);
334		buffer_append(&b, session_id2, session_id2_len);
335		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
336		buffer_put_cstring(&b, server_user);
337		buffer_put_cstring(&b, service);
338		buffer_put_cstring(&b, "publickey");
339		buffer_put_char(&b, 1);
340		buffer_put_cstring(&b, KEX_DSS);
341		buffer_put_string(&b, blob, bloblen);
342	}
343	xfree(blob);
344	/* append signature */
345	buffer_put_string(&b, signature, slen);
346	xfree(signature);
347
348	/* skip session id and packet type */
349	if (buffer_len(&b) < skip + 1)
350		fatal("ssh2_try_pubkey: internal error");
351	buffer_consume(&b, skip + 1);
352
353	/* put remaining data from buffer into packet */
354	packet_start(SSH2_MSG_USERAUTH_REQUEST);
355	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
356	buffer_free(&b);
357
358	/* send */
359	packet_send();
360	packet_write_wait();
361
362	return 1;
363}
364
365int
366ssh2_try_pubkey(char *filename,
367    const char *server_user, const char *host, const char *service)
368{
369	Key *k;
370	int ret = 0;
371	struct stat st;
372
373	if (stat(filename, &st) != 0) {
374		debug("key does not exist: %s", filename);
375		return 0;
376	}
377	debug("try pubkey: %s", filename);
378
379	k = key_new(KEY_DSA);
380	if (!load_private_key(filename, "", k, NULL)) {
381		int success = 0;
382		char *passphrase;
383		char prompt[300];
384		snprintf(prompt, sizeof prompt,
385		     "Enter passphrase for DSA key '%.100s': ",
386		     filename);
387		passphrase = read_passphrase(prompt, 0);
388		success = load_private_key(filename, passphrase, k, NULL);
389		memset(passphrase, 0, strlen(passphrase));
390		xfree(passphrase);
391		if (!success) {
392			key_free(k);
393			return 0;
394		}
395	}
396	ret = ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service);
397	key_free(k);
398	return ret;
399}
400
401int agent_sign(
402    Key *key,
403    unsigned char **sigp, int *lenp,
404    unsigned char *data, int datalen)
405{
406	int ret = -1;
407	AuthenticationConnection *ac = ssh_get_authentication_connection();
408	if (ac != NULL) {
409		ret = ssh_agent_sign(ac, key, sigp, lenp, data, datalen);
410		ssh_close_authentication_connection(ac);
411	}
412	return ret;
413}
414
415int
416ssh2_try_agent(AuthenticationConnection *ac,
417    const char *server_user, const char *host, const char *service)
418{
419	static int called = 0;
420	char *comment;
421	Key *k;
422	int ret;
423
424	if (called == 0) {
425		k = ssh_get_first_identity(ac, &comment, 2);
426		called ++;
427	} else {
428		k = ssh_get_next_identity(ac, &comment, 2);
429	}
430	if (k == NULL)
431		return 0;
432	debug("trying DSA agent key %s", comment);
433	xfree(comment);
434	ret = ssh2_sign_and_send_pubkey(k, agent_sign, server_user, host, service);
435	key_free(k);
436	return ret;
437}
438
439void
440ssh_userauth2(const char *server_user, char *host)
441{
442	AuthenticationConnection *ac = ssh_get_authentication_connection();
443	int type;
444	int plen;
445	int sent;
446	unsigned int dlen;
447	int partial;
448	int i = 0;
449	char *auths;
450	char *service = "ssh-connection";		/* service name */
451
452	debug("send SSH2_MSG_SERVICE_REQUEST");
453	packet_start(SSH2_MSG_SERVICE_REQUEST);
454	packet_put_cstring("ssh-userauth");
455	packet_send();
456	packet_write_wait();
457
458	type = packet_read(&plen);
459	if (type != SSH2_MSG_SERVICE_ACCEPT) {
460		fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
461	}
462	if (packet_remaining() > 0) {
463		char *reply = packet_get_string(&plen);
464		debug("service_accept: %s", reply);
465		xfree(reply);
466	} else {
467		/* payload empty for ssh-2.0.13 ?? */
468		debug("buggy server: service_accept w/o service");
469	}
470	packet_done();
471	debug("got SSH2_MSG_SERVICE_ACCEPT");
472
473	/* INITIAL request for auth */
474	packet_start(SSH2_MSG_USERAUTH_REQUEST);
475	packet_put_cstring(server_user);
476	packet_put_cstring(service);
477	packet_put_cstring("none");
478	packet_send();
479	packet_write_wait();
480
481	for (;;) {
482		sent = 0;
483		type = packet_read(&plen);
484		if (type == SSH2_MSG_USERAUTH_SUCCESS)
485			break;
486		if (type != SSH2_MSG_USERAUTH_FAILURE)
487			fatal("access denied: %d", type);
488		/* SSH2_MSG_USERAUTH_FAILURE means: try again */
489		auths = packet_get_string(&dlen);
490		debug("authentications that can continue: %s", auths);
491		partial = packet_get_char();
492		packet_done();
493		if (partial)
494			debug("partial success");
495		if (options.dsa_authentication &&
496		    strstr(auths, "publickey") != NULL) {
497			if (ac != NULL)
498				sent = ssh2_try_agent(ac,
499				    server_user, host, service);
500			if (!sent) {
501				while (i < options.num_identity_files2) {
502					sent = ssh2_try_pubkey(
503					    options.identity_files2[i++],
504					    server_user, host, service);
505					if (sent)
506						break;
507				}
508			}
509		}
510		if (!sent) {
511			if (options.password_authentication &&
512			    !options.batch_mode &&
513			    strstr(auths, "password") != NULL) {
514				sent = ssh2_try_passwd(server_user, host, service);
515			}
516		}
517		if (!sent)
518			fatal("Permission denied (%s).", auths);
519		xfree(auths);
520	}
521	if (ac != NULL)
522		ssh_close_authentication_connection(ac);
523	packet_done();
524	debug("ssh-userauth2 successfull");
525}
526