Mercurial > dropbear
comparison packet.c @ 452:4cab61369879
Prevent invalid packets being sent during key-exchange, instead queue
them until afterwards. This could sometimes terminate connections
after 8 hours if (for example) a new TCP forwarded connection
was sent at the KEX timeout.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 27 Jul 2007 17:13:42 +0000 |
parents | 9c61e7af0156 |
children | 7e43f5e473b9 |
comparison
equal
deleted
inserted
replaced
451:f2aa5aeea619 | 452:4cab61369879 |
---|---|
401 } | 401 } |
402 } | 402 } |
403 #endif | 403 #endif |
404 | 404 |
405 | 405 |
406 | 406 /* returns 1 if the packet is a valid type during kex (see 7.1 of rfc4253) */ |
407 static int packet_is_okay_kex(unsigned char type) { | |
408 if (type >= SSH_MSG_USERAUTH_REQUEST) { | |
409 return 0; | |
410 } | |
411 if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) { | |
412 return 0; | |
413 } | |
414 if (type == SSH_MSG_KEXINIT) { | |
415 /* XXX should this die horribly if !dataallowed ?? */ | |
416 return 0; | |
417 } | |
418 return 1; | |
419 } | |
420 | |
421 static void enqueue_reply_packet() { | |
422 struct packetlist * new_item = NULL; | |
423 new_item = m_malloc(sizeof(struct packetlist)); | |
424 new_item->next = NULL; | |
425 | |
426 new_item->payload = buf_newcopy(ses.writepayload); | |
427 buf_setpos(ses.writepayload, 0); | |
428 buf_setlen(ses.writepayload, 0); | |
429 | |
430 if (ses.reply_queue_tail) { | |
431 ses.reply_queue_tail->next = new_item; | |
432 } else { | |
433 ses.reply_queue_head = new_item; | |
434 ses.reply_queue_tail = new_item; | |
435 } | |
436 TRACE(("leave enqueue_reply_packet")) | |
437 } | |
438 | |
439 void maybe_flush_reply_queue() { | |
440 struct packetlist *tmp_item = NULL, *curr_item = NULL; | |
441 if (!ses.dataallowed) | |
442 { | |
443 TRACE(("maybe_empty_reply_queue - no data allowed")) | |
444 return; | |
445 } | |
446 | |
447 for (curr_item = ses.reply_queue_head; curr_item; ) { | |
448 CHECKCLEARTOWRITE(); | |
449 buf_putbytes(ses.writepayload, | |
450 curr_item->payload->data, curr_item->payload->len); | |
451 | |
452 buf_free(curr_item->payload); | |
453 tmp_item = curr_item; | |
454 curr_item = curr_item->next; | |
455 m_free(tmp_item); | |
456 encrypt_packet(); | |
457 } | |
458 ses.reply_queue_head = ses.reply_queue_tail = NULL; | |
459 } | |
407 | 460 |
408 /* encrypt the writepayload, putting into writebuf, ready for write_packet() | 461 /* encrypt the writepayload, putting into writebuf, ready for write_packet() |
409 * to put on the wire */ | 462 * to put on the wire */ |
410 void encrypt_packet() { | 463 void encrypt_packet() { |
411 | 464 |
412 unsigned char padlen; | 465 unsigned char padlen; |
413 unsigned char blocksize, macsize; | 466 unsigned char blocksize, macsize; |
414 buffer * writebuf; /* the packet which will go on the wire */ | 467 buffer * writebuf; /* the packet which will go on the wire */ |
415 buffer * clearwritebuf; /* unencrypted, possibly compressed */ | 468 buffer * clearwritebuf; /* unencrypted, possibly compressed */ |
416 | 469 unsigned char type; |
470 | |
471 type = ses.writepayload->data[0]; | |
417 TRACE(("enter encrypt_packet()")) | 472 TRACE(("enter encrypt_packet()")) |
418 TRACE(("encrypt_packet type is %d", ses.writepayload->data[0])) | 473 TRACE(("encrypt_packet type is %d", type)) |
474 | |
475 if (!ses.dataallowed && !packet_is_okay_kex(type)) { | |
476 /* During key exchange only particular packets are allowed. | |
477 Since this type isn't OK we just enqueue it to send | |
478 after the KEX, see maybe_flush_reply_queue */ | |
479 enqueue_reply_packet(); | |
480 return; | |
481 } | |
482 | |
419 blocksize = ses.keys->trans_algo_crypt->blocksize; | 483 blocksize = ses.keys->trans_algo_crypt->blocksize; |
420 macsize = ses.keys->trans_algo_mac->hashsize; | 484 macsize = ses.keys->trans_algo_mac->hashsize; |
421 | 485 |
422 /* Encrypted packet len is payload+5, then worst case is if we are 3 away | 486 /* Encrypted packet len is payload+5, then worst case is if we are 3 away |
423 * from a blocksize multiple. In which case we need to pad to the | 487 * from a blocksize multiple. In which case we need to pad to the |