Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.11
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.11 ! markus 31: RCSID("$OpenBSD: sshconnect2.c,v 1.10 2000/05/08 17:42:25 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
1.11 ! markus 71: ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
! 72: Buffer *client_kexinit, Buffer *server_kexinit)
1.1 markus 73: {
1.11 ! markus 74: int i;
! 75: int plen, dlen;
1.1 markus 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:
1.11 ! markus 109: packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
1.1 markus 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: );
1.3 markus 169: xfree(server_host_key_blob);
1.11 ! markus 170: DH_free(dh);
1.1 markus 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);
1.11 ! markus 188: }
! 189:
! 190: void
! 191: ssh_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);
1.1 markus 236:
237: debug("Wait SSH2_MSG_NEWKEYS.");
1.11 ! markus 238: packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
1.1 markus 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: }
1.11 ! markus 257:
1.1 markus 258: /*
259: * Authenticate user
260: */
261: int
262: ssh2_try_passwd(const char *server_user, const char *host, const char *service)
263: {
1.6 markus 264: static int attempt = 0;
1.1 markus 265: char prompt[80];
266: char *password;
1.6 markus 267:
268: if (attempt++ > options.number_of_password_prompts)
269: return 0;
1.1 markus 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:
287: int
288: ssh2_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;
1.5 markus 295: struct stat st;
1.1 markus 296:
1.5 markus 297: if (stat(filename, &st) != 0) {
298: debug("key does not exist: %s", filename);
299: return 0;
300: }
1.1 markus 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];
1.5 markus 308: snprintf(prompt, sizeof prompt,
1.1 markus 309: "Enter passphrase for DSA key '%.100s': ",
1.5 markus 310: filename);
1.1 markus 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);
1.10 markus 325: buffer_put_cstring(&b,
326: datafellows & SSH_BUG_PUBKEYAUTH ?
327: "ssh-userauth" :
328: service);
1.1 markus 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
1.10 markus 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);
1.1 markus 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:
373: void
374: ssh_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 ?? */
1.8 markus 401: debug("buggy server: service_accept w/o service");
1.1 markus 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");
1.7 markus 428: if (options.dsa_authentication &&
1.4 markus 429: strstr(auths, "publickey") != NULL) {
1.1 markus 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) {
1.4 markus 439: if (options.password_authentication &&
440: !options.batch_mode &&
441: strstr(auths, "password") != NULL) {
1.1 markus 442: sent = ssh2_try_passwd(server_user, host, service);
443: }
444: }
1.4 markus 445: if (!sent)
446: fatal("Permission denied (%s).", auths);
1.1 markus 447: xfree(auths);
448: }
449: packet_done();
450: debug("ssh-userauth2 successfull");
451: }