Annotation of src/usr.bin/ssh/sshconnect2.c, Revision 1.7
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.7 ! markus 31: RCSID("$OpenBSD: sshconnect2.c,v 1.6 2000/05/03 17:55:21 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: {
1.6 markus 286: static int attempt = 0;
1.1 markus 287: char prompt[80];
288: char *password;
1.6 markus 289:
290: if (attempt++ > options.number_of_password_prompts)
291: return 0;
1.1 markus 292:
293: snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
294: server_user, host);
295: password = read_passphrase(prompt, 0);
296: packet_start(SSH2_MSG_USERAUTH_REQUEST);
297: packet_put_cstring(server_user);
298: packet_put_cstring(service);
299: packet_put_cstring("password");
300: packet_put_char(0);
301: packet_put_cstring(password);
302: memset(password, 0, strlen(password));
303: xfree(password);
304: packet_send();
305: packet_write_wait();
306: return 1;
307: }
308:
309: int
310: ssh2_try_pubkey(char *filename,
311: const char *server_user, const char *host, const char *service)
312: {
313: Buffer b;
314: Key *k;
315: unsigned char *blob, *signature;
316: int bloblen, slen;
1.5 markus 317: struct stat st;
1.1 markus 318:
1.5 markus 319: if (stat(filename, &st) != 0) {
320: debug("key does not exist: %s", filename);
321: return 0;
322: }
1.1 markus 323: debug("try pubkey: %s", filename);
324:
325: k = key_new(KEY_DSA);
326: if (!load_private_key(filename, "", k, NULL)) {
327: int success = 0;
328: char *passphrase;
329: char prompt[300];
1.5 markus 330: snprintf(prompt, sizeof prompt,
1.1 markus 331: "Enter passphrase for DSA key '%.100s': ",
1.5 markus 332: filename);
1.1 markus 333: passphrase = read_passphrase(prompt, 0);
334: success = load_private_key(filename, passphrase, k, NULL);
335: memset(passphrase, 0, strlen(passphrase));
336: xfree(passphrase);
337: if (!success)
338: return 0;
339: }
340: dsa_make_key_blob(k, &blob, &bloblen);
341:
342: /* data to be signed */
343: buffer_init(&b);
344: buffer_append(&b, session_id2, session_id2_len);
345: buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
346: buffer_put_cstring(&b, server_user);
347: buffer_put_cstring(&b, service);
348: buffer_put_cstring(&b, "publickey");
349: buffer_put_char(&b, 1);
350: buffer_put_cstring(&b, KEX_DSS);
351: buffer_put_string(&b, blob, bloblen);
1.3 markus 352: xfree(blob);
1.1 markus 353:
354: /* generate signature */
355: dsa_sign(k, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
356: key_free(k);
357: #ifdef DEBUG_DSS
358: buffer_dump(&b);
359: #endif
360: /* append signature */
361: buffer_put_string(&b, signature, slen);
362: xfree(signature);
363:
364: /* skip session id and packet type */
365: if (buffer_len(&b) < session_id2_len + 1)
366: fatal("ssh2_try_pubkey: internal error");
367: buffer_consume(&b, session_id2_len + 1);
368:
369: /* put remaining data from buffer into packet */
370: packet_start(SSH2_MSG_USERAUTH_REQUEST);
371: packet_put_raw(buffer_ptr(&b), buffer_len(&b));
372: buffer_free(&b);
373:
374: /* send */
375: packet_send();
376: packet_write_wait();
377: return 1;
378: }
379:
380: void
381: ssh_userauth2(const char *server_user, char *host)
382: {
383: int type;
384: int plen;
385: int sent;
386: unsigned int dlen;
387: int partial;
388: int i = 0;
389: char *auths;
390: char *service = "ssh-connection"; /* service name */
391:
392: debug("send SSH2_MSG_SERVICE_REQUEST");
393: packet_start(SSH2_MSG_SERVICE_REQUEST);
394: packet_put_cstring("ssh-userauth");
395: packet_send();
396: packet_write_wait();
397:
398: type = packet_read(&plen);
399: if (type != SSH2_MSG_SERVICE_ACCEPT) {
400: fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
401: }
402: if (packet_remaining() > 0) {
403: char *reply = packet_get_string(&plen);
404: debug("service_accept: %s", reply);
405: xfree(reply);
406: } else {
407: /* payload empty for ssh-2.0.13 ?? */
408: log("buggy server: service_accept w/o service");
409: }
410: packet_done();
411: debug("got SSH2_MSG_SERVICE_ACCEPT");
412:
413: /* INITIAL request for auth */
414: packet_start(SSH2_MSG_USERAUTH_REQUEST);
415: packet_put_cstring(server_user);
416: packet_put_cstring(service);
417: packet_put_cstring("none");
418: packet_send();
419: packet_write_wait();
420:
421: for (;;) {
422: sent = 0;
423: type = packet_read(&plen);
424: if (type == SSH2_MSG_USERAUTH_SUCCESS)
425: break;
426: if (type != SSH2_MSG_USERAUTH_FAILURE)
427: fatal("access denied: %d", type);
428: /* SSH2_MSG_USERAUTH_FAILURE means: try again */
429: auths = packet_get_string(&dlen);
430: debug("authentications that can continue: %s", auths);
431: partial = packet_get_char();
432: packet_done();
433: if (partial)
434: debug("partial success");
1.7 ! markus 435: if (options.dsa_authentication &&
1.4 markus 436: strstr(auths, "publickey") != NULL) {
1.1 markus 437: while (i < options.num_identity_files2) {
438: sent = ssh2_try_pubkey(
439: options.identity_files2[i++],
440: server_user, host, service);
441: if (sent)
442: break;
443: }
444: }
445: if (!sent) {
1.4 markus 446: if (options.password_authentication &&
447: !options.batch_mode &&
448: strstr(auths, "password") != NULL) {
1.1 markus 449: sent = ssh2_try_passwd(server_user, host, service);
450: }
451: }
1.4 markus 452: if (!sent)
453: fatal("Permission denied (%s).", auths);
1.1 markus 454: xfree(auths);
455: }
456: packet_done();
457: debug("ssh-userauth2 successfull");
458: }