summaryrefslogtreecommitdiff
path: root/sshconnect.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-12-14 10:47:15 +1100
committerDamien Miller <djm@mindrot.org>1999-12-14 10:47:15 +1100
commita34a28bf86c04eb35c522b1e31c32e94edf355d2 (patch)
treeb048bcbc954cae87930fe287a92197abccceb1de /sshconnect.c
parentc6b3bbe2b991f4f87ca1f8214f43c13a5a73f385 (diff)
- OpenBSD CVS Changes
- [canohost.c] fix get_remote_port() and friends for sshd -i; Holger.Trapp@Informatik.TU-Chemnitz.DE - [mpaux.c] make code simpler. no need for memcpy. niels@ ok - [pty.c] namebuflen not sizeof namebuflen; bnd@ep-ag.com via djm@mindrot.org fix proto; markus - [ssh.1] typo; mark.baushke@solipsa.com - [channels.c ssh.c ssh.h sshd.c] type conflict for 'extern Type *options' in channels.c; dot@dotat.at - [sshconnect.c] move checking of hostkey into own function. - [version.h] OpenSSH-1.2.1
Diffstat (limited to 'sshconnect.c')
-rw-r--r--sshconnect.c246
1 files changed, 135 insertions, 111 deletions
diff --git a/sshconnect.c b/sshconnect.c
index e6175f11b..d96f8e026 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.17 1999/12/07 04:38:32 damien Exp $"); 11RCSID("$Id: sshconnect.c,v 1.18 1999/12/13 23:47:16 damien Exp $");
12 12
13#ifdef HAVE_OPENSSL 13#ifdef HAVE_OPENSSL
14#include <openssl/bn.h> 14#include <openssl/bn.h>
@@ -156,8 +156,10 @@ ssh_create_socket(uid_t original_real_uid, int privileged)
156 fatal("rresvport: %.100s", strerror(errno)); 156 fatal("rresvport: %.100s", strerror(errno));
157 debug("Allocated local port %d.", p); 157 debug("Allocated local port %d.", p);
158 } else { 158 } else {
159 /* Just create an ordinary socket on arbitrary port. We 159 /*
160 use the user's uid to create the socket. */ 160 * Just create an ordinary socket on arbitrary port. We use
161 * the user's uid to create the socket.
162 */
161 temporarily_use_uid(original_real_uid); 163 temporarily_use_uid(original_real_uid);
162 sock = socket(AF_INET, SOCK_STREAM, 0); 164 sock = socket(AF_INET, SOCK_STREAM, 0);
163 if (sock < 0) 165 if (sock < 0)
@@ -209,9 +211,11 @@ ssh_connect(const char *host, struct sockaddr_in * hostaddr,
209 /* No host lookup made yet. */ 211 /* No host lookup made yet. */
210 hp = NULL; 212 hp = NULL;
211 213
212 /* Try to connect several times. On some machines, the first time 214 /*
213 will sometimes fail. In general socket code appears to behave 215 * Try to connect several times. On some machines, the first time
214 quite magically on many machines. */ 216 * will sometimes fail. In general socket code appears to behave
217 * quite magically on many machines.
218 */
215 for (attempt = 0; attempt < connection_attempts; attempt++) { 219 for (attempt = 0; attempt < connection_attempts; attempt++) {
216 if (attempt > 0) 220 if (attempt > 0)
217 debug("Trying again..."); 221 debug("Trying again...");
@@ -1087,39 +1091,21 @@ read_yes_or_no(const char *prompt, int defval)
1087} 1091}
1088 1092
1089/* 1093/*
1090 * Starts a dialog with the server, and authenticates the current user on the 1094 * check whether the supplied host key is valid, return only if ok.
1091 * server. This does not need any extra privileges. The basic connection
1092 * to the server must already have been established before this is called.
1093 * User is the remote user; if it is NULL, the current local user name will
1094 * be used. Anonymous indicates that no rhosts authentication will be used.
1095 * If login fails, this function prints an error and never returns.
1096 * This function does not require super-user privileges.
1097 */ 1095 */
1096
1098void 1097void
1099ssh_login(int host_key_valid, 1098check_host_key(char *host,
1100 RSA *own_host_key, 1099 struct sockaddr_in *hostaddr,
1101 const char *orighost, 1100 RSA *host_key)
1102 struct sockaddr_in *hostaddr,
1103 uid_t original_real_uid)
1104{ 1101{
1105 int i, type; 1102 RSA *file_key;
1106 struct passwd *pw; 1103 char *ip = NULL;
1107 BIGNUM *key;
1108 RSA *host_key, *file_key;
1109 RSA *public_key;
1110 int bits, rbits;
1111 unsigned char session_key[SSH_SESSION_KEY_LENGTH];
1112 const char *server_user, *local_user;
1113 char *cp, *host, *ip = NULL;
1114 char hostline[1000], *hostp; 1104 char hostline[1000], *hostp;
1115 unsigned char check_bytes[8];
1116 unsigned int supported_ciphers, supported_authentications, protocol_flags;
1117 HostStatus host_status; 1105 HostStatus host_status;
1118 HostStatus ip_status; 1106 HostStatus ip_status;
1119 int host_ip_differ = 0; 1107 int host_ip_differ = 0;
1120 int local = (ntohl(hostaddr->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; 1108 int local = (ntohl(hostaddr->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
1121 int payload_len, clen, sum_len = 0;
1122 u_int32_t rand = 0;
1123 1109
1124 /* 1110 /*
1125 * Turn off check_host_ip for proxy connects, since 1111 * Turn off check_host_ip for proxy connects, since
@@ -1131,88 +1117,14 @@ ssh_login(int host_key_valid,
1131 if (options.check_host_ip) 1117 if (options.check_host_ip)
1132 ip = xstrdup(inet_ntoa(hostaddr->sin_addr)); 1118 ip = xstrdup(inet_ntoa(hostaddr->sin_addr));
1133 1119
1134 /* Convert the user-supplied hostname into all lowercase. */ 1120 /*
1135 host = xstrdup(orighost); 1121 * Store the host key from the known host file in here so that we can
1136 for (cp = host; *cp; cp++) 1122 * compare it with the key for the IP address.
1137 if (isupper(*cp)) 1123 */
1138 *cp = tolower(*cp);
1139
1140 /* Exchange protocol version identification strings with the server. */
1141 ssh_exchange_identification();
1142
1143 /* Put the connection into non-blocking mode. */
1144 packet_set_nonblocking();
1145
1146 /* Get local user name. Use it as server user if no user name was given. */
1147 pw = getpwuid(original_real_uid);
1148 if (!pw)
1149 fatal("User id %d not found from user database.", original_real_uid);
1150 local_user = xstrdup(pw->pw_name);
1151 server_user = options.user ? options.user : local_user;
1152
1153 debug("Waiting for server public key.");
1154
1155 /* Wait for a public key packet from the server. */
1156 packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
1157
1158 /* Get check bytes from the packet. */
1159 for (i = 0; i < 8; i++)
1160 check_bytes[i] = packet_get_char();
1161
1162 /* Get the public key. */
1163 public_key = RSA_new();
1164 bits = packet_get_int();/* bits */
1165 public_key->e = BN_new();
1166 packet_get_bignum(public_key->e, &clen);
1167 sum_len += clen;
1168 public_key->n = BN_new();
1169 packet_get_bignum(public_key->n, &clen);
1170 sum_len += clen;
1171
1172 rbits = BN_num_bits(public_key->n);
1173 if (bits != rbits) {
1174 log("Warning: Server lies about size of server public key: "
1175 "actual size is %d bits vs. announced %d.", rbits, bits);
1176 log("Warning: This may be due to an old implementation of ssh.");
1177 }
1178 /* Get the host key. */
1179 host_key = RSA_new();
1180 bits = packet_get_int();/* bits */
1181 host_key->e = BN_new();
1182 packet_get_bignum(host_key->e, &clen);
1183 sum_len += clen;
1184 host_key->n = BN_new();
1185 packet_get_bignum(host_key->n, &clen);
1186 sum_len += clen;
1187
1188 rbits = BN_num_bits(host_key->n);
1189 if (bits != rbits) {
1190 log("Warning: Server lies about size of server host key: "
1191 "actual size is %d bits vs. announced %d.", rbits, bits);
1192 log("Warning: This may be due to an old implementation of ssh.");
1193 }
1194 /* Store the host key from the known host file in here so that we
1195 can compare it with the key for the IP address. */
1196 file_key = RSA_new(); 1124 file_key = RSA_new();
1197 file_key->n = BN_new(); 1125 file_key->n = BN_new();
1198 file_key->e = BN_new(); 1126 file_key->e = BN_new();
1199 1127
1200 /* Get protocol flags. */
1201 protocol_flags = packet_get_int();
1202 packet_set_protocol_flags(protocol_flags);
1203
1204 supported_ciphers = packet_get_int();
1205 supported_authentications = packet_get_int();
1206
1207 debug("Received server public key (%d bits) and host key (%d bits).",
1208 BN_num_bits(public_key->n), BN_num_bits(host_key->n));
1209
1210 packet_integrity_check(payload_len,
1211 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1212 SSH_SMSG_PUBLIC_KEY);
1213
1214 compute_session_id(session_id, check_bytes, host_key->n, public_key->n);
1215
1216 /* 1128 /*
1217 * Check if the host key is present in the user\'s list of known 1129 * Check if the host key is present in the user\'s list of known
1218 * hosts or in the systemwide list. 1130 * hosts or in the systemwide list.
@@ -1372,9 +1284,121 @@ ssh_login(int host_key_valid,
1372 */ 1284 */
1373 break; 1285 break;
1374 } 1286 }
1375
1376 if (options.check_host_ip) 1287 if (options.check_host_ip)
1377 xfree(ip); 1288 xfree(ip);
1289}
1290
1291/*
1292 * Starts a dialog with the server, and authenticates the current user on the
1293 * server. This does not need any extra privileges. The basic connection
1294 * to the server must already have been established before this is called.
1295 * User is the remote user; if it is NULL, the current local user name will
1296 * be used. Anonymous indicates that no rhosts authentication will be used.
1297 * If login fails, this function prints an error and never returns.
1298 * This function does not require super-user privileges.
1299 */
1300void
1301ssh_login(int host_key_valid,
1302 RSA *own_host_key,
1303 const char *orighost,
1304 struct sockaddr_in *hostaddr,
1305 uid_t original_real_uid)
1306{
1307 int i, type;
1308 struct passwd *pw;
1309 BIGNUM *key;
1310 RSA *host_key;
1311 RSA *public_key;
1312 int bits, rbits;
1313 unsigned char session_key[SSH_SESSION_KEY_LENGTH];
1314 const char *server_user, *local_user;
1315 char *host, *cp;
1316 unsigned char check_bytes[8];
1317 unsigned int supported_ciphers, supported_authentications;
1318 unsigned int server_flags, client_flags;
1319 int payload_len, clen, sum_len = 0;
1320 u_int32_t rand = 0;
1321
1322 /* Convert the user-supplied hostname into all lowercase. */
1323 host = xstrdup(orighost);
1324 for (cp = host; *cp; cp++)
1325 if (isupper(*cp))
1326 *cp = tolower(*cp);
1327
1328 /* Exchange protocol version identification strings with the server. */
1329 ssh_exchange_identification();
1330
1331 /* Put the connection into non-blocking mode. */
1332 packet_set_nonblocking();
1333
1334 /* Get local user name. Use it as server user if no user name was given. */
1335 pw = getpwuid(original_real_uid);
1336 if (!pw)
1337 fatal("User id %d not found from user database.", original_real_uid);
1338 local_user = xstrdup(pw->pw_name);
1339 server_user = options.user ? options.user : local_user;
1340
1341 debug("Waiting for server public key.");
1342
1343 /* Wait for a public key packet from the server. */
1344 packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
1345
1346 /* Get check bytes from the packet. */
1347 for (i = 0; i < 8; i++)
1348 check_bytes[i] = packet_get_char();
1349
1350 /* Get the public key. */
1351 public_key = RSA_new();
1352 bits = packet_get_int();/* bits */
1353 public_key->e = BN_new();
1354 packet_get_bignum(public_key->e, &clen);
1355 sum_len += clen;
1356 public_key->n = BN_new();
1357 packet_get_bignum(public_key->n, &clen);
1358 sum_len += clen;
1359
1360 rbits = BN_num_bits(public_key->n);
1361 if (bits != rbits) {
1362 log("Warning: Server lies about size of server public key: "
1363 "actual size is %d bits vs. announced %d.", rbits, bits);
1364 log("Warning: This may be due to an old implementation of ssh.");
1365 }
1366 /* Get the host key. */
1367 host_key = RSA_new();
1368 bits = packet_get_int();/* bits */
1369 host_key->e = BN_new();
1370 packet_get_bignum(host_key->e, &clen);
1371 sum_len += clen;
1372 host_key->n = BN_new();
1373 packet_get_bignum(host_key->n, &clen);
1374 sum_len += clen;
1375
1376 rbits = BN_num_bits(host_key->n);
1377 if (bits != rbits) {
1378 log("Warning: Server lies about size of server host key: "
1379 "actual size is %d bits vs. announced %d.", rbits, bits);
1380 log("Warning: This may be due to an old implementation of ssh.");
1381 }
1382
1383 /* Get protocol flags. */
1384 server_flags = packet_get_int();
1385 packet_set_protocol_flags(server_flags);
1386
1387 supported_ciphers = packet_get_int();
1388 supported_authentications = packet_get_int();
1389
1390 debug("Received server public key (%d bits) and host key (%d bits).",
1391 BN_num_bits(public_key->n), BN_num_bits(host_key->n));
1392
1393 packet_integrity_check(payload_len,
1394 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
1395 SSH_SMSG_PUBLIC_KEY);
1396
1397 check_host_key(host, hostaddr, host_key);
1398
1399 client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
1400
1401 compute_session_id(session_id, check_bytes, host_key->n, public_key->n);
1378 1402
1379 /* Generate a session key. */ 1403 /* Generate a session key. */
1380 arc4random_stir(); 1404 arc4random_stir();
@@ -1465,7 +1489,7 @@ ssh_login(int host_key_valid,
1465 packet_put_bignum(key); 1489 packet_put_bignum(key);
1466 1490
1467 /* Send protocol flags. */ 1491 /* Send protocol flags. */
1468 packet_put_int(SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN); 1492 packet_put_int(client_flags);
1469 1493
1470 /* Send the packet now. */ 1494 /* Send the packet now. */
1471 packet_send(); 1495 packet_send();