diff options
author | Colin Watson <cjwatson@debian.org> | 2016-02-29 12:15:15 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2016-03-08 11:51:22 +0000 |
commit | 46961f5704f8e86cea3e99253faad55aef4d8f35 (patch) | |
tree | 0dd97fa4fb649a62b4639fe2674380872b1f3e98 /packet.c | |
parent | c753fe267efb1b027424fa8706cf0385fc3d14c1 (diff) | |
parent | 85e40e87a75fb80a0bf893ac05a417d6c353537d (diff) |
New upstream release (7.2).
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 366 |
1 files changed, 206 insertions, 160 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.214 2015/08/20 22:32:42 deraadt Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.229 2016/02/17 22:20:14 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -83,7 +83,6 @@ | |||
83 | #include "channels.h" | 83 | #include "channels.h" |
84 | #include "ssh.h" | 84 | #include "ssh.h" |
85 | #include "packet.h" | 85 | #include "packet.h" |
86 | #include "roaming.h" | ||
87 | #include "ssherr.h" | 86 | #include "ssherr.h" |
88 | #include "sshbuf.h" | 87 | #include "sshbuf.h" |
89 | 88 | ||
@@ -181,8 +180,7 @@ struct session_state { | |||
181 | struct packet_state p_read, p_send; | 180 | struct packet_state p_read, p_send; |
182 | 181 | ||
183 | /* Volume-based rekeying */ | 182 | /* Volume-based rekeying */ |
184 | u_int64_t max_blocks_in, max_blocks_out; | 183 | u_int64_t max_blocks_in, max_blocks_out, rekey_limit; |
185 | u_int32_t rekey_limit; | ||
186 | 184 | ||
187 | /* Time-based rekeying */ | 185 | /* Time-based rekeying */ |
188 | u_int32_t rekey_interval; /* how often in seconds */ | 186 | u_int32_t rekey_interval; /* how often in seconds */ |
@@ -261,6 +259,14 @@ ssh_alloc_session_state(void) | |||
261 | return NULL; | 259 | return NULL; |
262 | } | 260 | } |
263 | 261 | ||
262 | /* Returns nonzero if rekeying is in progress */ | ||
263 | int | ||
264 | ssh_packet_is_rekeying(struct ssh *ssh) | ||
265 | { | ||
266 | return compat20 && | ||
267 | (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0)); | ||
268 | } | ||
269 | |||
264 | /* | 270 | /* |
265 | * Sets the descriptors used for communication. Disables encryption until | 271 | * Sets the descriptors used for communication. Disables encryption until |
266 | * packet_set_encryption_key is called. | 272 | * packet_set_encryption_key is called. |
@@ -338,7 +344,8 @@ ssh_packet_stop_discard(struct ssh *ssh) | |||
338 | sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE, | 344 | sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE, |
339 | NULL, 0); | 345 | NULL, 0); |
340 | } | 346 | } |
341 | logit("Finished discarding for %.200s", ssh_remote_ipaddr(ssh)); | 347 | logit("Finished discarding for %.200s port %d", |
348 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | ||
342 | return SSH_ERR_MAC_INVALID; | 349 | return SSH_ERR_MAC_INVALID; |
343 | } | 350 | } |
344 | 351 | ||
@@ -455,16 +462,30 @@ ssh_packet_get_connection_out(struct ssh *ssh) | |||
455 | const char * | 462 | const char * |
456 | ssh_remote_ipaddr(struct ssh *ssh) | 463 | ssh_remote_ipaddr(struct ssh *ssh) |
457 | { | 464 | { |
465 | const int sock = ssh->state->connection_in; | ||
466 | |||
458 | /* Check whether we have cached the ipaddr. */ | 467 | /* Check whether we have cached the ipaddr. */ |
459 | if (ssh->remote_ipaddr == NULL) | 468 | if (ssh->remote_ipaddr == NULL) { |
460 | ssh->remote_ipaddr = ssh_packet_connection_is_on_socket(ssh) ? | 469 | if (ssh_packet_connection_is_on_socket(ssh)) { |
461 | get_peer_ipaddr(ssh->state->connection_in) : | 470 | ssh->remote_ipaddr = get_peer_ipaddr(sock); |
462 | strdup("UNKNOWN"); | 471 | ssh->remote_port = get_sock_port(sock, 0); |
463 | if (ssh->remote_ipaddr == NULL) | 472 | } else { |
464 | return "UNKNOWN"; | 473 | ssh->remote_ipaddr = strdup("UNKNOWN"); |
474 | ssh->remote_port = 0; | ||
475 | } | ||
476 | } | ||
465 | return ssh->remote_ipaddr; | 477 | return ssh->remote_ipaddr; |
466 | } | 478 | } |
467 | 479 | ||
480 | /* Returns the port number of the remote host. */ | ||
481 | |||
482 | int | ||
483 | ssh_remote_port(struct ssh *ssh) | ||
484 | { | ||
485 | (void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */ | ||
486 | return ssh->remote_port; | ||
487 | } | ||
488 | |||
468 | /* Closes the connection and clears and frees internal data structures. */ | 489 | /* Closes the connection and clears and frees internal data structures. */ |
469 | 490 | ||
470 | void | 491 | void |
@@ -519,10 +540,8 @@ ssh_packet_close(struct ssh *ssh) | |||
519 | error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); | 540 | error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); |
520 | if ((r = cipher_cleanup(&state->receive_context)) != 0) | 541 | if ((r = cipher_cleanup(&state->receive_context)) != 0) |
521 | error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); | 542 | error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); |
522 | if (ssh->remote_ipaddr) { | 543 | free(ssh->remote_ipaddr); |
523 | free(ssh->remote_ipaddr); | 544 | ssh->remote_ipaddr = NULL; |
524 | ssh->remote_ipaddr = NULL; | ||
525 | } | ||
526 | free(ssh->state); | 545 | free(ssh->state); |
527 | ssh->state = NULL; | 546 | ssh->state = NULL; |
528 | } | 547 | } |
@@ -941,7 +960,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
941 | max_blocks = &state->max_blocks_in; | 960 | max_blocks = &state->max_blocks_in; |
942 | } | 961 | } |
943 | if (state->newkeys[mode] != NULL) { | 962 | if (state->newkeys[mode] != NULL) { |
944 | debug("set_newkeys: rekeying"); | 963 | debug("set_newkeys: rekeying, input %llu bytes %llu blocks, " |
964 | "output %llu bytes %llu blocks", | ||
965 | (unsigned long long)state->p_read.bytes, | ||
966 | (unsigned long long)state->p_read.blocks, | ||
967 | (unsigned long long)state->p_send.bytes, | ||
968 | (unsigned long long)state->p_send.blocks); | ||
945 | if ((r = cipher_cleanup(cc)) != 0) | 969 | if ((r = cipher_cleanup(cc)) != 0) |
946 | return r; | 970 | return r; |
947 | enc = &state->newkeys[mode]->enc; | 971 | enc = &state->newkeys[mode]->enc; |
@@ -1009,9 +1033,55 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
1009 | if (state->rekey_limit) | 1033 | if (state->rekey_limit) |
1010 | *max_blocks = MIN(*max_blocks, | 1034 | *max_blocks = MIN(*max_blocks, |
1011 | state->rekey_limit / enc->block_size); | 1035 | state->rekey_limit / enc->block_size); |
1036 | debug("rekey after %llu blocks", (unsigned long long)*max_blocks); | ||
1012 | return 0; | 1037 | return 0; |
1013 | } | 1038 | } |
1014 | 1039 | ||
1040 | #define MAX_PACKETS (1U<<31) | ||
1041 | static int | ||
1042 | ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) | ||
1043 | { | ||
1044 | struct session_state *state = ssh->state; | ||
1045 | u_int32_t out_blocks; | ||
1046 | |||
1047 | /* XXX client can't cope with rekeying pre-auth */ | ||
1048 | if (!state->after_authentication) | ||
1049 | return 0; | ||
1050 | |||
1051 | /* Haven't keyed yet or KEX in progress. */ | ||
1052 | if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh)) | ||
1053 | return 0; | ||
1054 | |||
1055 | /* Peer can't rekey */ | ||
1056 | if (ssh->compat & SSH_BUG_NOREKEY) | ||
1057 | return 0; | ||
1058 | |||
1059 | /* | ||
1060 | * Permit one packet in or out per rekey - this allows us to | ||
1061 | * make progress when rekey limits are very small. | ||
1062 | */ | ||
1063 | if (state->p_send.packets == 0 && state->p_read.packets == 0) | ||
1064 | return 0; | ||
1065 | |||
1066 | /* Time-based rekeying */ | ||
1067 | if (state->rekey_interval != 0 && | ||
1068 | state->rekey_time + state->rekey_interval <= monotime()) | ||
1069 | return 1; | ||
1070 | |||
1071 | /* Always rekey when MAX_PACKETS sent in either direction */ | ||
1072 | if (state->p_send.packets > MAX_PACKETS || | ||
1073 | state->p_read.packets > MAX_PACKETS) | ||
1074 | return 1; | ||
1075 | |||
1076 | /* Rekey after (cipher-specific) maxiumum blocks */ | ||
1077 | out_blocks = roundup(outbound_packet_len, | ||
1078 | state->newkeys[MODE_OUT]->enc.block_size); | ||
1079 | return (state->max_blocks_out && | ||
1080 | (state->p_send.blocks + out_blocks > state->max_blocks_out)) || | ||
1081 | (state->max_blocks_in && | ||
1082 | (state->p_read.blocks > state->max_blocks_in)); | ||
1083 | } | ||
1084 | |||
1015 | /* | 1085 | /* |
1016 | * Delayed compression for SSH2 is enabled after authentication: | 1086 | * Delayed compression for SSH2 is enabled after authentication: |
1017 | * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, | 1087 | * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, |
@@ -1050,6 +1120,20 @@ ssh_packet_enable_delayed_compress(struct ssh *ssh) | |||
1050 | return 0; | 1120 | return 0; |
1051 | } | 1121 | } |
1052 | 1122 | ||
1123 | /* Used to mute debug logging for noisy packet types */ | ||
1124 | static int | ||
1125 | ssh_packet_log_type(u_char type) | ||
1126 | { | ||
1127 | switch (type) { | ||
1128 | case SSH2_MSG_CHANNEL_DATA: | ||
1129 | case SSH2_MSG_CHANNEL_EXTENDED_DATA: | ||
1130 | case SSH2_MSG_CHANNEL_WINDOW_ADJUST: | ||
1131 | return 0; | ||
1132 | default: | ||
1133 | return 1; | ||
1134 | } | ||
1135 | } | ||
1136 | |||
1053 | /* | 1137 | /* |
1054 | * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) | 1138 | * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) |
1055 | */ | 1139 | */ |
@@ -1078,7 +1162,8 @@ ssh_packet_send2_wrapped(struct ssh *ssh) | |||
1078 | aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; | 1162 | aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; |
1079 | 1163 | ||
1080 | type = (sshbuf_ptr(state->outgoing_packet))[5]; | 1164 | type = (sshbuf_ptr(state->outgoing_packet))[5]; |
1081 | 1165 | if (ssh_packet_log_type(type)) | |
1166 | debug3("send packet: type %u", type); | ||
1082 | #ifdef PACKET_DEBUG | 1167 | #ifdef PACKET_DEBUG |
1083 | fprintf(stderr, "plain: "); | 1168 | fprintf(stderr, "plain: "); |
1084 | sshbuf_dump(state->outgoing_packet, stderr); | 1169 | sshbuf_dump(state->outgoing_packet, stderr); |
@@ -1200,34 +1285,58 @@ ssh_packet_send2_wrapped(struct ssh *ssh) | |||
1200 | return r; | 1285 | return r; |
1201 | } | 1286 | } |
1202 | 1287 | ||
1288 | /* returns non-zero if the specified packet type is usec by KEX */ | ||
1289 | static int | ||
1290 | ssh_packet_type_is_kex(u_char type) | ||
1291 | { | ||
1292 | return | ||
1293 | type >= SSH2_MSG_TRANSPORT_MIN && | ||
1294 | type <= SSH2_MSG_TRANSPORT_MAX && | ||
1295 | type != SSH2_MSG_SERVICE_REQUEST && | ||
1296 | type != SSH2_MSG_SERVICE_ACCEPT && | ||
1297 | type != SSH2_MSG_EXT_INFO; | ||
1298 | } | ||
1299 | |||
1203 | int | 1300 | int |
1204 | ssh_packet_send2(struct ssh *ssh) | 1301 | ssh_packet_send2(struct ssh *ssh) |
1205 | { | 1302 | { |
1206 | struct session_state *state = ssh->state; | 1303 | struct session_state *state = ssh->state; |
1207 | struct packet *p; | 1304 | struct packet *p; |
1208 | u_char type; | 1305 | u_char type; |
1209 | int r; | 1306 | int r, need_rekey; |
1210 | 1307 | ||
1308 | if (sshbuf_len(state->outgoing_packet) < 6) | ||
1309 | return SSH_ERR_INTERNAL_ERROR; | ||
1211 | type = sshbuf_ptr(state->outgoing_packet)[5]; | 1310 | type = sshbuf_ptr(state->outgoing_packet)[5]; |
1311 | need_rekey = !ssh_packet_type_is_kex(type) && | ||
1312 | ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet)); | ||
1212 | 1313 | ||
1213 | /* during rekeying we can only send key exchange messages */ | 1314 | /* |
1214 | if (state->rekeying) { | 1315 | * During rekeying we can only send key exchange messages. |
1215 | if ((type < SSH2_MSG_TRANSPORT_MIN) || | 1316 | * Queue everything else. |
1216 | (type > SSH2_MSG_TRANSPORT_MAX) || | 1317 | */ |
1217 | (type == SSH2_MSG_SERVICE_REQUEST) || | 1318 | if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) { |
1218 | (type == SSH2_MSG_SERVICE_ACCEPT)) { | 1319 | if (need_rekey) |
1219 | debug("enqueue packet: %u", type); | 1320 | debug3("%s: rekex triggered", __func__); |
1220 | p = calloc(1, sizeof(*p)); | 1321 | debug("enqueue packet: %u", type); |
1221 | if (p == NULL) | 1322 | p = calloc(1, sizeof(*p)); |
1222 | return SSH_ERR_ALLOC_FAIL; | 1323 | if (p == NULL) |
1223 | p->type = type; | 1324 | return SSH_ERR_ALLOC_FAIL; |
1224 | p->payload = state->outgoing_packet; | 1325 | p->type = type; |
1225 | TAILQ_INSERT_TAIL(&state->outgoing, p, next); | 1326 | p->payload = state->outgoing_packet; |
1226 | state->outgoing_packet = sshbuf_new(); | 1327 | TAILQ_INSERT_TAIL(&state->outgoing, p, next); |
1227 | if (state->outgoing_packet == NULL) | 1328 | state->outgoing_packet = sshbuf_new(); |
1228 | return SSH_ERR_ALLOC_FAIL; | 1329 | if (state->outgoing_packet == NULL) |
1229 | return 0; | 1330 | return SSH_ERR_ALLOC_FAIL; |
1331 | if (need_rekey) { | ||
1332 | /* | ||
1333 | * This packet triggered a rekey, so send the | ||
1334 | * KEXINIT now. | ||
1335 | * NB. reenters this function via kex_start_rekex(). | ||
1336 | */ | ||
1337 | return kex_start_rekex(ssh); | ||
1230 | } | 1338 | } |
1339 | return 0; | ||
1231 | } | 1340 | } |
1232 | 1341 | ||
1233 | /* rekeying starts with sending KEXINIT */ | 1342 | /* rekeying starts with sending KEXINIT */ |
@@ -1243,10 +1352,22 @@ ssh_packet_send2(struct ssh *ssh) | |||
1243 | state->rekey_time = monotime(); | 1352 | state->rekey_time = monotime(); |
1244 | while ((p = TAILQ_FIRST(&state->outgoing))) { | 1353 | while ((p = TAILQ_FIRST(&state->outgoing))) { |
1245 | type = p->type; | 1354 | type = p->type; |
1355 | /* | ||
1356 | * If this packet triggers a rekex, then skip the | ||
1357 | * remaining packets in the queue for now. | ||
1358 | * NB. re-enters this function via kex_start_rekex. | ||
1359 | */ | ||
1360 | if (ssh_packet_need_rekeying(ssh, | ||
1361 | sshbuf_len(p->payload))) { | ||
1362 | debug3("%s: queued packet triggered rekex", | ||
1363 | __func__); | ||
1364 | return kex_start_rekex(ssh); | ||
1365 | } | ||
1246 | debug("dequeue packet: %u", type); | 1366 | debug("dequeue packet: %u", type); |
1247 | sshbuf_free(state->outgoing_packet); | 1367 | sshbuf_free(state->outgoing_packet); |
1248 | state->outgoing_packet = p->payload; | 1368 | state->outgoing_packet = p->payload; |
1249 | TAILQ_REMOVE(&state->outgoing, p, next); | 1369 | TAILQ_REMOVE(&state->outgoing, p, next); |
1370 | memset(p, 0, sizeof(*p)); | ||
1250 | free(p); | 1371 | free(p); |
1251 | if ((r = ssh_packet_send2_wrapped(ssh)) != 0) | 1372 | if ((r = ssh_packet_send2_wrapped(ssh)) != 0) |
1252 | return r; | 1373 | return r; |
@@ -1265,7 +1386,7 @@ int | |||
1265 | ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | 1386 | ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) |
1266 | { | 1387 | { |
1267 | struct session_state *state = ssh->state; | 1388 | struct session_state *state = ssh->state; |
1268 | int len, r, ms_remain, cont; | 1389 | int len, r, ms_remain; |
1269 | fd_set *setp; | 1390 | fd_set *setp; |
1270 | char buf[8192]; | 1391 | char buf[8192]; |
1271 | struct timeval timeout, start, *timeoutp = NULL; | 1392 | struct timeval timeout, start, *timeoutp = NULL; |
@@ -1335,11 +1456,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1335 | if (r == 0) | 1456 | if (r == 0) |
1336 | return SSH_ERR_CONN_TIMEOUT; | 1457 | return SSH_ERR_CONN_TIMEOUT; |
1337 | /* Read data from the socket. */ | 1458 | /* Read data from the socket. */ |
1338 | do { | 1459 | len = read(state->connection_in, buf, sizeof(buf)); |
1339 | cont = 0; | ||
1340 | len = roaming_read(state->connection_in, buf, | ||
1341 | sizeof(buf), &cont); | ||
1342 | } while (len == 0 && cont); | ||
1343 | if (len == 0) { | 1460 | if (len == 0) { |
1344 | r = SSH_ERR_CONN_CLOSED; | 1461 | r = SSH_ERR_CONN_CLOSED; |
1345 | goto out; | 1462 | goto out; |
@@ -1734,6 +1851,8 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1734 | */ | 1851 | */ |
1735 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) | 1852 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) |
1736 | goto out; | 1853 | goto out; |
1854 | if (ssh_packet_log_type(*typep)) | ||
1855 | debug3("receive packet: type %u", *typep); | ||
1737 | if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { | 1856 | if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { |
1738 | if ((r = sshpkt_disconnect(ssh, | 1857 | if ((r = sshpkt_disconnect(ssh, |
1739 | "Invalid ssh2 packet type: %d", *typep)) != 0 || | 1858 | "Invalid ssh2 packet type: %d", *typep)) != 0 || |
@@ -1753,6 +1872,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1753 | #endif | 1872 | #endif |
1754 | /* reset for next packet */ | 1873 | /* reset for next packet */ |
1755 | state->packlen = 0; | 1874 | state->packlen = 0; |
1875 | |||
1876 | /* do we need to rekey? */ | ||
1877 | if (ssh_packet_need_rekeying(ssh, 0)) { | ||
1878 | debug3("%s: rekex triggered", __func__); | ||
1879 | if ((r = kex_start_rekex(ssh)) != 0) | ||
1880 | return r; | ||
1881 | } | ||
1756 | out: | 1882 | out: |
1757 | return r; | 1883 | return r; |
1758 | } | 1884 | } |
@@ -1783,8 +1909,7 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1783 | if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || | 1909 | if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || |
1784 | (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || | 1910 | (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || |
1785 | (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { | 1911 | (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { |
1786 | if (msg) | 1912 | free(msg); |
1787 | free(msg); | ||
1788 | return r; | 1913 | return r; |
1789 | } | 1914 | } |
1790 | debug("Remote: %.900s", msg); | 1915 | debug("Remote: %.900s", msg); |
@@ -1798,8 +1923,9 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1798 | do_log2(ssh->state->server_side && | 1923 | do_log2(ssh->state->server_side && |
1799 | reason == SSH2_DISCONNECT_BY_APPLICATION ? | 1924 | reason == SSH2_DISCONNECT_BY_APPLICATION ? |
1800 | SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, | 1925 | SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, |
1801 | "Received disconnect from %s: %u: %.400s", | 1926 | "Received disconnect from %s port %d:" |
1802 | ssh_remote_ipaddr(ssh), reason, msg); | 1927 | "%u: %.400s", ssh_remote_ipaddr(ssh), |
1928 | ssh_remote_port(ssh), reason, msg); | ||
1803 | free(msg); | 1929 | free(msg); |
1804 | return SSH_ERR_DISCONNECTED; | 1930 | return SSH_ERR_DISCONNECTED; |
1805 | case SSH2_MSG_UNIMPLEMENTED: | 1931 | case SSH2_MSG_UNIMPLEMENTED: |
@@ -1827,8 +1953,9 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1827 | case SSH_MSG_DISCONNECT: | 1953 | case SSH_MSG_DISCONNECT: |
1828 | if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) | 1954 | if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) |
1829 | return r; | 1955 | return r; |
1830 | error("Received disconnect from %s: %.400s", | 1956 | error("Received disconnect from %s port %d: " |
1831 | ssh_remote_ipaddr(ssh), msg); | 1957 | "%.400s", ssh_remote_ipaddr(ssh), |
1958 | ssh_remote_port(ssh), msg); | ||
1832 | free(msg); | 1959 | free(msg); |
1833 | return SSH_ERR_DISCONNECTED; | 1960 | return SSH_ERR_DISCONNECTED; |
1834 | default: | 1961 | default: |
@@ -1918,19 +2045,22 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r) | |||
1918 | { | 2045 | { |
1919 | switch (r) { | 2046 | switch (r) { |
1920 | case SSH_ERR_CONN_CLOSED: | 2047 | case SSH_ERR_CONN_CLOSED: |
1921 | logit("Connection closed by %.200s", ssh_remote_ipaddr(ssh)); | 2048 | logit("Connection closed by %.200s port %d", |
2049 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | ||
1922 | cleanup_exit(255); | 2050 | cleanup_exit(255); |
1923 | case SSH_ERR_CONN_TIMEOUT: | 2051 | case SSH_ERR_CONN_TIMEOUT: |
1924 | logit("Connection to %.200s timed out", ssh_remote_ipaddr(ssh)); | 2052 | logit("Connection %s %.200s port %d timed out", |
2053 | ssh->state->server_side ? "from" : "to", | ||
2054 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); | ||
1925 | cleanup_exit(255); | 2055 | cleanup_exit(255); |
1926 | case SSH_ERR_DISCONNECTED: | 2056 | case SSH_ERR_DISCONNECTED: |
1927 | logit("Disconnected from %.200s", | 2057 | logit("Disconnected from %.200s port %d", |
1928 | ssh_remote_ipaddr(ssh)); | 2058 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); |
1929 | cleanup_exit(255); | 2059 | cleanup_exit(255); |
1930 | case SSH_ERR_SYSTEM_ERROR: | 2060 | case SSH_ERR_SYSTEM_ERROR: |
1931 | if (errno == ECONNRESET) { | 2061 | if (errno == ECONNRESET) { |
1932 | logit("Connection reset by %.200s", | 2062 | logit("Connection reset by %.200s port %d", |
1933 | ssh_remote_ipaddr(ssh)); | 2063 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); |
1934 | cleanup_exit(255); | 2064 | cleanup_exit(255); |
1935 | } | 2065 | } |
1936 | /* FALLTHROUGH */ | 2066 | /* FALLTHROUGH */ |
@@ -1940,15 +2070,17 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r) | |||
1940 | case SSH_ERR_NO_KEX_ALG_MATCH: | 2070 | case SSH_ERR_NO_KEX_ALG_MATCH: |
1941 | case SSH_ERR_NO_HOSTKEY_ALG_MATCH: | 2071 | case SSH_ERR_NO_HOSTKEY_ALG_MATCH: |
1942 | if (ssh && ssh->kex && ssh->kex->failed_choice) { | 2072 | if (ssh && ssh->kex && ssh->kex->failed_choice) { |
1943 | fatal("Unable to negotiate with %.200s: %s. " | 2073 | fatal("Unable to negotiate with %.200s port %d: %s. " |
1944 | "Their offer: %s", ssh_remote_ipaddr(ssh), | 2074 | "Their offer: %s", ssh_remote_ipaddr(ssh), |
1945 | ssh_err(r), ssh->kex->failed_choice); | 2075 | ssh_remote_port(ssh), ssh_err(r), |
2076 | ssh->kex->failed_choice); | ||
1946 | } | 2077 | } |
1947 | /* FALLTHROUGH */ | 2078 | /* FALLTHROUGH */ |
1948 | default: | 2079 | default: |
1949 | fatal("%s%sConnection to %.200s: %s", | 2080 | fatal("%s%sConnection %s %.200s port %d: %s", |
1950 | tag != NULL ? tag : "", tag != NULL ? ": " : "", | 2081 | tag != NULL ? tag : "", tag != NULL ? ": " : "", |
1951 | ssh_remote_ipaddr(ssh), ssh_err(r)); | 2082 | ssh->state->server_side ? "from" : "to", |
2083 | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r)); | ||
1952 | } | 2084 | } |
1953 | } | 2085 | } |
1954 | 2086 | ||
@@ -2005,19 +2137,18 @@ ssh_packet_write_poll(struct ssh *ssh) | |||
2005 | { | 2137 | { |
2006 | struct session_state *state = ssh->state; | 2138 | struct session_state *state = ssh->state; |
2007 | int len = sshbuf_len(state->output); | 2139 | int len = sshbuf_len(state->output); |
2008 | int cont, r; | 2140 | int r; |
2009 | 2141 | ||
2010 | if (len > 0) { | 2142 | if (len > 0) { |
2011 | cont = 0; | 2143 | len = write(state->connection_out, |
2012 | len = roaming_write(state->connection_out, | 2144 | sshbuf_ptr(state->output), len); |
2013 | sshbuf_ptr(state->output), len, &cont); | ||
2014 | if (len == -1) { | 2145 | if (len == -1) { |
2015 | if (errno == EINTR || errno == EAGAIN || | 2146 | if (errno == EINTR || errno == EAGAIN || |
2016 | errno == EWOULDBLOCK) | 2147 | errno == EWOULDBLOCK) |
2017 | return 0; | 2148 | return 0; |
2018 | return SSH_ERR_SYSTEM_ERROR; | 2149 | return SSH_ERR_SYSTEM_ERROR; |
2019 | } | 2150 | } |
2020 | if (len == 0 && !cont) | 2151 | if (len == 0) |
2021 | return SSH_ERR_CONN_CLOSED; | 2152 | return SSH_ERR_CONN_CLOSED; |
2022 | if ((r = sshbuf_consume(state->output, len)) != 0) | 2153 | if ((r = sshbuf_consume(state->output, len)) != 0) |
2023 | return r; | 2154 | return r; |
@@ -2041,7 +2172,10 @@ ssh_packet_write_wait(struct ssh *ssh) | |||
2041 | NFDBITS), sizeof(fd_mask)); | 2172 | NFDBITS), sizeof(fd_mask)); |
2042 | if (setp == NULL) | 2173 | if (setp == NULL) |
2043 | return SSH_ERR_ALLOC_FAIL; | 2174 | return SSH_ERR_ALLOC_FAIL; |
2044 | ssh_packet_write_poll(ssh); | 2175 | if ((r = ssh_packet_write_poll(ssh)) != 0) { |
2176 | free(setp); | ||
2177 | return r; | ||
2178 | } | ||
2045 | while (ssh_packet_have_data_to_write(ssh)) { | 2179 | while (ssh_packet_have_data_to_write(ssh)) { |
2046 | memset(setp, 0, howmany(state->connection_out + 1, | 2180 | memset(setp, 0, howmany(state->connection_out + 1, |
2047 | NFDBITS) * sizeof(fd_mask)); | 2181 | NFDBITS) * sizeof(fd_mask)); |
@@ -2229,29 +2363,10 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes) | |||
2229 | } | 2363 | } |
2230 | } | 2364 | } |
2231 | 2365 | ||
2232 | #define MAX_PACKETS (1U<<31) | ||
2233 | int | ||
2234 | ssh_packet_need_rekeying(struct ssh *ssh) | ||
2235 | { | ||
2236 | struct session_state *state = ssh->state; | ||
2237 | |||
2238 | if (ssh->compat & SSH_BUG_NOREKEY) | ||
2239 | return 0; | ||
2240 | return | ||
2241 | (state->p_send.packets > MAX_PACKETS) || | ||
2242 | (state->p_read.packets > MAX_PACKETS) || | ||
2243 | (state->max_blocks_out && | ||
2244 | (state->p_send.blocks > state->max_blocks_out)) || | ||
2245 | (state->max_blocks_in && | ||
2246 | (state->p_read.blocks > state->max_blocks_in)) || | ||
2247 | (state->rekey_interval != 0 && state->rekey_time + | ||
2248 | state->rekey_interval <= monotime()); | ||
2249 | } | ||
2250 | |||
2251 | void | 2366 | void |
2252 | ssh_packet_set_rekey_limits(struct ssh *ssh, u_int32_t bytes, time_t seconds) | 2367 | ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds) |
2253 | { | 2368 | { |
2254 | debug3("rekey after %lld bytes, %d seconds", (long long)bytes, | 2369 | debug3("rekey after %llu bytes, %d seconds", (unsigned long long)bytes, |
2255 | (int)seconds); | 2370 | (int)seconds); |
2256 | ssh->state->rekey_limit = bytes; | 2371 | ssh->state->rekey_limit = bytes; |
2257 | ssh->state->rekey_interval = seconds; | 2372 | ssh->state->rekey_interval = seconds; |
@@ -2291,58 +2406,6 @@ ssh_packet_get_output(struct ssh *ssh) | |||
2291 | return (void *)ssh->state->output; | 2406 | return (void *)ssh->state->output; |
2292 | } | 2407 | } |
2293 | 2408 | ||
2294 | /* XXX TODO update roaming to new API (does not work anyway) */ | ||
2295 | /* | ||
2296 | * Save the state for the real connection, and use a separate state when | ||
2297 | * resuming a suspended connection. | ||
2298 | */ | ||
2299 | void | ||
2300 | ssh_packet_backup_state(struct ssh *ssh, | ||
2301 | struct ssh *backup_state) | ||
2302 | { | ||
2303 | struct ssh *tmp; | ||
2304 | |||
2305 | close(ssh->state->connection_in); | ||
2306 | ssh->state->connection_in = -1; | ||
2307 | close(ssh->state->connection_out); | ||
2308 | ssh->state->connection_out = -1; | ||
2309 | if (backup_state) | ||
2310 | tmp = backup_state; | ||
2311 | else | ||
2312 | tmp = ssh_alloc_session_state(); | ||
2313 | backup_state = ssh; | ||
2314 | ssh = tmp; | ||
2315 | } | ||
2316 | |||
2317 | /* XXX FIXME FIXME FIXME */ | ||
2318 | /* | ||
2319 | * Swap in the old state when resuming a connecion. | ||
2320 | */ | ||
2321 | void | ||
2322 | ssh_packet_restore_state(struct ssh *ssh, | ||
2323 | struct ssh *backup_state) | ||
2324 | { | ||
2325 | struct ssh *tmp; | ||
2326 | u_int len; | ||
2327 | int r; | ||
2328 | |||
2329 | tmp = backup_state; | ||
2330 | backup_state = ssh; | ||
2331 | ssh = tmp; | ||
2332 | ssh->state->connection_in = backup_state->state->connection_in; | ||
2333 | backup_state->state->connection_in = -1; | ||
2334 | ssh->state->connection_out = backup_state->state->connection_out; | ||
2335 | backup_state->state->connection_out = -1; | ||
2336 | len = sshbuf_len(backup_state->state->input); | ||
2337 | if (len > 0) { | ||
2338 | if ((r = sshbuf_putb(ssh->state->input, | ||
2339 | backup_state->state->input)) != 0) | ||
2340 | fatal("%s: %s", __func__, ssh_err(r)); | ||
2341 | sshbuf_reset(backup_state->state->input); | ||
2342 | add_recv_bytes(len); | ||
2343 | } | ||
2344 | } | ||
2345 | |||
2346 | /* Reset after_authentication and reset compression in post-auth privsep */ | 2409 | /* Reset after_authentication and reset compression in post-auth privsep */ |
2347 | static int | 2410 | static int |
2348 | ssh_packet_set_postauth(struct ssh *ssh) | 2411 | ssh_packet_set_postauth(struct ssh *ssh) |
@@ -2430,8 +2493,7 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) | |||
2430 | goto out; | 2493 | goto out; |
2431 | r = sshbuf_put_stringb(m, b); | 2494 | r = sshbuf_put_stringb(m, b); |
2432 | out: | 2495 | out: |
2433 | if (b != NULL) | 2496 | sshbuf_free(b); |
2434 | sshbuf_free(b); | ||
2435 | return r; | 2497 | return r; |
2436 | } | 2498 | } |
2437 | 2499 | ||
@@ -2462,7 +2524,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | |||
2462 | if ((r = kex_to_blob(m, ssh->kex)) != 0 || | 2524 | if ((r = kex_to_blob(m, ssh->kex)) != 0 || |
2463 | (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || | 2525 | (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || |
2464 | (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || | 2526 | (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || |
2465 | (r = sshbuf_put_u32(m, state->rekey_limit)) != 0 || | 2527 | (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 || |
2466 | (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 || | 2528 | (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 || |
2467 | (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 || | 2529 | (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 || |
2468 | (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 || | 2530 | (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 || |
@@ -2493,11 +2555,6 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | |||
2493 | (r = sshbuf_put_stringb(m, state->output)) != 0) | 2555 | (r = sshbuf_put_stringb(m, state->output)) != 0) |
2494 | return r; | 2556 | return r; |
2495 | 2557 | ||
2496 | if (compat20) { | ||
2497 | if ((r = sshbuf_put_u64(m, get_sent_bytes())) != 0 || | ||
2498 | (r = sshbuf_put_u64(m, get_recv_bytes())) != 0) | ||
2499 | return r; | ||
2500 | } | ||
2501 | return 0; | 2558 | return 0; |
2502 | } | 2559 | } |
2503 | 2560 | ||
@@ -2566,10 +2623,8 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode) | |||
2566 | newkey = NULL; | 2623 | newkey = NULL; |
2567 | r = 0; | 2624 | r = 0; |
2568 | out: | 2625 | out: |
2569 | if (newkey != NULL) | 2626 | free(newkey); |
2570 | free(newkey); | 2627 | sshbuf_free(b); |
2571 | if (b != NULL) | ||
2572 | sshbuf_free(b); | ||
2573 | return r; | 2628 | return r; |
2574 | } | 2629 | } |
2575 | 2630 | ||
@@ -2602,10 +2657,8 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp) | |||
2602 | out: | 2657 | out: |
2603 | if (r != 0 || kexp == NULL) { | 2658 | if (r != 0 || kexp == NULL) { |
2604 | if (kex != NULL) { | 2659 | if (kex != NULL) { |
2605 | if (kex->my != NULL) | 2660 | sshbuf_free(kex->my); |
2606 | sshbuf_free(kex->my); | 2661 | sshbuf_free(kex->peer); |
2607 | if (kex->peer != NULL) | ||
2608 | sshbuf_free(kex->peer); | ||
2609 | free(kex); | 2662 | free(kex); |
2610 | } | 2663 | } |
2611 | if (kexp != NULL) | 2664 | if (kexp != NULL) |
@@ -2628,7 +2681,6 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | |||
2628 | size_t ssh1keylen, rlen, slen, ilen, olen; | 2681 | size_t ssh1keylen, rlen, slen, ilen, olen; |
2629 | int r; | 2682 | int r; |
2630 | u_int ssh1cipher = 0; | 2683 | u_int ssh1cipher = 0; |
2631 | u_int64_t sent_bytes = 0, recv_bytes = 0; | ||
2632 | 2684 | ||
2633 | if (!compat20) { | 2685 | if (!compat20) { |
2634 | if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || | 2686 | if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || |
@@ -2651,7 +2703,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | |||
2651 | if ((r = kex_from_blob(m, &ssh->kex)) != 0 || | 2703 | if ((r = kex_from_blob(m, &ssh->kex)) != 0 || |
2652 | (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || | 2704 | (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || |
2653 | (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || | 2705 | (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || |
2654 | (r = sshbuf_get_u32(m, &state->rekey_limit)) != 0 || | 2706 | (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 || |
2655 | (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || | 2707 | (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || |
2656 | (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 || | 2708 | (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 || |
2657 | (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 || | 2709 | (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 || |
@@ -2693,12 +2745,6 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | |||
2693 | (r = sshbuf_put(state->output, output, olen)) != 0) | 2745 | (r = sshbuf_put(state->output, output, olen)) != 0) |
2694 | return r; | 2746 | return r; |
2695 | 2747 | ||
2696 | if (compat20) { | ||
2697 | if ((r = sshbuf_get_u64(m, &sent_bytes)) != 0 || | ||
2698 | (r = sshbuf_get_u64(m, &recv_bytes)) != 0) | ||
2699 | return r; | ||
2700 | roam_set_bytes(sent_bytes, recv_bytes); | ||
2701 | } | ||
2702 | if (sshbuf_len(m)) | 2748 | if (sshbuf_len(m)) |
2703 | return SSH_ERR_INVALID_FORMAT; | 2749 | return SSH_ERR_INVALID_FORMAT; |
2704 | debug3("%s: done", __func__); | 2750 | debug3("%s: done", __func__); |