diff options
author | Damien Miller <djm@mindrot.org> | 2000-04-06 12:32:37 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-04-06 12:32:37 +1000 |
commit | 1383bd8eb91a8ec9c8d283679faec5925b0ccc42 (patch) | |
tree | f71278df6c50983ea3dad850ae79c45c340d9362 /sshconnect.c | |
parent | 74a333bbe11f67c59c559e0f424d5945eb438577 (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.c | 350 |
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" |
11 | RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $"); | 13 | RCSID("$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 */ |
43 | unsigned int supported_authentications; | 53 | unsigned int supported_authentications; |
44 | 54 | ||
55 | static char *client_version_string = NULL; | ||
56 | static char *server_version_string = NULL; | ||
57 | |||
45 | extern Options options; | 58 | extern Options options; |
46 | extern char *__progname; | 59 | extern char *__progname; |
47 | 60 | ||
@@ -957,6 +970,21 @@ try_password_authentication(char *prompt) | |||
957 | return 0; | 970 | return 0; |
958 | } | 971 | } |
959 | 972 | ||
973 | char * | ||
974 | chop(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 | ||
1031 | int ssh_cipher_default = SSH_CIPHER_3DES; | ||
1032 | |||
1033 | int | 1072 | int |
1034 | read_yes_or_no(const char *prompt, int defval) | 1073 | read_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 | */ | ||
1327 | void | ||
1328 | ssh_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 | */ | ||
1521 | void | ||
1522 | ssh_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 | */ |
1288 | void | 1599 | void |
@@ -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 | } |