summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-10-14 16:23:11 +1100
committerDamien Miller <djm@mindrot.org>2000-10-14 16:23:11 +1100
commit874d77bb134a21a5cf625956b60173376a993ba8 (patch)
tree93dd73b2ff1fbf0ad5f3978a2c4e0d8438a0bf7c /sshd.c
parent89d9796fbedef4eed6956a2c095c7cc25330c28d (diff)
- (djm) Big OpenBSD sync:
- markus@cvs.openbsd.org 2000/09/30 10:27:44 [log.c] allow loglevel debug - markus@cvs.openbsd.org 2000/10/03 11:59:57 [packet.c] hmac->mac - markus@cvs.openbsd.org 2000/10/03 12:03:03 [auth-krb4.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth1.c] move fake-auth from auth1.c to individual auth methods, disables s/key in debug-msg - markus@cvs.openbsd.org 2000/10/03 12:16:48 ssh.c do not resolve canonname, i have no idea why this was added oin ossh - markus@cvs.openbsd.org 2000/10/09 15:30:44 ssh-keygen.1 ssh-keygen.c -X now reads private ssh.com DSA keys, too. - markus@cvs.openbsd.org 2000/10/09 15:32:34 auth-options.c clear options on every call. - markus@cvs.openbsd.org 2000/10/09 15:51:00 authfd.c authfd.h interop with ssh-agent2, from <res@shore.net> - markus@cvs.openbsd.org 2000/10/10 14:20:45 compat.c use rexexp for version string matching - provos@cvs.openbsd.org 2000/10/10 22:02:18 [kex.c kex.h myproposal.h ssh.h ssh2.h sshconnect2.c sshd.c dh.c dh.h] First rough implementation of the diffie-hellman group exchange. The client can ask the server for bigger groups to perform the diffie-hellman in, thus increasing the attack complexity when using ciphers with longer keys. University of Windsor provided network, T the company. - markus@cvs.openbsd.org 2000/10/11 13:59:52 [auth-rsa.c auth2.c] clear auth options unless auth sucessfull - markus@cvs.openbsd.org 2000/10/11 14:00:27 [auth-options.h] clear auth options unless auth sucessfull - markus@cvs.openbsd.org 2000/10/11 14:03:27 [scp.1 scp.c] support 'scp -o' with help from mouring@pconline.com - markus@cvs.openbsd.org 2000/10/11 14:11:35 [dh.c] Wall - markus@cvs.openbsd.org 2000/10/11 14:14:40 [auth.h auth2.c readconf.c readconf.h readpass.c servconf.c servconf.h] [ssh.h sshconnect2.c sshd_config auth2-skey.c cli.c cli.h] add support for s/key (kbd-interactive) to ssh2, based on work by mkiernan@avantgo.com and me - markus@cvs.openbsd.org 2000/10/11 14:27:24 [auth.c auth1.c auth2.c authfile.c cipher.c cipher.h kex.c kex.h] [myproposal.h packet.c readconf.c session.c ssh.c ssh.h sshconnect1.c] [sshconnect2.c sshd.c] new cipher framework - markus@cvs.openbsd.org 2000/10/11 14:45:21 [cipher.c] remove DES - markus@cvs.openbsd.org 2000/10/12 03:59:20 [cipher.c cipher.h sshconnect1.c sshconnect2.c sshd.c] enable DES in SSH-1 clients only - markus@cvs.openbsd.org 2000/10/12 08:21:13 [kex.h packet.c] remove unused - markus@cvs.openbsd.org 2000/10/13 12:34:46 [sshd.c] Kludge for F-Secure Macintosh < 1.0.2; appro@fy.chalmers.se - markus@cvs.openbsd.org 2000/10/13 12:59:15 [cipher.c cipher.h myproposal.h rijndael.c rijndael.h] rijndael/aes support - markus@cvs.openbsd.org 2000/10/13 13:10:54 [sshd.8] more info about -V - markus@cvs.openbsd.org 2000/10/13 13:12:02 [myproposal.h] prefer no compression
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c225
1 files changed, 197 insertions, 28 deletions
diff --git a/sshd.c b/sshd.c
index ae22cd953..e5c2508a1 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,14 +40,13 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.128 2000/09/17 15:38:59 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.132 2000/10/13 18:34:46 markus Exp $");
44 44
45#include "xmalloc.h" 45#include "xmalloc.h"
46#include "rsa.h" 46#include "rsa.h"
47#include "ssh.h" 47#include "ssh.h"
48#include "pty.h" 48#include "pty.h"
49#include "packet.h" 49#include "packet.h"
50#include "cipher.h"
51#include "mpaux.h" 50#include "mpaux.h"
52#include "servconf.h" 51#include "servconf.h"
53#include "uidswap.h" 52#include "uidswap.h"
@@ -63,6 +62,7 @@ RCSID("$OpenBSD: sshd.c,v 1.128 2000/09/17 15:38:59 markus Exp $");
63#include <openssl/rsa.h> 62#include <openssl/rsa.h>
64#include "key.h" 63#include "key.h"
65#include "dsa.h" 64#include "dsa.h"
65#include "dh.h"
66 66
67#include "auth.h" 67#include "auth.h"
68#include "myproposal.h" 68#include "myproposal.h"
@@ -172,6 +172,9 @@ unsigned int utmp_len = MAXHOSTNAMELEN;
172void do_ssh1_kex(); 172void do_ssh1_kex();
173void do_ssh2_kex(); 173void do_ssh2_kex();
174 174
175void ssh_dh1_server(Kex *, Buffer *_kexinit, Buffer *);
176void ssh_dhgex_server(Kex *, Buffer *_kexinit, Buffer *);
177
175/* 178/*
176 * Close all listening sockets 179 * Close all listening sockets
177 */ 180 */
@@ -333,6 +336,10 @@ sshd_exchange_identification(int sock_in, int sock_out)
333 if (buf[i] == '\r') { 336 if (buf[i] == '\r') {
334 buf[i] = '\n'; 337 buf[i] = '\n';
335 buf[i + 1] = 0; 338 buf[i + 1] = 0;
339 /* Kludge for F-Secure Macintosh < 1.0.2 */
340 if (i == 12 &&
341 strncmp(buf, "SSH-1.5-W1.0", 12) == 0)
342 break;
336 continue; 343 continue;
337 } 344 }
338 if (buf[i] == '\n') { 345 if (buf[i] == '\n') {
@@ -1151,7 +1158,7 @@ do_ssh1_kex()
1151 packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); 1158 packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
1152 1159
1153 /* Declare which ciphers we support. */ 1160 /* Declare which ciphers we support. */
1154 packet_put_int(cipher_mask1()); 1161 packet_put_int(cipher_mask_ssh1(0));
1155 1162
1156 /* Declare supported authentication types. */ 1163 /* Declare supported authentication types. */
1157 auth_mask = 0; 1164 auth_mask = 0;
@@ -1192,7 +1199,7 @@ do_ssh1_kex()
1192 /* Get cipher type and check whether we accept this. */ 1199 /* Get cipher type and check whether we accept this. */
1193 cipher_type = packet_get_char(); 1200 cipher_type = packet_get_char();
1194 1201
1195 if (!(cipher_mask() & (1 << cipher_type))) 1202 if (!(cipher_mask_ssh1(0) & (1 << cipher_type)))
1196 packet_disconnect("Warning: client selects unsupported cipher."); 1203 packet_disconnect("Warning: client selects unsupported cipher.");
1197 1204
1198 /* Get check bytes from the packet. These must match those we 1205 /* Get check bytes from the packet. These must match those we
@@ -1296,18 +1303,8 @@ do_ssh2_kex()
1296{ 1303{
1297 Buffer *server_kexinit; 1304 Buffer *server_kexinit;
1298 Buffer *client_kexinit; 1305 Buffer *client_kexinit;
1299 int payload_len, dlen; 1306 int payload_len;
1300 int slen;
1301 unsigned int klen, kout;
1302 unsigned char *signature = NULL;
1303 unsigned char *server_host_key_blob = NULL;
1304 unsigned int sbloblen;
1305 DH *dh;
1306 BIGNUM *dh_client_pub = 0;
1307 BIGNUM *shared_secret = 0;
1308 int i; 1307 int i;
1309 unsigned char *kbuf;
1310 unsigned char *hash;
1311 Kex *kex; 1308 Kex *kex;
1312 char *cprop[PROPOSAL_MAX]; 1309 char *cprop[PROPOSAL_MAX];
1313 1310
@@ -1327,8 +1324,63 @@ do_ssh2_kex()
1327 for (i = 0; i < PROPOSAL_MAX; i++) 1324 for (i = 0; i < PROPOSAL_MAX; i++)
1328 xfree(cprop[i]); 1325 xfree(cprop[i]);
1329 1326
1330/* KEXDH */ 1327 switch (kex->kex_type) {
1328 case DH_GRP1_SHA1:
1329 ssh_dh1_server(kex, client_kexinit, server_kexinit);
1330 break;
1331 case DH_GEX_SHA1:
1332 ssh_dhgex_server(kex, client_kexinit, server_kexinit);
1333 break;
1334 default:
1335 fatal("Unsupported key exchange %d", kex->kex_type);
1336 }
1337
1338 debug("send SSH2_MSG_NEWKEYS.");
1339 packet_start(SSH2_MSG_NEWKEYS);
1340 packet_send();
1341 packet_write_wait();
1342 debug("done: send SSH2_MSG_NEWKEYS.");
1343
1344 debug("Wait SSH2_MSG_NEWKEYS.");
1345 packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
1346 debug("GOT SSH2_MSG_NEWKEYS.");
1347
1348#ifdef DEBUG_KEXDH
1349 /* send 1st encrypted/maced/compressed message */
1350 packet_start(SSH2_MSG_IGNORE);
1351 packet_put_cstring("markus");
1352 packet_send();
1353 packet_write_wait();
1354#endif
1355
1356 debug("done: KEX2.");
1357}
1358
1359/*
1360 * SSH2 key exchange
1361 */
1362
1363/* diffie-hellman-group1-sha1 */
1364
1365void
1366ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1367{
1368#ifdef DEBUG_KEXDH
1369 int i;
1370#endif
1371 int payload_len, dlen;
1372 int slen;
1373 unsigned char *signature = NULL;
1374 unsigned char *server_host_key_blob = NULL;
1375 unsigned int sbloblen;
1376 unsigned int klen, kout;
1377 unsigned char *kbuf;
1378 unsigned char *hash;
1379 BIGNUM *shared_secret = 0;
1380 DH *dh;
1381 BIGNUM *dh_client_pub = 0;
1331 1382
1383/* KEXDH */
1332 debug("Wait SSH2_MSG_KEXDH_INIT."); 1384 debug("Wait SSH2_MSG_KEXDH_INIT.");
1333 packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT); 1385 packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);
1334 1386
@@ -1379,7 +1431,8 @@ do_ssh2_kex()
1379 xfree(kbuf); 1431 xfree(kbuf);
1380 1432
1381 /* XXX precompute? */ 1433 /* XXX precompute? */
1382 dsa_make_key_blob(sensitive_data.dsa_host_key, &server_host_key_blob, &sbloblen); 1434 dsa_make_key_blob(sensitive_data.dsa_host_key,
1435 &server_host_key_blob, &sbloblen);
1383 1436
1384 /* calc H */ /* XXX depends on 'kex' */ 1437 /* calc H */ /* XXX depends on 'kex' */
1385 hash = kex_hash( 1438 hash = kex_hash(
@@ -1429,23 +1482,139 @@ do_ssh2_kex()
1429 1482
1430 /* have keys, free DH */ 1483 /* have keys, free DH */
1431 DH_free(dh); 1484 DH_free(dh);
1485}
1432 1486
1433 debug("send SSH2_MSG_NEWKEYS."); 1487/* diffie-hellman-group-exchange-sha1 */
1434 packet_start(SSH2_MSG_NEWKEYS); 1488
1489void
1490ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1491{
1492#ifdef DEBUG_KEXDH
1493 int i;
1494#endif
1495 int payload_len, dlen;
1496 int slen, nbits;
1497 unsigned char *signature = NULL;
1498 unsigned char *server_host_key_blob = NULL;
1499 unsigned int sbloblen;
1500 unsigned int klen, kout;
1501 unsigned char *kbuf;
1502 unsigned char *hash;
1503 BIGNUM *shared_secret = 0;
1504 DH *dh;
1505 BIGNUM *dh_client_pub = 0;
1506
1507/* KEXDHGEX */
1508 debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
1509 packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_REQUEST);
1510 nbits = packet_get_int();
1511 dh = choose_dh(nbits);
1512
1513 debug("Sending SSH2_MSG_KEX_DH_GEX_GROUP.");
1514 packet_start(SSH2_MSG_KEX_DH_GEX_GROUP);
1515 packet_put_bignum2(dh->p);
1516 packet_put_bignum2(dh->g);
1435 packet_send(); 1517 packet_send();
1436 packet_write_wait(); 1518 packet_write_wait();
1437 debug("done: send SSH2_MSG_NEWKEYS.");
1438 1519
1439 debug("Wait SSH2_MSG_NEWKEYS."); 1520 debug("Wait SSH2_MSG_KEX_DH_GEX_INIT.");
1440 packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); 1521 packet_read_expect(&payload_len, SSH2_MSG_KEX_DH_GEX_INIT);
1441 debug("GOT SSH2_MSG_NEWKEYS."); 1522
1523 /* key, cert */
1524 dh_client_pub = BN_new();
1525 if (dh_client_pub == NULL)
1526 fatal("dh_client_pub == NULL");
1527 packet_get_bignum2(dh_client_pub, &dlen);
1442 1528
1443#ifdef DEBUG_KEXDH 1529#ifdef DEBUG_KEXDH
1444 /* send 1st encrypted/maced/compressed message */ 1530 fprintf(stderr, "\ndh_client_pub= ");
1445 packet_start(SSH2_MSG_IGNORE); 1531 BN_print_fp(stderr, dh_client_pub);
1446 packet_put_cstring("markus"); 1532 fprintf(stderr, "\n");
1533 debug("bits %d", BN_num_bits(dh_client_pub));
1534#endif
1535
1536#ifdef DEBUG_KEXDH
1537 fprintf(stderr, "\np= ");
1538 BN_print_fp(stderr, dh->p);
1539 fprintf(stderr, "\ng= ");
1540 bn_print(dh->g);
1541 fprintf(stderr, "\npub= ");
1542 BN_print_fp(stderr, dh->pub_key);
1543 fprintf(stderr, "\n");
1544 DHparams_print_fp(stderr, dh);
1545#endif
1546 if (!dh_pub_is_valid(dh, dh_client_pub))
1547 packet_disconnect("bad client public DH value");
1548
1549 klen = DH_size(dh);
1550 kbuf = xmalloc(klen);
1551 kout = DH_compute_key(kbuf, dh_client_pub, dh);
1552
1553#ifdef DEBUG_KEXDH
1554 debug("shared secret: len %d/%d", klen, kout);
1555 fprintf(stderr, "shared secret == ");
1556 for (i = 0; i< kout; i++)
1557 fprintf(stderr, "%02x", (kbuf[i])&0xff);
1558 fprintf(stderr, "\n");
1559#endif
1560 shared_secret = BN_new();
1561
1562 BN_bin2bn(kbuf, kout, shared_secret);
1563 memset(kbuf, 0, klen);
1564 xfree(kbuf);
1565
1566 /* XXX precompute? */
1567 dsa_make_key_blob(sensitive_data.dsa_host_key,
1568 &server_host_key_blob, &sbloblen);
1569
1570 /* calc H */ /* XXX depends on 'kex' */
1571 hash = kex_hash_gex(
1572 client_version_string,
1573 server_version_string,
1574 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
1575 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
1576 (char *)server_host_key_blob, sbloblen,
1577 nbits, dh->p, dh->g,
1578 dh_client_pub,
1579 dh->pub_key,
1580 shared_secret
1581 );
1582 buffer_free(client_kexinit);
1583 buffer_free(server_kexinit);
1584 xfree(client_kexinit);
1585 xfree(server_kexinit);
1586#ifdef DEBUG_KEXDH
1587 fprintf(stderr, "hash == ");
1588 for (i = 0; i< 20; i++)
1589 fprintf(stderr, "%02x", (hash[i])&0xff);
1590 fprintf(stderr, "\n");
1591#endif
1592 /* save session id := H */
1593 /* XXX hashlen depends on KEX */
1594 session_id2_len = 20;
1595 session_id2 = xmalloc(session_id2_len);
1596 memcpy(session_id2, hash, session_id2_len);
1597
1598 /* sign H */
1599 /* XXX hashlen depends on KEX */
1600 dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20);
1601
1602 destroy_sensitive_data();
1603
1604 /* send server hostkey, DH pubkey 'f' and singed H */
1605 packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
1606 packet_put_string((char *)server_host_key_blob, sbloblen);
1607 packet_put_bignum2(dh->pub_key); /* f */
1608 packet_put_string((char *)signature, slen);
1447 packet_send(); 1609 packet_send();
1610 xfree(signature);
1611 xfree(server_host_key_blob);
1448 packet_write_wait(); 1612 packet_write_wait();
1449#endif 1613
1450 debug("done: KEX2."); 1614 kex_derive_keys(kex, hash, shared_secret);
1615 packet_set_kex(kex);
1616
1617 /* have keys, free DH */
1618 DH_free(dh);
1451} 1619}
1620