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