diff options
Diffstat (limited to 'sshconnect.c')
-rw-r--r-- | sshconnect.c | 128 |
1 files changed, 76 insertions, 52 deletions
diff --git a/sshconnect.c b/sshconnect.c index 068c23072..5e2a34497 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "includes.h" | 10 | #include "includes.h" |
11 | RCSID("$Id: sshconnect.c,v 1.22 2000/01/19 02:45:07 damien Exp $"); | 11 | RCSID("$OpenBSD: sshconnect.c,v 1.53 2000/01/18 09:42:17 markus Exp $"); |
12 | 12 | ||
13 | #ifdef HAVE_OPENSSL | 13 | #ifdef HAVE_OPENSSL |
14 | #include <openssl/bn.h> | 14 | #include <openssl/bn.h> |
@@ -34,6 +34,9 @@ RCSID("$Id: sshconnect.c,v 1.22 2000/01/19 02:45:07 damien Exp $"); | |||
34 | /* Session id for the current session. */ | 34 | /* Session id for the current session. */ |
35 | unsigned char session_id[16]; | 35 | unsigned char session_id[16]; |
36 | 36 | ||
37 | /* authentications supported by server */ | ||
38 | unsigned int supported_authentications; | ||
39 | |||
37 | extern Options options; | 40 | extern Options options; |
38 | extern char *__progname; | 41 | extern char *__progname; |
39 | 42 | ||
@@ -988,9 +991,8 @@ ssh_exchange_identification() | |||
988 | /* We speak 1.3, too. */ | 991 | /* We speak 1.3, too. */ |
989 | if (remote_major == 1 && remote_minor == 3) { | 992 | if (remote_major == 1 && remote_minor == 3) { |
990 | enable_compat13(); | 993 | enable_compat13(); |
991 | if (options.forward_agent && strcmp(remote_version, "OpenSSH-1.1") != 0) { | 994 | if (options.forward_agent) { |
992 | log("Agent forwarding disabled, remote version '%s' is not compatible.", | 995 | log("Agent forwarding disabled for protocol 1.3"); |
993 | remote_version); | ||
994 | options.forward_agent = 0; | 996 | options.forward_agent = 0; |
995 | } | 997 | } |
996 | } | 998 | } |
@@ -1274,63 +1276,31 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) | |||
1274 | } | 1276 | } |
1275 | 1277 | ||
1276 | /* | 1278 | /* |
1277 | * Starts a dialog with the server, and authenticates the current user on the | 1279 | * SSH1 key exchange |
1278 | * server. This does not need any extra privileges. The basic connection | ||
1279 | * to the server must already have been established before this is called. | ||
1280 | * User is the remote user; if it is NULL, the current local user name will | ||
1281 | * be used. Anonymous indicates that no rhosts authentication will be used. | ||
1282 | * If login fails, this function prints an error and never returns. | ||
1283 | * This function does not require super-user privileges. | ||
1284 | */ | 1280 | */ |
1285 | void | 1281 | void |
1286 | ssh_login(int host_key_valid, | 1282 | ssh_kex(char *host, struct sockaddr *hostaddr) |
1287 | RSA *own_host_key, | ||
1288 | const char *orighost, | ||
1289 | struct sockaddr *hostaddr, | ||
1290 | uid_t original_real_uid) | ||
1291 | { | 1283 | { |
1292 | int i, type; | 1284 | int i; |
1293 | struct passwd *pw; | ||
1294 | BIGNUM *key; | 1285 | BIGNUM *key; |
1295 | RSA *host_key; | 1286 | RSA *host_key; |
1296 | RSA *public_key; | 1287 | RSA *public_key; |
1297 | int bits, rbits; | 1288 | int bits, rbits; |
1298 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; | 1289 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
1299 | const char *server_user, *local_user; | 1290 | unsigned char cookie[8]; |
1300 | char *host, *cp; | 1291 | unsigned int supported_ciphers; |
1301 | unsigned char check_bytes[8]; | ||
1302 | unsigned int supported_ciphers, supported_authentications; | ||
1303 | unsigned int server_flags, client_flags; | 1292 | unsigned int server_flags, client_flags; |
1304 | int payload_len, clen, sum_len = 0; | 1293 | int payload_len, clen, sum_len = 0; |
1305 | u_int32_t rand = 0; | 1294 | u_int32_t rand = 0; |
1306 | 1295 | ||
1307 | /* Convert the user-supplied hostname into all lowercase. */ | ||
1308 | host = xstrdup(orighost); | ||
1309 | for (cp = host; *cp; cp++) | ||
1310 | if (isupper(*cp)) | ||
1311 | *cp = tolower(*cp); | ||
1312 | |||
1313 | /* Exchange protocol version identification strings with the server. */ | ||
1314 | ssh_exchange_identification(); | ||
1315 | |||
1316 | /* Put the connection into non-blocking mode. */ | ||
1317 | packet_set_nonblocking(); | ||
1318 | |||
1319 | /* Get local user name. Use it as server user if no user name was given. */ | ||
1320 | pw = getpwuid(original_real_uid); | ||
1321 | if (!pw) | ||
1322 | fatal("User id %d not found from user database.", original_real_uid); | ||
1323 | local_user = xstrdup(pw->pw_name); | ||
1324 | server_user = options.user ? options.user : local_user; | ||
1325 | |||
1326 | debug("Waiting for server public key."); | 1296 | debug("Waiting for server public key."); |
1327 | 1297 | ||
1328 | /* Wait for a public key packet from the server. */ | 1298 | /* Wait for a public key packet from the server. */ |
1329 | packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); | 1299 | packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY); |
1330 | 1300 | ||
1331 | /* Get check bytes from the packet. */ | 1301 | /* Get cookie from the packet. */ |
1332 | for (i = 0; i < 8; i++) | 1302 | for (i = 0; i < 8; i++) |
1333 | check_bytes[i] = packet_get_char(); | 1303 | cookie[i] = packet_get_char(); |
1334 | 1304 | ||
1335 | /* Get the public key. */ | 1305 | /* Get the public key. */ |
1336 | public_key = RSA_new(); | 1306 | public_key = RSA_new(); |
@@ -1383,7 +1353,7 @@ ssh_login(int host_key_valid, | |||
1383 | 1353 | ||
1384 | client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; | 1354 | client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; |
1385 | 1355 | ||
1386 | compute_session_id(session_id, check_bytes, host_key->n, public_key->n); | 1356 | compute_session_id(session_id, cookie, host_key->n, public_key->n); |
1387 | 1357 | ||
1388 | /* Generate a session key. */ | 1358 | /* Generate a session key. */ |
1389 | arc4random_stir(); | 1359 | arc4random_stir(); |
@@ -1445,6 +1415,10 @@ ssh_login(int host_key_valid, | |||
1445 | rsa_public_encrypt(key, key, public_key); | 1415 | rsa_public_encrypt(key, key, public_key); |
1446 | } | 1416 | } |
1447 | 1417 | ||
1418 | /* Destroy the public keys since we no longer need them. */ | ||
1419 | RSA_free(public_key); | ||
1420 | RSA_free(host_key); | ||
1421 | |||
1448 | if (options.cipher == SSH_CIPHER_NOT_SET) { | 1422 | if (options.cipher == SSH_CIPHER_NOT_SET) { |
1449 | if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default)) | 1423 | if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default)) |
1450 | options.cipher = ssh_cipher_default; | 1424 | options.cipher = ssh_cipher_default; |
@@ -1466,12 +1440,13 @@ ssh_login(int host_key_valid, | |||
1466 | packet_start(SSH_CMSG_SESSION_KEY); | 1440 | packet_start(SSH_CMSG_SESSION_KEY); |
1467 | packet_put_char(options.cipher); | 1441 | packet_put_char(options.cipher); |
1468 | 1442 | ||
1469 | /* Send the check bytes back to the server. */ | 1443 | /* Send the cookie back to the server. */ |
1470 | for (i = 0; i < 8; i++) | 1444 | for (i = 0; i < 8; i++) |
1471 | packet_put_char(check_bytes[i]); | 1445 | packet_put_char(cookie[i]); |
1472 | 1446 | ||
1473 | /* Send the encrypted encryption key. */ | 1447 | /* Send and destroy the encrypted encryption key integer. */ |
1474 | packet_put_bignum(key); | 1448 | packet_put_bignum(key); |
1449 | BN_clear_free(key); | ||
1475 | 1450 | ||
1476 | /* Send protocol flags. */ | 1451 | /* Send protocol flags. */ |
1477 | packet_put_int(client_flags); | 1452 | packet_put_int(client_flags); |
@@ -1480,11 +1455,6 @@ ssh_login(int host_key_valid, | |||
1480 | packet_send(); | 1455 | packet_send(); |
1481 | packet_write_wait(); | 1456 | packet_write_wait(); |
1482 | 1457 | ||
1483 | /* Destroy the session key integer and the public keys since we no longer need them. */ | ||
1484 | BN_clear_free(key); | ||
1485 | RSA_free(public_key); | ||
1486 | RSA_free(host_key); | ||
1487 | |||
1488 | debug("Sent encrypted session key."); | 1458 | debug("Sent encrypted session key."); |
1489 | 1459 | ||
1490 | /* Set the encryption key. */ | 1460 | /* Set the encryption key. */ |
@@ -1500,6 +1470,26 @@ ssh_login(int host_key_valid, | |||
1500 | packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); | 1470 | packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); |
1501 | 1471 | ||
1502 | debug("Received encrypted confirmation."); | 1472 | debug("Received encrypted confirmation."); |
1473 | } | ||
1474 | |||
1475 | /* | ||
1476 | * Authenticate user | ||
1477 | */ | ||
1478 | void | ||
1479 | ssh_userauth(int host_key_valid, RSA *own_host_key, | ||
1480 | uid_t original_real_uid, char *host) | ||
1481 | { | ||
1482 | int i, type; | ||
1483 | int payload_len; | ||
1484 | struct passwd *pw; | ||
1485 | const char *server_user, *local_user; | ||
1486 | |||
1487 | /* Get local user name. Use it as server user if no user name was given. */ | ||
1488 | pw = getpwuid(original_real_uid); | ||
1489 | if (!pw) | ||
1490 | fatal("User id %d not found from user database.", original_real_uid); | ||
1491 | local_user = xstrdup(pw->pw_name); | ||
1492 | server_user = options.user ? options.user : local_user; | ||
1503 | 1493 | ||
1504 | /* Send the name of the user to log in as on the server. */ | 1494 | /* Send the name of the user to log in as on the server. */ |
1505 | packet_start(SSH_CMSG_USER); | 1495 | packet_start(SSH_CMSG_USER); |
@@ -1618,3 +1608,37 @@ ssh_login(int host_key_valid, | |||
1618 | fatal("Permission denied."); | 1608 | fatal("Permission denied."); |
1619 | /* NOTREACHED */ | 1609 | /* NOTREACHED */ |
1620 | } | 1610 | } |
1611 | |||
1612 | /* | ||
1613 | * Starts a dialog with the server, and authenticates the current user on the | ||
1614 | * server. This does not need any extra privileges. The basic connection | ||
1615 | * to the server must already have been established before this is called. | ||
1616 | * If login fails, this function prints an error and never returns. | ||
1617 | * This function does not require super-user privileges. | ||
1618 | */ | ||
1619 | void | ||
1620 | ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, | ||
1621 | struct sockaddr *hostaddr, uid_t original_real_uid) | ||
1622 | { | ||
1623 | char *host, *cp; | ||
1624 | |||
1625 | /* Convert the user-supplied hostname into all lowercase. */ | ||
1626 | host = xstrdup(orighost); | ||
1627 | for (cp = host; *cp; cp++) | ||
1628 | if (isupper(*cp)) | ||
1629 | *cp = tolower(*cp); | ||
1630 | |||
1631 | /* Exchange protocol version identification strings with the server. */ | ||
1632 | ssh_exchange_identification(); | ||
1633 | |||
1634 | /* Put the connection into non-blocking mode. */ | ||
1635 | packet_set_nonblocking(); | ||
1636 | |||
1637 | supported_authentications = 0; | ||
1638 | /* key exchange */ | ||
1639 | ssh_kex(host, hostaddr); | ||
1640 | if (supported_authentications == 0) | ||
1641 | fatal("supported_authentications == 0."); | ||
1642 | /* authenticate user */ | ||
1643 | ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); | ||
1644 | } | ||