summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 11:54:57 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 11:54:57 +1100
commit5428f646ad32da88ddd04a8c287d595524674fbf (patch)
treecc1f1e5d7852e1f44d41077f776abf7dab7ac06d /sshconnect.c
parent9072e1889648988da38b7b81bce95291c1dc3a23 (diff)
- More reformatting merged from OpenBSD CVS
- Merged OpenBSD CVS changes: - [channels.c] report from mrwizard@psu.edu via djm@ibs.com.au - [channels.c] set SO_REUSEADDR and SO_LINGER for forwarded ports. chip@valinux.com via damien@ibs.com.au - [nchan.c] it's not an error() if shutdown_write failes in nchan. - [readconf.c] remove dead #ifdef-0-code - [readconf.c servconf.c] strcasecmp instead of tolower - [scp.c] progress meter overflow fix from damien@ibs.com.au - [ssh-add.1 ssh-add.c] SSH_ASKPASS support - [ssh.1 ssh.c] postpone fork_after_authentication until command execution, request/patch from jahakala@cc.jyu.fi via damien@ibs.com.au plus: use daemon() for backgrounding
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c187
1 files changed, 117 insertions, 70 deletions
diff --git a/sshconnect.c b/sshconnect.c
index 0657c37e8..0b1c0901f 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$Id: sshconnect.c,v 1.14 1999/11/24 13:26:23 damien Exp $"); 11RCSID("$Id: sshconnect.c,v 1.15 1999/11/25 00:54:59 damien Exp $");
12 12
13#ifdef HAVE_OPENSSL 13#ifdef HAVE_OPENSSL
14#include <openssl/bn.h> 14#include <openssl/bn.h>
@@ -142,8 +142,10 @@ ssh_create_socket(uid_t original_real_uid, int privileged)
142{ 142{
143 int sock; 143 int sock;
144 144
145 /* If we are running as root and want to connect to a privileged 145 /*
146 port, bind our own socket to a privileged port. */ 146 * If we are running as root and want to connect to a privileged
147 * port, bind our own socket to a privileged port.
148 */
147 if (privileged) { 149 if (privileged) {
148 int p = IPPORT_RESERVED - 1; 150 int p = IPPORT_RESERVED - 1;
149 151
@@ -227,9 +229,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
227 !anonymous && geteuid() == 0 && 229 !anonymous && geteuid() == 0 &&
228 port < IPPORT_RESERVED); 230 port < IPPORT_RESERVED);
229 231
230 /* Connect to the host. We use the user's uid in 232 /*
231 the hope that it will help with the problems of 233 * Connect to the host. We use the user's uid in the
232 tcp_wrappers showing the remote uid as root. */ 234 * hope that it will help with the problems of
235 * tcp_wrappers showing the remote uid as root.
236 */
233 temporarily_use_uid(original_real_uid); 237 temporarily_use_uid(original_real_uid);
234 if (connect(sock, (struct sockaddr *) hostaddr, sizeof(*hostaddr)) 238 if (connect(sock, (struct sockaddr *) hostaddr, sizeof(*hostaddr))
235 >= 0) { 239 >= 0) {
@@ -270,8 +274,12 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
270 !anonymous && geteuid() == 0 && 274 !anonymous && geteuid() == 0 &&
271 port < IPPORT_RESERVED); 275 port < IPPORT_RESERVED);
272 276
273 /* Connect to the host. We use the user's uid in the hope that 277 /*
274 it will help with tcp_wrappers showing the remote uid as root. */ 278 * Connect to the host. We use the user's
279 * uid in the hope that it will help with
280 * tcp_wrappers showing the remote uid as
281 * root.
282 */
275 temporarily_use_uid(original_real_uid); 283 temporarily_use_uid(original_real_uid);
276 if (connect(sock, (struct sockaddr *) hostaddr, 284 if (connect(sock, (struct sockaddr *) hostaddr,
277 sizeof(*hostaddr)) >= 0) { 285 sizeof(*hostaddr)) >= 0) {
@@ -282,8 +290,12 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
282 debug("connect: %.100s", strerror(errno)); 290 debug("connect: %.100s", strerror(errno));
283 restore_uid(); 291 restore_uid();
284 292
285 /* Close the failed socket; there appear to be some problems when 293 /*
286 reusing a socket for which connect() has already returned an error. */ 294 * Close the failed socket; there appear to
295 * be some problems when reusing a socket for
296 * which connect() has already returned an
297 * error.
298 */
287 shutdown(sock, SHUT_RDWR); 299 shutdown(sock, SHUT_RDWR);
288 close(sock); 300 close(sock);
289 } 301 }
@@ -300,10 +312,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
300 312
301 debug("Connection established."); 313 debug("Connection established.");
302 314
303 /* Set socket options. We would like the socket to disappear as 315 /*
304 soon as it has been closed for whatever reason. */ 316 * Set socket options. We would like the socket to disappear as soon
305 /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, 317 * as it has been closed for whatever reason.
306 sizeof(on)); */ 318 */
319 /* setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
307 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on)); 320 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &on, sizeof(on));
308 linger.l_onoff = 1; 321 linger.l_onoff = 1;
309 linger.l_linger = 5; 322 linger.l_linger = 5;
@@ -493,8 +506,10 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
493 /* Wait for server's response. */ 506 /* Wait for server's response. */
494 type = packet_read(&plen); 507 type = packet_read(&plen);
495 508
496 /* The server responds with failure if it doesn\'t like our key or 509 /*
497 doesn\'t support RSA authentication. */ 510 * The server responds with failure if it doesn\'t like our key or
511 * doesn\'t support RSA authentication.
512 */
498 if (type == SSH_SMSG_FAILURE) { 513 if (type == SSH_SMSG_FAILURE) {
499 debug("Server refused our key."); 514 debug("Server refused our key.");
500 xfree(comment); 515 xfree(comment);
@@ -514,8 +529,10 @@ try_rsa_authentication(struct passwd * pw, const char *authfile)
514 debug("Received RSA challenge from server."); 529 debug("Received RSA challenge from server.");
515 530
516 private_key = RSA_new(); 531 private_key = RSA_new();
517 /* Load the private key. Try first with empty passphrase; if it 532 /*
518 fails, ask for a passphrase. */ 533 * Load the private key. Try first with empty passphrase; if it
534 * fails, ask for a passphrase.
535 */
519 if (!load_private_key(authfile, "", private_key, NULL)) { 536 if (!load_private_key(authfile, "", private_key, NULL)) {
520 char buf[300]; 537 char buf[300];
521 snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ", 538 snprintf(buf, sizeof buf, "Enter passphrase for RSA key '%.100s': ",
@@ -720,9 +737,11 @@ try_kerberos_authentication()
720 737
721 packet_integrity_check(plen, 4 + auth.length, type); 738 packet_integrity_check(plen, 4 + auth.length, type);
722 739
723 /* If his response isn't properly encrypted with the 740 /*
724 session key, and the decrypted checksum fails to match, 741 * If his response isn't properly encrypted with the session
725 he's bogus. Bail out. */ 742 * key, and the decrypted checksum fails to match, he's
743 * bogus. Bail out.
744 */
726 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, 745 r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session,
727 &foreign, &local, &msg_data); 746 &foreign, &local, &msg_data);
728 if (r != KSUCCESS) { 747 if (r != KSUCCESS) {
@@ -894,8 +913,10 @@ ssh_exchange_identification()
894 } 913 }
895 buf[sizeof(buf) - 1] = 0; 914 buf[sizeof(buf) - 1] = 0;
896 915
897 /* Check that the versions match. In future this might accept 916 /*
898 several versions and set appropriate flags to handle them. */ 917 * Check that the versions match. In future this might accept
918 * several versions and set appropriate flags to handle them.
919 */
899 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, 920 if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
900 remote_version) != 3) 921 remote_version) != 3)
901 fatal("Bad remote protocol version identification: '%.100s'", buf); 922 fatal("Bad remote protocol version identification: '%.100s'", buf);
@@ -916,9 +937,11 @@ ssh_exchange_identification()
916 } 937 }
917 } 938 }
918#if 0 939#if 0
919 /* Removed for now, to permit compatibility with latter versions. 940 /*
920 The server will reject our version and disconnect if it doesn't 941 * Removed for now, to permit compatibility with latter versions. The
921 support it. */ 942 * server will reject our version and disconnect if it doesn't
943 * support it.
944 */
922 if (remote_major != PROTOCOL_MAJOR) 945 if (remote_major != PROTOCOL_MAJOR)
923 fatal("Protocol major versions differ: %d vs. %d", 946 fatal("Protocol major versions differ: %d vs. %d",
924 PROTOCOL_MAJOR, remote_major); 947 PROTOCOL_MAJOR, remote_major);
@@ -1086,10 +1109,7 @@ ssh_login(int host_key_valid,
1086 protocol_flags = packet_get_int(); 1109 protocol_flags = packet_get_int();
1087 packet_set_protocol_flags(protocol_flags); 1110 packet_set_protocol_flags(protocol_flags);
1088 1111
1089 /* Get supported cipher types. */
1090 supported_ciphers = packet_get_int(); 1112 supported_ciphers = packet_get_int();
1091
1092 /* Get supported authentication types. */
1093 supported_authentications = packet_get_int(); 1113 supported_authentications = packet_get_int();
1094 1114
1095 debug("Received server public key (%d bits) and host key (%d bits).", 1115 debug("Received server public key (%d bits) and host key (%d bits).",
@@ -1099,11 +1119,12 @@ ssh_login(int host_key_valid,
1099 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 1119 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1100 SSH_SMSG_PUBLIC_KEY); 1120 SSH_SMSG_PUBLIC_KEY);
1101 1121
1102 /* Compute the session id. */
1103 compute_session_id(session_id, check_bytes, host_key->n, public_key->n); 1122 compute_session_id(session_id, check_bytes, host_key->n, public_key->n);
1104 1123
1105 /* Check if the host key is present in the user\'s list of known 1124 /*
1106 hosts or in the systemwide list. */ 1125 * Check if the host key is present in the user\'s list of known
1126 * hosts or in the systemwide list.
1127 */
1107 host_status = check_host_in_hostfile(options.user_hostfile, host, 1128 host_status = check_host_in_hostfile(options.user_hostfile, host,
1108 host_key->e, host_key->n, 1129 host_key->e, host_key->n,
1109 file_key->e, file_key->n); 1130 file_key->e, file_key->n);
@@ -1111,18 +1132,22 @@ ssh_login(int host_key_valid,
1111 host_status = check_host_in_hostfile(options.system_hostfile, host, 1132 host_status = check_host_in_hostfile(options.system_hostfile, host,
1112 host_key->e, host_key->n, 1133 host_key->e, host_key->n,
1113 file_key->e, file_key->n); 1134 file_key->e, file_key->n);
1114 /* Force accepting of the host key for localhost and 127.0.0.1. 1135 /*
1115 The problem is that if the home directory is NFS-mounted to 1136 * Force accepting of the host key for localhost and 127.0.0.1. The
1116 multiple machines, localhost will refer to a different machine 1137 * problem is that if the home directory is NFS-mounted to multiple
1117 in each of them, and the user will get bogus HOST_CHANGED 1138 * machines, localhost will refer to a different machine in each of
1118 warnings. This essentially disables host authentication for 1139 * them, and the user will get bogus HOST_CHANGED warnings. This
1119 localhost; however, this is probably not a real problem. */ 1140 * essentially disables host authentication for localhost; however,
1141 * this is probably not a real problem.
1142 */
1120 if (local) { 1143 if (local) {
1121 debug("Forcing accepting of host key for localhost."); 1144 debug("Forcing accepting of host key for localhost.");
1122 host_status = HOST_OK; 1145 host_status = HOST_OK;
1123 } 1146 }
1124 /* Also perform check for the ip address, skip the check if we are 1147 /*
1125 localhost or the hostname was an ip address to begin with */ 1148 * Also perform check for the ip address, skip the check if we are
1149 * localhost or the hostname was an ip address to begin with
1150 */
1126 if (options.check_host_ip && !local && strcmp(host, ip)) { 1151 if (options.check_host_ip && !local && strcmp(host, ip)) {
1127 RSA *ip_key = RSA_new(); 1152 RSA *ip_key = RSA_new();
1128 ip_key->n = BN_new(); 1153 ip_key->n = BN_new();
@@ -1226,13 +1251,18 @@ ssh_login(int host_key_valid,
1226 error("Add correct host key in %.100s to get rid of this message.", 1251 error("Add correct host key in %.100s to get rid of this message.",
1227 options.user_hostfile); 1252 options.user_hostfile);
1228 1253
1229 /* If strict host key checking is in use, the user will 1254 /*
1230 have to edit the key manually and we can only abort. */ 1255 * If strict host key checking is in use, the user will have
1256 * to edit the key manually and we can only abort.
1257 */
1231 if (options.strict_host_key_checking) 1258 if (options.strict_host_key_checking)
1232 fatal("Host key for %.200s has changed and you have requested strict checking.", host); 1259 fatal("Host key for %.200s has changed and you have requested strict checking.", host);
1233 1260
1234 /* If strict host key checking has not been requested, allow the connection 1261 /*
1235 but without password authentication or agent forwarding. */ 1262 * If strict host key checking has not been requested, allow
1263 * the connection but without password authentication or
1264 * agent forwarding.
1265 */
1236 if (options.password_authentication) { 1266 if (options.password_authentication) {
1237 error("Password authentication is disabled to avoid trojan horses."); 1267 error("Password authentication is disabled to avoid trojan horses.");
1238 options.password_authentication = 0; 1268 options.password_authentication = 0;
@@ -1241,11 +1271,13 @@ ssh_login(int host_key_valid,
1241 error("Agent forwarding is disabled to avoid trojan horses."); 1271 error("Agent forwarding is disabled to avoid trojan horses.");
1242 options.forward_agent = 0; 1272 options.forward_agent = 0;
1243 } 1273 }
1244 /* XXX Should permit the user to change to use the new id. 1274 /*
1245 This could be done by converting the host key to an 1275 * XXX Should permit the user to change to use the new id.
1246 identifying sentence, tell that the host identifies 1276 * This could be done by converting the host key to an
1247 itself by that sentence, and ask the user if he/she 1277 * identifying sentence, tell that the host identifies itself
1248 whishes to accept the authentication. */ 1278 * by that sentence, and ask the user if he/she whishes to
1279 * accept the authentication.
1280 */
1249 break; 1281 break;
1250 } 1282 }
1251 1283
@@ -1255,9 +1287,11 @@ ssh_login(int host_key_valid,
1255 /* Generate a session key. */ 1287 /* Generate a session key. */
1256 arc4random_stir(); 1288 arc4random_stir();
1257 1289
1258 /* Generate an encryption key for the session. The key is a 256 1290 /*
1259 bit random number, interpreted as a 32-byte key, with the least 1291 * Generate an encryption key for the session. The key is a 256 bit
1260 significant 8 bits being the first byte of the key. */ 1292 * random number, interpreted as a 32-byte key, with the least
1293 * significant 8 bits being the first byte of the key.
1294 */
1261 for (i = 0; i < 32; i++) { 1295 for (i = 0; i < 32; i++) {
1262 if (i % 4 == 0) 1296 if (i % 4 == 0)
1263 rand = arc4random(); 1297 rand = arc4random();
@@ -1265,9 +1299,11 @@ ssh_login(int host_key_valid,
1265 rand >>= 8; 1299 rand >>= 8;
1266 } 1300 }
1267 1301
1268 /* According to the protocol spec, the first byte of the session 1302 /*
1269 key is the highest byte of the integer. The session key is 1303 * According to the protocol spec, the first byte of the session key
1270 xored with the first 16 bytes of the session id. */ 1304 * is the highest byte of the integer. The session key is xored with
1305 * the first 16 bytes of the session id.
1306 */
1271 key = BN_new(); 1307 key = BN_new();
1272 BN_set_word(key, 0); 1308 BN_set_word(key, 0);
1273 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { 1309 for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
@@ -1278,8 +1314,10 @@ ssh_login(int host_key_valid,
1278 BN_add_word(key, session_key[i]); 1314 BN_add_word(key, session_key[i]);
1279 } 1315 }
1280 1316
1281 /* Encrypt the integer using the public key and host key of the 1317 /*
1282 server (key with smaller modulus first). */ 1318 * Encrypt the integer using the public key and host key of the
1319 * server (key with smaller modulus first).
1320 */
1283 if (BN_cmp(public_key->n, host_key->n) < 0) { 1321 if (BN_cmp(public_key->n, host_key->n) < 0) {
1284 /* Public key has smaller modulus. */ 1322 /* Public key has smaller modulus. */
1285 if (BN_num_bits(host_key->n) < 1323 if (BN_num_bits(host_key->n) <
@@ -1354,8 +1392,10 @@ ssh_login(int host_key_valid,
1354 /* We will no longer need the session key here. Destroy any extra copies. */ 1392 /* We will no longer need the session key here. Destroy any extra copies. */
1355 memset(session_key, 0, sizeof(session_key)); 1393 memset(session_key, 0, sizeof(session_key));
1356 1394
1357 /* Expect a success message from the server. Note that this 1395 /*
1358 message will be received in encrypted form. */ 1396 * Expect a success message from the server. Note that this message
1397 * will be received in encrypted form.
1398 */
1359 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); 1399 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
1360 1400
1361 debug("Received encrypted confirmation."); 1401 debug("Received encrypted confirmation.");
@@ -1366,9 +1406,11 @@ ssh_login(int host_key_valid,
1366 packet_send(); 1406 packet_send();
1367 packet_write_wait(); 1407 packet_write_wait();
1368 1408
1369 /* The server should respond with success if no authentication is 1409 /*
1370 needed (the user has no password). Otherwise the server 1410 * The server should respond with success if no authentication is
1371 responds with failure. */ 1411 * needed (the user has no password). Otherwise the server responds
1412 * with failure.
1413 */
1372 type = packet_read(&payload_len); 1414 type = packet_read(&payload_len);
1373 1415
1374 /* check whether the connection was accepted without authentication. */ 1416 /* check whether the connection was accepted without authentication. */
@@ -1410,8 +1452,10 @@ ssh_login(int host_key_valid,
1410 } 1452 }
1411#endif /* KRB4 */ 1453#endif /* KRB4 */
1412 1454
1413 /* Use rhosts authentication if running in privileged socket and 1455 /*
1414 we do not wish to remain anonymous. */ 1456 * Use rhosts authentication if running in privileged socket and we
1457 * do not wish to remain anonymous.
1458 */
1415 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && 1459 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) &&
1416 options.rhosts_authentication) { 1460 options.rhosts_authentication) {
1417 debug("Trying rhosts authentication."); 1461 debug("Trying rhosts authentication.");
@@ -1428,8 +1472,10 @@ ssh_login(int host_key_valid,
1428 packet_disconnect("Protocol error: got %d in response to rhosts auth", 1472 packet_disconnect("Protocol error: got %d in response to rhosts auth",
1429 type); 1473 type);
1430 } 1474 }
1431 /* Try .rhosts or /etc/hosts.equiv authentication with RSA host 1475 /*
1432 authentication. */ 1476 * Try .rhosts or /etc/hosts.equiv authentication with RSA host
1477 * authentication.
1478 */
1433 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && 1479 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1434 options.rhosts_rsa_authentication && host_key_valid) { 1480 options.rhosts_rsa_authentication && host_key_valid) {
1435 if (try_rhosts_rsa_authentication(local_user, own_host_key)) 1481 if (try_rhosts_rsa_authentication(local_user, own_host_key))
@@ -1438,10 +1484,11 @@ ssh_login(int host_key_valid,
1438 /* Try RSA authentication if the server supports it. */ 1484 /* Try RSA authentication if the server supports it. */
1439 if ((supported_authentications & (1 << SSH_AUTH_RSA)) && 1485 if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
1440 options.rsa_authentication) { 1486 options.rsa_authentication) {
1441 /* Try RSA authentication using the authentication agent. 1487 /*
1442 The agent is tried first because no passphrase is 1488 * Try RSA authentication using the authentication agent. The
1443 needed for it, whereas identity files may require 1489 * agent is tried first because no passphrase is needed for
1444 passphrases. */ 1490 * it, whereas identity files may require passphrases.
1491 */
1445 if (try_agent_authentication()) 1492 if (try_agent_authentication())
1446 return; 1493 return;
1447 1494