summaryrefslogtreecommitdiff
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
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
-rw-r--r--Makefile.in2
-rw-r--r--monitor.c48
-rw-r--r--monitor.h6
-rw-r--r--monitor_mm.c357
-rw-r--r--monitor_mm.h62
-rw-r--r--monitor_wrap.h5
-rw-r--r--myproposal.h4
-rw-r--r--opacket.h3
-rw-r--r--packet.c104
-rw-r--r--packet.h7
-rw-r--r--servconf.c4
-rw-r--r--sshconnect2.c4
-rw-r--r--sshd.c10
13 files changed, 18 insertions, 598 deletions
diff --git a/Makefile.in b/Makefile.in
index d6df2ff3c..3990f5525 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -104,7 +104,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
104 auth2-chall.o groupaccess.o \ 104 auth2-chall.o groupaccess.o \
105 auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ 105 auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
106 auth2-none.o auth2-passwd.o auth2-pubkey.o \ 106 auth2-none.o auth2-passwd.o auth2-pubkey.o \
107 monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ 107 monitor.o monitor_wrap.o auth-krb5.o \
108 auth2-gss.o gss-serv.o gss-serv-krb5.o \ 108 auth2-gss.o gss-serv.o gss-serv-krb5.o \
109 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ 109 loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
110 sftp-server.o sftp-common.o \ 110 sftp-server.o sftp-common.o \
diff --git a/monitor.c b/monitor.c
index bea8d8b27..43f484709 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.165 2016/09/05 13:57:31 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.166 2016/09/28 16:33:06 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -94,7 +94,6 @@
94#include "misc.h" 94#include "misc.h"
95#include "servconf.h" 95#include "servconf.h"
96#include "monitor.h" 96#include "monitor.h"
97#include "monitor_mm.h"
98#ifdef GSSAPI 97#ifdef GSSAPI
99#include "ssh-gss.h" 98#include "ssh-gss.h"
100#endif 99#endif
@@ -411,31 +410,6 @@ monitor_child_postauth(struct monitor *pmonitor)
411 monitor_read(pmonitor, mon_dispatch, NULL); 410 monitor_read(pmonitor, mon_dispatch, NULL);
412} 411}
413 412
414void
415monitor_sync(struct monitor *pmonitor)
416{
417 if (options.compression) {
418 /* The member allocation is not visible, so sync it */
419 mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);
420 }
421}
422
423/* Allocation functions for zlib */
424static void *
425mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
426{
427 if (size == 0 || ncount == 0 || ncount > SIZE_MAX / size)
428 fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
429
430 return mm_malloc(mm, size * ncount);
431}
432
433static void
434mm_zfree(struct mm_master *mm, void *address)
435{
436 mm_free(mm, address);
437}
438
439static int 413static int
440monitor_read_log(struct monitor *pmonitor) 414monitor_read_log(struct monitor *pmonitor)
441{ 415{
@@ -1632,13 +1606,6 @@ monitor_apply_keystate(struct monitor *pmonitor)
1632 kex->host_key_index=&get_hostkey_index; 1606 kex->host_key_index=&get_hostkey_index;
1633 kex->sign = sshd_hostkey_sign; 1607 kex->sign = sshd_hostkey_sign;
1634 } 1608 }
1635
1636 /* Update with new address */
1637 if (options.compression) {
1638 ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib,
1639 (ssh_packet_comp_alloc_func *)mm_zalloc,
1640 (ssh_packet_comp_free_func *)mm_zfree);
1641 }
1642} 1609}
1643 1610
1644/* This function requries careful sanity checking */ 1611/* This function requries careful sanity checking */
@@ -1691,24 +1658,11 @@ monitor_openfds(struct monitor *mon, int do_logfds)
1691struct monitor * 1658struct monitor *
1692monitor_init(void) 1659monitor_init(void)
1693{ 1660{
1694 struct ssh *ssh = active_state; /* XXX */
1695 struct monitor *mon; 1661 struct monitor *mon;
1696 1662
1697 mon = xcalloc(1, sizeof(*mon)); 1663 mon = xcalloc(1, sizeof(*mon));
1698
1699 monitor_openfds(mon, 1); 1664 monitor_openfds(mon, 1);
1700 1665
1701 /* Used to share zlib space across processes */
1702 if (options.compression) {
1703 mon->m_zback = mm_create(NULL, MM_MEMSIZE);
1704 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
1705
1706 /* Compression needs to share state across borders */
1707 ssh_packet_set_compress_hooks(ssh, mon->m_zlib,
1708 (ssh_packet_comp_alloc_func *)mm_zalloc,
1709 (ssh_packet_comp_free_func *)mm_zfree);
1710 }
1711
1712 return mon; 1666 return mon;
1713} 1667}
1714 1668
diff --git a/monitor.h b/monitor.h
index 93b8b66dd..d68f67458 100644
--- a/monitor.h
+++ b/monitor.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.h,v 1.19 2015/01/19 19:52:16 markus Exp $ */ 1/* $OpenBSD: monitor.h,v 1.20 2016/09/28 16:33:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -67,21 +67,17 @@ enum monitor_reqtype {
67 67
68}; 68};
69 69
70struct mm_master;
71struct monitor { 70struct monitor {
72 int m_recvfd; 71 int m_recvfd;
73 int m_sendfd; 72 int m_sendfd;
74 int m_log_recvfd; 73 int m_log_recvfd;
75 int m_log_sendfd; 74 int m_log_sendfd;
76 struct mm_master *m_zback;
77 struct mm_master *m_zlib;
78 struct kex **m_pkex; 75 struct kex **m_pkex;
79 pid_t m_pid; 76 pid_t m_pid;
80}; 77};
81 78
82struct monitor *monitor_init(void); 79struct monitor *monitor_init(void);
83void monitor_reinit(struct monitor *); 80void monitor_reinit(struct monitor *);
84void monitor_sync(struct monitor *);
85 81
86struct Authctxt; 82struct Authctxt;
87void monitor_child_preauth(struct Authctxt *, struct monitor *); 83void monitor_child_preauth(struct Authctxt *, struct monitor *);
diff --git a/monitor_mm.c b/monitor_mm.c
deleted file mode 100644
index aa47b2ed5..000000000
--- a/monitor_mm.c
+++ /dev/null
@@ -1,357 +0,0 @@
1/* $OpenBSD: monitor_mm.c,v 1.21 2015/02/06 23:21:59 millert Exp $ */
2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "includes.h"
28
29#include <sys/types.h>
30#ifdef HAVE_SYS_MMAN_H
31#include <sys/mman.h>
32#endif
33#include "openbsd-compat/sys-tree.h"
34
35#include <errno.h>
36#include <stdarg.h>
37#include <stddef.h>
38#ifdef HAVE_STDINT_H
39#include <stdint.h>
40#endif
41#include <stdlib.h>
42#include <string.h>
43
44#include "xmalloc.h"
45#include "ssh.h"
46#include "log.h"
47#include "monitor_mm.h"
48
49static int
50mm_compare(struct mm_share *a, struct mm_share *b)
51{
52 ptrdiff_t diff = (char *)a->address - (char *)b->address;
53
54 if (diff == 0)
55 return (0);
56 else if (diff < 0)
57 return (-1);
58 else
59 return (1);
60}
61
62RB_GENERATE(mmtree, mm_share, next, mm_compare)
63
64static struct mm_share *
65mm_make_entry(struct mm_master *mm, struct mmtree *head,
66 void *address, size_t size)
67{
68 struct mm_share *tmp, *tmp2;
69
70 if (mm->mmalloc == NULL)
71 tmp = xcalloc(1, sizeof(struct mm_share));
72 else
73 tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share));
74 tmp->address = address;
75 tmp->size = size;
76
77 tmp2 = RB_INSERT(mmtree, head, tmp);
78 if (tmp2 != NULL)
79 fatal("mm_make_entry(%p): double address %p->%p(%zu)",
80 mm, tmp2, address, size);
81
82 return (tmp);
83}
84
85/* Creates a shared memory area of a certain size */
86
87struct mm_master *
88mm_create(struct mm_master *mmalloc, size_t size)
89{
90 void *address;
91 struct mm_master *mm;
92
93 if (mmalloc == NULL)
94 mm = xcalloc(1, sizeof(struct mm_master));
95 else
96 mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
97
98 /*
99 * If the memory map has a mm_master it can be completely
100 * shared including authentication between the child
101 * and the client.
102 */
103 mm->mmalloc = mmalloc;
104
105 address = xmmap(size);
106 if (address == (void *)MAP_FAILED)
107 fatal("mmap(%zu): %s", size, strerror(errno));
108
109 mm->address = address;
110 mm->size = size;
111
112 RB_INIT(&mm->rb_free);
113 RB_INIT(&mm->rb_allocated);
114
115 mm_make_entry(mm, &mm->rb_free, address, size);
116
117 return (mm);
118}
119
120/* Frees either the allocated or the free list */
121
122static void
123mm_freelist(struct mm_master *mmalloc, struct mmtree *head)
124{
125 struct mm_share *mms, *next;
126
127 for (mms = RB_ROOT(head); mms; mms = next) {
128 next = RB_NEXT(mmtree, head, mms);
129 RB_REMOVE(mmtree, head, mms);
130 if (mmalloc == NULL)
131 free(mms);
132 else
133 mm_free(mmalloc, mms);
134 }
135}
136
137/* Destroys a memory mapped area */
138
139void
140mm_destroy(struct mm_master *mm)
141{
142 mm_freelist(mm->mmalloc, &mm->rb_free);
143 mm_freelist(mm->mmalloc, &mm->rb_allocated);
144
145#ifdef HAVE_MMAP
146 if (munmap(mm->address, mm->size) == -1)
147 fatal("munmap(%p, %zu): %s", mm->address, mm->size,
148 strerror(errno));
149#else
150 fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
151 __func__);
152#endif
153 if (mm->mmalloc == NULL)
154 free(mm);
155 else
156 mm_free(mm->mmalloc, mm);
157}
158
159void *
160mm_xmalloc(struct mm_master *mm, size_t size)
161{
162 void *address;
163
164 address = mm_malloc(mm, size);
165 if (address == NULL)
166 fatal("%s: mm_malloc(%zu)", __func__, size);
167 memset(address, 0, size);
168 return (address);
169}
170
171
172/* Allocates data from a memory mapped area */
173
174void *
175mm_malloc(struct mm_master *mm, size_t size)
176{
177 struct mm_share *mms, *tmp;
178
179 if (size == 0)
180 fatal("mm_malloc: try to allocate 0 space");
181 if (size > SIZE_MAX - MM_MINSIZE + 1)
182 fatal("mm_malloc: size too big");
183
184 size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE;
185
186 RB_FOREACH(mms, mmtree, &mm->rb_free) {
187 if (mms->size >= size)
188 break;
189 }
190
191 if (mms == NULL)
192 return (NULL);
193
194 /* Debug */
195 memset(mms->address, 0xd0, size);
196
197 tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size);
198
199 /* Does not change order in RB tree */
200 mms->size -= size;
201 mms->address = (char *)mms->address + size;
202
203 if (mms->size == 0) {
204 RB_REMOVE(mmtree, &mm->rb_free, mms);
205 if (mm->mmalloc == NULL)
206 free(mms);
207 else
208 mm_free(mm->mmalloc, mms);
209 }
210
211 return (tmp->address);
212}
213
214/* Frees memory in a memory mapped area */
215
216void
217mm_free(struct mm_master *mm, void *address)
218{
219 struct mm_share *mms, *prev, tmp;
220
221 tmp.address = address;
222 mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp);
223 if (mms == NULL)
224 fatal("mm_free(%p): can not find %p", mm, address);
225
226 /* Debug */
227 memset(mms->address, 0xd0, mms->size);
228
229 /* Remove from allocated list and insert in free list */
230 RB_REMOVE(mmtree, &mm->rb_allocated, mms);
231 if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL)
232 fatal("mm_free(%p): double address %p", mm, address);
233
234 /* Find previous entry */
235 prev = mms;
236 if (RB_LEFT(prev, next)) {
237 prev = RB_LEFT(prev, next);
238 while (RB_RIGHT(prev, next))
239 prev = RB_RIGHT(prev, next);
240 } else {
241 if (RB_PARENT(prev, next) &&
242 (prev == RB_RIGHT(RB_PARENT(prev, next), next)))
243 prev = RB_PARENT(prev, next);
244 else {
245 while (RB_PARENT(prev, next) &&
246 (prev == RB_LEFT(RB_PARENT(prev, next), next)))
247 prev = RB_PARENT(prev, next);
248 prev = RB_PARENT(prev, next);
249 }
250 }
251
252 /* Check if range does not overlap */
253 if (prev != NULL && MM_ADDRESS_END(prev) > address)
254 fatal("mm_free: memory corruption: %p(%zu) > %p",
255 prev->address, prev->size, address);
256
257 /* See if we can merge backwards */
258 if (prev != NULL && MM_ADDRESS_END(prev) == address) {
259 prev->size += mms->size;
260 RB_REMOVE(mmtree, &mm->rb_free, mms);
261 if (mm->mmalloc == NULL)
262 free(mms);
263 else
264 mm_free(mm->mmalloc, mms);
265 } else
266 prev = mms;
267
268 if (prev == NULL)
269 return;
270
271 /* Check if we can merge forwards */
272 mms = RB_NEXT(mmtree, &mm->rb_free, prev);
273 if (mms == NULL)
274 return;
275
276 if (MM_ADDRESS_END(prev) > mms->address)
277 fatal("mm_free: memory corruption: %p < %p(%zu)",
278 mms->address, prev->address, prev->size);
279 if (MM_ADDRESS_END(prev) != mms->address)
280 return;
281
282 prev->size += mms->size;
283 RB_REMOVE(mmtree, &mm->rb_free, mms);
284
285 if (mm->mmalloc == NULL)
286 free(mms);
287 else
288 mm_free(mm->mmalloc, mms);
289}
290
291static void
292mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree,
293 struct mm_master *mm, struct mm_master *mmold)
294{
295 struct mm_master *mmalloc = mm->mmalloc;
296 struct mm_share *mms, *new;
297
298 /* Sync free list */
299 RB_FOREACH(mms, mmtree, oldtree) {
300 /* Check the values */
301 mm_memvalid(mmold, mms, sizeof(struct mm_share));
302 mm_memvalid(mm, mms->address, mms->size);
303
304 new = mm_xmalloc(mmalloc, sizeof(struct mm_share));
305 memcpy(new, mms, sizeof(struct mm_share));
306 RB_INSERT(mmtree, newtree, new);
307 }
308}
309
310void
311mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc)
312{
313 struct mm_master *mm;
314 struct mm_master *mmalloc;
315 struct mm_master *mmold;
316 struct mmtree rb_free, rb_allocated;
317
318 debug3("%s: Share sync", __func__);
319
320 mm = *pmm;
321 mmold = mm->mmalloc;
322 mm_memvalid(mmold, mm, sizeof(*mm));
323
324 mmalloc = mm_create(NULL, mm->size);
325 mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
326 memcpy(mm, *pmm, sizeof(struct mm_master));
327 mm->mmalloc = mmalloc;
328
329 rb_free = mm->rb_free;
330 rb_allocated = mm->rb_allocated;
331
332 RB_INIT(&mm->rb_free);
333 RB_INIT(&mm->rb_allocated);
334
335 mm_sync_list(&rb_free, &mm->rb_free, mm, mmold);
336 mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold);
337
338 mm_destroy(mmold);
339
340 *pmm = mm;
341 *pmmalloc = mmalloc;
342
343 debug3("%s: Share sync end", __func__);
344}
345
346void
347mm_memvalid(struct mm_master *mm, void *address, size_t size)
348{
349 void *end = (char *)address + size;
350
351 if (address < mm->address)
352 fatal("mm_memvalid: address too small: %p", address);
353 if (end < address)
354 fatal("mm_memvalid: end < address: %p < %p", end, address);
355 if (end > MM_ADDRESS_END(mm))
356 fatal("mm_memvalid: address too large: %p", address);
357}
diff --git a/monitor_mm.h b/monitor_mm.h
deleted file mode 100644
index f1fae7e3b..000000000
--- a/monitor_mm.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/* $OpenBSD: monitor_mm.h,v 1.6 2014/01/04 17:50:55 tedu Exp $ */
2
3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef _MM_H_
29#define _MM_H_
30
31struct mm_share {
32 RB_ENTRY(mm_share) next;
33 void *address;
34 size_t size;
35};
36
37struct mm_master {
38 RB_HEAD(mmtree, mm_share) rb_free;
39 struct mmtree rb_allocated;
40 void *address;
41 size_t size;
42
43 struct mm_master *mmalloc; /* Used to completely share */
44};
45
46RB_PROTOTYPE(mmtree, mm_share, next, mm_compare)
47
48#define MM_MINSIZE 128
49
50#define MM_ADDRESS_END(x) (void *)((char *)(x)->address + (x)->size)
51
52struct mm_master *mm_create(struct mm_master *, size_t);
53void mm_destroy(struct mm_master *);
54
55void mm_share_sync(struct mm_master **, struct mm_master **);
56
57void *mm_malloc(struct mm_master *, size_t);
58void *mm_xmalloc(struct mm_master *, size_t);
59void mm_free(struct mm_master *, void *);
60
61void mm_memvalid(struct mm_master *, void *, size_t);
62#endif /* _MM_H_ */
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 1bc76afff..db5902f55 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.h,v 1.31 2016/08/13 17:47:41 markus Exp $ */ 1/* $OpenBSD: monitor_wrap.h,v 1.32 2016/09/28 16:33:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -95,7 +95,4 @@ int mm_bsdauth_respond(void *, u_int, char **);
95int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); 95int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
96int mm_skey_respond(void *, u_int, char **); 96int mm_skey_respond(void *, u_int, char **);
97 97
98/* zlib allocation hooks */
99void mm_init_compression(struct mm_master *);
100
101#endif /* _MM_WRAP_H_ */ 98#endif /* _MM_WRAP_H_ */
diff --git a/myproposal.h b/myproposal.h
index 4729b30b0..072e36ec7 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: myproposal.h,v 1.53 2016/09/22 17:52:53 djm Exp $ */ 1/* $OpenBSD: myproposal.h,v 1.54 2016/09/28 16:33:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -167,7 +167,7 @@
167 167
168#endif /* WITH_OPENSSL */ 168#endif /* WITH_OPENSSL */
169 169
170#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" 170#define KEX_DEFAULT_COMP "none,zlib@openssh.com"
171#define KEX_DEFAULT_LANG "" 171#define KEX_DEFAULT_LANG ""
172 172
173#define KEX_CLIENT \ 173#define KEX_CLIENT \
diff --git a/opacket.h b/opacket.h
index 16322ec6f..d2a63a355 100644
--- a/opacket.h
+++ b/opacket.h
@@ -133,9 +133,6 @@ void packet_disconnect(const char *, ...)
133 ssh_packet_get_input(active_state) 133 ssh_packet_get_input(active_state)
134#define packet_get_output() \ 134#define packet_get_output() \
135 ssh_packet_get_output(active_state) 135 ssh_packet_get_output(active_state)
136#define packet_set_compress_hooks(ctx, allocfunc, freefunc) \
137 ssh_packet_set_compress_hooks(active_state, ctx, \
138 allocfunc, freefunc);
139#define packet_check_eom() \ 136#define packet_check_eom() \
140 ssh_packet_check_eom(active_state) 137 ssh_packet_check_eom(active_state)
141#define set_newkeys(mode) \ 138#define set_newkeys(mode) \
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);
diff --git a/packet.h b/packet.h
index 464d83b1a..690f2ec7e 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.h,v 1.71 2016/03/07 19:02:43 djm Exp $ */ 1/* $OpenBSD: packet.h,v 1.72 2016/09/28 16:33:07 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -120,11 +120,6 @@ void ssh_packet_send_debug(struct ssh *, const char *fmt, ...) __attribute__
120int ssh_set_newkeys(struct ssh *, int mode); 120int ssh_set_newkeys(struct ssh *, int mode);
121void ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *); 121void ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *);
122 122
123typedef void *(ssh_packet_comp_alloc_func)(void *, u_int, u_int);
124typedef void (ssh_packet_comp_free_func)(void *, void *);
125void ssh_packet_set_compress_hooks(struct ssh *, void *,
126 ssh_packet_comp_alloc_func *, ssh_packet_comp_free_func *);
127
128int ssh_packet_write_poll(struct ssh *); 123int ssh_packet_write_poll(struct ssh *);
129int ssh_packet_write_wait(struct ssh *); 124int ssh_packet_write_wait(struct ssh *);
130int ssh_packet_have_data_to_write(struct ssh *); 125int ssh_packet_have_data_to_write(struct ssh *);
diff --git a/servconf.c b/servconf.c
index acd903a88..51feb051f 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,5 +1,5 @@
1 1
2/* $OpenBSD: servconf.c,v 1.295 2016/08/25 23:57:54 djm Exp $ */ 2/* $OpenBSD: servconf.c,v 1.296 2016/09/28 16:33:07 djm Exp $ */
3/* 3/*
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved 5 * All rights reserved
@@ -921,7 +921,7 @@ static const struct multistate multistate_permitrootlogin[] = {
921}; 921};
922static const struct multistate multistate_compression[] = { 922static const struct multistate multistate_compression[] = {
923 { "delayed", COMP_DELAYED }, 923 { "delayed", COMP_DELAYED },
924 { "yes", COMP_ZLIB }, 924 { "yes", COMP_DELAYED },
925 { "no", COMP_NONE }, 925 { "no", COMP_NONE },
926 { NULL, -1 } 926 { NULL, -1 }
927}; 927};
diff --git a/sshconnect2.c b/sshconnect2.c
index 5e7d07dc5..a633e76cb 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.248 2016/09/22 02:29:57 dtucker Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.249 2016/09/28 16:33:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -174,7 +174,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
174 compat_cipher_proposal(options.ciphers); 174 compat_cipher_proposal(options.ciphers);
175 myproposal[PROPOSAL_COMP_ALGS_CTOS] = 175 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
176 myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ? 176 myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ?
177 "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib"; 177 "zlib@openssh.com,none" : "none,zlib@openssh.com";
178 myproposal[PROPOSAL_MAC_ALGS_CTOS] = 178 myproposal[PROPOSAL_MAC_ALGS_CTOS] =
179 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 179 myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
180 if (options.hostkeyalgorithms != NULL) { 180 if (options.hostkeyalgorithms != NULL) {
diff --git a/sshd.c b/sshd.c
index 6d182239b..816611c93 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshd.c,v 1.475 2016/08/28 22:28:12 djm Exp $ */ 1/* $OpenBSD: sshd.c,v 1.476 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
@@ -114,7 +114,6 @@
114#include "dispatch.h" 114#include "dispatch.h"
115#include "channels.h" 115#include "channels.h"
116#include "session.h" 116#include "session.h"
117#include "monitor_mm.h"
118#include "monitor.h" 117#include "monitor.h"
119#ifdef GSSAPI 118#ifdef GSSAPI
120#include "ssh-gss.h" 119#include "ssh-gss.h"
@@ -582,9 +581,6 @@ privsep_preauth(Authctxt *authctxt)
582 ssh_sandbox_parent_preauth(box, pid); 581 ssh_sandbox_parent_preauth(box, pid);
583 monitor_child_preauth(authctxt, pmonitor); 582 monitor_child_preauth(authctxt, pmonitor);
584 583
585 /* Sync memory */
586 monitor_sync(pmonitor);
587
588 /* Wait for the child's exit status */ 584 /* Wait for the child's exit status */
589 while (waitpid(pid, &status, 0) < 0) { 585 while (waitpid(pid, &status, 0) < 0) {
590 if (errno == EINTR) 586 if (errno == EINTR)
@@ -2152,10 +2148,6 @@ do_ssh2_kex(void)
2152 if (options.compression == COMP_NONE) { 2148 if (options.compression == COMP_NONE) {
2153 myproposal[PROPOSAL_COMP_ALGS_CTOS] = 2149 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
2154 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; 2150 myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
2155 } else if (options.compression == COMP_DELAYED) {
2156 myproposal[PROPOSAL_COMP_ALGS_CTOS] =
2157 myproposal[PROPOSAL_COMP_ALGS_STOC] =
2158 "none,zlib@openssh.com";
2159 } 2151 }
2160 2152
2161 if (options.rekey_limit || options.rekey_interval) 2153 if (options.rekey_limit || options.rekey_interval)