27 files added
1 files modified
New file |
| | |
| | | # |
| | | # CDDL HEADER START |
| | | # |
| | | # The contents of this file are subject to the terms of the |
| | | # Common Development and Distribution License (the "License"). |
| | | # You may not use this file except in compliance with the License. |
| | | # |
| | | # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| | | # or http://www.opensolaris.org/os/licensing. |
| | | # See the License for the specific language governing permissions |
| | | # and limitations under the License. |
| | | # |
| | | # When distributing Covered Code, include this CDDL HEADER in each |
| | | # file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| | | # If applicable, add the following below this CDDL HEADER, with the |
| | | # fields enclosed by brackets "[]" replaced with your own identifying |
| | | # information: Portions Copyright [yyyy] [name of copyright owner] |
| | | # |
| | | # CDDL HEADER END |
| | | |
| | | # |
| | | # Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. |
| | | # Copyright 2018 Till Wegmüller |
| | | # Copyright 2019 Michal Nowak |
| | | # |
| | | |
| | | include ../../../make-rules/shared-macros.mk |
| | | |
| | | COMPONENT_NAME= hpn-ssh |
| | | COMPONENT_VERSION= 18.3.1 |
| | | COMPONENT_SUMMARY= High performance SSH/SCP |
| | | COMPONENT_SRC= $(COMPONENT_NAME)-hpn-$(HUMAN_VERSION) |
| | | COMPONENT_PROJECT_URL= https://www.psc.edu/hpn-ssh-home/ |
| | | COMPONENT_ARCHIVE= $(COMPONENT_SRC).tar.gz |
| | | COMPONENT_ARCHIVE_HASH= sha256:7165ecef8ae008aff8e317a5f0d2f546e56d5173ae82a51fa75525dcba67d48f |
| | | COMPONENT_ARCHIVE_URL= https://github.com/rapier1/hpn-ssh/archive/refs/tags/hpn-$(HUMAN_VERSION).tar.gz |
| | | COMPONENT_FMRI= network/hpn-ssh |
| | | COMPONENT_LICENSE= BSD, BSD-like |
| | | COMPONENT_LICENSE_FILE= LICENCE |
| | | |
| | | COMPONENT_SUMMARY.$(COMPONENT_NAME)= $(COMPONENT_SUMMARY) - client and utilities |
| | | |
| | | COMPONENT_FMRI.$(COMPONENT_NAME)-service= service/$(COMPONENT_FMRI) |
| | | COMPONENT_SUMMARY.$(COMPONENT_NAME)-service= $(COMPONENT_SUMMARY) - servers and services |
| | | |
| | | TEST_TARGET= $(SKIP_TEST) |
| | | include $(WS_MAKE_RULES)/common.mk |
| | | |
| | | COMPONENT_PREP_ACTION = ( cd $(@D) ; autoreconf -f -i ) |
| | | |
| | | # Enable various fixes and enhancements implemented by patches |
| | | CFLAGS += -DSET_USE_PAM |
| | | CFLAGS += -DPAM_ENHANCEMENT |
| | | CFLAGS += -DPAM_BUGFIX |
| | | CFLAGS += -DDTRACE_SFTP |
| | | CFLAGS += -DDISABLE_BANNER |
| | | CFLAGS += -DDEPRECATE_SUNSSH_OPT |
| | | CFLAGS += -DPER_SESSION_XAUTHFILE |
| | | |
| | | # configure is unable to find OpenSSL headers without this workaround |
| | | CFLAGS += -I$(OPENSSL_INCDIR) |
| | | |
| | | # We need to disable lazyloading of dynamic dependent libraries. During the |
| | | # pre-authentication phase, hpnsshd will chroot to /var/empty which doesn't |
| | | # contain any files. If we use lazyloading, hpnsshd will fail to find any |
| | | # libraries that it needs. |
| | | LDFLAGS += -B direct -z nolazyload |
| | | |
| | | # configure is unable to find OpenSSL libraries by default so we need to pass |
| | | # OPENSSL_LIBDIR to --with-ssl-dir as a workaround |
| | | CONFIGURE_OPTIONS += --with-ssl-dir=$(OPENSSL_LIBDIR) |
| | | CONFIGURE_OPTIONS += --with-ssl-engine |
| | | CONFIGURE_OPTIONS += --with-audit=solaris |
| | | CONFIGURE_OPTIONS += --with-libedit |
| | | CONFIGURE_OPTIONS += --with-kerberos5 |
| | | CONFIGURE_OPTIONS += --with-pam |
| | | CONFIGURE_OPTIONS += --with-sandbox=solaris |
| | | CONFIGURE_OPTIONS += --with-solaris-contracts |
| | | CONFIGURE_OPTIONS += --with-solaris-privs |
| | | CONFIGURE_OPTIONS += --with-solaris-projects |
| | | CONFIGURE_OPTIONS += --with-tcp-wrappers |
| | | CONFIGURE_OPTIONS += --with-4in6 |
| | | CONFIGURE_OPTIONS += --with-xauth=/usr/bin/xauth |
| | | CONFIGURE_OPTIONS += --enable-strip=no |
| | | CONFIGURE_OPTIONS += --without-rpath |
| | | CONFIGURE_OPTIONS += --disable-lastlog |
| | | CONFIGURE_OPTIONS += --sysconfdir=$(ETCDIR) |
| | | |
| | | # Install hpnssh-copy-id and its man page |
| | | COMPONENT_POST_INSTALL_ACTION += $(INSTALL) -Dm755 $(SOURCE_DIR)/contrib/hpnssh-copy-id $(PROTOUSRBINDIR)/hpnssh-copy-id ; |
| | | COMPONENT_POST_INSTALL_ACTION += $(INSTALL) -Dm644 $(SOURCE_DIR)/contrib/hpnssh-copy-id.1 $(PROTOUSRSHAREMAN1DIR)/hpnssh-copy-id.1 ; |
| | | |
| | | # Install the service related files |
| | | COMPONENT_POST_INSTALL_ACTION += $(INSTALL) -Dm0444 $(COMPONENT_DIR)/files/hpnssh.xml $(PROTO_DIR)/lib/svc/manifest/network/hpnssh.xml ; |
| | | COMPONENT_POST_INSTALL_ACTION += $(INSTALL) -Dm0555 $(COMPONENT_DIR)/files/hpnsshd $(PROTO_DIR)/lib/svc/method/hpnsshd ; |
| | | |
| | | COMPONENT_TEST_TARGETS = tests |
| | | |
| | | # Auto-generated dependencies |
| | | REQUIRED_PACKAGES += SUNWcs |
| | | REQUIRED_PACKAGES += library/libedit |
| | | REQUIRED_PACKAGES += library/security/openssl-31 |
| | | REQUIRED_PACKAGES += library/zlib |
| | | REQUIRED_PACKAGES += network/ssh-askpass |
| | | REQUIRED_PACKAGES += service/security/kerberos-5 |
| | | REQUIRED_PACKAGES += shell/bash |
| | | REQUIRED_PACKAGES += shell/ksh93 |
| | | REQUIRED_PACKAGES += system/library |
| | | REQUIRED_PACKAGES += system/library/security/gss |
| | | REQUIRED_PACKAGES += x11/session/xauth |
New file |
| | |
| | | <?xml version="1.0"?> |
| | | <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> |
| | | <!-- |
| | | CDDL HEADER START |
| | | |
| | | The contents of this file are subject to the terms of the |
| | | Common Development and Distribution License (the "License"). |
| | | You may not use this file except in compliance with the License. |
| | | |
| | | You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| | | or http://www.opensolaris.org/os/licensing. |
| | | See the License for the specific language governing permissions |
| | | and limitations under the License. |
| | | |
| | | When distributing Covered Code, include this CDDL HEADER in each |
| | | file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| | | If applicable, add the following below this CDDL HEADER, with the |
| | | fields enclosed by brackets "[]" replaced with your own identifying |
| | | information: Portions Copyright [yyyy] [name of copyright owner] |
| | | |
| | | CDDL HEADER END |
| | | |
| | | Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
| | | Use is subject to license terms. |
| | | |
| | | Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> |
| | | |
| | | NOTE: This service manifest is not editable; its contents will |
| | | be overwritten by package or patch operations, including |
| | | operating system upgrade. Make customizations in a different |
| | | file. |
| | | --> |
| | | |
| | | <service_bundle type='manifest' name='network/hpnssh'> |
| | | |
| | | <service |
| | | name='network/hpnssh' |
| | | type='service' |
| | | version='1'> |
| | | |
| | | <create_default_instance enabled='false' /> |
| | | |
| | | <single_instance /> |
| | | |
| | | <dependency name='fs-local' |
| | | grouping='require_all' |
| | | restart_on='none' |
| | | type='service'> |
| | | <service_fmri |
| | | value='svc:/system/filesystem/local' /> |
| | | </dependency> |
| | | |
| | | <dependency name='fs-autofs' |
| | | grouping='optional_all' |
| | | restart_on='none' |
| | | type='service'> |
| | | <service_fmri value='svc:/system/filesystem/autofs' /> |
| | | </dependency> |
| | | |
| | | <dependency name='net-loopback' |
| | | grouping='require_all' |
| | | restart_on='none' |
| | | type='service'> |
| | | <service_fmri value='svc:/network/loopback' /> |
| | | </dependency> |
| | | |
| | | <dependency name='net-physical' |
| | | grouping='require_all' |
| | | restart_on='none' |
| | | type='service'> |
| | | <service_fmri value='svc:/network/physical' /> |
| | | </dependency> |
| | | |
| | | <dependency name='cryptosvc' |
| | | grouping='require_all' |
| | | restart_on='none' |
| | | type='service'> |
| | | <service_fmri value='svc:/system/cryptosvc' /> |
| | | </dependency> |
| | | |
| | | <dependency name='utmp' |
| | | grouping='require_all' |
| | | restart_on='none' |
| | | type='service'> |
| | | <service_fmri value='svc:/system/utmp' /> |
| | | </dependency> |
| | | |
| | | <dependency name='network_ipfilter' |
| | | grouping='optional_all' |
| | | restart_on='error' |
| | | type='service'> |
| | | <service_fmri value='svc:/network/ipfilter:default' /> |
| | | </dependency> |
| | | |
| | | <dependency name='config_data' |
| | | grouping='require_all' |
| | | restart_on='restart' |
| | | type='path'> |
| | | <service_fmri |
| | | value='file://localhost/etc/hpnssh/sshd_config' /> |
| | | </dependency> |
| | | |
| | | <dependent |
| | | name='hpnssh_multi-user-server' |
| | | grouping='optional_all' |
| | | restart_on='none'> |
| | | <service_fmri |
| | | value='svc:/milestone/multi-user-server' /> |
| | | </dependent> |
| | | |
| | | <exec_method |
| | | type='method' |
| | | name='start' |
| | | exec='/lib/svc/method/hpnsshd start' |
| | | timeout_seconds='60'> |
| | | <method_context security_flags="current"/> |
| | | </exec_method> |
| | | |
| | | <exec_method |
| | | type='method' |
| | | name='stop' |
| | | exec=':kill' |
| | | timeout_seconds='60' /> |
| | | |
| | | <exec_method |
| | | type='method' |
| | | name='refresh' |
| | | exec=':kill -HUP' |
| | | timeout_seconds='60' /> |
| | | |
| | | <property_group name='startd' |
| | | type='framework'> |
| | | <!-- sub-process core dumps shouldn't restart session --> |
| | | <propval name='ignore_error' |
| | | type='astring' value='core,signal' /> |
| | | </property_group> |
| | | |
| | | <property_group name='general' type='framework'> |
| | | <!-- to start stop sshd --> |
| | | <propval name='action_authorization' type='astring' |
| | | value='solaris.smf.manage.ssh' /> |
| | | </property_group> |
| | | |
| | | <property_group name='firewall_context' type='com.sun,fw_definition'> |
| | | <propval name='name' type='astring' value='hpnssh' /> |
| | | <propval name='ipf_method' type='astring' |
| | | value='/lib/svc/method/hpnsshd ipfilter' /> |
| | | </property_group> |
| | | |
| | | <property_group name='firewall_config' type='com.sun,fw_configuration'> |
| | | <propval name='policy' type='astring' value='use_global' /> |
| | | <propval name='block_policy' type='astring' |
| | | value='use_global' /> |
| | | <propval name='apply_to' type='astring' value='' /> |
| | | <propval name='apply_to_6' type='astring' value='' /> |
| | | <propval name='exceptions' type='astring' value='' /> |
| | | <propval name='exceptions_6' type='astring' value='' /> |
| | | <propval name='target' type='astring' value='' /> |
| | | <propval name='target_6' type='astring' value='' /> |
| | | <propval name='value_authorization' type='astring' |
| | | value='solaris.smf.value.firewall.config' /> |
| | | </property_group> |
| | | |
| | | <stability value='Unstable' /> |
| | | |
| | | <template> |
| | | <common_name> |
| | | <loctext xml:lang='C'> |
| | | HPN-SSH server |
| | | </loctext> |
| | | </common_name> |
| | | <documentation> |
| | | <manpage title='hpnsshd' section='8' manpath='/usr/share/man' /> |
| | | </documentation> |
| | | </template> |
| | | |
| | | </service> |
| | | |
| | | </service_bundle> |
New file |
| | |
| | | #!/sbin/sh |
| | | # |
| | | # Copyright 2010 Sun Microsystems, Inc. All rights reserved. |
| | | # Use is subject to license terms. |
| | | # |
| | | # Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> |
| | | # Copyright 2023 Klaus Ziegler |
| | | # |
| | | |
| | | . /lib/svc/share/ipf_include.sh |
| | | . /lib/svc/share/smf_include.sh |
| | | |
| | | SSHDIR=/etc/hpnssh |
| | | |
| | | create_ipf_rules() |
| | | { |
| | | FMRI=$1 |
| | | ipf_file=`fmri_to_file ${FMRI} $IPF_SUFFIX` |
| | | ipf6_file=`fmri_to_file ${FMRI} $IPF6_SUFFIX` |
| | | policy=`get_policy ${FMRI}` |
| | | |
| | | # |
| | | # Get port from the sshd_config file |
| | | # |
| | | tports=`grep "^Port" "$SSHDIR/sshd_config" 2>/dev/null | \ |
| | | awk '{print $2}'` |
| | | |
| | | echo "# $FMRI" >$ipf_file |
| | | echo "# $FMRI" >$ipf6_file |
| | | for port in $tports; do |
| | | generate_rules $FMRI $policy "tcp" $port $ipf_file |
| | | generate_rules $FMRI $policy "tcp" $port $ipf6_file _6 |
| | | done |
| | | } |
| | | |
| | | # This script is being used as part of an SMF |
| | | # start/stop/refresh method for HPN-SSH server. |
| | | # Note: there is no refresh/restart switch defined, |
| | | # because this is done by the SMF restarter property. |
| | | # |
| | | |
| | | case $1 in |
| | | |
| | | 'ipfilter') |
| | | create_ipf_rules $2 |
| | | ;; |
| | | |
| | | 'start') |
| | | # |
| | | # If host keys don't exist when the service is started, create them. |
| | | # |
| | | /usr/bin/hpnssh-keygen -A |
| | | |
| | | /usr/sbin/hpnsshd |
| | | ;; |
| | | |
| | | *) |
| | | echo "Usage: $0 { start | restart }" |
| | | exit 1 |
| | | ;; |
| | | esac |
| | | |
| | | exit $? |
New file |
| | |
| | | # |
| | | # CDDL HEADER START |
| | | # |
| | | # The contents of this file are subject to the terms of the |
| | | # Common Development and Distribution License (the "License"). |
| | | # You may not use this file except in compliance with the License. |
| | | # |
| | | # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| | | # or http://www.opensolaris.org/os/licensing. |
| | | # See the License for the specific language governing permissions |
| | | # and limitations under the License. |
| | | # |
| | | # When distributing Covered Code, include this CDDL HEADER in each |
| | | # file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| | | # If applicable, add the following below this CDDL HEADER, with # fields enclosed by brackets "[]" replaced with your own identifying |
| | | # information: Portions Copyright [yyyy] [name of copyright owner] |
| | | # |
| | | # CDDL HEADER END |
| | | # |
| | | # Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. |
| | | # |
| | | |
| | | <transform file path=usr/sbin/hpnsshd$ -> default restart_fmri svc:/network/hpnssh:default> |
| | | <transform file path=usr/libexec/hpnssh-keysign$ -> default mode 4555> |
| | | <transform file path=etc/hpnssh/sshd_config$ -> default mode 0644> |
| | | <transform file path=etc/hpnssh/sshd_config$ -> default preserve true> |
| | | |
| | | set name=pkg.fmri value=pkg:/$(COMPONENT_FMRI)@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION) |
| | | set name=pkg.human-version value=$(HUMAN_VERSION) |
| | | set name=pkg.summary value="$(COMPONENT_SUMMARY)" |
| | | set name=info.classification \ |
| | | value=org.opensolaris.category.2008:Applications/Internet \ |
| | | value=org.opensolaris.category.2008:System/Security |
| | | set name=info.upstream-url value=$(COMPONENT_PROJECT_URL) |
| | | set name=info.source-url value=$(COMPONENT_ARCHIVE_URL) |
| | | set name=org.opensolaris.consolidation value=$(CONSOLIDATION) |
| | | |
| | | license $(COMPONENT_LICENSE_FILE) license='$(COMPONENT_LICENSE)' |
| | | |
| | | dir path=var/empty owner=root group=sys mode=0755 sysattr=readonly |
| | | |
| | | group groupname=hpnsshd gid=24 |
| | | user username=hpnsshd ftpuser=false gcos-field="hpnsshd privsep" group=hpnsshd \ |
| | | home-dir=/var/empty login-shell=/bin/false uid=24 |
| | | |
| | | depend type=require fmri=pkg:/network/hpn-ssh |
| | | |
| | | file path=etc/hpnssh/moduli |
| | | file path=etc/hpnssh/sshd_config |
| | | file path=lib/svc/manifest/network/hpnssh.xml |
| | | file path=lib/svc/method/hpnsshd |
| | | file path=usr/lib/dtrace/hpnsftp.d |
| | | file path=usr/libexec/hpnsftp-server |
| | | file path=usr/libexec/hpnssh-keysign |
| | | file path=usr/libexec/hpnssh-pkcs11-helper |
| | | file path=usr/libexec/hpnssh-sk-helper |
| | | file path=usr/sbin/hpnsshd |
| | | file path=usr/share/man/man5/hpnmoduli.5 |
| | | file path=usr/share/man/man5/hpnsshd_config.5 |
| | | file path=usr/share/man/man8/hpnsftp-server.8 |
| | | file path=usr/share/man/man8/hpnssh-keysign.8 |
| | | file path=usr/share/man/man8/hpnssh-pkcs11-helper.8 |
| | | file path=usr/share/man/man8/hpnssh-sk-helper.8 |
| | | file path=usr/share/man/man8/hpnsshd.8 |
New file |
| | |
| | | # |
| | | # This file and its contents are supplied under the terms of the |
| | | # Common Development and Distribution License ("CDDL"), version 1.0. |
| | | # You may only use this file in accordance with the terms of version |
| | | # 1.0 of the CDDL. |
| | | # |
| | | # A full copy of the text of the CDDL should have accompanied this |
| | | # source. A copy of the CDDL is also available via the Internet at |
| | | # http://www.illumos.org/license/CDDL. |
| | | # |
| | | |
| | | # |
| | | # Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. |
| | | # Copyright 2018 Till Wegmüller |
| | | # |
| | | |
| | | # A full copy of the text of the CDDL should have accompanied this |
| | | set name=pkg.fmri value=pkg:/$(COMPONENT_FMRI)@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION) |
| | | set name=pkg.human-version value=$(HUMAN_VERSION) |
| | | set name=pkg.summary value="$(COMPONENT_SUMMARY)" |
| | | set name=info.classification \ |
| | | value=org.opensolaris.category.2008:Applications/Internet \ |
| | | value=org.opensolaris.category.2008:System/Security |
| | | set name=info.upstream-url value=$(COMPONENT_PROJECT_URL) |
| | | set name=info.source-url value=$(COMPONENT_ARCHIVE_URL) |
| | | set name=org.opensolaris.consolidation value=$(CONSOLIDATION) |
| | | |
| | | license $(COMPONENT_LICENSE_FILE) license='$(COMPONENT_LICENSE)' |
| | | |
| | | <transform file path=etc/hpnssh/ssh_config$ -> default preserve true> |
| | | <transform file path=etc/hpnssh/ssh_config$ -> default mode 0644> |
| | | |
| | | depend type=conditional fmri=pkg:/x11/session/xauth \ |
| | | predicate=pkg:/x11/library/libxau |
| | | |
| | | depend type=conditional fmri=pkg:/network/ssh-askpass \ |
| | | predicate=pkg:/x11/server/xserver-common |
| | | |
| | | file path=etc/hpnssh/ssh_config |
| | | file path=usr/bin/hpnscp |
| | | file path=usr/bin/hpnsftp |
| | | file path=usr/bin/hpnssh |
| | | file path=usr/bin/hpnssh-add |
| | | file path=usr/bin/hpnssh-agent |
| | | file path=usr/bin/hpnssh-copy-id |
| | | file path=usr/bin/hpnssh-keygen |
| | | file path=usr/bin/hpnssh-keyscan |
| | | file path=usr/share/man/man1/hpnscp.1 |
| | | file path=usr/share/man/man1/hpnsftp.1 |
| | | file path=usr/share/man/man1/hpnssh-add.1 |
| | | file path=usr/share/man/man1/hpnssh-agent.1 |
| | | file path=usr/share/man/man1/hpnssh-copy-id.1 |
| | | file path=usr/share/man/man1/hpnssh-keygen.1 |
| | | file path=usr/share/man/man1/hpnssh-keyscan.1 |
| | | file path=usr/share/man/man1/hpnssh.1 |
| | | file path=usr/share/man/man5/hpnssh_config.5 |
New file |
| | |
| | | # |
| | | # This file and its contents are supplied under the terms of the |
| | | # Common Development and Distribution License ("CDDL"), version 1.0. |
| | | # You may only use this file in accordance with the terms of version |
| | | # 1.0 of the CDDL. |
| | | # |
| | | # A full copy of the text of the CDDL should have accompanied this |
| | | # source. A copy of the CDDL is also available via the Internet at |
| | | # http://www.illumos.org/license/CDDL. |
| | | # |
| | | |
| | | # |
| | | # Copyright 2024 <contributor> |
| | | # |
| | | |
| | | set name=pkg.fmri value=pkg:/$(COMPONENT_FMRI)@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION) |
| | | set name=pkg.human-version value=$(HUMAN_VERSION) |
| | | set name=pkg.summary value="$(COMPONENT_SUMMARY)" |
| | | set name=info.classification value="$(COMPONENT_CLASSIFICATION)" |
| | | set name=info.upstream-url value=$(COMPONENT_PROJECT_URL) |
| | | set name=info.source-url value=$(COMPONENT_ARCHIVE_URL) |
| | | set name=org.opensolaris.consolidation value=$(CONSOLIDATION) |
| | | |
| | | license $(COMPONENT_LICENSE_FILE) license='$(COMPONENT_LICENSE)' |
| | | |
| | | file path=etc/hpnssh/moduli |
| | | file path=etc/hpnssh/ssh_config |
| | | file path=etc/hpnssh/sshd_config |
| | | file path=lib/svc/manifest/network/hpnssh.xml |
| | | file path=lib/svc/method/hpnsshd |
| | | file path=usr/bin/hpnscp |
| | | file path=usr/bin/hpnsftp |
| | | file path=usr/bin/hpnssh |
| | | file path=usr/bin/hpnssh-add |
| | | file path=usr/bin/hpnssh-agent |
| | | file path=usr/bin/hpnssh-copy-id |
| | | file path=usr/bin/hpnssh-keygen |
| | | file path=usr/bin/hpnssh-keyscan |
| | | file path=usr/lib/dtrace/hpnsftp.d |
| | | file path=usr/libexec/hpnsftp-server |
| | | file path=usr/libexec/hpnssh-keysign |
| | | file path=usr/libexec/hpnssh-pkcs11-helper |
| | | file path=usr/libexec/hpnssh-sk-helper |
| | | file path=usr/sbin/hpnsshd |
| | | file path=usr/share/man/man1/hpnscp.1 |
| | | file path=usr/share/man/man1/hpnsftp.1 |
| | | file path=usr/share/man/man1/hpnssh-add.1 |
| | | file path=usr/share/man/man1/hpnssh-agent.1 |
| | | file path=usr/share/man/man1/hpnssh-copy-id.1 |
| | | file path=usr/share/man/man1/hpnssh-keygen.1 |
| | | file path=usr/share/man/man1/hpnssh-keyscan.1 |
| | | file path=usr/share/man/man1/hpnssh.1 |
| | | file path=usr/share/man/man5/hpnmoduli.5 |
| | | file path=usr/share/man/man5/hpnssh_config.5 |
| | | file path=usr/share/man/man5/hpnsshd_config.5 |
| | | file path=usr/share/man/man8/hpnsftp-server.8 |
| | | file path=usr/share/man/man8/hpnssh-keysign.8 |
| | | file path=usr/share/man/man8/hpnssh-pkcs11-helper.8 |
| | | file path=usr/share/man/man8/hpnssh-sk-helper.8 |
| | | file path=usr/share/man/man8/hpnsshd.8 |
New file |
| | |
| | | # |
| | | # This change is to remove some misleading error messages when running |
| | | # "gmake install". OpenSSH mixes the building and running together. Some |
| | | # system setup checking for running the program needs to be removed, because |
| | | # they are not suitable in a build system. This is for OpenIndiana only, so we |
| | | # will not contribute back this change to the upstream community. |
| | | # |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/Makefile.in.orig |
| | | +++ hpn-ssh-hpn-18.3.1/Makefile.in |
| | | @@ -424,7 +424,16 @@ |
| | | install-nosysconf: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files |
| | | |
| | | check-config: |
| | | - -$(DESTDIR)$(sbindir)/hpnsshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config |
| | | +# On OpenIndiana, to workaround OpenSSH's unlucky mixing of 'building ssh' and |
| | | +# 'running ssh', on build machine the following requisites shouldn't be |
| | | +# enforced: |
| | | +# 1) existence of privsep user hpnsshd |
| | | +# 2) existence of privsep directory /var/empty |
| | | +# 3) read permissions for /etc/hpnssh/ssh_host_[rsa,dsa]_key |
| | | +# |
| | | +# -$(DESTDIR)$(sbindir)/hpnsshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config |
| | | +# |
| | | + @echo 'OpenIndiana: skipping check-config' |
| | | |
| | | install-files: |
| | | $(MKDIR_P) $(DESTDIR)$(bindir) |
New file |
| | |
| | | # |
| | | # To comply to the Solaris PAM policy, the UsePAM option is changed to be |
| | | # always on and not configurable on Solaris. This is for Solaris only, so we |
| | | # will not contribute the changes to the upstream community. |
| | | # |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/servconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.c |
| | | @@ -285,7 +285,12 @@ |
| | | |
| | | /* Portable-specific options */ |
| | | if (options->use_pam == -1) |
| | | +#ifdef SET_USE_PAM |
| | | + /* use_pam should be always set to 1 on Solaris */ |
| | | + options->use_pam = 1; |
| | | +#else |
| | | options->use_pam = 0; |
| | | +#endif |
| | | |
| | | /* Standard Options */ |
| | | if (options->num_host_key_files == 0) { |
| | | @@ -1392,8 +1397,17 @@ |
| | | switch (opcode) { |
| | | /* Portable-specific options */ |
| | | case sUsePAM: |
| | | +#ifdef SET_USE_PAM |
| | | + /* UsePAM is always on and not configurable on Solaris */ |
| | | + logit("%s line %d: ignoring UsePAM option value." |
| | | + " This option is always on.", filename, linenum); |
| | | + while (arg) |
| | | + arg = strdelim(&str); |
| | | + break; |
| | | +#else |
| | | intptr = &options->use_pam; |
| | | goto parse_flag; |
| | | +#endif |
| | | |
| | | /* Standard Options */ |
| | | case sBadOption: |
| | | --- hpn-ssh-hpn-18.3.1/sshd_config.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshd_config |
| | | @@ -70,17 +70,6 @@ |
| | | #GSSAPIAuthentication no |
| | | #GSSAPICleanupCredentials yes |
| | | |
| | | -# Set this to 'yes' to enable PAM authentication, account processing, |
| | | -# and session processing. If this is enabled, PAM authentication will |
| | | -# be allowed through the KbdInteractiveAuthentication and |
| | | -# PasswordAuthentication. Depending on your PAM configuration, |
| | | -# PAM authentication via KbdInteractiveAuthentication may bypass |
| | | -# the setting of "PermitRootLogin prohibit-password". |
| | | -# If you just want the PAM account and session checks to run without |
| | | -# PAM authentication, then enable this but set PasswordAuthentication |
| | | -# and KbdInteractiveAuthentication to 'no'. |
| | | -#UsePAM no |
| | | - |
| | | #AllowAgentForwarding yes |
| | | #AllowTcpForwarding yes |
| | | #GatewayPorts no |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/hpnsshd_config.5.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsshd_config.5 |
| | | @@ -1610,8 +1610,8 @@ |
| | | .Xr sshd 8 |
| | | should print the date and time of the last user login when a user logs |
| | | in interactively. |
| | | -The default is |
| | | -.Cm yes . |
| | | +On OpenIndiana this option is always ignored since pam_unix_session(7) |
| | | +reports the last login time. |
| | | .It Cm PrintMotd |
| | | Specifies whether |
| | | .Xr sshd 8 |
| | | @@ -2127,7 +2127,8 @@ |
| | | .El |
| | | .Sh SEE ALSO |
| | | .Xr sftp-server 8 , |
| | | -.Xr sshd 8 |
| | | +.Xr sshd 8 , |
| | | +.Xr pam_unix_session 7 |
| | | .Sh AUTHORS |
| | | .An -nosplit |
| | | OpenSSH is a derivative of the original and free |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/configure.ac.orig |
| | | +++ hpn-ssh-hpn-18.3.1/configure.ac |
| | | @@ -1161,6 +1161,9 @@ |
| | | ], |
| | | ) |
| | | TEST_SHELL=$SHELL # let configure find us a capable shell |
| | | + AC_DEFINE([USE_GSS_STORE_CRED], [1], [Use the Solaris-style GSS cred store]) |
| | | + AC_DEFINE([GSSAPI_STORECREDS_NEEDS_RUID], [1], [GSSAPI storecreds needs ruid]) |
| | | + AC_DEFINE([HAVE_PAM_AUSER], [1], [pam_auser]) |
| | | ;; |
| | | *-*-sunos4*) |
| | | CPPFLAGS="$CPPFLAGS -DSUNOS4" |
| | | --- hpn-ssh-hpn-18.3.1/gss-serv-krb5.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/gss-serv-krb5.c |
| | | @@ -109,7 +109,7 @@ |
| | | return retval; |
| | | } |
| | | |
| | | - |
| | | +#ifndef USE_GSS_STORE_CRED |
| | | /* This writes out any forwarded credentials from the structure populated |
| | | * during userauth. Called after we have setuid to the user */ |
| | | |
| | | @@ -195,6 +195,7 @@ |
| | | |
| | | return; |
| | | } |
| | | +#endif /* #ifndef USE_GSS_STORE_CRED */ |
| | | |
| | | ssh_gssapi_mech gssapi_kerberos_mech = { |
| | | "toWM5Slw5Ew8Mqkay+al2g==", |
| | | @@ -203,7 +204,11 @@ |
| | | NULL, |
| | | &ssh_gssapi_krb5_userok, |
| | | NULL, |
| | | +#ifdef USE_GSS_STORE_CRED |
| | | + NULL |
| | | +#else |
| | | &ssh_gssapi_krb5_storecreds |
| | | +#endif |
| | | }; |
| | | |
| | | #endif /* KRB5 */ |
| | | --- hpn-ssh-hpn-18.3.1/gss-serv.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/gss-serv.c |
| | | @@ -44,6 +44,7 @@ |
| | | #include "session.h" |
| | | #include "misc.h" |
| | | #include "servconf.h" |
| | | +#include "sshbuf.h" |
| | | |
| | | #include "ssh-gss.h" |
| | | |
| | | @@ -319,22 +320,66 @@ |
| | | void |
| | | ssh_gssapi_cleanup_creds(void) |
| | | { |
| | | +#ifdef USE_GSS_STORE_CRED |
| | | + debug("removing gssapi cred file not implemented"); |
| | | +#else |
| | | if (gssapi_client.store.filename != NULL) { |
| | | /* Unlink probably isn't sufficient */ |
| | | debug("removing gssapi cred file\"%s\"", |
| | | gssapi_client.store.filename); |
| | | unlink(gssapi_client.store.filename); |
| | | } |
| | | +#endif /* USE_GSS_STORE_CRED */ |
| | | } |
| | | |
| | | /* As user */ |
| | | void |
| | | ssh_gssapi_storecreds(void) |
| | | { |
| | | +#ifdef USE_GSS_STORE_CRED |
| | | + OM_uint32 maj_status, min_status; |
| | | + |
| | | + if (gssapi_client.creds == NULL) { |
| | | + debug("No credentials stored"); |
| | | + return; |
| | | + } |
| | | + |
| | | + maj_status = gss_store_cred(&min_status, gssapi_client.creds, |
| | | + GSS_C_INITIATE, &gssapi_client.mech->oid, 1, 1, NULL, NULL); |
| | | + |
| | | + if (GSS_ERROR(maj_status)) { |
| | | + struct sshbuf *b; |
| | | + gss_buffer_desc msg; |
| | | + OM_uint32 lmin; |
| | | + OM_uint32 more = 0; |
| | | + if ((b = sshbuf_new()) == NULL) fatal("malloc"); |
| | | + /* GSS-API error */ |
| | | + do { |
| | | + gss_display_status(&lmin, maj_status, GSS_C_GSS_CODE, |
| | | + GSS_C_NULL_OID, &more, &msg); |
| | | + sshbuf_put(b, msg.value, msg.length); |
| | | + sshbuf_put(b, "\n", 1); |
| | | + gss_release_buffer(&lmin, &msg); |
| | | + } while (more != 0); |
| | | + /* Mechanism specific error */ |
| | | + do { |
| | | + gss_display_status(&lmin, min_status, GSS_C_MECH_CODE, |
| | | + &gssapi_client.mech->oid, &more, &msg); |
| | | + sshbuf_put(b, msg.value, msg.length); |
| | | + sshbuf_put(b, "\n", 1); |
| | | + gss_release_buffer(&lmin, &msg); |
| | | + } while (more != 0); |
| | | + sshbuf_put(b, "\0", 1); |
| | | + error("GSS-API error while storing delegated credentials: %s", |
| | | + sshbuf_ptr(b)); |
| | | + sshbuf_free(b); |
| | | + } |
| | | +#else /* #ifdef USE_GSS_STORE_CRED */ |
| | | if (gssapi_client.mech && gssapi_client.mech->storecreds) { |
| | | (*gssapi_client.mech->storecreds)(&gssapi_client); |
| | | } else |
| | | debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); |
| | | +#endif /* #ifdef USE_GSS_STORE_CRED */ |
| | | } |
| | | |
| | | /* This allows GSSAPI methods to do things to the child's environment based |
| | | --- hpn-ssh-hpn-18.3.1/servconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.c |
| | | @@ -624,7 +624,11 @@ |
| | | { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, |
| | | #ifdef GSSAPI |
| | | { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, |
| | | +#ifdef USE_GSS_STORE_CRED |
| | | + { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, |
| | | +#else /* USE_GSS_STORE_CRED */ |
| | | { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, |
| | | +#endif /* USE_GSS_STORE_CRED */ |
| | | { "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL }, |
| | | #else |
| | | { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, |
| | | --- hpn-ssh-hpn-18.3.1/sshd.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshd.c |
| | | @@ -2313,9 +2313,23 @@ |
| | | |
| | | #ifdef GSSAPI |
| | | if (options.gss_authentication) { |
| | | +#ifdef GSSAPI_STORECREDS_NEEDS_RUID |
| | | + if (setreuid(authctxt->pw->pw_uid, -1) != 0) { |
| | | + debug("setreuid %u: %.100s", |
| | | + (u_int) authctxt->pw->pw_uid, strerror(errno)); |
| | | + goto bail_storecred; |
| | | + } |
| | | +#endif |
| | | temporarily_use_uid(authctxt->pw); |
| | | ssh_gssapi_storecreds(); |
| | | restore_uid(); |
| | | +#ifdef GSSAPI_STORECREDS_NEEDS_RUID |
| | | + if (setuid(geteuid()) != 0) { |
| | | + fatal("setuid %u: %.100s", (u_int) geteuid(), |
| | | + strerror(errno)); |
| | | + } |
| | | + bail_storecred: ; |
| | | +#endif |
| | | } |
| | | #endif |
| | | #ifdef USE_PAM |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/Makefile.in.orig |
| | | +++ hpn-ssh-hpn-18.3.1/Makefile.in |
| | | @@ -103,6 +103,7 @@ |
| | | monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ |
| | | ssh-ed25519-sk.o ssh-rsa.o dh.o \ |
| | | msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ |
| | | + sftp_provider.o \ |
| | | ssh-pkcs11.o smult_curve25519_ref.o \ |
| | | poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ |
| | | cipher-chachapoly-libcrypto-mt.o \ |
| | | @@ -133,7 +134,7 @@ |
| | | srclimit.o sftp-server.o sftp-common.o \ |
| | | sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ |
| | | sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ |
| | | - sandbox-solaris.o uidswap.o cipher-switch.o $(SKOBJS) |
| | | + sandbox-solaris.o uidswap.o cipher-switch.o sftp_provider.o $(SKOBJS) |
| | | |
| | | SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o |
| | | |
| | | @@ -153,7 +154,8 @@ |
| | | |
| | | SSHKEYSCAN_OBJS=ssh-keyscan.o $(SKOBJS) |
| | | |
| | | -SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o |
| | | +SFTPSERVER_OBJS=sftp-common.o sftp-server.o sftp-server-main.o sftp_provider.o |
| | | +ROOTDLIBDIR=$(DESTDIR)/usr/lib/dtrace |
| | | |
| | | SFTP_OBJS= sftp.o sftp-usergroup.o progressmeter.o $(SFTP_CLIENT_OBJS) |
| | | |
| | | @@ -266,9 +268,22 @@ |
| | | moduli: |
| | | echo |
| | | |
| | | +# dtrace sftp |
| | | +sftp_provider.h: $(srcdir)/sftp_provider.d |
| | | + /usr/sbin/dtrace -xnolibs -h -s $(srcdir)/sftp_provider.d \ |
| | | + -o $(srcdir)/sftp_provider.h |
| | | + |
| | | +sftp_provider.o: sftp_provider.d sftp_provider.h sftp-server.o |
| | | + /usr/sbin/dtrace -G -64 -xnolibs -s $(srcdir)/sftp_provider.d \ |
| | | + sftp-server.o -o sftp_provider.o |
| | | + |
| | | +# special case for sftp-server.o, it includes sftp_provider.h |
| | | +sftp-server.o: sftp_provider.h sftp-server.c |
| | | + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $(srcdir)/sftp-server.c |
| | | + |
| | | clean: regressclean |
| | | rm -f *.o *.lo *.a $(TARGETS) logintest config.cache config.log |
| | | - rm -f *.out core survey |
| | | + rm -f *.out core survey sftp_provider.h |
| | | rm -f regress/check-perm$(EXEEXT) |
| | | rm -f regress/mkdtemp$(EXEEXT) |
| | | rm -f regress/unittests/test_helper/*.a |
| | | @@ -470,6 +485,7 @@ |
| | | $(INSTALL) -m 644 hpnssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/hpnssh-keysign.8 |
| | | $(INSTALL) -m 644 hpnssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/hpnssh-pkcs11-helper.8 |
| | | $(INSTALL) -m 644 hpnssh-sk-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/hpnssh-sk-helper.8 |
| | | + mkdir -p $(ROOTDLIBDIR) && cp $(srcdir)/hpnsftp.d $(ROOTDLIBDIR)/ |
| | | |
| | | install-sysconf: |
| | | $(MKDIR_P) $(DESTDIR)$(sysconfdir) |
| | | --- hpn-ssh-hpn-18.3.1/sftp-server.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sftp-server.c |
| | | @@ -56,6 +56,9 @@ |
| | | |
| | | #include "sftp.h" |
| | | #include "sftp-common.h" |
| | | +#ifdef DTRACE_SFTP |
| | | +#include "sftp_provider_impl.h" |
| | | +#endif |
| | | |
| | | char *sftp_realpath(const char *, char *); /* sftp-realpath.c */ |
| | | |
| | | @@ -803,14 +806,17 @@ |
| | | u_int32_t len; |
| | | int r, handle, fd, ret, status = SSH2_FX_FAILURE; |
| | | u_int64_t off; |
| | | + char *fpath; |
| | | |
| | | if ((r = get_handle(iqueue, &handle)) != 0 || |
| | | (r = sshbuf_get_u64(iqueue, &off)) != 0 || |
| | | (r = sshbuf_get_u32(iqueue, &len)) != 0) |
| | | fatal_fr(r, "parse"); |
| | | |
| | | + fpath = handle_to_name(handle); |
| | | + |
| | | debug("request %u: read \"%s\" (handle %d) off %llu len %u", |
| | | - id, handle_to_name(handle), handle, (unsigned long long)off, len); |
| | | + id, fpath, handle, (unsigned long long)off, len); |
| | | if ((fd = handle_to_fd(handle)) == -1) |
| | | goto out; |
| | | if (len > SFTP_MAX_READ_LENGTH) { |
| | | @@ -829,6 +835,9 @@ |
| | | strerror(errno)); |
| | | goto out; |
| | | } |
| | | +#ifdef DTRACE_SFTP |
| | | + SFTP_TRANSFER_START_OP("read", fd, fpath, len); |
| | | +#endif |
| | | if (len == 0) { |
| | | /* weird, but not strictly disallowed */ |
| | | ret = 0; |
| | | @@ -841,11 +850,18 @@ |
| | | status = SSH2_FX_EOF; |
| | | goto out; |
| | | } |
| | | +#ifdef DTRACE_SFTP |
| | | + SFTP_TRANSFER_DONE_OP("read", fd, fpath, ret); |
| | | +#endif |
| | | send_data(id, buf, ret); |
| | | handle_update_read(handle, ret); |
| | | /* success */ |
| | | status = SSH2_FX_OK; |
| | | out: |
| | | +#ifdef DTRACE_SFTP |
| | | + if (status != SSH2_FX_OK) |
| | | + SFTP_TRANSFER_DONE_OP("read", fd, fpath, ret); |
| | | +#endif |
| | | if (status != SSH2_FX_OK) |
| | | send_status(id, status); |
| | | } |
| | | @@ -857,14 +873,17 @@ |
| | | size_t len; |
| | | int r, handle, fd, ret, status; |
| | | u_char *data; |
| | | + char *fpath; |
| | | |
| | | if ((r = get_handle(iqueue, &handle)) != 0 || |
| | | (r = sshbuf_get_u64(iqueue, &off)) != 0 || |
| | | (r = sshbuf_get_string(iqueue, &data, &len)) != 0) |
| | | fatal_fr(r, "parse"); |
| | | |
| | | + fpath = handle_to_name(handle); |
| | | + |
| | | debug("request %u: write \"%s\" (handle %d) off %llu len %zu", |
| | | - id, handle_to_name(handle), handle, (unsigned long long)off, len); |
| | | + id, fpath, handle, (unsigned long long)off, len); |
| | | fd = handle_to_fd(handle); |
| | | |
| | | if (fd < 0) |
| | | @@ -877,7 +896,13 @@ |
| | | strerror(errno)); |
| | | } else { |
| | | /* XXX ATOMICIO ? */ |
| | | +#ifdef DTRACE_SFTP |
| | | + SFTP_TRANSFER_START_OP("write", fd, fpath, len); |
| | | +#endif |
| | | ret = write(fd, data, len); |
| | | +#ifdef DTRACE_SFTP |
| | | + SFTP_TRANSFER_DONE_OP("write", fd, fpath, ret); |
| | | +#endif |
| | | if (ret == -1) { |
| | | status = errno_to_portable(errno); |
| | | error_f("write \"%.100s\": %s", |
| | | --- /dev/null |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsftp.d |
| | | @@ -0,0 +1,56 @@ |
| | | +/* |
| | | + * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. |
| | | + */ |
| | | + |
| | | +#pragma D depends_on library net.d |
| | | +#pragma D depends_on library io.d |
| | | +#pragma D depends_on module lofs |
| | | + |
| | | +typedef struct sftpinfo { |
| | | + string sfi_user; /* user name */ |
| | | + string sfi_operation; /* SFTP Operation */ |
| | | + ssize_t sfi_nbytes; /* bytes transferred, if any */ |
| | | + string sfi_pathname; /* pathname of transfer */ |
| | | + string sfi_fsresource; /* Dataset(ZFS) or resource name */ |
| | | +} sftpinfo_t; |
| | | + |
| | | +/* |
| | | + * This structure must match the definition of same in sftp_provider_impl.h. |
| | | + */ |
| | | +typedef struct sftpproto { |
| | | + int64_t sftp_nbytes; /* bytes written or read */ |
| | | + uint64_t sftp_user; /* user name */ |
| | | + uint64_t sftp_operation; /* SFTP operation */ |
| | | + uint64_t sftp_raddr; /* remote address */ |
| | | + uint64_t sftp_pathname; /* path with file name */ |
| | | + int32_t sftp_fd; /* fd for transfer, if any */ |
| | | +} sftpproto_t; |
| | | + |
| | | +#pragma D binding "1.6.1" translator |
| | | +translator conninfo_t <sftpproto_t *s> { |
| | | + ci_protocol = "tcp"; |
| | | + ci_remote = copyinstr((uintptr_t) |
| | | + *(uint64_t *)copyin((uintptr_t)&s->sftp_raddr, sizeof (uint64_t))); |
| | | + ci_local = "<unknown>"; |
| | | +}; |
| | | + |
| | | +#pragma D binding "1.6.1" translator |
| | | +translator sftpinfo_t <sftpproto_t *s> { |
| | | + sfi_user = copyinstr((uintptr_t) |
| | | + *(uint64_t *)copyin((uintptr_t)&s->sftp_user, sizeof (uint64_t))); |
| | | + sfi_operation = copyinstr((uintptr_t) |
| | | + *(uint64_t *)copyin((uintptr_t)&s->sftp_operation, |
| | | + sizeof (uint64_t))); |
| | | + sfi_nbytes = |
| | | + *(uint64_t *)copyin((uintptr_t)&s->sftp_nbytes, sizeof (uint64_t)); |
| | | + sfi_fsresource = stringof(fds[*(int32_t *)copyin((uintptr_t)&s->sftp_fd, |
| | | + sizeof (int32_t))].fi_fs) == "lofs" ? stringof(((struct loinfo *) |
| | | + curthread->t_procp->p_user.u_finfo.fi_list[*(int32_t *)copyin( |
| | | + (uintptr_t)&s->sftp_fd, sizeof (int32_t))].uf_file->f_vnode-> |
| | | + v_vfsp->vfs_data)->li_realvfs->vfs_resource->rs_string) : |
| | | + stringof(curthread->t_procp->p_user.u_finfo.fi_list[ |
| | | + *(int32_t *)copyin((uintptr_t)&s->sftp_fd, sizeof (int32_t))]. |
| | | + uf_file->f_vnode->v_vfsp->vfs_resource->rs_string); |
| | | + sfi_pathname = copyinstr((uintptr_t)*(uint64_t *)copyin( |
| | | + (uintptr_t)&s->sftp_pathname, sizeof (uint64_t))); |
| | | +}; |
| | | --- /dev/null |
| | | +++ hpn-ssh-hpn-18.3.1/sftp_provider.d |
| | | @@ -0,0 +1,61 @@ |
| | | +/* |
| | | + * CDDL HEADER START |
| | | + * |
| | | + * The contents of this file are subject to the terms of the |
| | | + * Common Development and Distribution License (the "License"). |
| | | + * You may not use this file except in compliance with the License. |
| | | + * |
| | | + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| | | + * or http://www.opensolaris.org/os/licensing. |
| | | + * See the License for the specific language governing permissions |
| | | + * and limitations under the License. |
| | | + * |
| | | + * When distributing Covered Code, include this CDDL HEADER in each |
| | | + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| | | + * If applicable, add the following below this CDDL HEADER, with the |
| | | + * fields enclosed by brackets "[]" replaced with your own identifying |
| | | + * information: Portions Copyright [yyyy] [name of copyright owner] |
| | | + * |
| | | + * CDDL HEADER END |
| | | + */ |
| | | +/* |
| | | + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. |
| | | + */ |
| | | + |
| | | +/* |
| | | + * We seem currently unable to depend properly on existing D libraries (like |
| | | + * hpnsftp.d). But the definitions for conninfo_t and sftpinfo_t are stored there |
| | | + * (and have to be, since that's where the real translators live). So we're |
| | | + * forced to define something here to satisfy dtrace(8), but none of the |
| | | + * definitions or translators here are actually used. |
| | | + */ |
| | | +typedef struct sftpinfo { |
| | | + int dummy; |
| | | +} sftpinfo_t; |
| | | + |
| | | +typedef struct sftpproto { |
| | | + int dummy; |
| | | +} sftpproto_t; |
| | | + |
| | | +typedef struct conninfo { |
| | | + int dummy; |
| | | +} conninfo_t; |
| | | + |
| | | +translator conninfo_t <sftpproto_t *dp> { |
| | | +}; |
| | | + |
| | | +translator sftpinfo_t <sftpproto_t *dp> { |
| | | +}; |
| | | + |
| | | +provider sftp { |
| | | + probe transfer__start(sftpproto_t *p) : |
| | | + (conninfo_t *p, sftpinfo_t *p); |
| | | + probe transfer__done(sftpproto_t *p) : |
| | | + (conninfo_t *p, sftpinfo_t *p); |
| | | +}; |
| | | + |
| | | +#pragma D attributes Evolving/Evolving/ISA provider sftp provider |
| | | +#pragma D attributes Private/Private/Unknown provider sftp module |
| | | +#pragma D attributes Private/Private/Unknown provider sftp function |
| | | +#pragma D attributes Private/Private/ISA provider sftp name |
| | | +#pragma D attributes Evolving/Evolving/ISA provider sftp args |
| | | --- /dev/null |
| | | +++ hpn-ssh-hpn-18.3.1/sftp_provider_impl.h |
| | | @@ -0,0 +1,73 @@ |
| | | +/* |
| | | + * CDDL HEADER START |
| | | + * |
| | | + * The contents of this file are subject to the terms of the |
| | | + * Common Development and Distribution License (the "License"). |
| | | + * You may not use this file except in compliance with the License. |
| | | + * |
| | | + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| | | + * or http://www.opensolaris.org/os/licensing. |
| | | + * See the License for the specific language governing permissions |
| | | + * and limitations under the License. |
| | | + * |
| | | + * When distributing Covered Code, include this CDDL HEADER in each |
| | | + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| | | + * If applicable, add the following below this CDDL HEADER, with the |
| | | + * fields enclosed by brackets "[]" replaced with your own identifying |
| | | + * information: Portions Copyright [yyyy] [name of copyright owner] |
| | | + * |
| | | + * CDDL HEADER END |
| | | + */ |
| | | +/* |
| | | + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. |
| | | + */ |
| | | + |
| | | +#ifndef _SFTP_PROVIDER_IMPL_H |
| | | +#define _SFTP_PROVIDER_IMPL_H |
| | | + |
| | | +#ifdef __cplusplus |
| | | +extern "C" { |
| | | +#endif |
| | | + |
| | | +/* |
| | | + * This structure must match the definition of same in hpnsftp.d. |
| | | + */ |
| | | +typedef struct sftpproto { |
| | | + int64_t sftp_nbytes; /* bytes writtten or read */ |
| | | + const char *sftp_user; /* user name */ |
| | | + const char *sftp_operation; /* SFTP Operation */ |
| | | + const char *sftp_raddr; /* remote address */ |
| | | + const char *sftp_pathname; /* path with file name */ |
| | | + int32_t sftp_fd; /* fd for transfer, if any */ |
| | | +} sftpproto_t; |
| | | + |
| | | +#define SFTP_TRANSFER_PROTO(proto, op, fd, path, len) \ |
| | | + bzero((proto), sizeof (struct sftpproto)); \ |
| | | + (proto)->sftp_user = (pw->pw_name ? pw->pw_name : "UNKNOWN"); \ |
| | | + (proto)->sftp_operation = (op ? op : "UNKNOWN"); \ |
| | | + (proto)->sftp_raddr = (client_addr); \ |
| | | + (proto)->sftp_fd = (fd); \ |
| | | + (proto)->sftp_pathname = (path ? path : "UNKNOWN"); \ |
| | | + (proto)->sftp_nbytes = (len); \ |
| | | + |
| | | +#define SFTP_TRANSFER_START_OP(op, fd, path, len) \ |
| | | + if (SFTP_TRANSFER_START_ENABLED()) { \ |
| | | + sftpproto_t proto; \ |
| | | + SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \ |
| | | + SFTP_TRANSFER_START(&proto); \ |
| | | + } \ |
| | | + |
| | | +#define SFTP_TRANSFER_DONE_OP(op, fd, path, len) \ |
| | | + if (SFTP_TRANSFER_DONE_ENABLED()) { \ |
| | | + sftpproto_t proto; \ |
| | | + SFTP_TRANSFER_PROTO(&proto, op, fd, path, len); \ |
| | | + SFTP_TRANSFER_DONE(&proto); \ |
| | | + } \ |
| | | + |
| | | +#include "sftp_provider.h" |
| | | + |
| | | +#ifdef __cplusplus |
| | | +} |
| | | +#endif |
| | | + |
| | | +#endif /* _SFTP_PROVIDER_IMPL_H */ |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/readconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/readconf.c |
| | | @@ -168,6 +168,9 @@ |
| | | oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, |
| | | oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, |
| | | oHashKnownHosts, |
| | | +#ifdef DISABLE_BANNER |
| | | + oDisableBanner, |
| | | +#endif |
| | | oTunnel, oTunnelDevice, |
| | | oLocalCommand, oPermitLocalCommand, oRemoteCommand, |
| | | oTcpRcvBufPoll, oHPNDisabled, |
| | | @@ -298,6 +301,9 @@ |
| | | { "controlpersist", oControlPersist }, |
| | | { "hashknownhosts", oHashKnownHosts }, |
| | | { "include", oInclude }, |
| | | +#ifdef DISABLE_BANNER |
| | | + { "disablebanner", oDisableBanner }, |
| | | +#endif |
| | | { "tunnel", oTunnel }, |
| | | { "tunneldevice", oTunnelDevice }, |
| | | { "localcommand", oLocalCommand }, |
| | | @@ -1026,6 +1032,17 @@ |
| | | return -1; |
| | | } |
| | | |
| | | +#ifdef DISABLE_BANNER |
| | | +static const struct multistate multistate_disablebanner[] = { |
| | | + { "true", SSH_DISABLEBANNER_YES }, |
| | | + { "false", SSH_DISABLEBANNER_NO }, |
| | | + { "yes", SSH_DISABLEBANNER_YES }, |
| | | + { "no", SSH_DISABLEBANNER_NO }, |
| | | + { "in-exec-mode", SSH_DISABLEBANNER_INEXECMODE }, |
| | | + { NULL, -1 } |
| | | +}; |
| | | +#endif |
| | | + |
| | | /* |
| | | * Processes a single option line as used in the configuration files. This |
| | | * only sets those values that have not already been set. |
| | | @@ -2425,6 +2442,13 @@ |
| | | } |
| | | break; |
| | | |
| | | +#ifdef DISABLE_BANNER |
| | | + case oDisableBanner: |
| | | + intptr = &options->disable_banner; |
| | | + multistate_ptr = multistate_disablebanner; |
| | | + goto parse_multistate; |
| | | +#endif |
| | | + |
| | | case oDeprecated: |
| | | debug("%s line %d: Deprecated option \"%s\"", |
| | | filename, linenum, keyword); |
| | | @@ -2672,6 +2696,9 @@ |
| | | options->stdin_null = -1; |
| | | options->fork_after_authentication = -1; |
| | | options->proxy_use_fdpass = -1; |
| | | +#ifdef DISABLE_BANNER |
| | | + options->disable_banner = -1; |
| | | +#endif |
| | | options->ignored_unknown = NULL; |
| | | options->num_canonical_domains = 0; |
| | | options->num_permitted_cnames = 0; |
| | | @@ -2906,6 +2933,10 @@ |
| | | options->canonicalize_fallback_local = 1; |
| | | if (options->canonicalize_hostname == -1) |
| | | options->canonicalize_hostname = SSH_CANONICALISE_NO; |
| | | +#ifdef DISABLE_BANNER |
| | | + if (options->disable_banner == -1) |
| | | + options->disable_banner = 0; |
| | | +#endif |
| | | if (options->fingerprint_hash == -1) |
| | | options->fingerprint_hash = SSH_FP_HASH_DEFAULT; |
| | | #ifdef ENABLE_SK_INTERNAL |
| | | --- hpn-ssh-hpn-18.3.1/readconf.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/readconf.h |
| | | @@ -198,6 +198,9 @@ |
| | | u_int num_channel_timeouts; |
| | | |
| | | char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ |
| | | +#ifdef DISABLE_BANNER |
| | | + int disable_banner; /* Disable display of banner */ |
| | | +#endif |
| | | } Options; |
| | | |
| | | #define SSH_PUBKEY_AUTH_NO 0x00 |
| | | @@ -243,6 +246,12 @@ |
| | | #define SSH_KEYSTROKE_CHAFF_MIN_MS 1024 |
| | | #define SSH_KEYSTROKE_CHAFF_RNG_MS 2048 |
| | | |
| | | +#ifdef DISABLE_BANNER |
| | | +#define SSH_DISABLEBANNER_NO 0 |
| | | +#define SSH_DISABLEBANNER_YES 1 |
| | | +#define SSH_DISABLEBANNER_INEXECMODE 2 |
| | | +#endif |
| | | + |
| | | const char *kex_default_pk_alg(void); |
| | | char *ssh_connection_hash(const char *thishost, const char *host, |
| | | const char *portstr, const char *user, const char *jump_host); |
| | | --- hpn-ssh-hpn-18.3.1/hpnssh_config.5.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnssh_config.5 |
| | | @@ -713,6 +713,14 @@ |
| | | then the backgrounded master connection will automatically terminate |
| | | after it has remained idle (with no client connections) for the |
| | | specified time. |
| | | +.It Cm DisableBanner |
| | | +If set to yes, disables the display of the banner message. |
| | | +If set to in-exec-mode, disables the display of banner message when in remote |
| | | +command mode only. |
| | | +.Pp |
| | | +The default value is no, which means that the banner is displayed unless the |
| | | +log level is QUIET, FATAL, or ERROR. See also the Banner option in |
| | | +.Xr sshd_config 4 . This option applies to protocol version 2 only. |
| | | .It Cm DisableMTAES |
| | | Switch the encryption cipher being used from the multithreaded MT-AES-CTR cipher |
| | | back to the stock single-threaded AES-CTR cipher. This may prove to be more |
| | | --- hpn-ssh-hpn-18.3.1/sshconnect2.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshconnect2.c |
| | | @@ -85,6 +85,10 @@ |
| | | extern char *server_version_string; |
| | | extern Options options; |
| | | |
| | | +#ifdef DISABLE_BANNER |
| | | +extern struct sshbuf *command; |
| | | +#endif |
| | | + |
| | | /* |
| | | * tty_flag is set in ssh.c. Use this in ssh_userauth2: |
| | | * if it is set, then prevent the switch to the null cipher. |
| | | @@ -630,8 +634,28 @@ |
| | | if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 || |
| | | (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) |
| | | goto out; |
| | | - if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) |
| | | - fmprintf(stderr, "%s", msg); |
| | | +#ifdef DISABLE_BANNER |
| | | + /* |
| | | + * Banner is a warning message according to RFC 4252. So, never print |
| | | + * a banner in error log level or lower. If the log level is higher, |
| | | + * use DisableBanner option to decide whether to display it or not. |
| | | + */ |
| | | + if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO && |
| | | + (options.disable_banner == SSH_DISABLEBANNER_NO || |
| | | + (options.disable_banner == SSH_DISABLEBANNER_INEXECMODE && |
| | | + sshbuf_len(command) == 0))) { |
| | | +#else |
| | | + if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { |
| | | +#endif |
| | | + char *safe; |
| | | + |
| | | + if (len > 65536) |
| | | + len = 65536; |
| | | + safe = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ |
| | | + strnvis(safe, msg, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH); |
| | | + fmprintf(stderr, "%s", safe); |
| | | + free(safe); |
| | | + } |
| | | r = 0; |
| | | out: |
| | | free(msg); |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/auth-pam.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth-pam.c |
| | | @@ -1281,11 +1281,13 @@ |
| | | free(env); |
| | | } |
| | | |
| | | +#ifndef PAM_BUGFIX |
| | | /* |
| | | * "Blind" conversation function for password authentication. Assumes that |
| | | * echo-off prompts are for the password and stores messages for later |
| | | * display. |
| | | */ |
| | | +#endif |
| | | static int |
| | | sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, |
| | | struct pam_response **resp, void *data) |
| | | @@ -1307,12 +1309,24 @@ |
| | | for (i = 0; i < n; ++i) { |
| | | switch (PAM_MSG_MEMBER(msg, i, msg_style)) { |
| | | case PAM_PROMPT_ECHO_OFF: |
| | | +#ifdef PAM_BUGFIX |
| | | + /* |
| | | + * PAM conversation function for the password userauth |
| | | + * method (non-interactive) really cannot do any |
| | | + * prompting. We set the PAM_AUTHTOK item in |
| | | + * sshpam_auth_passwd()to avoid conversation. If some |
| | | + * modules still try to converse, then the password |
| | | + * userauth will fail. |
| | | + */ |
| | | + goto fail; |
| | | +#else |
| | | if (sshpam_password == NULL) |
| | | goto fail; |
| | | if ((reply[i].resp = strdup(sshpam_password)) == NULL) |
| | | goto fail; |
| | | reply[i].resp_retcode = PAM_SUCCESS; |
| | | break; |
| | | +#endif |
| | | case PAM_ERROR_MSG: |
| | | case PAM_TEXT_INFO: |
| | | len = strlen(PAM_MSG_MEMBER(msg, i, msg)); |
| | | @@ -1349,6 +1363,9 @@ |
| | | int |
| | | sshpam_auth_passwd(Authctxt *authctxt, const char *password) |
| | | { |
| | | +#ifdef PAM_BUGFIX |
| | | + int set_item_rtn; |
| | | +#endif |
| | | int flags = (options.permit_empty_passwd == 0 ? |
| | | PAM_DISALLOW_NULL_AUTHTOK : 0); |
| | | char *fake = NULL; |
| | | @@ -1369,6 +1386,15 @@ |
| | | options.permit_root_login != PERMIT_YES)) |
| | | sshpam_password = fake = fake_password(password); |
| | | |
| | | +#ifdef PAM_BUGFIX |
| | | + sshpam_err = pam_set_item(sshpam_handle, PAM_AUTHTOK, password); |
| | | + if (sshpam_err != PAM_SUCCESS) { |
| | | + debug("PAM: %s: failed to set PAM_AUTHTOK: %s", __func__, |
| | | + pam_strerror(sshpam_handle, sshpam_err)); |
| | | + return 0; |
| | | + } |
| | | +#endif |
| | | + |
| | | sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, |
| | | (const void *)&passwd_conv); |
| | | if (sshpam_err != PAM_SUCCESS) |
| | | @@ -1380,6 +1406,16 @@ |
| | | free(fake); |
| | | if (sshpam_err == PAM_MAXTRIES) |
| | | sshpam_set_maxtries_reached(1); |
| | | + |
| | | +#ifdef PAM_BUGFIX |
| | | + set_item_rtn = pam_set_item(sshpam_handle, PAM_AUTHTOK, NULL); |
| | | + if (set_item_rtn != PAM_SUCCESS) { |
| | | + debug("PAM: %s: failed to set PAM_AUTHTOK: %s", __func__, |
| | | + pam_strerror(sshpam_handle, set_item_rtn)); |
| | | + return 0; |
| | | + } |
| | | +#endif |
| | | + |
| | | if (sshpam_err == PAM_SUCCESS && authctxt->valid) { |
| | | debug("PAM: password authentication accepted for %.100s", |
| | | authctxt->user); |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/auth-pam.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth-pam.c |
| | | @@ -687,6 +687,66 @@ |
| | | sshpam_handle = NULL; |
| | | } |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | +char * |
| | | +derive_pam_service_name(Authctxt *authctxt) |
| | | +{ |
| | | + char *svcname = xmalloc(BUFSIZ); |
| | | + |
| | | + /* |
| | | + * If PamServiceName is set we use that for everything, including |
| | | + * SSHv1 |
| | | + */ |
| | | + if (options.pam_service_name != NULL) { |
| | | + (void) strlcpy(svcname, options.pam_service_name, BUFSIZ); |
| | | + return (svcname); |
| | | + } |
| | | + |
| | | + char *method_name = authctxt->authmethod_name; |
| | | + |
| | | + if (!method_name) |
| | | + fatal("Userauth method unknown while starting PAM"); |
| | | + |
| | | + /* |
| | | + * For SSHv2 we use "sshd-<userauth name> |
| | | + * The "sshd" prefix can be changed via the PAMServicePrefix |
| | | + * sshd_config option. |
| | | + */ |
| | | + if (strcmp(method_name, "none") == 0) { |
| | | + snprintf(svcname, BUFSIZ, "%s-none", |
| | | + options.pam_service_prefix); |
| | | + } |
| | | + if (strcmp(method_name, "password") == 0) { |
| | | + snprintf(svcname, BUFSIZ, "%s-password", |
| | | + options.pam_service_prefix); |
| | | + } |
| | | + if (strcmp(method_name, "keyboard-interactive") == 0) { |
| | | + /* "keyboard-interactive" is too long, shorten it */ |
| | | + snprintf(svcname, BUFSIZ, "%s-kbdint", |
| | | + options.pam_service_prefix); |
| | | + } |
| | | + if (strcmp(method_name, "publickey") == 0) { |
| | | + /* "publickey" is too long, shorten it */ |
| | | + snprintf(svcname, BUFSIZ, "%s-pubkey", |
| | | + options.pam_service_prefix); |
| | | + } |
| | | + if (strcmp(method_name, "hostbased") == 0) { |
| | | + snprintf(svcname, BUFSIZ, "%s-hostbased", |
| | | + options.pam_service_prefix); |
| | | + } |
| | | + if (strncmp(method_name, "gssapi-", 7) == 0) { |
| | | + /* |
| | | + * Although OpenSSH only supports "gssapi-with-mic" |
| | | + * for now. We will still map any userauth method |
| | | + * prefixed with "gssapi-" to the gssapi PAM service. |
| | | + */ |
| | | + snprintf(svcname, BUFSIZ, "%s-gssapi", |
| | | + options.pam_service_prefix); |
| | | + } |
| | | + return svcname; |
| | | +} |
| | | +#endif /* PAM_ENHANCEMENT */ |
| | | + |
| | | static int |
| | | sshpam_init(struct ssh *ssh, Authctxt *authctxt) |
| | | { |
| | | @@ -700,23 +760,76 @@ |
| | | fatal("Username too long from %s port %d", |
| | | ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); |
| | | #endif |
| | | + |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + const char *pam_service; |
| | | + const char **ptr_pam_service = &pam_service; |
| | | + char *svc = NULL; |
| | | + |
| | | + svc = derive_pam_service_name(authctxt); |
| | | + debug3("PAM service is %s", svc); |
| | | +#endif |
| | | + |
| | | if (sshpam_handle == NULL) { |
| | | if (ssh == NULL) { |
| | | fatal("%s: called initially with no " |
| | | "packet context", __func__); |
| | | } |
| | | } if (sshpam_handle != NULL) { |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + /* get the pam service name */ |
| | | + sshpam_err = pam_get_item(sshpam_handle, |
| | | + PAM_SERVICE, (sshpam_const void **)ptr_pam_service); |
| | | + if (sshpam_err != PAM_SUCCESS) |
| | | + fatal("Failed to get the PAM service name"); |
| | | + debug3("Previous pam_service is %s", pam_service ? |
| | | + pam_service : "NULL"); |
| | | + |
| | | + /* get the pam user name */ |
| | | + sshpam_err = pam_get_item(sshpam_handle, |
| | | + PAM_USER, (sshpam_const void **)ptr_pam_user); |
| | | + |
| | | + /* |
| | | + * only need to re-start if either user or service is |
| | | + * different. |
| | | + */ |
| | | + if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0 |
| | | + && strncmp(svc, pam_service, strlen(svc)) == 0) { |
| | | + free(svc); |
| | | + return (0); |
| | | + } |
| | | + |
| | | + /* |
| | | + * Clean up previous PAM state. No need to clean up session |
| | | + * and creds. |
| | | + */ |
| | | + sshpam_authenticated = 0; |
| | | + sshpam_account_status = -1; |
| | | + |
| | | + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, NULL); |
| | | + if (sshpam_err != PAM_SUCCESS) |
| | | + debug3("Cannot remove PAM conv"); /* a warning only */ |
| | | +#else /* Original */ |
| | | /* We already have a PAM context; check if the user matches */ |
| | | sshpam_err = pam_get_item(sshpam_handle, |
| | | PAM_USER, (sshpam_const void **)ptr_pam_user); |
| | | if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) |
| | | return (0); |
| | | +#endif /* PAM_ENHANCEMENT */ |
| | | pam_end(sshpam_handle, sshpam_err); |
| | | sshpam_handle = NULL; |
| | | } |
| | | debug("PAM: initializing for \"%s\"", user); |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + debug3("Starting PAM service %s for user %s method %s", svc, user, |
| | | + authctxt->authmethod_name); |
| | | + sshpam_err = |
| | | + pam_start(svc, user, &store_conv, &sshpam_handle); |
| | | + free(svc); |
| | | +#else /* Original */ |
| | | sshpam_err = |
| | | pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle); |
| | | +#endif |
| | | sshpam_authctxt = authctxt; |
| | | |
| | | if (sshpam_err != PAM_SUCCESS) { |
| | | --- hpn-ssh-hpn-18.3.1/auth.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth.h |
| | | @@ -95,6 +95,9 @@ |
| | | |
| | | /* Information exposed to session */ |
| | | struct sshbuf *session_info; /* Auth info for environment */ |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + char *authmethod_name; |
| | | +#endif |
| | | }; |
| | | |
| | | /* |
| | | --- hpn-ssh-hpn-18.3.1/auth2.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth2.c |
| | | @@ -317,9 +317,17 @@ |
| | | #endif |
| | | } |
| | | #ifdef USE_PAM |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + /* |
| | | + * Start PAM here and once only, if each userauth does not |
| | | + * has its own PAM service. |
| | | + */ |
| | | + if (options.use_pam && !options.pam_service_per_authmethod) |
| | | +#else |
| | | if (options.use_pam) |
| | | +#endif /* PAM_ENHANCEMENT */ |
| | | PRIVSEP(start_pam(ssh)); |
| | | -#endif |
| | | +#endif /* USE_PAM */ |
| | | ssh_packet_set_log_preamble(ssh, "%suser %s", |
| | | authctxt->valid ? "authenticating " : "invalid ", user); |
| | | setproctitle("%s%s", authctxt->valid ? user : "unknown", |
| | | @@ -356,6 +364,18 @@ |
| | | /* try to authenticate user */ |
| | | m = authmethod_lookup(authctxt, method); |
| | | if (m != NULL && authctxt->failures < options.max_authtries) { |
| | | + |
| | | +#if defined(USE_PAM) && defined(PAM_ENHANCEMENT) |
| | | + /* start PAM service for each userauth */ |
| | | + if (options.use_pam && options.pam_service_per_authmethod) { |
| | | + if (authctxt->authmethod_name != NULL) |
| | | + free(authctxt->authmethod_name); |
| | | + authctxt->authmethod_name = xstrdup(method); |
| | | + if (use_privsep) |
| | | + mm_inform_authmethod(method); |
| | | + PRIVSEP(start_pam(authctxt)); |
| | | + } |
| | | +#endif |
| | | debug2("input_userauth_request: try method %s", method); |
| | | authenticated = m->userauth(ssh, method); |
| | | } |
| | | @@ -381,6 +401,10 @@ |
| | | char *methods; |
| | | int r, partial = 0; |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + debug3("%s: entering", __func__); |
| | | +#endif |
| | | + |
| | | if (authenticated) { |
| | | if (!authctxt->valid) { |
| | | fatal("INTERNAL ERROR: authenticated invalid user %s", |
| | | @@ -404,6 +428,25 @@ |
| | | } |
| | | |
| | | if (authenticated && options.num_auth_methods != 0) { |
| | | + |
| | | +#if defined(USE_PAM) && defined(PAM_ENHANCEMENT) |
| | | + /* |
| | | + * If each userauth has its own PAM service, then PAM needs to |
| | | + * perform the account check for this service. |
| | | + */ |
| | | + if (options.use_pam && options.pam_service_per_authmethod && |
| | | + !PRIVSEP(do_pam_account())) { |
| | | + /* if PAM returned a message, send it to the user */ |
| | | + if (sshbuf_len(loginmsg) > 0) { |
| | | + sshbuf_put(loginmsg, "\0", 1); |
| | | + userauth_send_banner(ssh, sshbuf_ptr(loginmsg)); |
| | | + ssh_packet_write_wait(ssh); |
| | | + } |
| | | + |
| | | + fatal("Access denied for user %s by PAM account " |
| | | + "configuration", authctxt->user); |
| | | + } |
| | | +#endif |
| | | if (!auth2_update_methods_lists(authctxt, method, submethod)) { |
| | | authenticated = 0; |
| | | partial = 1; |
| | | @@ -421,7 +464,19 @@ |
| | | return; |
| | | |
| | | #ifdef USE_PAM |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + /* |
| | | + * PAM needs to perform account checks after auth. However, if each |
| | | + * userauth has its own PAM service and options.num_auth_methods != 0, |
| | | + * then no need to perform account checking, because it was done |
| | | + * already. |
| | | + */ |
| | | + if (options.use_pam && authenticated && |
| | | + !(options.num_auth_methods != 0 && |
| | | + options.pam_service_per_authmethod)) { |
| | | +#else |
| | | if (options.use_pam && authenticated) { |
| | | +#endif |
| | | int r, success = PRIVSEP(do_pam_account()); |
| | | |
| | | /* If PAM returned a message, send it to the user. */ |
| | | --- hpn-ssh-hpn-18.3.1/monitor.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/monitor.c |
| | | @@ -117,6 +117,9 @@ |
| | | int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); |
| | | int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); |
| | | int mm_answer_authserv(struct ssh *, int, struct sshbuf *); |
| | | +#ifdef PAM_ENHANCEMENT |
| | | +int mm_answer_authmethod(struct ssh *, int, struct sshbuf *); |
| | | +#endif |
| | | int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); |
| | | int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); |
| | | int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); |
| | | @@ -190,10 +193,17 @@ |
| | | {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, |
| | | {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, |
| | | {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + {MONITOR_REQ_AUTHMETHOD, MON_ISAUTH, mm_answer_authmethod}, |
| | | +#endif |
| | | {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, |
| | | {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, |
| | | #ifdef USE_PAM |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start}, |
| | | +#else |
| | | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, |
| | | +#endif |
| | | {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, |
| | | {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, |
| | | {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, |
| | | @@ -300,6 +310,25 @@ |
| | | |
| | | /* Special handling for multiple required authentications */ |
| | | if (options.num_auth_methods != 0) { |
| | | + |
| | | +#if defined(USE_PAM) && defined(PAM_ENHANCEMENT) |
| | | + /* |
| | | + * If each userauth has its own PAM service, then PAM |
| | | + * need to perform account check for this service. |
| | | + */ |
| | | + if (options.use_pam && authenticated && |
| | | + options.pam_service_per_authmethod) { |
| | | + struct sshbuf *m; |
| | | + if ((m = sshbuf_new()) == NULL) |
| | | + fatal("%s: sshbuf_new", __func__); |
| | | + mm_request_receive_expect(pmonitor->m_sendfd, |
| | | + MONITOR_REQ_PAM_ACCOUNT, m); |
| | | + authenticated = mm_answer_pam_account(ssh, |
| | | + pmonitor->m_sendfd, m); |
| | | + sshbuf_free(m); |
| | | + } |
| | | +#endif |
| | | + |
| | | if (authenticated && |
| | | !auth2_update_methods_lists(authctxt, |
| | | auth_method, auth_submethod)) { |
| | | @@ -317,8 +346,21 @@ |
| | | !auth_root_allowed(ssh, auth_method)) |
| | | authenticated = 0; |
| | | #ifdef USE_PAM |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + /* |
| | | + * PAM needs to perform account checks after auth. |
| | | + * However, if each userauth has its own PAM service |
| | | + * and options.num_auth_methods != 0, then no need to |
| | | + * perform account checking, because it was done |
| | | + * already. |
| | | + */ |
| | | + if (options.use_pam && authenticated && |
| | | + !(options.num_auth_methods != 0 && |
| | | + options.pam_service_per_authmethod)) { |
| | | +#else |
| | | /* PAM needs to perform account checks after auth */ |
| | | if (options.use_pam && authenticated) { |
| | | +#endif |
| | | struct sshbuf *m; |
| | | |
| | | if ((m = sshbuf_new()) == NULL) |
| | | @@ -802,6 +844,11 @@ |
| | | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
| | | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + /* Allow authmethod information on the auth context */ |
| | | + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHMETHOD, 1); |
| | | +#endif |
| | | + |
| | | #ifdef USE_PAM |
| | | if (options.use_pam) |
| | | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); |
| | | @@ -825,6 +872,27 @@ |
| | | return (0); |
| | | } |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | +int |
| | | +mm_answer_authmethod(struct ssh *ssh, int sock, struct sshbuf *m) |
| | | +{ |
| | | + Authctxt *authctxt = ssh->authctxt; |
| | | + |
| | | + monitor_permit_authentications(1); |
| | | + /*sshbuf_dump(m, stderr);*/ |
| | | + sshbuf_get_cstring(m, &authctxt->authmethod_name, NULL); |
| | | + debug3("%s: authmethod_name=%s", __func__, authctxt->authmethod_name); |
| | | + |
| | | + if (authctxt->authmethod_name && |
| | | + strlen(authctxt->authmethod_name) == 0) { |
| | | + free(authctxt->authmethod_name); |
| | | + authctxt->authmethod_name = NULL; |
| | | + } |
| | | + |
| | | + return (0); |
| | | +} |
| | | +#endif |
| | | + |
| | | int |
| | | mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m) |
| | | { |
| | | --- hpn-ssh-hpn-18.3.1/monitor.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/monitor.h |
| | | @@ -63,6 +63,9 @@ |
| | | MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111, |
| | | MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113, |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + MONITOR_REQ_AUTHMETHOD = 114, |
| | | +#endif |
| | | }; |
| | | |
| | | struct ssh; |
| | | --- hpn-ssh-hpn-18.3.1/monitor_wrap.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/monitor_wrap.c |
| | | @@ -396,6 +396,24 @@ |
| | | sshbuf_free(m); |
| | | } |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | +/* Inform the privileged process about the authentication method */ |
| | | +void |
| | | +mm_inform_authmethod(char *authmethod) |
| | | +{ |
| | | + struct sshbuf *m; |
| | | + |
| | | + debug3("%s entering", __func__); |
| | | + if ((m = sshbuf_new()) == NULL) |
| | | + fatal("%s: sshbuf_new", __func__); |
| | | + sshbuf_put_cstring(m, authmethod); |
| | | + |
| | | + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHMETHOD, m); |
| | | + |
| | | + sshbuf_free(m); |
| | | +} |
| | | +#endif |
| | | + |
| | | /* Do the password authentication */ |
| | | int |
| | | mm_auth_password(struct ssh *ssh, char *password) |
| | | --- hpn-ssh-hpn-18.3.1/servconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.c |
| | | @@ -203,6 +203,18 @@ |
| | | options->channel_timeouts = NULL; |
| | | options->num_channel_timeouts = 0; |
| | | options->unused_connection_timeout = -1; |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + options->pam_service_name = NULL; |
| | | + options->pam_service_prefix = NULL; |
| | | + |
| | | + /* |
| | | + * Each user method will have its own PAM service by default. |
| | | + * However, if PAMServiceName is specified |
| | | + * then there will be only one PAM service for the |
| | | + * entire user authentication. |
| | | + */ |
| | | + options->pam_service_per_authmethod = 1; |
| | | +#endif |
| | | } |
| | | |
| | | /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ |
| | | @@ -454,6 +466,12 @@ |
| | | options->ip_qos_bulk = IPTOS_DSCP_CS1; |
| | | if (options->version_addendum == NULL) |
| | | options->version_addendum = xstrdup(""); |
| | | + |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + if (options->pam_service_prefix == NULL) |
| | | + options->pam_service_prefix = _SSH_PAM_SERVICE_PREFIX; |
| | | +#endif |
| | | + |
| | | if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1) |
| | | options->fwd_opts.streamlocal_bind_mask = 0177; |
| | | if (options->fwd_opts.streamlocal_bind_unlink == -1) |
| | | @@ -547,6 +565,9 @@ |
| | | sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, |
| | | sUsePrivilegeSeparation, sAllowAgentForwarding, |
| | | sHostCertificate, sInclude, |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + sPAMServicePrefix, sPAMServiceName, |
| | | +#endif |
| | | sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, |
| | | sAuthorizedPrincipalsCommand, sAuthorizedPrincipalsCommandUser, |
| | | sKexAlgorithms, sCASignatureAlgorithms, sIPQoS, sVersionAddendum, |
| | | @@ -698,6 +719,10 @@ |
| | | { "forcecommand", sForceCommand, SSHCFG_ALL }, |
| | | { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, |
| | | { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + { "pamserviceprefix", sPAMServicePrefix, SSHCFG_GLOBAL }, |
| | | + { "pamservicename", sPAMServiceName, SSHCFG_GLOBAL }, |
| | | +#endif |
| | | { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, |
| | | { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, |
| | | { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, |
| | | @@ -2605,6 +2630,37 @@ |
| | | } |
| | | goto parse_time; |
| | | |
| | | + case sPAMServicePrefix: |
| | | + arg = strdelim(&str); |
| | | + if (!arg || *arg == '\0') |
| | | + fatal("%s line %d: Missing argument.", |
| | | + filename, linenum); |
| | | + if (options->pam_service_name != NULL) |
| | | + fatal("%s line %d: PAMServiceName and PAMServicePrefix" |
| | | + " are mutually exclusive.", filename, linenum); |
| | | + if (options->pam_service_prefix == NULL) |
| | | + options->pam_service_prefix = xstrdup(arg); |
| | | + break; |
| | | + |
| | | + case sPAMServiceName: |
| | | + arg = strdelim(&str); |
| | | + if (!arg || *arg == '\0') |
| | | + fatal("%s line %d: Missing argument.", |
| | | + filename, linenum); |
| | | + if (options->pam_service_prefix != NULL) |
| | | + fatal("%s line %d: PAMServiceName and PAMServicePrefix" |
| | | + " are mutually exclusive.", filename, linenum); |
| | | + if (options->pam_service_name == NULL) { |
| | | + options->pam_service_name = xstrdup(arg); |
| | | + |
| | | + /* |
| | | + * When this option is specified, we will not have |
| | | + * PAM service for each auth method. |
| | | + */ |
| | | + options->pam_service_per_authmethod = 0; |
| | | + } |
| | | + break; |
| | | + |
| | | case sDeprecated: |
| | | case sIgnore: |
| | | case sUnsupported: |
| | | --- hpn-ssh-hpn-18.3.1/servconf.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.h |
| | | @@ -71,6 +71,10 @@ |
| | | struct addrinfo *addrs; |
| | | }; |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | +#define _SSH_PAM_SERVICE_PREFIX "sshd" |
| | | +#endif |
| | | + |
| | | typedef struct { |
| | | u_int num_ports; |
| | | u_int ports_from_cmdline; |
| | | @@ -228,6 +232,12 @@ |
| | | u_int num_auth_methods; |
| | | char **auth_methods; |
| | | |
| | | +#ifdef PAM_ENHANCEMENT |
| | | + char *pam_service_prefix; |
| | | + char *pam_service_name; |
| | | + int pam_service_per_authmethod; |
| | | +#endif |
| | | + |
| | | int fingerprint_hash; |
| | | int expose_userauth_info; |
| | | u_int64_t timing_secret; |
| | | --- hpn-ssh-hpn-18.3.1/hpnsshd.8.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsshd.8 |
| | | @@ -1017,6 +1017,33 @@ |
| | | started last). |
| | | The content of this file is not sensitive; it can be world-readable. |
| | | .El |
| | | + |
| | | +.Sh SECURITY |
| | | +sshd uses pam(3PAM) for password and keyboard-interactive methods as well as |
| | | +for account management, session management, and the password management for all |
| | | +authentication methods. |
| | | +.Pp |
| | | +Each SSHv2 userauth type has its own PAM service name: |
| | | + |
| | | +.Bd -literal -offset 3n |
| | | + |
| | | +----------------------------------------------- |
| | | +| SSHv2 Userauth | PAM Service Name | |
| | | +----------------------------------------------- |
| | | +| none | sshd-none | |
| | | +----------------------------------------------- |
| | | +| password | sshd-password | |
| | | +----------------------------------------------- |
| | | +| keyboard-interactive | sshd-kbdint | |
| | | +----------------------------------------------- |
| | | +| pubkey | sshd-pubkey | |
| | | +----------------------------------------------- |
| | | +| hostbased | sshd-hostbased | |
| | | +----------------------------------------------- |
| | | +| gssapi-with-mic | sshd-gssapi | |
| | | +----------------------------------------------- |
| | | +.Ed |
| | | + |
| | | .Sh SEE ALSO |
| | | .Xr hpnscp 1 , |
| | | .Xr hpnsftp 1 , |
| | | --- hpn-ssh-hpn-18.3.1/hpnsshd_config.5.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsshd_config.5 |
| | | @@ -1401,6 +1401,35 @@ |
| | | protection against man-in-the-middle attacks. As with NoneEnabled all authentication |
| | | remains encrypted and integrity is ensured. Default is |
| | | .Cm no. |
| | | +.It Cm PAMServiceName |
| | | +Specifies the PAM service name for the PAM session. |
| | | +The |
| | | +.Cm PAMServiceName |
| | | +and |
| | | +.Cm PAMServicePrefix |
| | | +options are mutually exclusive and if both are set, sshd does not start. |
| | | +If this option is set the service name is the same for all user authentication |
| | | +methods. |
| | | +The option has no default value. |
| | | +See |
| | | +.Cm PAMServicePrefix |
| | | +for more information. |
| | | +.It Cm PAMServicePrefix |
| | | +Specifies the PAM service name prefix for service names used for individual |
| | | +user authentication methods. |
| | | +The default is sshd. |
| | | +The |
| | | +.Cm PAMServiceName |
| | | +and |
| | | +.Cm PAMServicePrefix |
| | | +options are mutually exclusive and if both are set, sshd does not start. |
| | | +.Pp |
| | | +For example, if this option is set to |
| | | +.Cm admincli , |
| | | +the service name for the keyboard-interactive authentication method is |
| | | +.Sy admincli-kbdint |
| | | +instead of the default |
| | | +.Sy sshd-kbdint . |
| | | .It Cm PasswordAuthentication |
| | | Specifies whether password authentication is allowed. |
| | | The default is |
| | | @@ -1943,8 +1972,7 @@ |
| | | is enabled, you will not be able to run |
| | | .Xr sshd 8 |
| | | as a non-root user. |
| | | -The default is |
| | | -.Cm no . |
| | | +On OpenIndiana, the option is always enabled. |
| | | .It Cm VersionAddendum |
| | | Optionally specifies additional text to append to the SSH protocol banner |
| | | sent by the server upon connection. |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/INSTALL.orig |
| | | +++ hpn-ssh-hpn-18.3.1/INSTALL |
| | | @@ -103,9 +103,13 @@ |
| | | |
| | | Basic Security Module (BSM): |
| | | |
| | | -Native BSM support is known to exist in Solaris from at least 2.5.1, |
| | | -FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM |
| | | -implementation (http://www.openbsm.org). |
| | | +Native BSM support is known to exist in Solaris from at least 2.5.1 |
| | | +to Solaris 10. From Solaris 11 the previously documented BSM (libbsm) |
| | | +interfaces are no longer public and are unsupported. While not public |
| | | +interfaces, audit-solaris.c implements Solaris Audit from Solaris 11. |
| | | +Native BSM support is known to exist in FreeBSD 6.1 and OS X. |
| | | +Alternatively, you may use the OpenBSM implementation |
| | | +(http://www.openbsm.org). |
| | | |
| | | makedepend: |
| | | |
| | | @@ -171,8 +175,9 @@ |
| | | There are a few other options to the configure script: |
| | | |
| | | --with-audit=[module] enable additional auditing via the specified module. |
| | | -Currently, drivers for "debug" (additional info via syslog) and "bsm" |
| | | -(Sun's Basic Security Module) are supported. |
| | | +Currently, drivers for "debug" (additional info via syslog), and "bsm" |
| | | +(Sun's Legacy Basic Security Module prior to Solaris 11), and "solaris" |
| | | +(Sun's Audit infrastructure from Solaris 11) are supported. |
| | | |
| | | --with-pam enables PAM support. If PAM support is compiled in, it must |
| | | also be enabled in sshd_config (refer to the UsePAM directive). |
| | | --- hpn-ssh-hpn-18.3.1/Makefile.in.orig |
| | | +++ hpn-ssh-hpn-18.3.1/Makefile.in |
| | | @@ -122,7 +122,7 @@ |
| | | sshconnect.o sshconnect2.o mux.o cipher-switch.o $(SKOBJS) |
| | | |
| | | SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ |
| | | - audit.o audit-bsm.o audit-linux.o platform.o \ |
| | | + audit.o audit-bsm.o audit-linux.o audit-solaris.o platform.o \ |
| | | sshpty.o sshlogin.o servconf.o serverloop.o \ |
| | | auth.o auth2.o auth-options.o session.o \ |
| | | auth2-chall.o groupaccess.o \ |
| | | --- hpn-ssh-hpn-18.3.1/README.platform.orig |
| | | +++ hpn-ssh-hpn-18.3.1/README.platform |
| | | @@ -71,10 +71,10 @@ |
| | | libssl-dev, libz-dev and libpam-dev. |
| | | |
| | | |
| | | -Solaris |
| | | -------- |
| | | -If you enable BSM auditing on Solaris, you need to update audit_event(4) |
| | | -for praudit(1m) to give sensible output. The following line needs to be |
| | | +Prior to Solaris 11 |
| | | +------------------- |
| | | +If you enable BSM auditing on Solaris, you need to update audit_event(5) |
| | | +for praudit(8) to give sensible output. The following line needs to be |
| | | added to /etc/security/audit_event: |
| | | |
| | | 32800:AUE_openssh:OpenSSH login:lo |
| | | @@ -85,6 +85,9 @@ |
| | | number is already in use on your system, you may change it at build time |
| | | by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding. |
| | | |
| | | +From Solaris 11 |
| | | +--------------- |
| | | +Solaris Audit is supported by configuring --with-audit=solaris. |
| | | |
| | | Platforms using PAM |
| | | ------------------- |
| | | --- hpn-ssh-hpn-18.3.1/audit-bsm.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/audit-bsm.c |
| | | @@ -348,7 +348,7 @@ |
| | | /* Below is the sshd audit API code */ |
| | | |
| | | void |
| | | -audit_connection_from(const char *host, int port) |
| | | +audit_connection_from(struct ssh *ssh, const char *host, int port) |
| | | { |
| | | AuditInfoTermID *tid = &ssh_bsm_tid; |
| | | char buf[1024]; |
| | | --- hpn-ssh-hpn-18.3.1/audit-linux.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/audit-linux.c |
| | | @@ -71,7 +71,7 @@ |
| | | /* Below is the sshd audit API code */ |
| | | |
| | | void |
| | | -audit_connection_from(const char *host, int port) |
| | | +audit_connection_from(struct ssh *ssh, const char *host, int port) |
| | | { |
| | | /* not implemented */ |
| | | } |
| | | --- /dev/null |
| | | +++ hpn-ssh-hpn-18.3.1/audit-solaris.c |
| | | @@ -0,0 +1,574 @@ |
| | | +/* |
| | | + * CDDL HEADER START |
| | | + * |
| | | + * The contents of this file are subject to the terms of the |
| | | + * Common Development and Distribution License (the "License"). |
| | | + * You may not use this file except in compliance with the License. |
| | | + * |
| | | + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| | | + * or http://www.opensolaris.org/os/licensing. |
| | | + * See the License for the specific language governing permissions |
| | | + * and limitations under the License. |
| | | + * |
| | | + * When distributing Covered Code, include this CDDL HEADER in each |
| | | + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| | | + * If applicable, add the following below this CDDL HEADER, with the |
| | | + * fields enclosed by brackets "[]" replaced with your own identifying |
| | | + * information: Portions Copyright [yyyy] [name of copyright owner] |
| | | + * |
| | | + * CDDL HEADER END |
| | | + */ |
| | | + |
| | | +/* |
| | | + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. |
| | | + */ |
| | | + |
| | | +#include "includes.h" |
| | | +#if defined(USE_SOLARIS_AUDIT) |
| | | + |
| | | +#include "audit.h" |
| | | +#include "sshbuf.h" |
| | | +#include "sshkey.h" |
| | | +#include "hostfile.h" |
| | | +#include "auth.h" |
| | | +#include "log.h" |
| | | +#include "packet.h" |
| | | + |
| | | +#include <errno.h> |
| | | +#include <pwd.h> |
| | | +#include <string.h> |
| | | + |
| | | +#include <bsm/adt.h> |
| | | +#include <bsm/adt_event.h> |
| | | + |
| | | +#ifdef ADT_DEBUG |
| | | +#include <bsm/audit.h> |
| | | +#include <arpa/inet.h> |
| | | +#include <netinet/in.h> |
| | | +#include <values.h> |
| | | +#include <errno.h> |
| | | +#include <pwd.h> |
| | | +#include <stdio.h> |
| | | +#include <unistd.h> |
| | | +#include <stdarg.h> |
| | | +#include <string.h> |
| | | +#include <ucred.h> |
| | | +#include <values.h> |
| | | + |
| | | +#include <bsm/adt.h> |
| | | +#include <bsm/audit.h> |
| | | + |
| | | +#include <sys/types.h> |
| | | +#include <sys/stat.h> |
| | | + |
| | | +/* semi private adt functions to extract information */ |
| | | + |
| | | +extern void adt_get_asid(const adt_session_data_t *, au_asid_t *); |
| | | +extern void adt_get_auid(const adt_session_data_t *, au_id_t *); |
| | | +extern void adt_get_mask(const adt_session_data_t *, au_mask_t *); |
| | | +extern void adt_get_termid(const adt_session_data_t *, au_tid_addr_t *); |
| | | + |
| | | +extern void __auditd_debug(char *, ...); |
| | | + |
| | | +void |
| | | +__audit_pidinfo(void) |
| | | +{ |
| | | + adt_session_data_t *ah = NULL; |
| | | + au_id_t auid; |
| | | + char *auid_name = "badname"; |
| | | + struct passwd *pwd; |
| | | + au_asid_t asid; |
| | | + au_mask_t mask; |
| | | + char flags[512]; |
| | | + au_tid_addr_t tid; |
| | | + char pbuf[INET6_ADDRSTRLEN]; |
| | | + int af = AF_INET; |
| | | + int remote; |
| | | + int local; |
| | | + |
| | | + if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) { |
| | | + __auditd_debug("cannot start session %s\n", strerror(errno)); |
| | | + return; |
| | | + } |
| | | + if (ah == NULL) { |
| | | + __auditd_debug("ah is NULL\n"); |
| | | + return; |
| | | + } |
| | | + adt_get_auid(ah, &auid); |
| | | + if ((pwd = getpwuid((uid_t)auid)) != NULL) { |
| | | + auid_name = pwd->pw_name; |
| | | + } |
| | | + __auditd_debug("audit id = %s(%d)\n", auid_name, auid); |
| | | + |
| | | + adt_get_mask(ah, &mask); |
| | | + if (getauditflagschar(flags, &mask, NULL) < 0) { |
| | | + (void) strlcpy(flags, "badflags", sizeof (flags)); |
| | | + } |
| | | +#ifdef _LP64 |
| | | + __auditd_debug("preselection mask = %s(0x%lx,0x%lx)\n", flags, |
| | | + mask.am_success, mask.am_failure); |
| | | +#else /* _ILP32 */ |
| | | + __auditd_debug("preselection mask = %s(0x%llx,0x%llx)\n", flags, |
| | | + mask.am_success, mask.am_failure); |
| | | +#endif /* _LP64 */ |
| | | + |
| | | + adt_get_termid(ah, &tid); |
| | | + __auditd_debug("tid type=%d, maj=%u, min=%u, addr=%x:%x:%x:%x\n", |
| | | + tid.at_type, |
| | | + (uint16_t)((tid.at_port) >> BITS(uint16_t)), |
| | | + (uint16_t)(tid.at_port & UINT16_MAX), |
| | | + tid.at_addr[0], |
| | | + tid.at_addr[1], |
| | | + tid.at_addr[2], |
| | | + tid.at_addr[3]); |
| | | + if (tid.at_type == AU_IPv6) { |
| | | + af = AF_INET6; |
| | | + } |
| | | + (void) inet_ntop(af, (void *)(tid.at_addr), pbuf, |
| | | + sizeof (pbuf)); |
| | | + remote = (tid.at_port >> BITS(uint16_t)); |
| | | + local = (tid.at_port & UINT16_MAX); |
| | | + __auditd_debug("tid type-%d (remote,local,host)= %u,%u,%s\n", |
| | | + tid.at_type, remote, local, pbuf); |
| | | + adt_get_asid(ah, &asid); |
| | | + __auditd_debug("audit session id = %u\n", asid); |
| | | + (void) adt_end_session(ah); |
| | | +} |
| | | +#else /* !ADT_DEBUG */ |
| | | +/*ARGSUSED*/ |
| | | +/*PRINTFLIKE1*/ |
| | | +static void |
| | | +__auditd_debug(char *fmt, ...) |
| | | +{ |
| | | +} |
| | | +static void |
| | | +__audit_pidinfo() |
| | | +{ |
| | | +} |
| | | +#endif /* ADT_DEBUG */ |
| | | + |
| | | +#include <security/pam_appl.h> |
| | | + |
| | | +#include <sys/types.h> |
| | | + |
| | | +extern Authctxt *the_authctxt; |
| | | + |
| | | +extern const char *audit_username(void); |
| | | +extern const char *audit_event_lookup(ssh_audit_event_t); |
| | | + |
| | | +static adt_session_data_t *ah = NULL; /* audit session handle */ |
| | | +static adt_termid_t *tid = NULL; /* peer terminal id */ |
| | | + |
| | | +static void audit_login(void); |
| | | +static void audit_logout(void); |
| | | +static void audit_fail(int); |
| | | + |
| | | +/* Below is the sshd audit API Solaris adt interpretation */ |
| | | + |
| | | +/* |
| | | + * Called after a connection has been accepted but before any authentication |
| | | + * has been attempted. |
| | | + */ |
| | | +/* ARGSUSED */ |
| | | +void |
| | | +audit_connection_from(struct ssh *ssh, const char *host, int port) |
| | | +{ |
| | | + int peer = ssh_packet_get_connection_in(ssh); |
| | | + adt_session_data_t *ah = NULL; |
| | | + |
| | | + if (adt_load_termid(peer, &tid) != 0) { |
| | | + error("adt audit_connection_from: unable to load tid for %d:%s", |
| | | + peer, strerror(errno)); |
| | | + goto err; |
| | | + } |
| | | + if (adt_start_session(&ah, NULL, 0) != 0) { |
| | | + error("adt audit_connection_from: unable to start session " |
| | | + "for %s:%d:%s", host, port, strerror(errno)); |
| | | + goto err; |
| | | + } |
| | | + if (adt_set_user(ah, ADT_NO_AUDIT, ADT_NO_AUDIT, 0, |
| | | + ADT_NO_AUDIT, tid, ADT_SETTID) != 0) { |
| | | + error("adt audit_connection_from: unable to set user " |
| | | + "for %s:%d:%s", host, port, strerror(errno)); |
| | | + goto err; |
| | | + } |
| | | + if (adt_set_proc(ah) != 0) { |
| | | + error("adt audit_connection_from: unable to set proc " |
| | | + "for %s:%d:%s", host, port, strerror(errno)); |
| | | + goto err; |
| | | + } |
| | | + (void) adt_end_session(ah); |
| | | + debug("adt audit_connection_from(%s, %d): peerfd=%d", host, port, |
| | | + peer); |
| | | + __auditd_debug("%d/%d:%d-adt audit_connection_from(%s, %d)ctxt=%p: " |
| | | + "peerfd=%d\n", getpid(), getuid(), geteuid(), host, port, |
| | | + (void *)the_authctxt, peer); |
| | | + __audit_pidinfo(); |
| | | + return; |
| | | + |
| | | +err: |
| | | + free(tid); |
| | | + tid = NULL; |
| | | + if (ah != NULL) { |
| | | + (void) adt_end_session(ah); |
| | | + } |
| | | +} |
| | | + |
| | | +/* |
| | | + * Called when various events occur (see audit.h for a list of possible |
| | | + * events and what they mean). |
| | | + * |
| | | + * Entry the_authcntxt |
| | | + */ |
| | | +void |
| | | +audit_event(struct ssh *ssh, ssh_audit_event_t event) |
| | | +{ |
| | | + static boolean_t logged_in = B_FALSE; /* if user did login */ |
| | | + int fail = PAM_IGNORE; /* default unset */ |
| | | + static boolean_t did_maxtries = B_FALSE; /* if interactive and abort */ |
| | | + |
| | | + debug("adt audit_event(%s)", audit_event_lookup(event)); |
| | | + __auditd_debug("%d/%d:%d-adt audit_event(%s/%s)ctxt=%p\n", |
| | | + getpid(), getuid(), geteuid(), audit_event_lookup(event), |
| | | + audit_username(), (void *)the_authctxt); |
| | | + __audit_pidinfo(); |
| | | + |
| | | + switch (event) { |
| | | + case SSH_AUTH_SUCCESS: /* authentication success */ |
| | | + logged_in = B_TRUE; |
| | | + audit_login(); /* ADT_ssh; */ |
| | | + return; |
| | | + |
| | | + case SSH_CONNECTION_CLOSE: /* connection closed, all done */ |
| | | + if (logged_in) { |
| | | + audit_logout(); /* ADT_logout; */ |
| | | + logged_in = B_FALSE; |
| | | + } else { |
| | | + error("adt audit_event logout without login"); |
| | | + } |
| | | + free(tid); |
| | | + tid = NULL; |
| | | + return; |
| | | + |
| | | + /* Translate fail events to Solaris PAM errors */ |
| | | + |
| | | + /* auth2.c: userauth_finish as audit_event(SSH_LOGIN_EXCEED_MAXTRIES) */ |
| | | + /* auth1.c:do_authloop audit_event(SSH_LOGIN_EXCEED_MAXTRIES) */ |
| | | + case SSH_LOGIN_EXCEED_MAXTRIES: |
| | | + fail = PAM_MAXTRIES; |
| | | + did_maxtries = B_TRUE; |
| | | + break; |
| | | + |
| | | + /* auth2.c: userauth_finish as audit_event(SSH_LOGIN_ROOT_DENIED) */ |
| | | + /* auth1.c:do_authloop audit_event(SSH_LOGIN_ROOT_DENIED) */ |
| | | + case SSH_LOGIN_ROOT_DENIED: |
| | | + fail = PAM_PERM_DENIED; |
| | | + break; |
| | | + |
| | | + /* auth2.c: input_userauth_request as audit_event(SSH_INVALID_USER) */ |
| | | + /* auth.c: getpwnamallow as audit_event(SSH_INVALID_USER) */ |
| | | + case SSH_INVALID_USER: |
| | | + fail = PAM_USER_UNKNOWN; |
| | | + break; |
| | | + |
| | | + /* seems unused, but translate to the Solaris PAM error */ |
| | | + case SSH_NOLOGIN: |
| | | + fail = PAM_ACCT_EXPIRED; |
| | | + break; |
| | | + |
| | | + /* |
| | | + * auth.c in auth_log as it's walking through methods calls |
| | | + * audit_classify_method(method) which maps |
| | | + * |
| | | + * none -> SSH_AUTH_FAIL_NONE |
| | | + * password -> SSH_AUTH_FAIL_PASSWD |
| | | + * |
| | | + * publickey -> SSH_AUTH_FAIL_PUBKEY |
| | | + * rsa -> SSH_AUTH_FAIL_PUBKEY |
| | | + * |
| | | + * keyboard-interactive -> SSH_AUTH_FAIL_KBDINT |
| | | + * challenge-response -> SSH_AUTH_FAIL_KBDINT |
| | | + * |
| | | + * hostbased -> SSH_AUTH_FAIL_HOSTBASED |
| | | + * rhosts-rsa -> SSH_AUTH_FAIL_HOSTBASED |
| | | + * |
| | | + * gssapi-with-mic -> SSH_AUTH_FAIL_GSSAPI |
| | | + * |
| | | + * unknown method -> SSH_AUDIT_UNKNOWN |
| | | + */ |
| | | + /* |
| | | + * see mon_table mon_dispatch_proto20[], mon_dispatch_postauth20[], |
| | | + * mon_dispatch_proto15[], mon_dispatch_postauth15[]: |
| | | + * MONITOR_REQ_AUDIT_EVENT |
| | | + * called from monitor.c:mm_answer_audit_event() |
| | | + * SSH_AUTH_FAIL_PUBKEY, SSH_AUTH_FAIL_HOSTBASED, |
| | | + * SSH_AUTH_FAIL_GSSAPI, SSH_LOGIN_EXCEED_MAXTRIES, |
| | | + * SSH_LOGIN_ROOT_DENIED, SSH_CONNECTION_CLOSE SSH_INVALID_USER |
| | | + * monitor_wrap.c: mm_audit_event() |
| | | + */ |
| | | + case SSH_AUTH_FAIL_NONE: /* auth type none */ |
| | | + case SSH_AUTH_FAIL_PUBKEY: /* authtype publickey */ |
| | | + break; |
| | | + |
| | | + case SSH_AUTH_FAIL_PASSWD: /* auth type password */ |
| | | + case SSH_AUTH_FAIL_KBDINT: /* authtype keyboard-interactive */ |
| | | + case SSH_AUTH_FAIL_HOSTBASED: /* auth type hostbased */ |
| | | + case SSH_AUTH_FAIL_GSSAPI: /* auth type gssapi-with-mic */ |
| | | + case SSH_AUDIT_UNKNOWN: /* auth type unknown */ |
| | | + fail = PAM_AUTH_ERR; |
| | | + break; |
| | | + |
| | | + /* sshd.c: cleanup_exit: server specific fatal cleanup */ |
| | | + case SSH_CONNECTION_ABANDON: /* bailing with fatal error */ |
| | | + /* |
| | | + * This seems to occur with OpenSSH client when |
| | | + * the user login shell exits. |
| | | + */ |
| | | + if (logged_in) { |
| | | + audit_logout(); /* ADT_logout; */ |
| | | + logged_in = B_FALSE; |
| | | + return; |
| | | + } else if (!did_maxtries) { |
| | | + fail = PAM_AUTHINFO_UNAVAIL; |
| | | + } else { |
| | | + /* reset saw max tries */ |
| | | + did_maxtries = FALSE; |
| | | + } |
| | | + free(tid); |
| | | + tid = NULL; |
| | | + break; |
| | | + |
| | | + default: |
| | | + error("adt audit_event: unknown event %d", event); |
| | | + __auditd_debug("%d/%d:%d-unknown event %d", |
| | | + getpid(), getuid(), geteuid(), event); |
| | | + __audit_pidinfo(); |
| | | + break; |
| | | + } |
| | | + audit_fail(fail); |
| | | +} |
| | | + |
| | | +/* |
| | | + * Called when a user session is started. Argument is the tty allocated to |
| | | + * the session, or NULL if no tty was allocated. |
| | | + * |
| | | + * Note that this may be called multiple times if multiple sessions are used |
| | | + * within a single connection. |
| | | + */ |
| | | +/* ARGSUSED */ |
| | | +void |
| | | +audit_session_open(struct logininfo *li) |
| | | +{ |
| | | + const char *t = li->line ? li->line : "(no tty)"; |
| | | + |
| | | + debug("adt audit_session_open: user=%s:tty=%s", audit_username(), |
| | | + t); |
| | | + __auditd_debug("%d/%d:%d-adt audit_session_open:ctxt=%p " |
| | | + "user=%s:tty=%s\n", getpid(), getuid(), geteuid(), |
| | | + (void *)the_authctxt, audit_username(), t); |
| | | + __audit_pidinfo(); |
| | | +} |
| | | + |
| | | +/* |
| | | + * Called when a user session is closed. Argument is the tty allocated to |
| | | + * the session, or NULL if no tty was allocated. |
| | | + * |
| | | + * Note that this may be called multiple times if multiple sessions are used |
| | | + * within a single connection. |
| | | + */ |
| | | +/* ARGSUSED */ |
| | | +void |
| | | +audit_session_close(struct logininfo *li) |
| | | +{ |
| | | + const char *t = li->line ? li->line : "(no tty)"; |
| | | + |
| | | + debug("adt audit_session_close: user=%s:tty=%s", audit_username(), |
| | | + t); |
| | | + __auditd_debug("%d/%d:%d-adt audit_session_close:ctxt=%p " |
| | | + "user=%s:tty=%s\n", getpid(), getuid(), geteuid(), |
| | | + (void *)the_authctxt, audit_username(), t); |
| | | + __audit_pidinfo(); |
| | | +} |
| | | + |
| | | +/* |
| | | + * This will be called when a user runs a non-interactive command. Note that |
| | | + * it may be called multiple times for a single connection since SSH2 allows |
| | | + * multiple sessions within a single connection. |
| | | + */ |
| | | +/* ARGSUSED */ |
| | | +void |
| | | +audit_run_command(const char *command) |
| | | +{ |
| | | + debug("adt audit_run_command: \"%s\"", command); |
| | | + __auditd_debug("%d/%d:%d-adt audit_run_command:ctxt=%p \"%s\"\n", |
| | | + getpid(), getuid(), geteuid(), (void *)the_authctxt, command); |
| | | + __audit_pidinfo(); |
| | | +} |
| | | + |
| | | +/* |
| | | + * audit_login - audit successful login |
| | | + * |
| | | + * Entry the_authctxt should be valid ;-) |
| | | + * and pam_setcred called. |
| | | + * adt_info & ADT_INFO_PW_SUCCESS if successful |
| | | + * password change. |
| | | + * |
| | | + * Exit ah = audit session established for audit_logout(); |
| | | + */ |
| | | +static void |
| | | +audit_login(void) |
| | | +{ |
| | | + adt_event_data_t *event; |
| | | + uid_t uid = ADT_NO_ATTRIB; |
| | | + gid_t gid = (gid_t)ADT_NO_ATTRIB; |
| | | + au_id_t auid; |
| | | + |
| | | + if ((the_authctxt != NULL) && (the_authctxt->valid != 0)) { |
| | | + uid = the_authctxt->pw->pw_uid; |
| | | + gid = the_authctxt->pw->pw_gid; |
| | | + } |
| | | + |
| | | + if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) != 0) { |
| | | + error("adt_start_session: %s", strerror(errno)); |
| | | + return; |
| | | + } |
| | | + |
| | | + adt_get_auid(ah, &auid); |
| | | + |
| | | + if (adt_set_user(ah, uid, gid, uid, gid, NULL, |
| | | + auid == AU_NOAUDITID ? ADT_NEW : ADT_USER)) { |
| | | + error("adt_set_user auid=%d, uid=%d", auid, uid); |
| | | + (void) adt_end_session(ah); |
| | | + ah = NULL; |
| | | + free(tid); |
| | | + tid = NULL; |
| | | + return; |
| | | + } |
| | | + if ((event = adt_alloc_event(ah, ADT_ssh)) == NULL) { |
| | | + error("adt_alloc_event(ADT_ssh): %s", strerror(errno)); |
| | | + return; |
| | | + } |
| | | + if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { |
| | | + error("adt_put_event(ADT_ssh, ADT_SUCCESS): %s", |
| | | + strerror(errno)); |
| | | + } |
| | | + /* should audit successful password change here */ |
| | | + adt_free_event(event); |
| | | +} |
| | | + |
| | | +/* |
| | | + * audit_logout - audit the logout |
| | | + * |
| | | + * Entry ah = audit session. |
| | | + */ |
| | | +static void |
| | | +audit_logout(void) |
| | | +{ |
| | | + adt_event_data_t *event; |
| | | + |
| | | + if ((event = adt_alloc_event(ah, ADT_logout)) == NULL) { |
| | | + error("adt_alloc_event(ADT_logout): %s", strerror(errno)); |
| | | + return; |
| | | + } |
| | | + if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) { |
| | | + error("adt_put_event(ADT_logout, ADT_SUCCESS): %s", |
| | | + strerror(errno)); |
| | | + } |
| | | + adt_free_event(event); |
| | | + (void) adt_end_session(ah); |
| | | + ah = NULL; |
| | | +} |
| | | + |
| | | +/* |
| | | + * audit_fail - audit login failure. |
| | | + * |
| | | + * Entry the_authctxt assumed to have some info. |
| | | + * user = user who asked to be authenticated. |
| | | + * tid = connection audit TID set by audit_connect_from(); |
| | | + * |
| | | + * N.B. pam_strerror() prototype takes a pam handle and error number. |
| | | + * At least on Solaris, pam_strerror never uses the pam handle. |
| | | + * Since there doesn't seem to be a pam handle available, this |
| | | + * code just uses NULL. |
| | | + */ |
| | | +static void |
| | | +audit_fail(int pamerr) |
| | | +{ |
| | | + adt_session_data_t *ah = NULL; |
| | | + adt_event_data_t *event; |
| | | + uid_t uid = ADT_NO_ATTRIB; |
| | | + gid_t gid = (gid_t)ADT_NO_ATTRIB; |
| | | + |
| | | + __auditd_debug("%d/%d:%d-audit_fail(%s) ctxt=%p\n", |
| | | + getpid(), getuid(), geteuid(), pam_strerror(NULL, pamerr), |
| | | + (void *)the_authctxt); |
| | | + if (the_authctxt != NULL) { |
| | | + uid_t pwuid = ADT_NO_ATTRIB; |
| | | + |
| | | + if (the_authctxt->pw != NULL) { |
| | | + pwuid = the_authctxt->pw->pw_uid; |
| | | + } |
| | | + __auditd_debug("valid=%d, user=%s, uid=%d\n", |
| | | + the_authctxt->valid, audit_username(), pwuid); |
| | | + } else { |
| | | + __auditd_debug("\tNo autxctxt\n"); |
| | | + } |
| | | + __audit_pidinfo(); |
| | | + if (pamerr == PAM_IGNORE) { |
| | | + return; |
| | | + } |
| | | + if ((the_authctxt != NULL) && (the_authctxt->valid != 0)) { |
| | | + uid = the_authctxt->pw->pw_uid; |
| | | + gid = the_authctxt->pw->pw_gid; |
| | | + } else if ((the_authctxt != NULL) && (the_authctxt->user != NULL)) { |
| | | + struct passwd *pw; |
| | | + |
| | | + if ((pw = getpwnam(the_authctxt->user)) != NULL) { |
| | | + uid = pw->pw_uid; |
| | | + gid = pw->pw_gid; |
| | | + } |
| | | + } |
| | | + if (adt_start_session(&ah, NULL, 0) != 0) { |
| | | + error("adt_start_session(ADT_ssh, 0, fail=%s):" |
| | | + " %s", pam_strerror(NULL, pamerr), strerror(errno)); |
| | | + __auditd_debug("%d/%d:%d-adt_start_session(ADT_ssh, " |
| | | + "PROC_DATA, fail=%s): %s", getpid(), getuid(), |
| | | + geteuid(), pam_strerror(NULL, pamerr), |
| | | + strerror(errno)); |
| | | + return; |
| | | + } |
| | | + __auditd_debug("%d/%d:%d-audit_fail+start_session() ah=%p\n", |
| | | + getpid(), getuid(), geteuid(), (void *)ah); |
| | | + if (adt_set_user(ah, uid, gid, uid, gid, tid, ADT_NEW) != 0) { |
| | | + error("adt_set_user(ADT_ssh, PROC_DATA, fail=%s): %s", |
| | | + pam_strerror(NULL, pamerr), strerror(errno)); |
| | | + __auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, " |
| | | + "PROC_DATA, fail=%s): %s", getpid(), getuid(), |
| | | + geteuid(), pam_strerror(NULL, pamerr), |
| | | + strerror(errno)); |
| | | + goto done; |
| | | + } |
| | | + __auditd_debug("%d/%d:%d-audit_fail+set_user() ah=%p\n", getpid(), |
| | | + getuid(), geteuid(), (void *)ah); |
| | | + if ((event = adt_alloc_event(ah, ADT_ssh)) == NULL) { |
| | | + error("adt_alloc_event(ADT_ssh, fail=%s): %s", |
| | | + pam_strerror(NULL, pamerr), strerror(errno)); |
| | | + __auditd_debug("%d/%d:%d-adt_set_user(ADT_ssh, 0, " |
| | | + "fail=%s): %s", getpid(), getuid(), geteuid(), |
| | | + pam_strerror(NULL, pamerr), strerror(errno)); |
| | | + } else if (adt_put_event(event, ADT_FAILURE, |
| | | + ADT_FAIL_PAM + pamerr) != 0) { |
| | | + error("adt_put_event(ADT_ssh, fail=%s): %s", |
| | | + pam_strerror(NULL, pamerr), strerror(errno)); |
| | | + __auditd_debug("%d/%d:%d-adt_put_event(ADT_ssh, fail=%s): %s", |
| | | + getpid(), getuid(), geteuid(), pam_strerror(NULL, pamerr), |
| | | + strerror(errno)); |
| | | + } |
| | | + __auditd_debug("%d/%d:%d-audit_fail+put_event() ah=%p\n", getpid(), |
| | | + getuid(), geteuid(), (void *)ah); |
| | | + /* should audit authentication with failed password change here. */ |
| | | + adt_free_event(event); |
| | | +done: |
| | | + (void) adt_end_session(ah); |
| | | +} |
| | | +#endif /* USE_SOLARIS_AUDIT */ |
| | | --- hpn-ssh-hpn-18.3.1/audit.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/audit.c |
| | | @@ -120,7 +120,7 @@ |
| | | * has been attempted. |
| | | */ |
| | | void |
| | | -audit_connection_from(const char *host, int port) |
| | | +audit_connection_from(struct ssh *, const char *host, int port) |
| | | { |
| | | debug("audit connection from %s port %d euid %d", host, port, |
| | | (int)geteuid()); |
| | | --- hpn-ssh-hpn-18.3.1/audit.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/audit.h |
| | | @@ -47,7 +47,7 @@ |
| | | }; |
| | | typedef enum ssh_audit_event_type ssh_audit_event_t; |
| | | |
| | | -void audit_connection_from(const char *, int); |
| | | +void audit_connection_from(struct ssh *, const char *, int); |
| | | void audit_event(struct ssh *, ssh_audit_event_t); |
| | | void audit_session_open(struct logininfo *); |
| | | void audit_session_close(struct logininfo *); |
| | | --- hpn-ssh-hpn-18.3.1/configure.ac.orig |
| | | +++ hpn-ssh-hpn-18.3.1/configure.ac |
| | | @@ -1761,7 +1761,7 @@ |
| | | |
| | | AUDIT_MODULE=none |
| | | AC_ARG_WITH([audit], |
| | | - [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], |
| | | + [ --with-audit=module Enable audit support (modules=debug,bsm,linux,solaris)], |
| | | [ |
| | | AC_MSG_CHECKING([for supported audit module]) |
| | | case "$withval" in |
| | | @@ -1798,6 +1798,13 @@ |
| | | SSHDLIBS="$SSHDLIBS -laudit" |
| | | AC_DEFINE([USE_LINUX_AUDIT], [1], [Use Linux audit module]) |
| | | ;; |
| | | + solaris) |
| | | + AC_MSG_RESULT([solaris]) |
| | | + AUDIT_MODULE=solaris |
| | | + AC_CHECK_HEADERS([bsm/adt.h]) |
| | | + SSHDLIBS="$SSHDLIBS -lbsm" |
| | | + AC_DEFINE([USE_SOLARIS_AUDIT], [1], [Use Solaris audit module]) |
| | | + ;; |
| | | debug) |
| | | AUDIT_MODULE=debug |
| | | AC_MSG_RESULT([debug]) |
| | | --- hpn-ssh-hpn-18.3.1/defines.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/defines.h |
| | | @@ -715,6 +715,11 @@ |
| | | # define CUSTOM_SSH_AUDIT_EVENTS |
| | | #endif |
| | | |
| | | +#ifdef USE_SOLARIS_AUDIT |
| | | +# define SSH_AUDIT_EVENTS |
| | | +# define CUSTOM_SSH_AUDIT_EVENTS |
| | | +#endif |
| | | + |
| | | #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) |
| | | # define __func__ __FUNCTION__ |
| | | #elif !defined(HAVE___func__) |
| | | --- hpn-ssh-hpn-18.3.1/sshd.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshd.c |
| | | @@ -2216,7 +2216,7 @@ |
| | | remote_ip = ssh_remote_ipaddr(ssh); |
| | | |
| | | #ifdef SSH_AUDIT_EVENTS |
| | | - audit_connection_from(remote_ip, remote_port); |
| | | + audit_connection_from(ssh, remote_ip, remote_port); |
| | | #endif |
| | | |
| | | rdomain = ssh_packet_rdomain_in(ssh); |
| | | @@ -2308,8 +2308,10 @@ |
| | | } |
| | | |
| | | #ifdef SSH_AUDIT_EVENTS |
| | | +#ifndef USE_SOLARIS_AUDIT |
| | | audit_event(ssh, SSH_AUTH_SUCCESS); |
| | | #endif |
| | | +#endif |
| | | |
| | | #ifdef GSSAPI |
| | | if (options.gss_authentication) { |
| | | @@ -2338,6 +2340,10 @@ |
| | | do_pam_session(ssh); |
| | | } |
| | | #endif |
| | | +#ifdef USE_SOLARIS_AUDIT |
| | | + /* Audit should take place after all successful pam */ |
| | | + audit_event(ssh, SSH_AUTH_SUCCESS); |
| | | +#endif /* USE_SOLARIS_AUDIT */ |
| | | |
| | | /* |
| | | * In privilege separation, we fork another child and prepare |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/auth-pam.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth-pam.c |
| | | @@ -1213,6 +1213,20 @@ |
| | | return (sshpam_account_status); |
| | | } |
| | | |
| | | +#ifdef HAVE_PAM_AUSER |
| | | +void |
| | | +do_pam_set_auser(const char* auser) |
| | | +{ |
| | | + if (auser != NULL) { |
| | | + debug("PAM: setting PAM_AUSER to \"%s\"", auser); |
| | | + sshpam_err = pam_set_item(sshpam_handle, PAM_AUSER, auser); |
| | | + if (sshpam_err != PAM_SUCCESS) |
| | | + error("PAM: failed to set PAM_AUSER: %s", |
| | | + pam_strerror(sshpam_handle, sshpam_err)); |
| | | + } |
| | | +} |
| | | +#endif |
| | | + |
| | | void |
| | | do_pam_setcred(int init) |
| | | { |
| | | --- hpn-ssh-hpn-18.3.1/auth-pam.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth-pam.h |
| | | @@ -44,4 +44,9 @@ |
| | | void sshpam_set_maxtries_reached(int); |
| | | int is_pam_session_open(void); |
| | | |
| | | +#ifdef HAVE_PAM_AUSER |
| | | +void do_pam_set_auser(const char *); |
| | | +#endif |
| | | +void do_pam_set_tty(const char *); |
| | | + |
| | | #endif /* USE_PAM */ |
| | | --- hpn-ssh-hpn-18.3.1/auth.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth.h |
| | | @@ -98,6 +98,9 @@ |
| | | #ifdef PAM_ENHANCEMENT |
| | | char *authmethod_name; |
| | | #endif |
| | | +#ifdef HAVE_PAM_AUSER |
| | | + char *auser; |
| | | +#endif |
| | | }; |
| | | |
| | | /* |
| | | --- hpn-ssh-hpn-18.3.1/auth2-hostbased.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth2-hostbased.c |
| | | @@ -80,6 +80,9 @@ |
| | | debug("signature:"); |
| | | sshbuf_dump_data(sig, slen, stderr); |
| | | #endif |
| | | +#ifdef HAVE_PAM_AUSER |
| | | + authctxt->auser = NULL; |
| | | +#endif |
| | | pktype = sshkey_type_from_name(pkalg); |
| | | if (pktype == KEY_UNSPEC) { |
| | | /* this is perfectly legal */ |
| | | @@ -151,6 +154,13 @@ |
| | | sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0) |
| | | authenticated = 1; |
| | | |
| | | +#ifdef HAVE_PAM_AUSER |
| | | + if (authenticated) { |
| | | + authctxt->auser = cuser; |
| | | + cuser = NULL; |
| | | + } |
| | | +#endif |
| | | + |
| | | auth2_record_key(authctxt, authenticated, key); |
| | | sshbuf_free(b); |
| | | done: |
| | | --- hpn-ssh-hpn-18.3.1/auth2.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth2.c |
| | | @@ -427,6 +427,14 @@ |
| | | #endif |
| | | } |
| | | |
| | | +#ifdef HAVE_PAM_AUSER |
| | | + if (!use_privsep) { |
| | | + do_pam_set_auser(authctxt->auser); |
| | | + free(authctxt->auser); |
| | | + authctxt->auser = NULL; |
| | | + } |
| | | +#endif |
| | | + |
| | | if (authenticated && options.num_auth_methods != 0) { |
| | | |
| | | #if defined(USE_PAM) && defined(PAM_ENHANCEMENT) |
| | | --- hpn-ssh-hpn-18.3.1/monitor.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/monitor.c |
| | | @@ -391,6 +391,12 @@ |
| | | } |
| | | } |
| | | |
| | | +#if defined(HAVE_PAM_AUSER) && defined(USE_PAM) |
| | | + if (hostbased_cuser != NULL) { |
| | | + free(hostbased_cuser); |
| | | + hostbased_cuser = NULL; |
| | | + } |
| | | +#endif |
| | | if (!authctxt->valid) |
| | | fatal_f("authenticated invalid user"); |
| | | if (strcmp(auth_method, "unknown") == 0) |
| | | @@ -594,14 +600,16 @@ |
| | | { |
| | | /* reset state */ |
| | | free(key_blob); |
| | | +#if !defined(HAVE_PAM_AUSER) || !defined(USE_PAM) |
| | | free(hostbased_cuser); |
| | | + hostbased_cuser = NULL; |
| | | +#endif |
| | | free(hostbased_chost); |
| | | sshauthopt_free(key_opts); |
| | | key_blob = NULL; |
| | | key_bloblen = 0; |
| | | key_blobtype = MM_NOKEY; |
| | | key_opts = NULL; |
| | | - hostbased_cuser = NULL; |
| | | hostbased_chost = NULL; |
| | | } |
| | | |
| | | @@ -1074,6 +1082,11 @@ |
| | | if (!options.use_pam) |
| | | fatal("%s: PAM not enabled", __func__); |
| | | |
| | | +#ifdef HAVE_PAM_AUSER |
| | | + if (hostbased_cuser != NULL) |
| | | + do_pam_set_auser(hostbased_cuser); |
| | | +#endif |
| | | + |
| | | ret = do_pam_account(); |
| | | |
| | | if ((r = sshbuf_put_u32(m, ret)) != 0 || |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/auth-pam.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth-pam.c |
| | | @@ -1246,12 +1246,19 @@ |
| | | sshpam_cred_established = 1; |
| | | return; |
| | | } |
| | | + |
| | | +#ifdef PAM_BUGFIX |
| | | + /* Server will fatal out when pam_setcred() failed. */ |
| | | + fatal("PAM: pam_setcred(): %s", pam_strerror(sshpam_handle, |
| | | + sshpam_err)); |
| | | +#else /* orig */ |
| | | if (sshpam_authenticated) |
| | | fatal("PAM: pam_setcred(): %s", |
| | | pam_strerror(sshpam_handle, sshpam_err)); |
| | | else |
| | | debug("PAM: pam_setcred(): %s", |
| | | pam_strerror(sshpam_handle, sshpam_err)); |
| | | +#endif /* PAM_BUGFIX */ |
| | | } |
| | | |
| | | static int |
| | | @@ -1347,10 +1354,16 @@ |
| | | if (sshpam_err == PAM_SUCCESS) |
| | | sshpam_session_open = 1; |
| | | else { |
| | | +#ifdef PAM_BUGFIX |
| | | + /* Server will fatal out when pam_open_session() failed */ |
| | | + fatal("PAM: pam_open_session(): %s", |
| | | + pam_strerror(sshpam_handle, sshpam_err)); |
| | | +#else /* orig */ |
| | | sshpam_session_open = 0; |
| | | auth_restrict_session(ssh); |
| | | error("PAM: pam_open_session(): %s", |
| | | pam_strerror(sshpam_handle, sshpam_err)); |
| | | +#endif /* PAM_BUGFIX */ |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | # This issue has been raised with the upstream OpenSSH community: |
| | | # |
| | | # 2426 OpenSSH doesn't need the second call to do_pam_setcred() on non-Linux |
| | | # platforms |
| | | # https://bugzilla.mindrot.org/show_bug.cgi?id=2426 |
| | | # |
| | | # The OpenSSH maintainers added a call to do_pam_setcred() in |
| | | # platform_setusercontext_post_groups() with no corresponding bugID along with |
| | | # a befuddling comment that initgroups(3C) wipes out supplementary groups: |
| | | # |
| | | #https://anongit.mindrot.org/openssh.git/commit/platform.c?id=cc12418e18242ce1f61d7035da4956274ba13a96 |
| | | # |
| | | # This only applies in the Linux world if the LinuxPAM pam_group(8) module |
| | | # has been installed and configured which allows one to assign additional |
| | | # secondary groups to a user using /etc/security/group.conf in addition to |
| | | # /etc/group. To confuse things a bit more, there is an OpenPAM PAM module |
| | | # of the same name, pam_group(8), which has different functionality, it |
| | | # performs access control based on group membership. |
| | | # |
| | | # In short, this additional call to do_pam_setcred() is Linux-specific and |
| | | # shouldn't be called on Solaris. |
| | | # |
| | | --- hpn-ssh-hpn-18.3.1/platform.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/platform.c |
| | | @@ -146,7 +146,7 @@ |
| | | void |
| | | platform_setusercontext_post_groups(struct passwd *pw) |
| | | { |
| | | -#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) |
| | | +#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) && !defined(PAM_SUN_CODEBASE) |
| | | /* |
| | | * PAM credentials may take the form of supplementary groups. |
| | | * These will have been wiped by the above initgroups() call. |
New file |
| | |
| | | This patch is to fix a X11 connection failure when a user's home directory |
| | | is read-only. |
| | | |
| | | Oracle contributed back this fix to the OpenSSH upstream community. For |
| | | more information, see https://bugzilla.mindrot.org/show_bug.cgi?id=2440 |
| | | In the future, if this fix is accepted by the upsteam in a later release, we |
| | | will remove this patch when we upgrade to that release. |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/session.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/session.c |
| | | @@ -62,6 +62,10 @@ |
| | | #include <unistd.h> |
| | | #include <limits.h> |
| | | |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | +#include <libgen.h> |
| | | +#endif |
| | | + |
| | | #include "openbsd-compat/sys-queue.h" |
| | | #include "xmalloc.h" |
| | | #include "ssh.h" |
| | | @@ -129,6 +133,11 @@ |
| | | |
| | | static int session_pty_req(struct ssh *, Session *); |
| | | |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | +void session_xauthfile_cleanup(Session *); |
| | | +void cleanup_all_session_xauthfile(); |
| | | +#endif |
| | | + |
| | | /* import */ |
| | | extern ServerOptions options; |
| | | extern char *__progname; |
| | | @@ -1104,6 +1113,11 @@ |
| | | auth_sock_name); |
| | | |
| | | |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + if (s->auth_file != NULL) |
| | | + child_set_env(&env, &envsize, "XAUTHORITY", s->auth_file); |
| | | +#endif |
| | | + |
| | | /* Set custom environment options from pubkey authentication. */ |
| | | if (options.permit_user_env) { |
| | | for (n = 0 ; n < auth_opts->nenv; n++) { |
| | | @@ -2006,6 +2020,11 @@ |
| | | int r, success; |
| | | u_char single_connection = 0; |
| | | |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + int fd; |
| | | + char xauthdir[] = "/tmp/ssh-xauth-XXXXXX"; |
| | | +#endif |
| | | + |
| | | if (s->auth_proto != NULL || s->auth_data != NULL) { |
| | | error("session_x11_req: session %d: " |
| | | "x11 forwarding already active", s->self); |
| | | @@ -2020,19 +2039,82 @@ |
| | | |
| | | s->single_connection = single_connection; |
| | | |
| | | - if (xauth_valid_string(s->auth_proto) && |
| | | - xauth_valid_string(s->auth_data)) |
| | | - success = session_setup_x11fwd(ssh, s); |
| | | - else { |
| | | + if (!xauth_valid_string(s->auth_proto) || |
| | | + !xauth_valid_string(s->auth_data)) { |
| | | success = 0; |
| | | error("Invalid X11 forwarding data"); |
| | | + goto out; |
| | | } |
| | | + |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + /* |
| | | + * Create per session X authority file in the /tmp directory. |
| | | + * |
| | | + * If mkdtemp() or open() fails then s->auth_file remains NULL which |
| | | + * means that we won't set XAUTHORITY variable in child's environment |
| | | + * and xauth(1) will use the default location for the authority file. |
| | | + */ |
| | | + temporarily_use_uid(s->pw); |
| | | + if (mkdtemp(xauthdir) != NULL) { |
| | | + s->auth_file = xmalloc(MAXPATHLEN); |
| | | + if (snprintf(s->auth_file, MAXPATHLEN, "%s/xauthfile", |
| | | + xauthdir) >= MAXPATHLEN) { |
| | | + error("temporary X authority file name was too long " |
| | | + "for the buffer allocated"); |
| | | + success = 0; |
| | | + restore_uid(); |
| | | + goto out; |
| | | + } |
| | | + /* |
| | | + * we don't want that "creating new authority file" message to |
| | | + * be printed by xauth(1) so we must create that file |
| | | + * beforehand. |
| | | + */ |
| | | + if ((fd = open(s->auth_file, O_CREAT | O_EXCL | O_RDONLY, |
| | | + S_IRUSR | S_IWUSR)) == -1) { |
| | | + error("failed to create the temporary X authority " |
| | | + "file %s: %.100s; will use the default one", |
| | | + s->auth_file, strerror(errno)); |
| | | + free(s->auth_file); |
| | | + s->auth_file = NULL; |
| | | + if (rmdir(xauthdir) == -1) { |
| | | + error("cannot remove xauth directory " |
| | | + "%s: %.100s", xauthdir, strerror(errno)); |
| | | + } |
| | | + } else { |
| | | + if (close(fd) != 0) { |
| | | + error("close() failed on temporary X authority " |
| | | + "file: %s", strerror(errno)); |
| | | + success = 0; |
| | | + restore_uid(); |
| | | + goto out; |
| | | + } |
| | | + debug("temporary X authority file %s created", |
| | | + s->auth_file); |
| | | + debug("session number = %d", s->self); |
| | | + } |
| | | + } else { |
| | | + error("failed to create a directory for the temporary X " |
| | | + "authority file: %.100s; will use the default xauth file", |
| | | + strerror(errno)); |
| | | + } |
| | | + restore_uid(); |
| | | +#endif |
| | | + |
| | | + success = session_setup_x11fwd(ssh, s); |
| | | + |
| | | +out: |
| | | if (!success) { |
| | | free(s->auth_proto); |
| | | free(s->auth_data); |
| | | s->auth_proto = NULL; |
| | | s->auth_data = NULL; |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + free(s->auth_file); |
| | | + s->auth_file = NULL; |
| | | +#endif |
| | | } |
| | | + |
| | | return success; |
| | | } |
| | | |
| | | @@ -2312,6 +2394,51 @@ |
| | | PRIVSEP(session_pty_cleanup2(s)); |
| | | } |
| | | |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | +/* |
| | | + * We use a different temporary X authority file per session so we should |
| | | + * remove those files when cleanup_exit() is called. |
| | | + */ |
| | | +void |
| | | +session_xauthfile_cleanup(Session *s) |
| | | +{ |
| | | + if (s == NULL || s->auth_file == NULL) { |
| | | + return; |
| | | + } |
| | | + |
| | | + debug("session_xauthfile_cleanup: session %d removing %s", s->self, |
| | | + s->auth_file); |
| | | + |
| | | + if (unlink(s->auth_file) == -1) { |
| | | + error("session_xauthfile_cleanup: cannot remove xauth file " |
| | | + "%s: %.100s", s->auth_file, strerror(errno)); |
| | | + return; |
| | | + } |
| | | + |
| | | + /* dirname() will modify s->auth_file but that's ok */ |
| | | + if (rmdir(dirname(s->auth_file)) == -1) { |
| | | + error("session_xauthfile_cleanup: " |
| | | + "cannot remove xauth directory %s: %.100s", |
| | | + s->auth_file, strerror(errno)); |
| | | + return; |
| | | + } |
| | | + free(s->auth_file); |
| | | + s->auth_file = NULL; |
| | | +} |
| | | + |
| | | +/* |
| | | + * This is called by do_cleanup() when cleanup_exit() is called. |
| | | + */ |
| | | +void |
| | | +cleanup_all_session_xauthfile() |
| | | +{ |
| | | + int i; |
| | | + for (i = 0; i < sessions_nalloc; i++) { |
| | | + session_xauthfile_cleanup(&sessions[i]); |
| | | + } |
| | | +} |
| | | +#endif |
| | | + |
| | | static char * |
| | | sig2name(int sig) |
| | | { |
| | | @@ -2459,6 +2586,9 @@ |
| | | free(s->auth_display); |
| | | free(s->auth_data); |
| | | free(s->auth_proto); |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + session_xauthfile_cleanup(s); |
| | | +#endif |
| | | free(s->subsys); |
| | | if (s->env != NULL) { |
| | | for (i = 0; i < s->num_env; i++) { |
| | | @@ -2714,6 +2844,10 @@ |
| | | auth_info_file = NULL; |
| | | } |
| | | |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + cleanup_all_session_xauthfile(); |
| | | +#endif |
| | | + |
| | | /* |
| | | * Cleanup ptys/utmp only if privsep is disabled, |
| | | * or if running in monitor. |
| | | --- hpn-ssh-hpn-18.3.1/session.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/session.h |
| | | @@ -50,6 +50,9 @@ |
| | | char *auth_display; |
| | | char *auth_proto; |
| | | char *auth_data; |
| | | +#ifdef PER_SESSION_XAUTHFILE |
| | | + char *auth_file; /* xauth(1) authority file */ |
| | | +#endif |
| | | int single_connection; |
| | | |
| | | int chanid; |
New file |
| | |
| | | This adds the PubKeyPlugin directive and associated code from |
| | | SunSSH, allowing an in-process shared library to be called |
| | | into to check public keys for authentication. |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/auth2-pubkey.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/auth2-pubkey.c |
| | | @@ -23,6 +23,11 @@ |
| | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| | | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| | | */ |
| | | +/* |
| | | + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
| | | + * Copyright 2015 Joyent, Inc. |
| | | + * Use is subject to license terms. |
| | | + */ |
| | | |
| | | #include "includes.h" |
| | | |
| | | @@ -41,11 +46,13 @@ |
| | | #include <time.h> |
| | | #include <unistd.h> |
| | | #include <limits.h> |
| | | +#include <dlfcn.h> |
| | | |
| | | #include "xmalloc.h" |
| | | #include "ssh.h" |
| | | #include "ssh2.h" |
| | | #include "packet.h" |
| | | +#include "digest.h" |
| | | #include "kex.h" |
| | | #include "sshbuf.h" |
| | | #include "log.h" |
| | | @@ -84,6 +91,15 @@ |
| | | return ret; |
| | | } |
| | | |
| | | +static const char *RSA_SYM_NAME = "sshd_user_rsa_key_allowed"; |
| | | +static const char *ECDSA_SYM_NAME = "sshd_user_ecdsa_key_allowed"; |
| | | +typedef int (*RSA_SYM)(struct passwd *, RSA *, const char *); |
| | | +typedef int (*ECDSA_SYM)(struct passwd *, EC_KEY *, const char *); |
| | | + |
| | | +static const char *UNIV_SYM_NAME = "sshd_user_key_allowed"; |
| | | +typedef int (*UNIV_SYM)(struct passwd *, const char *, |
| | | + const u_char *, size_t); |
| | | + |
| | | static int |
| | | userauth_pubkey(struct ssh *ssh, const char *method) |
| | | { |
| | | @@ -745,6 +761,124 @@ |
| | | return found_key; |
| | | } |
| | | |
| | | +/** |
| | | + * Checks whether or not access is allowed based on a plugin specified |
| | | + * in sshd_config (PubKeyPlugin). |
| | | + * |
| | | + * Note that this expects a symbol in the loaded library that takes |
| | | + * the current user (pwd entry), the current RSA key and it's fingerprint. |
| | | + * The symbol is expected to return 1 on success and 0 on failure. |
| | | + * |
| | | + * While we could optimize this code to dlopen once in the process' lifetime, |
| | | + * sshd is already a slow beast, so this is really not a concern. |
| | | + * The overhead is basically a rounding error compared to everything else, and |
| | | + * it keeps this code minimally invasive. |
| | | + */ |
| | | +static int |
| | | +user_key_allowed_from_plugin(struct passwd *pw, struct sshkey *key) |
| | | +{ |
| | | + RSA_SYM rsa_sym = NULL; |
| | | + ECDSA_SYM ecdsa_sym = NULL; |
| | | + UNIV_SYM univ_sym = NULL; |
| | | + char *fp = NULL; |
| | | + char *argfp = NULL; |
| | | + void *handle = NULL; |
| | | + int success = 0; |
| | | + |
| | | + if (options.pubkey_plugin == NULL || pw == NULL || key == NULL || |
| | | + (key->type != KEY_RSA && |
| | | + key->type != KEY_DSA && key->type != KEY_ECDSA)) |
| | | + return success; |
| | | + |
| | | + handle = dlopen(options.pubkey_plugin, RTLD_NOW); |
| | | + if (handle == NULL) { |
| | | + debug("Unable to open library %s: %s", options.pubkey_plugin, |
| | | + dlerror()); |
| | | + goto out; |
| | | + } |
| | | + |
| | | + /* |
| | | + * If we have the new-style universal symbol for checking keys, use |
| | | + * that instead of the old-style per-key-type symbols. |
| | | + */ |
| | | + univ_sym = (UNIV_SYM)dlsym(handle, UNIV_SYM_NAME); |
| | | + if (univ_sym != NULL) { |
| | | + u_char *blob; |
| | | + const char *type = sshkey_type(key); |
| | | + size_t len = 0; |
| | | + if (sshkey_to_blob(key, &blob, &len) != 0) { |
| | | + debug("failed to convert key to rfc4253 format"); |
| | | + goto out; |
| | | + } |
| | | + debug("Invoking %s from %s", UNIV_SYM_NAME, |
| | | + options.pubkey_plugin); |
| | | + success = (*univ_sym)(pw, type, blob, len); |
| | | + debug("pubkeyplugin returned: %d", success); |
| | | + goto out; |
| | | + } |
| | | + |
| | | + /* Otherwise, continue with the old-style fingerprint symbols. */ |
| | | + fp = sshkey_fingerprint(key, SSH_DIGEST_MD5, SSH_FP_HEX); |
| | | + if (fp == NULL) { |
| | | + debug("failed to generate fingerprint"); |
| | | + goto out; |
| | | + } |
| | | + if (strncmp(fp, "MD5:", 4) != 0) { |
| | | + debug("fingerprint not in MD5:hex format"); |
| | | + goto out; |
| | | + } |
| | | + /* give the plugin the string without leading MD5: */ |
| | | + argfp = fp + 4; |
| | | + |
| | | + switch (key->type) { |
| | | + case KEY_RSA: |
| | | + rsa_sym = (RSA_SYM)dlsym(handle, RSA_SYM_NAME); |
| | | + if (rsa_sym == NULL) { |
| | | + debug("Unable to resolve symbol %s: %s", RSA_SYM_NAME, |
| | | + dlerror()); |
| | | + goto out; |
| | | + } |
| | | + debug2("Invoking %s from %s", RSA_SYM_NAME, |
| | | + options.pubkey_plugin); |
| | | + success = (*rsa_sym)(pw, key->rsa, argfp); |
| | | + break; |
| | | + case KEY_ECDSA: |
| | | + ecdsa_sym = (ECDSA_SYM)dlsym(handle, ECDSA_SYM_NAME); |
| | | + if (ecdsa_sym == NULL) { |
| | | + debug("Unable to resolve symbol %s: %s", ECDSA_SYM_NAME, |
| | | + dlerror()); |
| | | + goto out; |
| | | + } |
| | | + debug2("Invoking %s from %s", ECDSA_SYM_NAME, |
| | | + options.pubkey_plugin); |
| | | + success = (*ecdsa_sym)(pw, key->ecdsa, argfp); |
| | | + break; |
| | | + default: |
| | | + debug2("user_key_plugins only support RSA and ECDSA keys"); |
| | | + } |
| | | + |
| | | + debug("pubkeyplugin returned: %d", success); |
| | | + |
| | | +out: |
| | | + if (handle != NULL) { |
| | | + dlclose(handle); |
| | | + ecdsa_sym = NULL; |
| | | + rsa_sym = NULL; |
| | | + univ_sym = NULL; |
| | | + handle = NULL; |
| | | + } |
| | | + |
| | | + if (success) |
| | | + verbose("Found matching %s key: %s", sshkey_type(key), fp); |
| | | + |
| | | + if (fp != NULL) { |
| | | + free(fp); |
| | | + fp = NULL; |
| | | + } |
| | | + |
| | | + return success; |
| | | +} |
| | | + |
| | | /* |
| | | * Check whether key authenticates and authorises the user. |
| | | */ |
| | | @@ -796,6 +930,10 @@ |
| | | sshauthopt_free(opts); |
| | | opts = NULL; |
| | | |
| | | + success = user_key_allowed_from_plugin(pw, key); |
| | | + if (success > 0) |
| | | + goto out; |
| | | + |
| | | if ((success = user_key_command_allowed2(pw, key, remote_ip, |
| | | remote_host, conn_id, rdomain, &opts)) != 0) |
| | | goto out; |
| | | --- hpn-ssh-hpn-18.3.1/servconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.c |
| | | @@ -215,6 +215,7 @@ |
| | | */ |
| | | options->pam_service_per_authmethod = 1; |
| | | #endif |
| | | + options->pubkey_plugin = NULL; |
| | | } |
| | | |
| | | /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ |
| | | @@ -577,6 +578,7 @@ |
| | | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, |
| | | sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, |
| | | sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, |
| | | + sPubKeyPlugin, |
| | | sDeprecated, sIgnore, sUnsupported |
| | | } ServerOpCodes; |
| | | |
| | | @@ -748,6 +750,7 @@ |
| | | { "exposeauthinfo", sExposeAuthInfo, SSHCFG_ALL }, |
| | | { "rdomain", sRDomain, SSHCFG_ALL }, |
| | | { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, |
| | | + { "pubkeyplugin", sPubKeyPlugin, SSHCFG_ALL }, |
| | | { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, |
| | | { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, |
| | | { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, |
| | | @@ -2661,6 +2664,18 @@ |
| | | } |
| | | break; |
| | | |
| | | + case sPubKeyPlugin: |
| | | + /* |
| | | + * Can't use parse_filename, as we need to support plain |
| | | + * names which dlopen will find on our lib path. |
| | | + */ |
| | | + arg = strdelim(&str); |
| | | + if (!arg || *arg == '\0') |
| | | + fatal("%s line %d: missing file name.", |
| | | + filename, linenum); |
| | | + options->pubkey_plugin = xstrdup(arg); |
| | | + break; |
| | | + |
| | | case sDeprecated: |
| | | case sIgnore: |
| | | case sUnsupported: |
| | | --- hpn-ssh-hpn-18.3.1/servconf.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.h |
| | | @@ -240,6 +240,7 @@ |
| | | |
| | | int fingerprint_hash; |
| | | int expose_userauth_info; |
| | | + char *pubkey_plugin; |
| | | u_int64_t timing_secret; |
| | | char *sk_provider; |
| | | int required_rsa_size; /* minimum size of RSA keys */ |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/pathnames.h.orig |
| | | +++ hpn-ssh-hpn-18.3.1/pathnames.h |
| | | @@ -42,6 +42,7 @@ |
| | | #define _PATH_HOST_XMSS_KEY_FILE SSHDIR "/ssh_host_xmss_key" |
| | | #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" |
| | | #define _PATH_DH_MODULI SSHDIR "/moduli" |
| | | +#define _PATH_DEFAULT_LOGIN ETCDIR "/default/login" |
| | | |
| | | #ifndef _PATH_SSH_PROGRAM |
| | | #define _PATH_SSH_PROGRAM "/usr/bin/hpnssh" |
| | | --- hpn-ssh-hpn-18.3.1/servconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.c |
| | | @@ -36,6 +36,7 @@ |
| | | #include <unistd.h> |
| | | #include <limits.h> |
| | | #include <stdarg.h> |
| | | +#include <deflt.h> |
| | | #include <errno.h> |
| | | #ifdef HAVE_UTIL_H |
| | | #include <util.h> |
| | | @@ -225,6 +226,64 @@ |
| | | return o == NULL || strcasecmp(o, "none") == 0; |
| | | } |
| | | |
| | | +/* |
| | | + * Reads /etc/default/login and defaults several ServerOptions: |
| | | + * |
| | | + * PermitRootLogin |
| | | + * PermitEmptyPasswords |
| | | + * LoginGraceTime |
| | | + * |
| | | + * CONSOLE=* -> PermitRootLogin=without-password |
| | | + * #CONSOLE=* -> PermitRootLogin=yes |
| | | + * |
| | | + * PASSREQ=YES -> PermitEmptyPasswords=no |
| | | + * PASSREQ=NO -> PermitEmptyPasswords=yes |
| | | + * #PASSREQ=* -> PermitEmptyPasswords=no |
| | | + * |
| | | + * TIMEOUT=<secs> -> LoginGraceTime=<secs> |
| | | + * #TIMEOUT=<secs> -> LoginGraceTime=300 |
| | | + */ |
| | | +static void |
| | | +deflt_fill_default_server_options(ServerOptions *options) |
| | | +{ |
| | | + int flags; |
| | | + char *ptr; |
| | | + |
| | | + if (defopen(_PATH_DEFAULT_LOGIN)) |
| | | + return; |
| | | + |
| | | + /* Ignore case */ |
| | | + flags = defcntl(DC_GETFLAGS, 0); |
| | | + TURNOFF(flags, DC_CASE); |
| | | + (void) defcntl(DC_SETFLAGS, flags); |
| | | + |
| | | + if (options->permit_root_login == PERMIT_NOT_SET && |
| | | + (ptr = defread("CONSOLE=")) != NULL) |
| | | + options->permit_root_login = PERMIT_NO_PASSWD; |
| | | + |
| | | + if (options->permit_empty_passwd == -1 && |
| | | + (ptr = defread("PASSREQ=")) != NULL) { |
| | | + if (strcasecmp("YES", ptr) == 0) |
| | | + options->permit_empty_passwd = 0; |
| | | + else if (strcasecmp("NO", ptr) == 0) |
| | | + options->permit_empty_passwd = 1; |
| | | + } |
| | | + |
| | | + if (options->max_authtries == -1 && |
| | | + (ptr = defread("RETRIES=")) != NULL) { |
| | | + options->max_authtries = atoi(ptr); |
| | | + } |
| | | + |
| | | + if (options->login_grace_time == -1) { |
| | | + if ((ptr = defread("TIMEOUT=")) != NULL) |
| | | + options->login_grace_time = (unsigned)atoi(ptr); |
| | | + else |
| | | + options->login_grace_time = 300; |
| | | + } |
| | | + |
| | | + (void) defopen((char *)NULL); |
| | | +} |
| | | + |
| | | static void |
| | | assemble_algorithms(ServerOptions *o) |
| | | { |
| | | @@ -305,6 +364,8 @@ |
| | | options->use_pam = 0; |
| | | #endif |
| | | |
| | | + deflt_fill_default_server_options(options); |
| | | + |
| | | /* Standard Options */ |
| | | if (options->num_host_key_files == 0) { |
| | | /* fill default hostkeys for protocols */ |
| | | --- hpn-ssh-hpn-18.3.1/hpnsshd_config.5.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsshd_config.5 |
| | | @@ -1350,7 +1350,14 @@ |
| | | connection. |
| | | Once the number of failures reaches half this value, |
| | | additional failures are logged. |
| | | -The default is 6. |
| | | +The default is 6, or the value given by |
| | | +.Dq RETRIES= |
| | | +in the file |
| | | +.Pa /etc/default/login , |
| | | +if available |
| | | +.Po see |
| | | +.Xr login 1 |
| | | +.Pc . |
| | | .It Cm MaxSessions |
| | | Specifies the maximum number of open shell, login or subsystem (e.g. sftp) |
| | | sessions permitted per network connection. |
| | | @@ -1438,7 +1445,14 @@ |
| | | When password authentication is allowed, it specifies whether the |
| | | server allows login to accounts with empty password strings. |
| | | The default is |
| | | -.Cm no . |
| | | +.Cm no |
| | | +unless |
| | | +.Dq PASSREQ=YES |
| | | +is present in |
| | | +.Pa /etc/default/login |
| | | +.Po see |
| | | +.Xr login 1 |
| | | +.Pc . |
| | | .It Cm PermitListen |
| | | Specifies the addresses/ports on which a remote TCP port forwarding may listen. |
| | | The listen specification must be one of the following forms: |
New file |
| | |
| | | We use the kex compat mechanism here to recognise old SunSSH |
| | | versions and present a kex proposal that always includes the |
| | | dh-group14 and -group1 algorithms. |
| | | |
| | | Without this, an old SunSSH client cannot connect to our |
| | | new daemon. |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/compat.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/compat.c |
| | | @@ -36,6 +36,7 @@ |
| | | #include "compat.h" |
| | | #include "log.h" |
| | | #include "match.h" |
| | | +#include "sshbuf.h" |
| | | |
| | | /* determine bug flags from SSH protocol banner */ |
| | | void |
| | | @@ -51,8 +52,12 @@ |
| | | "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR| |
| | | SSH_BUG_SIGTYPE}, |
| | | { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR|SSH_BUG_SIGTYPE }, |
| | | - { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| |
| | | - SSH_BUG_SIGTYPE}, |
| | | + { "Sun_SSH_1.2*," |
| | | + "Sun_SSH_1.3*," |
| | | + "Sun_SSH_1.4*," |
| | | + "Sun_SSH_1.5*", SSH_OLD_DHGEX}, |
| | | + { "Sun_SSH_1.*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| |
| | | + SSH_BUG_SIGTYPE|SSH_OLD_DHGEX}, |
| | | { "OpenSSH_2*," |
| | | "OpenSSH_3*," |
| | | "OpenSSH_4*", SSH_BUG_SIGTYPE }, |
| | | @@ -167,6 +172,31 @@ |
| | | debug_f("no match: %s", version); |
| | | } |
| | | |
| | | +/* |
| | | + * Adds an algorithm to the end of a proposal list, only if the algorithm is |
| | | + * not already present. |
| | | + */ |
| | | +static char * |
| | | +append_proposal(char *proposal, const char *append) |
| | | +{ |
| | | + struct sshbuf *b; |
| | | + char *fix_prop; |
| | | + |
| | | + if (strstr(proposal, append) != NULL) |
| | | + return proposal; |
| | | + if ((b = sshbuf_new()) == NULL) |
| | | + fatal("sshbuf_new()"); |
| | | + sshbuf_put(b, proposal, strlen(proposal)); |
| | | + if (sshbuf_len(b) > 0) |
| | | + sshbuf_put(b, ",", 1); |
| | | + sshbuf_put(b, append, strlen(append)); |
| | | + sshbuf_put(b, "\0", 1); |
| | | + fix_prop = sshbuf_dup_string(b); |
| | | + sshbuf_free(b); |
| | | + |
| | | + return fix_prop; |
| | | +} |
| | | + |
| | | /* Always returns pointer to allocated memory, caller must free. */ |
| | | char * |
| | | compat_kex_proposal(struct ssh *ssh, const char *p) |
| | | @@ -185,6 +215,8 @@ |
| | | "diffie-hellman-group-exchange-sha256," |
| | | "diffie-hellman-group-exchange-sha1")) == NULL) |
| | | fatal("match_filter_denylist failed"); |
| | | + p = append_proposal(p, "diffie-hellman-group14-sha1"); |
| | | + p = append_proposal(p, "diffie-hellman-group1-sha1"); |
| | | free(cp); |
| | | cp = cp2; |
| | | } |
New file |
| | |
| | | This preserves most of the old SunSSH locale negotiation |
| | | behaviour (at least the parts that are most commonly used). |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/servconf.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/servconf.c |
| | | @@ -174,7 +174,7 @@ |
| | | options->client_alive_interval = -1; |
| | | options->client_alive_count_max = -1; |
| | | options->num_authkeys_files = 0; |
| | | - options->num_accept_env = 0; |
| | | + options->num_accept_env = -1; |
| | | options->num_setenv = 0; |
| | | options->permit_tun = -1; |
| | | options->permitted_opens = NULL; |
| | | @@ -494,6 +494,33 @@ |
| | | options->max_sessions = DEFAULT_SESSIONS_MAX; |
| | | if (options->use_dns == -1) |
| | | options->use_dns = 0; |
| | | + if (options->num_accept_env == -1) { |
| | | + options->num_accept_env = 0; |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LANG"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_ALL"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_CTYPE"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_COLLATE"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_TIME"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_NUMERIC"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_MONETARY"); |
| | | + opt_array_append("[default]", 0, "AcceptEnv", |
| | | + &options->accept_env, &options->num_accept_env, |
| | | + "LC_MESSAGES"); |
| | | + } |
| | | if (options->client_alive_interval == -1) |
| | | options->client_alive_interval = 0; |
| | | if (options->client_alive_count_max == -1) |
| | | @@ -2233,8 +2260,12 @@ |
| | | if (*arg == '\0' || strchr(arg, '=') != NULL) |
| | | fatal("%s line %d: Invalid environment name.", |
| | | filename, linenum); |
| | | + if (options->num_accept_env == -1) |
| | | + options->num_accept_env = 0; |
| | | if (!*activep) |
| | | continue; |
| | | + if (strcmp(arg, "none") == 0) |
| | | + continue; |
| | | opt_array_append(filename, linenum, keyword, |
| | | &options->accept_env, &options->num_accept_env, |
| | | arg); |
| | | @@ -2971,7 +3002,7 @@ |
| | | } while(0) |
| | | #define M_CP_STRARRAYOPT(s, num_s) do {\ |
| | | u_int i; \ |
| | | - if (src->num_s != 0) { \ |
| | | + if (src->num_s != 0 && src->num_s != -1) { \ |
| | | for (i = 0; i < dst->num_s; i++) \ |
| | | free(dst->s[i]); \ |
| | | free(dst->s); \ |
| | | --- hpn-ssh-hpn-18.3.1/session.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/session.c |
| | | @@ -848,6 +848,18 @@ |
| | | } |
| | | |
| | | /* |
| | | + * If the given environment variable is set in the daemon's environment, |
| | | + * push it into the new child as well. If it is unset, do nothing. |
| | | + */ |
| | | +static void |
| | | +child_inherit_env(char ***envp, u_int *envsizep, const char *name) |
| | | +{ |
| | | + char *value; |
| | | + if ((value = getenv(name)) != NULL) |
| | | + child_set_env(envp, envsizep, name, value); |
| | | +} |
| | | + |
| | | +/* |
| | | * Reads environment variables from the given file and adds/overrides them |
| | | * into the environment. If the file does not exist, this does nothing. |
| | | * Otherwise, it must consist of empty lines, comments (line starts with '#') |
| | | @@ -1031,6 +1043,16 @@ |
| | | ssh_gssapi_do_child(&env, &envsize); |
| | | #endif |
| | | |
| | | + /* Default to the system-wide locale/language settings. */ |
| | | + child_inherit_env(&env, &envsize, "LANG"); |
| | | + child_inherit_env(&env, &envsize, "LC_ALL"); |
| | | + child_inherit_env(&env, &envsize, "LC_CTYPE"); |
| | | + child_inherit_env(&env, &envsize, "LC_COLLATE"); |
| | | + child_inherit_env(&env, &envsize, "LC_TIME"); |
| | | + child_inherit_env(&env, &envsize, "LC_NUMERIC"); |
| | | + child_inherit_env(&env, &envsize, "LC_MONETARY"); |
| | | + child_inherit_env(&env, &envsize, "LC_MESSAGES"); |
| | | + |
| | | /* Set basic environment. */ |
| | | for (i = 0; i < s->num_env; i++) |
| | | child_set_env(&env, &envsize, s->env[i].name, s->env[i].val); |
| | | @@ -1074,8 +1096,7 @@ |
| | | /* Normal systems set SHELL by default. */ |
| | | child_set_env(&env, &envsize, "SHELL", shell); |
| | | |
| | | - if (getenv("TZ")) |
| | | - child_set_env(&env, &envsize, "TZ", getenv("TZ")); |
| | | + child_inherit_env(&env, &envsize, "TZ"); |
| | | if (s->term) |
| | | child_set_env(&env, &envsize, "TERM", s->term); |
| | | if (s->display) |
| | | --- hpn-ssh-hpn-18.3.1/sshd_config.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshd_config |
| | | @@ -26,6 +26,10 @@ |
| | | #SyslogFacility AUTH |
| | | #LogLevel INFO |
| | | |
| | | +# Use the client's locale/language settings |
| | | +#AcceptEnv LANG LC_ALL LC_CTYPE LC_COLLATE LC_TIME LC_NUMERIC |
| | | +#AcceptEnv LC_MONETARY LC_MESSAGES |
| | | + |
| | | # Authentication: |
| | | |
| | | #LoginGraceTime 2m |
| | | --- hpn-ssh-hpn-18.3.1/hpnsshd_config.5.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsshd_config.5 |
| | | @@ -96,7 +96,20 @@ |
| | | Be warned that some environment variables could be used to bypass restricted |
| | | user environments. |
| | | For this reason, care should be taken in the use of this directive. |
| | | -The default is not to accept any environment variables. |
| | | +The default is to accept only |
| | | +.Ev LANG |
| | | +and the |
| | | +.Ev LC_* |
| | | +family of environment variables. If any |
| | | +.Cm AcceptEnv |
| | | +directives are present in your config file, they will replace this default |
| | | +.Po |
| | | +ie, only the variables you list will be passed into the session's |
| | | +.Xr environ 7 |
| | | +.Pc . |
| | | +You can also use an argument of |
| | | +.Dq none |
| | | +to specify that no environment variables should be passed. |
| | | .It Cm AddressFamily |
| | | Specifies which address family should be used by |
| | | .Xr sshd 8 . |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/configure.ac.orig |
| | | +++ hpn-ssh-hpn-18.3.1/configure.ac |
| | | @@ -1656,6 +1656,62 @@ |
| | | AC_MSG_RESULT([no]) |
| | | fi |
| | | |
| | | +# 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 <sys/types.h> |
| | | +#include <sys/socket.h> |
| | | +#include <netinet/in.h> |
| | | +#include <tcpd.h> |
| | | +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, |
| | | @@ -5683,6 +5739,7 @@ |
| | | echo " OSF SIA support: $SIA_MSG" |
| | | echo " KerberosV support: $KRB5_MSG" |
| | | echo " SELinux support: $SELINUX_MSG" |
| | | +echo " TCP Wrappers support: $TCPW_MSG" |
| | | echo " libedit support: $LIBEDIT_MSG" |
| | | echo " libldns support: $LDNS_MSG" |
| | | echo " Solaris process contract support: $SPC_MSG" |
| | | --- hpn-ssh-hpn-18.3.1/hpnsshd.8.orig |
| | | +++ hpn-ssh-hpn-18.3.1/hpnsshd.8 |
| | | @@ -924,6 +924,12 @@ |
| | | 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 hpnssh 1 ) . |
| | | @@ -1053,6 +1059,7 @@ |
| | | .Xr hpnssh-keygen 1 , |
| | | .Xr hpnssh-keyscan 1 , |
| | | .Xr chroot 2 , |
| | | +.Xr hosts_access 5 , |
| | | .Xr login.conf 5 , |
| | | .Xr moduli 5 , |
| | | .Xr hpnsshd_config 5 , |
| | | --- hpn-ssh-hpn-18.3.1/sshd.c.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshd.c |
| | | @@ -128,6 +128,17 @@ |
| | | #include "srclimit.h" |
| | | #include "dh.h" |
| | | |
| | | +#ifdef LIBWRAP |
| | | +#include <tcpd.h> |
| | | +#include <syslog.h> |
| | | +int allow_severity; |
| | | +int deny_severity; |
| | | +#endif /* LIBWRAP */ |
| | | + |
| | | +#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) |
| | | @@ -2218,6 +2229,24 @@ |
| | | #ifdef SSH_AUDIT_EVENTS |
| | | audit_connection_from(ssh, 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 (ssh_packet_connection_is_on_socket(ssh)) { |
| | | + 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 */ |
| | | |
| | | rdomain = ssh_packet_rdomain_in(ssh); |
| | | |
New file |
| | |
| | | --- hpn-ssh-hpn-18.3.1/contrib/hpnssh-copy-id.orig |
| | | +++ hpn-ssh-hpn-18.3.1/contrib/hpnssh-copy-id |
| | | @@ -1,4 +1,4 @@ |
| | | -#!/bin/sh |
| | | +#!/bin/bash |
| | | |
| | | # Copyright (c) 1999-2023 Philip Hands <phil@hands.com> |
| | | # 2021 Carlos RodrÃguez Gili <carlos.rodriguez-gili@upc.edu> |
New file |
| | |
| | | sshd_config customizations for OpenIndiana. |
| | | |
| | | --- hpn-ssh-hpn-18.3.1/sshd_config.orig |
| | | +++ hpn-ssh-hpn-18.3.1/sshd_config |
| | | @@ -34,6 +34,7 @@ |
| | | |
| | | #LoginGraceTime 2m |
| | | #PermitRootLogin prohibit-password |
| | | +PermitRootLogin no |
| | | #StrictModes yes |
| | | #MaxAuthTries 6 |
| | | #MaxSessions 10 |
| | | @@ -78,10 +79,15 @@ |
| | | #AllowTcpForwarding yes |
| | | #GatewayPorts no |
| | | #X11Forwarding no |
| | | +X11Forwarding yes |
| | | #X11DisplayOffset 10 |
| | | #X11UseLocalhost yes |
| | | #PermitTTY yes |
| | | + |
| | | #PrintMotd yes |
| | | +# On OpenIndiana it is assumed that the login shell will print /etc/motd |
| | | +PrintMotd no |
| | | + |
| | | #PrintLastLog yes |
| | | #TCPKeepAlive yes |
| | | #PermitUserEnvironment no |
New file |
| | |
| | | { |
| | | "dependencies": [ |
| | | "SUNWcs", |
| | | "library/libedit", |
| | | "library/security/openssl-31", |
| | | "library/zlib", |
| | | "network/ssh-askpass", |
| | | "service/security/kerberos-5", |
| | | "shell/bash", |
| | | "shell/ksh93", |
| | | "system/library", |
| | | "system/library/security/gss", |
| | | "x11/session/xauth" |
| | | ], |
| | | "fmris": [ |
| | | "network/hpn-ssh", |
| | | "service/network/hpn-ssh" |
| | | ], |
| | | "name": "hpn-ssh" |
| | | } |
| | |
| | | 19 | minidlna |
| | | 21 | ftp |
| | | 22 | sshd |
| | | 24 | hpnsshd |
| | | 25 | smmsp |
| | | 27 | postfix |
| | | 30 | opendkim |
| | |
| | | 20 | games |
| | | 21 | ftp |
| | | 22 | sshd |
| | | 24 | hpnsshd |
| | | 25 | smmsp |
| | | 27 | postfix |
| | | 28 | postdrop |