diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 104 |
1 files changed, 6 insertions, 98 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.238 2016/09/19 19:02:19 markus Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.239 2016/09/28 16:33: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 |
@@ -756,86 +756,6 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) | |||
756 | /* NOTREACHED */ | 756 | /* NOTREACHED */ |
757 | } | 757 | } |
758 | 758 | ||
759 | /* Serialise compression state into a blob for privsep */ | ||
760 | static int | ||
761 | ssh_packet_get_compress_state(struct sshbuf *m, struct ssh *ssh) | ||
762 | { | ||
763 | struct session_state *state = ssh->state; | ||
764 | struct sshbuf *b; | ||
765 | int r; | ||
766 | |||
767 | if ((b = sshbuf_new()) == NULL) | ||
768 | return SSH_ERR_ALLOC_FAIL; | ||
769 | if (state->compression_in_started) { | ||
770 | if ((r = sshbuf_put_string(b, &state->compression_in_stream, | ||
771 | sizeof(state->compression_in_stream))) != 0) | ||
772 | goto out; | ||
773 | } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) | ||
774 | goto out; | ||
775 | if (state->compression_out_started) { | ||
776 | if ((r = sshbuf_put_string(b, &state->compression_out_stream, | ||
777 | sizeof(state->compression_out_stream))) != 0) | ||
778 | goto out; | ||
779 | } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) | ||
780 | goto out; | ||
781 | r = sshbuf_put_stringb(m, b); | ||
782 | out: | ||
783 | sshbuf_free(b); | ||
784 | return r; | ||
785 | } | ||
786 | |||
787 | /* Deserialise compression state from a blob for privsep */ | ||
788 | static int | ||
789 | ssh_packet_set_compress_state(struct ssh *ssh, struct sshbuf *m) | ||
790 | { | ||
791 | struct session_state *state = ssh->state; | ||
792 | struct sshbuf *b = NULL; | ||
793 | int r; | ||
794 | const u_char *inblob, *outblob; | ||
795 | size_t inl, outl; | ||
796 | |||
797 | if ((r = sshbuf_froms(m, &b)) != 0) | ||
798 | goto out; | ||
799 | if ((r = sshbuf_get_string_direct(b, &inblob, &inl)) != 0 || | ||
800 | (r = sshbuf_get_string_direct(b, &outblob, &outl)) != 0) | ||
801 | goto out; | ||
802 | if (inl == 0) | ||
803 | state->compression_in_started = 0; | ||
804 | else if (inl != sizeof(state->compression_in_stream)) { | ||
805 | r = SSH_ERR_INTERNAL_ERROR; | ||
806 | goto out; | ||
807 | } else { | ||
808 | state->compression_in_started = 1; | ||
809 | memcpy(&state->compression_in_stream, inblob, inl); | ||
810 | } | ||
811 | if (outl == 0) | ||
812 | state->compression_out_started = 0; | ||
813 | else if (outl != sizeof(state->compression_out_stream)) { | ||
814 | r = SSH_ERR_INTERNAL_ERROR; | ||
815 | goto out; | ||
816 | } else { | ||
817 | state->compression_out_started = 1; | ||
818 | memcpy(&state->compression_out_stream, outblob, outl); | ||
819 | } | ||
820 | r = 0; | ||
821 | out: | ||
822 | sshbuf_free(b); | ||
823 | return r; | ||
824 | } | ||
825 | |||
826 | void | ||
827 | ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx, | ||
828 | void *(*allocfunc)(void *, u_int, u_int), | ||
829 | void (*freefunc)(void *, void *)) | ||
830 | { | ||
831 | ssh->state->compression_out_stream.zalloc = (alloc_func)allocfunc; | ||
832 | ssh->state->compression_out_stream.zfree = (free_func)freefunc; | ||
833 | ssh->state->compression_out_stream.opaque = ctx; | ||
834 | ssh->state->compression_in_stream.zalloc = (alloc_func)allocfunc; | ||
835 | ssh->state->compression_in_stream.zfree = (free_func)freefunc; | ||
836 | ssh->state->compression_in_stream.opaque = ctx; | ||
837 | } | ||
838 | |||
839 | /* | 759 | /* |
840 | * Causes any further packets to be encrypted using the given key. The same | 760 | * Causes any further packets to be encrypted using the given key. The same |
841 | * key is used for both sending and reception. However, both directions are | 761 | * key is used for both sending and reception. However, both directions are |
@@ -2450,21 +2370,14 @@ ssh_packet_get_output(struct ssh *ssh) | |||
2450 | static int | 2370 | static int |
2451 | ssh_packet_set_postauth(struct ssh *ssh) | 2371 | ssh_packet_set_postauth(struct ssh *ssh) |
2452 | { | 2372 | { |
2453 | struct sshcomp *comp; | 2373 | int r; |
2454 | int r, mode; | ||
2455 | 2374 | ||
2456 | debug("%s: called", __func__); | 2375 | debug("%s: called", __func__); |
2457 | /* This was set in net child, but is not visible in user child */ | 2376 | /* This was set in net child, but is not visible in user child */ |
2458 | ssh->state->after_authentication = 1; | 2377 | ssh->state->after_authentication = 1; |
2459 | ssh->state->rekeying = 0; | 2378 | ssh->state->rekeying = 0; |
2460 | for (mode = 0; mode < MODE_MAX; mode++) { | 2379 | if ((r = ssh_packet_enable_delayed_compress(ssh)) != 0) |
2461 | if (ssh->state->newkeys[mode] == NULL) | 2380 | return r; |
2462 | continue; | ||
2463 | comp = &ssh->state->newkeys[mode]->comp; | ||
2464 | if (comp && comp->enabled && | ||
2465 | (r = ssh_packet_init_compression(ssh)) != 0) | ||
2466 | return r; | ||
2467 | } | ||
2468 | return 0; | 2381 | return 0; |
2469 | } | 2382 | } |
2470 | 2383 | ||
@@ -2528,7 +2441,6 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) | |||
2528 | goto out; | 2441 | goto out; |
2529 | } | 2442 | } |
2530 | if ((r = sshbuf_put_u32(b, comp->type)) != 0 || | 2443 | if ((r = sshbuf_put_u32(b, comp->type)) != 0 || |
2531 | (r = sshbuf_put_u32(b, comp->enabled)) != 0 || | ||
2532 | (r = sshbuf_put_cstring(b, comp->name)) != 0) | 2444 | (r = sshbuf_put_cstring(b, comp->name)) != 0) |
2533 | goto out; | 2445 | goto out; |
2534 | r = sshbuf_put_stringb(m, b); | 2446 | r = sshbuf_put_stringb(m, b); |
@@ -2589,9 +2501,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | |||
2589 | return r; | 2501 | return r; |
2590 | if (cipher_get_keycontext(state->receive_context, p) != (int)rlen) | 2502 | if (cipher_get_keycontext(state->receive_context, p) != (int)rlen) |
2591 | return SSH_ERR_INTERNAL_ERROR; | 2503 | return SSH_ERR_INTERNAL_ERROR; |
2592 | 2504 | if ((r = sshbuf_put_stringb(m, state->input)) != 0 || | |
2593 | if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || | ||
2594 | (r = sshbuf_put_stringb(m, state->input)) != 0 || | ||
2595 | (r = sshbuf_put_stringb(m, state->output)) != 0) | 2505 | (r = sshbuf_put_stringb(m, state->output)) != 0) |
2596 | return r; | 2506 | return r; |
2597 | 2507 | ||
@@ -2645,7 +2555,6 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode) | |||
2645 | mac->key_len = maclen; | 2555 | mac->key_len = maclen; |
2646 | } | 2556 | } |
2647 | if ((r = sshbuf_get_u32(b, &comp->type)) != 0 || | 2557 | if ((r = sshbuf_get_u32(b, &comp->type)) != 0 || |
2648 | (r = sshbuf_get_u32(b, (u_int *)&comp->enabled)) != 0 || | ||
2649 | (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0) | 2558 | (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0) |
2650 | goto out; | 2559 | goto out; |
2651 | if (enc->name == NULL || | 2560 | if (enc->name == NULL || |
@@ -2773,8 +2682,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | |||
2773 | cipher_set_keycontext(state->send_context, keyout); | 2682 | cipher_set_keycontext(state->send_context, keyout); |
2774 | cipher_set_keycontext(state->receive_context, keyin); | 2683 | cipher_set_keycontext(state->receive_context, keyin); |
2775 | 2684 | ||
2776 | if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || | 2685 | if ((r = ssh_packet_set_postauth(ssh)) != 0) |
2777 | (r = ssh_packet_set_postauth(ssh)) != 0) | ||
2778 | return r; | 2686 | return r; |
2779 | 2687 | ||
2780 | sshbuf_reset(state->input); | 2688 | sshbuf_reset(state->input); |