summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-04-06 12:32:37 +1000
committerDamien Miller <djm@mindrot.org>2000-04-06 12:32:37 +1000
commit1383bd8eb91a8ec9c8d283679faec5925b0ccc42 (patch)
treef71278df6c50983ea3dad850ae79c45c340d9362 /sshconnect.c
parent74a333bbe11f67c59c559e0f424d5945eb438577 (diff)
- OpenBSD CVS update:
- [channels.c] close efd on eof - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h] ssh2 client implementation, interops w/ ssh.com and lsh servers. - [sshconnect.c] missing free. - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c] remove unused argument, split cipher_mask() - [clientloop.c] re-order: group ssh1 vs. ssh2 - Make Redhat spec require openssl >= 0.9.5a
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c350
1 files changed, 333 insertions, 17 deletions
diff --git a/sshconnect.c b/sshconnect.c
index d64c0e2c0..2f9496090 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -5,27 +5,30 @@
5 * Created: Sat Mar 18 22:15:47 1995 ylo 5 * Created: Sat Mar 18 22:15:47 1995 ylo
6 * Code to connect to a remote host, and to perform the client side of the 6 * Code to connect to a remote host, and to perform the client side of the
7 * login (authentication) dialog. 7 * login (authentication) dialog.
8 *
9 * SSH2 support added by Markus Friedl.
8 */ 10 */
9 11
10#include "includes.h" 12#include "includes.h"
11RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $"); 13RCSID("$OpenBSD: sshconnect.c,v 1.61 2000/04/04 21:37:27 markus Exp $");
12 14
13#ifdef HAVE_OPENSSL 15#ifdef HAVE_OPENSSL
16#include <openssl/bn.h>
14#include <openssl/rsa.h> 17#include <openssl/rsa.h>
15#include <openssl/dsa.h> 18#include <openssl/dsa.h>
16#include <openssl/md5.h> 19#include <openssl/md5.h>
17#include <openssl/bn.h>
18#endif 20#endif
19#ifdef HAVE_SSL 21#ifdef HAVE_SSL
22#include <ssl/bn.h>
20#include <ssl/rsa.h> 23#include <ssl/rsa.h>
21#include <ssl/dsa.h> 24#include <ssl/dsa.h>
22#include <ssl/md5.h> 25#include <ssl/md5.h>
23#include <ssl/bn.h>
24#endif 26#endif
25 27
26#include "xmalloc.h" 28#include "xmalloc.h"
27#include "rsa.h" 29#include "rsa.h"
28#include "ssh.h" 30#include "ssh.h"
31#include "buffer.h"
29#include "packet.h" 32#include "packet.h"
30#include "authfd.h" 33#include "authfd.h"
31#include "cipher.h" 34#include "cipher.h"
@@ -33,7 +36,14 @@ RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $");
33#include "uidswap.h" 36#include "uidswap.h"
34#include "compat.h" 37#include "compat.h"
35#include "readconf.h" 38#include "readconf.h"
39
40#include "bufaux.h"
41
42#include "ssh2.h"
43#include "kex.h"
44#include "myproposal.h"
36#include "key.h" 45#include "key.h"
46#include "dsa.h"
37#include "hostfile.h" 47#include "hostfile.h"
38 48
39/* Session id for the current session. */ 49/* Session id for the current session. */
@@ -42,6 +52,9 @@ unsigned char session_id[16];
42/* authentications supported by server */ 52/* authentications supported by server */
43unsigned int supported_authentications; 53unsigned int supported_authentications;
44 54
55static char *client_version_string = NULL;
56static char *server_version_string = NULL;
57
45extern Options options; 58extern Options options;
46extern char *__progname; 59extern char *__progname;
47 60
@@ -957,6 +970,21 @@ try_password_authentication(char *prompt)
957 return 0; 970 return 0;
958} 971}
959 972
973char *
974chop(char *s)
975{
976 char *t = s;
977 while (*t) {
978 if(*t == '\n' || *t == '\r') {
979 *t = '\0';
980 return s;
981 }
982 t++;
983 }
984 return s;
985
986}
987
960/* 988/*
961 * Waits for the server identification string, and sends our own 989 * Waits for the server identification string, and sends our own
962 * identification string. 990 * identification string.
@@ -979,7 +1007,7 @@ ssh_exchange_identification()
979 if (buf[i] == '\r') { 1007 if (buf[i] == '\r') {
980 buf[i] = '\n'; 1008 buf[i] = '\n';
981 buf[i + 1] = 0; 1009 buf[i + 1] = 0;
982 break; 1010 continue; /**XXX wait for \n */
983 } 1011 }
984 if (buf[i] == '\n') { 1012 if (buf[i] == '\n') {
985 buf[i + 1] = 0; 1013 buf[i + 1] = 0;
@@ -987,17 +1015,21 @@ ssh_exchange_identification()
987 } 1015 }
988 } 1016 }
989 buf[sizeof(buf) - 1] = 0; 1017 buf[sizeof(buf) - 1] = 0;
1018 server_version_string = xstrdup(buf);
990 1019
991 /* 1020 /*
992 * Check that the versions match. In future this might accept 1021 * Check that the versions match. In future this might accept
993 * several versions and set appropriate flags to handle them. 1022 * several versions and set appropriate flags to handle them.
994 */ 1023 */
995 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, 1024 if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n",
996 remote_version) != 3) 1025 &remote_major, &remote_minor, remote_version) != 3)
997 fatal("Bad remote protocol version identification: '%.100s'", buf); 1026 fatal("Bad remote protocol version identification: '%.100s'", buf);
998 debug("Remote protocol version %d.%d, remote software version %.100s", 1027 debug("Remote protocol version %d.%d, remote software version %.100s",
999 remote_major, remote_minor, remote_version); 1028 remote_major, remote_minor, remote_version);
1000 1029
1030/*** XXX option for disabling 2.0 or 1.5 */
1031 compat_datafellows(remote_version);
1032
1001 /* Check if the remote protocol version is too old. */ 1033 /* Check if the remote protocol version is too old. */
1002 if (remote_major == 1 && remote_minor < 3) 1034 if (remote_major == 1 && remote_minor < 3)
1003 fatal("Remote machine has too old SSH software version."); 1035 fatal("Remote machine has too old SSH software version.");
@@ -1010,6 +1042,10 @@ ssh_exchange_identification()
1010 options.forward_agent = 0; 1042 options.forward_agent = 0;
1011 } 1043 }
1012 } 1044 }
1045 if ((remote_major == 2 && remote_minor == 0) ||
1046 (remote_major == 1 && remote_minor == 99)) {
1047 enable_compat20();
1048 }
1013#if 0 1049#if 0
1014 /* 1050 /*
1015 * Removed for now, to permit compatibility with latter versions. The 1051 * Removed for now, to permit compatibility with latter versions. The
@@ -1020,16 +1056,19 @@ ssh_exchange_identification()
1020 fatal("Protocol major versions differ: %d vs. %d", 1056 fatal("Protocol major versions differ: %d vs. %d",
1021 PROTOCOL_MAJOR, remote_major); 1057 PROTOCOL_MAJOR, remote_major);
1022#endif 1058#endif
1023
1024 /* Send our own protocol version identification. */ 1059 /* Send our own protocol version identification. */
1025 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", 1060 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
1026 PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); 1061 compat20 ? 2 : PROTOCOL_MAJOR,
1062 compat20 ? 0 : PROTOCOL_MINOR,
1063 SSH_VERSION);
1027 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) 1064 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
1028 fatal("write: %.100s", strerror(errno)); 1065 fatal("write: %.100s", strerror(errno));
1066 client_version_string = xstrdup(buf);
1067 chop(client_version_string);
1068 chop(server_version_string);
1069 debug("Local version string %.100s", client_version_string);
1029} 1070}
1030 1071
1031int ssh_cipher_default = SSH_CIPHER_3DES;
1032
1033int 1072int
1034read_yes_or_no(const char *prompt, int defval) 1073read_yes_or_no(const char *prompt, int defval)
1035{ 1074{
@@ -1283,6 +1322,278 @@ check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
1283} 1322}
1284 1323
1285/* 1324/*
1325 * SSH2 key exchange
1326 */
1327void
1328ssh_kex2(char *host, struct sockaddr *hostaddr)
1329{
1330 Kex *kex;
1331 char *cprop[PROPOSAL_MAX];
1332 char *sprop[PROPOSAL_MAX];
1333 Buffer *client_kexinit;
1334 Buffer *server_kexinit;
1335 int payload_len, dlen;
1336 unsigned int klen, kout;
1337 char *ptr;
1338 char *signature = NULL;
1339 unsigned int slen;
1340 char *server_host_key_blob = NULL;
1341 Key *server_host_key;
1342 unsigned int sbloblen;
1343 DH *dh;
1344 BIGNUM *dh_server_pub = 0;
1345 BIGNUM *shared_secret = 0;
1346 int i;
1347 unsigned char *kbuf;
1348 unsigned char *hash;
1349
1350/* KEXINIT */
1351
1352 debug("Sending KEX init.");
1353 if (options.cipher == SSH_CIPHER_ARCFOUR ||
1354 options.cipher == SSH_CIPHER_3DES_CBC ||
1355 options.cipher == SSH_CIPHER_CAST128_CBC ||
1356 options.cipher == SSH_CIPHER_BLOWFISH_CBC) {
1357 myproposal[PROPOSAL_ENC_ALGS_CTOS] = cipher_name(options.cipher);
1358 myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher);
1359 }
1360 if (options.compression) {
1361 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";
1362 myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";
1363 } else {
1364 myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";
1365 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
1366 }
1367 for (i = 0; i < PROPOSAL_MAX; i++)
1368 cprop[i] = xstrdup(myproposal[i]);
1369
1370 client_kexinit = kex_init(cprop);
1371 packet_start(SSH2_MSG_KEXINIT);
1372 packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit));
1373 packet_send();
1374 packet_write_wait();
1375
1376 debug("done");
1377
1378 packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);
1379
1380 /* save payload for session_id */
1381 server_kexinit = xmalloc(sizeof(*server_kexinit));
1382 buffer_init(server_kexinit);
1383 ptr = packet_get_raw(&payload_len);
1384 buffer_append(server_kexinit, ptr, payload_len);
1385
1386 /* skip cookie */
1387 for (i = 0; i < 16; i++)
1388 (void) packet_get_char();
1389 /* kex init proposal strings */
1390 for (i = 0; i < PROPOSAL_MAX; i++) {
1391 sprop[i] = packet_get_string(NULL);
1392 debug("got kexinit string: %s", sprop[i]);
1393 }
1394 i = (int) packet_get_char();
1395 debug("first kex follow == %d", i);
1396 i = packet_get_int();
1397 debug("reserved == %d", i);
1398
1399 debug("done read kexinit");
1400 kex = kex_choose_conf(cprop, sprop, 0);
1401
1402/* KEXDH */
1403
1404 debug("Sending SSH2_MSG_KEXDH_INIT.");
1405
1406 /* generate and send 'e', client DH public key */
1407 dh = new_dh_group1();
1408 packet_start(SSH2_MSG_KEXDH_INIT);
1409 packet_put_bignum2(dh->pub_key);
1410 packet_send();
1411 packet_write_wait();
1412
1413#ifdef DEBUG_KEXDH
1414 fprintf(stderr, "\np= ");
1415 bignum_print(dh->p);
1416 fprintf(stderr, "\ng= ");
1417 bignum_print(dh->g);
1418 fprintf(stderr, "\npub= ");
1419 bignum_print(dh->pub_key);
1420 fprintf(stderr, "\n");
1421 DHparams_print_fp(stderr, dh);
1422#endif
1423
1424 debug("Wait SSH2_MSG_KEXDH_REPLY.");
1425
1426 packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY);
1427
1428 debug("Got SSH2_MSG_KEXDH_REPLY.");
1429
1430 /* key, cert */
1431 server_host_key_blob = packet_get_string(&sbloblen);
1432 server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen);
1433 if (server_host_key == NULL)
1434 fatal("cannot decode server_host_key_blob");
1435
1436 check_host_key(host, hostaddr, server_host_key);
1437
1438 /* DH paramter f, server public DH key */
1439 dh_server_pub = BN_new();
1440 if (dh_server_pub == NULL)
1441 fatal("dh_server_pub == NULL");
1442 packet_get_bignum2(dh_server_pub, &dlen);
1443
1444#ifdef DEBUG_KEXDH
1445 fprintf(stderr, "\ndh_server_pub= ");
1446 bignum_print(dh_server_pub);
1447 fprintf(stderr, "\n");
1448 debug("bits %d", BN_num_bits(dh_server_pub));
1449#endif
1450
1451 /* signed H */
1452 signature = packet_get_string(&slen);
1453
1454 klen = DH_size(dh);
1455 kbuf = xmalloc(klen);
1456 kout = DH_compute_key(kbuf, dh_server_pub, dh);
1457#ifdef DEBUG_KEXDH
1458 debug("shared secret: len %d/%d", klen, kout);
1459 fprintf(stderr, "shared secret == ");
1460 for (i = 0; i< kout; i++)
1461 fprintf(stderr, "%02x", (kbuf[i])&0xff);
1462 fprintf(stderr, "\n");
1463#endif
1464 shared_secret = BN_new();
1465
1466 BN_bin2bn(kbuf, kout, shared_secret);
1467 memset(kbuf, 0, klen);
1468 xfree(kbuf);
1469
1470 /* calc and verify H */
1471 hash = kex_hash(
1472 client_version_string,
1473 server_version_string,
1474 buffer_ptr(client_kexinit), buffer_len(client_kexinit),
1475 buffer_ptr(server_kexinit), buffer_len(server_kexinit),
1476 server_host_key_blob, sbloblen,
1477 dh->pub_key,
1478 dh_server_pub,
1479 shared_secret
1480 );
1481 buffer_free(client_kexinit);
1482 buffer_free(server_kexinit);
1483 xfree(client_kexinit);
1484 xfree(server_kexinit);
1485#ifdef DEBUG_KEXDH
1486 fprintf(stderr, "hash == ");
1487 for (i = 0; i< 20; i++)
1488 fprintf(stderr, "%02x", (hash[i])&0xff);
1489 fprintf(stderr, "\n");
1490#endif
1491 dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20);
1492 key_free(server_host_key);
1493
1494 kex_derive_keys(kex, hash, shared_secret);
1495 packet_set_kex(kex);
1496
1497 /* have keys, free DH */
1498 DH_free(dh);
1499
1500 debug("Wait SSH2_MSG_NEWKEYS.");
1501 packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
1502 debug("GOT SSH2_MSG_NEWKEYS.");
1503
1504 debug("send SSH2_MSG_NEWKEYS.");
1505 packet_start(SSH2_MSG_NEWKEYS);
1506 packet_send();
1507 packet_write_wait();
1508 debug("done: send SSH2_MSG_NEWKEYS.");
1509
1510 /* send 1st encrypted/maced/compressed message */
1511 packet_start(SSH2_MSG_IGNORE);
1512 packet_put_cstring("markus");
1513 packet_send();
1514 packet_write_wait();
1515
1516 debug("done: KEX2.");
1517}
1518/*
1519 * Authenticate user
1520 */
1521void
1522ssh_userauth2(int host_key_valid, RSA *own_host_key,
1523 uid_t original_real_uid, char *host)
1524{
1525 int type;
1526 int plen;
1527 unsigned int dlen;
1528 int partial;
1529 struct passwd *pw;
1530 char *server_user, *local_user;
1531 char *auths;
1532 char *password;
1533 char *service = "ssh-connection"; // service name
1534
1535 debug("send SSH2_MSG_SERVICE_REQUEST");
1536 packet_start(SSH2_MSG_SERVICE_REQUEST);
1537 packet_put_cstring("ssh-userauth");
1538 packet_send();
1539 packet_write_wait();
1540
1541 type = packet_read(&plen);
1542 if (type != SSH2_MSG_SERVICE_ACCEPT) {
1543 fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
1544 }
1545 /* payload empty for ssh-2.0.13 ?? */
1546 /* reply = packet_get_string(&payload_len); */
1547 debug("got SSH2_MSG_SERVICE_ACCEPT");
1548
1549 /*XX COMMONCODE: */
1550 /* Get local user name. Use it as server user if no user name was given. */
1551 pw = getpwuid(original_real_uid);
1552 if (!pw)
1553 fatal("User id %d not found from user database.", original_real_uid);
1554 local_user = xstrdup(pw->pw_name);
1555 server_user = options.user ? options.user : local_user;
1556
1557 /* INITIAL request for auth */
1558 packet_start(SSH2_MSG_USERAUTH_REQUEST);
1559 packet_put_cstring(server_user);
1560 packet_put_cstring(service);
1561 packet_put_cstring("none");
1562 packet_send();
1563 packet_write_wait();
1564
1565 for (;;) {
1566 type = packet_read(&plen);
1567 if (type == SSH2_MSG_USERAUTH_SUCCESS)
1568 break;
1569 if (type != SSH2_MSG_USERAUTH_FAILURE)
1570 fatal("access denied: %d", type);
1571 /* SSH2_MSG_USERAUTH_FAILURE means: try again */
1572 auths = packet_get_string(&dlen);
1573 debug("authentications that can continue: %s", auths);
1574 partial = packet_get_char();
1575 if (partial)
1576 debug("partial success");
1577 if (strstr(auths, "password") == NULL)
1578 fatal("passwd auth not supported: %s", auths);
1579 xfree(auths);
1580 /* try passwd */
1581 password = read_passphrase("password: ", 0);
1582 packet_start(SSH2_MSG_USERAUTH_REQUEST);
1583 packet_put_cstring(server_user);
1584 packet_put_cstring(service);
1585 packet_put_cstring("password");
1586 packet_put_char(0);
1587 packet_put_cstring(password);
1588 memset(password, 0, strlen(password));
1589 xfree(password);
1590 packet_send();
1591 packet_write_wait();
1592 }
1593 debug("ssh-userauth2 successfull");
1594}
1595
1596/*
1286 * SSH1 key exchange 1597 * SSH1 key exchange
1287 */ 1598 */
1288void 1599void
@@ -1293,6 +1604,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
1293 RSA *host_key; 1604 RSA *host_key;
1294 RSA *public_key; 1605 RSA *public_key;
1295 int bits, rbits; 1606 int bits, rbits;
1607 int ssh_cipher_default = SSH_CIPHER_3DES;
1296 unsigned char session_key[SSH_SESSION_KEY_LENGTH]; 1608 unsigned char session_key[SSH_SESSION_KEY_LENGTH];
1297 unsigned char cookie[8]; 1609 unsigned char cookie[8];
1298 unsigned int supported_ciphers; 1610 unsigned int supported_ciphers;
@@ -1427,7 +1739,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
1427 RSA_free(host_key); 1739 RSA_free(host_key);
1428 1740
1429 if (options.cipher == SSH_CIPHER_NOT_SET) { 1741 if (options.cipher == SSH_CIPHER_NOT_SET) {
1430 if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default)) 1742 if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default))
1431 options.cipher = ssh_cipher_default; 1743 options.cipher = ssh_cipher_default;
1432 else { 1744 else {
1433 debug("Cipher %s not supported, using %.100s instead.", 1745 debug("Cipher %s not supported, using %.100s instead.",
@@ -1640,12 +1952,16 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost,
1640 /* Put the connection into non-blocking mode. */ 1952 /* Put the connection into non-blocking mode. */
1641 packet_set_nonblocking(); 1953 packet_set_nonblocking();
1642 1954
1643 supported_authentications = 0;
1644 /* key exchange */ 1955 /* key exchange */
1645 ssh_kex(host, hostaddr);
1646 if (supported_authentications == 0)
1647 fatal("supported_authentications == 0.");
1648
1649 /* authenticate user */ 1956 /* authenticate user */
1650 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); 1957 if (compat20) {
1958 ssh_kex2(host, hostaddr);
1959 ssh_userauth2(host_key_valid, own_host_key, original_real_uid, host);
1960 } else {
1961 supported_authentications = 0;
1962 ssh_kex(host, hostaddr);
1963 if (supported_authentications == 0)
1964 fatal("supported_authentications == 0.");
1965 ssh_userauth(host_key_valid, own_host_key, original_real_uid, host);
1966 }
1651} 1967}