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