Index: head/security/openssh-portable/Makefile =================================================================== --- head/security/openssh-portable/Makefile (revision 431697) +++ head/security/openssh-portable/Makefile (revision 431698) @@ -1,223 +1,223 @@ # Created by: dwcjr@inethouston.net # $FreeBSD$ PORTNAME= openssh -DISTVERSION= 7.3p1 -PORTREVISION= 5 +DISTVERSION= 7.4p1 +PORTREVISION= 0 PORTEPOCH= 1 CATEGORIES= security ipv6 MASTER_SITES= OPENBSD/OpenSSH/portable PKGNAMESUFFIX?= -portable MAINTAINER= bdrewery@FreeBSD.org COMMENT= The portable version of OpenBSD's OpenSSH #LICENSE= BSD2,BSD3,MIT,public domain,BSD-Style,BEER-WARE,"any purpose with notice intact",ISC-Style #LICENSE_FILE= ${WRKSRC}/LICENCE CONFLICTS?= openssh-3.* ssh-1.* ssh2-3.* openssh-portable-devel-* USES= alias ncurses USE_AUTOTOOLS= autoconf autoheader USE_OPENSSL= yes GNU_CONFIGURE= yes CONFIGURE_ENV= ac_cv_func_strnvis=no CONFIGURE_ARGS= --prefix=${PREFIX} --with-md5-passwords \ --without-zlib-version-check --with-ssl-engine ETCOLD= ${PREFIX}/etc OPTIONS_DEFINE= PAM TCP_WRAPPERS LIBEDIT BSM \ HPN X509 KERB_GSSAPI \ OVERWRITE_BASE SCTP LDNS NONECIPHER OPTIONS_DEFAULT= LIBEDIT PAM TCP_WRAPPERS HPN LDNS OPTIONS_RADIO= KERBEROS OPTIONS_RADIO_KERBEROS= MIT HEIMDAL HEIMDAL_BASE TCP_WRAPPERS_DESC= tcp_wrappers support BSM_DESC= OpenBSM Auditing KERB_GSSAPI_DESC= Kerberos/GSSAPI patch (req: GSSAPI) HPN_DESC= HPN-SSH patch LDNS_DESC= SSHFP/LDNS support X509_DESC= x509 certificate patch SCTP_DESC= SCTP support OVERWRITE_BASE_DESC= EOL, No longer supported. HEIMDAL_DESC= Heimdal Kerberos (security/heimdal) HEIMDAL_BASE_DESC= Heimdal Kerberos (base) MIT_DESC= MIT Kerberos (security/krb5) NONECIPHER_DESC= NONE Cipher support OPTIONS_SUB= yes TCP_WRAPPERS_EXTRA_PATCHES=${FILESDIR}/extra-patch-tcpwrappers LDNS_CONFIGURE_WITH= ldns LDNS_LIB_DEPENDS= libldns.so:dns/ldns LDNS_EXTRA_PATCHES= ${FILESDIR}/extra-patch-ldns LDNS_CFLAGS= -I${LOCALBASE}/include LDNS_CONFIGURE_ON= --with-ldflags='-L${LOCALBASE}/lib' # http://www.psc.edu/index.php/hpn-ssh HPN_CONFIGURE_WITH= hpn NONECIPHER_CONFIGURE_WITH= nonecipher # See http://www.roumenpetrov.info/openssh/ -X509_VERSION= 9.0 +X509_VERSION= 9.3 X509_PATCH_SITES= http://www.roumenpetrov.info/openssh/x509-${X509_VERSION}/:x509 -X509_PATCHFILES= ${PORTNAME}-7.3p1+x509-${X509_VERSION}.diff.gz:-p1:x509 +X509_EXTRA_PATCHES+= ${FILESDIR}/extra-patch-x509-glue +X509_PATCHFILES= ${PORTNAME}-7.4p1+x509-${X509_VERSION}.diff.gz:-p1:x509 # See https://bugzilla.mindrot.org/show_bug.cgi?id=2016 # and https://bugzilla.mindrot.org/show_bug.cgi?id=1604 #SCTP_PATCHFILES= ${PORTNAME}-7.2_p1-sctp.patch.gz:-p1 SCTP_CONFIGURE_WITH= sctp -#SCTP_BROKEN= does not apply to 7.3+ SCTP_EXTRA_PATCHES+= ${FILESDIR}/extra-patch-sctp:-p1 MIT_LIB_DEPENDS= libkrb5.so.3:security/krb5 HEIMDAL_LIB_DEPENDS= libkrb5.so.26:security/heimdal PAM_CONFIGURE_WITH= pam TCP_WRAPPERS_CONFIGURE_WITH= tcp-wrappers LIBEDIT_CONFIGURE_WITH= libedit LIBEDIT_USES= libedit BSM_CONFIGURE_ON= --with-audit=bsm ETCDIR?= ${PREFIX}/etc/ssh .include PATCH_SITES+= http://mirror.shatow.net/freebsd/${PORTNAME}/:DEFAULT,x509,hpn,gsskex # X509 patch includes TCP Wrapper support already .if ${PORT_OPTIONS:MX509} EXTRA_PATCHES:= ${EXTRA_PATCHES:N${TCP_WRAPPERS_EXTRA_PATCHES}} .endif # Must add this patch before HPN due to conflicts .if ${PORT_OPTIONS:MKERB_GSSAPI} -# 7.3 patch taken from -# http://sources.debian.net/data/main/o/openssh/1:7.1p2-2/debian/patches/gssapi.patch +# Patch from: +# http://sources.debian.net/data/main/o/openssh/1:7.4p1-5/debian/patches/gssapi.patch # which was originally based on 5.7 patch from # http://www.sxw.org.uk/computing/patches/ # It is mirrored simply to apply gzip -9. . if ${PORT_OPTIONS:MHPN} || ${PORT_OPTIONS:MNONECIPHER} # Needed glue for applying HPN patch without conflict EXTRA_PATCHES+= ${FILESDIR}/extra-patch-hpn-gss-glue . endif -PATCHFILES+= openssh-7.3p1-gsskex-all-20141021-debian-rh-20160808.patch.gz:-p1:gsskex +PATCHFILES+= openssh-7.4p1-gsskex-all-20141021-debian-rh-20161228.patch.gz:-p1:gsskex .endif # http://www.psc.edu/index.php/hpn-ssh https://github.com/rapier1/hpn-ssh https://github.com/rapier1/openssh-portable .if ${PORT_OPTIONS:MHPN} || ${PORT_OPTIONS:MNONECIPHER} PORTDOCS+= HPN-README HPN_VERSION= 14v5 HPN_DISTVERSION= 6.7p1 #PATCH_SITES+= SOURCEFORGE/hpnssh/HPN-SSH%20${HPN_VERSION}%20${HPN_DISTVERSION}/:hpn #PATCHFILES+= ${PORTNAME}-${HPN_DISTVERSION}-hpnssh${HPN_VERSION}.diff.gz:-p1:hpn EXTRA_PATCHES+= ${FILESDIR}/extra-patch-hpn:-p2 .endif CONFIGURE_LIBS+= -lutil CONFIGURE_ARGS+= --disable-utmp --disable-wtmp --disable-wtmpx --without-lastlog # Keep this last EXTRA_PATCHES+= ${FILESDIR}/extra-patch-version-addendum .if ${PORT_OPTIONS:MX509} . if ${PORT_OPTIONS:MHPN} || ${PORT_OPTIONS:MNONECIPHER} BROKEN= X509 patch and HPN patch do not apply cleanly together . endif . if ${PORT_OPTIONS:MSCTP} BROKEN= X509 patch and SCTP patch do not apply cleanly together . endif . if ${PORT_OPTIONS:MKERB_GSSAPI} BROKEN= X509 patch incompatible with KERB_GSSAPI patch . endif .endif .if ${PORT_OPTIONS:MHEIMDAL_BASE} && ${PORT_OPTIONS:MKERB_GSSAPI} BROKEN= KERB_GSSAPI Requires either MIT or HEMIDAL, does not build with base Heimdal currently .endif .if ${PORT_OPTIONS:MHEIMDAL_BASE} && !exists(/usr/lib/libkrb5.so) IGNORE= you have selected HEIMDAL_BASE but do not have heimdal installed in base .endif .if ${PORT_OPTIONS:MMIT} || ${PORT_OPTIONS:MHEIMDAL} || ${PORT_OPTIONS:MHEIMDAL_BASE} . if ${PORT_OPTIONS:MHEIMDAL_BASE} CONFIGURE_LIBS+= -lgssapi_krb5 CONFIGURE_ARGS+= --with-kerberos5=/usr . else CONFIGURE_ARGS+= --with-kerberos5=${LOCALBASE} . endif . if ${OPENSSLBASE} == "/usr" CONFIGURE_ARGS+= --without-rpath LDFLAGS= # empty . endif .else . if ${PORT_OPTIONS:MKERB_GSSAPI} IGNORE= KERB_GSSAPI requires one of MIT HEIMDAL or HEIMDAL_BASE . endif .endif .if ${OPENSSLBASE} != "/usr" CONFIGURE_ARGS+= --with-ssl-dir=${OPENSSLBASE} .endif EMPTYDIR= /var/empty .if ${PORT_OPTIONS:MOVERWRITE_BASE} || defined(OPENSSH_OVERWRITE_BASE) IGNORE= Overwrite base option is no longer supported. .endif USE_RC_SUBR= openssh # After all CONFIGURE_ARGS+= --sysconfdir=${ETCDIR} --with-privsep-path=${EMPTYDIR} .if !empty(CONFIGURE_LIBS) CONFIGURE_ARGS+= --with-libs='${CONFIGURE_LIBS}' .endif CONFIGURE_ARGS+= --with-xauth=${LOCALBASE}/bin/xauth RC_SCRIPT_NAME= openssh VERSION_ADDENDUM_DEFAULT?= ${OPSYS}-${PKGNAME} post-patch: @${REINPLACE_CMD} -e 's|-ldes|-lcrypto|g' ${WRKSRC}/configure @${REINPLACE_CMD} \ -e 's|install: \(.*\) host-key check-config|install: \1|g' \ ${WRKSRC}/Makefile.in @${REINPLACE_CMD} -e 's|%%PREFIX%%|${LOCALBASE}|' \ -e 's|%%RC_SCRIPT_NAME%%|${RC_SCRIPT_NAME}|' ${WRKSRC}/sshd.8 @${REINPLACE_CMD} \ -e 's|\(VersionAddendum\) none|\1 ${VERSION_ADDENDUM_DEFAULT}|' \ ${WRKSRC}/sshd_config @${REINPLACE_CMD} \ -e 's|%%SSH_VERSION_FREEBSD_PORT%%|${VERSION_ADDENDUM_DEFAULT}|' \ ${WRKSRC}/sshd_config.5 @${ECHO_CMD} '#define SSH_VERSION_FREEBSD_PORT "${VERSION_ADDENDUM_DEFAULT}"' >> \ ${WRKSRC}/version.h post-install: ${MV} ${STAGEDIR}${ETCDIR}/ssh_config \ ${STAGEDIR}${ETCDIR}//ssh_config.sample ${MV} ${STAGEDIR}${ETCDIR}/sshd_config \ ${STAGEDIR}${ETCDIR}/sshd_config.sample .if ${PORT_OPTIONS:MHPN} || ${PORT_OPTIONS:MNONECIPHER} ${MKDIR} ${STAGEDIR}${DOCSDIR} ${INSTALL_DATA} ${WRKSRC}/HPN-README ${STAGEDIR}${DOCSDIR} .endif test: build cd ${WRKSRC} && ${SETENV} -i \ OBJ=${WRKDIR} ${MAKE_ENV} \ TEST_SHELL=${SH} \ SUDO="${SUDO}" \ PATH=${WRKSRC}:${PREFIX}/bin:${PREFIX}/sbin:${PATH} \ ${MAKE_CMD} ${MAKE_FLAGS} ${MAKEFILE} ${MAKE_ARGS} tests .include Index: head/security/openssh-portable/distinfo =================================================================== --- head/security/openssh-portable/distinfo (revision 431697) +++ head/security/openssh-portable/distinfo (revision 431698) @@ -1,9 +1,9 @@ -TIMESTAMP = 1470675521 -SHA256 (openssh-7.3p1.tar.gz) = 3ffb989a6dcaa69594c3b550d4855a5a2e1718ccdde7f5e36387b424220fbecc -SIZE (openssh-7.3p1.tar.gz) = 1522617 +TIMESTAMP = 1484161900 +SHA256 (openssh-7.4p1.tar.gz) = 1b1fc4a14e2024293181924ed24872e6f2e06293f3e8926a376b8aec481f19d1 +SIZE (openssh-7.4p1.tar.gz) = 1511780 SHA256 (openssh-7.2_p1-sctp.patch.gz) = fb67e3e23f39fabf44ef198e3e19527417c75c9352747547448512032365dbfc SIZE (openssh-7.2_p1-sctp.patch.gz) = 8501 -SHA256 (openssh-7.3p1+x509-9.0.diff.gz) = ed468fe2e6220065b2bf3e2ed9eb0c7c8183f32f50fa50d64505d5feaef2d900 -SIZE (openssh-7.3p1+x509-9.0.diff.gz) = 571918 -SHA256 (openssh-7.3p1-gsskex-all-20141021-debian-rh-20160808.patch.gz) = 83698da23a7d4dd24be9bc15ea7e801890dfc9303815135552c8ddfd158f1a95 -SIZE (openssh-7.3p1-gsskex-all-20141021-debian-rh-20160808.patch.gz) = 26818 +SHA256 (openssh-7.4p1+x509-9.3.diff.gz) = 1d3fd23b3d02a3baad50890bf5498ef01af6dab6375da0aeb00a0d59fd3ac9ee +SIZE (openssh-7.4p1+x509-9.3.diff.gz) = 446572 +SHA256 (openssh-7.4p1-gsskex-all-20141021-debian-rh-20161228.patch.gz) = f77ac434e6914814bc2f16d1581efd74baedaa86f1249a3cee00566d458c5f6b +SIZE (openssh-7.4p1-gsskex-all-20141021-debian-rh-20161228.patch.gz) = 27091 Index: head/security/openssh-portable/files/patch-serverloop.c =================================================================== --- head/security/openssh-portable/files/patch-serverloop.c (revision 431697) +++ head/security/openssh-portable/files/patch-serverloop.c (nonexistent) @@ -1,23 +0,0 @@ -Fix CVE-2016-10010 - - ---- serverloop.c.orig 2016-07-27 17:54:27.000000000 -0500 -+++ serverloop.c 2017-01-11 18:44:42.881227000 -0600 -@@ -999,7 +999,7 @@ - - /* XXX fine grained permissions */ - if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && -- !no_port_forwarding_flag) { -+ !no_port_forwarding_flag && use_privsep) { - c = channel_connect_to_path(target, - "direct-streamlocal@openssh.com", "direct-streamlocal"); - } else { -@@ -1280,7 +1280,7 @@ - - /* check permissions */ - if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 -- || no_port_forwarding_flag) { -+ || no_port_forwarding_flag || !use_privsep) { - success = 0; - packet_send_debug("Server has disabled port forwarding."); - } else { Property changes on: head/security/openssh-portable/files/patch-serverloop.c ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -1 \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/security/openssh-portable/files/patch-kex.c =================================================================== --- head/security/openssh-portable/files/patch-kex.c (revision 431697) +++ head/security/openssh-portable/files/patch-kex.c (nonexistent) @@ -1,33 +0,0 @@ -From ec165c392ca54317dbe3064a8c200de6531e89ad Mon Sep 17 00:00:00 2001 -From: "markus@openbsd.org" -Date: Mon, 10 Oct 2016 19:28:48 +0000 -Subject: [PATCH] upstream commit - -Unregister the KEXINIT handler after message has been -received. Otherwise an unauthenticated peer can repeat the KEXINIT and cause -allocation of up to 128MB -- until the connection is closed. Reported by -shilei-c at 360.cn - -Upstream-ID: 43649ae12a27ef94290db16d1a98294588b75c05 ---- - kex.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git kex.c kex.c -index 3f97f8c..6a94bc5 100644 ---- kex.c -+++ kex.c -@@ -1,4 +1,4 @@ --/* $OpenBSD: kex.c,v 1.126 2016/09/28 21:44:52 djm Exp $ */ -+/* $OpenBSD: kex.c,v 1.127 2016/10/10 19:28:48 markus Exp $ */ - /* - * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. - * -@@ -481,6 +481,7 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt) - if (kex == NULL) - return SSH_ERR_INVALID_ARGUMENT; - -+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL); - ptr = sshpkt_ptr(ssh, &dlen); - if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) - return r; Property changes on: head/security/openssh-portable/files/patch-kex.c ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/security/openssh-portable/files/extra-patch-hpn =================================================================== --- head/security/openssh-portable/files/extra-patch-hpn (revision 431697) +++ head/security/openssh-portable/files/extra-patch-hpn (revision 431698) @@ -1,1290 +1,1290 @@ diff -urN -x configure -x config.guess -x config.h.in -x config.sub work.clean/openssh-6.8p1/HPN-README work/openssh-6.8p1/HPN-README --- work.clean/openssh-6.8p1/HPN-README 1969-12-31 18:00:00.000000000 -0600 +++ work/openssh-6.8p1/HPN-README 2015-04-01 22:16:49.869215000 -0500 @@ -0,0 +1,129 @@ +Notes: + +MULTI-THREADED CIPHER: +The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations +on hosts with multiple cores to use more than one processing core during encryption. +Tests have show significant throughput performance increases when using MTR-AES-CTR up +to and including a full gigabit per second on quad core systems. It should be possible to +achieve full line rate on dual core systems but OS and data management overhead makes this +more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single +thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal +performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. +The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same +nomenclature. +Use examples: ssh -caes128-ctr you@host.com + scp -oCipher=aes256-ctr file you@host.com:~/file + +NONE CIPHER: +To use the NONE option you must have the NoneEnabled switch set on the server and +you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE +feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not +spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will +be disabled. + +The performance increase will only be as good as the network and TCP stack tuning +on the reciever side of the connection allows. As a rule of thumb a user will need +at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The +HPN-SSH home page describes this in greater detail. + +http://www.psc.edu/networking/projects/hpn-ssh + +BUFFER SIZES: + +If HPN is disabled the receive buffer size will be set to the +OpenSSH default of 64K. + +If an HPN system connects to a nonHPN system the receive buffer will +be set to the HPNBufferSize value. The default is 2MB but user adjustable. + +If an HPN to HPN connection is established a number of different things might +happen based on the user options and conditions. + +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set +HPN Buffer Size = up to 64MB +This is the default state. The HPN buffer size will grow to a maximum of 64MB +as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is +geared towards 10GigE transcontinental connections. + +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set +HPN Buffer Size = TCP receive buffer value. +Users on non-autotuning systesm should disable TCPRcvBufPoll in the +ssh_cofig and sshd_config + +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set +HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. +This would be the system defined TCP receive buffer (RWIN). + +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. +Generally there is no need to set both. + +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set +HPN Buffer Size = grows to HPNBufferSize +The buffer will grow up to the maximum size specified here. + +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. +Generally there is no need to set both of these, especially on autotuning +systems. However, if the users wishes to override the autotuning this would be +one way to do it. + +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET +HPN Buffer Size = TCPRcvBuf. +This will override autotuning and set the TCP recieve buffer to the user defined +value. + + +HPN Specific Configuration options + +TcpRcvBuf=[int]KB client + set the TCP socket receive buffer to n Kilobytes. It can be set up to the +maximum socket size allowed by the system. This is useful in situations where +the tcp receive window is set low but the maximum buffer size is set +higher (as is typical). This works on a per TCP connection basis. You can also +use this to artifically limit the transfer rate of the connection. In these +cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. +Default is the current system wide tcp receive buffer size. + +TcpRcvBufPoll=[yes/no] client/server + enable of disable the polling of the tcp receive buffer through the life +of the connection. You would want to make sure that this option is enabled +for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) +default is yes. + +NoneEnabled=[yes/no] client/server + enable or disable the use of the None cipher. Care must always be used +when enabling this as it will allow users to send data in the clear. However, +it is important to note that authentication information remains encrypted +even if this option is enabled. Set to no by default. + +NoneSwitch=[yes/no] client + Switch the encryption cipher being used to the None cipher after +authentication takes place. NoneEnabled must be enabled on both the client +and server side of the connection. When the connection switches to the NONE +cipher a warning is sent to STDERR. The connection attempt will fail with an +error if a client requests a NoneSwitch from the server that does not explicitly +have NoneEnabled set to yes. Note: The NONE cipher cannot be used in +interactive (shell) sessions and it will fail silently. Set to no by default. + +HPNDisabled=[yes/no] client/server + In some situations, such as transfers on a local area network, the impact +of the HPN code produces a net decrease in performance. In these cases it is +helpful to disable the HPN functionality. By default HPNDisabled is set to no. + +HPNBufferSize=[int]KB client/server + This is the default buffer size the HPN functionality uses when interacting +with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf +option as applied to the internal SSH flow control. This value can range from +1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance +problems depending on the length of the network path. The default size of this buffer +is 2MB. + + +Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu) + The majority of the actual coding for versions up to HPN12v1 was performed + by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was + implemented by Ben Bennet (ben@psc.edu) and improved by Mike Tasota + (tasota@gmail.com) an NSF REU grant recipient for 2013. + This work was financed, in part, by Cisco System, Inc., the National + Library of Medicine, and the National Science Foundation. --- work.clean/openssh-6.8p1/channels.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/channels.c 2015-04-03 15:51:59.599537000 -0500 @@ -183,8 +183,14 @@ static int connect_next(struct channel_connect *); static void channel_connect_ctx_free(struct channel_connect *); + +#ifdef HPN_ENABLED +static int hpn_disabled = 0; +static int hpn_buffer_size = 2 * 1024 * 1024; +#endif + /* -- channel core */ Channel * channel_by_id(int id) { @@ -333,6 +339,9 @@ c->local_window_max = window; c->local_consumed = 0; c->local_maxpacket = maxpack; +#ifdef HPN_ENABLED + c->dynamic_window = 0; +#endif c->remote_id = -1; c->remote_name = xstrdup(remote_name); c->remote_window = 0; @@ -837,11 +846,41 @@ FD_SET(c->sock, writeset); } +#ifdef HPN_ENABLED +static u_int +channel_tcpwinsz(void) +{ + u_int32_t tcpwinsz = 0; + socklen_t optsz = sizeof(tcpwinsz); + int ret = -1; + + /* if we aren't on a socket return 128KB */ + if (!packet_connection_is_on_socket()) + return (128*1024); + ret = getsockopt(packet_get_connection_in(), + SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz); + /* return no more than SSHBUF_SIZE_MAX */ + if (ret == 0 && tcpwinsz > SSHBUF_SIZE_MAX) + tcpwinsz = SSHBUF_SIZE_MAX; + debug2("tcpwinsz: %d for connection: %d", tcpwinsz, + packet_get_connection_in()); + return (tcpwinsz); +} +#endif + static void channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) { u_int limit = compat20 ? c->remote_window : packet_get_maxsize(); +#ifdef HPN_ENABLED + /* check buffer limits */ + if (!c->tcpwinsz || c->dynamic_window > 0) + c->tcpwinsz = channel_tcpwinsz(); + + limit = MIN(limit, 2 * c->tcpwinsz); +#endif + if (c->istate == CHAN_INPUT_OPEN && limit > 0 && buffer_len(&c->input) < limit && @@ -1846,6 +1885,20 @@ c->local_maxpacket*3) || c->local_window < c->local_window_max/2) && c->local_consumed > 0) { +#ifdef HPN_ENABLED + /* adjust max window size if we are in a dynamic environment */ + if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) { + u_int addition = 0; + + /* + * grow the window somewhat aggressively to maintain + * pressure + */ + addition = 1.5*(c->tcpwinsz - c->local_window_max); + c->local_window_max += addition; + c->local_consumed += addition; + } +#endif packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); packet_put_int(c->remote_id); packet_put_int(c->local_consumed); @@ -2794,6 +2847,17 @@ return addr; } +#ifdef HPN_ENABLED +void +channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size) +{ + hpn_disabled = external_hpn_disabled; + hpn_buffer_size = external_hpn_buffer_size; + debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, + hpn_buffer_size); +} +#endif + static int channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd, int *allocated_listen_port, struct ForwardOptions *fwd_opts) @@ -2918,9 +2982,20 @@ } /* Allocate a channel number for the socket. */ +#ifdef HPN_ENABLED + /* + * explicitly test for hpn disabled option. if true use smaller + * window size. + */ + if (!hpn_disabled) + c = channel_new("port listener", type, sock, sock, -1, + hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, + 0, "port listener", 1); + else +#endif c = channel_new("port listener", type, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "port listener", 1); c->path = xstrdup(host); c->host_port = fwd->connect_port; c->listening_addr = addr == NULL ? NULL : xstrdup(addr); @@ -3952,6 +4027,14 @@ *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); for (n = 0; n < num_socks; n++) { sock = socks[n]; +#ifdef HPN_ENABLED + if (!hpn_disabled) + nc = channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, + 0, "X11 inet listener", 1); + else +#endif nc = channel_new("x11 listener", SSH_CHANNEL_X11_LISTENER, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, --- work.clean/openssh-6.8p1/channels.h 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/channels.h 2015-04-03 13:58:44.472717000 -0500 @@ -136,6 +136,10 @@ u_int local_maxpacket; int extended_usage; int single_connection; +#ifdef HPN_ENABLED + int dynamic_window; + u_int tcpwinsz; +#endif char *ctype; /* type */ @@ -311,4 +315,9 @@ void chan_write_failed(Channel *); void chan_obuf_empty(Channel *); +#ifdef HPN_ENABLED +/* hpn handler */ +void channel_set_hpn(int, int); +#endif + #endif --- work.clean/openssh-6.8p1/cipher.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/cipher.c 2015-04-03 16:22:04.972592000 -0500 @@ -244,7 +244,13 @@ for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; (p = strsep(&cp, CIPHER_SEP))) { c = cipher_by_name(p); - if (c == NULL || c->number != SSH_CIPHER_SSH2) { + if (c == NULL || (c->number != SSH_CIPHER_SSH2 && +#ifdef NONE_CIPHER_ENABLED + c->number != SSH_CIPHER_NONE +#else + 1 +#endif + )) { free(cipher_list); return 0; } @@ -545,6 +551,9 @@ switch (c->number) { #ifdef WITH_OPENSSL +#ifdef NONE_CIPHER_ENABLED + case SSH_CIPHER_NONE: +#endif case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: @@ -593,6 +602,9 @@ switch (c->number) { #ifdef WITH_OPENSSL +#ifdef NONE_CIPHER_ENABLED + case SSH_CIPHER_NONE: +#endif case SSH_CIPHER_SSH2: case SSH_CIPHER_DES: case SSH_CIPHER_BLOWFISH: --- work.clean/openssh-6.8p1/clientloop.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/clientloop.c 2015-04-03 17:29:40.618489000 -0500 @@ -1909,6 +1909,15 @@ sock = x11_connect_display(); if (sock < 0) return NULL; +#ifdef HPN_ENABLED + /* again is this really necessary for X11? */ + if (!options.hpn_disabled) + c = channel_new("x11", + SSH_CHANNEL_X11_OPEN, sock, sock, -1, + options.hpn_buffer_size, + CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); + else +#endif c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); @@ -1934,6 +1943,14 @@ __func__, ssh_err(r)); return NULL; } +#ifdef HPN_ENABLED + if (!options.hpn_disabled) + c = channel_new("authentication agent connection", + SSH_CHANNEL_OPEN, sock, sock, -1, + options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, + "authentication agent connection", 1); + else +#endif c = channel_new("authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, @@ -1964,6 +1981,12 @@ return -1; } +#ifdef HPN_ENABLED + if (!options.hpn_disabled) + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, + options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + else +#endif c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; --- work.clean/openssh-6.8p1/compat.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/compat.c 2015-04-03 16:39:57.665699000 -0500 @@ -177,6 +177,14 @@ debug("match: %s pat %s compat 0x%08x", version, check[i].pat, check[i].bugs); datafellows = check[i].bugs; /* XXX for now */ +#ifdef HPN_ENABLED + /* Check to see if the remote side is OpenSSH and not HPN */ + if (strstr(version,"OpenSSH") != NULL && + strstr(version,"hpn") == NULL) { + datafellows |= SSH_BUG_LARGEWINDOW; + debug("Remote is NON-HPN aware"); + } +#endif return check[i].bugs; } } --- work/openssh/compat.h.orig 2015-05-29 03:27:21.000000000 -0500 +++ work/openssh/compat.h 2015-06-02 09:55:04.208681000 -0500 @@ -62,6 +62,9 @@ #define SSH_BUG_CURVE25519PAD 0x10000000 #define SSH_BUG_HOSTKEYS 0x20000000 #define SSH_BUG_DHGEX_LARGE 0x40000000 +#ifdef HPN_ENABLED +#define SSH_BUG_LARGEWINDOW 0x80000000 +#endif void enable_compat13(void); void enable_compat20(void); --- work.clean/openssh-6.8p1/configure.ac 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/configure.ac 2015-04-03 16:36:28.916502000 -0500 @@ -4238,6 +4238,25 @@ ] ) # maildir +#check whether user wants HPN support +HPN_MSG="no" +AC_ARG_WITH(hpn, + [ --with-hpn Enable HPN support], + [ if test "x$withval" != "xno" ; then + AC_DEFINE(HPN_ENABLED,1,[Define if you want HPN support.]) + HPN_MSG="yes" + fi ] +) +#check whether user wants NONECIPHER support +NONECIPHER_MSG="no" +AC_ARG_WITH(nonecipher, + [ --with-nonecipher Enable NONECIPHER support], + [ if test "x$withval" != "xno" ; then + AC_DEFINE(NONE_CIPHER_ENABLED,1,[Define if you want NONECIPHER support.]) + NONECIPHER_MSG="yes" + fi ] +) + if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then AC_MSG_WARN([cross compiling: Disabling /dev/ptmx test]) disable_ptmx_check=yes @@ -4905,6 +4924,8 @@ echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" echo " Privsep sandbox style: $SANDBOX_STYLE" +echo " HPN support: $HPN_MSG" +echo " NONECIPHER support: $NONECIPHER_MSG" echo "" --- work.clean/openssh-7.2p1/kex.c.orig 2016-02-25 19:40:04.000000000 -0800 +++ work.clean/openssh-7.2p1/kex.c 2016-02-29 08:02:25.565288000 -0800 @@ -822,6 +822,20 @@ kex_choose_conf(struct ssh *ssh) peer[ncomp] = NULL; goto out; } +#ifdef NONE_CIPHER_ENABLED + debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name); + if (strcmp(newkeys->enc.name, "none") == 0) { + int auth_flag; + + auth_flag = ssh_packet_authentication_state(ssh); + debug("Requesting NONE. Authflag is %d", auth_flag); + if (auth_flag == 1) { + debug("None requested post authentication."); + } else { + fatal("Pre-authentication none cipher requests are not allowed."); + } + } +#endif debug("kex: %s cipher: %s MAC: %s compression: %s", ctos ? "client->server" : "server->client", newkeys->enc.name, --- work.clean/openssh-7.2p1/packet.c.orig 2016-02-25 19:40:04.000000000 -0800 +++ work.clean/openssh-7.2p1/packet.c 2016-02-29 08:05:15.744201000 -0800 @@ -1037,6 +1037,24 @@ ssh_set_newkeys(struct ssh *ssh, int mod return 0; } +#ifdef NONE_CIPHER_ENABLED +/* this supports the forced rekeying required for the NONE cipher */ +int rekey_requested = 0; +void +packet_request_rekeying(void) +{ + rekey_requested = 1; +} + +int +ssh_packet_authentication_state(struct ssh *ssh) +{ + struct session_state *state = ssh->state; + + return(state->after_authentication); +} +#endif + #define MAX_PACKETS (1U<<31) static int ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) @@ -1055,6 +1073,12 @@ ssh_packet_need_rekeying(struct ssh *ssh /* Peer can't rekey */ if (ssh->compat & SSH_BUG_NOREKEY) return 0; +#ifdef NONE_CIPHER_ENABLED + if (rekey_requested == 1) { + rekey_requested = 0; + return 1; + } +#endif /* * Permit one packet in or out per rekey - this allows us to --- work.clean/openssh-6.8p1/packet.h 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/packet.h 2015-04-03 16:10:34.728161000 -0500 @@ -188,6 +188,11 @@ int sshpkt_get_end(struct ssh *ssh); const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); +#ifdef NONE_CIPHER_ENABLED +void packet_request_rekeying(void); +int ssh_packet_authentication_state(struct ssh *ssh); +#endif + /* OLD API */ extern struct ssh *active_state; #include "opacket.h" --- work/openssh-6.9p1/readconf.c.orig 2015-07-27 13:32:13.169218000 -0500 +++ work/openssh-6.9p1/readconf.c 2015-07-27 13:33:00.429332000 -0500 @@ -153,6 +153,12 @@ typedef enum { oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, +#ifdef HPN_ENABLED + oHPNDisabled, oHPNBufferSize, oTcpRcvBufPoll, oTcpRcvBuf, +#endif +#ifdef NONE_CIPHER_ENABLED + oNoneSwitch, oNoneEnabled, +#endif oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, @@ -277,6 +283,16 @@ static struct { { "updatehostkeys", oUpdateHostkeys }, { "hostbasedkeytypes", oHostbasedKeyTypes }, { "pubkeyacceptedkeytypes", oPubkeyAcceptedKeyTypes }, +#ifdef NONE_CIPHER_ENABLED + { "noneenabled", oNoneEnabled }, + { "noneswitch", oNoneSwitch }, +#endif +#ifdef HPN_ENABLED + { "tcprcvbufpoll", oTcpRcvBufPoll }, + { "tcprcvbuf", oTcpRcvBuf }, + { "hpndisabled", oHPNDisabled }, + { "hpnbuffersize", oHPNBufferSize }, +#endif { "ignoreunknown", oIgnoreUnknown }, { NULL, oBadOption } @@ -906,6 +922,44 @@ parse_time: intptr = &options->check_host_ip; goto parse_flag; +#ifdef HPN_ENABLED + case oHPNDisabled: + intptr = &options->hpn_disabled; + goto parse_flag; + + case oHPNBufferSize: + intptr = &options->hpn_buffer_size; + goto parse_int; + + case oTcpRcvBufPoll: + intptr = &options->tcp_rcv_buf_poll; + goto parse_flag; + + case oTcpRcvBuf: + intptr = &options->tcp_rcv_buf; + goto parse_int; +#endif + +#ifdef NONE_CIPHER_ENABLED + case oNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; + + /* we check to see if the command comes from the */ + /* command line or not. If it does then enable it */ + /* otherwise fail. NONE should never be a default configuration */ + case oNoneSwitch: + if(strcmp(filename,"command-line") == 0) { + intptr = &options->none_switch; + goto parse_flag; + } else { + error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename); + error("Continuing..."); + debug("NoneSwitch directive found in %.200s.", filename); + return 0; + } +#endif + case oVerifyHostKeyDNS: intptr = &options->verify_host_key_dns; multistate_ptr = multistate_yesnoask; @@ -1665,6 +1719,16 @@ initialize_options(Options * options) options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->request_tty = -1; +#ifdef NONE_CIPHER_ENABLED + options->none_switch = -1; + options->none_enabled = -1; +#endif +#ifdef HPN_ENABLED + options->hpn_disabled = -1; + options->hpn_buffer_size = -1; + options->tcp_rcv_buf_poll = -1; + options->tcp_rcv_buf = -1; +#endif options->proxy_use_fdpass = -1; options->ignored_unknown = NULL; options->num_canonical_domains = 0; @@ -1826,6 +1890,35 @@ fill_default_options(Options * options) options->server_alive_interval = 0; if (options->server_alive_count_max == -1) options->server_alive_count_max = 3; +#ifdef NONE_CIPHER_ENABLED + if (options->none_switch == -1) + options->none_switch = 0; + if (options->none_enabled == -1) + options->none_enabled = 0; +#endif +#ifdef HPN_ENABLED + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; + if (options->hpn_buffer_size > -1) { + /* if a user tries to set the size to 0 set it to 1KB */ + if (options->hpn_buffer_size == 0) + options->hpn_buffer_size = 1; + /* limit the buffer to 64MB */ + if (options->hpn_buffer_size > 64*1024) { + options->hpn_buffer_size = 64*1024*1024; + debug("User requested buffer larger than 64MB. Request" + " reverted to 64MB"); + } else + options->hpn_buffer_size *= 1024; + debug("hpn_buffer_size set to %d", options->hpn_buffer_size); + } + if (options->tcp_rcv_buf == 0) + options->tcp_rcv_buf = 1; + if (options->tcp_rcv_buf > -1) + options->tcp_rcv_buf *=1024; + if (options->tcp_rcv_buf_poll == -1) + options->tcp_rcv_buf_poll = 1; +#endif if (options->control_master == -1) options->control_master = 0; if (options->control_persist == -1) { --- work.clean/openssh-6.8p1/readconf.h 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/readconf.h 2015-04-03 13:47:45.670125000 -0500 @@ -105,6 +105,16 @@ int clear_forwardings; int enable_ssh_keysign; +#ifdef NONE_CIPHER_ENABLED + int none_switch; /* Use none cipher */ + int none_enabled; /* Allow none to be used */ +#endif +#ifdef HPN_ENABLED + int tcp_rcv_buf; /* user switch to set tcp recv buffer */ + int tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */ + int hpn_disabled; /* Switch to disable HPN buffer management */ + int hpn_buffer_size; /* User definable size for HPN buffer window */ +#endif int64_t rekey_limit; int rekey_interval; int no_host_authentication_for_localhost; --- work.clean/openssh-6.8p1/scp.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/scp.c 2015-04-02 16:51:25.108407000 -0500 @@ -764,7 +764,7 @@ source(int argc, char **argv) off_t i, statbytes; size_t amt, nr; int fd = -1, haderr, indx; - char *last, *name, buf[2048], encname[PATH_MAX]; + char *last, *name, buf[16384], encname[PATH_MAX]; int len; for (indx = 0; indx < argc; ++indx) { @@ -932,7 +932,7 @@ sink(int argc, char **argv) off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; + char ch, *cp, *np, *targ, *why, *vect[1], buf[16384], visbuf[16384]; struct timeval tv[2]; #define atime tv[0] --- work/openssh/servconf.c.orig 2015-05-29 03:27:21.000000000 -0500 +++ work/openssh/servconf.c 2015-06-02 09:56:36.041601000 -0500 -@@ -163,6 +163,14 @@ initialize_server_options(ServerOptions +@@ -159,6 +159,14 @@ initialize_server_options(ServerOptions options->authorized_principals_file = NULL; options->authorized_principals_command = NULL; options->authorized_principals_command_user = NULL; +#ifdef NONE_CIPHER_ENABLED + options->none_enabled = -1; +#endif +#ifdef HPN_ENABLED + options->tcp_rcv_buf_poll = -1; + options->hpn_disabled = -1; + options->hpn_buffer_size = -1; +#endif options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; -@@ -329,6 +337,57 @@ fill_default_server_options(ServerOption +@@ -319,6 +327,57 @@ fill_default_server_options(ServerOption } if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; +#ifdef NONE_CIPHER_ENABLED + if (options->none_enabled == -1) + options->none_enabled = 0; +#endif +#ifdef HPN_ENABLED + if (options->hpn_disabled == -1) + options->hpn_disabled = 0; + + if (options->hpn_buffer_size == -1) { + /* + * option not explicitly set. Now we have to figure out + * what value to use. + */ + if (options->hpn_disabled == 1) { + options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; + } else { + int sock, socksize; + socklen_t socksizelen = sizeof(socksize); + + /* + * get the current RCV size and set it to that + * create a socket but don't connect it + * we use that the get the rcv socket size + */ + sock = socket(AF_INET, SOCK_STREAM, 0); + getsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + close(sock); + options->hpn_buffer_size = socksize; + debug ("HPN Buffer Size: %d", options->hpn_buffer_size); + } + } else { + /* + * we have to do this incase the user sets both values in a + * contradictory manner. hpn_disabled overrrides + * hpn_buffer_size + */ + if (options->hpn_disabled <= 0) { + if (options->hpn_buffer_size == 0) + options->hpn_buffer_size = 1; + /* limit the maximum buffer to 64MB */ + if (options->hpn_buffer_size > 64*1024) { + options->hpn_buffer_size = 64*1024*1024; + } else { + options->hpn_buffer_size *= 1024; + } + } else + options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT; + } +#endif + if (options->ip_qos_interactive == -1) options->ip_qos_interactive = IPTOS_LOWDELAY; if (options->ip_qos_bulk == -1) -@@ -406,6 +465,12 @@ typedef enum { +@@ -412,6 +471,12 @@ typedef enum { sUsePrivilegeSeparation, sAllowAgentForwarding, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, +#ifdef NONE_CIPHER_ENABLED + sNoneEnabled, +#endif +#ifdef HPN_ENABLED + sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize, +#endif sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, sKexAlgorithms, sIPQoS, sVersionAddendum, sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, -@@ -537,6 +602,14 @@ static struct { +@@ -548,6 +613,14 @@ static struct { { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, +#ifdef NONE_CIPHER_ENABLED + { "noneenabled", sNoneEnabled, SSHCFG_ALL }, +#endif +#ifdef HPN_ENABLED + { "hpndisabled", sHPNDisabled, SSHCFG_ALL }, + { "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL }, + { "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL }, +#endif { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, { "ipqos", sIPQoS, SSHCFG_ALL }, { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL }, -@@ -1156,6 +1229,25 @@ process_server_config_line(ServerOptions +@@ -1153,6 +1226,25 @@ process_server_config_line(ServerOptions intptr = &options->ignore_user_known_hosts; goto parse_flag; +#ifdef NONE_CIPHER_ENABLED + case sNoneEnabled: + intptr = &options->none_enabled; + goto parse_flag; +#endif +#ifdef HPN_ENABLED + case sTcpRcvBufPoll: + intptr = &options->tcp_rcv_buf_poll; + goto parse_flag; + + case sHPNDisabled: + intptr = &options->hpn_disabled; + goto parse_flag; + + case sHPNBufferSize: + intptr = &options->hpn_buffer_size; + goto parse_int; +#endif + - case sRhostsRSAAuthentication: - intptr = &options->rhosts_rsa_authentication; + case sHostbasedAuthentication: + intptr = &options->hostbased_authentication; goto parse_flag; --- work.clean/openssh-6.8p1/servconf.h 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/servconf.h 2015-04-03 13:48:37.316827000 -0500 @@ -169,6 +169,15 @@ int use_pam; /* Enable auth via PAM */ +#ifdef NONE_CIPHER_ENABLED + int none_enabled; /* enable NONE cipher switch */ +#endif +#ifdef HPN_ENABLED + int tcp_rcv_buf_poll; /* poll tcp rcv window in autotuning kernels*/ + int hpn_disabled; /* disable hpn functionality. false by default */ + int hpn_buffer_size; /* set the hpn buffer size - default 3MB */ +#endif + int permit_tun; int num_permitted_opens; --- work.clean/openssh-6.8p1/serverloop.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/serverloop.c 2015-04-03 17:14:15.182548000 -0500 -@@ -1051,6 +1051,12 @@ +@@ -526,6 +526,12 @@ server_request_tun(void) sock = tun_open(tun, mode); if (sock < 0) goto done; +#ifdef HPN_ENABLED + if (!options.hpn_disabled) + c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, + options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + else +#endif c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; -@@ -1088,6 +1094,10 @@ +@@ -563,6 +569,10 @@ server_request_session(void) c = channel_new("session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); +#ifdef HPN_ENABLED + if (options.tcp_rcv_buf_poll && !options.hpn_disabled) + c->dynamic_window = 1; +#endif if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); --- work.clean/openssh-6.8p1/session.c 2015-04-01 22:07:18.149110000 -0500 +++ work/openssh-6.8p1/session.c 2015-04-03 17:09:02.984097000 -0500 @@ -2340,6 +2340,14 @@ */ if (s->chanid == -1) fatal("no channel for session %d", s->self); +#ifdef HPN_ENABLED + if (!options.hpn_disabled) + channel_set_fds(s->chanid, + fdout, fdin, fderr, + ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, + 1, is_tty, options.hpn_buffer_size); + else +#endif channel_set_fds(s->chanid, fdout, fdin, fderr, ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, --- work.clean/openssh-6.8p1/sftp.1 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/sftp.1 2015-04-01 22:16:49.921688000 -0500 @@ -263,7 +263,8 @@ Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. -The default is 64 outstanding requests. +The default is 256 outstanding requests providing for 8MB +of outstanding data with a 32KB buffer. .It Fl r Recursively copy entire directories when uploading and downloading. Note that --- work.clean/openssh-6.8p1/sftp.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/sftp.c 2015-04-03 17:16:00.959795000 -0500 @@ -71,7 +71,11 @@ #include "sftp-client.h" #define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */ +#ifdef HPN_ENABLED +#define DEFAULT_NUM_REQUESTS 256 /* # concurrent outstanding requests */ +#else #define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */ +#endif /* File to read commands from */ FILE* infile; --- work.clean/openssh-6.8p1/ssh.c 2015-04-01 22:07:18.166356000 -0500 +++ work/openssh-6.8p1/ssh.c 2015-04-03 17:16:34.114673000 -0500 @@ -885,6 +885,14 @@ break; case 'T': options.request_tty = REQUEST_TTY_NO; +#ifdef NONE_CIPHER_ENABLED + /* + * ensure that the user doesn't try to backdoor a + * null cipher switch on an interactive session + * so explicitly disable it no matter what. + */ + options.none_switch = 0; +#endif break; case 'o': line = xstrdup(optarg); @@ -1848,9 +1856,85 @@ if (!isatty(err)) set_nonblock(err); +#ifdef HPN_ENABLED + /* + * we need to check to see if what they want to do about buffer + * sizes here. In a hpn to nonhpn connection we want to limit + * the window size to something reasonable in case the far side + * has the large window bug. In hpn to hpn connection we want to + * use the max window size but allow the user to override it + * lastly if they disabled hpn then use the ssh std window size + + * so why don't we just do a getsockopt() here and set the + * ssh window to that? In the case of a autotuning receive + * window the window would get stuck at the initial buffer + * size generally less than 96k. Therefore we need to set the + * maximum ssh window size to the maximum hpn buffer size + * unless the user has specifically set the tcprcvbufpoll + * to no. In which case we *can* just set the window to the + * minimum of the hpn buffer size and tcp receive buffer size + */ + + if (tty_flag) + options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT; + else + options.hpn_buffer_size = 2*1024*1024; + + if (datafellows & SSH_BUG_LARGEWINDOW) { + debug("HPN to Non-HPN Connection"); + } else { + int sock, socksize; + socklen_t socksizelen = sizeof(socksize); + + if (options.tcp_rcv_buf_poll <= 0) { + sock = socket(AF_INET, SOCK_STREAM, 0); + getsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + close(sock); + debug("socksize %d", socksize); + options.hpn_buffer_size = socksize; + debug ("HPNBufferSize set to TCP RWIN: %d", + options.hpn_buffer_size); + } else { + if (options.tcp_rcv_buf > 0) { + /* + * create a socket but don't connect it. + * we use that the get the rcv socket size + */ + sock = socket(AF_INET, SOCK_STREAM, 0); + /* + * if they are using the tcp_rcv_buf option + * attempt to set the buffer size to that + */ + if (options.tcp_rcv_buf) + setsockopt(sock, SOL_SOCKET, SO_RCVBUF, + (void *)&options.tcp_rcv_buf, + sizeof(options.tcp_rcv_buf)); + getsockopt(sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + close(sock); + debug("socksize %d", socksize); + options.hpn_buffer_size = socksize; + debug ("HPNBufferSize set to user TCPRcvBuf: " + "%d", options.hpn_buffer_size); + } + } + } + + debug("Final hpn_buffer_size = %d", options.hpn_buffer_size); + + window = options.hpn_buffer_size; + + channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); +#else window = CHAN_SES_WINDOW_DEFAULT; +#endif + packetmax = CHAN_SES_PACKET_DEFAULT; if (tty_flag) { +#ifdef HPN_ENABLED + window = CHAN_SES_WINDOW_DEFAULT; +#endif window >>= 1; packetmax >>= 1; } @@ -1859,6 +1943,12 @@ window, packetmax, CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); +#ifdef HPN_ENABLED + if (options.tcp_rcv_buf_poll > 0 && !options.hpn_disabled) { + c->dynamic_window = 1; + debug ("Enabled Dynamic Window Scaling"); + } +#endif debug3("ssh_session2_open: channel_new: %d", c->self); channel_send_open(c->self); --- work.clean/openssh-6.8p1/sshconnect.c 2015-03-17 00:49:20.000000000 -0500 +++ work/openssh-6.8p1/sshconnect.c 2015-04-03 16:32:38.204744000 -0500 @@ -266,6 +266,31 @@ kill(proxy_command_pid, SIGHUP); } +#ifdef HPN_ENABLED +/* + * Set TCP receive buffer if requested. + * Note: tuning needs to happen after the socket is + * created but before the connection happens + * so winscale is negotiated properly -cjr + */ +static void +ssh_set_socket_recvbuf(int sock) +{ + void *buf = (void *)&options.tcp_rcv_buf; + int sz = sizeof(options.tcp_rcv_buf); + int socksize; + socklen_t socksizelen = sizeof(socksize); + + debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf); + if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) { + getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen); + debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize); + } else + error("Couldn't set socket receive buffer to %d: %.100s", + options.tcp_rcv_buf, strerror(errno)); +} +#endif + /* * Creates a (possibly privileged) socket for use as the ssh connection. */ @@ -282,6 +307,11 @@ } fcntl(sock, F_SETFD, FD_CLOEXEC); +#ifdef HPN_ENABLED + if (options.tcp_rcv_buf > 0) + ssh_set_socket_recvbuf(sock); +#endif + /* Bind the socket to an alternative local IP address */ if (options.bind_address == NULL && !privileged) return sock; @@ -523,11 +553,23 @@ send_client_banner(int connection_out, i { /* Send our own protocol version identification. */ if (compat20) { - xasprintf(&client_version_string, "SSH-%d.%d-%.100s\r\n", - PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION); + xasprintf(&client_version_string, "SSH-%d.%d-%.100s%s\r\n", + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, +#ifdef HPN_ENABLED + options.hpn_disabled ? "" : SSH_HPN +#else + "" +#endif + ); } else { - xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", - PROTOCOL_MAJOR_1, minor1, SSH_VERSION); + xasprintf(&client_version_string, "SSH-%d.%d-%.100s%s\n", + PROTOCOL_MAJOR_1, minor1, SSH_VERSION, +#ifdef HPN_ENABLED + options.hpn_disabled ? "" : SSH_HPN +#else + "" +#endif + ); } if (roaming_atomicio(vwrite, connection_out, client_version_string, strlen(client_version_string)) != strlen(client_version_string)) --- work.clean/openssh-7.2p1/sshconnect2.c.orig 2016-02-25 19:40:04.000000000 -0800 +++ work.clean/openssh-7.2p1/sshconnect2.c 2016-02-29 08:06:31.134954000 -0800 -@@ -80,6 +80,14 @@ +@@ -81,6 +81,14 @@ extern char *client_version_string; extern char *server_version_string; extern Options options; +#ifdef NONE_CIPHER_ENABLED +struct kex *xxx_kex; + +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */ +/* if it is set then prevent the switch to the null cipher */ + +extern int tty_flag; +#endif /* * SSH2 key exchange -@@ -153,14 +161,17 @@ order_hostkeyalgs(char *host, struct soc +@@ -154,14 +162,17 @@ order_hostkeyalgs(char *host, struct soc return ret; } +static char *myproposal[PROPOSAL_MAX]; +static const char *myproposal_default[PROPOSAL_MAX] = { KEX_CLIENT }; void ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { - char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; char *s; struct kex *kex; int r; + memcpy(&myproposal, &myproposal_default, sizeof(myproposal)); + xxx_host = host; xxx_hostaddr = hostaddr; @@ -235,6 +246,9 @@ ssh_kex2(char *host, struct sockaddr *ho packet_send(); packet_write_wait(); #endif +#ifdef NONE_CIPHER_ENABLED + xxx_kex = kex; +#endif } /* -@@ -404,6 +418,29 @@ ssh_userauth2(const char *local_user, co - pubkey_cleanup(&authctxt); - ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); +@@ -407,6 +421,29 @@ ssh_userauth2(const char *local_user, co + if (!authctxt.success) + fatal("Authentication failed."); +#ifdef NONE_CIPHER_ENABLED + /* + * if the user wants to use the none cipher do it + * post authentication and only if the right conditions are met + * both of the NONE commands must be true and there must be no + * tty allocated. + */ + if ((options.none_switch == 1) && (options.none_enabled == 1)) { + if (!tty_flag) { /* no null on tty sessions */ + debug("Requesting none rekeying..."); + myproposal[PROPOSAL_ENC_ALGS_STOC] = "none"; + myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none"; + kex_prop2buf(xxx_kex->my, myproposal); + packet_request_rekeying(); + fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n"); + } else { + /* requested NONE cipher when in a tty */ + debug("Cannot switch to NONE cipher with tty allocated"); + fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n"); + } + } +#endif + debug("Authentication succeeded (%s).", authctxt.method->name); } --- work.clean/openssh-7.1p1/sshd.c.orig 2015-08-20 21:49:03.000000000 -0700 +++ work.clean/openssh-7.1p1/sshd.c 2015-11-11 12:45:48.202186000 -0800 -@@ -431,8 +431,13 @@ sshd_exchange_identification(int sock_in - minor = PROTOCOL_MINOR_1; - } +@@ -373,8 +373,13 @@ sshd_exchange_identification(struct ssh + char buf[256]; /* Must not be larger than remote_version. */ + char remote_version[256]; /* Must be at least as big as buf. */ - xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s", + xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s%s%s", - major, minor, SSH_VERSION, + PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, +#ifdef HPN_ENABLED + options.hpn_disabled ? "" : SSH_HPN, +#else + "", +#endif *options.version_addendum == '\0' ? "" : " ", options.version_addendum, newline); -@@ -1155,6 +1160,10 @@ server_listen(void) +@@ -1027,6 +1032,10 @@ server_listen(void) int ret, listen_sock, on = 1; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; +#ifdef HPN_ENABLED + int socksize; + socklen_t socksizelen = sizeof(socksize); +#endif for (ai = options.listen_addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) -@@ -1195,6 +1204,13 @@ server_listen(void) +@@ -1067,6 +1076,13 @@ server_listen(void) debug("Bind to port %s on %s.", strport, ntop); +#ifdef HPN_ENABLED + getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, + &socksize, &socksizelen); + debug("Server TCP RWIN socket size: %d", socksize); + debug("HPN Buffer Size: %d", options.hpn_buffer_size); +#endif + /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { error("Bind to port %s on %s failed: %.200s.", -@@ -1693,6 +1709,15 @@ main(int ac, char **av) +@@ -1591,6 +1607,15 @@ main(int ac, char **av) /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); +#ifdef NONE_CIPHER_ENABLED + if (options.none_enabled == 1) { + char *old_ciphers = options.ciphers; + + xasprintf(&options.ciphers, "%s,none", old_ciphers); + free(old_ciphers); + } +#endif + /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; -@@ -2123,6 +2148,11 @@ main(int ac, char **av) - cleanup_exit(255); +@@ -2085,6 +2110,11 @@ main(int ac, char **av) } + #endif +#ifdef HPN_ENABLED + /* set the HPN options for the child */ + channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size); +#endif + /* - * We use get_canonical_hostname with usedns = 0 instead of - * get_remote_ipaddr here so IP options will be checked. -@@ -2539,6 +2569,11 @@ do_ssh2_kex(void) + * In privilege separation, we fork another child and prepare + * file descriptor passing. +@@ -2163,6 +2193,11 @@ do_ssh2_kex(void) struct kex *kex; int r; +#ifdef NONE_CIPHER_ENABLED + if (options.none_enabled == 1) + debug ("WARNING: None cipher enabled"); +#endif + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( options.kex_algorithms); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal( --- work.clean/openssh-6.8p1/sshd_config 2015-04-01 22:07:18.248858000 -0500 +++ work/openssh-6.8p1/sshd_config 2015-04-01 22:16:49.932279000 -0500 -@@ -127,6 +127,20 @@ +@@ -111,6 +111,20 @@ AuthorizedKeysFile .ssh/authorized_keys # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server +# the following are HPN related configuration options +# tcp receive buffer polling. disable in non autotuning kernels +#TcpRcvBufPoll yes + +# disable hpn performance boosts +#HPNDisabled no + +# buffer size for hpn to non-hpn connections +#HPNBufferSize 2048 + + +# allow the use of the none cipher +#NoneEnabled no + # Example of overriding settings on a per-user basis #Match User anoncvs # X11Forwarding no --- work.clean/openssh-6.8p1/version.h 2015-04-01 22:07:18.258955000 -0500 +++ work/openssh-6.8p1/version.h 2015-04-02 16:51:25.209617000 -0500 @@ -3,4 +3,5 @@ #define SSH_VERSION "OpenSSH_6.8" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE +#define SSH_HPN "-hpn14v5" Index: head/security/openssh-portable/files/extra-patch-ldns =================================================================== --- head/security/openssh-portable/files/extra-patch-ldns (revision 431697) +++ head/security/openssh-portable/files/extra-patch-ldns (revision 431698) @@ -1,51 +1,51 @@ r255461 | des | 2013-09-10 17:30:22 -0500 (Tue, 10 Sep 2013) | 7 lines Changed paths: M /head/crypto/openssh/readconf.c M /head/crypto/openssh/ssh_config M /head/crypto/openssh/ssh_config.5 Change the default value of VerifyHostKeyDNS to "yes" if compiled with LDNS. With that setting, OpenSSH will silently accept host keys that match verified SSHFP records. If an SSHFP record exists but could not be verified, OpenSSH will print a message and prompt the user as usual. --- readconf.c 2013-10-03 08:15:03.496131082 -0500 +++ readconf.c 2013-10-03 08:15:22.716134315 -0500 @@ -1414,8 +1414,14 @@ fill_default_options(Options * options) options->rekey_limit = 0; if (options->rekey_interval == -1) options->rekey_interval = 0; +#if HAVE_LDNS + if (options->verify_host_key_dns == -1) + /* automatically trust a verified SSHFP record */ + options->verify_host_key_dns = 1; +#else if (options->verify_host_key_dns == -1) options->verify_host_key_dns = 0; +#endif if (options->server_alive_interval == -1) options->server_alive_interval = 0; if (options->server_alive_count_max == -1) --- ssh_config 2013-10-03 08:15:03.537131330 -0500 +++ ssh_config 2013-10-03 08:15:22.755131175 -0500 @@ -44,5 +44,6 @@ # TunnelDevice any:any # PermitLocalCommand no # VisualHostKey no +# VerifyHostKeyDNS yes # ProxyCommand ssh -q -W %h:%p gateway.example.com # RekeyLimit 1G 1h ---- ssh_config.5.orig 2016-02-25 19:40:04.000000000 -0800 -+++ ssh_config.5 2016-02-29 07:57:41.763889000 -0800 -@@ -1715,7 +1715,10 @@ - or - .Dq ask . +--- ssh_config.5.orig 2016-12-18 20:59:41.000000000 -0800 ++++ ssh_config.5 2017-01-11 11:24:25.573200000 -0800 +@@ -1635,7 +1635,10 @@ need to confirm new host keys according + .Cm StrictHostKeyChecking + option. The default is --.Dq no . -+.Dq yes +-.Cm no . ++.Cm yes +if compiled with LDNS and -+.Dq no ++.Cm no +otherwise. .Pp - See also VERIFYING HOST KEYS in - .Xr ssh 1 . + See also + .Sx VERIFYING HOST KEYS Index: head/security/openssh-portable/files/extra-patch-sctp =================================================================== --- head/security/openssh-portable/files/extra-patch-sctp (revision 431697) +++ head/security/openssh-portable/files/extra-patch-sctp (revision 431698) @@ -1,873 +1,873 @@ From 9ee55407a8a0fbaa0be5b5a70c6907f7a3fd061f Mon Sep 17 00:00:00 2001 From: rse Date: Thu, 19 Mar 2015 20:08:09 -0400 Subject: [PATCH] add sctp support https://bugzilla.mindrot.org/show_bug.cgi?id=1604 https://bugzilla.mindrot.org/show_bug.cgi?id=2016 People who have helped out: Jan F. Chadima rse Joshua Kinard Mike Frysinger --- configure.ac | 14 ++++++ misc.c | 39 +++++++++++++--- readconf.c | 23 ++++++++++ readconf.h | 5 +++ scp.1 | 5 ++- scp.c | 7 +++ servconf.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++ servconf.h | 8 ++++ ssh.1 | 5 ++- ssh.c | 14 +++++- ssh_config.5 | 6 +++ sshconnect.c | 55 +++++++++++++++++++++++ sshd.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- sshd_config.5 | 11 +++++ 14 files changed, 445 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 7258cc0..2cb034b 100644 --- a/configure.ac +++ b/configure.ac @@ -4054,6 +4054,19 @@ AC_ARG_WITH([selinux], AC_SUBST([SSHLIBS]) AC_SUBST([SSHDLIBS]) +#check whether user wants SCTP support +SCTP_MSG="no" +AC_ARG_WITH(sctp, + [ --with-sctp Enable SCTP support], + [ if test "x$withval" != "xno" ; then + AC_DEFINE(SCTP,1,[Define if you want SCTP support.]) + AC_CHECK_FUNCS(sctp_recvmsg, , AC_CHECK_LIB(sctp, sctp_recvmsg, , + [AC_MSG_ERROR([*** Can not use SCTP - maybe libsctp-dev is missing ***])] + )) + SCTP_MSG="yes" + fi ] +) + # Check whether user wants Kerberos 5 support KRB5_MSG="no" AC_ARG_WITH([kerberos5], @@ -4977,6 +4990,7 @@ echo " PAM support: $PAM_MSG" echo " OSF SIA support: $SIA_MSG" echo " KerberosV support: $KRB5_MSG" echo " SELinux support: $SELINUX_MSG" +echo " SCTP support: $SCTP_MSG" echo " Smartcard support: $SCARD_MSG" echo " S/KEY support: $SKEY_MSG" echo " MD5 password support: $MD5_MSG" diff --git a/misc.c b/misc.c index de7e1fa..17973d0 100644 --- a/misc.c +++ b/misc.c @@ -62,6 +62,10 @@ #include "log.h" #include "ssh.h" +#ifdef SCTP +#include +#endif + /* remove newline at end of string */ char * chop(char *s) @@ -140,21 +144,46 @@ void set_nodelay(int fd) { int opt; + int is_tcp = 1; + int ret; socklen_t optlen; optlen = sizeof opt; if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { - debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); +#ifdef SCTP + /* TCP_NODELAY failed, try SCTP_NODELAY */ + if (getsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &opt, &optlen) == -1) { + debug("getsockopt TCP_NODELAY/SCTP_NODELAY: %.100s", strerror(errno)); + return; + } + is_tcp = 0; +#else return; +#endif } if (opt == 1) { - debug2("fd %d is TCP_NODELAY", fd); + debug2("fd %d is TCP_NODELAY/SCTP_NODELAY", fd); return; } opt = 1; - debug2("fd %d setting TCP_NODELAY", fd); - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) - error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); + debug2("fd %d setting TCP_NODELAY/SCTP_NODELAY", fd); + + if (is_tcp) { + ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, + sizeof(opt)); + if (ret < 0) + error("setsockopt TCP_NODELAY: %.100s", + strerror(errno)); + } +#ifdef SCTP + else { + ret = setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &opt, + sizeof(opt)); + if (ret < 0) + error("setsockopt SCTP_NODELAY: %.100s", + strerror(errno)); + } +#endif } /* Characters considered whitespace in strsep calls. */ diff --git a/readconf.c b/readconf.c index 69d4553..83a2c06 100644 --- a/readconf.c +++ b/readconf.c @@ -136,6 +136,7 @@ typedef enum { oChallengeResponseAuthentication, oXAuthLocation, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, oCertificateFile, oAddKeysToAgent, oIdentityAgent, + oTransport, oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, @@ -208,6 +209,11 @@ static struct { { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, { "proxycommand", oProxyCommand }, +#ifdef SCTP + { "transport", oTransport }, +#else + { "transport", oUnsupported }, +#endif { "port", oPort }, { "cipher", oCipher }, { "ciphers", oCiphers }, @@ -1094,6 +1100,20 @@ parse_command: *charptr = xstrdup(s + len); return 0; + case oTransport: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%s line %d: missing transport protocol specification", + filename, linenum); + if (strcasecmp(arg, "tcp") == 0) + options->transport = TRANSPORT_TCP; + else if (strcasecmp(arg, "sctp") == 0) + options->transport = TRANSPORT_SCTP; + else + fatal("%s line %d: unknown transport protocol specified", + filename, linenum); + break; + case oPort: intptr = &options->port; parse_int: @@ -1660,6 +1680,7 @@ initialize_options(Options * options) options->compression = -1; options->tcp_keep_alive = -1; options->compression_level = -1; + options->transport = -1; options->port = -1; options->address_family = -1; options->connection_attempts = -1; @@ -1799,6 +1820,8 @@ fill_default_options(Options * options) options->tcp_keep_alive = 1; if (options->compression_level == -1) options->compression_level = 6; + if (options->transport == -1) + options->transport = TRANSPORT_TCP; if (options->port == -1) options->port = 0; /* Filled in ssh_connect. */ if (options->address_family == -1) diff --git a/readconf.h b/readconf.h index c84d068..28fa3ec 100644 --- a/readconf.h +++ b/readconf.h @@ -28,6 +28,10 @@ struct allowed_cname { char *target_list; }; +/* Transport protocols */ +#define TRANSPORT_TCP 1 +#define TRANSPORT_SCTP 2 + typedef struct { int forward_agent; /* Forward authentication agent. */ int forward_x11; /* Forward X11 display. */ @@ -61,6 +65,7 @@ typedef struct { int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ LogLevel log_level; /* Level for logging. */ + int transport; /* Transport protocol used. */ int port; /* Port to connect. */ int address_family; int connection_attempts; /* Max attempts (seconds) before diff --git a/scp.1 b/scp.1 index 54ea352..d12802e 100644 --- a/scp.1 +++ b/scp.1 @@ -19,7 +19,7 @@ .Sh SYNOPSIS .Nm scp .Bk -words -.Op Fl 12346BCpqrv +.Op Fl 12346BCpqrvz .Op Fl c Ar cipher .Op Fl F Ar ssh_config .Op Fl i Ar identity_file @@ -181,6 +181,7 @@ For full details of the options listed below, and their possible values, see .It ServerAliveCountMax .It StrictHostKeyChecking .It TCPKeepAlive +.It Transport .It UpdateHostKeys .It UsePrivilegedPort .It User @@ -222,6 +223,8 @@ and to print debugging messages about their progress. This is helpful in debugging connection, authentication, and configuration problems. +.It Fl z +Use the SCTP protocol for connection instead of TCP which is the default. .El .Sh EXIT STATUS .Ex -std scp diff --git a/scp.c b/scp.c index 0bdd7cb..8c456d4 100644 --- a/scp.c +++ b/scp.c @@ -396,7 +396,11 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings=yes"); fflag = tflag = 0; +#ifdef SCTP + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:z")) != -1) +#else while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1) +#endif switch (ch) { /* User-visible flags. */ case '1': @@ -404,6 +408,9 @@ main(int argc, char **argv) case '4': case '6': case 'C': +#ifdef SCTP + case 'z': +#endif addargs(&args, "-%c", ch); addargs(&remote_remote_args, "-%c", ch); break; diff --git a/servconf.c b/servconf.c index b19d30e..14b0a0f 100644 --- a/servconf.c +++ b/servconf.c @@ -138,6 +138,7 @@ initialize_server_options(ServerOptions *options) options->ciphers = NULL; options->macs = NULL; options->kex_algorithms = NULL; + options->transport = -1; - options->protocol = SSH_PROTO_UNKNOWN; options->fwd_opts.gateway_ports = -1; options->fwd_opts.streamlocal_bind_mask = (mode_t)-1; + options->fwd_opts.streamlocal_bind_unlink = -1; @@ -315,6 +316,8 @@ fill_default_server_options(ServerOptions *options) options->allow_streamlocal_forwarding = FORWARD_ALLOW; if (options->allow_agent_forwarding == -1) options->allow_agent_forwarding = 1; + if (options->transport == -1) + options->transport = TRANSPORT_TCP; if (options->fwd_opts.gateway_ports == -1) options->fwd_opts.gateway_ports = 0; if (options->max_startups == -1) @@ -406,6 +409,7 @@ typedef enum { sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sAddressFamily, + sTransport, sListenMultipleAddresses, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive, @@ -504,6 +508,13 @@ static struct { { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ { "checkmail", sDeprecated, SSHCFG_GLOBAL }, { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, +#ifdef SCTP + { "listenmultipleaddresses", sListenMultipleAddresses, SSHCFG_GLOBAL }, + { "transport", sTransport, SSHCFG_GLOBAL }, +#else + { "listenmultipleaddresses", sUnsupported, SSHCFG_GLOBAL }, + { "transport", sUnsupported, SSHCFG_GLOBAL }, +#endif { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, #ifdef DISABLE_LASTLOG @@ -717,6 +728,79 @@ get_connection_info(int populate, int use_dns) return &ci; } +#ifdef SCTP +static void +add_one_listen_multiple_addr(ServerOptions *options, char *addr, int port, int last) +{ + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = options->address_family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) + fatal("bad addr or host: %s (%s)", + addr ? addr : "", + ssh_gai_strerror(gaierr)); + /* Mark addresses as multihomed */ + for (ai = aitop; ai->ai_next; ai = ai->ai_next) + ai->ai_flags = IS_MULTIPLE_ADDR; + ai->ai_flags = IS_MULTIPLE_ADDR; + ai->ai_next = options->listen_addrs; + options->listen_addrs = aitop; + + if (last) { + aitop->ai_flags = 0; + } +} + +static void +add_listen_multiple_addrs(ServerOptions *options, char *addrs, int port) +{ + u_int i, num_addrs; + char **addrsptr, *p; + + if (options->num_ports == 0) + options->ports[options->num_ports++] = SSH_DEFAULT_PORT; + if (options->address_family == -1) + options->address_family = AF_UNSPEC; + + num_addrs = 1; + p = addrs; + while ((p = strchr(p, ',')) != NULL) { + num_addrs++; + p++; + } + debug("found %d addresses for multi-homing", num_addrs); + + addrsptr = xmalloc(num_addrs * sizeof(char*)); + p = addrs; + for (i = 0; i < num_addrs; i++) { + addrsptr[i] = p; + p = strchr(p+1, ','); + if (p != NULL) + *(p++) = '\0'; + } + + if (port == 0) + for (i = 0; i < options->num_ports; i++) { + while (--num_addrs) + add_one_listen_multiple_addr(options, addrsptr[num_addrs], options->ports[i], 0); + add_one_listen_multiple_addr(options, addrs, options->ports[i], 1); + } + else { + while (--num_addrs) + add_one_listen_multiple_addr(options, addrsptr[num_addrs], port, 0); + add_one_listen_multiple_addr(options, addrs, port, 1); + } + + free(addrsptr); +} +#endif + /* * The strategy for the Match blocks is that the config file is parsed twice. * @@ -1061,6 +1145,25 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->key_regeneration_time; goto parse_time; +#ifdef SCTP + case sListenMultipleAddresses: + arg = strdelim(&cp); + if (arg == NULL || *arg == '\0') + fatal("%s line %d: missing addresses", + filename, linenum); + + /* Check for appended port */ + p = strchr(arg, ';'); + if (p != NULL) { + if ((port = a2port(p + 1)) <= 0) + fatal("%s line %d: bad port number", filename, linenum); + *p = '\0'; + } else + port = 0; + add_listen_multiple_addrs(options, arg, port); + break; +#endif + case sListenAddress: arg = strdelim(&cp); if (arg == NULL || *arg == '\0') @@ -1478,6 +1581,22 @@ process_server_config_line(ServerOptions *options, char *line, options->kex_algorithms = xstrdup(arg); break; + case sTransport: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing transport protocol specification", + filename, linenum); + if (strcasecmp(arg, "all") == 0) + options->transport = TRANSPORT_ALL; + else if (strcasecmp(arg, "tcp") == 0) + options->transport = TRANSPORT_TCP; + else if (strcasecmp(arg, "sctp") == 0) + options->transport = TRANSPORT_SCTP; + else + fatal("%s line %d: unknown transport protocol specified", + filename, linenum); + break; + - case sProtocol: - intptr = &options->protocol; - arg = strdelim(&cp); + case sSubsystem: + if (options->num_subsystems >= MAX_SUBSYSTEMS) { + fatal("%s line %d: too many subsystems defined.", @@ -1992,6 +2111,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(allow_streamlocal_forwarding); M_CP_INTOPT(allow_agent_forwarding); M_CP_INTOPT(permit_tun); + M_CP_INTOPT(transport); M_CP_INTOPT(fwd_opts.gateway_ports); M_CP_INTOPT(x11_display_offset); M_CP_INTOPT(x11_forwarding); @@ -2286,6 +2406,9 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); dump_cfg_fmtint(sUseLogin, o->use_login); dump_cfg_fmtint(sCompression, o->compression); +#ifdef SCTP + dump_cfg_fmtint(sTransport, o->transport); +#endif dump_cfg_fmtint(sGatewayPorts, o->fwd_opts.gateway_ports); dump_cfg_fmtint(sUseDNS, o->use_dns); dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); diff --git a/servconf.h b/servconf.h index f4137af..63a0637 100644 --- a/servconf.h +++ b/servconf.h @@ -54,6 +54,13 @@ /* Magic name for internal sftp-server */ #define INTERNAL_SFTP_NAME "internal-sftp" +/* Transport protocols */ +#define TRANSPORT_TCP 1 +#define TRANSPORT_SCTP 2 +#define TRANSPORT_ALL (TRANSPORT_TCP | TRANSPORT_SCTP) + +#define IS_MULTIPLE_ADDR 0x1000 + typedef struct { u_int num_ports; u_int ports_from_cmdline; @@ -93,6 +100,7 @@ typedef struct { char *ciphers; /* Supported SSH2 ciphers. */ char *macs; /* Supported SSH2 macs. */ char *kex_algorithms; /* SSH2 kex methods in order of preference. */ + int transport; /* Transport protocol(s) used */ - int protocol; /* Supported protocol versions. */ struct ForwardOptions fwd_opts; /* forwarding options */ SyslogFacility log_facility; /* Facility for system logging. */ + LogLevel log_level;<--->/* Level for system logging. */ diff --git a/ssh.1 b/ssh.1 index cc53343..b1a45e8 100644 --- a/ssh.1 +++ b/ssh.1 @@ -43,7 +43,7 @@ .Sh SYNOPSIS .Nm ssh .Bk -words -.Op Fl 1246AaCfGgKkMNnqsTtVvXxYy +.Op Fl 1246AaCfGgKkMNnqsTtVvXxYyz .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl D Oo Ar bind_address : Oc Ns Ar port @@ -536,6 +536,7 @@ For full details of the options listed below, and their possible values, see .It StreamLocalBindUnlink .It StrictHostKeyChecking .It TCPKeepAlive +.It Transport .It Tunnel .It TunnelDevice .It UpdateHostKeys @@ -770,6 +771,8 @@ controls. .Pp .It Fl y Send log information using the +.It Fl z +Use the SCTP protocol for connection instead of TCP which is the default. .Xr syslog 3 system module. By default this information is sent to stderr. diff --git a/ssh.c b/ssh.c index f9ff91f..d0d92ce 100644 --- a/ssh.c +++ b/ssh.c @@ -195,12 +195,17 @@ extern int muxserver_sock; extern u_int muxclient_command; /* Prints a help message to the user. This function never returns. */ +#ifdef SCTP +#define SCTP_OPT "z" +#else +#define SCTP_OPT "" +#endif static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy" SCTP_OPT "] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" " [-F configfile] [-I pkcs11] [-i identity_file] [-L address]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" @@ -605,7 +610,7 @@ main(int ac, char **av) argv0 = av[0]; again: - while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" + while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" SCTP_OPT "ACD:E:F:GI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': @@ -845,6 +850,11 @@ main(int ac, char **av) else options.control_master = SSHCTL_MASTER_YES; break; +#ifdef SCTP + case 'z': + options.transport = TRANSPORT_SCTP; + break; +#endif case 'p': options.port = a2port(optarg); if (options.port <= 0) { diff --git a/ssh_config.5 b/ssh_config.5 index caf13a6..a088f30 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -1597,6 +1597,12 @@ This is important in scripts, and many users want it too. .Pp To disable TCP keepalive messages, the value should be set to - .Dq no . + .Cm no . +.It Cm Transport +Specifies the transport protocol while connecting. Valid values are +.Dq TCP +and +.Dq SCTP . +The default is TCP. .It Cm Tunnel Request .Xr tun 4 diff --git a/sshconnect.c b/sshconnect.c index 356ec79..21b3f54 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -66,6 +66,10 @@ #include "ssherr.h" #include "authfd.h" +#ifdef SCTP +#include +#endif + char *client_version_string = NULL; char *server_version_string = NULL; Key *previous_host_key = NULL; @@ -275,6 +279,9 @@ ssh_create_socket(int privileged, struct addrinfo *ai) { int sock, r, gaierr; struct addrinfo hints, *res = NULL; +#ifdef SCTP + char *more_addrs, *next_addr; +#endif sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { @@ -288,10 +295,21 @@ ssh_create_socket(int privileged, struct addrinfo *ai) return sock; if (options.bind_address) { +#ifdef SCTP + /* Check if multiple addresses have been specified */ + if ((more_addrs = strchr(options.bind_address, ',')) != NULL) { + *(more_addrs++) = '\0'; + } +#endif memset(&hints, 0, sizeof(hints)); hints.ai_family = ai->ai_family; hints.ai_socktype = ai->ai_socktype; +#ifndef SCTP + /* Only specify protocol if SCTP is not used, due + * to the lack of SCTP support for getaddrinfo() + */ hints.ai_protocol = ai->ai_protocol; +#endif hints.ai_flags = AI_PASSIVE; gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); if (gaierr) { @@ -324,6 +342,34 @@ ssh_create_socket(int privileged, struct addrinfo *ai) return -1; } } +#ifdef SCTP + /* If there are multiple addresses, bind them too */ + if (more_addrs) { + do { + next_addr = strchr(more_addrs, ','); + if (next_addr != NULL) { + *(next_addr++) = '\0'; + } + + gaierr = getaddrinfo(more_addrs, NULL, &hints, &res); + if (gaierr) { + error("getaddrinfo: %s: %s", more_addrs, + ssh_gai_strerror(gaierr)); + close(sock); + return -1; + } + if (sctp_bindx(sock, (struct sockaddr *)res->ai_addr, + 1, SCTP_BINDX_ADD_ADDR) != 0) { + error("bind: %s: %s", options.bind_address, strerror(errno)); + close(sock); + freeaddrinfo(res); + return -1; + } + + more_addrs = next_addr; + } while (next_addr != NULL); + } +#endif if (res != NULL) freeaddrinfo(res); return sock; @@ -437,6 +483,15 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, memset(ntop, 0, sizeof(ntop)); memset(strport, 0, sizeof(strport)); +#ifdef SCTP + /* Use SCTP if requested */ + if (options.transport == TRANSPORT_SCTP) { + for (ai = aitop; ai; ai = ai->ai_next) { + ai->ai_protocol = IPPROTO_SCTP; + } + } +#endif + for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { /* Sleep a moment before retrying. */ diff --git a/sshd.c b/sshd.c index 430569c..4ca58ed 100644 --- a/sshd.c +++ b/sshd.c @@ -125,6 +125,10 @@ #include "version.h" #include "ssherr.h" +#ifdef SCTP +#include +#endif + - #ifndef O_NOCTTY - #define O_NOCTTY 0 - #endif + /* Re-exec fds */ + #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) + #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) @@ -1164,6 +1168,12 @@ server_listen(void) for (ai = options.listen_addrs; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; +#ifdef SCTP + /* Ignore multi-homing addresses for TCP */ + if (ai->ai_flags & IS_MULTIPLE_ADDR || + (ai->ai_next != NULL && ai->ai_next->ai_flags & IS_MULTIPLE_ADDR)) + continue; +#endif if (num_listen_socks >= MAX_LISTEN_SOCKS) fatal("Too many listen sockets. " "Enlarge MAX_LISTEN_SOCKS"); @@ -1222,6 +1232,127 @@ server_listen(void) fatal("Cannot bind any address."); } +#ifdef SCTP +/* + * Listen for SCTP connections + */ +static void +server_listen_sctp(void) +{ + int ret, listen_sock, on = 1; + struct addrinfo *ai, *aiv6; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + + for (ai = options.listen_addrs; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + /* Ignore multi-homing addresses at this point */ + if (ai->ai_flags & IS_MULTIPLE_ADDR) + continue; + if (num_listen_socks >= MAX_LISTEN_SOCKS) + fatal("Too many listen sockets. " + "Enlarge MAX_LISTEN_SOCKS"); + if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { + error("getnameinfo failed: %.100s", + ssh_gai_strerror(ret)); + continue; + } + /* Check for multi-homed IPv6 addresses if family is IPv4 */ + if (ai->ai_family == AF_INET) { + aiv6 = ai->ai_next; + while (aiv6 != NULL && aiv6->ai_flags & IS_MULTIPLE_ADDR) { + if (aiv6->ai_family == AF_INET6) { + ai->ai_family = AF_INET6; + break; + } + aiv6 = aiv6->ai_next; + } + } + + /* Create socket for listening. */ + listen_sock = socket(ai->ai_family, ai->ai_socktype, + IPPROTO_SCTP); + if (listen_sock < 0) { + /* kernel may not support ipv6 */ + verbose("SCTP socket: %.100s", strerror(errno)); + continue; + } + if (set_nonblock(listen_sock) == -1) { + close(listen_sock); + continue; + } + /* + * Set socket options. + * Allow local port reuse in TIME_WAIT. + */ + if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)) == -1) + error("SCTP setsockopt SO_REUSEADDR: %s", strerror(errno)); + + /* Only communicate in IPv6 over AF_INET6 sockets if not multi-homed. */ + if (ai->ai_family == AF_INET6 && (ai->ai_next == NULL || + (ai->ai_next != NULL && ai->ai_next->ai_flags == 0))) + sock_set_v6only(listen_sock); + + if (ai->ai_next != NULL && ai->ai_next->ai_flags & IS_MULTIPLE_ADDR) + debug("Bind multi-homed to SCTP port %s on %s.", strport, ntop); + else + debug("Bind to SCTP port %s on %s.", strport, ntop); + + /* Bind the socket to the desired port. */ + if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { + error("Bind to SCTP port %s on %s failed: %.200s.", + strport, ntop, strerror(errno)); + close(listen_sock); + continue; + } + + /* Bind multi-homing addresses */ + while (ai->ai_next != NULL && + ai->ai_next->ai_flags & IS_MULTIPLE_ADDR) { + ai = ai->ai_next; + + if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { + error("getnameinfo failed: %.100s", + ssh_gai_strerror(ret)); + continue; + } + + debug("Bind multi-homed to SCTP port %s on %s.", strport, ntop); + + if (sctp_bindx(listen_sock, (struct sockaddr *)ai->ai_addr, 1, SCTP_BINDX_ADD_ADDR) != 0) { + error("Bind to SCTP port %s on %s failed: %.200s.", + strport, ntop, strerror(errno)); + close(listen_sock); + continue; + } + } + + listen_socks[num_listen_socks] = listen_sock; + num_listen_socks++; + + /* Start listening on the port. */ + if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0) + fatal("SCTP listen on [%s]:%s: %.100s", + ntop, strport, strerror(errno)); + if (ai->ai_flags & IS_MULTIPLE_ADDR) + logit("Server listening multi-homed with SCTP on port %s.", strport); + else + logit("Server listening with SCTP on %s port %s.", ntop, strport); + } + /* Only free addresses if SCTP is the only used protocol */ + if (options.transport == TRANSPORT_SCTP) + freeaddrinfo(options.listen_addrs); + + if (!num_listen_socks) + fatal("Cannot bind any address for SCTP."); +} +#endif + /* * The main TCP accept loop. Note that, for the non-debug case, returns * from this function are in a forked subprocess. @@ -2007,7 +2138,14 @@ main(int ac, char **av) server_accept_inetd(&sock_in, &sock_out); } else { platform_pre_listen(); - server_listen(); + +#ifdef SCTP + if (options.transport & TRANSPORT_SCTP) + server_listen_sctp(); + + if (options.transport & TRANSPORT_TCP) +#endif + server_listen(); if (options.protocol & SSH_PROTO_1) generate_ephemeral_server_key(); diff --git a/sshd_config.5 b/sshd_config.5 index a37a3ac..24e3826 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -1508,6 +1508,17 @@ This avoids infinitely hanging sessions. .Pp To disable TCP keepalive messages, the value should be set to - .Dq no . + .Cm no . +.It Cm Transport +Specifies the transport protocol that should be used by +.Xr sshd 8 . +Valid values are +.Dq TCP , +.Dq SCTP , +.Dq all. +The value +.Dq all +means to listen on TCP and SCTP sockets. The default is to listen only on +TCP sockets. .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or -- 2.6.2 Index: head/security/openssh-portable/files/extra-patch-tcpwrappers =================================================================== --- head/security/openssh-portable/files/extra-patch-tcpwrappers (revision 431697) +++ head/security/openssh-portable/files/extra-patch-tcpwrappers (revision 431698) @@ -1,159 +1,159 @@ Revert TCPWRAPPER removal -bdrewery commit f2719b7c2b8a3b14d778d8a6d8dc729b5174b054 Author: Damien Miller Date: Sun Apr 20 13:22:18 2014 +1000 - tedu@cvs.openbsd.org 2014/03/26 19:58:37 [sshd.8 sshd.c] remove libwrap support. ok deraadt djm mfriedl diff --git sshd.8 sshd.8 index 289e13d..e6a900b 100644 --- sshd.8 +++ sshd.8 @@ -851,6 +851,12 @@ the user's home directory becomes accessible. This file should be writable only by the user, and need not be readable by anyone else. .Pp +.It Pa /etc/hosts.allow +.It Pa /etc/hosts.deny +Access controls that should be enforced by tcp-wrappers are defined here. +Further details are described in +.Xr hosts_access 5 . +.Pp .It Pa /etc/hosts.equiv This file is for host-based authentication (see .Xr ssh 1 ) . @@ -954,6 +960,7 @@ The content of this file is not sensitive; it can be world-readable. .Xr ssh-keygen 1 , .Xr ssh-keyscan 1 , .Xr chroot 2 , +.Xr hosts_access 5 , .Xr login.conf 5 , .Xr moduli 5 , .Xr sshd_config 5 , diff --git sshd.c sshd.c index 0ade557..045f149 100644 --- sshd.c +++ sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.421 2014/03/26 19:58:37 tedu Exp $ */ +/* $OpenBSD: sshd.c,v 1.422 2014/03/27 23:01:27 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland -@@ -122,6 +122,13 @@ - #include "ssh-sandbox.h" +@@ -123,6 +123,13 @@ #include "version.h" + #include "ssherr.h" +#ifdef LIBWRAP +#include +#include +int allow_severity; +int deny_severity; +#endif /* LIBWRAP */ + - #ifndef O_NOCTTY - #define O_NOCTTY 0 - #endif -@@ -2027,6 +2034,24 @@ main(int ac, char **av) + /* Re-exec fds */ + #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) + #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) +@@ -1971,6 +1978,24 @@ main(int ac, char **av) #ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); #endif +#ifdef LIBWRAP + allow_severity = options.log_facility|LOG_INFO; + deny_severity = options.log_facility|LOG_WARNING; + /* Check whether logins are denied from this host. */ + if (packet_connection_is_on_socket()) { + struct request_info req; + + request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); + fromhost(&req); + + if (!hosts_access(&req)) { + debug("Connection refused by tcp wrapper"); + refuse(&req); + /* NOTREACHED */ + fatal("libwrap refuse returns"); + } + } +#endif /* LIBWRAP */ /* Log the connection. */ - verbose("Connection from %s port %d on %s port %d", + laddr = get_local_ipaddr(sock_in); diff --git configure.ac configure.ac index f48ba4a..66fbe82 100644 --- configure.ac +++ configure.ac @@ -1380,6 +1380,62 @@ AC_ARG_WITH([skey], ] ) +# Check whether user wants TCP wrappers support +TCPW_MSG="no" +AC_ARG_WITH([tcp-wrappers], + [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], + [ + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + saved_LDFLAGS="$LDFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + if test -n "${withval}" && \ + test "x${withval}" != "xyes"; then + if test -d "${withval}/lib"; then + if test -n "${need_dash_r}"; then + LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" + else + LDFLAGS="-L${withval}/lib ${LDFLAGS}" + fi + else + if test -n "${need_dash_r}"; then + LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}" + else + LDFLAGS="-L${withval} ${LDFLAGS}" + fi + fi + if test -d "${withval}/include"; then + CPPFLAGS="-I${withval}/include ${CPPFLAGS}" + else + CPPFLAGS="-I${withval} ${CPPFLAGS}" + fi + fi + LIBS="-lwrap $LIBS" + AC_MSG_CHECKING([for libwrap]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +#include +int deny_severity = 0, allow_severity = 0; + ]], [[ + hosts_access(0); + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([LIBWRAP], [1], + [Define if you want + TCP Wrappers support]) + SSHDLIBS="$SSHDLIBS -lwrap" + TCPW_MSG="yes" + ], [ + AC_MSG_ERROR([*** libwrap missing]) + + ]) + LIBS="$saved_LIBS" + fi + ] +) + # Check whether user wants to use ldns LDNS_MSG="no" AC_ARG_WITH(ldns, @@ -4803,6 +4859,7 @@ echo " KerberosV support: $KRB5_MSG" echo " SELinux support: $SELINUX_MSG" echo " Smartcard support: $SCARD_MSG" echo " S/KEY support: $SKEY_MSG" +echo " TCP Wrappers support: $TCPW_MSG" echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" Index: head/security/openssh-portable/files/extra-patch-x509-glue =================================================================== --- head/security/openssh-portable/files/extra-patch-x509-glue (nonexistent) +++ head/security/openssh-portable/files/extra-patch-x509-glue (revision 431698) @@ -0,0 +1,39 @@ +--- session.c.orig 2017-01-12 11:58:30.754769000 -0800 ++++ session.c 2017-01-12 11:58:35.360654000 -0800 +@@ -1252,36 +1252,6 @@ do_setup_env(Session *s, const char *she + if (getenv("TZ")) + child_set_env(&env, &envsize, "TZ", getenv("TZ")); + +-#ifdef __ANDROID__ +-{ +-#define COPY_ANDROID_ENV(name) { \ +- char *s = getenv(name); \ +- if (s) child_set_env(&env, &envsize, name, s); } +- +- /* from /init.rc */ +- COPY_ANDROID_ENV("ANDROID_BOOTLOGO"); +- COPY_ANDROID_ENV("ANDROID_ROOT"); +- COPY_ANDROID_ENV("ANDROID_ASSETS"); +- COPY_ANDROID_ENV("ANDROID_DATA"); +- COPY_ANDROID_ENV("ASEC_MOUNTPOINT"); +- COPY_ANDROID_ENV("LOOP_MOUNTPOINT"); +- COPY_ANDROID_ENV("BOOTCLASSPATH"); +- +- /* FIXME: keep android property workspace open +- * (see openbsd-compat/bsd-closefrom.c) +- */ +- COPY_ANDROID_ENV("ANDROID_PROPERTY_WORKSPACE"); +- +- COPY_ANDROID_ENV("EXTERNAL_STORAGE"); /* ??? */ +- COPY_ANDROID_ENV("SECONDARY_STORAGE"); /* ??? */ +- COPY_ANDROID_ENV("SD_EXT_DIRECTORY"); /* ??? */ +- +- /* may contain path to custom libraries */ +- COPY_ANDROID_ENV("LD_LIBRARY_PATH"); +-#undef COPY_ANDROID_ENV +-} +-#endif +- + /* Set custom environment options from RSA authentication. */ + while (custom_environment) { + struct envstring *ce = custom_environment; Property changes on: head/security/openssh-portable/files/extra-patch-x509-glue ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/security/openssh-portable/files/patch-misc.c =================================================================== --- head/security/openssh-portable/files/patch-misc.c (nonexistent) +++ head/security/openssh-portable/files/patch-misc.c (revision 431698) @@ -0,0 +1,43 @@ +------------------------------------------------------------------------ +r181918 | des | 2008-08-20 05:40:07 -0500 (Wed, 20 Aug 2008) | 6 lines +Changed paths: + M /head/crypto/openssh/readconf.c + +Use net.inet.ip.portrange.reservedhigh instead of IPPORT_RESERVED. +Submitted upstream, no reaction. + +Submitted by: delphij@ +[rewritten for 7.4 by bdrewery@] + +--- misc.c.orig 2017-01-12 11:54:41.058558000 -0800 ++++ misc.c 2017-01-12 11:55:16.531356000 -0800 +@@ -56,6 +56,8 @@ + #include + #endif + ++#include ++ + #include "xmalloc.h" + #include "misc.h" + #include "log.h" +@@ -1253,7 +1255,19 @@ forward_equals(const struct Forward *a, + int + bind_permitted(int port, uid_t uid) + { +- if (port < IPPORT_RESERVED && uid != 0) ++ int ipport_reserved; ++#ifdef __FreeBSD__ ++ size_t len_ipport_reserved = sizeof(ipport_reserved); ++ ++ if (sysctlbyname("net.inet.ip.portrange.reservedhigh", ++ &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) ++ ipport_reserved = IPPORT_RESERVED; ++ else ++ ipport_reserved++; ++#else ++ ipport_reserved = IPPORT_RESERVED; ++#endif ++ if (port < ipport_reserved && uid != 0) + return 0; + return 1; + } Property changes on: head/security/openssh-portable/files/patch-misc.c ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +1 \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/security/openssh-portable/files/patch-readconf.c =================================================================== --- head/security/openssh-portable/files/patch-readconf.c (revision 431697) +++ head/security/openssh-portable/files/patch-readconf.c (revision 431698) @@ -1,62 +1,22 @@ --- UTC base defaults r99048 | des | 2002-06-29 05:51:56 -0500 (Sat, 29 Jun 2002) | 4 lines Changed paths: M /head/crypto/openssh/myproposal.h M /head/crypto/openssh/readconf.c M /head/crypto/openssh/servconf.c Apply FreeBSD's configuration defaults. ------------------------------------------------------------------------- -r181918 | des | 2008-08-20 05:40:07 -0500 (Wed, 20 Aug 2008) | 6 lines -Changed paths: - M /head/crypto/openssh/readconf.c - -Use net.inet.ip.portrange.reservedhigh instead of IPPORT_RESERVED. -Submitted upstream, no reaction. - -Submitted by: delphij@ - --- readconf.c.orig 2014-07-17 23:11:26.000000000 -0500 +++ readconf.c 2014-11-03 16:45:05.188796445 -0600 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -311,8 +312,19 @@ add_local_forward(Options *options, cons - struct Forward *fwd; - extern uid_t original_real_uid; - int i; -- -- if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 && -+ int ipport_reserved; -+#ifdef __FreeBSD__ -+ size_t len_ipport_reserved = sizeof(ipport_reserved); -+ -+ if (sysctlbyname("net.inet.ip.portrange.reservedhigh", -+ &ipport_reserved, &len_ipport_reserved, NULL, 0) != 0) -+ ipport_reserved = IPPORT_RESERVED; -+ else -+ ipport_reserved++; -+#else -+ ipport_reserved = IPPORT_RESERVED; -+#endif -+ if (newfwd->listen_port < ipport_reserved && original_real_uid != 0 && - newfwd->listen_path == NULL) - fatal("Privileged ports can only be forwarded by root."); - /* Don't add duplicates */ @@ -1934,7 +1946,7 @@ fill_default_options(Options * options) if (options->batch_mode == -1) options->batch_mode = 0; if (options->check_host_ip == -1) - options->check_host_ip = 1; + options->check_host_ip = 0; if (options->strict_host_key_checking == -1) options->strict_host_key_checking = 2; /* 2 is default */ if (options->compression == -1) Index: head/security/openssh-portable/files/patch-session.c =================================================================== --- head/security/openssh-portable/files/patch-session.c (revision 431697) +++ head/security/openssh-portable/files/patch-session.c (revision 431698) @@ -1,74 +1,85 @@ +------------------------------------------------------------------------ +r99055 | des | 2002-06-29 04:21:58 -0700 (Sat, 29 Jun 2002) | 6 lines +Changed paths: + M /head/crypto/openssh/session.c + +Make sure the environment variables set by setusercontext() are passed on +to the child process. + +Reviewed by: ache +Sponsored by: DARPA, NAI Labs + + --- session.c 2013-03-14 19:22:37 UTC +++ session.c -@@ -1131,6 +1136,9 @@ +@@ -985,6 +985,9 @@ do_setup_env(Session *s, const char *she struct passwd *pw = s->pw; #if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) char *path = NULL; +#else + extern char **environ; + char **senv, **var; #endif /* Initialize the environment. */ -@@ -1152,6 +1160,9 @@ +@@ -1006,6 +1009,9 @@ do_setup_env(Session *s, const char *she } #endif + if (getenv("TZ")) + child_set_env(&env, &envsize, "TZ", getenv("TZ")); + #ifdef GSSAPI /* Allow any GSSAPI methods that we've used to alter * the childs environment as they see fit -@@ -1171,11 +1182,22 @@ - child_set_env(&env, &envsize, "LOGIN", pw->pw_name); +@@ -1023,11 +1029,21 @@ do_setup_env(Session *s, const char *she + child_set_env(&env, &envsize, "LOGIN", pw->pw_name); #endif - child_set_env(&env, &envsize, "HOME", pw->pw_dir); -+ snprintf(buf, sizeof buf, "%.200s/%.50s", -+ _PATH_MAILDIR, pw->pw_name); -+ child_set_env(&env, &envsize, "MAIL", buf); + child_set_env(&env, &envsize, "HOME", pw->pw_dir); ++ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); ++ child_set_env(&env, &envsize, "MAIL", buf); #ifdef HAVE_LOGIN_CAP -- if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) -- child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); -- else -- child_set_env(&env, &envsize, "PATH", getenv("PATH")); -+ child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); -+ child_set_env(&env, &envsize, "TERM", "su"); -+ senv = environ; -+ environ = xmalloc(sizeof(char *)); -+ *environ = NULL; -+ (void) setusercontext(lc, pw, pw->pw_uid, -+ LOGIN_SETENV|LOGIN_SETPATH); -+ copy_environment(environ, &env, &envsize); -+ for (var = environ; *var != NULL; ++var) -+ free(*var); -+ free(environ); -+ environ = senv; +- if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) +- child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); +- else +- child_set_env(&env, &envsize, "PATH", getenv("PATH")); ++ child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); ++ child_set_env(&env, &envsize, "TERM", "su"); ++ senv = environ; ++ environ = xmalloc(sizeof(char *)); ++ *environ = NULL; ++ (void) setusercontext(lc, pw, pw->pw_uid, ++ LOGIN_SETENV|LOGIN_SETPATH); ++ copy_environment(environ, &env, &envsize); ++ for (var = environ; *var != NULL; ++var) ++ free(*var); ++ free(environ); ++ environ = senv; #else /* HAVE_LOGIN_CAP */ # ifndef HAVE_CYGWIN - /* -@@ -1196,15 +1218,9 @@ + /* +@@ -1047,15 +1063,9 @@ do_setup_env(Session *s, const char *she # endif /* HAVE_CYGWIN */ #endif /* HAVE_LOGIN_CAP */ -- snprintf(buf, sizeof buf, "%.200s/%.50s", -- _PATH_MAILDIR, pw->pw_name); -- child_set_env(&env, &envsize, "MAIL", buf); +- snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); +- child_set_env(&env, &envsize, "MAIL", buf); - - /* Normal systems set SHELL by default. */ - child_set_env(&env, &envsize, "SHELL", shell); - } + /* Normal systems set SHELL by default. */ + child_set_env(&env, &envsize, "SHELL", shell); + - if (getenv("TZ")) - child_set_env(&env, &envsize, "TZ", getenv("TZ")); - +- /* Set custom environment options from RSA authentication. */ - if (!options.use_login) { -@@ -1483,7 +1499,7 @@ + while (custom_environment) { + struct envstring *ce = custom_environment; +@@ -1334,7 +1344,7 @@ do_setusercontext(struct passwd *pw) if (platform_privileged_uidswap()) { #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, - (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { + (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { perror("unable to set user context"); exit(1); } Index: head/security/openssh-portable/files/patch-ssh-agent.1 =================================================================== --- head/security/openssh-portable/files/patch-ssh-agent.1 (revision 431697) +++ head/security/openssh-portable/files/patch-ssh-agent.1 (revision 431698) @@ -1,52 +1,26 @@ --- UTC r226103 | des | 2011-10-07 08:10:16 -0500 (Fri, 07 Oct 2011) | 5 lines Add a -x option that causes ssh-agent(1) to exit when all clients have disconnected. -Add a -P option to specify PKCS11_WHITELIST - - ---- ssh-agent.1.orig 2016-07-27 17:54:27.000000000 -0500 -+++ ssh-agent.1 2017-01-11 19:05:12.513900000 -0600 -@@ -43,10 +43,11 @@ +--- ssh-agent.1.orig 2015-05-29 03:27:21.000000000 -0500 ++++ ssh-agent.1 2015-06-02 09:45:37.025390000 -0500 +@@ -43,7 +43,7 @@ .Sh SYNOPSIS .Nm ssh-agent .Op Fl c | s -.Op Fl \&Dd +.Op Fl \&Ddx .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl t Ar life -+.Op Fl P Ar pkcs11_whitelist - .Op Ar command Op Ar arg ... - .Nm ssh-agent - .Op Fl c | s -@@ -121,6 +122,18 @@ - Kill the current agent (given by the - .Ev SSH_AGENT_PID - environment variable). -+.It Fl P -+Specify a pattern-list of acceptable paths for PKCS#11 shared libraries -+that may be added using the -+.Fl s -+option to -+.Xr ssh-add 1 . -+The default is to allow loading PKCS#11 libraries from -+.Dq /usr/lib/*,/usr/local/lib/* . -+PKCS#11 libraries that do not match the whitelist will be refused. -+See PATTERNS in -+.Xr ssh_config 5 -+for a description of pattern-list syntax. - .It Fl s - Generate Bourne shell commands on - .Dv stdout . -@@ -135,6 +148,8 @@ +@@ -128,6 +128,8 @@ .Xr ssh-add 1 overrides this value. Without this option the default maximum lifetime is forever. +.It Fl x +Exit after the last client has disconnected. .El .Pp - If a command line is given, this is executed as a subprocess of the agent. + If a commandline is given, this is executed as a subprocess of the agent. Index: head/security/openssh-portable/files/patch-ssh-agent.c =================================================================== --- head/security/openssh-portable/files/patch-ssh-agent.c (revision 431697) +++ head/security/openssh-portable/files/patch-ssh-agent.c (revision 431698) @@ -1,200 +1,94 @@ --- UTC r110506 | des | 2003-02-07 09:48:27 -0600 (Fri, 07 Feb 2003) | 4 lines Set the ruid to the euid at startup as a workaround for a bug in pam_ssh. r226103 | des | 2011-10-07 08:10:16 -0500 (Fri, 07 Oct 2011) | 5 lines Add a -x option that causes ssh-agent(1) to exit when all clients have disconnected. -Add a -P option to specify PKCS11_WHITELIST (fixes CVE-2016-10009) - - ---- ssh-agent.c.orig 2016-07-27 17:54:27.000000000 -0500 -+++ ssh-agent.c 2017-01-11 19:02:59.600125000 -0600 -@@ -83,11 +83,16 @@ - #include "misc.h" - #include "digest.h" - #include "ssherr.h" -+#include "match.h" +--- ssh-agent.c.orig 2015-05-29 03:27:21.000000000 -0500 ++++ ssh-agent.c 2015-06-02 09:46:54.719580000 -0500 +@@ -157,15 +157,34 @@ static long lifetime = 0; - #ifdef ENABLE_PKCS11 - #include "ssh-pkcs11.h" - #endif - -+#ifndef DEFAULT_PKCS11_WHITELIST -+# define DEFAULT_PKCS11_WHITELIST "/usr/lib/*,/usr/local/lib/*" -+#endif -+ - typedef enum { - AUTH_UNUSED, - AUTH_SOCKET, -@@ -135,6 +140,9 @@ - char socket_name[PATH_MAX]; - char socket_dir[PATH_MAX]; - -+/* PKCS#11 path whitelist */ -+static char *pkcs11_whitelist; -+ - /* locking */ - #define LOCK_SIZE 32 - #define LOCK_SALT_SIZE 16 -@@ -150,15 +158,34 @@ - static int fingerprint_hash = SSH_FP_HASH_DEFAULT; +/* + * Client connection count; incremented in new_socket() and decremented in + * close_socket(). When it reaches 0, ssh-agent will exit. Since it is + * normally initialized to 1, it will never reach 0. However, if the -x + * option is specified, it is initialized to 0 in main(); in that case, + * ssh-agent will exit as soon as it has had at least one client but no + * longer has any. + */ +static int xcount = 1; + static void close_socket(SocketEntry *e) { + int last = 0; + + if (e->type == AUTH_CONNECTION) { + debug("xcount %d -> %d", xcount, xcount - 1); + if (--xcount == 0) + last = 1; + } close(e->fd); e->fd = -1; e->type = AUTH_UNUSED; sshbuf_free(e->input); sshbuf_free(e->output); sshbuf_free(e->request); + if (last) + cleanup_exit(0); } static void -@@ -738,7 +765,7 @@ - static void - process_add_smartcard_key(SocketEntry *e) +@@ -963,6 +982,10 @@ new_socket(sock_type type, int fd) { -- char *provider = NULL, *pin; -+ char *provider = NULL, *pin, canonical_provider[PATH_MAX]; - int r, i, version, count = 0, success = 0, confirm = 0; - u_int seconds; - time_t death = 0; -@@ -770,10 +797,21 @@ - goto send; - } - } -+ if (realpath(provider, canonical_provider) == NULL) { -+ verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", -+ provider, strerror(errno)); -+ goto send; -+ } -+ if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { -+ verbose("refusing PKCS#11 add of \"%.100s\": " -+ "provider not whitelisted", canonical_provider); -+ goto send; -+ } -+ debug("%s: add %.100s", __func__, canonical_provider); - if (lifetime && !death) - death = monotime() + lifetime; - -- count = pkcs11_add_provider(provider, pin, &keys); -+ count = pkcs11_add_provider(canonical_provider, pin, &keys); - for (i = 0; i < count; i++) { - k = keys[i]; - version = k->type == KEY_RSA1 ? 1 : 2; -@@ -781,8 +819,8 @@ - if (lookup_identity(k, version) == NULL) { - id = xcalloc(1, sizeof(Identity)); - id->key = k; -- id->provider = xstrdup(provider); -- id->comment = xstrdup(provider); /* XXX */ -+ id->provider = xstrdup(canonical_provider); -+ id->comment = xstrdup(canonical_provider); /* XXX */ - id->death = death; - id->confirm = confirm; - TAILQ_INSERT_TAIL(&tab->idlist, id, next); -@@ -945,6 +983,10 @@ - { u_int i, old_alloc, new_alloc; + if (type == AUTH_CONNECTION) { + debug("xcount %d -> %d", xcount, xcount + 1); + ++xcount; + } set_nonblock(fd); if (fd > max_fd) -@@ -1172,8 +1214,8 @@ +@@ -1190,7 +1213,7 @@ static void usage(void) { fprintf(stderr, - "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" -- " [-t life] [command [arg ...]]\n" + "usage: ssh-agent [-c | -s] [-Ddx] [-a bind_address] [-E fingerprint_hash]\n" -+ " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n" + " [-P pkcs11_whitelist] [-t life] [command [arg ...]]\n" " ssh-agent [-c | -s] -k\n"); exit(1); - } -@@ -1204,6 +1246,7 @@ +@@ -1222,6 +1245,7 @@ main(int ac, char **av) /* drop */ setegid(getgid()); setgid(getgid()); + setuid(geteuid()); platform_disable_tracing(0); /* strict=no */ -@@ -1214,7 +1257,7 @@ +@@ -1232,7 +1256,7 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); -- while ((ch = getopt(ac, av, "cDdksE:a:t:")) != -1) { +- while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) { + while ((ch = getopt(ac, av, "cDdksE:a:P:t:x")) != -1) { switch (ch) { case 'E': fingerprint_hash = ssh_digest_alg_by_name(optarg); -@@ -1229,6 +1272,11 @@ - case 'k': - k_flag++; - break; -+ case 'P': -+ if (pkcs11_whitelist != NULL) -+ fatal("-P option already specified"); -+ pkcs11_whitelist = xstrdup(optarg); -+ break; - case 's': - if (c_flag) +@@ -1276,6 +1300,9 @@ main(int ac, char **av) usage(); -@@ -1253,6 +1301,9 @@ - usage(); } break; + case 'x': + xcount = 0; + break; default: usage(); } -@@ -1263,6 +1314,9 @@ - if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) - usage(); - -+ if (pkcs11_whitelist == NULL) -+ pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); -+ - if (ac == 0 && !c_flag && !s_flag) { - shell = getenv("SHELL"); - if (shell != NULL && (len = strlen(shell)) > 2 && -@@ -1410,7 +1464,7 @@ - signal(SIGTERM, cleanup_handler); - nalloc = 0; - -- if (pledge("stdio cpath unix id proc exec", NULL) == -1) -+ if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) - fatal("%s: pledge: %s", __progname, strerror(errno)); - platform_pledge_agent(); - Index: head/security/openssh-portable/files/patch-ssh_config.5 =================================================================== --- head/security/openssh-portable/files/patch-ssh_config.5 (revision 431697) +++ head/security/openssh-portable/files/patch-ssh_config.5 (revision 431698) @@ -1,17 +1,26 @@ --- UTC r100678 | fanf | 2002-07-25 10:59:40 -0500 (Thu, 25 Jul 2002) | 5 lines Document the FreeBSD default for CheckHostIP, which was changed in rev 1.2 of readconf.c. --- ssh_config.5.orig 2010-08-04 21:03:13.000000000 -0600 +++ ssh_config.5 2010-09-14 16:14:13.000000000 -0600 -@@ -164,7 +164,7 @@ - .Dq no , +@@ -377,8 +377,7 @@ or + .Cm no . + .It Cm CheckHostIP + If set to +-.Cm yes +-(the default), ++.Cm yes , + .Xr ssh 1 + will additionally check the host IP address in the + .Pa known_hosts +@@ -390,6 +389,7 @@ in the process, regardless of the settin + .Cm StrictHostKeyChecking . + If the option is set to + .Cm no , ++(the default), the check will not be executed. - The default is --.Dq yes . -+.Dq no . .It Cm Cipher Specifies the cipher to use for encrypting the session - in protocol version 1. Index: head/security/openssh-portable/files/patch-sshd_config.5 =================================================================== --- head/security/openssh-portable/files/patch-sshd_config.5 (revision 431697) +++ head/security/openssh-portable/files/patch-sshd_config.5 (revision 431698) @@ -1,91 +1,91 @@ ---- sshd_config.5.orig 2015-05-29 03:27:21.000000000 UTC -+++ sshd_config.5 2015-06-02 09:49:08.463186000 -0500 -@@ -375,7 +375,9 @@ By default, no banner is displayed. +--- sshd_config.5.orig 2016-12-18 20:59:41.000000000 -0800 ++++ sshd_config.5 2017-01-11 13:35:46.496538000 -0800 +@@ -373,7 +373,9 @@ By default, no banner is displayed. .It Cm ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed (e.g. via PAM or through authentication styles supported in -.Xr login.conf 5 ) +.Xr login.conf 5 ) . +See also +.Cm UsePAM . The default is - .Dq yes . + .Cm yes . .It Cm ChrootDirectory -@@ -1111,7 +1113,22 @@ are refused if the number of unauthentic +@@ -663,7 +665,9 @@ ssh-ed25519,ssh-rsa + The list of available key types may also be obtained using + .Qq ssh -Q key . + .It Cm HostbasedAuthentication +-Specifies whether rhosts or /etc/hosts.equiv authentication together ++Specifies whether rhosts or ++.Pa /etc/hosts.equiv ++authentication together + with successful public key client host authentication is allowed + (host-based authentication). + The default is +@@ -1120,7 +1124,22 @@ are refused if the number of unauthentic .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is -+.Dq no , ++.Cm no , +unless +.Nm sshd +was built without PAM support, in which case the default is - .Dq yes . + .Cm yes . +Note that if +.Cm ChallengeResponseAuthentication +is -+.Dq yes , ++.Cm yes , +and the PAM authentication policy for +.Nm sshd +includes +.Xr pam_unix 8 , +password authentication will be allowed through the challenge-response +mechanism regardless of the value of +.Cm PasswordAuthentication . .It Cm PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. -@@ -1158,6 +1175,13 @@ or - .Dq no . +@@ -1216,6 +1235,13 @@ and + .Cm ethernet . The default is - .Dq no . + .Cm no . +Note that if +.Cm ChallengeResponseAuthentication +is -+.Dq yes , ++.Cm yes , +the root user may be allowed in with its password even if +.Cm PermitRootLogin is set to -+.Dq without-password . ++.Cm without-password . .Pp - If this option is set to - .Dq without-password , -@@ -1331,7 +1355,9 @@ an OpenSSH Key Revocation List (KRL) as - For more information on KRLs, see the KEY REVOCATION LISTS section in - .Xr ssh-keygen 1 . - .It Cm RhostsRSAAuthentication --Specifies whether rhosts or /etc/hosts.equiv authentication together -+Specifies whether rhosts or -+.Pa /etc/hosts.equiv -+authentication together - with successful RSA host authentication is allowed. - The default is - .Dq no . -@@ -1498,7 +1524,7 @@ is enabled, you will not be able to run + Independent of this setting, the permissions of the selected + .Xr tun 4 +@@ -1473,7 +1499,7 @@ is enabled, you will not be able to run .Xr sshd 8 as a non-root user. The default is --.Dq no . -+.Dq yes . +-.Cm no . ++.Cm yes . .It Cm UsePrivilegeSeparation Specifies whether .Xr sshd 8 -@@ -1520,7 +1546,10 @@ restrictions. +@@ -1500,7 +1526,10 @@ The default is Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default is --.Dq none . -+.Dq %%SSH_VERSION_FREEBSD_PORT%% . +-.Cm none . ++.Cm %%SSH_VERSION_FREEBSD_PORT%% . +The value -+.Dq none ++.Cm none +may be used to disable this. .It Cm X11DisplayOffset Specifies the first display number available for .Xr sshd 8 Ns 's -@@ -1534,7 +1563,7 @@ The argument must be +@@ -1514,7 +1543,7 @@ The argument must be or - .Dq no . + .Cm no . The default is --.Dq no . -+.Dq yes . +-.Cm no . ++.Cm yes . .Pp When X11 forwarding is enabled, there may be additional exposure to the server and to client displays if the