summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2016-09-28 16:33:06 +0000
committerDamien Miller <djm@mindrot.org>2016-09-29 03:11:32 +1000
commit0082fba4efdd492f765ed4c53f0d0fbd3bdbdf7f (patch)
treeb0271896ec4d6c0e716821954212677438824a05 /packet.c
parent27c3a9c2aede2184856b5de1e6eca414bb751c38 (diff)
upstream commit
Remove support for pre-authentication compression. Doing compression early in the protocol probably seemed reasonable in the 1990s, but today it's clearly a bad idea in terms of both cryptography (cf. multiple compression oracle attacks in TLS) and attack surface. Moreover, to support it across privilege-separation zlib needed the assistance of a complex shared-memory manager that made the required attack surface considerably larger. Prompted by Guido Vranken pointing out a compiler-elided security check in the shared memory manager found by Stack (http://css.csail.mit.edu/stack/); ok deraadt@ markus@ NB. pre-auth authentication has been disabled by default in sshd for >10 years. Upstream-ID: 32af9771788d45a0779693b41d06ec199d849caf
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c104
1 files changed, 6 insertions, 98 deletions
diff --git a/packet.c b/packet.c
index fb316acbc..002e8d49a 100644
--- a/packet.c
+++ b/packet.c
@@ -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 */
760static int
761ssh_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 */
788static int
789ssh_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
826void
827ssh_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)
2450static int 2370static int
2451ssh_packet_set_postauth(struct ssh *ssh) 2371ssh_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);