From f31c654b30a6f02ce0b8ea8ab81791b675489628 Mon Sep 17 00:00:00 2001 From: "dtucker@openbsd.org" Date: Thu, 22 Sep 2016 02:29:57 +0000 Subject: upstream commit If ssh receives a PACKET_DISCONNECT during userauth it will cause ssh_dispatch_run(DISPATCH_BLOCK, ...) to return without the session being authenticated. Check for this and exit if necessary. ok djm@ Upstream-ID: b3afe126c0839d2eae6cddd41ff2ba317eda0903 --- sshconnect2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sshconnect2.c') diff --git a/sshconnect2.c b/sshconnect2.c index fae8b0f2c..5e7d07dc5 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.247 2016/07/22 05:46:11 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.248 2016/09/22 02:29:57 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -404,6 +404,8 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, pubkey_cleanup(&authctxt); ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); + if (!authctxt.success) + fatal("Authentication failed."); debug("Authentication succeeded (%s).", authctxt.method->name); } -- cgit v1.2.3 From 0082fba4efdd492f765ed4c53f0d0fbd3bdbdf7f Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Wed, 28 Sep 2016 16:33:06 +0000 Subject: 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 --- Makefile.in | 2 +- monitor.c | 48 +------- monitor.h | 6 +- monitor_mm.c | 357 --------------------------------------------------------- monitor_mm.h | 62 ---------- monitor_wrap.h | 5 +- myproposal.h | 4 +- opacket.h | 3 - packet.c | 104 +---------------- packet.h | 7 +- servconf.c | 4 +- sshconnect2.c | 4 +- sshd.c | 10 +- 13 files changed, 18 insertions(+), 598 deletions(-) delete mode 100644 monitor_mm.c delete mode 100644 monitor_mm.h (limited to 'sshconnect2.c') 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 \ auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ - monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ + monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ 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 @@ -/* $OpenBSD: monitor.c,v 1.165 2016/09/05 13:57:31 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.166 2016/09/28 16:33:06 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -94,7 +94,6 @@ #include "misc.h" #include "servconf.h" #include "monitor.h" -#include "monitor_mm.h" #ifdef GSSAPI #include "ssh-gss.h" #endif @@ -411,31 +410,6 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_read(pmonitor, mon_dispatch, NULL); } -void -monitor_sync(struct monitor *pmonitor) -{ - if (options.compression) { - /* The member allocation is not visible, so sync it */ - mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); - } -} - -/* Allocation functions for zlib */ -static void * -mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) -{ - if (size == 0 || ncount == 0 || ncount > SIZE_MAX / size) - fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); - - return mm_malloc(mm, size * ncount); -} - -static void -mm_zfree(struct mm_master *mm, void *address) -{ - mm_free(mm, address); -} - static int monitor_read_log(struct monitor *pmonitor) { @@ -1632,13 +1606,6 @@ monitor_apply_keystate(struct monitor *pmonitor) kex->host_key_index=&get_hostkey_index; kex->sign = sshd_hostkey_sign; } - - /* Update with new address */ - if (options.compression) { - ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib, - (ssh_packet_comp_alloc_func *)mm_zalloc, - (ssh_packet_comp_free_func *)mm_zfree); - } } /* This function requries careful sanity checking */ @@ -1691,24 +1658,11 @@ monitor_openfds(struct monitor *mon, int do_logfds) struct monitor * monitor_init(void) { - struct ssh *ssh = active_state; /* XXX */ struct monitor *mon; mon = xcalloc(1, sizeof(*mon)); - monitor_openfds(mon, 1); - /* Used to share zlib space across processes */ - if (options.compression) { - mon->m_zback = mm_create(NULL, MM_MEMSIZE); - mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); - - /* Compression needs to share state across borders */ - ssh_packet_set_compress_hooks(ssh, mon->m_zlib, - (ssh_packet_comp_alloc_func *)mm_zalloc, - (ssh_packet_comp_free_func *)mm_zfree); - } - return mon; } diff --git a/monitor.h b/monitor.h index 93b8b66dd..d68f67458 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.19 2015/01/19 19:52:16 markus Exp $ */ +/* $OpenBSD: monitor.h,v 1.20 2016/09/28 16:33:07 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -67,21 +67,17 @@ enum monitor_reqtype { }; -struct mm_master; struct monitor { int m_recvfd; int m_sendfd; int m_log_recvfd; int m_log_sendfd; - struct mm_master *m_zback; - struct mm_master *m_zlib; struct kex **m_pkex; pid_t m_pid; }; struct monitor *monitor_init(void); void monitor_reinit(struct monitor *); -void monitor_sync(struct monitor *); struct Authctxt; void 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 @@ -/* $OpenBSD: monitor_mm.c,v 1.21 2015/02/06 23:21:59 millert Exp $ */ -/* - * Copyright 2002 Niels Provos - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" - -#include -#ifdef HAVE_SYS_MMAN_H -#include -#endif -#include "openbsd-compat/sys-tree.h" - -#include -#include -#include -#ifdef HAVE_STDINT_H -#include -#endif -#include -#include - -#include "xmalloc.h" -#include "ssh.h" -#include "log.h" -#include "monitor_mm.h" - -static int -mm_compare(struct mm_share *a, struct mm_share *b) -{ - ptrdiff_t diff = (char *)a->address - (char *)b->address; - - if (diff == 0) - return (0); - else if (diff < 0) - return (-1); - else - return (1); -} - -RB_GENERATE(mmtree, mm_share, next, mm_compare) - -static struct mm_share * -mm_make_entry(struct mm_master *mm, struct mmtree *head, - void *address, size_t size) -{ - struct mm_share *tmp, *tmp2; - - if (mm->mmalloc == NULL) - tmp = xcalloc(1, sizeof(struct mm_share)); - else - tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share)); - tmp->address = address; - tmp->size = size; - - tmp2 = RB_INSERT(mmtree, head, tmp); - if (tmp2 != NULL) - fatal("mm_make_entry(%p): double address %p->%p(%zu)", - mm, tmp2, address, size); - - return (tmp); -} - -/* Creates a shared memory area of a certain size */ - -struct mm_master * -mm_create(struct mm_master *mmalloc, size_t size) -{ - void *address; - struct mm_master *mm; - - if (mmalloc == NULL) - mm = xcalloc(1, sizeof(struct mm_master)); - else - mm = mm_xmalloc(mmalloc, sizeof(struct mm_master)); - - /* - * If the memory map has a mm_master it can be completely - * shared including authentication between the child - * and the client. - */ - mm->mmalloc = mmalloc; - - address = xmmap(size); - if (address == (void *)MAP_FAILED) - fatal("mmap(%zu): %s", size, strerror(errno)); - - mm->address = address; - mm->size = size; - - RB_INIT(&mm->rb_free); - RB_INIT(&mm->rb_allocated); - - mm_make_entry(mm, &mm->rb_free, address, size); - - return (mm); -} - -/* Frees either the allocated or the free list */ - -static void -mm_freelist(struct mm_master *mmalloc, struct mmtree *head) -{ - struct mm_share *mms, *next; - - for (mms = RB_ROOT(head); mms; mms = next) { - next = RB_NEXT(mmtree, head, mms); - RB_REMOVE(mmtree, head, mms); - if (mmalloc == NULL) - free(mms); - else - mm_free(mmalloc, mms); - } -} - -/* Destroys a memory mapped area */ - -void -mm_destroy(struct mm_master *mm) -{ - mm_freelist(mm->mmalloc, &mm->rb_free); - mm_freelist(mm->mmalloc, &mm->rb_allocated); - -#ifdef HAVE_MMAP - if (munmap(mm->address, mm->size) == -1) - fatal("munmap(%p, %zu): %s", mm->address, mm->size, - strerror(errno)); -#else - fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", - __func__); -#endif - if (mm->mmalloc == NULL) - free(mm); - else - mm_free(mm->mmalloc, mm); -} - -void * -mm_xmalloc(struct mm_master *mm, size_t size) -{ - void *address; - - address = mm_malloc(mm, size); - if (address == NULL) - fatal("%s: mm_malloc(%zu)", __func__, size); - memset(address, 0, size); - return (address); -} - - -/* Allocates data from a memory mapped area */ - -void * -mm_malloc(struct mm_master *mm, size_t size) -{ - struct mm_share *mms, *tmp; - - if (size == 0) - fatal("mm_malloc: try to allocate 0 space"); - if (size > SIZE_MAX - MM_MINSIZE + 1) - fatal("mm_malloc: size too big"); - - size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE; - - RB_FOREACH(mms, mmtree, &mm->rb_free) { - if (mms->size >= size) - break; - } - - if (mms == NULL) - return (NULL); - - /* Debug */ - memset(mms->address, 0xd0, size); - - tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size); - - /* Does not change order in RB tree */ - mms->size -= size; - mms->address = (char *)mms->address + size; - - if (mms->size == 0) { - RB_REMOVE(mmtree, &mm->rb_free, mms); - if (mm->mmalloc == NULL) - free(mms); - else - mm_free(mm->mmalloc, mms); - } - - return (tmp->address); -} - -/* Frees memory in a memory mapped area */ - -void -mm_free(struct mm_master *mm, void *address) -{ - struct mm_share *mms, *prev, tmp; - - tmp.address = address; - mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp); - if (mms == NULL) - fatal("mm_free(%p): can not find %p", mm, address); - - /* Debug */ - memset(mms->address, 0xd0, mms->size); - - /* Remove from allocated list and insert in free list */ - RB_REMOVE(mmtree, &mm->rb_allocated, mms); - if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL) - fatal("mm_free(%p): double address %p", mm, address); - - /* Find previous entry */ - prev = mms; - if (RB_LEFT(prev, next)) { - prev = RB_LEFT(prev, next); - while (RB_RIGHT(prev, next)) - prev = RB_RIGHT(prev, next); - } else { - if (RB_PARENT(prev, next) && - (prev == RB_RIGHT(RB_PARENT(prev, next), next))) - prev = RB_PARENT(prev, next); - else { - while (RB_PARENT(prev, next) && - (prev == RB_LEFT(RB_PARENT(prev, next), next))) - prev = RB_PARENT(prev, next); - prev = RB_PARENT(prev, next); - } - } - - /* Check if range does not overlap */ - if (prev != NULL && MM_ADDRESS_END(prev) > address) - fatal("mm_free: memory corruption: %p(%zu) > %p", - prev->address, prev->size, address); - - /* See if we can merge backwards */ - if (prev != NULL && MM_ADDRESS_END(prev) == address) { - prev->size += mms->size; - RB_REMOVE(mmtree, &mm->rb_free, mms); - if (mm->mmalloc == NULL) - free(mms); - else - mm_free(mm->mmalloc, mms); - } else - prev = mms; - - if (prev == NULL) - return; - - /* Check if we can merge forwards */ - mms = RB_NEXT(mmtree, &mm->rb_free, prev); - if (mms == NULL) - return; - - if (MM_ADDRESS_END(prev) > mms->address) - fatal("mm_free: memory corruption: %p < %p(%zu)", - mms->address, prev->address, prev->size); - if (MM_ADDRESS_END(prev) != mms->address) - return; - - prev->size += mms->size; - RB_REMOVE(mmtree, &mm->rb_free, mms); - - if (mm->mmalloc == NULL) - free(mms); - else - mm_free(mm->mmalloc, mms); -} - -static void -mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree, - struct mm_master *mm, struct mm_master *mmold) -{ - struct mm_master *mmalloc = mm->mmalloc; - struct mm_share *mms, *new; - - /* Sync free list */ - RB_FOREACH(mms, mmtree, oldtree) { - /* Check the values */ - mm_memvalid(mmold, mms, sizeof(struct mm_share)); - mm_memvalid(mm, mms->address, mms->size); - - new = mm_xmalloc(mmalloc, sizeof(struct mm_share)); - memcpy(new, mms, sizeof(struct mm_share)); - RB_INSERT(mmtree, newtree, new); - } -} - -void -mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc) -{ - struct mm_master *mm; - struct mm_master *mmalloc; - struct mm_master *mmold; - struct mmtree rb_free, rb_allocated; - - debug3("%s: Share sync", __func__); - - mm = *pmm; - mmold = mm->mmalloc; - mm_memvalid(mmold, mm, sizeof(*mm)); - - mmalloc = mm_create(NULL, mm->size); - mm = mm_xmalloc(mmalloc, sizeof(struct mm_master)); - memcpy(mm, *pmm, sizeof(struct mm_master)); - mm->mmalloc = mmalloc; - - rb_free = mm->rb_free; - rb_allocated = mm->rb_allocated; - - RB_INIT(&mm->rb_free); - RB_INIT(&mm->rb_allocated); - - mm_sync_list(&rb_free, &mm->rb_free, mm, mmold); - mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold); - - mm_destroy(mmold); - - *pmm = mm; - *pmmalloc = mmalloc; - - debug3("%s: Share sync end", __func__); -} - -void -mm_memvalid(struct mm_master *mm, void *address, size_t size) -{ - void *end = (char *)address + size; - - if (address < mm->address) - fatal("mm_memvalid: address too small: %p", address); - if (end < address) - fatal("mm_memvalid: end < address: %p < %p", end, address); - if (end > MM_ADDRESS_END(mm)) - fatal("mm_memvalid: address too large: %p", address); -} 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 @@ -/* $OpenBSD: monitor_mm.h,v 1.6 2014/01/04 17:50:55 tedu Exp $ */ - -/* - * Copyright 2002 Niels Provos - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MM_H_ -#define _MM_H_ - -struct mm_share { - RB_ENTRY(mm_share) next; - void *address; - size_t size; -}; - -struct mm_master { - RB_HEAD(mmtree, mm_share) rb_free; - struct mmtree rb_allocated; - void *address; - size_t size; - - struct mm_master *mmalloc; /* Used to completely share */ -}; - -RB_PROTOTYPE(mmtree, mm_share, next, mm_compare) - -#define MM_MINSIZE 128 - -#define MM_ADDRESS_END(x) (void *)((char *)(x)->address + (x)->size) - -struct mm_master *mm_create(struct mm_master *, size_t); -void mm_destroy(struct mm_master *); - -void mm_share_sync(struct mm_master **, struct mm_master **); - -void *mm_malloc(struct mm_master *, size_t); -void *mm_xmalloc(struct mm_master *, size_t); -void mm_free(struct mm_master *, void *); - -void mm_memvalid(struct mm_master *, void *, size_t); -#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 @@ -/* $OpenBSD: monitor_wrap.h,v 1.31 2016/08/13 17:47:41 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.32 2016/09/28 16:33:07 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -95,7 +95,4 @@ int mm_bsdauth_respond(void *, u_int, char **); int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); -/* zlib allocation hooks */ -void mm_init_compression(struct mm_master *); - #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 @@ -/* $OpenBSD: myproposal.h,v 1.53 2016/09/22 17:52:53 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.54 2016/09/28 16:33:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -167,7 +167,7 @@ #endif /* WITH_OPENSSL */ -#define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" +#define KEX_DEFAULT_COMP "none,zlib@openssh.com" #define KEX_DEFAULT_LANG "" #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 *, ...) ssh_packet_get_input(active_state) #define packet_get_output() \ ssh_packet_get_output(active_state) -#define packet_set_compress_hooks(ctx, allocfunc, freefunc) \ - ssh_packet_set_compress_hooks(active_state, ctx, \ - allocfunc, freefunc); #define packet_check_eom() \ ssh_packet_check_eom(active_state) #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 @@ -/* $OpenBSD: packet.c,v 1.238 2016/09/19 19:02:19 markus Exp $ */ +/* $OpenBSD: packet.c,v 1.239 2016/09/28 16:33:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -756,86 +756,6 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) /* NOTREACHED */ } -/* Serialise compression state into a blob for privsep */ -static int -ssh_packet_get_compress_state(struct sshbuf *m, struct ssh *ssh) -{ - struct session_state *state = ssh->state; - struct sshbuf *b; - int r; - - if ((b = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; - if (state->compression_in_started) { - if ((r = sshbuf_put_string(b, &state->compression_in_stream, - sizeof(state->compression_in_stream))) != 0) - goto out; - } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) - goto out; - if (state->compression_out_started) { - if ((r = sshbuf_put_string(b, &state->compression_out_stream, - sizeof(state->compression_out_stream))) != 0) - goto out; - } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) - goto out; - r = sshbuf_put_stringb(m, b); - out: - sshbuf_free(b); - return r; -} - -/* Deserialise compression state from a blob for privsep */ -static int -ssh_packet_set_compress_state(struct ssh *ssh, struct sshbuf *m) -{ - struct session_state *state = ssh->state; - struct sshbuf *b = NULL; - int r; - const u_char *inblob, *outblob; - size_t inl, outl; - - if ((r = sshbuf_froms(m, &b)) != 0) - goto out; - if ((r = sshbuf_get_string_direct(b, &inblob, &inl)) != 0 || - (r = sshbuf_get_string_direct(b, &outblob, &outl)) != 0) - goto out; - if (inl == 0) - state->compression_in_started = 0; - else if (inl != sizeof(state->compression_in_stream)) { - r = SSH_ERR_INTERNAL_ERROR; - goto out; - } else { - state->compression_in_started = 1; - memcpy(&state->compression_in_stream, inblob, inl); - } - if (outl == 0) - state->compression_out_started = 0; - else if (outl != sizeof(state->compression_out_stream)) { - r = SSH_ERR_INTERNAL_ERROR; - goto out; - } else { - state->compression_out_started = 1; - memcpy(&state->compression_out_stream, outblob, outl); - } - r = 0; - out: - sshbuf_free(b); - return r; -} - -void -ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx, - void *(*allocfunc)(void *, u_int, u_int), - void (*freefunc)(void *, void *)) -{ - ssh->state->compression_out_stream.zalloc = (alloc_func)allocfunc; - ssh->state->compression_out_stream.zfree = (free_func)freefunc; - ssh->state->compression_out_stream.opaque = ctx; - ssh->state->compression_in_stream.zalloc = (alloc_func)allocfunc; - ssh->state->compression_in_stream.zfree = (free_func)freefunc; - ssh->state->compression_in_stream.opaque = ctx; -} - /* * Causes any further packets to be encrypted using the given key. The same * key is used for both sending and reception. However, both directions are @@ -2450,21 +2370,14 @@ ssh_packet_get_output(struct ssh *ssh) static int ssh_packet_set_postauth(struct ssh *ssh) { - struct sshcomp *comp; - int r, mode; + int r; debug("%s: called", __func__); /* This was set in net child, but is not visible in user child */ ssh->state->after_authentication = 1; ssh->state->rekeying = 0; - for (mode = 0; mode < MODE_MAX; mode++) { - if (ssh->state->newkeys[mode] == NULL) - continue; - comp = &ssh->state->newkeys[mode]->comp; - if (comp && comp->enabled && - (r = ssh_packet_init_compression(ssh)) != 0) - return r; - } + if ((r = ssh_packet_enable_delayed_compress(ssh)) != 0) + return r; return 0; } @@ -2528,7 +2441,6 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) goto out; } if ((r = sshbuf_put_u32(b, comp->type)) != 0 || - (r = sshbuf_put_u32(b, comp->enabled)) != 0 || (r = sshbuf_put_cstring(b, comp->name)) != 0) goto out; r = sshbuf_put_stringb(m, b); @@ -2589,9 +2501,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) return r; if (cipher_get_keycontext(state->receive_context, p) != (int)rlen) return SSH_ERR_INTERNAL_ERROR; - - if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || - (r = sshbuf_put_stringb(m, state->input)) != 0 || + if ((r = sshbuf_put_stringb(m, state->input)) != 0 || (r = sshbuf_put_stringb(m, state->output)) != 0) return r; @@ -2645,7 +2555,6 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode) mac->key_len = maclen; } if ((r = sshbuf_get_u32(b, &comp->type)) != 0 || - (r = sshbuf_get_u32(b, (u_int *)&comp->enabled)) != 0 || (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0) goto out; if (enc->name == NULL || @@ -2773,8 +2682,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) cipher_set_keycontext(state->send_context, keyout); cipher_set_keycontext(state->receive_context, keyin); - if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || - (r = ssh_packet_set_postauth(ssh)) != 0) + if ((r = ssh_packet_set_postauth(ssh)) != 0) return r; 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 @@ -/* $OpenBSD: packet.h,v 1.71 2016/03/07 19:02:43 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.72 2016/09/28 16:33:07 djm Exp $ */ /* * Author: Tatu Ylonen @@ -120,11 +120,6 @@ void ssh_packet_send_debug(struct ssh *, const char *fmt, ...) __attribute__ int ssh_set_newkeys(struct ssh *, int mode); void ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *); -typedef void *(ssh_packet_comp_alloc_func)(void *, u_int, u_int); -typedef void (ssh_packet_comp_free_func)(void *, void *); -void ssh_packet_set_compress_hooks(struct ssh *, void *, - ssh_packet_comp_alloc_func *, ssh_packet_comp_free_func *); - int ssh_packet_write_poll(struct ssh *); int ssh_packet_write_wait(struct ssh *); int 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 @@ -/* $OpenBSD: servconf.c,v 1.295 2016/08/25 23:57:54 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.296 2016/09/28 16:33:07 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -921,7 +921,7 @@ static const struct multistate multistate_permitrootlogin[] = { }; static const struct multistate multistate_compression[] = { { "delayed", COMP_DELAYED }, - { "yes", COMP_ZLIB }, + { "yes", COMP_DELAYED }, { "no", COMP_NONE }, { NULL, -1 } }; diff --git a/sshconnect2.c b/sshconnect2.c index 5e7d07dc5..a633e76cb 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.248 2016/09/22 02:29:57 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.249 2016/09/28 16:33:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -174,7 +174,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) compat_cipher_proposal(options.ciphers); myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ? - "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib"; + "zlib@openssh.com,none" : "none,zlib@openssh.com"; myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; 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 @@ -/* $OpenBSD: sshd.c,v 1.475 2016/08/28 22:28:12 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.476 2016/09/28 16:33:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -114,7 +114,6 @@ #include "dispatch.h" #include "channels.h" #include "session.h" -#include "monitor_mm.h" #include "monitor.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -582,9 +581,6 @@ privsep_preauth(Authctxt *authctxt) ssh_sandbox_parent_preauth(box, pid); monitor_child_preauth(authctxt, pmonitor); - /* Sync memory */ - monitor_sync(pmonitor); - /* Wait for the child's exit status */ while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) @@ -2152,10 +2148,6 @@ do_ssh2_kex(void) if (options.compression == COMP_NONE) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; - } else if (options.compression == COMP_DELAYED) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = - "none,zlib@openssh.com"; } if (options.rekey_limit || options.rekey_interval) -- cgit v1.2.3 From 4577adead6a7d600c8e764619d99477a08192c8f Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Wed, 28 Sep 2016 20:32:42 +0000 Subject: upstream commit restore pre-auth compression support in the client -- the previous commit was intended to remove it from the server only. remove a few server-side pre-auth compression bits that escaped adjust wording of Compression directive in sshd_config(5) pointed out by naddy@ ok markus@ Upstream-ID: d23696ed72a228dacd4839dd9f2dec424ba2016b --- kex.c | 4 +--- kex.h | 5 ++--- packet.c | 7 +++---- servconf.c | 4 ++-- sshconnect2.c | 4 ++-- sshd_config.5 | 12 +++++++----- 6 files changed, 17 insertions(+), 19 deletions(-) (limited to 'sshconnect2.c') diff --git a/kex.c b/kex.c index 811e2cf6c..c122361f2 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.124 2016/09/22 17:52:53 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.125 2016/09/28 20:32:42 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -684,8 +684,6 @@ choose_comp(struct sshcomp *comp, char *client, char *server) return SSH_ERR_NO_COMPRESS_ALG_MATCH; if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; - } else if (strcmp(name, "zlib") == 0) { - comp->type = COMP_ZLIB; } else if (strcmp(name, "none") == 0) { comp->type = COMP_NONE; } else { diff --git a/kex.h b/kex.h index 382630660..318c41d4a 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.79 2016/09/22 21:15:41 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.80 2016/09/28 20:32:42 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -64,8 +64,7 @@ #define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org" #define COMP_NONE 0 -#define COMP_ZLIB 1 -#define COMP_DELAYED 2 +#define COMP_DELAYED 1 #define CURVE25519_SIZE 32 diff --git a/packet.c b/packet.c index 002e8d49a..337304bd0 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.239 2016/09/28 16:33:07 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.240 2016/09/28 20:32:42 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -965,9 +965,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode) /* explicit_bzero(enc->iv, enc->block_size); explicit_bzero(enc->key, enc->key_len); explicit_bzero(mac->key, mac->key_len); */ - if ((comp->type == COMP_ZLIB || - (comp->type == COMP_DELAYED && - state->after_authentication)) && comp->enabled == 0) { + if (comp->type == COMP_DELAYED && state->after_authentication && + comp->enabled == 0) { if ((r = ssh_packet_init_compression(ssh)) < 0) return r; if (mode == MODE_OUT) { diff --git a/servconf.c b/servconf.c index 51feb051f..4bf0b2a35 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.296 2016/09/28 16:33:07 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.297 2016/09/28 20:32:42 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -920,8 +920,8 @@ static const struct multistate multistate_permitrootlogin[] = { { NULL, -1 } }; static const struct multistate multistate_compression[] = { - { "delayed", COMP_DELAYED }, { "yes", COMP_DELAYED }, + { "delayed", COMP_DELAYED }, { "no", COMP_NONE }, { NULL, -1 } }; diff --git a/sshconnect2.c b/sshconnect2.c index a633e76cb..7a8b7ea97 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.249 2016/09/28 16:33:07 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.250 2016/09/28 20:32:42 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -174,7 +174,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) compat_cipher_proposal(options.ciphers); myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ? - "zlib@openssh.com,none" : "none,zlib@openssh.com"; + "zlib@openssh.com,zlib,none" : "none,zlib@openssh.com,zlib"; myproposal[PROPOSAL_MAC_ALGS_CTOS] = myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; if (options.hostkeyalgorithms != NULL) { diff --git a/sshd_config.5 b/sshd_config.5 index 59c9ea471..b5d361e1d 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.235 2016/09/22 19:19:01 jmc Exp $ -.Dd $Mdocdate: September 22 2016 $ +.\" $OpenBSD: sshd_config.5,v 1.236 2016/09/28 20:32:42 djm Exp $ +.Dd $Mdocdate: September 28 2016 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -529,15 +529,17 @@ channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client. .It Cm Compression -Specifies whether compression is allowed, or delayed until +Specifies whether compression is enabled after the user has authenticated successfully. The argument must be .Dq yes , -.Dq delayed , +.Dq delayed +(a legacy synonym for +.Dq yes ) or .Dq no . The default is -.Dq delayed . +.Dq yes . .It Cm DenyGroups This keyword can be followed by a list of group name patterns, separated by spaces. -- cgit v1.2.3 From b9844a45c7f0162fd1b5465683879793d4cc4aaa Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Sun, 4 Dec 2016 23:54:02 +0000 Subject: upstream commit Fix public key authentication when multiple authentication is in use. Instead of deleting and re-preparing the entire keys list, just reset the 'used' flags; the keys list is already in a good order (with already- tried keys at the back) Analysis and patch from Vincent Brillault on bz#2642; ok dtucker@ Upstream-ID: 7123f12dc2f3bcaae715853035a97923d7300176 --- sshconnect2.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'sshconnect2.c') diff --git a/sshconnect2.c b/sshconnect2.c index 7a8b7ea97..103a2b36a 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.250 2016/09/28 20:32:42 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.251 2016/12/04 23:54:02 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -318,6 +318,7 @@ void userauth(Authctxt *, char *); static int sign_and_send_pubkey(Authctxt *, Identity *); static void pubkey_prepare(Authctxt *); static void pubkey_cleanup(Authctxt *); +static void pubkey_reset(Authctxt *); static Key *load_identity_file(Identity *); static Authmethod *authmethod_get(char *authlist); @@ -560,8 +561,7 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt) if (partial != 0) { verbose("Authenticated with partial success."); /* reset state */ - pubkey_cleanup(authctxt); - pubkey_prepare(authctxt); + pubkey_reset(authctxt); } debug("Authentications that can continue: %s", authlist); @@ -1414,6 +1414,15 @@ pubkey_cleanup(Authctxt *authctxt) } } +static void +pubkey_reset(Authctxt *authctxt) +{ + Identity *id; + + TAILQ_FOREACH(id, &authctxt->keys, next) + id->tried = 0; +} + static int try_identity(Identity *id) { @@ -1462,6 +1471,7 @@ userauth_pubkey(Authctxt *authctxt) } key_free(id->key); id->key = NULL; + id->isprivate = 0; } } if (sent) -- cgit v1.2.3