Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.10.2.2
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.10.2.2! jason 31: RCSID("$OpenBSD: sshconnect2.c,v 1.17 2000/08/19 21:34:44 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"
1.10.2.2! jason 57: #include "authfd.h"
1.1 markus 58:
59: /* import */
60: extern char *client_version_string;
61: extern char *server_version_string;
62: extern Options options;
63:
64: /*
65: * SSH2 key exchange
66: */
67:
68: unsigned char *session_id2 = NULL;
69: int session_id2_len = 0;
70:
71: void
1.10.2.1 jason 72: ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr,
73: Buffer *client_kexinit, Buffer *server_kexinit)
1.1 markus 74: {
1.10.2.1 jason 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.10.2.1 jason 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.10.2.1 jason 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.10.2.1 jason 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.10.2.1 jason 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.10.2.1 jason 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:
1.10.2.1 jason 268: if (attempt++ >= options.number_of_password_prompts)
1.6 markus 269: return 0;
1.10.2.1 jason 270:
271: if(attempt != 1)
272: error("Permission denied, please try again.");
1.1 markus 273:
274: snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
275: server_user, host);
276: password = read_passphrase(prompt, 0);
277: packet_start(SSH2_MSG_USERAUTH_REQUEST);
278: packet_put_cstring(server_user);
279: packet_put_cstring(service);
280: packet_put_cstring("password");
281: packet_put_char(0);
282: packet_put_cstring(password);
283: memset(password, 0, strlen(password));
284: xfree(password);
285: packet_send();
286: packet_write_wait();
287: return 1;
288: }
289:
1.10.2.2! jason 290: typedef int sign_fn(
! 291: Key *key,
! 292: unsigned char **sigp, int *lenp,
! 293: unsigned char *data, int datalen);
! 294:
1.1 markus 295: int
1.10.2.2! jason 296: ssh2_sign_and_send_pubkey(Key *k, sign_fn *do_sign,
1.1 markus 297: const char *server_user, const char *host, const char *service)
298: {
299: Buffer b;
300: unsigned char *blob, *signature;
301: int bloblen, slen;
1.10.2.2! jason 302: int skip = 0;
! 303: int ret = -1;
1.1 markus 304:
305: dsa_make_key_blob(k, &blob, &bloblen);
306:
307: /* data to be signed */
308: buffer_init(&b);
1.10.2.2! jason 309: if (datafellows & SSH_COMPAT_SESSIONID_ENCODING) {
! 310: buffer_put_string(&b, session_id2, session_id2_len);
! 311: skip = buffer_len(&b);
! 312: } else {
! 313: buffer_append(&b, session_id2, session_id2_len);
! 314: skip = session_id2_len;
! 315: }
1.1 markus 316: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
317: buffer_put_cstring(&b, server_user);
1.10 markus 318: buffer_put_cstring(&b,
319: datafellows & SSH_BUG_PUBKEYAUTH ?
320: "ssh-userauth" :
321: service);
1.1 markus 322: buffer_put_cstring(&b, "publickey");
323: buffer_put_char(&b, 1);
324: buffer_put_cstring(&b, KEX_DSS);
325: buffer_put_string(&b, blob, bloblen);
326:
327: /* generate signature */
1.10.2.2! jason 328: ret = do_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
! 329: if (ret == -1) {
! 330: xfree(blob);
! 331: buffer_free(&b);
! 332: return 0;
! 333: }
1.1 markus 334: #ifdef DEBUG_DSS
335: buffer_dump(&b);
336: #endif
1.10 markus 337: if (datafellows & SSH_BUG_PUBKEYAUTH) {
338: buffer_clear(&b);
339: buffer_append(&b, session_id2, session_id2_len);
340: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
341: buffer_put_cstring(&b, server_user);
342: buffer_put_cstring(&b, service);
343: buffer_put_cstring(&b, "publickey");
344: buffer_put_char(&b, 1);
345: buffer_put_cstring(&b, KEX_DSS);
346: buffer_put_string(&b, blob, bloblen);
347: }
348: xfree(blob);
1.1 markus 349: /* append signature */
350: buffer_put_string(&b, signature, slen);
351: xfree(signature);
352:
353: /* skip session id and packet type */
1.10.2.2! jason 354: if (buffer_len(&b) < skip + 1)
1.1 markus 355: fatal("ssh2_try_pubkey: internal error");
1.10.2.2! jason 356: buffer_consume(&b, skip + 1);
1.1 markus 357:
358: /* put remaining data from buffer into packet */
359: packet_start(SSH2_MSG_USERAUTH_REQUEST);
360: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
361: buffer_free(&b);
362:
363: /* send */
364: packet_send();
365: packet_write_wait();
1.10.2.2! jason 366:
1.1 markus 367: return 1;
368: }
369:
1.10.2.2! jason 370: int
! 371: ssh2_try_pubkey(char *filename,
! 372: const char *server_user, const char *host, const char *service)
! 373: {
! 374: Key *k;
! 375: int ret = 0;
! 376: struct stat st;
! 377:
! 378: if (stat(filename, &st) != 0) {
! 379: debug("key does not exist: %s", filename);
! 380: return 0;
! 381: }
! 382: debug("try pubkey: %s", filename);
! 383:
! 384: k = key_new(KEY_DSA);
! 385: if (!load_private_key(filename, "", k, NULL)) {
! 386: int success = 0;
! 387: char *passphrase;
! 388: char prompt[300];
! 389: snprintf(prompt, sizeof prompt,
! 390: "Enter passphrase for DSA key '%.100s': ",
! 391: filename);
! 392: passphrase = read_passphrase(prompt, 0);
! 393: success = load_private_key(filename, passphrase, k, NULL);
! 394: memset(passphrase, 0, strlen(passphrase));
! 395: xfree(passphrase);
! 396: if (!success) {
! 397: key_free(k);
! 398: return 0;
! 399: }
! 400: }
! 401: ret = ssh2_sign_and_send_pubkey(k, dsa_sign, server_user, host, service);
! 402: key_free(k);
! 403: return ret;
! 404: }
! 405:
! 406: int agent_sign(
! 407: Key *key,
! 408: unsigned char **sigp, int *lenp,
! 409: unsigned char *data, int datalen)
! 410: {
! 411: int ret = -1;
! 412: AuthenticationConnection *ac = ssh_get_authentication_connection();
! 413: if (ac != NULL) {
! 414: ret = ssh_agent_sign(ac, key, sigp, lenp, data, datalen);
! 415: ssh_close_authentication_connection(ac);
! 416: }
! 417: return ret;
! 418: }
! 419:
! 420: int
! 421: ssh2_try_agent(AuthenticationConnection *ac,
! 422: const char *server_user, const char *host, const char *service)
! 423: {
! 424: static int called = 0;
! 425: char *comment;
! 426: Key *k;
! 427: int ret;
! 428:
! 429: if (called == 0) {
! 430: k = ssh_get_first_identity(ac, &comment, 2);
! 431: called ++;
! 432: } else {
! 433: k = ssh_get_next_identity(ac, &comment, 2);
! 434: }
! 435: if (k == NULL)
! 436: return 0;
! 437: debug("trying DSA agent key %s", comment);
! 438: xfree(comment);
! 439: ret = ssh2_sign_and_send_pubkey(k, agent_sign, server_user, host, service);
! 440: key_free(k);
! 441: return ret;
! 442: }
! 443:
1.1 markus 444: void
445: ssh_userauth2(const char *server_user, char *host)
446: {
1.10.2.2! jason 447: AuthenticationConnection *ac = ssh_get_authentication_connection();
1.1 markus 448: int type;
449: int plen;
450: int sent;
451: unsigned int dlen;
452: int partial;
453: int i = 0;
454: char *auths;
455: char *service = "ssh-connection"; /* service name */
456:
457: debug("send SSH2_MSG_SERVICE_REQUEST");
458: packet_start(SSH2_MSG_SERVICE_REQUEST);
459: packet_put_cstring("ssh-userauth");
460: packet_send();
461: packet_write_wait();
462:
463: type = packet_read(&plen);
464: if (type != SSH2_MSG_SERVICE_ACCEPT) {
465: fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
466: }
467: if (packet_remaining() > 0) {
468: char *reply = packet_get_string(&plen);
469: debug("service_accept: %s", reply);
470: xfree(reply);
471: } else {
472: /* payload empty for ssh-2.0.13 ?? */
1.8 markus 473: debug("buggy server: service_accept w/o service");
1.1 markus 474: }
475: packet_done();
476: debug("got SSH2_MSG_SERVICE_ACCEPT");
477:
478: /* INITIAL request for auth */
479: packet_start(SSH2_MSG_USERAUTH_REQUEST);
480: packet_put_cstring(server_user);
481: packet_put_cstring(service);
482: packet_put_cstring("none");
483: packet_send();
484: packet_write_wait();
485:
486: for (;;) {
487: sent = 0;
488: type = packet_read(&plen);
489: if (type == SSH2_MSG_USERAUTH_SUCCESS)
490: break;
491: if (type != SSH2_MSG_USERAUTH_FAILURE)
492: fatal("access denied: %d", type);
493: /* SSH2_MSG_USERAUTH_FAILURE means: try again */
494: auths = packet_get_string(&dlen);
495: debug("authentications that can continue: %s", auths);
496: partial = packet_get_char();
497: packet_done();
498: if (partial)
499: debug("partial success");
1.7 markus 500: if (options.dsa_authentication &&
1.4 markus 501: strstr(auths, "publickey") != NULL) {
1.10.2.2! jason 502: if (ac != NULL)
! 503: sent = ssh2_try_agent(ac,
1.1 markus 504: server_user, host, service);
1.10.2.2! jason 505: if (!sent) {
! 506: while (i < options.num_identity_files2) {
! 507: sent = ssh2_try_pubkey(
! 508: options.identity_files2[i++],
! 509: server_user, host, service);
! 510: if (sent)
! 511: break;
! 512: }
1.1 markus 513: }
514: }
515: if (!sent) {
1.4 markus 516: if (options.password_authentication &&
517: !options.batch_mode &&
518: strstr(auths, "password") != NULL) {
1.1 markus 519: sent = ssh2_try_passwd(server_user, host, service);
520: }
521: }
1.4 markus 522: if (!sent)
523: fatal("Permission denied (%s).", auths);
1.1 markus 524: xfree(auths);
525: }
1.10.2.2! jason 526: if (ac != NULL)
! 527: ssh_close_authentication_connection(ac);
1.1 markus 528: packet_done();
529: debug("ssh-userauth2 successfull");
530: }