summaryrefslogtreecommitdiffstats
path: root/.github
diff options
context:
space:
mode:
Diffstat (limited to '.github')
-rw-r--r--.github/ci-status.md15
-rwxr-xr-x.github/configs361
-rwxr-xr-x.github/configure.sh21
-rwxr-xr-x.github/run_test.sh48
-rwxr-xr-x.github/setup_ci.sh243
-rw-r--r--.github/workflows/c-cpp.yml132
-rw-r--r--.github/workflows/cifuzz.yml32
-rw-r--r--.github/workflows/selfhosted.yml125
-rw-r--r--.github/workflows/upstream.yml53
9 files changed, 1030 insertions, 0 deletions
diff --git a/.github/ci-status.md b/.github/ci-status.md
new file mode 100644
index 0000000..8d4cea1
--- /dev/null
+++ b/.github/ci-status.md
@@ -0,0 +1,15 @@
+master :
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:master)
+[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:master)
+[![Upstream self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml/badge.svg)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/upstream.yml?query=branch:master)
+[![CIFuzz](https://github.com/openssh/openssh-portable/actions/workflows/cifuzz.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/cifuzz.yml)
+[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
+[![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable)
+
+9.4 :
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_4)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_4)
+[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_4)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_4)
+
+9.3 :
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_3)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_3)
+[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_3)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_3)
diff --git a/.github/configs b/.github/configs
new file mode 100755
index 0000000..df82faf
--- /dev/null
+++ b/.github/configs
@@ -0,0 +1,361 @@
+#!/bin/sh
+#
+# usage: configs vmname test_config (or '' for default)
+#
+# Sets the following variables:
+# CONFIGFLAGS options to ./configure
+# SSHD_CONFOPTS sshd_config options
+# TEST_TARGET make target used when testing. defaults to "tests".
+# LTESTS
+
+config=$1
+if [ "$config" = "" ]; then
+ config="default"
+fi
+
+unset CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO
+
+TEST_TARGET="tests compat-tests"
+LTESTS=""
+SKIP_LTESTS=""
+SUDO=sudo # run with sudo by default
+TEST_SSH_UNSAFE_PERMISSIONS=1
+# Stop on first test failure to minimize logs
+TEST_SSH_FAIL_FATAL=yes
+
+CONFIGFLAGS=""
+LIBCRYPTOFLAGS=""
+
+case "$config" in
+ default|sol64)
+ ;;
+ c89)
+ # If we don't have LLONG_MAX, configure will figure out that it can
+ # get it by setting -std=gnu99, at which point we won't be testing
+ # C89 any more. To avoid this, feed it in via CFLAGS.
+ llong_max=`gcc -E -dM - </dev/null | \
+ awk '$2=="__LONG_LONG_MAX__"{print $3}'`
+ CPPFLAGS="-DLLONG_MAX=${llong_max}"
+
+ CC="gcc"
+ CFLAGS="-Wall -std=c89 -pedantic -Werror=vla"
+ CONFIGFLAGS="--without-zlib"
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET=t-exec
+ ;;
+ cygwin-release)
+ # See https://cygwin.com/git/?p=git/cygwin-packages/openssh.git;a=blob;f=openssh.cygport;hb=HEAD
+ CONFIGFLAGS="--with-xauth=/usr/bin/xauth --with-security-key-builtin"
+ CONFIGFLAGS="$CONFIGFLAGS --with-kerberos5=/usr --with-libedit --disable-strip"
+ ;;
+ clang-12-Werror)
+ CC="clang-12"
+ # clang's implicit-fallthrough requires that the code be annotated with
+ # __attribute__((fallthrough)) and does not understand /* FALLTHROUGH */
+ CFLAGS="-Wall -Wextra -O2 -Wno-error=implicit-fallthrough -Wno-error=unused-parameter"
+ CONFIGFLAGS="--with-pam --with-Werror"
+ ;;
+ *-sanitize-*)
+ case "$config" in
+ gcc-*)
+ CC=gcc
+ ;;
+ clang-*)
+ # Find the newest available version of clang
+ for i in `seq 10 99`; do
+ clang="`which clang-$i 2>/dev/null`"
+ [ -x "$clang" ] && CC="$clang"
+ done
+ ;;
+ esac
+ # Put Sanitizer logs in regress dir.
+ SANLOGS=`pwd`/regress
+ # - We replace chroot with chdir so that the sanitizer in the preauth
+ # privsep process can read /proc.
+ # - clang does not recognizes explicit_bzero so we use bzero
+ # (see https://github.com/google/sanitizers/issues/1507
+ # - openssl and zlib trip ASAN.
+ # - sp_pwdp returned by getspnam trips ASAN, hence disabling shadow.
+ case "$config" in
+ *-sanitize-address)
+ CFLAGS="-fsanitize=address -fno-omit-frame-pointer"
+ LDFLAGS="-fsanitize=address"
+ CPPFLAGS='-Dchroot=chdir -Dexplicit_bzero=bzero -D_FORTIFY_SOURCE=0 -DASAN_OPTIONS=\"detect_leaks=0:log_path='$SANLOGS'/asan.log\"'
+ CONFIGFLAGS=""
+ TEST_TARGET="t-exec"
+ ;;
+ clang-sanitize-memory)
+ CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer"
+ LDFLAGS="-fsanitize=memory"
+ CPPFLAGS='-Dchroot=chdir -Dexplicit_bzero=bzero -DMSAN_OPTIONS=\"log_path='$SANLOGS'/msan.log\"'
+ CONFIGFLAGS="--without-zlib --without-shadow"
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET="t-exec"
+ ;;
+ *-sanitize-undefined)
+ CFLAGS="-fsanitize=undefined"
+ LDFLAGS="-fsanitize=undefined"
+ ;;
+ *)
+ echo unknown sanitize option;
+ exit 1;;
+ esac
+ features="--disable-security-key --disable-pkcs11"
+ hardening="--without-sandbox --without-hardening --without-stackprotect"
+ privsep="--with-privsep-user=root"
+ CONFIGFLAGS="$CONFIGFLAGS $features $hardening $privsep"
+ # Because we hobble chroot we can't test it.
+ SKIP_LTESTS=sftp-chroot
+ ;;
+ gcc-11-Werror)
+ CC="gcc-11"
+ # -Wnoformat-truncation in gcc 7.3.1 20180130 fails on fmt_scaled
+ # -Wunused-result ignores (void) so is not useful. See
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425
+ CFLAGS="-O2 -Wno-format-truncation -Wimplicit-fallthrough=4 -Wno-unused-parameter -Wno-unused-result"
+ CONFIGFLAGS="--with-pam --with-Werror"
+ ;;
+ gcc-12-Werror)
+ CC="gcc-12"
+ # -Wnoformat-truncation in gcc 7.3.1 20180130 fails on fmt_scaled
+ # -Wunused-result ignores (void) so is not useful. See
+ # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425
+ CFLAGS="-O2 -Wno-format-truncation -Wimplicit-fallthrough=4 -Wno-unused-parameter -Wno-unused-result"
+ CONFIGFLAGS="--with-pam --with-Werror"
+ ;;
+ clang*|gcc*)
+ CC="$config"
+ ;;
+ kitchensink)
+ CONFIGFLAGS="--with-kerberos5 --with-libedit --with-pam"
+ CONFIGFLAGS="${CONFIGFLAGS} --with-security-key-builtin --with-selinux"
+ CFLAGS="-DSK_DEBUG -DSANDBOX_SECCOMP_FILTER_DEBUG"
+ ;;
+ hardenedmalloc)
+ CONFIGFLAGS="--with-ldflags=-lhardened_malloc"
+ ;;
+ tcmalloc)
+ CONFIGFLAGS="--with-ldflags=-ltcmalloc"
+ ;;
+ krb5|heimdal)
+ CONFIGFLAGS="--with-kerberos5"
+ ;;
+ libedit)
+ CONFIGFLAGS="--with-libedit"
+ ;;
+ musl)
+ CC="musl-gcc"
+ CONFIGFLAGS="--without-zlib"
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET="t-exec"
+ ;;
+ pam-krb5)
+ CONFIGFLAGS="--with-pam --with-kerberos5"
+ SSHD_CONFOPTS="UsePam yes"
+ ;;
+ *pam)
+ CONFIGFLAGS="--with-pam"
+ SSHD_CONFOPTS="UsePam yes"
+ ;;
+ boringssl)
+ CONFIGFLAGS="--disable-pkcs11"
+ LIBCRYPTOFLAGS="--with-ssl-dir=/opt/boringssl --with-rpath=-Wl,-rpath,"
+ ;;
+ libressl-*)
+ LIBCRYPTOFLAGS="--with-ssl-dir=/opt/libressl --with-rpath=-Wl,-rpath,"
+ ;;
+ openssl-*)
+ LIBCRYPTOFLAGS="--with-ssl-dir=/opt/openssl --with-rpath=-Wl,-rpath,"
+ # OpenSSL 1.1.1 specifically has a bug in its RNG that breaks reexec
+ # fallback. See https://bugzilla.mindrot.org/show_bug.cgi?id=3483
+ if [ "$config" = "openssl-1.1.1" ]; then
+ SKIP_LTESTS="reexec"
+ fi
+ ;;
+ selinux)
+ CONFIGFLAGS="--with-selinux"
+ ;;
+ sk)
+ CONFIGFLAGS="--with-security-key-builtin"
+ ;;
+ without-openssl)
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET=t-exec
+ ;;
+ valgrind-[1-5]|valgrind-unit)
+ # rlimit sandbox and FORTIFY_SOURCE confuse Valgrind.
+ CONFIGFLAGS="--without-sandbox --without-hardening"
+ CONFIGFLAGS="$CONFIGFLAGS --with-cppflags=-D_FORTIFY_SOURCE=0"
+ TEST_TARGET="t-exec USE_VALGRIND=1"
+ TEST_SSH_ELAPSED_TIMES=1
+ export TEST_SSH_ELAPSED_TIMES
+ # Valgrind slows things down enough that the agent timeout test
+ # won't reliably pass, and the unit tests run longer than allowed
+ # by github so split into separate tests.
+ tests2="integrity try-ciphers"
+ tests3="krl forward-control sshsig agent-restrict kextype sftp"
+ tests4="cert-userkey cert-hostkey kextype sftp-perm keygen-comment percent"
+ tests5="rekey"
+ case "$config" in
+ valgrind-1)
+ # All tests except agent-timeout (which is flaky under valgrind),
+ # connection-timeout (which doesn't work since it's so slow)
+ # and hostbased (since valgrind won't let ssh exec keysign).
+ # Slow ones are run separately to increase parallelism.
+ SKIP_LTESTS="agent-timeout connection-timeout hostbased"
+ SKIP_LTESTS="$SKIP_LTESTS ${tests2} ${tests3} ${tests4} ${tests5}"
+ ;;
+ valgrind-2)
+ LTESTS="${tests2}"
+ ;;
+ valgrind-3)
+ LTESTS="${tests3}"
+ ;;
+ valgrind-4)
+ LTESTS="${tests4}"
+ ;;
+ valgrind-5)
+ LTESTS="${tests5}"
+ ;;
+ valgrind-unit)
+ TEST_TARGET="unit USE_VALGRIND=1"
+ ;;
+ esac
+ ;;
+ zlib-develop)
+ INSTALL_ZLIB=develop
+ CONFIGFLAGS="--with-zlib=/opt/zlib --with-rpath=-Wl,-rpath,"
+ ;;
+ *)
+ echo "Unknown configuration $config"
+ exit 1
+ ;;
+esac
+
+# The Solaris 64bit targets are special since they need a non-flag arg.
+case "$config" in
+ sol64*)
+ CONFIGFLAGS="--target=x86_64 --with-cflags=-m64 --with-ldflags=-m64 ${CONFIGFLAGS}"
+ LIBCRYPTOFLAGS="--with-ssl-dir=/usr/local/ssl64 --with-rpath=-Wl,-rpath,"
+ ;;
+esac
+
+case "${TARGET_HOST}" in
+ aix*)
+ CONFIGFLAGS="--disable-security-key"
+ LIBCRYPTOFLAGS="--without-openssl"
+ # These are slow real or virtual machines so skip the slowest tests
+ # (which tend to be thw ones that transfer lots of data) so that the
+ # test run does not time out.
+ # The agent-restrict test fails due to some quoting issue when run
+ # with sh or ksh so specify bash for now.
+ TEST_TARGET="t-exec unit TEST_SHELL=bash"
+ SKIP_LTESTS="rekey sftp"
+ ;;
+ debian-riscv64)
+ # This machine is fairly slow, so skip the unit tests.
+ TEST_TARGET="t-exec"
+ ;;
+ dfly58*|dfly60*)
+ # scp 3-way connection hangs on these so skip until sorted.
+ SKIP_LTESTS=scp3
+ ;;
+ fbsd6)
+ # Native linker is not great with PIC so OpenSSL is built w/out.
+ CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key"
+ ;;
+ hurd)
+ SKIP_LTESTS="forwarding multiplex proxy-connect hostkey-agent agent-ptrace"
+ ;;
+ minix3)
+ CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key"
+ LIBCRYPTOFLAGS="--without-openssl"
+ # Minix does not have a loopback interface so we have to skip any
+ # test that relies on one.
+ # Also, Minix seems to be very limited in the number of select()
+ # calls that can be operating concurrently, so prune additional tests for that.
+ T="addrmatch agent-restrict brokenkeys cfgmatch cfgmatchlisten cfgparse
+ connect connect-uri exit-status forwarding hostkey-agent
+ key-options keyscan knownhosts-command login-timeout
+ reconfigure reexec rekey scp scp-uri scp3 sftp sftp-badcmds
+ sftp-batch sftp-cmds sftp-glob sftp-perm sftp-uri stderr-data
+ transfer"
+ # Unix domain sockets don't work quite like we expect, so also skip any tests
+ # that use multiplexing.
+ T="$T connection-timeout dynamic-forward forward-control multiplex"
+ SKIP_LTESTS="$(echo $T)"
+ TEST_TARGET=t-exec
+ SUDO=""
+ ;;
+ nbsd4)
+ # System compiler will ICE on some files with fstack-protector
+ # SHA256 functions in sha2.h conflict with OpenSSL's breaking sk-dummy
+ CONFIGFLAGS="${CONFIGFLAGS} --without-hardening --disable-security-key"
+ ;;
+ openwrt-*)
+ CONFIGFLAGS="${CONFIGFLAGS} --without-zlib"
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET="t-exec"
+ ;;
+ sol10|sol11)
+ # sol10 VM is 32bit and the unit tests are slow.
+ # sol11 has 4 test configs so skip unit tests to speed up.
+ TEST_TARGET="tests SKIP_UNIT=1"
+ ;;
+ win10)
+ # No sudo on Windows.
+ SUDO=""
+ ;;
+esac
+
+host=`./config.guess`
+case "$host" in
+*cygwin)
+ SUDO=""
+ # Don't run compat tests on cygwin as they don't currently compile.
+ TEST_TARGET="tests"
+ ;;
+*-darwin*)
+ # Unless specified otherwise, build without OpenSSL on Mac OS since
+ # modern versions don't ship with libcrypto.
+ LIBCRYPTOFLAGS="--without-openssl"
+ TEST_TARGET=t-exec
+ case "$host" in
+ *-darwin22.*)
+ # sudo -S nobody doesn't work on macos 13 for some reason.
+ SKIP_LTESTS="agent-getpeereid" ;;
+ esac
+ ;;
+esac
+
+# Unless specifically configured, search for a suitable version of OpenSSL,
+# otherwise build without it.
+if [ -z "${LIBCRYPTOFLAGS}" ]; then
+ LIBCRYPTOFLAGS="--without-openssl"
+ # last-match
+ for i in /usr /usr/local /usr/local/ssl /usr/local/opt/openssl; do
+ ver="none"
+ if [ -x ${i}/bin/openssl ]; then
+ ver="$(${i}/bin/openssl version)"
+ fi
+ case "$ver" in
+ none) ;;
+ "OpenSSL 0."*|"OpenSSL 1.0."*|"OpenSSL 1.1.0"*) ;;
+ "LibreSSL 2."*|"LibreSSL 3.0."*) ;;
+ *) LIBCRYPTOFLAGS="--with-ssl-dir=${i}" ;;
+ esac
+ done
+ if [ "${LIBCRYPTOFLAGS}" = "--without-openssl" ]; then
+ TEST_TARGET="t-exec"
+ fi
+fi
+
+CONFIGFLAGS="${CONFIGFLAGS} ${LIBCRYPTOFLAGS}"
+
+if [ -x "$(which plink 2>/dev/null)" ]; then
+ REGRESS_INTEROP_PUTTY=yes
+ export REGRESS_INTEROP_PUTTY
+fi
+
+export CC CFLAGS CPPFLAGS LDFLAGS LTESTS SUDO
+export TEST_TARGET TEST_SSH_UNSAFE_PERMISSIONS TEST_SSH_FAIL_FATAL
diff --git a/.github/configure.sh b/.github/configure.sh
new file mode 100755
index 0000000..bd00377
--- /dev/null
+++ b/.github/configure.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+. .github/configs $1
+
+printf "$ "
+
+if [ "x$CC" != "x" ]; then
+ printf "CC='$CC' "
+fi
+if [ "x$CFLAGS" != "x" ]; then
+ printf "CFLAGS='$CFLAGS' "
+fi
+if [ "x$CPPFLAGS" != "x" ]; then
+ printf "CPPFLAGS='$CPPFLAGS' "
+fi
+if [ "x$LDFLAGS" != "x" ]; then
+ printf "LDFLAGS='$LDFLAGS' "
+fi
+
+echo ./configure ${CONFIGFLAGS}
+./configure ${CONFIGFLAGS} 2>&1
diff --git a/.github/run_test.sh b/.github/run_test.sh
new file mode 100755
index 0000000..d5fd487
--- /dev/null
+++ b/.github/run_test.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+. .github/configs $1
+
+[ -z "${SUDO}" ] || ${SUDO} mkdir -p /var/empty
+
+set -ex
+
+# If we want to test hostbased auth, set up the host for it.
+if [ ! -z "$SUDO" ] && [ ! -z "$TEST_SSH_HOSTBASED_AUTH" ]; then
+ sshconf=/usr/local/etc
+ hostname | $SUDO tee $sshconf/shosts.equiv >/dev/null
+ echo "EnableSSHKeysign yes" | $SUDO tee $sshconf/ssh_config >/dev/null
+ $SUDO mkdir -p $sshconf
+ $SUDO cp -p /etc/ssh/ssh_host*key* $sshconf
+ $SUDO make install
+ for key in $sshconf/ssh_host*key*.pub; do
+ echo `hostname` `cat $key` | \
+ $SUDO tee -a $sshconf/ssh_known_hosts >/dev/null
+ done
+fi
+
+output_failed_logs() {
+ for i in regress/failed*.log; do
+ if [ -f "$i" ]; then
+ echo -------------------------------------------------------------------------
+ echo LOGFILE $i
+ cat $i
+ echo -------------------------------------------------------------------------
+ fi
+ done
+}
+trap output_failed_logs 0
+
+if [ -z "${LTESTS}" ]; then
+ make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}"
+else
+ make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}"
+fi
+
+if [ ! -z "${SSHD_CONFOPTS}" ]; then
+ echo "rerunning t-exec with TEST_SSH_SSHD_CONFOPTS='${SSHD_CONFOPTS}'"
+ if [ -z "${LTESTS}" ]; then
+ make t-exec SKIP_LTESTS="${SKIP_LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}"
+ else
+ make t-exec SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}"
+ fi
+fi
diff --git a/.github/setup_ci.sh b/.github/setup_ci.sh
new file mode 100755
index 0000000..d0ba7b4
--- /dev/null
+++ b/.github/setup_ci.sh
@@ -0,0 +1,243 @@
+#!/bin/sh
+
+PACKAGES=""
+
+ . .github/configs $@
+
+host=`./config.guess`
+echo "config.guess: $host"
+case "$host" in
+*cygwin)
+ PACKAGER=setup
+ echo Setting CYGWIN system environment variable.
+ setx CYGWIN "binmode"
+ echo Removing extended ACLs so umask works as expected.
+ setfacl -b . regress
+ PACKAGES="$PACKAGES,autoconf,automake,cygwin-devel,gcc-core"
+ PACKAGES="$PACKAGES,make,openssl-devel,zlib-devel"
+ ;;
+*-darwin*)
+ PACKAGER=brew
+ PACKAGES="automake"
+ ;;
+*)
+ PACKAGER=apt
+esac
+
+TARGETS=$@
+
+INSTALL_FIDO_PPA="no"
+export DEBIAN_FRONTEND=noninteractive
+
+set -e
+
+if [ -x "`which lsb_release 2>&1`" ]; then
+ lsb_release -a
+fi
+
+if [ ! -z "$SUDO" ]; then
+ # Ubuntu 22.04 defaults to private home dirs which prevent the
+ # agent-getpeerid test from running ssh-add as nobody. See
+ # https://github.com/actions/runner-images/issues/6106
+ if ! "$SUDO" -u nobody test -x ~; then
+ echo ~ is not executable by nobody, adding perms.
+ chmod go+x ~
+ fi
+ # Some of the Mac OS X runners don't have a nopasswd sudo rule. Regular
+ # sudo still works, but sudo -u doesn't. Restore the sudo rule.
+ if ! "$SUDO" grep -E 'runner.*NOPASSWD' /etc/passwd >/dev/null; then
+ echo "Restoring runner nopasswd rule to sudoers."
+ echo 'runner ALL=(ALL) NOPASSWD: ALL' |$SUDO tee -a /etc/sudoers
+ fi
+ if ! "$SUDO" -u nobody -S test -x ~ </dev/null; then
+ echo "Still can't sudo to nobody."
+ exit 1
+ fi
+fi
+
+if [ "${TARGETS}" = "kitchensink" ]; then
+ TARGETS="krb5 libedit pam sk selinux"
+fi
+
+for flag in $CONFIGFLAGS; do
+ case "$flag" in
+ --with-pam) TARGETS="${TARGETS} pam" ;;
+ --with-libedit) TARGETS="${TARGETS} libedit" ;;
+ esac
+done
+
+echo "Setting up for '$TARGETS'"
+for TARGET in $TARGETS; do
+ case $TARGET in
+ default|without-openssl|without-zlib|c89)
+ # nothing to do
+ ;;
+ clang-sanitize*)
+ PACKAGES="$PACKAGES clang-12"
+ ;;
+ cygwin-release)
+ PACKAGES="$PACKAGES libcrypt-devel libfido2-devel libkrb5-devel"
+ ;;
+ gcc-sanitize*)
+ ;;
+ clang-*|gcc-*)
+ compiler=$(echo $TARGET | sed 's/-Werror//')
+ PACKAGES="$PACKAGES $compiler"
+ ;;
+ krb5)
+ PACKAGES="$PACKAGES libkrb5-dev"
+ ;;
+ heimdal)
+ PACKAGES="$PACKAGES heimdal-dev"
+ ;;
+ libedit)
+ case "$PACKAGER" in
+ setup) PACKAGES="$PACKAGES libedit-devel" ;;
+ apt) PACKAGES="$PACKAGES libedit-dev" ;;
+ esac
+ ;;
+ *pam)
+ case "$PACKAGER" in
+ apt) PACKAGES="$PACKAGES libpam0g-dev" ;;
+ esac
+ ;;
+ sk)
+ INSTALL_FIDO_PPA="yes"
+ PACKAGES="$PACKAGES libfido2-dev libu2f-host-dev libcbor-dev"
+ ;;
+ selinux)
+ PACKAGES="$PACKAGES libselinux1-dev selinux-policy-dev"
+ ;;
+ hardenedmalloc)
+ INSTALL_HARDENED_MALLOC=yes
+ ;;
+ musl)
+ PACKAGES="$PACKAGES musl-tools"
+ ;;
+ tcmalloc)
+ PACKAGES="$PACKAGES libgoogle-perftools-dev"
+ ;;
+ openssl-noec)
+ INSTALL_OPENSSL=OpenSSL_1_1_1k
+ SSLCONFOPTS="no-ec"
+ ;;
+ openssl-*)
+ INSTALL_OPENSSL=$(echo ${TARGET} | cut -f2 -d-)
+ case ${INSTALL_OPENSSL} in
+ 1.1.1_stable) INSTALL_OPENSSL="OpenSSL_1_1_1-stable" ;;
+ 1.*) INSTALL_OPENSSL="OpenSSL_$(echo ${INSTALL_OPENSSL} | tr . _)" ;;
+ 3.*) INSTALL_OPENSSL="openssl-${INSTALL_OPENSSL}" ;;
+ esac
+ PACKAGES="${PACKAGES} putty-tools dropbear-bin"
+ ;;
+ libressl-*)
+ INSTALL_LIBRESSL=$(echo ${TARGET} | cut -f2 -d-)
+ case ${INSTALL_LIBRESSL} in
+ master) ;;
+ *) INSTALL_LIBRESSL="$(echo ${TARGET} | cut -f2 -d-)" ;;
+ esac
+ PACKAGES="${PACKAGES} putty-tools dropbear-bin"
+ ;;
+ boringssl)
+ INSTALL_BORINGSSL=1
+ PACKAGES="${PACKAGES} cmake ninja-build"
+ ;;
+ valgrind*)
+ PACKAGES="$PACKAGES valgrind"
+ ;;
+ zlib-*)
+ ;;
+ *) echo "Invalid option '${TARGET}'"
+ exit 1
+ ;;
+ esac
+done
+
+if [ "yes" = "$INSTALL_FIDO_PPA" ]; then
+ sudo apt update -qq
+ sudo apt install -qy software-properties-common
+ sudo apt-add-repository -y ppa:yubico/stable
+fi
+
+tries=3
+while [ ! -z "$PACKAGES" ] && [ "$tries" -gt "0" ]; do
+ case "$PACKAGER" in
+ apt)
+ sudo apt update -qq
+ if sudo apt install -qy $PACKAGES; then
+ PACKAGES=""
+ fi
+ ;;
+ brew)
+ if [ ! -z "PACKAGES" ]; then
+ if brew install $PACKAGES; then
+ PACKAGES=""
+ fi
+ fi
+ ;;
+ setup)
+ if /cygdrive/c/setup.exe -q -P `echo "$PACKAGES" | tr ' ' ,`; then
+ PACKAGES=""
+ fi
+ ;;
+ esac
+ if [ ! -z "$PACKAGES" ]; then
+ sleep 90
+ fi
+ tries=$(($tries - 1))
+done
+if [ ! -z "$PACKAGES" ]; then
+ echo "Package installation failed."
+ exit 1
+fi
+
+if [ "${INSTALL_HARDENED_MALLOC}" = "yes" ]; then
+ (cd ${HOME} &&
+ git clone https://github.com/GrapheneOS/hardened_malloc.git &&
+ cd ${HOME}/hardened_malloc &&
+ make && sudo cp out/libhardened_malloc.so /usr/lib/)
+fi
+
+if [ ! -z "${INSTALL_OPENSSL}" ]; then
+ (cd ${HOME} &&
+ git clone https://github.com/openssl/openssl.git &&
+ cd ${HOME}/openssl &&
+ git checkout ${INSTALL_OPENSSL} &&
+ ./config no-threads shared ${SSLCONFOPTS} \
+ --prefix=/opt/openssl &&
+ make && sudo make install_sw)
+fi
+
+if [ ! -z "${INSTALL_LIBRESSL}" ]; then
+ if [ "${INSTALL_LIBRESSL}" = "master" ]; then
+ (mkdir -p ${HOME}/libressl && cd ${HOME}/libressl &&
+ git clone https://github.com/libressl-portable/portable.git &&
+ cd ${HOME}/libressl/portable &&
+ git checkout ${INSTALL_LIBRESSL} &&
+ sh update.sh && sh autogen.sh &&
+ ./configure --prefix=/opt/libressl &&
+ make && sudo make install)
+ else
+ LIBRESSL_URLBASE=https://cdn.openbsd.org/pub/OpenBSD/LibreSSL
+ (cd ${HOME} &&
+ wget ${LIBRESSL_URLBASE}/libressl-${INSTALL_LIBRESSL}.tar.gz &&
+ tar xfz libressl-${INSTALL_LIBRESSL}.tar.gz &&
+ cd libressl-${INSTALL_LIBRESSL} &&
+ ./configure --prefix=/opt/libressl && make && sudo make install)
+ fi
+fi
+
+if [ ! -z "${INSTALL_BORINGSSL}" ]; then
+ (cd ${HOME} && git clone https://boringssl.googlesource.com/boringssl &&
+ cd ${HOME}/boringssl && mkdir build && cd build &&
+ cmake -GNinja -DCMAKE_POSITION_INDEPENDENT_CODE=ON .. && ninja &&
+ mkdir -p /opt/boringssl/lib &&
+ cp ${HOME}/boringssl/build/crypto/libcrypto.a /opt/boringssl/lib &&
+ cp -r ${HOME}/boringssl/include /opt/boringssl)
+fi
+
+if [ ! -z "${INSTALL_ZLIB}" ]; then
+ (cd ${HOME} && git clone https://github.com/madler/zlib.git &&
+ cd ${HOME}/zlib && ./configure && make &&
+ sudo make install prefix=/opt/zlib)
+fi
diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml
new file mode 100644
index 0000000..8f624d2
--- /dev/null
+++ b/.github/workflows/c-cpp.yml
@@ -0,0 +1,132 @@
+name: C/C++ CI
+
+on:
+ push:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+ pull_request:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+
+jobs:
+ ci:
+ if: github.repository != 'openssh/openssh-portable-selfhosted'
+ strategy:
+ fail-fast: false
+ matrix:
+ # First we test all OSes in the default configuration.
+ target:
+ - ubuntu-20.04
+ - ubuntu-22.04
+ - macos-11
+ - macos-12
+ - macos-13
+ - windows-2019
+ - windows-2022
+ config: [default]
+ # Then we include any extra configs we want to test for specific VMs.
+ # Valgrind slows things down quite a bit, so start them first.
+ include:
+ - { target: windows-2019, config: cygwin-release }
+ - { target: windows-2022, config: cygwin-release }
+ - { target: ubuntu-20.04, config: valgrind-1 }
+ - { target: ubuntu-20.04, config: valgrind-2 }
+ - { target: ubuntu-20.04, config: valgrind-3 }
+ - { target: ubuntu-20.04, config: valgrind-4 }
+ - { target: ubuntu-20.04, config: valgrind-5 }
+ - { target: ubuntu-20.04, config: valgrind-unit }
+ - { target: ubuntu-20.04, config: c89 }
+ - { target: ubuntu-20.04, config: clang-6.0 }
+ - { target: ubuntu-20.04, config: clang-8 }
+ - { target: ubuntu-20.04, config: clang-9 }
+ - { target: ubuntu-20.04, config: clang-10 }
+ - { target: ubuntu-20.04, config: clang-11 }
+ - { target: ubuntu-20.04, config: clang-12-Werror }
+ - { target: ubuntu-20.04, config: clang-sanitize-address }
+ - { target: ubuntu-20.04, config: clang-sanitize-undefined }
+ - { target: ubuntu-20.04, config: gcc-sanitize-address }
+ - { target: ubuntu-20.04, config: gcc-sanitize-undefined }
+ - { target: ubuntu-20.04, config: gcc-7 }
+ - { target: ubuntu-20.04, config: gcc-8 }
+ - { target: ubuntu-20.04, config: gcc-10 }
+ - { target: ubuntu-22.04, config: gcc-11-Werror }
+ - { target: ubuntu-22.04, config: gcc-12-Werror }
+ - { target: ubuntu-20.04, config: pam }
+ - { target: ubuntu-20.04, config: kitchensink }
+ - { target: ubuntu-22.04, config: hardenedmalloc }
+ - { target: ubuntu-20.04, config: tcmalloc }
+ - { target: ubuntu-20.04, config: musl }
+ - { target: ubuntu-latest, config: boringssl }
+ - { target: ubuntu-latest, config: libressl-master }
+ - { target: ubuntu-latest, config: libressl-3.2.6 }
+ - { target: ubuntu-latest, config: libressl-3.3.6 }
+ - { target: ubuntu-latest, config: libressl-3.4.3 }
+ - { target: ubuntu-latest, config: libressl-3.5.3 }
+ - { target: ubuntu-latest, config: libressl-3.6.1 }
+ - { target: ubuntu-latest, config: libressl-3.7.2 }
+ - { target: ubuntu-latest, config: libressl-3.8.2 }
+ - { target: ubuntu-latest, config: openssl-master }
+ - { target: ubuntu-latest, config: openssl-noec }
+ - { target: ubuntu-latest, config: openssl-1.1.1 }
+ - { target: ubuntu-latest, config: openssl-1.1.1t }
+ - { target: ubuntu-latest, config: openssl-1.1.1w }
+ - { target: ubuntu-latest, config: openssl-3.0.0 }
+ - { target: ubuntu-latest, config: openssl-3.0.12 }
+ - { target: ubuntu-latest, config: openssl-3.1.0 }
+ - { target: ubuntu-latest, config: openssl-3.1.4 }
+ - { target: ubuntu-latest, config: openssl-3.2.0 }
+ - { target: ubuntu-latest, config: openssl-1.1.1_stable }
+ - { target: ubuntu-latest, config: openssl-3.0 } # stable branch
+ - { target: ubuntu-latest, config: openssl-3.2 } # stable branch
+ - { target: ubuntu-latest, config: zlib-develop }
+ - { target: ubuntu-22.04, config: pam }
+ - { target: ubuntu-22.04, config: krb5 }
+ - { target: ubuntu-22.04, config: heimdal }
+ - { target: ubuntu-22.04, config: libedit }
+ - { target: ubuntu-22.04, config: sk }
+ - { target: ubuntu-22.04, config: selinux }
+ - { target: ubuntu-22.04, config: kitchensink }
+ - { target: ubuntu-22.04, config: without-openssl }
+ - { target: macos-11, config: pam }
+ - { target: macos-12, config: pam }
+ - { target: macos-13, config: pam }
+ runs-on: ${{ matrix.target }}
+ steps:
+ - name: set cygwin git params
+ if: ${{ startsWith(matrix.target, 'windows') }}
+ run: git config --global core.autocrlf input
+ - name: install cygwin
+ if: ${{ startsWith(matrix.target, 'windows') }}
+ uses: cygwin/cygwin-install-action@master
+ - uses: actions/checkout@main
+ - name: setup CI system
+ run: sh ./.github/setup_ci.sh ${{ matrix.config }}
+ - name: autoreconf
+ run: sh -c autoreconf
+ - name: configure
+ run: sh ./.github/configure.sh ${{ matrix.config }}
+ - name: save config
+ uses: actions/upload-artifact@main
+ with:
+ name: ${{ matrix.target }}-${{ matrix.config }}-config
+ path: config.h
+ - name: make clean
+ run: make clean
+ - name: make
+ run: make
+ - name: make tests
+ run: sh ./.github/run_test.sh ${{ matrix.config }}
+ env:
+ TEST_SSH_UNSAFE_PERMISSIONS: 1
+ TEST_SSH_HOSTBASED_AUTH: yes
+ - name: save logs
+ if: failure()
+ uses: actions/upload-artifact@main
+ with:
+ name: ${{ matrix.target }}-${{ matrix.config }}-logs
+ path: |
+ config.h
+ config.log
+ regress/*.log
+ regress/valgrind-out/
+ regress/asan.log.*
+ regress/msan.log.*
+ regress/log/*
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml
new file mode 100644
index 0000000..7ca8c47
--- /dev/null
+++ b/.github/workflows/cifuzz.yml
@@ -0,0 +1,32 @@
+name: CIFuzz
+on:
+ push:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+ pull_request:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+
+jobs:
+ Fuzzing:
+ if: github.repository != 'openssh/openssh-portable-selfhosted'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Build Fuzzers
+ id: build
+ uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'openssh'
+ dry-run: false
+ language: c++
+ - name: Run Fuzzers
+ uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
+ with:
+ oss-fuzz-project-name: 'openssh'
+ fuzz-seconds: 600
+ dry-run: false
+ language: c++
+ - name: Upload Crash
+ uses: actions/upload-artifact@main
+ if: failure() && steps.build.outcome == 'success'
+ with:
+ name: artifacts
+ path: ./out/artifacts
diff --git a/.github/workflows/selfhosted.yml b/.github/workflows/selfhosted.yml
new file mode 100644
index 0000000..be0b4ff
--- /dev/null
+++ b/.github/workflows/selfhosted.yml
@@ -0,0 +1,125 @@
+name: C/C++ CI self-hosted
+
+on:
+ push:
+ paths: [ '**.c', '**.h', '**.m4', '**.sh', '.github/**', '**/Makefile.in', 'configure.ac' ]
+
+jobs:
+ selfhosted:
+ if: github.repository == 'openssh/openssh-portable-selfhosted'
+ runs-on: ${{ matrix.host }}
+ timeout-minutes: 600
+ env:
+ HOST: ${{ matrix.host }}
+ TARGET_HOST: ${{ matrix.target }}
+ TARGET_CONFIG: ${{ matrix.config }}
+ strategy:
+ fail-fast: false
+ # We use a matrix in two parts: firstly all of the VMs are tested with the
+ # default config. "target" corresponds to a label associated with the
+ # worker. The default is an ephemeral VM running under libvirt.
+ matrix:
+ target:
+ - alpine
+ - centos7
+ - debian-i386
+ - dfly30
+ - dfly48
+ - dfly60
+ - dfly62
+ - dfly64
+ - fbsd10
+ - fbsd12
+ - fbsd13
+ - fbsd14
+ - minix3
+ - nbsd3
+ - nbsd4
+ - nbsd8
+ - nbsd9
+ - obsd51
+ - obsd67
+ - obsd72
+ - obsd73
+ - obsd74
+ - obsdsnap
+ - obsdsnap-i386
+ - openindiana
+ - ubuntu-2204
+ config:
+ - default
+ host:
+ - libvirt
+ include:
+ # Long-running/slow tests have access to high priority runners.
+ - { target: aix51, config: default, host: libvirt-hipri }
+ - { target: openindiana, config: pam, host: libvirt-hipri }
+ - { target: sol10, config: default, host: libvirt-hipri }
+ - { target: sol10, config: pam, host: libvirt-hipri }
+ - { target: sol11, config: default, host: libvirt-hipri }
+ - { target: sol11, config: pam-krb5, host: libvirt-hipri }
+ - { target: sol11, config: sol64, host: libvirt-hipri }
+ # Then we include extra libvirt test configs.
+ - { target: centos7, config: pam, host: libvirt }
+ - { target: debian-i386, config: pam, host: libvirt }
+ - { target: dfly30, config: without-openssl, host: libvirt}
+ - { target: dfly48, config: pam ,host: libvirt }
+ - { target: dfly58, config: pam, host: libvirt }
+ - { target: dfly60, config: pam, host: libvirt }
+ - { target: dfly62, config: pam, host: libvirt }
+ - { target: fbsd10, config: pam, host: libvirt }
+ - { target: fbsd12, config: pam, host: libvirt }
+ - { target: fbsd13, config: pam, host: libvirt }
+ - { target: fbsd14, config: pam, host: libvirt }
+ - { target: nbsd8, config: pam, host: libvirt }
+ - { target: nbsd9, config: pam, host: libvirt }
+ # VMs with persistent disks that have their own runner.
+ - { target: win10, config: default, host: win10 }
+ - { target: win10, config: cygwin-release, host: win10 }
+ # Physical hosts, with either native runners or remote via ssh.
+ - { target: ARM, config: default, host: ARM }
+ - { target: ARM64, config: default, host: ARM64 }
+ - { target: ARM64, config: pam, host: ARM64 }
+ - { target: debian-riscv64, config: default, host: debian-riscv64 }
+ - { target: obsd-arm64, config: default, host: obsd-arm64 }
+ - { target: openwrt-mips, config: default, host: openwrt-mips }
+ - { target: openwrt-mipsel, config: default, host: openwrt-mipsel }
+ steps:
+ - name: shutdown VM if running
+ run: vmshutdown
+ working-directory: ${{ runner.temp }}
+ - uses: actions/checkout@main
+ - name: autoreconf
+ run: autoreconf
+ - name: startup VM
+ run: vmstartup
+ working-directory: ${{ runner.temp }}
+ - name: configure
+ run: vmrun ./.github/configure.sh ${{ matrix.config }}
+ - name: save config
+ uses: actions/upload-artifact@main
+ with:
+ name: ${{ matrix.target }}-${{ matrix.config }}-config
+ path: config.h
+ - name: make clean
+ run: vmrun make clean
+ - name: make
+ run: vmrun make
+ - name: make tests
+ run: vmrun ./.github/run_test.sh ${{ matrix.config }}
+ timeout-minutes: 600
+ - name: save logs
+ if: failure()
+ uses: actions/upload-artifact@main
+ with:
+ name: ${{ matrix.target }}-${{ matrix.config }}-logs
+ path: |
+ config.h
+ config.log
+ regress/*.log
+ regress/log/*
+ regress/valgrind-out/
+ - name: shutdown VM
+ if: always()
+ run: vmshutdown
+ working-directory: ${{ runner.temp }}
diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml
new file mode 100644
index 0000000..b280793
--- /dev/null
+++ b/.github/workflows/upstream.yml
@@ -0,0 +1,53 @@
+name: Upstream self-hosted
+
+on:
+ push:
+ branches: [ master ]
+ paths: [ '**.c', '**.h', '.github/**' ]
+
+jobs:
+ selfhosted:
+ if: github.repository == 'openssh/openssh-portable-selfhosted'
+ runs-on: 'libvirt'
+ env:
+ HOST: 'libvirt'
+ TARGET_HOST: ${{ matrix.target }}
+ TARGET_CONFIG: ${{ matrix.config }}
+ strategy:
+ fail-fast: false
+ matrix:
+ target: [ obsdsnap, obsdsnap-i386 ]
+ config: [ default, without-openssl, ubsan ]
+ steps:
+ - name: shutdown VM if running
+ run: vmshutdown
+ working-directory: ${{ runner.temp }}
+ - uses: actions/checkout@main
+ - name: startup VM
+ run: vmstartup
+ working-directory: ${{ runner.temp }}
+ - name: update source
+ run: vmrun "cd /usr/src && cvs up -dPA usr.bin/ssh regress/usr.bin/ssh"
+ - name: make clean
+ run: vmrun "cd /usr/src/usr.bin/ssh && make obj && make clean && cd /usr/src/regress/usr.bin/ssh && make obj && make clean && sudo chmod -R g-w /usr/src /usr/obj"
+ - name: make
+ run: vmrun "cd /usr/src/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
+ - name: make install
+ run: vmrun "cd /usr/src/usr.bin/ssh && sudo make install"
+ - name: make tests`
+ run: vmrun "cd /usr/src/regress/usr.bin/ssh && case ${{ matrix.config }} in without-openssl) make OPENSSL=no;; ubsan) make DEBUG='-fsanitize-minimal-runtime -fsanitize=undefined';; *) make; esac"
+ env:
+ SUDO: sudo
+ timeout-minutes: 300
+ - name: save logs
+ if: failure()
+ uses: actions/upload-artifact@main
+ with:
+ name: ${{ matrix.target }}-${{ matrix.config }}-logs
+ path: |
+ /usr/obj/regress/usr.bin/ssh/obj/*.log
+ /usr/obj/regress/usr.bin/ssh/obj/log/*
+ - name: shutdown VM
+ if: always()
+ run: vmshutdown
+ working-directory: ${{ runner.temp }}