Commit 947c714c authored by Konstantin Artyushkin's avatar Konstantin Artyushkin

Import vanilla OpenSSH 9.6p1

parent 271921d3
This source diff could not be displayed because it is too large. You can view the blob instead.
dtucker@dtucker.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG
djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBLnJo3ZVDENYZGXm5uO9lU7b0iDFq5gHpTu1MaHPWTEfPdvw+AjFQQ/q5YizuMJkXGsMdYmblJEJZYHpm9IS7ZkAAAAEc3NoOg==
djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBJoAXBTQalfg+kC5wy1vE7HkIHtVnmV6AUuuIo9KQ1P+70juHwvsFKpsGaqQbrHJkTVgYDGVP02XHj8+Fb18yBIAAAAEc3NoOg==
djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBH+z1I48s6ydOhP5SJmI02zVCLf0K15B+UMHgoTIKVfUIv5oDoVX7e9f+7QiRmTeEOdZfQydiaVqsfi7qPSve+0AAAAEc3NoOg==
djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBPM4BmUg/fMnsl42JwktTekk/mB8Be3M+yK2ayg6lqYsqEri8yhRx84gey51OHKVk1TwlGbJjcMHI4URreDBEMQAAAAEc3NoOg==
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEcWi5g4FaXu9ZpK39Kj9BTnNgYLoFAmMMMiIACgkQKj9BTnNg
YLpyGhAAhZ1RxmD62JnT0gnor1aD0inq1fGPRadaFvXH2OScPcxXMIZWx+otnyZ/
H9s0bIti42dPHqurgh92KS2mDGVIW8Y8MvxFUr678+hdem1U7Xvjoo0uaveNhJhe
GxuQDOvXKRmmfL2c6w3wnFChFA1o3K+JNshjCHhWz7u6+UmY0Q9yIxqbSi+vmEPP
NfWPfGdu4h8r7q11UgTxRSUQkfZXMqpBtb367B9BLduGuKRFKEJNyi6WpjBrqy38
BvEbAaL52KX8hEp3TKMjo38RbOK+veSoPV5zlLui0WlEwwasgljal3f4RkqCAJob
hqpFJRogM5XNnA2e68TDTf3buJ3wRRjuK39/CusOJz5v4i6+VCdte+BET1Y4gD6y
v8KV4pRyumcdbN3khFUkmaQsjo+fyQjWNrgOvv60J2xUWZdchn8lxHOxrfRVKnOi
BD4bdks7tPQY/XsS5GNJIp21Ji9HGyBajjHo0BlesLodw7FEOf6YE18A3n9qzosR
RliuP4Hs/Z4sCUuDTbpKtQiUVs40kBbkhEL8kS8FsXz3VO89hAWaUqNUYom8AkKv
nfDjrZDBLXuVj1Mi8qNPXxqrB/1Cza2/W4U7SK4TlMFXfoXXWxxhefN5vIdMhAJB
u9Mdz1pY9mowKbd0c0dR+3fauvjM133dzKuyeDHMqDa5JPyd59o=
=kgnS
-----END PGP SIGNATURE-----
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)
This diff is collapsed. Click to expand it.
#!/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
#!/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
#!/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
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/*
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
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 }}
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 }}
Makefile
buildpkg.sh
config.h
config.h.in
config.h.in~
config.log
config.status
configure
aclocal.m4
openbsd-compat/Makefile
openbsd-compat/regress/Makefile
openssh.xml
opensshd.init
survey.sh
**/*.0
**/*.o
**/*.lo
**/*.so
**/*.out
**/*.a
autom4te.cache/
scp
sftp
sftp-server
ssh
ssh-add
ssh-agent
ssh-keygen
ssh-keyscan
ssh-keysign
ssh-pkcs11-helper
ssh-sk-helper
sshd
!regress/misc/fuzz-harness/Makefile
!regress/unittests/sshsig/Makefile
tags
5317f294d63a876bfc861e19773b1575f96f027d remove libssh from makefiles
a337e886a49f96701ccbc4832bed086a68abfa85 Makefile changes
f2c9feb26963615c4fece921906cf72e248b61ee more Makefile
fa728823ba21c4b45212750e1d3a4b2086fd1a62 more Makefile refactoring
1de0e85522051eb2ffa00437e1885e9d7b3e0c2e moduli update
814b2f670df75759e1581ecef530980b2b3d7e0f remove redundant make defs
04431e8e7872f49a2129bf080a6b73c19d576d40 moduli update
c07772f58028fda683ee6abd41c73da3ff70d403 moduli update
db6375fc302e3bdf07d96430c63c991b2c2bd3ff moduli update
5ea3d63ab972691f43e9087ab5fd8376d48e898f uuencode.c Makefile accident
99dd10e72c04e93849981d43d64c946619efa474 include sshbuf-misc.c
9e1c23476bb845f3cf3d15d9032da3ed0cb2fcf5 sshbuf-misc.c in regress
569f08445c27124ec7c7f6c0268d844ec56ac061 Makefile tweaks for !openssl
58ec755be4e51978ecfee73539090eb68652a987 moduli update
4bd5551b306df55379afe17d841207990eb773bf Makefile.inc
14806a59353152f843eb349e618abbf6f4dd3ada Makefile.inc
8ea4455a2d9364a0a04f9e4a2cbfa4c9fcefe77e Makefile.inc
d9b910e412d139141b072a905e66714870c38ac0 Makefile.inc
7b7b619c1452a459310b0cf4391c5757c6bdbc0f moduli update
5010ff08f7ad92082e87dde098b20f5c24921a8f moduli regen script update
3bcae7a754db3fc5ad3cab63dd46774edb35b8ae moduli regen script update
52ff0e3205036147b2499889353ac082e505ea54 moduli update
07b5031e9f49f2b69ac5e85b8da4fc9e393992a0 Makefile.inc
cc12a9029833d222043aecd252d654965c351a69 moduli-gen Makefile
7ac6c252d2a5be8fbad4c66d9d35db507c9dac5b moduli update
6b52cd2b637f3d29ef543f0ce532a2bce6d86af5 makefile change
f9a0726d957cf10692a231996a1f34e7f9cdfeb0 moduli update
1e0a2692b7e20b126dda60bf04999d1d30d959d8 sshd relinking makefile changes
e1dc11143f83082e3154d6094f9136d0dc2637ad more relinking makefile tweaks
Old upstream tree:
321065a95a7ccebdd5fd08482a1e19afbf524e35 Update DH groups
d4f699a421504df35254cf1c6f1a7c304fb907ca Remove 1k bit groups
aafe246655b53b52bc32c8a24002bc262f4230f7 Remove intermediate moduli
......@@ -11,3 +43,13 @@ f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead.
96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile
6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file
77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY
38c2133817cbcae75c88c63599ac54228f0fa384 Change COMPILER_VERSION tests
30c20180c87cbc99fa1020489fe7fd8245b6420c resync integrity.sh shell
1e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability
fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits
5781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c
ea80f445e819719ccdcb237022cacfac990fdc5c Makefile.inc warning flags
b92c93266d8234d493857bb822260dacf4366157 moduli-gen.sh tweak
b25bf747544265b39af74fe0716dc8d9f5b63b95 Updated moduli
1bd41cba06a7752de4df304305a8153ebfb6b0ac rsa.[ch] already removed
e39b3902fe1d6c4a7ba6a3c58e072219f3c1e604 Makefile changes
......@@ -33,7 +33,7 @@ David Agraz <dagraz@jahoopa.com> - Build fixes
David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes
David Hesprich <darkgrue@gue-tech.org> - Configure fixes
David Rankin <drankin@bohemians.lexington.ky.us> - libwrap, AIX, NetBSD fixes
Dag-Erling Smrgrav <des at freebsd.org> - Challenge-Response PAM code.
Dag-Erling Smørgrav <des at freebsd.org> - Challenge-Response PAM code.
Dhiraj Gulati <dgulati@sco.com> - UnixWare long passwords
Ed Eden <ede370@stl.rural.usda.gov> - configure fixes
Garrick James <garrick@james.net> - configure fixes
......
This source diff could not be displayed because it is too large. You can view the blob instead.
1. Prerequisites
----------------
A C compiler. Any C89 or better compiler should work. Where supported,
configure will attempt to enable the compiler's run-time integrity checking
options. Some notes about specific compilers:
A C compiler. Any C89 or better compiler that supports variadic macros
should work. Where supported, configure will attempt to enable the
compiler's run-time integrity checking options. Some notes about
specific compilers:
- clang: -ftrapv and -sanitize=integer require the compiler-rt runtime
(CC=clang LDFLAGS=--rtlib=compiler-rt ./configure)
You will need working installations of Zlib and libcrypto (LibreSSL /
OpenSSL)
To support Privilege Separation (which is now required) you will need
to create the user, group and directory used by sshd for privilege
separation. See README.privsep for details.
The remaining items are optional.
A working installation of zlib:
Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems):
http://www.gzip.org/zlib/
https://zlib.net/
libcrypto (LibreSSL or OpenSSL >= 0.9.8f < 1.1.0)
LibreSSL http://www.libressl.org/ ; or
OpenSSL http://www.openssl.org/
libcrypto from either of LibreSSL or OpenSSL. Building without libcrypto
is supported but severely restricts the available ciphers and algorithms.
- LibreSSL (https://www.libressl.org/) 3.1.0 or greater
- OpenSSL (https://www.openssl.org) 1.1.1 or greater
LibreSSL/OpenSSL should be compiled as a position-independent library
(i.e. with -fPIC) otherwise OpenSSH will not be able to link with it.
If you must use a non-position-independent libcrypto, then you may need
to configure OpenSSH --without-pie. Note that because of API changes,
OpenSSL 1.1.x is not currently supported.
(i.e. -fPIC, eg by configuring OpenSSL as "./config [options] -fPIC"
or LibreSSL as "CFLAGS=-fPIC ./configure") otherwise OpenSSH will not
be able to link with it. If you must use a non-position-independent
libcrypto, then you may need to configure OpenSSH --without-pie.
The remaining items are optional.
If you build either from source, running the OpenSSL self-test ("make
tests") or the LibreSSL equivalent ("make check") and ensuring that all
tests pass is strongly recommended.
NB. If you operating system supports /dev/random, you should configure
libcrypto (LibreSSL/OpenSSL) to use it. OpenSSH relies on libcrypto's
direct support of /dev/random, or failing that, either prngd or egd
direct support of /dev/random, or failing that, either prngd or egd.
PRNGD:
If your system lacks kernel-based random collection, the use of Lutz
Jaenicke's PRNGd is recommended.
Jaenicke's PRNGd is recommended. It requires that libcrypto be configured
to support it.
http://prngd.sourceforge.net/
EGD:
If the kernel lacks /dev/random the Entropy Gathering Daemon (EGD) is
supported only if libcrypto supports it.
The Entropy Gathering Daemon (EGD) supports the same interface as prngd.
It also supported only if libcrypto is configured to support it.
http://egd.sourceforge.net/
......@@ -47,7 +57,7 @@ PAM:
OpenSSH can utilise Pluggable Authentication Modules (PAM) if your
system supports it. PAM is standard most Linux distributions, Solaris,
HP-UX 11, AIX >= 5.2, FreeBSD and NetBSD.
HP-UX 11, AIX >= 5.2, FreeBSD, NetBSD and Mac OS X.
Information about the various PAM implementations are available:
......@@ -66,13 +76,6 @@ passphrase requester. This is maintained separately at:
http://www.jmknoble.net/software/x11-ssh-askpass/
S/Key Libraries:
If you wish to use --with-skey then you will need the library below
installed. No other S/Key library is currently known to be supported.
http://www.sparc.spb.su/solaris/skey/
LibEdit:
sftp supports command-line editing via NetBSD's libedit. If your platform
......@@ -91,18 +94,36 @@ http://nlnetlabs.nl/projects/ldns/
Autoconf:
If you modify configure.ac or configure doesn't exist (eg if you checked
the code out of CVS yourself) then you will need autoconf-2.69 to rebuild
the automatically generated files by running "autoreconf". Earlier
versions may also work but this is not guaranteed.
the code out of git yourself) then you will need autoconf-2.69 and
automake-1.16.1 to rebuild the automatically generated files by running
"autoreconf". Earlier versions may also work but this is not guaranteed.
http://www.gnu.org/software/autoconf/
http://www.gnu.org/software/automake/
Basic Security Module (BSM):
Native BSM support is know to exist in Solaris from at least 2.5.1,
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).
makedepend:
https://www.x.org/archive/individual/util/
If you are making significant changes to the code you may need to rebuild
the dependency (.depend) file using "make depend", which requires the
"makedepend" tool from the X11 distribution.
libfido2:
libfido2 allows the use of hardware security keys over USB. libfido2
in turn depends on libcbor. libfido2 >= 1.5.0 is strongly recommended.
Limited functionality is possible with earlier libfido2 versions.
https://github.com/Yubico/libfido2
https://github.com/pjk/libcbor
2. Building / Installation
--------------------------
......@@ -131,10 +152,6 @@ make install
This will install the binaries in /opt/{bin,lib,sbin}, but will place the
configuration files in /etc/ssh.
If you are using Privilege Separation (which is enabled by default)
then you will also need to create the user, group and directory used by
sshd for privilege separation. See README.privsep for details.
If you are using PAM, you may need to manually install a PAM control
file as "/etc/pam.d/sshd" (or wherever your system prefers to keep
them). Note that the service name used to start PAM is __progname,
......@@ -162,13 +179,11 @@ also be enabled in sshd_config (refer to the UsePAM directive).
--with-prngd-socket=/some/file allows you to enable EGD or PRNGD
support and to specify a PRNGd socket. Use this if your Unix lacks
/dev/random and you don't want to use OpenSSH's builtin entropy
collection support.
/dev/random.
--with-prngd-port=portnum allows you to enable EGD or PRNGD support
and to specify a EGD localhost TCP port. Use this if your Unix lacks
/dev/random and you don't want to use OpenSSH's builtin entropy
collection support.
/dev/random.
--with-lastlog=FILE will specify the location of the lastlog file.
./configure searches a few locations for lastlog, but may not find
......@@ -179,14 +194,6 @@ it if lastlog is installed in a different place.
--with-osfsia, --without-osfsia will enable or disable OSF1's Security
Integration Architecture. The default for OSF1 machines is enable.
--with-skey=PATH will enable S/Key one time password support. You will
need the S/Key libraries and header files installed for this to work.
--with-md5-passwords will enable the use of MD5 passwords. Enable this
if your operating system uses MD5 passwords and the system crypt() does
not support them directly (see the crypt(3/3c) man page). If enabled, the
resulting binary will support both MD5 and traditional crypt passwords.
--with-utmpx enables utmpx support. utmpx support is automatic for
some platforms.
......@@ -204,11 +211,15 @@ created.
--with-xauth=PATH specifies the location of the xauth binary
--with-ssl-dir=DIR allows you to specify where your Libre/OpenSSL
libraries
are installed.
libraries are installed.
--with-ssl-engine enables Libre/OpenSSL's (hardware) ENGINE support
--without-openssl builds without using OpenSSL. Only a subset of ciphers
and algorithms are supported in this configuration.
--without-zlib builds without zlib. This disables the Compression option.
--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
......@@ -216,7 +227,7 @@ If you need to pass special options to the compiler or linker, you
can specify these as environment variables before running ./configure.
For example:
CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure
CC="/usr/foo/cc" CFLAGS="-O" LDFLAGS="-s" LIBS="-lrubbish" ./configure
3. Configuration
----------------
......@@ -240,10 +251,10 @@ to generate keys for all supported types.
Replacing /etc/ssh with the correct path to the configuration directory.
(${prefix}/etc or whatever you specified with --sysconfdir during
configuration)
configuration).
If you have configured OpenSSH with EGD support, ensure that EGD is
running and has collected some Entropy.
If you have configured OpenSSH with EGD/prngd support, ensure that EGD or
prngd is running and has collected some entropy first.
For more information on configuration, please refer to the manual pages
for sshd, ssh and ssh-agent.
......@@ -265,6 +276,6 @@ summary data may be published.
5. Problems?
------------
If you experience problems compiling, installing or running OpenSSH.
Please refer to the "reporting bugs" section of the webpage at
If you experience problems compiling, installing or running OpenSSH,
please refer to the "reporting bugs" section of the webpage at
https://www.openssh.com/
......@@ -75,27 +75,6 @@ OpenSSH contains no GPL code.
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
2)
The 32-bit CRC compensation attack detector in deattack.c was
contributed by CORE SDI S.A. under a BSD-style license.
* Cryptographic attack detector for ssh - source code
*
* Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
*
* All rights reserved. Redistribution and use in source and binary
* forms, with or without modification, are permitted provided that
* this copyright notice is retained.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
* CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
* SOFTWARE.
*
* Ariel Futoransky <futo@core-sdi.com>
* <http://www.core-sdi.com>
3)
ssh-keyscan was contributed by David Mazieres under a BSD-style
license.
......@@ -195,7 +174,7 @@ OpenSSH contains no GPL code.
Gert Doering
Jakob Schlyter
Jason Downs
Juha Yrjölä
Juha Yrjölä
Michael Stone
Networks Associates Technology, Inc.
Solar Designer
......@@ -231,22 +210,14 @@ OpenSSH contains no GPL code.
8) Portable OpenSSH contains the following additional licenses:
a) md5crypt.c, md5crypt.h
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we meet
* some day, and you think this stuff is worth it, you can buy me a
* beer in return. Poul-Henning Kamp
b) snprintf replacement
a) snprintf replacement
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell
* (papowell@astart.com) It may be used for any purpose as long as this
* notice remains intact on all source code distributions
c) Compatibility code (openbsd-compat)
b) Compatibility code (openbsd-compat)
Apart from the previously mentioned licenses, various pieces of code
in the openbsd-compat/ subdirectory are licensed as follows:
......@@ -260,6 +231,7 @@ OpenSSH contains no GPL code.
Eric P. Allman
The Regents of the University of California
Constantin S. Svintsoff
Kungliga Tekniska Högskolan
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -335,6 +307,65 @@ OpenSSH contains no GPL code.
* authorization. *
****************************************************************************/
The Blowfish cipher implementation is licensed by Niels Provos under
a 3-clause BSD license:
* Blowfish - a fast block cipher designed by Bruce Schneier
*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Some replacement code is licensed by the NetBSD foundation under a
2-clause BSD license:
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Todd Vierling.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
------
$OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
$OpenBSD: LICENCE,v 1.20 2017/04/30 23:26:16 djm Exp $
......@@ -23,9 +23,8 @@ these programs.
- These provide an arbitrary size buffer, where data can be appended.
Data can be consumed from either end. The code is used heavily
throughout ssh. The basic buffer manipulation functions are in
buffer.c (header buffer.h), and additional code to manipulate specific
data types is in bufaux.c.
throughout ssh. The buffer manipulation functions are in
sshbuf*.c (header sshbuf.h).
Compression Library
......@@ -35,11 +34,12 @@ these programs.
- Ssh contains several encryption algorithms. These are all
accessed through the cipher.h interface. The interface code is
in cipher.c, and the implementations are in libc.
in cipher.c, and the implementations are either in libc or
LibreSSL.
Multiple Precision Integer Library
- Uses the SSLeay BIGNUM sublibrary.
- Uses the LibreSSL BIGNUM sublibrary.
Random Numbers
......@@ -62,7 +62,7 @@ these programs.
code in packet.c does not concern itself with packet types or their
execution; it contains code to build packets, to receive them and
extract data from them, and the code to compress and/or encrypt
packets. CRC code comes from crc32.c.
packets.
- The code in packet.c calls the buffer manipulation routines
(buffer.c, bufaux.c), compression routines (zlib), and the
......@@ -106,12 +106,6 @@ these programs.
calls client_loop in clientloop.c. This does the real work for
the session.
- The client is suid root. It tries to temporarily give up this
rights while reading the configuration data. The root
privileges are only used to make the connection (from a
privileged socket). Any extra privileges are dropped before
calling ssh_login.
Pseudo-tty manipulation and tty modes
- Code to allocate and use a pseudo tty is in pty.c. Code to
......@@ -165,4 +159,4 @@ these programs.
uidswap.c uid-swapping
xmalloc.c "safe" malloc routines
$OpenBSD: OVERVIEW,v 1.12 2015/07/08 19:01:15 markus Exp $
$OpenBSD: OVERVIEW,v 1.15 2018/10/23 05:56:35 djm Exp $
......@@ -25,6 +25,10 @@ raw user keys. The ssh client will support automatic verification of
acceptance of certified host keys, by adding a similar ability to
specify CA keys in ~/.ssh/known_hosts.
All certificate types include certification information along with the
public key that is used to sign challenges. In OpenSSH, ssh-keygen
performs the CA signing operation.
Certified keys are represented using new key types:
ssh-rsa-cert-v01@openssh.com
......@@ -32,10 +36,19 @@ Certified keys are represented using new key types:
ecdsa-sha2-nistp256-cert-v01@openssh.com
ecdsa-sha2-nistp384-cert-v01@openssh.com
ecdsa-sha2-nistp521-cert-v01@openssh.com
ssh-ed25519-cert-v01@openssh.com
Two additional types exist for RSA certificates to force use of
SHA-2 signatures (SHA-256 and SHA-512 respectively):
These include certification information along with the public key
that is used to sign challenges. ssh-keygen performs the CA signing
operation.
rsa-sha2-256-cert-v01@openssh.com
rsa-sha2-512-cert-v01@openssh.com
These RSA/SHA-2 types should not appear in keys at rest or transmitted
on the wire, but do appear in a SSH_MSG_KEXINIT's host-key algorithms
field or in the "public key algorithm name" field of a "publickey"
SSH_USERAUTH_REQUEST to indicate that the signature will use the
specified algorithm.
Protocol extensions
-------------------
......@@ -100,9 +113,9 @@ DSA certificate
ECDSA certificate
string "ecdsa-sha2-nistp256-v01@openssh.com" |
"ecdsa-sha2-nistp384-v01@openssh.com" |
"ecdsa-sha2-nistp521-v01@openssh.com"
string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
"ecdsa-sha2-nistp384-cert-v01@openssh.com" |
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
string nonce
string curve
string public_key
......@@ -146,12 +159,11 @@ p, q, g, y are the DSA parameters as described in FIPS-186-2.
curve and public key are respectively the ECDSA "[identifier]" and "Q"
defined in section 3.1 of RFC5656.
pk is the encoded Ed25519 public key as defined by
draft-josefsson-eddsa-ed25519-03.
pk is the encoded Ed25519 public key as defined by RFC8032.
serial is an optional certificate serial number set by the CA to
provide an abbreviated way to refer to certificates from that CA.
If a CA does not wish to number its certificates it must set this
If a CA does not wish to number its certificates, it must set this
field to zero.
type specifies whether this certificate is for identification of a user
......@@ -174,7 +186,7 @@ certificate. Each represents a time in seconds since 1970-01-01
valid after <= current time < valid before
criticial options is a set of zero or more key options encoded as
critical options is a set of zero or more key options encoded as
below. All such options are "critical" in the sense that an implementation
must refuse to authorise a key that has an unrecognised option.
......@@ -192,24 +204,25 @@ compatibility.
The reserved field is currently unused and is ignored in this version of
the protocol.
signature key contains the CA key used to sign the certificate.
The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types
ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained"
certificates, where the signature key type is a certificate type itself
are NOT supported. Note that it is possible for a RSA certificate key to
be signed by a DSS or ECDSA CA key and vice-versa.
The signature key field contains the CA key used to sign the
certificate. The valid key types for CA keys are ssh-rsa,
ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256,
ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where
the signature key type is a certificate type itself are NOT supported.
Note that it is possible for a RSA certificate key to be signed by a
Ed25519 or ECDSA CA key and vice-versa.
signature is computed over all preceding fields from the initial string
up to, and including the signature key. Signatures are computed and
encoded according to the rules defined for the CA's public key algorithm
(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA
types), and draft-josefsson-eddsa-ed25519-03 for Ed25519.
types, and RFC8032 for Ed25519).
Critical options
----------------
The critical options section of the certificate specifies zero or more
options on the certificates validity. The format of this field
options on the certificate's validity. The format of this field
is a sequence of zero or more tuples:
string name
......@@ -220,9 +233,12 @@ sequence. Each named option may only appear once in a certificate.
The name field identifies the option and the data field encodes
option-specific information (see below). All options are
"critical", if an implementation does not recognise a option
"critical"; if an implementation does not recognise a option,
then the validating party should refuse to accept the certificate.
Custom options should append the originating author or organisation's
domain name to the option name, e.g. "my-option@example.com".
No critical options are defined for host certificates at present. The
supported user certificate options and the contents and structure of
their data fields are:
......@@ -239,10 +255,18 @@ source-address string Comma-separated list of source addresses
for authentication. Addresses are
specified in CIDR format (nn.nn.nn.nn/nn
or hhhh::hhhh/nn).
If this option is not present then
If this option is not present, then
certificates may be presented from any
source address.
verify-required empty Flag indicating that signatures made
with this certificate must assert FIDO
user verification (e.g. PIN or
biometric). This option only makes sense
for the U2F/FIDO security key types that
support this feature in their signature
formats.
Extensions
----------
......@@ -254,12 +278,22 @@ as is the requirement that each name appear only once.
If an implementation does not recognise an extension, then it should
ignore it.
Custom options should append the originating author or organisation's
domain name to the option name, e.g. "my-option@example.com".
No extensions are defined for host certificates at present. The
supported user certificate extensions and the contents and structure of
their data fields are:
Name Format Description
-----------------------------------------------------------------------------
no-touch-required empty Flag indicating that signatures made
with this certificate need not assert
FIDO user presence. This option only
makes sense for the U2F/FIDO security
key types that support this feature in
their signature formats.
permit-X11-forwarding empty Flag indicating that X11 forwarding
should be permitted. X11 forwarding will
be refused if this option is absent.
......@@ -271,7 +305,7 @@ permit-agent-forwarding empty Flag indicating that agent forwarding
permit-port-forwarding empty Flag indicating that port-forwarding
should be allowed. If this option is
not present then no port forwarding will
not present, then no port forwarding will
be allowed.
permit-pty empty Flag indicating that PTY allocation
......@@ -284,4 +318,4 @@ permit-user-rc empty Flag indicating that execution of
of this script will not be permitted if
this option is not present.
$OpenBSD: PROTOCOL.certkeys,v 1.10 2016/05/03 10:27:59 djm Exp $
$OpenBSD: PROTOCOL.certkeys,v 1.19 2021/06/05 13:47:00 naddy Exp $
......@@ -16,7 +16,7 @@ that computes a 128 bit integrity tag given a message and a single-use
The chacha20-poly1305@openssh.com combines these two primitives into an
authenticated encryption mode. The construction used is based on that
proposed for TLS by Adam Langley in [3], but differs in the layout of
data passed to the MAC and in the addition of encyption of the packet
data passed to the MAC and in the addition of encryption of the packet
lengths.
Negotiation
......@@ -34,7 +34,7 @@ Detailed Construction
The chacha20-poly1305@openssh.com cipher requires 512 bits of key
material as output from the SSH key exchange. This forms two 256 bit
keys (K_1 and K_2), used by two separate instances of chacha20.
The first 256 bits consitute K_2 and the second 256 bits become
The first 256 bits constitute K_2 and the second 256 bits become
K_1.
The instance keyed by K_1 is a stream cipher that is used only
......@@ -103,5 +103,5 @@ References
[3] "ChaCha20 and Poly1305 based Cipher Suites for TLS", Adam Langley
http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03
$OpenBSD: PROTOCOL.chacha20poly1305,v 1.3 2016/05/03 13:10:24 djm Exp $
$OpenBSD: PROTOCOL.chacha20poly1305,v 1.5 2020/02/21 00:04:43 dtucker Exp $
......@@ -11,7 +11,7 @@ an encrypted list of matching private keys.
string ciphername
string kdfname
string kdfoptions
int number of keys N
uint32 number of keys N
string publickey1
string publickey2
...
......@@ -35,18 +35,21 @@ of the cipher block size.
uint32 checkint
uint32 checkint
string privatekey1
byte[] privatekey1
string comment1
string privatekey2
byte[] privatekey2
string comment2
...
string privatekeyN
string commentN
char 1
char 2
char 3
byte 1
byte 2
byte 3
...
char padlen % 255
byte padlen % 255
where each private key is encoded using the same rules as used for
SSH agent.
Before the key is encrypted, a random integer is assigned
to both checkint fields so successful decryption can be
......@@ -65,4 +68,4 @@ For unencrypted keys the cipher "none" and the KDF "none"
are used with empty passphrases. The options if the KDF "none"
are the empty string.
$OpenBSD: PROTOCOL.key,v 1.1 2013/12/06 13:34:54 markus Exp $
$OpenBSD: PROTOCOL.key,v 1.3 2022/07/01 04:45:50 djm Exp $
......@@ -36,6 +36,8 @@ The available section types are:
#define KRL_SECTION_EXPLICIT_KEY 2
#define KRL_SECTION_FINGERPRINT_SHA1 3
#define KRL_SECTION_SIGNATURE 4
#define KRL_SECTION_FINGERPRINT_SHA256 5
#define KRL_SECTION_EXTENSION 255
2. Certificate section
......@@ -63,6 +65,7 @@ The certificate section types are:
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
#define KRL_SECTION_CERT_KEY_ID 0x23
#define KRL_SECTION_CERT_EXTENSION 0x39
2.1 Certificate serial list section
......@@ -113,6 +116,29 @@ associated with a particular identity, e.g. a host or a user.
This section must contain at least one "key_id". This section may appear
multiple times.
2.5. Certificate Extension subsections
This subsection type provides a generic extension mechanism to the
certificates KRL section that may be used to provide optional or critical
data.
Extensions are stored in subsections of type
KRL_SECTION_CERT_EXTENSION with the following contents:
string extension_name
boolean is_critical
string extension_contents.
Where "extension_name" describes the type of extension. It is
recommended that user extensions follow "cert-name@domain.org" naming.
The "is_critical" indicates whether this extension is mandatory or
optional. If true, then any unsupported extension encountered should
result in KRL parsing failure. If false, then it may be safely be
ignored.
The "extension_contents" contains the body of the extension.
3. Explicit key sections
These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys
......@@ -127,25 +153,52 @@ must be a raw key (i.e. not a certificate).
This section may appear multiple times.
4. SHA1 fingerprint sections
4. SHA1/SHA256 fingerprint sections
These sections, identified as KRL_SECTION_FINGERPRINT_SHA1, revoke
plain keys (i.e. not certificates) by listing their SHA1 hashes:
These sections, identified as KRL_SECTION_FINGERPRINT_SHA1 and
KRL_SECTION_FINGERPRINT_SHA256, revoke plain keys (i.e. not
certificates) by listing their hashes:
string public_key_hash[0]
....
This section must contain at least one "public_key_hash". The hash blob
is obtained by taking the SHA1 hash of the public key blob. Hashes in
this section must appear in numeric order, treating each hash as a big-
endian integer.
is obtained by taking the SHA1 or SHA256 hash of the public key blob.
Hashes in this section must appear in numeric order, treating each hash
as a big-endian integer.
This section may appear multiple times.
5. KRL signature sections
5. Extension sections
This section type provides a generic extension mechanism to the KRL
format that may be used to provide optional or critical data.
Extensions are recorded in sections of type KRL_SECTION_EXTENSION
with the following contents:
string extension_name
boolean is_critical
string extension_contents.
Where "extension_name" describes the type of extension. It is
recommended that user extensions follow "name@domain.org" naming.
The "is_critical" indicates whether this extension is mandatory or
optional. If true, then any unsupported extension encountered should
result in KRL parsing failure. If false, then it may be safely be
ignored.
The "extension_contents" contains the body of the extension.
6. KRL signature sections
Note: KRL signatures are not supported by OpenSSH. OpenSSH >= 9.4 will
refuse to load KRLs that contain signatures. We recommend the use
of SSHSIG (`ssh-keygen -Y sign ...`) style signatures for KRLs instead.
The KRL_SECTION_SIGNATURE section serves a different purpose to the
preceeding ones: to provide cryptographic authentication of a KRL that
preceding ones: to provide cryptographic authentication of a KRL that
is retrieved over a channel that does not provide integrity protection.
Its format is slightly different to the previously-described sections:
in order to simplify the signature generation, it includes as a "body"
......@@ -166,4 +219,4 @@ Implementations that retrieve KRLs over untrusted channels must verify
signatures. Signature sections are optional for KRLs distributed by
trusted means.
$OpenBSD: PROTOCOL.krl,v 1.3 2015/01/30 01:10:33 djm Exp $
$OpenBSD: PROTOCOL.krl,v 1.7 2023/07/17 04:01:10 djm Exp $
This document describes the multiplexing protocol used by ssh(1)'s
ControlMaster connection-sharing.
Most messages from the client to the server contain a "request id" field.
This field is returned in replies as "client request id" to facilitate
matching of responses to requests.
Multiplexing starts with a ssh(1) configured to act as a multiplexing
master. This will cause ssh(1) to listen on a Unix domain socket for
requests from clients. Clients communicate over this socket using a
simple packetised protocol, where each message is proceeded with
a length and message type in SSH uint32 wire format:
uint32 packet length
uint32 packet type
... packet body
Most messages from the client to the server contain a "request id"
field. This field is returned in replies as "client request id" to
facilitate matching of responses to requests.
Many multiplexing (mux) client requests yield immediate responses from
the mux process; requesting a forwarding, performing an alive check or
requesting the master terminate itself fall in to this category.
The most common use of multiplexing however is to maintain multiple
concurrent sessions. These are supported via two separate modes:
"Passenger" clients start by requesting a new session with a
MUX_C_NEW_SESSION message and passing stdio file descriptors over the
Unix domain control socket. The passenger client then waits until it is
signaled or the mux server closes the session. This mode is so named as
the client waits around while the mux server does all the driving.
Stdio forwarding (requested using MUX_C_NEW_STDIO_FWD) is another
example of passenger mode; the client passes the stdio file descriptors
and passively waits for something to happen.
"Proxy" clients, requested using MUX_C_PROXY, work quite differently. In
this mode, the mux client/server connection socket will stop speaking
the multiplexing protocol and start proxying SSH connection protocol
messages between the client and server. The client therefore must
speak a significant subset of the SSH protocol, but in return is able
to access basically the full suite of connection protocol features.
Moreover, as no file descriptor passing is required, the connection
supporting a proxy client may itself be forwarded or relayed to another
host if necessary.
1. Connection setup
When a multiplexing connection is made to a ssh(1) operating as a
ControlMaster from a ssh(1) in multiplex slave mode, the first
action of each is to exchange hello messages:
ControlMaster from a client ssh(1), the first action of each is send
a hello messages to its peer:
uint32 MUX_MSG_HELLO
uint32 protocol version
......@@ -17,16 +54,16 @@ action of each is to exchange hello messages:
string extension value [optional]
...
The current version of the mux protocol is 4. A slave should refuse
The current version of the mux protocol is 4. A client should refuse
to connect to a master that speaks an unsupported protocol version.
Following the version identifier are zero or more extensions
represented as a name/value pair. No extensions are currently
defined.
2. Opening sessions
Following the version identifier are zero or more extensions represented
as a name/value pair. No extensions are currently defined.
To open a new multiplexed session, a client may send the following
request:
2. Opening a passenger mode session
To open a new multiplexed session in passenger mode, a client sends the
following request:
uint32 MUX_C_NEW_SESSION
uint32 request id
......@@ -80,7 +117,25 @@ return its local tty to "cooked" mode.
uint32 MUX_S_TTY_ALLOC_FAIL
uint32 session id
3. Health checks
3. Requesting passenger-mode stdio forwarding
A client may request the master to establish a stdio forwarding:
uint32 MUX_C_NEW_STDIO_FWD
uint32 request id
string reserved
string connect host
string connect port
The client then sends its standard input and output file descriptors
(in that order) using Unix domain socket control messages.
The contents of "reserved" are currently ignored.
A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED
or a MUX_S_FAILURE.
4. Health checks
The client may request a health check/PID report from a server:
......@@ -93,7 +148,7 @@ The server replies with:
uint32 client request id
uint32 server pid
4. Remotely terminating a master
5. Remotely terminating a master
A client may request that a master terminate immediately:
......@@ -102,7 +157,7 @@ A client may request that a master terminate immediately:
The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED.
5. Requesting establishment of port forwards
6. Requesting establishment of port forwards
A client may request the master to establish a port forward:
......@@ -131,7 +186,7 @@ For dynamically allocated listen port the server replies with
uint32 client request id
uint32 allocated remote listen port
6. Requesting closure of port forwards
7. Requesting closure of port forwards
Note: currently unimplemented (server will always reply with MUX_S_FAILURE).
......@@ -148,36 +203,45 @@ A client may request the master to close a port forward:
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
MUX_S_FAILURE.
7. Requesting stdio forwarding
8. Requesting shutdown of mux listener
A client may request the master to establish a stdio forwarding:
A client may request the master to stop accepting new multiplexing requests
and remove its listener socket.
uint32 MUX_C_NEW_STDIO_FWD
uint32 MUX_C_STOP_LISTENING
uint32 request id
string reserved
string connect host
string connect port
The client then sends its standard input and output file descriptors
(in that order) using Unix domain socket control messages.
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
MUX_S_FAILURE.
The contents of "reserved" are currently ignored.
9. Requesting proxy mode
A server may reply with a MUX_S_SESSION_OPENED, a MUX_S_PERMISSION_DENIED
or a MUX_S_FAILURE.
A client may request that the control connection be placed in proxy
mode:
8. Requesting shutdown of mux listener
uint32 MUX_C_PROXY
uint32 request id
A client may request the master to stop accepting new multiplexing requests
and remove its listener socket.
When a mux master receives this message, it will reply with a
confirmation:
uint32 MUX_C_STOP_LISTENING
uint32 MUX_S_PROXY
uint32 request id
A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a
MUX_S_FAILURE.
And go into proxy mode. All subsequent data over the connection will
be formatted as unencrypted, unpadded, SSH transport messages:
uint32 packet length
byte 0 (padding length)
byte packet type
byte[packet length - 2] ...
9. Status messages
The mux master will accept most connection messages and global requests,
and will translate channel identifiers to ensure that the proxy client has
globally unique channel numbers (i.e. a proxy client need not worry about
collisions with other clients).
10. Status messages
The MUX_S_OK message is empty:
......@@ -194,7 +258,7 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason:
uint32 client request id
string reason
10. Protocol numbers
11. Protocol numbers
#define MUX_MSG_HELLO 0x00000001
#define MUX_C_NEW_SESSION 0x10000002
......@@ -224,5 +288,11 @@ XXX watch in/out traffic (pre/post crypto)
XXX inject packet (what about replies)
XXX server->client error/warning notifications
XXX send signals via mux
$OpenBSD: PROTOCOL.mux,v 1.10 2015/07/17 03:04:27 djm Exp $
XXX ^Z support in passengers
XXX extensions for multi-agent
XXX extensions for multi-X11
XXX session inspection via master
XXX signals via mux request
XXX list active connections via mux
$OpenBSD: PROTOCOL.mux,v 1.13 2022/01/01 01:55:30 jsg Exp $
This document describes a lightweight SSH Signature format
that is compatible with SSH keys and wire formats.
At present, only detached and armored signatures are supported.
1. Armored format
The Armored SSH signatures consist of a header, a base64
encoded blob, and a footer.
The header is the string "-----BEGIN SSH SIGNATURE-----"
followed by a newline. The footer is the string
"-----END SSH SIGNATURE-----" immediately after a newline.
The header MUST be present at the start of every signature.
Files containing the signature MUST start with the header.
Likewise, the footer MUST be present at the end of every
signature.
The base64 encoded blob SHOULD be broken up by newlines
every 76 characters.
Example:
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgJKxoLBJBivUPNTUJUSslQTt2hD
jozKvHarKeN8uYFqgAAAADZm9vAAAAAAAAAFMAAAALc3NoLWVkMjU1MTkAAABAKNC4IEbt
Tq0Fb56xhtuE1/lK9H9RZJfON4o6hE9R4ZGFX98gy0+fFJ/1d2/RxnZky0Y7GojwrZkrHT
FgCqVWAQ==
-----END SSH SIGNATURE-----
2. Blob format
#define MAGIC_PREAMBLE "SSHSIG"
#define SIG_VERSION 0x01
byte[6] MAGIC_PREAMBLE
uint32 SIG_VERSION
string publickey
string namespace
string reserved
string hash_algorithm
string signature
The publickey field MUST contain the serialisation of the
public key used to make the signature using the usual SSH
encoding rules, i.e RFC4253, RFC5656,
draft-ietf-curdle-ssh-ed25519-ed448, etc.
Verifiers MUST reject signatures with versions greater than those
they support.
The purpose of the namespace value is to specify a unambiguous
interpretation domain for the signature, e.g. file signing.
This prevents cross-protocol attacks caused by signatures
intended for one intended domain being accepted in another.
The namespace value MUST NOT be the empty string.
The reserved value is present to encode future information
(e.g. tags) into the signature. Implementations should ignore
the reserved field if it is not empty.
Data to be signed is first hashed with the specified hash_algorithm.
This is done to limit the amount of data presented to the signature
operation, which may be of concern if the signing key is held in limited
or slow hardware or on a remote ssh-agent. The supported hash algorithms
are "sha256" and "sha512".
The signature itself is made using the SSH signature algorithm and
encoding rules for the chosen key type. For RSA signatures, the
signature algorithm must be "rsa-sha2-512" or "rsa-sha2-256" (i.e.
not the legacy RSA-SHA1 "ssh-rsa").
This blob is encoded as a string using the RFC4253 encoding
rules and base64 encoded to form the middle part of the
armored signature.
3. Signed Data, of which the signature goes into the blob above
#define MAGIC_PREAMBLE "SSHSIG"
byte[6] MAGIC_PREAMBLE
string namespace
string reserved
string hash_algorithm
string H(message)
The preamble is the six-byte sequence "SSHSIG". It is included to
ensure that manual signatures can never be confused with any message
signed during SSH user or host authentication.
The reserved value is present to encode future information
(e.g. tags) into the signature. Implementations should ignore
the reserved field if it is not empty.
The data is concatenated and passed to the SSH signing
function.
$OpenBSD: PROTOCOL.sshsig,v 1.4 2020/08/31 00:17:41 djm Exp $
This diff is collapsed. Click to expand it.
See https://www.openssh.com/releasenotes.html#7.5p1 for the release notes.
See https://www.openssh.com/releasenotes.html#9.6p1 for the release
notes.
Please read https://www.openssh.com/report.html for bug reporting
instructions and note that we do not use Github for bug reporting or
patch/pull-request management.
- A Japanese translation of this document and of the release notes is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
- Thanks to HARUYAMA Seigo <haruyama@unixuser.org>
This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other
Unices.
......@@ -19,10 +16,10 @@ Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt,
and Dug Song. It has a homepage at https://www.openssh.com/
This port consists of the re-introduction of autoconf support, PAM
support, EGD[1]/PRNGD[2] support and replacements for OpenBSD library
support, EGD/PRNGD support and replacements for OpenBSD library
functions that are (regrettably) absent from other unices. This port
has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X,
NetBSD, OpenBSD, OpenServer, Solaris, Unicos, and UnixWare.
FreeBSD, NetBSD, OpenBSD, OpenServer, Solaris and UnixWare.
This version actively tracks changes in the OpenBSD CVS repository.
......@@ -30,35 +27,27 @@ The PAM support is now more functional than the popular packages of
commercial ssh-1.2.x. It checks "account" and "session" modules for
all logins, not just when using password authentication.
OpenSSH depends on Zlib[3], OpenSSL[4] and optionally PAM[5].
There is now several mailing lists for this port of OpenSSH. Please
refer to https://www.openssh.com/list.html for details on how to join.
Please send bug reports and patches to the mailing list
openssh-unix-dev@mindrot.org. The list is open to posting by unsubscribed
users. Code contribution are welcomed, but please follow the OpenBSD
style guidelines[6].
Please send bug reports and patches to https://bugzilla.mindrot.org or
the mailing list openssh-unix-dev@mindrot.org. To mitigate spam, the
list only allows posting from subscribed addresses. Code contribution
are welcomed, but please follow the OpenBSD style guidelines[1].
Please refer to the INSTALL document for information on how to install
OpenSSH on your system.
Please refer to the INSTALL document for information on dependencies and
how to install OpenSSH on your system.
Damien Miller <djm@mindrot.org>
Miscellania -
This version of OpenSSH is based upon code retrieved from the OpenBSD
CVS repository which in turn was based on the last free sample
implementation released by Tatu Ylonen.
This version of OpenSSH is based upon code retrieved from the OpenBSD CVS
repository which in turn was based on the last free sample implementation
released by Tatu Ylonen.
References -
[0] https://www.openssh.com/
[1] http://www.lothar.com/tech/crypto/
[2] http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html
[3] http://www.gzip.org/zlib/
[4] http://www.openssl.org/
[5] http://www.openpam.org
http://www.kernel.org/pub/linux/libs/pam/
(PAM also is standard on Solaris and HP-UX 11)
[6] http://man.openbsd.org/style.9
[1] https://man.openbsd.org/style.9
How to verify host keys using OpenSSH and DNS
---------------------------------------------
OpenSSH contains support for verifying host keys using DNS as described in
draft-ietf-secsh-dns-05.txt. The document contains very brief instructions
on how to use this feature. Configuring DNS is out of the scope of this
document.
OpenSSH contains support for verifying host keys using DNS as described
in https://tools.ietf.org/html/rfc4255. The document contains very brief
instructions on how to use this feature. Configuring DNS is out of the
scope of this document.
(1) Server: Generate and publish the DNS RR
......
# Portable OpenSSH
[![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)
[![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)
OpenSSH is a complete implementation of the SSH protocol (version 2) for secure remote login, command execution and file transfer. It includes a client ``ssh`` and server ``sshd``, file transfer utilities ``scp`` and ``sftp`` as well as tools for key generation (``ssh-keygen``), run-time key storage (``ssh-agent``) and a number of supporting programs.
This is a port of OpenBSD's [OpenSSH](https://openssh.com) to most Unix-like operating systems, including Linux, OS X and Cygwin. Portable OpenSSH polyfills OpenBSD APIs that are not available elsewhere, adds sshd sandboxing for more operating systems and includes support for OS-native authentication and auditing (e.g. using PAM).
## Documentation
The official documentation for OpenSSH are the man pages for each tool:
* [ssh(1)](https://man.openbsd.org/ssh.1)
* [sshd(8)](https://man.openbsd.org/sshd.8)
* [ssh-keygen(1)](https://man.openbsd.org/ssh-keygen.1)
* [ssh-agent(1)](https://man.openbsd.org/ssh-agent.1)
* [scp(1)](https://man.openbsd.org/scp.1)
* [sftp(1)](https://man.openbsd.org/sftp.1)
* [ssh-keyscan(8)](https://man.openbsd.org/ssh-keyscan.8)
* [sftp-server(8)](https://man.openbsd.org/sftp-server.8)
## Stable Releases
Stable release tarballs are available from a number of [download mirrors](https://www.openssh.com/portable.html#downloads). We recommend the use of a stable release for most users. Please read the [release notes](https://www.openssh.com/releasenotes.html) for details of recent changes and potential incompatibilities.
## Building Portable OpenSSH
### Dependencies
Portable OpenSSH is built using autoconf and make. It requires a working C compiler, standard library and headers.
``libcrypto`` from either [LibreSSL](https://www.libressl.org/) or [OpenSSL](https://www.openssl.org) may also be used. OpenSSH may be built without either of these, but the resulting binaries will have only a subset of the cryptographic algorithms normally available.
[zlib](https://www.zlib.net/) is optional; without it transport compression is not supported.
FIDO security token support needs [libfido2](https://github.com/Yubico/libfido2) and its dependencies and will be enabled automatically if they are found.
In addition, certain platforms and build-time options may require additional dependencies; see README.platform for details about your platform.
### Building a release
Releases include a pre-built copy of the ``configure`` script and may be built using:
```
tar zxvf openssh-X.YpZ.tar.gz
cd openssh
./configure # [options]
make && make tests
```
See the [Build-time Customisation](#build-time-customisation) section below for configure options. If you plan on installing OpenSSH to your system, then you will usually want to specify destination paths.
### Building from git
If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git:
```
git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git
cd openssh-portable
autoreconf
./configure
make && make tests
```
### Build-time Customisation
There are many build-time customisation options available. All Autoconf destination path flags (e.g. ``--prefix``) are supported (and are usually required if you want to install OpenSSH).
For a full list of available flags, run ``./configure --help`` but a few of the more frequently-used ones are described below. Some of these flags will require additional libraries and/or headers be installed.
Flag | Meaning
--- | ---
``--with-pam`` | Enable [PAM](https://en.wikipedia.org/wiki/Pluggable_authentication_module) support. [OpenPAM](https://www.openpam.org/), [Linux PAM](http://www.linux-pam.org/) and Solaris PAM are supported.
``--with-libedit`` | Enable [libedit](https://www.thrysoee.dk/editline/) support for sftp.
``--with-kerberos5`` | Enable Kerberos/GSSAPI support. Both [Heimdal](https://www.h5l.org/) and [MIT](https://web.mit.edu/kerberos/) Kerberos implementations are supported.
``--with-selinux`` | Enable [SELinux](https://en.wikipedia.org/wiki/Security-Enhanced_Linux) support.
## Development
Portable OpenSSH development is discussed on the [openssh-unix-dev mailing list](https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev) ([archive mirror](https://marc.info/?l=openssh-unix-dev)). Bugs and feature requests are tracked on our [Bugzilla](https://bugzilla.mindrot.org/).
## Reporting bugs
_Non-security_ bugs may be reported to the developers via [Bugzilla](https://bugzilla.mindrot.org/) or via the mailing list above. Security bugs should be reported to [openssh@openssh.com](mailto:openssh.openssh.com).
This file contains notes about OpenSSH on specific platforms.
AIX
---
As of OpenSSH 3.8p1, sshd will now honour an accounts password expiry
settings, where previously it did not. Because of this, it's possible for
sites that have used OpenSSH's sshd exclusively to have accounts which
have passwords expired longer than the inactive time (ie the "Weeks between
password EXPIRATION and LOCKOUT" setting in SMIT or the maxexpired
chuser attribute).
Beginning with OpenSSH 3.8p1, sshd will honour an account's password
expiry settings, where prior to that it did not. Because of this,
it's possible for sites that have used OpenSSH's sshd exclusively to
have accounts which have passwords expired longer than the inactive time
(ie the "Weeks between password EXPIRATION and LOCKOUT" setting in SMIT
or the maxexpired chuser attribute).
Accounts in this state must have their passwords reset manually by the
administrator. As a precaution, it is recommended that the administrative
passwords be reset before upgrading from OpenSSH <3.8.
As of OpenSSH 4.0, configure will attempt to detect if your version
As of OpenSSH 4.0p1, configure will attempt to detect if your version
and maintenance level of AIX has a working getaddrinfo, and will use it
if found. This will enable IPv6 support. If for some reason configure
gets it wrong, or if you want to build binaries to work on earlier MLs
......@@ -80,7 +80,7 @@ added to /etc/security/audit_event:
32800:AUE_openssh:OpenSSH login:lo
The BSM audit event range available for third party TCB applications is
32768 - 65535. Event number 32800 has been choosen for AUE_openssh.
32768 - 65535. Event number 32800 has been chosen for AUE_openssh.
There is no official registry of 3rd party event numbers, so if this
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.
......
......@@ -5,13 +5,10 @@ escalation by containing corruption to an unprivileged process.
More information is available at:
http://www.citi.umich.edu/u/provos/ssh/privsep.html
Privilege separation is now enabled by default; see the
UsePrivilegeSeparation option in sshd_config(5).
When privsep is enabled, during the pre-authentication phase sshd will
chroot(2) to "/var/empty" and change its privileges to the "sshd" user
and its primary group. sshd is a pseudo-account that should not be
used by other daemons, and must be locked and should contain a
Privilege separation is now mandatory. During the pre-authentication
phase sshd will chroot(2) to "/var/empty" and change its privileges to the
"sshd" user and its primary group. sshd is a pseudo-account that should
not be used by other daemons, and must be locked and should contain a
"nologin" or invalid shell.
You should do something like the following to prepare the privsep
......@@ -34,8 +31,8 @@ privsep user and chroot directory:
PAM-enabled OpenSSH is known to function with privsep on AIX, FreeBSD,
HP-UX (including Trusted Mode), Linux, NetBSD and Solaris.
On Cygwin, Tru64 Unix, OpenServer, and Unicos only the pre-authentication
part of privsep is supported. Post-authentication privsep is disabled
On Cygwin, Tru64 Unix and OpenServer only the pre-authentication part
of privsep is supported. Post-authentication privsep is disabled
automatically (so you won't see the additional process mentioned below).
Note that for a normal interactive login with a shell, enabling privsep
......
# Reporting OpenSSH Security Issues
To report security issues in OpenSSH, please refer to our website
[OpenSSH Security](https://www.openssh.com/security.html).
......@@ -35,7 +35,7 @@ Programming:
- Use different PAM service name for kbdint vs regular auth (suggest from
Solar Designer)
- Ability to select which ChallengeResponseAuthentications may be used
and order to try them in e.g. "ChallengeResponseAuthentication skey, pam"
and order to try them in e.g. "ChallengeResponseAuthentication pam"
- Complete Tru64 SIA support
- It looks like we could merge it into the password auth code to cut down
......@@ -57,10 +57,10 @@ Clean up configure/makefiles:
- Replace the whole u_intXX_t evilness in acconfig.h with something better???
- Do it in configure.ac
- Consider splitting the u_intXX_t test for sys/bitype.h into seperate test
- Consider splitting the u_intXX_t test for sys/bitype.h into separate test
to allow people to (right/wrongfully) link against Bind directly.
- Consider splitting configure.ac into seperate files which do logically
- Consider splitting configure.ac into separate files which do logically
similar tests. E.g move all the type detection stuff into one file,
entropy related stuff into another.
......
dnl OpenSSH-specific autoconf macros
dnl
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag])
dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
dnl 'check_flag'.
AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{
AC_MSG_CHECKING([if $CC supports compile flag $1])
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $WERROR $1"
_define_flag="$2"
test "x$_define_flag" = "x" && _define_flag="$1"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
/* Some math to catch -ftrapv problems in the toolchain */
int i = 123 * argc, j = 456 + argc, k = 789 - argc;
float l = i * 2.1;
double m = l / 0.5;
long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
printf("%d %d %d %f %f %lld %lld\n", i, j, k, l, m, n, o);
exit(0);
}
]])],
[
if `grep -i "unrecognized option" conftest.err >/dev/null`
then
AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS"
else
AC_MSG_RESULT([yes])
CFLAGS="$saved_CFLAGS $_define_flag"
fi],
[ AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS" ]
)
}])
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
dnl OSSH_CHECK_CFLAG_LINK(check_flag[, define_flag])
dnl Check that $CC accepts a flag 'check_flag'. If it is supported append
dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append
dnl 'check_flag'.
AC_DEFUN([OSSH_CHECK_CFLAG_LINK], [{
AC_MSG_CHECKING([if $CC supports compile flag $1 and linking succeeds])
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $WERROR $1"
_define_flag="$2"
test "x$_define_flag" = "x" && _define_flag="$1"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
/* Some math to catch -ftrapv problems in the toolchain */
int i = 123 * argc, j = 456 + argc, k = 789 - argc;
float l = i * 2.1;
double m = l / 0.5;
long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
long long int p = n * o;
printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
exit(0);
}
]])],
[
if `grep -i "unrecognized option" conftest.err >/dev/null`
then
AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS"
else
AC_MSG_RESULT([yes])
CFLAGS="$saved_CFLAGS $_define_flag"
fi],
[ AC_MSG_RESULT([no])
CFLAGS="$saved_CFLAGS" ]
)
}])
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
dnl OSSH_CHECK_LDFLAG_LINK(check_flag[, define_flag])
dnl Check that $LD accepts a flag 'check_flag'. If it is supported append
dnl 'define_flag' to $LDFLAGS. If 'define_flag' is not specified, then append
dnl 'check_flag'.
AC_DEFUN([OSSH_CHECK_LDFLAG_LINK], [{
AC_MSG_CHECKING([if $LD supports link flag $1])
saved_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $WERROR $1"
_define_flag="$2"
test "x$_define_flag" = "x" && _define_flag="$1"
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
/* Some math to catch -ftrapv problems in the toolchain */
int i = 123 * argc, j = 456 + argc, k = 789 - argc;
float l = i * 2.1;
double m = l / 0.5;
long long int n = argc * 12345LL, o = 12345LL * (long long int)argc;
long long p = n * o;
printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p);
exit(0);
}
]])],
[ AC_MSG_RESULT([yes])
LDFLAGS="$saved_LDFLAGS $_define_flag"],
[ AC_MSG_RESULT([no])
LDFLAGS="$saved_LDFLAGS" ]
)
}])
dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol)
dnl Does AC_EGREP_HEADER on 'header' for the string 'field'
dnl If found, set 'symbol' to be defined. Cache the result.
dnl TODO: This is not foolproof, better to compile and read from there
AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [
# look for field '$1' in header '$2'
dnl This strips characters illegal to m4 from the header filename
ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'`
dnl
ossh_varname="ossh_cv_$ossh_safe""_has_"$1
AC_MSG_CHECKING(for $1 field in $2)
AC_CACHE_VAL($ossh_varname, [
AC_EGREP_HEADER($1, $2, [ dnl
eval "$ossh_varname=yes" dnl
], [ dnl
eval "$ossh_varname=no" dnl
]) dnl
])
ossh_result=`eval 'echo $'"$ossh_varname"`
if test -n "`echo $ossh_varname`"; then
AC_MSG_RESULT($ossh_result)
if test "x$ossh_result" = "xyes"; then
AC_DEFINE($3, 1, [Define if you have $1 in $2])
fi
else
AC_MSG_RESULT(no)
fi
])
dnl Check for socklen_t: historically on BSD it is an int, and in
dnl POSIX 1g it is a type of its own, but some platforms use different
dnl types for the argument to getsockopt, getpeername, etc. So we
dnl have to test to find something that will work.
AC_DEFUN([TYPE_SOCKLEN_T],
[
AC_CHECK_TYPE([socklen_t], ,[
AC_MSG_CHECKING([for socklen_t equivalent])
AC_CACHE_VAL([curl_cv_socklen_t_equiv],
[
# Systems have either "struct sockaddr *" or
# "void *" as the second argument to getpeername
curl_cv_socklen_t_equiv=
for arg2 in "struct sockaddr" void; do
for t in int size_t unsigned long "unsigned long"; do
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
int getpeername (int, $arg2 *, $t *);
],[
$t len;
getpeername(0,0,&len);
],[
curl_cv_socklen_t_equiv="$t"
break
])
done
done
if test "x$curl_cv_socklen_t_equiv" = x; then
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
fi
])
AC_MSG_RESULT($curl_cv_socklen_t_equiv)
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
[type to use in place of socklen_t if not defined])],
[#include <sys/types.h>
#include <sys/socket.h>])
])
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
m4_include([m4/openssh.m4])
This diff is collapsed. Click to expand it.
/*
* Copyright (c) 2004,2005 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Address handling routines */
#ifndef _ADDR_H
#define _ADDR_H
#include <sys/socket.h>
#include <netinet/in.h>
struct xaddr {
sa_family_t af;
union {
struct in_addr v4;
struct in6_addr v6;
u_int8_t addr8[16];
u_int16_t addr16[8];
u_int32_t addr32[4];
} xa; /* 128-bit address */
u_int32_t scope_id; /* iface scope id for v6 */
#define v4 xa.v4
#define v6 xa.v6
#define addr8 xa.addr8
#define addr16 xa.addr16
#define addr32 xa.addr32
};
int addr_unicast_masklen(int af);
int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa,
socklen_t *len, u_int16_t port);
int addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa);
int addr_netmask(int af, u_int l, struct xaddr *n);
int addr_hostmask(int af, u_int l, struct xaddr *n);
int addr_invert(struct xaddr *n);
int addr_pton(const char *p, struct xaddr *n);
int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa,
socklen_t slen);
int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l);
int addr_ntop(const struct xaddr *n, char *p, size_t len);
int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b);
int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b);
int addr_cmp(const struct xaddr *a, const struct xaddr *b);
int addr_is_all0s(const struct xaddr *n);
int addr_host_is_all0s(const struct xaddr *n, u_int masklen);
int addr_host_to_all0s(struct xaddr *a, u_int masklen);
int addr_host_to_all1s(struct xaddr *a, u_int masklen);
int addr_netmatch(const struct xaddr *host, const struct xaddr *net,
u_int masklen);
void addr_increment(struct xaddr *a);
#endif /* _ADDR_H */
/* $OpenBSD: addrmatch.c,v 1.13 2016/09/21 16:55:42 djm Exp $ */
/* $OpenBSD: addrmatch.c,v 1.17 2021/04/03 06:18:40 djm Exp $ */
/*
* Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org>
......@@ -29,338 +29,10 @@
#include <stdio.h>
#include <stdarg.h>
#include "addr.h"
#include "match.h"
#include "log.h"
struct xaddr {
sa_family_t af;
union {
struct in_addr v4;
struct in6_addr v6;
u_int8_t addr8[16];
u_int32_t addr32[4];
} xa; /* 128-bit address */
u_int32_t scope_id; /* iface scope id for v6 */
#define v4 xa.v4
#define v6 xa.v6
#define addr8 xa.addr8
#define addr32 xa.addr32
};
static int
addr_unicast_masklen(int af)
{
switch (af) {
case AF_INET:
return 32;
case AF_INET6:
return 128;
default:
return -1;
}
}
static inline int
masklen_valid(int af, u_int masklen)
{
switch (af) {
case AF_INET:
return masklen <= 32 ? 0 : -1;
case AF_INET6:
return masklen <= 128 ? 0 : -1;
default:
return -1;
}
}
/*
* Convert struct sockaddr to struct xaddr
* Returns 0 on success, -1 on failure.
*/
static int
addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa)
{
struct sockaddr_in *in4 = (struct sockaddr_in *)sa;
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
memset(xa, '\0', sizeof(*xa));
switch (sa->sa_family) {
case AF_INET:
if (slen < (socklen_t)sizeof(*in4))
return -1;
xa->af = AF_INET;
memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4));
break;
case AF_INET6:
if (slen < (socklen_t)sizeof(*in6))
return -1;
xa->af = AF_INET6;
memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6));
#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
xa->scope_id = in6->sin6_scope_id;
#endif
break;
default:
return -1;
}
return 0;
}
/*
* Calculate a netmask of length 'l' for address family 'af' and
* store it in 'n'.
* Returns 0 on success, -1 on failure.
*/
static int
addr_netmask(int af, u_int l, struct xaddr *n)
{
int i;
if (masklen_valid(af, l) != 0 || n == NULL)
return -1;
memset(n, '\0', sizeof(*n));
switch (af) {
case AF_INET:
n->af = AF_INET;
if (l == 0)
return 0;
n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff);
return 0;
case AF_INET6:
n->af = AF_INET6;
for (i = 0; i < 4 && l >= 32; i++, l -= 32)
n->addr32[i] = 0xffffffffU;
if (i < 4 && l != 0)
n->addr32[i] = htonl((0xffffffff << (32 - l)) &
0xffffffff);
return 0;
default:
return -1;
}
}
/*
* Perform logical AND of addresses 'a' and 'b', storing result in 'dst'.
* Returns 0 on success, -1 on failure.
*/
static int
addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b)
{
int i;
if (dst == NULL || a == NULL || b == NULL || a->af != b->af)
return -1;
memcpy(dst, a, sizeof(*dst));
switch (a->af) {
case AF_INET:
dst->v4.s_addr &= b->v4.s_addr;
return 0;
case AF_INET6:
dst->scope_id = a->scope_id;
for (i = 0; i < 4; i++)
dst->addr32[i] &= b->addr32[i];
return 0;
default:
return -1;
}
}
/*
* Compare addresses 'a' and 'b'
* Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b)
*/
static int
addr_cmp(const struct xaddr *a, const struct xaddr *b)
{
int i;
if (a->af != b->af)
return a->af == AF_INET6 ? 1 : -1;
switch (a->af) {
case AF_INET:
if (a->v4.s_addr == b->v4.s_addr)
return 0;
return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1;
case AF_INET6:
for (i = 0; i < 16; i++)
if (a->addr8[i] - b->addr8[i] != 0)
return a->addr8[i] > b->addr8[i] ? 1 : -1;
if (a->scope_id == b->scope_id)
return 0;
return a->scope_id > b->scope_id ? 1 : -1;
default:
return -1;
}
}
/*
* Parse string address 'p' into 'n'
* Returns 0 on success, -1 on failure.
*/
static int
addr_pton(const char *p, struct xaddr *n)
{
struct addrinfo hints, *ai;
memset(&hints, '\0', sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0)
return -1;
if (ai == NULL || ai->ai_addr == NULL)
return -1;
if (n != NULL &&
addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) {
freeaddrinfo(ai);
return -1;
}
freeaddrinfo(ai);
return 0;
}
/*
* Perform bitwise negation of address
* Returns 0 on success, -1 on failure.
*/
static int
addr_invert(struct xaddr *n)
{
int i;
if (n == NULL)
return (-1);
switch (n->af) {
case AF_INET:
n->v4.s_addr = ~n->v4.s_addr;
return (0);
case AF_INET6:
for (i = 0; i < 4; i++)
n->addr32[i] = ~n->addr32[i];
return (0);
default:
return (-1);
}
}
/*
* Calculate a netmask of length 'l' for address family 'af' and
* store it in 'n'.
* Returns 0 on success, -1 on failure.
*/
static int
addr_hostmask(int af, u_int l, struct xaddr *n)
{
if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1)
return (-1);
return (0);
}
/*
* Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::)
* Returns 0 on if address is all-zeros, -1 if not all zeros or on failure.
*/
static int
addr_is_all0s(const struct xaddr *a)
{
int i;
switch (a->af) {
case AF_INET:
return (a->v4.s_addr == 0 ? 0 : -1);
case AF_INET6:;
for (i = 0; i < 4; i++)
if (a->addr32[i] != 0)
return (-1);
return (0);
default:
return (-1);
}
}
/*
* Test whether host portion of address 'a', as determined by 'masklen'
* is all zeros.
* Returns 0 on if host portion of address is all-zeros,
* -1 if not all zeros or on failure.
*/
static int
addr_host_is_all0s(const struct xaddr *a, u_int masklen)
{
struct xaddr tmp_addr, tmp_mask, tmp_result;
memcpy(&tmp_addr, a, sizeof(tmp_addr));
if (addr_hostmask(a->af, masklen, &tmp_mask) == -1)
return (-1);
if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1)
return (-1);
return (addr_is_all0s(&tmp_result));
}
/*
* Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z).
* Return -1 on parse error, -2 on inconsistency or 0 on success.
*/
static int
addr_pton_cidr(const char *p, struct xaddr *n, u_int *l)
{
struct xaddr tmp;
long unsigned int masklen = 999;
char addrbuf[64], *mp, *cp;
/* Don't modify argument */
if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf))
return -1;
if ((mp = strchr(addrbuf, '/')) != NULL) {
*mp = '\0';
mp++;
masklen = strtoul(mp, &cp, 10);
if (*mp == '\0' || *cp != '\0' || masklen > 128)
return -1;
}
if (addr_pton(addrbuf, &tmp) == -1)
return -1;
if (mp == NULL)
masklen = addr_unicast_masklen(tmp.af);
if (masklen_valid(tmp.af, masklen) == -1)
return -2;
if (addr_host_is_all0s(&tmp, masklen) != 0)
return -2;
if (n != NULL)
memcpy(n, &tmp, sizeof(*n));
if (l != NULL)
*l = masklen;
return 0;
}
static int
addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen)
{
struct xaddr tmp_mask, tmp_result;
if (host->af != net->af)
return -1;
if (addr_netmask(host->af, masklen, &tmp_mask) == -1)
return -1;
if (addr_and(&tmp_result, host, &tmp_mask) == -1)
return -1;
return addr_cmp(&tmp_result, net);
}
/*
* Match "addr" against list pattern list "_list", which may contain a
* mix of CIDR addresses and old-school wildcards.
......@@ -382,7 +54,7 @@ addr_match_list(const char *addr, const char *_list)
int ret = 0, r;
if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
debug2("%s: couldn't parse address %.100s", __func__, addr);
debug2_f("couldn't parse address %.100s", addr);
return 0;
}
if ((o = list = strdup(_list)) == NULL)
......@@ -398,13 +70,13 @@ addr_match_list(const char *addr, const char *_list)
/* Prefer CIDR address matching */
r = addr_pton_cidr(cp, &match_addr, &masklen);
if (r == -2) {
debug2("%s: inconsistent mask length for "
"match network \"%.100s\"", __func__, cp);
debug2_f("inconsistent mask length for "
"match network \"%.100s\"", cp);
ret = -2;
break;
} else if (r == 0) {
if (addr != NULL && addr_netmatch(&try_addr,
&match_addr, masklen) == 0) {
&match_addr, masklen) == 0) {
foundit:
if (neg) {
ret = -1;
......@@ -442,15 +114,14 @@ addr_match_cidr_list(const char *addr, const char *_list)
int ret = 0, r;
if (addr != NULL && addr_pton(addr, &try_addr) != 0) {
debug2("%s: couldn't parse address %.100s", __func__, addr);
debug2_f("couldn't parse address %.100s", addr);
return 0;
}
if ((o = list = strdup(_list)) == NULL)
return -1;
while ((cp = strsep(&list, ",")) != NULL) {
if (*cp == '\0') {
error("%s: empty entry in list \"%.100s\"",
__func__, o);
error_f("empty entry in list \"%.100s\"", o);
ret = -1;
break;
}
......@@ -463,15 +134,14 @@ addr_match_cidr_list(const char *addr, const char *_list)
/* Stop junk from reaching getaddrinfo. +3 is for masklen */
if (strlen(cp) > INET6_ADDRSTRLEN + 3) {
error("%s: list entry \"%.100s\" too long",
__func__, cp);
error_f("list entry \"%.100s\" too long", cp);
ret = -1;
break;
}
#define VALID_CIDR_CHARS "0123456789abcdefABCDEF.:/"
if (strspn(cp, VALID_CIDR_CHARS) != strlen(cp)) {
error("%s: list entry \"%.100s\" contains invalid "
"characters", __func__, cp);
error_f("list entry \"%.100s\" contains invalid "
"characters", cp);
ret = -1;
}
......
/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm Exp $ */
/* $OpenBSD: atomicio.c,v 1.30 2019/01/24 02:42:23 dtucker Exp $ */
/*
* Copyright (c) 2006 Damien Miller. All rights reserved.
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
......@@ -28,7 +28,6 @@
#include "includes.h"
#include <sys/param.h>
#include <sys/uio.h>
#include <errno.h>
......@@ -57,20 +56,25 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
ssize_t res;
struct pollfd pfd;
#ifndef BROKEN_READ_COMPARISON
pfd.fd = fd;
#ifndef BROKEN_READ_COMPARISON
pfd.events = f == read ? POLLIN : POLLOUT;
#else
pfd.events = POLLIN|POLLOUT;
#endif
while (n > pos) {
res = (f) (fd, s + pos, n - pos);
switch (res) {
case -1:
if (errno == EINTR)
if (errno == EINTR) {
/* possible SIGALARM, update callback */
if (cb != NULL && cb(cb_arg, 0) == -1) {
errno = EINTR;
return pos;
}
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
#ifndef BROKEN_READ_COMPARISON
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1);
#endif
continue;
}
return 0;
......@@ -114,20 +118,25 @@ atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd,
/* Make a copy of the iov array because we may modify it below */
memcpy(iov, _iov, (size_t)iovcnt * sizeof(*_iov));
#ifndef BROKEN_READV_COMPARISON
pfd.fd = fd;
#ifndef BROKEN_READV_COMPARISON
pfd.events = f == readv ? POLLIN : POLLOUT;
#else
pfd.events = POLLIN|POLLOUT;
#endif
for (; iovcnt > 0 && iov[0].iov_len > 0;) {
res = (f) (fd, iov, iovcnt);
switch (res) {
case -1:
if (errno == EINTR)
if (errno == EINTR) {
/* possible SIGALARM, update callback */
if (cb != NULL && cb(cb_arg, 0) == -1) {
errno = EINTR;
return pos;
}
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
#ifndef BROKEN_READV_COMPARISON
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1);
#endif
continue;
}
return 0;
......
/* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm Exp $ */
/* $OpenBSD: atomicio.h,v 1.12 2018/12/27 03:25:25 djm Exp $ */
/*
* Copyright (c) 2006 Damien Miller. All rights reserved.
......@@ -29,6 +29,8 @@
#ifndef _ATOMICIO_H
#define _ATOMICIO_H
struct iovec;
/*
* Ensure all of data on socket comes through. f==read || f==vwrite
*/
......
......@@ -49,7 +49,6 @@
#include "ssh.h"
#include "log.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "xmalloc.h"
......@@ -130,7 +129,7 @@ static AuditInfoTermID ssh_bsm_tid;
* getaudit_addr() is only present on IPv6 capable machines.
*/
#if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR)
extern int aug_get_machine(char *, u_int32_t *, u_int32_t *);
extern int aug_get_machine(char *, u_int32_t *, u_int32_t *);
#else
static int
aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type)
......@@ -184,41 +183,41 @@ getacna(char *auditstring, int len)
scf_value_t *value = NULL;
int ret = 0;
/*
* The man page for getacna on Solaris 10 states we should return -2
* in case of error and set errno to indicate the error. We don't
* bother with errno here, though, since the only use of this function
* below doesn't check for errors anyway.
*/
handle = scf_handle_create(SCF_VERSION);
if (handle == NULL)
return -2; /* The man page for getacna on Solaris 10 states
we should return -2 in case of error and set
errno to indicate the error. We don't bother
with errno here, though, since the only use
of this function below doesn't check for errors
anyway.
*/
return -2;
ret = scf_handle_bind(handle);
if (ret == -1)
return -2;
return -2;
property = scf_property_create(handle);
if (property == NULL)
return -2;
return -2;
ret = scf_handle_decode_fmri(handle,
"svc:/system/auditd:default/:properties/preselection/naflags",
NULL, NULL, NULL, NULL, property, 0);
"svc:/system/auditd:default/:properties/preselection/naflags",
NULL, NULL, NULL, NULL, property, 0);
if (ret == -1)
return -2;
return -2;
value = scf_value_create(handle);
if (value == NULL)
return -2;
return -2;
ret = scf_property_get_value(property, value);
if (ret == -1)
return -2;
return -2;
ret = scf_value_get_astring(value, auditstring, len);
if (ret == -1)
return -2;
return -2;
scf_value_destroy(value);
scf_property_destroy(property);
......@@ -281,9 +280,10 @@ bsm_audit_record(int typ, char *string, au_event_t event_no)
(void) au_write(ad, AUToReturnFunc(typ, rc));
#ifdef BROKEN_BSM_API
/* The last argument is the event modifier flags. For
some seemingly undocumented reason it was added in
Solaris 11. */
/*
* The last argument is the event modifier flags. For some seemingly
* undocumented reason it was added in Solaris 11.
*/
rc = au_close(ad, AU_TO_WRITE, event_no, 0);
#else
rc = au_close(ad, AU_TO_WRITE, event_no);
......@@ -392,7 +392,7 @@ audit_session_close(struct logininfo *li)
}
void
audit_event(ssh_audit_event_t event)
audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
char textbuf[BSM_TEXTBUFSZ];
static int logged_in = 0;
......
......@@ -97,10 +97,8 @@ audit_session_close(struct logininfo *li)
}
void
audit_event(ssh_audit_event_t event)
audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
struct ssh *ssh = active_state; /* XXX */
switch(event) {
case SSH_AUTH_SUCCESS:
case SSH_CONNECTION_CLOSE:
......
......@@ -26,12 +26,12 @@
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#ifdef SSH_AUDIT_EVENTS
#include "audit.h"
#include "log.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
......@@ -131,7 +131,7 @@ audit_connection_from(const char *host, int port)
* events and what they mean).
*/
void
audit_event(ssh_audit_event_t event)
audit_event(struct ssh *ssh, ssh_audit_event_t event)
{
debug("audit event euid %d user %s event %d (%s)", geteuid(),
audit_username(), event, audit_event_lookup(event));
......
......@@ -27,6 +27,8 @@
#include "loginrec.h"
struct ssh;
enum ssh_audit_event_type {
SSH_LOGIN_EXCEED_MAXTRIES,
SSH_LOGIN_ROOT_DENIED,
......@@ -46,7 +48,7 @@ enum ssh_audit_event_type {
typedef enum ssh_audit_event_type ssh_audit_event_t;
void audit_connection_from(const char *, int);
void audit_event(ssh_audit_event_t);
void audit_event(struct ssh *, ssh_audit_event_t);
void audit_session_open(struct logininfo *);
void audit_session_close(struct logininfo *);
void audit_run_command(const char *);
......
/* $OpenBSD: auth-bsdauth.c,v 1.14 2015/10/20 23:24:25 mmcc Exp $ */
/* $OpenBSD: auth-bsdauth.c,v 1.15 2018/07/09 21:35:50 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
......@@ -29,15 +29,13 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef BSD_AUTH
#include "xmalloc.h"
#include "key.h"
#include "sshkey.h"
#include "sshbuf.h"
#include "hostfile.h"
#include "auth.h"
#include "log.h"
#include "buffer.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
......
/* $OpenBSD: auth-krb5.c,v 1.22 2016/05/04 14:22:33 markus Exp $ */
/* $OpenBSD: auth-krb5.c,v 1.24 2021/04/03 06:18:40 djm Exp $ */
/*
* Kerberos v5 authentication and ticket-passing routines.
*
......@@ -38,11 +38,11 @@
#include "ssh.h"
#include "packet.h"
#include "log.h"
#include "buffer.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "misc.h"
#include "servconf.h"
#include "uidswap.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
......@@ -99,7 +99,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
#ifdef HEIMDAL
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
problem = krb5_cc_new_unique(authctxt->krb5_ctx,
krb5_mcc_ops.prefix, NULL, &ccache);
krb5_mcc_ops.prefix, NULL, &ccache);
# else
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
# endif
......@@ -123,7 +123,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
# ifdef HAVE_KRB5_CC_NEW_UNIQUE
problem = krb5_cc_new_unique(authctxt->krb5_ctx,
krb5_fcc_ops.prefix, NULL, &authctxt->krb5_fwd_ccache);
krb5_fcc_ops.prefix, NULL, &authctxt->krb5_fwd_ccache);
# else
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
&authctxt->krb5_fwd_ccache);
......@@ -163,17 +163,18 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
goto out;
}
problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache);
problem = ssh_krb5_cc_gen(authctxt->krb5_ctx,
&authctxt->krb5_fwd_ccache);
if (problem)
goto out;
problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
authctxt->krb5_user);
problem = krb5_cc_initialize(authctxt->krb5_ctx,
authctxt->krb5_fwd_ccache, authctxt->krb5_user);
if (problem)
goto out;
problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
&creds);
problem = krb5_cc_store_cred(authctxt->krb5_ctx,
authctxt->krb5_fwd_ccache, &creds);
if (problem)
goto out;
#endif
......@@ -202,7 +203,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
if (authctxt->krb5_ctx != NULL && problem!=-1) {
errmsg = krb5_get_error_message(authctxt->krb5_ctx,
problem);
debug("Kerberos password authentication failed: %s",
debug("Kerberos password authentication failed: %s",
errmsg);
krb5_free_error_message(authctxt->krb5_ctx, errmsg);
} else
......
/* $OpenBSD: auth-options.h,v 1.22 2016/11/30 02:57:40 djm Exp $ */
/* $OpenBSD: auth-options.h,v 1.31 2021/07/23 03:57:20 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Copyright (c) 2018 Damien Miller <djm@mindrot.org>
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef AUTH_OPTIONS_H
#define AUTH_OPTIONS_H
/* Linked list of custom environment strings */
struct envstring {
struct envstring *next;
char *s;
struct passwd;
struct sshkey;
/* Maximum number of permitopen/permitlisten directives to accept */
#define SSH_AUTHOPT_PERMIT_MAX 4096
/* Maximum number of environment directives to accept */
#define SSH_AUTHOPT_ENV_MAX 1024
/*
* sshauthopt represents key options parsed from authorized_keys or
* from certificate extensions/options.
*/
struct sshauthopt {
/* Feature flags */
int permit_port_forwarding_flag;
int permit_agent_forwarding_flag;
int permit_x11_forwarding_flag;
int permit_pty_flag;
int permit_user_rc;
/* "restrict" keyword was invoked */
int restricted;
/* key/principal expiry date */
uint64_t valid_before;
/* Certificate-related options */
int cert_authority;
char *cert_principals;
int force_tun_device;
char *force_command;
/* Custom environment */
size_t nenv;
char **env;
/* Permitted port forwardings */
size_t npermitopen;
char **permitopen;
/* Permitted listens (remote forwarding) */
size_t npermitlisten;
char **permitlisten;
/*
* Permitted host/addresses (comma-separated)
* Caller must check source address matches both lists (if present).
*/
char *required_from_host_cert;
char *required_from_host_keys;
/* Key requires user presence asserted */
int no_require_user_presence;
/* Key requires user verification (e.g. PIN) */
int require_verify;
};
/* Flags that may be set in authorized_keys options. */
extern int no_port_forwarding_flag;
extern int no_agent_forwarding_flag;
extern int no_x11_forwarding_flag;
extern int no_pty_flag;
extern int no_user_rc;
extern char *forced_command;
extern struct envstring *custom_environment;
extern int forced_tun_device;
extern int key_is_cert_authority;
extern char *authorized_principals;
int auth_parse_options(struct passwd *, char *, char *, u_long);
void auth_clear_options(void);
int auth_cert_options(struct sshkey *, struct passwd *, const char **);
struct sshauthopt *sshauthopt_new(void);
struct sshauthopt *sshauthopt_new_with_keys_defaults(void);
void sshauthopt_free(struct sshauthopt *opts);
struct sshauthopt *sshauthopt_copy(const struct sshauthopt *orig);
int sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m, int);
int sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **opts);
/*
* Parse authorized_keys options. Returns an options structure on success
* or NULL on failure. Will set errstr on failure.
*/
struct sshauthopt *sshauthopt_parse(const char *s, const char **errstr);
/*
* Parse certification options to a struct sshauthopt.
* Returns options on success or NULL on failure.
*/
struct sshauthopt *sshauthopt_from_cert(struct sshkey *k);
/*
* Merge key options.
*/
struct sshauthopt *sshauthopt_merge(const struct sshauthopt *primary,
const struct sshauthopt *additional, const char **errstrp);
#endif
......@@ -25,10 +25,12 @@
#include "includes.h"
#ifdef USE_PAM
void start_pam(Authctxt *);
struct ssh;
void start_pam(struct ssh *);
void finish_pam(void);
u_int do_pam_account(void);
void do_pam_session(void);
void do_pam_session(struct ssh *);
void do_pam_setcred(int );
void do_pam_chauthtok(void);
int do_pam_putenv(char *, char *);
......
/* $OpenBSD: auth-passwd.c,v 1.45 2016/07/21 01:39:35 dtucker Exp $ */
/* $OpenBSD: auth-passwd.c,v 1.48 2020/10/18 11:32:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
......@@ -46,16 +46,17 @@
#include <stdarg.h>
#include "packet.h"
#include "buffer.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
extern Buffer loginmsg;
extern struct sshbuf *loginmsg;
extern ServerOptions options;
#ifdef HAVE_LOGIN_CAP
......@@ -68,22 +69,15 @@ extern login_cap_t *lc;
#define MAX_PASSWORD_LEN 1024
void
disable_forwarding(void)
{
no_port_forwarding_flag = 1;
no_agent_forwarding_flag = 1;
no_x11_forwarding_flag = 1;
}
/*
* Tries to authenticate the user using password. Returns true if
* authentication succeeds.
*/
int
auth_password(Authctxt *authctxt, const char *password)
auth_password(struct ssh *ssh, const char *password)
{
struct passwd * pw = authctxt->pw;
Authctxt *authctxt = ssh->authctxt;
struct passwd *pw = authctxt->pw;
int result, ok = authctxt->valid;
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
static int expire_checked = 0;
......@@ -128,9 +122,9 @@ auth_password(Authctxt *authctxt, const char *password)
authctxt->force_pwchange = 1;
}
#endif
result = sys_auth_passwd(authctxt, password);
result = sys_auth_passwd(ssh, password);
if (authctxt->force_pwchange)
disable_forwarding();
auth_restrict_session(ssh);
return (result && ok);
}
......@@ -138,7 +132,7 @@ auth_password(Authctxt *authctxt, const char *password)
static void
warn_expiry(Authctxt *authctxt, auth_session_t *as)
{
char buf[256];
int r;
quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
pwwarntime = acwarntime = TWO_WEEKS;
......@@ -155,34 +149,34 @@ warn_expiry(Authctxt *authctxt, auth_session_t *as)
#endif
if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
daysleft = pwtimeleft / DAY + 1;
snprintf(buf, sizeof(buf),
if ((r = sshbuf_putf(loginmsg,
"Your password will expire in %lld day%s.\n",
daysleft, daysleft == 1 ? "" : "s");
buffer_append(&loginmsg, buf, strlen(buf));
daysleft, daysleft == 1 ? "" : "s")) != 0)
fatal_fr(r, "buffer error");
}
if (actimeleft != 0 && actimeleft < acwarntime) {
daysleft = actimeleft / DAY + 1;
snprintf(buf, sizeof(buf),
if ((r = sshbuf_putf(loginmsg,
"Your account will expire in %lld day%s.\n",
daysleft, daysleft == 1 ? "" : "s");
buffer_append(&loginmsg, buf, strlen(buf));
daysleft, daysleft == 1 ? "" : "s")) != 0)
fatal_fr(r, "buffer error");
}
}
int
sys_auth_passwd(Authctxt *authctxt, const char *password)
sys_auth_passwd(struct ssh *ssh, const char *password)
{
struct passwd *pw = authctxt->pw;
Authctxt *authctxt = ssh->authctxt;
auth_session_t *as;
static int expire_checked = 0;
as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
as = auth_usercheck(authctxt->pw->pw_name, authctxt->style, "auth-ssh",
(char *)password);
if (as == NULL)
return (0);
if (auth_getstate(as) & AUTH_PWEXPIRED) {
auth_close(as);
disable_forwarding();
auth_restrict_session(ssh);
authctxt->force_pwchange = 1;
return (1);
} else {
......@@ -195,14 +189,18 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
}
#elif !defined(CUSTOM_SYS_AUTH_PASSWD)
int
sys_auth_passwd(Authctxt *authctxt, const char *password)
sys_auth_passwd(struct ssh *ssh, const char *password)
{
Authctxt *authctxt = ssh->authctxt;
struct passwd *pw = authctxt->pw;
char *encrypted_password, *salt = NULL;
/* Just use the supplied fake password if authctxt is invalid */
char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
if (pw_password == NULL)
return 0;
/* Check for users with no password. */
if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
return (1);
......
/* $OpenBSD: auth-rhosts.c,v 1.48 2016/08/13 17:47:41 markus Exp $ */
/* $OpenBSD: auth-rhosts.c,v 1.57 2022/12/09 00:17:40 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
......@@ -19,6 +19,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_NETGROUP_H
# include <netgroup.h>
#endif
......@@ -26,7 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "packet.h"
......@@ -34,11 +36,11 @@
#include "pathnames.h"
#include "log.h"
#include "misc.h"
#include "buffer.h" /* XXX */
#include "key.h" /* XXX */
#include "xmalloc.h"
#include "sshbuf.h"
#include "sshkey.h"
#include "servconf.h"
#include "canohost.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
......@@ -190,12 +192,13 @@ int
auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
const char *ipaddr)
{
char buf[1024];
char *path = NULL;
struct stat st;
static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
static const char * const rhosts_files[] = {".shosts", ".rhosts", NULL};
u_int rhosts_file_index;
int r;
debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s",
debug2_f("clientuser %s hostname %s ipaddr %s",
client_user, hostname, ipaddr);
/* Switch to the user's uid. */
......@@ -209,9 +212,11 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
snprintf(buf, sizeof buf, "%.500s/%.100s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
if (stat(buf, &st) >= 0)
xasprintf(&path, "%s/%s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
r = stat(path, &st);
free(path);
if (r >= 0)
break;
}
/* Switch back to privileged uid. */
......@@ -222,9 +227,9 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* are no system-wide files.
*/
if (!rhosts_files[rhosts_file_index] &&
stat(_PATH_RHOSTS_EQUIV, &st) < 0 &&
stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) {
debug3("%s: no hosts access files exist", __func__);
stat(_PATH_RHOSTS_EQUIV, &st) == -1 &&
stat(_PATH_SSH_HOSTS_EQUIV, &st) == -1) {
debug3_f("no hosts access files exist");
return 0;
}
......@@ -233,7 +238,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* shosts.equiv.
*/
if (pw->pw_uid == 0)
debug3("%s: root user, ignoring system hosts files", __func__);
debug3_f("root user, ignoring system hosts files");
else {
if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
client_user, pw->pw_name)) {
......@@ -253,7 +258,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* Check that the home directory is owned by root or the user, and is
* not group or world writable.
*/
if (stat(pw->pw_dir, &st) < 0) {
if (stat(pw->pw_dir, &st) == -1) {
logit("Rhosts authentication refused for %.100s: "
"no home directory %.200s", pw->pw_name, pw->pw_dir);
auth_debug_add("Rhosts authentication refused for %.100s: "
......@@ -276,10 +281,13 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
snprintf(buf, sizeof buf, "%.500s/%.100s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
if (stat(buf, &st) < 0)
xasprintf(&path, "%s/%s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
if (stat(path, &st) == -1) {
debug3_f("stat %s: %s", path, strerror(errno));
free(path);
continue;
}
/*
* Make sure that the file is either owned by the user or by
......@@ -290,22 +298,26 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
if (options.strict_modes &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
(st.st_mode & 022) != 0)) {
logit("Rhosts authentication refused for %.100s: bad modes for %.200s",
pw->pw_name, buf);
auth_debug_add("Bad file modes for %.200s", buf);
logit("Rhosts authentication refused for %.100s: "
"bad modes for %.200s", pw->pw_name, path);
auth_debug_add("Bad file modes for %.200s", path);
free(path);
continue;
}
/*
* Check if we have been configured to ignore .rhosts
* and .shosts files.
*/
if (options.ignore_rhosts) {
if (options.ignore_rhosts == IGNORE_RHOSTS_YES ||
(options.ignore_rhosts == IGNORE_RHOSTS_SHOSTS &&
strcmp(rhosts_files[rhosts_file_index], ".shosts") != 0)) {
auth_debug_add("Server has been configured to "
"ignore %.100s.", rhosts_files[rhosts_file_index]);
free(path);
continue;
}
/* Check if authentication is permitted by the file. */
if (check_rhosts_file(buf, hostname, ipaddr,
if (check_rhosts_file(path, hostname, ipaddr,
client_user, pw->pw_name)) {
auth_debug_add("Accepted by %.100s.",
rhosts_files[rhosts_file_index]);
......@@ -314,8 +326,10 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
auth_debug_add("Accepted host %s ip %s client_user "
"%s server_user %s", hostname, ipaddr,
client_user, pw->pw_name);
free(path);
return 1;
}
free(path);
}
/* Restore the privileged uid. */
......
......@@ -30,10 +30,10 @@
#include <string.h>
#include <time.h>
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
#include "sshbuf.h"
#include "ssherr.h"
#include "log.h"
#ifdef DAY
......@@ -41,7 +41,7 @@
#endif
#define DAY (24L * 60 * 60) /* 1 day in seconds */
extern Buffer loginmsg;
extern struct sshbuf *loginmsg;
/*
* For the account and password expiration functions, we assume the expiry
......@@ -56,13 +56,13 @@ int
auth_shadow_acctexpired(struct spwd *spw)
{
time_t today;
int daysleft;
char buf[256];
long long daysleft;
int r;
today = time(NULL) / DAY;
daysleft = spw->sp_expire - today;
debug3("%s: today %d sp_expire %d days left %d", __func__, (int)today,
(int)spw->sp_expire, daysleft);
debug3("%s: today %lld sp_expire %lld days left %lld", __func__,
(long long)today, (long long)spw->sp_expire, daysleft);
if (spw->sp_expire == -1) {
debug3("account expiration disabled");
......@@ -70,11 +70,11 @@ auth_shadow_acctexpired(struct spwd *spw)
logit("Account %.100s has expired", spw->sp_namp);
return 1;
} else if (daysleft <= spw->sp_warn) {
debug3("account will expire in %d days", daysleft);
snprintf(buf, sizeof(buf),
"Your account will expire in %d day%s.\n", daysleft,
daysleft == 1 ? "" : "s");
buffer_append(&loginmsg, buf, strlen(buf));
debug3("account will expire in %lld days", daysleft);
if ((r = sshbuf_putf(loginmsg,
"Your account will expire in %lld day%s.\n", daysleft,
daysleft == 1 ? "" : "s")) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
return 0;
......@@ -89,9 +89,8 @@ auth_shadow_pwexpired(Authctxt *ctxt)
{
struct spwd *spw = NULL;
const char *user = ctxt->pw->pw_name;
char buf[256];
time_t today;
int daysleft, disabled = 0;
int r, daysleft, disabled = 0;
if ((spw = getspnam((char *)user)) == NULL) {
error("Could not get shadow information for %.100s", user);
......@@ -99,8 +98,8 @@ auth_shadow_pwexpired(Authctxt *ctxt)
}
today = time(NULL) / DAY;
debug3("%s: today %d sp_lstchg %d sp_max %d", __func__, (int)today,
(int)spw->sp_lstchg, (int)spw->sp_max);
debug3_f("today %lld sp_lstchg %lld sp_max %lld", (long long)today,
(long long)spw->sp_lstchg, (long long)spw->sp_max);
#if defined(__hpux) && !defined(HAVE_SECUREWARE)
if (iscomsec()) {
......@@ -131,10 +130,10 @@ auth_shadow_pwexpired(Authctxt *ctxt)
return 1;
} else if (daysleft <= spw->sp_warn) {
debug3("password will expire in %d days", daysleft);
snprintf(buf, sizeof(buf),
if ((r = sshbuf_putf(loginmsg,
"Your password will expire in %d day%s.\n", daysleft,
daysleft == 1 ? "" : "s");
buffer_append(&loginmsg, buf, strlen(buf));
daysleft == 1 ? "" : "s")) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
return 0;
......
......@@ -36,7 +36,7 @@
#include <string.h>
#include "ssh.h"
#include "key.h"
#include "ssh_api.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-sia.h"
......@@ -50,11 +50,12 @@ extern int saved_argc;
extern char **saved_argv;
int
sys_auth_passwd(Authctxt *authctxt, const char *pass)
sys_auth_passwd(struct ssh *ssh, const char *pass)
{
int ret;
SIAENTITY *ent = NULL;
const char *host;
Authctxt *authctxt = ssh->authctxt;
host = get_canonical_hostname(options.use_dns);
......
/* $OpenBSD: auth-skey.c,v 1.27 2007/01/21 01:41:54 stevesk Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#ifdef SKEY
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <skey.h>
#include "xmalloc.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "ssh-gss.h"
#include "log.h"
#include "monitor_wrap.h"
static void *
skey_init_ctx(Authctxt *authctxt)
{
return authctxt;
}
int
skey_query(void *ctx, char **name, char **infotxt,
u_int* numprompts, char ***prompts, u_int **echo_on)
{
Authctxt *authctxt = ctx;
char challenge[1024];
struct skey skey;
if (_compat_skeychallenge(&skey, authctxt->user, challenge,
sizeof(challenge)) == -1)
return -1;
*name = xstrdup("");
*infotxt = xstrdup("");
*numprompts = 1;
*prompts = xcalloc(*numprompts, sizeof(char *));
*echo_on = xcalloc(*numprompts, sizeof(u_int));
xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
return 0;
}
int
skey_respond(void *ctx, u_int numresponses, char **responses)
{
Authctxt *authctxt = ctx;
if (authctxt->valid &&
numresponses == 1 &&
skey_haskey(authctxt->pw->pw_name) == 0 &&
skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
return 0;
return -1;
}
static void
skey_free_ctx(void *ctx)
{
/* we don't have a special context */
}
KbdintDevice skey_device = {
"skey",
skey_init_ctx,
skey_query,
skey_respond,
skey_free_ctx
};
KbdintDevice mm_skey_device = {
"skey",
skey_init_ctx,
mm_skey_query,
mm_skey_respond,
skey_free_ctx
};
#endif /* SKEY */
/* $OpenBSD: auth.h,v 1.89 2016/08/13 17:47:41 markus Exp $ */
/* $OpenBSD: auth.h,v 1.106 2022/06/15 16:08:25 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
......@@ -29,8 +29,7 @@
#define AUTH_H
#include <signal.h>
#include <openssl/rsa.h>
#include <stdio.h>
#ifdef HAVE_LOGIN_CAP
#include <login_cap.h>
......@@ -42,8 +41,12 @@
#include <krb5.h>
#endif
struct passwd;
struct ssh;
struct sshbuf;
struct sshkey;
struct sshkey_cert;
struct sshauthopt;
typedef struct Authctxt Authctxt;
typedef struct Authmethod Authmethod;
......@@ -62,13 +65,17 @@ struct Authctxt {
char *service;
struct passwd *pw; /* set if 'valid' */
char *style;
/* Method lists for multiple authentication */
char **auth_methods; /* modified from server config */
u_int num_auth_methods;
/* Authentication method-specific data */
void *methoddata;
void *kbdintctxt;
char *info; /* Extra info for next auth_log */
#ifdef BSD_AUTH
auth_session_t *as;
#endif
char **auth_methods; /* modified from server config */
u_int num_auth_methods;
#ifdef KRB5
krb5_context krb5_ctx;
krb5_ccache krb5_fwd_ccache;
......@@ -76,12 +83,20 @@ struct Authctxt {
char *krb5_ticket_file;
char *krb5_ccname;
#endif
Buffer *loginmsg;
void *methoddata;
struct sshbuf *loginmsg;
/* Authentication keys already used; these will be refused henceforth */
struct sshkey **prev_keys;
u_int nprev_keys;
/* Last used key and ancillary information from active auth method */
struct sshkey *auth_method_key;
char *auth_method_info;
struct sshkey **prev_userkeys;
u_int nprev_userkeys;
/* Information exposed to session */
struct sshbuf *session_info; /* Auth info for environment */
};
/*
* Every authentication method has to handle authentication requests for
* non-existing users, or for users that are not allowed to login. In this
......@@ -91,7 +106,8 @@ struct Authctxt {
struct Authmethod {
char *name;
int (*userauth)(Authctxt *authctxt);
char *synonym;
int (*userauth)(struct ssh *, const char *);
int *enabled;
};
......@@ -115,18 +131,24 @@ struct KbdintDevice
int
auth_rhosts2(struct passwd *, const char *, const char *, const char *);
int auth_password(Authctxt *, const char *);
int auth_password(struct ssh *, const char *);
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
int user_key_allowed(struct passwd *, Key *, int);
void pubkey_auth_info(Authctxt *, const Key *, const char *, ...)
__attribute__((__format__ (printf, 3, 4)));
void auth2_record_userkey(Authctxt *, struct sshkey *);
int auth2_userkey_already_used(Authctxt *, struct sshkey *);
int hostbased_key_allowed(struct ssh *, struct passwd *,
const char *, char *, struct sshkey *);
int user_key_allowed(struct ssh *ssh, struct passwd *, struct sshkey *,
int, struct sshauthopt **);
int auth2_key_already_used(Authctxt *, const struct sshkey *);
struct stat;
int auth_secure_path(const char *, struct stat *, const char *, uid_t,
char *, size_t);
/*
* Handling auth method-specific information for logging and prevention
* of key reuse during multiple authentication.
*/
void auth2_authctxt_reset_info(Authctxt *);
void auth2_record_key(Authctxt *, int, const struct sshkey *);
void auth2_record_info(Authctxt *authctxt, const char *, ...)
__attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2)));
void auth2_update_session_info(Authctxt *, const char *, const char *);
#ifdef KRB5
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
......@@ -145,19 +167,12 @@ int auth_shadow_pwexpired(Authctxt *);
#include "audit.h"
void remove_kbdint_device(const char *);
void disable_forwarding(void);
void do_authentication2(struct ssh *);
void do_authentication2(Authctxt *);
void auth_info(Authctxt *authctxt, const char *, ...)
__attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2)));
void auth_log(Authctxt *, int, int, const char *, const char *);
void auth_maxtries_exceeded(Authctxt *) __attribute__((noreturn));
void userauth_finish(Authctxt *, int, const char *, const char *);
int auth_root_allowed(const char *);
void userauth_send_banner(const char *);
void auth_log(struct ssh *, int, int, const char *, const char *);
void auth_maxtries_exceeded(struct ssh *) __attribute__((noreturn));
void userauth_finish(struct ssh *, int, const char *, const char *);
int auth_root_allowed(struct ssh *, const char *);
char *auth2_read_banner(void);
int auth2_methods_valid(const char *, int);
......@@ -167,51 +182,66 @@ int auth2_method_allowed(Authctxt *, const char *, const char *);
void privsep_challenge_enable(void);
int auth2_challenge(Authctxt *, char *);
void auth2_challenge_stop(Authctxt *);
int auth2_challenge(struct ssh *, char *);
void auth2_challenge_stop(struct ssh *);
int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
int bsdauth_respond(void *, u_int, char **);
int skey_query(void *, char **, char **, u_int *, char ***, u_int **);
int skey_respond(void *, u_int, char **);
int allowed_user(struct passwd *);
struct passwd * getpwnamallow(const char *user);
int allowed_user(struct ssh *, struct passwd *);
struct passwd * getpwnamallow(struct ssh *, const char *user);
char *expand_authorized_keys(const char *, struct passwd *pw);
char *authorized_principals_file(struct passwd *);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
FILE *auth_openprincipals(const char *, struct passwd *, int);
int auth_key_is_revoked(Key *);
int auth_key_is_revoked(struct sshkey *);
const char *auth_get_canonical_hostname(struct ssh *, int);
HostStatus
check_key_in_hostfiles(struct passwd *, Key *, const char *,
check_key_in_hostfiles(struct passwd *, struct sshkey *, const char *,
const char *, const char *);
/* hostkey handling */
Key *get_hostkey_by_index(int);
Key *get_hostkey_public_by_index(int, struct ssh *);
Key *get_hostkey_public_by_type(int, int, struct ssh *);
Key *get_hostkey_private_by_type(int, int, struct ssh *);
int get_hostkey_index(Key *, int, struct ssh *);
int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *,
const u_char *, size_t, const char *, u_int);
struct sshkey *get_hostkey_by_index(int);
struct sshkey *get_hostkey_public_by_index(int, struct ssh *);
struct sshkey *get_hostkey_public_by_type(int, int, struct ssh *);
struct sshkey *get_hostkey_private_by_type(int, int, struct ssh *);
int get_hostkey_index(struct sshkey *, int, struct ssh *);
int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *,
u_char **, size_t *, const u_char *, size_t, const char *);
/* Key / cert options linkage to auth layer */
const struct sshauthopt *auth_options(struct ssh *);
int auth_activate_options(struct ssh *, struct sshauthopt *);
void auth_restrict_session(struct ssh *);
void auth_log_authopts(const char *, const struct sshauthopt *, int);
/* debug messages during authentication */
void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
void auth_debug_send(void);
void auth_debug_add(const char *fmt,...)
__attribute__((format(printf, 1, 2)));
void auth_debug_send(struct ssh *);
void auth_debug_reset(void);
struct passwd *fakepw(void);
int sys_auth_passwd(Authctxt *, const char *);
/* auth2-pubkeyfile.c */
int auth_authorise_keyopts(struct passwd *, struct sshauthopt *, int,
const char *, const char *, const char *);
int auth_check_principals_line(char *, const struct sshkey_cert *,
const char *, struct sshauthopt **);
int auth_process_principals(FILE *, const char *,
const struct sshkey_cert *, struct sshauthopt **);
int auth_check_authkey_line(struct passwd *, struct sshkey *,
char *, const char *, const char *, const char *, struct sshauthopt **);
int auth_check_authkeys_file(struct passwd *, FILE *, char *,
struct sshkey *, const char *, const char *, struct sshauthopt **);
FILE *auth_openkeyfile(const char *, struct passwd *, int);
FILE *auth_openprincipals(const char *, struct passwd *, int);
#define SKEY_PROMPT "\nS/Key Password: "
int sys_auth_passwd(struct ssh *, const char *);
#if defined(KRB5) && !defined(HEIMDAL)
#include <krb5.h>
krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
#endif
#endif
#endif /* AUTH_H */
/* $OpenBSD: auth2-chall.c,v 1.44 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
......@@ -28,18 +28,20 @@
#include <sys/types.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "ssh2.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
#include "sshbuf.h"
#include "packet.h"
#include "dispatch.h"
#include "ssherr.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
......@@ -47,9 +49,9 @@
/* import */
extern ServerOptions options;
static int auth2_challenge_start(Authctxt *);
static int send_userauth_info_request(Authctxt *);
static int input_userauth_info_response(int, u_int32_t, void *);
static int auth2_challenge_start(struct ssh *);
static int send_userauth_info_request(struct ssh *);
static int input_userauth_info_response(int, u_int32_t, struct ssh *);
#ifdef BSD_AUTH
extern KbdintDevice bsdauth_device;
......@@ -57,9 +59,6 @@ extern KbdintDevice bsdauth_device;
#ifdef USE_PAM
extern KbdintDevice sshpam_device;
#endif
#ifdef SKEY
extern KbdintDevice skey_device;
#endif
#endif
KbdintDevice *devices[] = {
......@@ -69,9 +68,6 @@ KbdintDevice *devices[] = {
#ifdef USE_PAM
&sshpam_device,
#endif
#ifdef SKEY
&skey_device,
#endif
#endif
NULL
};
......@@ -105,8 +101,8 @@ static KbdintAuthctxt *
kbdint_alloc(const char *devs)
{
KbdintAuthctxt *kbdintctxt;
Buffer b;
int i;
struct sshbuf *b;
int i, r;
#ifdef USE_PAM
if (!options.use_pam)
......@@ -115,16 +111,16 @@ kbdint_alloc(const char *devs)
kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
if (strcmp(devs, "") == 0) {
buffer_init(&b);
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
for (i = 0; devices[i]; i++) {
if (buffer_len(&b) > 0)
buffer_append(&b, ",", 1);
buffer_append(&b, devices[i]->name,
strlen(devices[i]->name));
if ((r = sshbuf_putf(b, "%s%s",
sshbuf_len(b) ? "," : "", devices[i]->name)) != 0)
fatal_fr(r, "buffer error");
}
if ((kbdintctxt->devices = sshbuf_dup_string(&b)) == NULL)
fatal("%s: sshbuf_dup_string failed", __func__);
buffer_free(&b);
if ((kbdintctxt->devices = sshbuf_dup_string(b)) == NULL)
fatal_f("sshbuf_dup_string failed");
sshbuf_free(b);
} else {
kbdintctxt->devices = xstrdup(devs);
}
......@@ -150,8 +146,7 @@ kbdint_free(KbdintAuthctxt *kbdintctxt)
if (kbdintctxt->device)
kbdint_reset_device(kbdintctxt);
free(kbdintctxt->devices);
explicit_bzero(kbdintctxt, sizeof(*kbdintctxt));
free(kbdintctxt);
freezero(kbdintctxt, sizeof(*kbdintctxt));
}
/* get next device */
static int
......@@ -195,8 +190,9 @@ kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
* wait for the response.
*/
int
auth2_challenge(Authctxt *authctxt, char *devs)
auth2_challenge(struct ssh *ssh, char *devs)
{
Authctxt *authctxt = ssh->authctxt;
debug("auth2_challenge: user=%s devs=%s",
authctxt->user ? authctxt->user : "<nouser>",
devs ? devs : "<no devs>");
......@@ -205,15 +201,16 @@ auth2_challenge(Authctxt *authctxt, char *devs)
return 0;
if (authctxt->kbdintctxt == NULL)
authctxt->kbdintctxt = kbdint_alloc(devs);
return auth2_challenge_start(authctxt);
return auth2_challenge_start(ssh);
}
/* unregister kbd-int callbacks and context */
void
auth2_challenge_stop(Authctxt *authctxt)
auth2_challenge_stop(struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
/* unregister callback */
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
if (authctxt->kbdintctxt != NULL) {
kbdint_free(authctxt->kbdintctxt);
authctxt->kbdintctxt = NULL;
......@@ -222,29 +219,30 @@ auth2_challenge_stop(Authctxt *authctxt)
/* side effect: sets authctxt->postponed if a reply was sent*/
static int
auth2_challenge_start(Authctxt *authctxt)
auth2_challenge_start(struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
debug2("auth2_challenge_start: devices %s",
kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
return 0;
}
debug("auth2_challenge_start: trying authentication method '%s'",
kbdintctxt->device->name);
if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
return 0;
}
if (send_userauth_info_request(authctxt) == 0) {
auth2_challenge_stop(authctxt);
if (send_userauth_info_request(ssh) == 0) {
auth2_challenge_stop(ssh);
return 0;
}
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE,
&input_userauth_info_response);
authctxt->postponed = 1;
......@@ -252,28 +250,32 @@ auth2_challenge_start(Authctxt *authctxt)
}
static int
send_userauth_info_request(Authctxt *authctxt)
send_userauth_info_request(struct ssh *ssh)
{
Authctxt *authctxt = ssh->authctxt;
KbdintAuthctxt *kbdintctxt;
char *name, *instr, **prompts;
u_int i, *echo_on;
u_int r, i, *echo_on;
kbdintctxt = authctxt->kbdintctxt;
if (kbdintctxt->device->query(kbdintctxt->ctxt,
&name, &instr, &kbdintctxt->nreq, &prompts, &echo_on))
return 0;
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
packet_put_cstring(name);
packet_put_cstring(instr);
packet_put_cstring(""); /* language not used */
packet_put_int(kbdintctxt->nreq);
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, name)) != 0 ||
(r = sshpkt_put_cstring(ssh, instr)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 || /* language not used */
(r = sshpkt_put_u32(ssh, kbdintctxt->nreq)) != 0)
fatal_fr(r, "start packet");
for (i = 0; i < kbdintctxt->nreq; i++) {
packet_put_cstring(prompts[i]);
packet_put_char(echo_on[i]);
if ((r = sshpkt_put_cstring(ssh, prompts[i])) != 0 ||
(r = sshpkt_put_u8(ssh, echo_on[i])) != 0)
fatal_fr(r, "assemble packet");
}
packet_send();
packet_write_wait();
if ((r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
fatal_fr(r, "send packet");
for (i = 0; i < kbdintctxt->nreq; i++)
free(prompts[i]);
......@@ -285,35 +287,40 @@ send_userauth_info_request(Authctxt *authctxt)
}
static int
input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
{
Authctxt *authctxt = ctxt;
Authctxt *authctxt = ssh->authctxt;
KbdintAuthctxt *kbdintctxt;
int authenticated = 0, res;
int r;
u_int i, nresp;
const char *devicename = NULL;
char **response = NULL;
if (authctxt == NULL)
fatal("input_userauth_info_response: no authctxt");
fatal_f("no authctxt");
kbdintctxt = authctxt->kbdintctxt;
if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
fatal("input_userauth_info_response: no kbdintctxt");
fatal_f("no kbdintctxt");
if (kbdintctxt->device == NULL)
fatal("input_userauth_info_response: no device");
fatal_f("no device");
authctxt->postponed = 0; /* reset */
nresp = packet_get_int();
if ((r = sshpkt_get_u32(ssh, &nresp)) != 0)
fatal_fr(r, "parse packet");
if (nresp != kbdintctxt->nreq)
fatal("input_userauth_info_response: wrong number of replies");
fatal_f("wrong number of replies");
if (nresp > 100)
fatal("input_userauth_info_response: too many replies");
fatal_f("too many replies");
if (nresp > 0) {
response = xcalloc(nresp, sizeof(char *));
for (i = 0; i < nresp; i++)
response[i] = packet_get_string(NULL);
for (i = 0; i < nresp; i++) {
if ((r = sshpkt_get_cstring(ssh, &response[i], NULL)) != 0)
fatal_fr(r, "parse response");
}
}
packet_check_eom();
if ((r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
......@@ -330,7 +337,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
break;
case 1:
/* Authentication needs further interaction */
if (send_userauth_info_request(authctxt) == 1)
if (send_userauth_info_request(ssh) == 1)
authctxt->postponed = 1;
break;
default:
......@@ -340,14 +347,14 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
devicename = kbdintctxt->device->name;
if (!authctxt->postponed) {
if (authenticated) {
auth2_challenge_stop(authctxt);
auth2_challenge_stop(ssh);
} else {
/* start next device */
/* may set authctxt->postponed */
auth2_challenge_start(authctxt);
auth2_challenge_start(ssh);
}
}
userauth_finish(authctxt, authenticated, "keyboard-interactive",
userauth_finish(ssh, authenticated, "keyboard-interactive",
devicename);
return 0;
}
......@@ -355,7 +362,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
void
privsep_challenge_enable(void)
{
#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY)
#if defined(BSD_AUTH) || defined(USE_PAM)
int n = 0;
#endif
#ifdef BSD_AUTH
......@@ -364,9 +371,6 @@ privsep_challenge_enable(void)
#ifdef USE_PAM
extern KbdintDevice mm_sshpam_device;
#endif
#ifdef SKEY
extern KbdintDevice mm_skey_device;
#endif
#ifdef BSD_AUTH
devices[n++] = &mm_bsdauth_device;
......@@ -374,8 +378,5 @@ privsep_challenge_enable(void)
#ifdef USE_PAM
devices[n++] = &mm_sshpam_device;
#endif
#ifdef SKEY
devices[n++] = &mm_skey_device;
#endif
#endif
}
/* $OpenBSD: auth2-hostbased.c,v 1.26 2016/03/07 19:02:43 djm Exp $ */
/* $OpenBSD: auth2-hostbased.c,v 1.52 2023/03/05 05:34:09 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
......@@ -27,6 +27,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <pwd.h>
#include <string.h>
#include <stdarg.h>
......@@ -34,12 +35,12 @@
#include "xmalloc.h"
#include "ssh2.h"
#include "packet.h"
#include "buffer.h"
#include "kex.h"
#include "sshbuf.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "compat.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "canohost.h"
......@@ -48,105 +49,113 @@
#endif
#include "monitor_wrap.h"
#include "pathnames.h"
#include "ssherr.h"
#include "match.h"
/* import */
extern ServerOptions options;
extern u_char *session_id2;
extern u_int session_id2_len;
static int
userauth_hostbased(Authctxt *authctxt)
userauth_hostbased(struct ssh *ssh, const char *method)
{
Buffer b;
Key *key = NULL;
char *pkalg, *cuser, *chost, *service;
Authctxt *authctxt = ssh->authctxt;
struct sshbuf *b;
struct sshkey *key = NULL;
char *pkalg, *cuser, *chost;
u_char *pkblob, *sig;
u_int alen, blen, slen;
int pktype;
int authenticated = 0;
size_t alen, blen, slen;
int r, pktype, authenticated = 0;
if (!authctxt->valid) {
debug2("userauth_hostbased: disabled because of invalid user");
return 0;
}
pkalg = packet_get_string(&alen);
pkblob = packet_get_string(&blen);
chost = packet_get_string(NULL);
cuser = packet_get_string(NULL);
sig = packet_get_string(&slen);
/* XXX use sshkey_froms() */
if ((r = sshpkt_get_cstring(ssh, &pkalg, &alen)) != 0 ||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
(r = sshpkt_get_cstring(ssh, &chost, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &cuser, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &sig, &slen)) != 0)
fatal_fr(r, "parse packet");
debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
debug_f("cuser %s chost %s pkalg %s slen %zu",
cuser, chost, pkalg, slen);
#ifdef DEBUG_PK
debug("signature:");
buffer_init(&b);
buffer_append(&b, sig, slen);
buffer_dump(&b);
buffer_free(&b);
sshbuf_dump_data(sig, slen, stderr);
#endif
pktype = key_type_from_name(pkalg);
pktype = sshkey_type_from_name(pkalg);
if (pktype == KEY_UNSPEC) {
/* this is perfectly legal */
logit("userauth_hostbased: unsupported "
"public key algorithm: %s", pkalg);
logit_f("unsupported public key algorithm: %s",
pkalg);
goto done;
}
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
error_fr(r, "key_from_blob");
goto done;
}
key = key_from_blob(pkblob, blen);
if (key == NULL) {
error("userauth_hostbased: cannot decode key: %s", pkalg);
error_f("cannot decode key: %s", pkalg);
goto done;
}
if (key->type != pktype) {
error("userauth_hostbased: type mismatch for decoded key "
error_f("type mismatch for decoded key "
"(received %d, expected %d)", key->type, pktype);
goto done;
}
if (key_type_plain(key->type) == KEY_RSA &&
(datafellows & SSH_BUG_RSASIGMD5) != 0) {
error("Refusing RSA key because peer uses unsafe "
"signature format");
if (match_pattern_list(pkalg, options.hostbased_accepted_algos, 0) != 1) {
logit_f("signature algorithm %s not in "
"HostbasedAcceptedAlgorithms", pkalg);
goto done;
}
if (match_pattern_list(sshkey_ssh_name(key),
options.hostbased_key_types, 0) != 1) {
logit("%s: key type %s not in HostbasedAcceptedKeyTypes",
__func__, sshkey_type(key));
if ((r = sshkey_check_cert_sigtype(key,
options.ca_sign_algorithms)) != 0) {
logit_fr(r, "certificate signature algorithm %s",
(key->cert == NULL || key->cert->signature_type == NULL) ?
"(null)" : key->cert->signature_type);
goto done;
}
if ((r = sshkey_check_rsa_length(key,
options.required_rsa_size)) != 0) {
logit_r(r, "refusing %s key", sshkey_type(key));
goto done;
}
if (!authctxt->valid || authctxt->user == NULL) {
debug2_f("disabled because of invalid user");
goto done;
}
service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
authctxt->service;
buffer_init(&b);
buffer_put_string(&b, session_id2, session_id2_len);
if ((b = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
/* reconstruct packet */
buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
buffer_put_cstring(&b, authctxt->user);
buffer_put_cstring(&b, service);
buffer_put_cstring(&b, "hostbased");
buffer_put_string(&b, pkalg, alen);
buffer_put_string(&b, pkblob, blen);
buffer_put_cstring(&b, chost);
buffer_put_cstring(&b, cuser);
if ((r = sshbuf_put_stringb(b, ssh->kex->session_id)) != 0 ||
(r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->user)) != 0 ||
(r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
(r = sshbuf_put_cstring(b, method)) != 0 ||
(r = sshbuf_put_string(b, pkalg, alen)) != 0 ||
(r = sshbuf_put_string(b, pkblob, blen)) != 0 ||
(r = sshbuf_put_cstring(b, chost)) != 0 ||
(r = sshbuf_put_cstring(b, cuser)) != 0)
fatal_fr(r, "reconstruct packet");
#ifdef DEBUG_PK
buffer_dump(&b);
sshbuf_dump(b, stderr);
#endif
pubkey_auth_info(authctxt, key,
auth2_record_info(authctxt,
"client user \"%.100s\", client host \"%.100s\"", cuser, chost);
/* test for allowed key and correct signature */
authenticated = 0;
if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
buffer_len(&b))) == 1)
if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser,
chost, key)) &&
PRIVSEP(sshkey_verify(key, sig, slen,
sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0)
authenticated = 1;
buffer_free(&b);
auth2_record_key(authctxt, authenticated, key);
sshbuf_free(b);
done:
debug2("userauth_hostbased: authenticated %d", authenticated);
if (key != NULL)
key_free(key);
debug2_f("authenticated %d", authenticated);
sshkey_free(key);
free(pkalg);
free(pkblob);
free(cuser);
......@@ -157,10 +166,9 @@ done:
/* return 1 if given hostkey is allowed */
int
hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
Key *key)
hostbased_key_allowed(struct ssh *ssh, struct passwd *pw,
const char *cuser, char *chost, struct sshkey *key)
{
struct ssh *ssh = active_state; /* XXX */
const char *resolvedname, *ipaddr, *lookup, *reason;
HostStatus host_status;
int len;
......@@ -172,7 +180,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
resolvedname = auth_get_canonical_hostname(ssh, options.use_dns);
ipaddr = ssh_remote_ipaddr(ssh);
debug2("%s: chost %s resolvedname %s ipaddr %s", __func__,
debug2_f("chost %s resolvedname %s ipaddr %s",
chost, resolvedname, ipaddr);
if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
......@@ -182,9 +190,8 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
if (options.hostbased_uses_name_from_packet_only) {
if (auth_rhosts2(pw, cuser, chost, chost) == 0) {
debug2("%s: auth_rhosts2 refused "
"user \"%.100s\" host \"%.100s\" (from packet)",
__func__, cuser, chost);
debug2_f("auth_rhosts2 refused user \"%.100s\" "
"host \"%.100s\" (from packet)", cuser, chost);
return 0;
}
lookup = chost;
......@@ -194,17 +201,17 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
"client sends %s, but we resolve %s to %s",
chost, ipaddr, resolvedname);
if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) {
debug2("%s: auth_rhosts2 refused "
debug2_f("auth_rhosts2 refused "
"user \"%.100s\" host \"%.100s\" addr \"%.100s\"",
__func__, cuser, resolvedname, ipaddr);
cuser, resolvedname, ipaddr);
return 0;
}
lookup = resolvedname;
}
debug2("%s: access allowed by auth_rhosts2", __func__);
debug2_f("access allowed by auth_rhosts2");
if (key_is_cert(key) &&
key_cert_check_authority(key, 1, 0, lookup, &reason)) {
if (sshkey_is_cert(key) &&
sshkey_cert_check_authority_now(key, 1, 0, 0, lookup, &reason)) {
error("%s", reason);
auth_debug_add("%s", reason);
return 0;
......@@ -223,20 +230,20 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
}
if (host_status == HOST_OK) {
if (key_is_cert(key)) {
if (sshkey_is_cert(key)) {
if ((fp = sshkey_fingerprint(key->cert->signature_key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
fatal("%s: sshkey_fingerprint fail", __func__);
fatal_f("sshkey_fingerprint fail");
verbose("Accepted certificate ID \"%s\" signed by "
"%s CA %s from %s@%s", key->cert->key_id,
key_type(key->cert->signature_key), fp,
sshkey_type(key->cert->signature_key), fp,
cuser, lookup);
} else {
if ((fp = sshkey_fingerprint(key,
options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
fatal("%s: sshkey_fingerprint fail", __func__);
fatal_f("sshkey_fingerprint fail");
verbose("Accepted %s public key %s from %s@%s",
key_type(key), fp, cuser, lookup);
sshkey_type(key), fp, cuser, lookup);
}
free(fp);
}
......@@ -246,6 +253,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
Authmethod method_hostbased = {
"hostbased",
NULL,
userauth_hostbased,
&options.hostbased_authentication
};
/* $OpenBSD: auth2-kbdint.c,v 1.7 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-kbdint.c,v 1.14 2021/12/19 22:12:07 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
......@@ -27,35 +27,37 @@
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "packet.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "log.h"
#include "buffer.h"
#include "misc.h"
#include "servconf.h"
#include "ssherr.h"
/* import */
extern ServerOptions options;
static int
userauth_kbdint(Authctxt *authctxt)
userauth_kbdint(struct ssh *ssh, const char *method)
{
int authenticated = 0;
int r, authenticated = 0;
char *lang, *devs;
lang = packet_get_string(NULL);
devs = packet_get_string(NULL);
packet_check_eom();
if ((r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &devs, NULL)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
debug("keyboard-interactive devs %s", devs);
if (options.challenge_response_authentication)
authenticated = auth2_challenge(authctxt, devs);
if (options.kbd_interactive_authentication)
authenticated = auth2_challenge(ssh, devs);
free(devs);
free(lang);
......@@ -64,6 +66,7 @@ userauth_kbdint(Authctxt *authctxt)
Authmethod method_kbdint = {
"keyboard-interactive",
NULL,
userauth_kbdint,
&options.kbd_interactive_authentication
};
/* $OpenBSD: auth2-none.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-none.c,v 1.25 2023/03/05 05:34:09 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
......@@ -37,16 +37,15 @@
#include "atomicio.h"
#include "xmalloc.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "packet.h"
#include "log.h"
#include "buffer.h"
#include "misc.h"
#include "servconf.h"
#include "compat.h"
#include "ssh2.h"
#include "ssherr.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
......@@ -59,17 +58,21 @@ extern ServerOptions options;
static int none_enabled = 1;
static int
userauth_none(Authctxt *authctxt)
userauth_none(struct ssh *ssh, const char *method)
{
int r;
none_enabled = 0;
packet_check_eom();
if ((r = sshpkt_get_end(ssh)) != 0)
fatal_fr(r, "parse packet");
if (options.permit_empty_passwd && options.password_authentication)
return (PRIVSEP(auth_password(authctxt, "")));
return (PRIVSEP(auth_password(ssh, "")));
return (0);
}
Authmethod method_none = {
"none",
NULL,
userauth_none,
&none_enabled
};
/* $OpenBSD: auth2-passwd.c,v 1.12 2014/07/15 15:54:14 millert Exp $ */
/* $OpenBSD: auth2-passwd.c,v 1.21 2022/05/27 04:29:40 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
......@@ -27,16 +27,17 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include "xmalloc.h"
#include "packet.h"
#include "ssherr.h"
#include "log.h"
#include "key.h"
#include "sshkey.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
......@@ -48,34 +49,32 @@
extern ServerOptions options;
static int
userauth_passwd(Authctxt *authctxt)
userauth_passwd(struct ssh *ssh, const char *method)
{
char *password, *newpass;
int authenticated = 0;
int change;
u_int len, newlen;
char *password = NULL;
int authenticated = 0, r;
u_char change;
size_t len = 0;
change = packet_get_char();
password = packet_get_string(&len);
if (change) {
/* discard new password from packet */
newpass = packet_get_string(&newlen);
explicit_bzero(newpass, newlen);
free(newpass);
if ((r = sshpkt_get_u8(ssh, &change)) != 0 ||
(r = sshpkt_get_cstring(ssh, &password, &len)) != 0 ||
(change && (r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) ||
(r = sshpkt_get_end(ssh)) != 0) {
freezero(password, len);
fatal_fr(r, "parse packet");
}
packet_check_eom();
if (change)
logit("password change not supported");
else if (PRIVSEP(auth_password(authctxt, password)) == 1)
else if (PRIVSEP(auth_password(ssh, password)) == 1)
authenticated = 1;
explicit_bzero(password, len);
free(password);
freezero(password, len);
return authenticated;
}
Authmethod method_passwd = {
"password",
NULL,
userauth_passwd,
&options.password_authentication
};
/* $OpenBSD: authfd.h,v 1.39 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: authfd.h,v 1.52 2023/12/18 14:46:56 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
......@@ -16,6 +16,9 @@
#ifndef AUTHFD_H
#define AUTHFD_H
struct sshbuf;
struct sshkey;
/* List of identities returned by ssh_fetch_identitylist() */
struct ssh_identitylist {
size_t nkeys;
......@@ -23,26 +26,48 @@ struct ssh_identitylist {
char **comments;
};
/* Key destination restrictions */
struct dest_constraint_hop {
char *user; /* wildcards allowed */
char *hostname; /* used to matching cert principals and for display */
int is_ca;
u_int nkeys; /* number of entries in *both* 'keys' and 'key_is_ca' */
struct sshkey **keys;
int *key_is_ca;
};
struct dest_constraint {
struct dest_constraint_hop from;
struct dest_constraint_hop to;
};
int ssh_get_authentication_socket(int *fdp);
int ssh_get_authentication_socket_path(const char *authsocket, int *fdp);
void ssh_close_authentication_socket(int sock);
int ssh_lock_agent(int sock, int lock, const char *password);
int ssh_fetch_identitylist(int sock, int version,
struct ssh_identitylist **idlp);
int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp);
void ssh_free_identitylist(struct ssh_identitylist *idl);
int ssh_add_identity_constrained(int sock, struct sshkey *key,
const char *comment, u_int life, u_int confirm);
int ssh_remove_identity(int sock, struct sshkey *key);
const char *comment, u_int life, u_int confirm, u_int maxsign,
const char *provider, struct dest_constraint **dest_constraints,
size_t ndest_constraints);
int ssh_agent_has_key(int sock, const struct sshkey *key);
int ssh_remove_identity(int sock, const struct sshkey *key);
int ssh_update_card(int sock, int add, const char *reader_id,
const char *pin, u_int life, u_int confirm);
const char *pin, u_int life, u_int confirm,
struct dest_constraint **dest_constraints,
size_t ndest_constraints,
int cert_only, struct sshkey **certs, size_t ncerts);
int ssh_remove_all_identities(int sock, int version);
int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
u_char session_id[16], u_char response[16]);
int ssh_agent_sign(int sock, struct sshkey *key,
int ssh_agent_sign(int sock, const struct sshkey *key,
u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, const char *alg, u_int compat);
int ssh_agent_bind_hostkey(int sock, const struct sshkey *key,
const struct sshbuf *session_id, const struct sshbuf *signature,
int forwarding);
/* Messages for the authentication agent connection. */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
......@@ -76,8 +101,13 @@ int ssh_agent_sign(int sock, struct sshkey *key,
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
/* generic extension mechanism */
#define SSH_AGENTC_EXTENSION 27
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
#define SSH_AGENT_CONSTRAIN_MAXSIGN 3
#define SSH_AGENT_CONSTRAIN_EXTENSION 255
/* extended failure messages */
#define SSH2_AGENT_FAILURE 30
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
File mode changed from 100755 to 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment