summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c154
1 files changed, 115 insertions, 39 deletions
diff --git a/packet.c b/packet.c
index f7e5bc78f..7ddebeb71 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.227 2016/02/04 23:43:48 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.228 2016/02/08 10:57:07 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
@@ -259,6 +259,14 @@ ssh_alloc_session_state(void)
259 return NULL; 259 return NULL;
260} 260}
261 261
262/* Returns nonzero if rekeying is in progress */
263int
264ssh_packet_is_rekeying(struct ssh *ssh)
265{
266 return ssh->state->rekeying ||
267 (ssh->kex != NULL && ssh->kex->done == 0);
268}
269
262/* 270/*
263 * Sets the descriptors used for communication. Disables encryption until 271 * Sets the descriptors used for communication. Disables encryption until
264 * packet_set_encryption_key is called. 272 * packet_set_encryption_key is called.
@@ -1029,6 +1037,51 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
1029 return 0; 1037 return 0;
1030} 1038}
1031 1039
1040#define MAX_PACKETS (1U<<31)
1041static int
1042ssh_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
1032/* 1085/*
1033 * Delayed compression for SSH2 is enabled after authentication: 1086 * Delayed compression for SSH2 is enabled after authentication:
1034 * 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,
@@ -1232,35 +1285,58 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
1232 return r; 1285 return r;
1233} 1286}
1234 1287
1288/* returns non-zero if the specified packet type is usec by KEX */
1289static int
1290ssh_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
1235int 1300int
1236ssh_packet_send2(struct ssh *ssh) 1301ssh_packet_send2(struct ssh *ssh)
1237{ 1302{
1238 struct session_state *state = ssh->state; 1303 struct session_state *state = ssh->state;
1239 struct packet *p; 1304 struct packet *p;
1240 u_char type; 1305 u_char type;
1241 int r; 1306 int r, need_rekey;
1242 1307
1308 if (sshbuf_len(state->outgoing_packet) < 6)
1309 return SSH_ERR_INTERNAL_ERROR;
1243 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));
1244 1313
1245 /* during rekeying we can only send key exchange messages */ 1314 /*
1246 if (state->rekeying) { 1315 * During rekeying we can only send key exchange messages.
1247 if ((type < SSH2_MSG_TRANSPORT_MIN) || 1316 * Queue everything else.
1248 (type > SSH2_MSG_TRANSPORT_MAX) || 1317 */
1249 (type == SSH2_MSG_SERVICE_REQUEST) || 1318 if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) {
1250 (type == SSH2_MSG_SERVICE_ACCEPT) || 1319 if (need_rekey)
1251 (type == SSH2_MSG_EXT_INFO)) { 1320 debug3("%s: rekex triggered", __func__);
1252 debug("enqueue packet: %u", type); 1321 debug("enqueue packet: %u", type);
1253 p = calloc(1, sizeof(*p)); 1322 p = calloc(1, sizeof(*p));
1254 if (p == NULL) 1323 if (p == NULL)
1255 return SSH_ERR_ALLOC_FAIL; 1324 return SSH_ERR_ALLOC_FAIL;
1256 p->type = type; 1325 p->type = type;
1257 p->payload = state->outgoing_packet; 1326 p->payload = state->outgoing_packet;
1258 TAILQ_INSERT_TAIL(&state->outgoing, p, next); 1327 TAILQ_INSERT_TAIL(&state->outgoing, p, next);
1259 state->outgoing_packet = sshbuf_new(); 1328 state->outgoing_packet = sshbuf_new();
1260 if (state->outgoing_packet == NULL) 1329 if (state->outgoing_packet == NULL)
1261 return SSH_ERR_ALLOC_FAIL; 1330 return SSH_ERR_ALLOC_FAIL;
1262 return 0; 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);
1263 } 1338 }
1339 return 0;
1264 } 1340 }
1265 1341
1266 /* rekeying starts with sending KEXINIT */ 1342 /* rekeying starts with sending KEXINIT */
@@ -1276,10 +1352,22 @@ ssh_packet_send2(struct ssh *ssh)
1276 state->rekey_time = monotime(); 1352 state->rekey_time = monotime();
1277 while ((p = TAILQ_FIRST(&state->outgoing))) { 1353 while ((p = TAILQ_FIRST(&state->outgoing))) {
1278 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 }
1279 debug("dequeue packet: %u", type); 1366 debug("dequeue packet: %u", type);
1280 sshbuf_free(state->outgoing_packet); 1367 sshbuf_free(state->outgoing_packet);
1281 state->outgoing_packet = p->payload; 1368 state->outgoing_packet = p->payload;
1282 TAILQ_REMOVE(&state->outgoing, p, next); 1369 TAILQ_REMOVE(&state->outgoing, p, next);
1370 memset(p, 0, sizeof(*p));
1283 free(p); 1371 free(p);
1284 if ((r = ssh_packet_send2_wrapped(ssh)) != 0) 1372 if ((r = ssh_packet_send2_wrapped(ssh)) != 0)
1285 return r; 1373 return r;
@@ -1784,6 +1872,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1784#endif 1872#endif
1785 /* reset for next packet */ 1873 /* reset for next packet */
1786 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 }
1787 out: 1882 out:
1788 return r; 1883 return r;
1789} 1884}
@@ -2268,25 +2363,6 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
2268 } 2363 }
2269} 2364}
2270 2365
2271#define MAX_PACKETS (1U<<31)
2272int
2273ssh_packet_need_rekeying(struct ssh *ssh)
2274{
2275 struct session_state *state = ssh->state;
2276
2277 if (ssh->compat & SSH_BUG_NOREKEY)
2278 return 0;
2279 return
2280 (state->p_send.packets > MAX_PACKETS) ||
2281 (state->p_read.packets > MAX_PACKETS) ||
2282 (state->max_blocks_out &&
2283 (state->p_send.blocks > state->max_blocks_out)) ||
2284 (state->max_blocks_in &&
2285 (state->p_read.blocks > state->max_blocks_in)) ||
2286 (state->rekey_interval != 0 && state->rekey_time +
2287 state->rekey_interval <= monotime());
2288}
2289
2290void 2366void
2291ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds) 2367ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds)
2292{ 2368{