diff options
Diffstat (limited to '.github')
-rw-r--r-- | .github/ci-status.md | 15 | ||||
-rwxr-xr-x | .github/configs | 361 | ||||
-rwxr-xr-x | .github/configure.sh | 21 | ||||
-rwxr-xr-x | .github/run_test.sh | 48 | ||||
-rwxr-xr-x | .github/setup_ci.sh | 243 | ||||
-rw-r--r-- | .github/workflows/c-cpp.yml | 132 | ||||
-rw-r--r-- | .github/workflows/cifuzz.yml | 32 | ||||
-rw-r--r-- | .github/workflows/selfhosted.yml | 125 | ||||
-rw-r--r-- | .github/workflows/upstream.yml | 53 |
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 }} |