sshconnect2.c revision 61209
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 * 3. All advertising materials mentioning features or use of this software
13 *    must display the following acknowledgement:
14 *      This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "includes.h"
31RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $");
32
33#include <openssl/bn.h>
34#include <openssl/rsa.h>
35#include <openssl/dsa.h>
36#include <openssl/md5.h>
37#include <openssl/dh.h>
38#include <openssl/hmac.h>
39
40#include "ssh.h"
41#include "xmalloc.h"
42#include "rsa.h"
43#include "buffer.h"
44#include "packet.h"
45#include "cipher.h"
46#include "uidswap.h"
47#include "compat.h"
48#include "readconf.h"
49#include "bufaux.h"
50#include "ssh2.h"
51#include "kex.h"
52#include "myproposal.h"
53#include "key.h"
54#include "dsa.h"
55#include "sshconnect.h"
56#include "authfile.h"
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_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
72    Buffer *client_kexinit, Buffer *server_kexinit)
73{
74	int i;
75	int plen, dlen;
76	unsigned int klen, kout;
77	char *signature = NULL;
78	unsigned int slen;
79	char *server_host_key_blob = NULL;
80	Key *server_host_key;
81	unsigned int sbloblen;
82	DH *dh;
83	BIGNUM *dh_server_pub = 0;
84	BIGNUM *shared_secret = 0;
85	unsigned char *kbuf;
86	unsigned char *hash;
87
88	debug("Sending SSH2_MSG_KEXDH_INIT.");
89	/* generate and send 'e', client DH public key */
90	dh = dh_new_group1();
91	packet_start(SSH2_MSG_KEXDH_INIT);
92	packet_put_bignum2(dh->pub_key);
93	packet_send();
94	packet_write_wait();
95
96#ifdef DEBUG_KEXDH
97	fprintf(stderr, "\np= ");
98	bignum_print(dh->p);
99	fprintf(stderr, "\ng= ");
100	bignum_print(dh->g);
101	fprintf(stderr, "\npub= ");
102	bignum_print(dh->pub_key);
103	fprintf(stderr, "\n");
104	DHparams_print_fp(stderr, dh);
105#endif
106
107	debug("Wait SSH2_MSG_KEXDH_REPLY.");
108
109	packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
110
111	debug("Got SSH2_MSG_KEXDH_REPLY.");
112
113	/* key, cert */
114	server_host_key_blob = packet_get_string(&sbloblen);
115	server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
116	if (server_host_key == NULL)
117		fatal("cannot decode server_host_key_blob");
118
119	check_host_key(host, hostaddr, server_host_key,
120	    options.user_hostfile2, options.system_hostfile2);
121
122	/* DH paramter f, server public DH key */
123	dh_server_pub = BN_new();
124	if (dh_server_pub == NULL)
125		fatal("dh_server_pub == NULL");
126	packet_get_bignum2(dh_server_pub, &dlen);
127
128#ifdef DEBUG_KEXDH
129	fprintf(stderr, "\ndh_server_pub= ");
130	bignum_print(dh_server_pub);
131	fprintf(stderr, "\n");
132	debug("bits %d", BN_num_bits(dh_server_pub));
133#endif
134
135	/* signed H */
136	signature = packet_get_string(&slen);
137	packet_done();
138
139	if (!dh_pub_is_valid(dh, dh_server_pub))
140		packet_disconnect("bad server public DH value");
141
142	klen = DH_size(dh);
143	kbuf = xmalloc(klen);
144	kout = DH_compute_key(kbuf, dh_server_pub, dh);
145#ifdef DEBUG_KEXDH
146	debug("shared secret: len %d/%d", klen, kout);
147	fprintf(stderr, "shared secret == ");
148	for (i = 0; i< kout; i++)
149		fprintf(stderr, "%02x", (kbuf[i])&0xff);
150	fprintf(stderr, "\n");
151#endif
152	shared_secret = BN_new();
153
154	BN_bin2bn(kbuf, kout, shared_secret);
155	memset(kbuf, 0, klen);
156	xfree(kbuf);
157
158	/* calc and verify H */
159	hash = kex_hash(
160	    client_version_string,
161	    server_version_string,
162	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),
163	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),
164	    server_host_key_blob, sbloblen,
165	    dh->pub_key,
166	    dh_server_pub,
167	    shared_secret
168	);
169	xfree(server_host_key_blob);
170	DH_free(dh);
171#ifdef DEBUG_KEXDH
172	fprintf(stderr, "hash == ");
173	for (i = 0; i< 20; i++)
174		fprintf(stderr, "%02x", (hash[i])&0xff);
175	fprintf(stderr, "\n");
176#endif
177	if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
178		fatal("dsa_verify failed for server_host_key");
179	key_free(server_host_key);
180
181	kex_derive_keys(kex, hash, shared_secret);
182	packet_set_kex(kex);
183
184	/* save session id */
185	session_id2_len = 20;
186	session_id2 = xmalloc(session_id2_len);
187	memcpy(session_id2, hash, session_id2_len);
188}
189
190void
191ssh_kex2(char *host, struct sockaddr *hostaddr)
192{
193	int i, plen;
194	Kex *kex;
195	Buffer *client_kexinit, *server_kexinit;
196	char *sprop[PROPOSAL_MAX];
197
198	if (options.ciphers != NULL) {
199		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
200		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
201	} else if (options.cipher == SSH_CIPHER_3DES) {
202		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
203		myproposal[PROPOSAL_ENC_ALGS_STOC] =
204		    (char *) cipher_name(SSH_CIPHER_3DES_CBC);
205	} else if (options.cipher == SSH_CIPHER_BLOWFISH) {
206		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
207		myproposal[PROPOSAL_ENC_ALGS_STOC] =
208		    (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC);
209	}
210	if (options.compression) {
211		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
212		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
213	} else {
214		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
215		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
216	}
217
218	/* buffers with raw kexinit messages */
219	server_kexinit = xmalloc(sizeof(*server_kexinit));
220	buffer_init(server_kexinit);
221	client_kexinit = kex_init(myproposal);
222
223	/* algorithm negotiation */
224	kex_exchange_kexinit(client_kexinit, server_kexinit, sprop);
225	kex = kex_choose_conf(myproposal, sprop, 0);
226	for (i = 0; i < PROPOSAL_MAX; i++)
227		xfree(sprop[i]);
228
229	/* server authentication and session key agreement */
230	ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit);
231
232	buffer_free(client_kexinit);
233	buffer_free(server_kexinit);
234	xfree(client_kexinit);
235	xfree(server_kexinit);
236
237	debug("Wait SSH2_MSG_NEWKEYS.");
238	packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
239	packet_done();
240	debug("GOT SSH2_MSG_NEWKEYS.");
241
242	debug("send SSH2_MSG_NEWKEYS.");
243	packet_start(SSH2_MSG_NEWKEYS);
244	packet_send();
245	packet_write_wait();
246	debug("done: send SSH2_MSG_NEWKEYS.");
247
248#ifdef DEBUG_KEXDH
249	/* send 1st encrypted/maced/compressed message */
250	packet_start(SSH2_MSG_IGNORE);
251	packet_put_cstring("markus");
252	packet_send();
253	packet_write_wait();
254#endif
255	debug("done: KEX2.");
256}
257
258/*
259 * Authenticate user
260 */
261int
262ssh2_try_passwd(const char *server_user, const char *host, const char *service)
263{
264	static int attempt = 0;
265	char prompt[80];
266	char *password;
267
268	if (attempt++ > options.number_of_password_prompts)
269		return 0;
270
271	snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
272	    server_user, host);
273	password = read_passphrase(prompt, 0);
274	packet_start(SSH2_MSG_USERAUTH_REQUEST);
275	packet_put_cstring(server_user);
276	packet_put_cstring(service);
277	packet_put_cstring("password");
278	packet_put_char(0);
279	packet_put_cstring(password);
280	memset(password, 0, strlen(password));
281	xfree(password);
282	packet_send();
283	packet_write_wait();
284	return 1;
285}
286
287int
288ssh2_try_pubkey(char *filename,
289    const char *server_user, const char *host, const char *service)
290{
291	Buffer b;
292	Key *k;
293	unsigned char *blob, *signature;
294	int bloblen, slen;
295	struct stat st;
296
297	if (stat(filename, &st) != 0) {
298		debug("key does not exist: %s", filename);
299		return 0;
300	}
301	debug("try pubkey: %s", filename);
302
303	k = key_new(KEY_DSA);
304	if (!load_private_key(filename, "", k, NULL)) {
305		int success = 0;
306		char *passphrase;
307		char prompt[300];
308		snprintf(prompt, sizeof prompt,
309		     "Enter passphrase for DSA key '%.100s': ",
310		     filename);
311		passphrase = read_passphrase(prompt, 0);
312		success = load_private_key(filename, passphrase, k, NULL);
313		memset(passphrase, 0, strlen(passphrase));
314		xfree(passphrase);
315		if (!success)
316			return 0;
317	}
318	dsa_make_key_blob(k, &blob, &bloblen);
319
320	/* data to be signed */
321	buffer_init(&b);
322	buffer_append(&b, session_id2, session_id2_len);
323	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
324	buffer_put_cstring(&b, server_user);
325	buffer_put_cstring(&b,
326	    datafellows & SSH_BUG_PUBKEYAUTH ?
327	    "ssh-userauth" :
328	    service);
329	buffer_put_cstring(&b, "publickey");
330	buffer_put_char(&b, 1);
331	buffer_put_cstring(&b, KEX_DSS);
332	buffer_put_string(&b, blob, bloblen);
333
334	/* generate signature */
335	dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
336	key_free(k);
337#ifdef DEBUG_DSS
338	buffer_dump(&b);
339#endif
340	if (datafellows & SSH_BUG_PUBKEYAUTH) {
341		/* e.g. ssh-2.0.13: data-to-be-signed != data-on-the-wire */
342		buffer_clear(&b);
343		buffer_append(&b, session_id2, session_id2_len);
344		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
345		buffer_put_cstring(&b, server_user);
346		buffer_put_cstring(&b, service);
347		buffer_put_cstring(&b, "publickey");
348		buffer_put_char(&b, 1);
349		buffer_put_cstring(&b, KEX_DSS);
350		buffer_put_string(&b, blob, bloblen);
351	}
352	xfree(blob);
353	/* append signature */
354	buffer_put_string(&b, signature, slen);
355	xfree(signature);
356
357	/* skip session id and packet type */
358	if (buffer_len(&b) < session_id2_len + 1)
359		fatal("ssh2_try_pubkey: internal error");
360	buffer_consume(&b, session_id2_len + 1);
361
362	/* put remaining data from buffer into packet */
363	packet_start(SSH2_MSG_USERAUTH_REQUEST);
364	packet_put_raw(buffer_ptr(&b), buffer_len(&b));
365	buffer_free(&b);
366
367	/* send */
368	packet_send();
369	packet_write_wait();
370	return 1;
371}
372
373void
374ssh_userauth2(const char *server_user, char *host)
375{
376	int type;
377	int plen;
378	int sent;
379	unsigned int dlen;
380	int partial;
381	int i = 0;
382	char *auths;
383	char *service = "ssh-connection";		/* service name */
384
385	debug("send SSH2_MSG_SERVICE_REQUEST");
386	packet_start(SSH2_MSG_SERVICE_REQUEST);
387	packet_put_cstring("ssh-userauth");
388	packet_send();
389	packet_write_wait();
390
391	type = packet_read(&plen);
392	if (type != SSH2_MSG_SERVICE_ACCEPT) {
393		fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
394	}
395	if (packet_remaining() > 0) {
396		char *reply = packet_get_string(&plen);
397		debug("service_accept: %s", reply);
398		xfree(reply);
399	} else {
400		/* payload empty for ssh-2.0.13 ?? */
401		debug("buggy server: service_accept w/o service");
402	}
403	packet_done();
404	debug("got SSH2_MSG_SERVICE_ACCEPT");
405
406	/* INITIAL request for auth */
407	packet_start(SSH2_MSG_USERAUTH_REQUEST);
408	packet_put_cstring(server_user);
409	packet_put_cstring(service);
410	packet_put_cstring("none");
411	packet_send();
412	packet_write_wait();
413
414	for (;;) {
415		sent = 0;
416		type = packet_read(&plen);
417		if (type == SSH2_MSG_USERAUTH_SUCCESS)
418			break;
419		if (type != SSH2_MSG_USERAUTH_FAILURE)
420			fatal("access denied: %d", type);
421		/* SSH2_MSG_USERAUTH_FAILURE means: try again */
422		auths = packet_get_string(&dlen);
423		debug("authentications that can continue: %s", auths);
424		partial = packet_get_char();
425		packet_done();
426		if (partial)
427			debug("partial success");
428		if (options.dsa_authentication &&
429		    strstr(auths, "publickey") != NULL) {
430			while (i < options.num_identity_files2) {
431				sent = ssh2_try_pubkey(
432				    options.identity_files2[i++],
433				    server_user, host, service);
434				if (sent)
435					break;
436			}
437		}
438		if (!sent) {
439			if (options.password_authentication &&
440			    !options.batch_mode &&
441			    strstr(auths, "password") != NULL) {
442				sent = ssh2_try_passwd(server_user, host, service);
443			}
444		}
445		if (!sent)
446			fatal("Permission denied (%s).", auths);
447		xfree(auths);
448	}
449	packet_done();
450	debug("ssh-userauth2 successfull");
451}
452