summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2016-02-08 10:57:07 +0000
committerDamien Miller <djm@mindrot.org>2016-02-08 21:58:32 +1100
commit19bcf2ea2d17413f2d9730dd2a19575ff86b9b6a (patch)
treea87286b290fcd540635890856fbcafef74341ec0 /packet.c
parent603ba41179e4b53951c7b90ee95b6ef3faa3f15d (diff)
upstream commit
refactor activation of rekeying This makes automatic rekeying internal to the packet code (previously the server and client loops needed to assist). In doing to it makes application of rekey limits more accurate by accounting for packets about to be sent as well as packets queued during rekeying events themselves. Based on a patch from dtucker@ which was in turn based on a patch Aleksander Adamowski in bz#2521; ok markus@ Upstream-ID: a441227fd64f9739850ca97b4cf794202860fcd8
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{