aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2023-10-04 12:06:41 +0000
committerEd Maste <emaste@FreeBSD.org>2023-10-04 12:06:41 +0000
commitb3ced7f26826767e378a5970a65d875fc1cad61e (patch)
treeef449f71f51d75e39e1e27fc5004afaefb75d805
parent78f30535bcdb64cf743b416327ecb0f00e25b2aa (diff)
downloadsrc-b3ced7f26826767e378a5970a65d875fc1cad61e.tar.gz
src-b3ced7f26826767e378a5970a65d875fc1cad61e.zip
Vendor import of OpenSSH 9.5p1vendor/openssh/9.5p1
-rw-r--r--.github/ci-status.md4
-rwxr-xr-x.github/configs11
-rwxr-xr-x.github/setup_ci.sh8
-rw-r--r--.github/workflows/c-cpp.yml1
-rw-r--r--.github/workflows/selfhosted.yml3
-rw-r--r--ChangeLog1611
-rw-r--r--PROTOCOL35
-rw-r--r--PROTOCOL.agent4
-rw-r--r--README2
-rw-r--r--auth2.c11
-rw-r--r--channels.c35
-rw-r--r--channels.h4
-rw-r--r--clientloop.c189
-rwxr-xr-xconfigure12
-rw-r--r--configure.ac12
-rw-r--r--contrib/redhat/openssh.spec2
-rw-r--r--contrib/suse/openssh.spec2
-rw-r--r--kex.c57
-rw-r--r--kex.h3
-rw-r--r--misc.c69
-rw-r--r--misc.h6
-rw-r--r--monitor.c7
-rw-r--r--mux.c6
-rw-r--r--openbsd-compat/bsd-closefrom.c1
-rw-r--r--packet.c35
-rw-r--r--packet.h3
-rw-r--r--readconf.c64
-rw-r--r--readconf.h8
-rw-r--r--regress/Makefile5
-rw-r--r--regress/match-subsystem.sh90
-rw-r--r--regress/scp.sh24
-rw-r--r--regress/scp3.sh19
-rw-r--r--scp.c50
-rw-r--r--servconf.c107
-rw-r--r--servconf.h14
-rw-r--r--serverloop.c4
-rw-r--r--session.c15
-rw-r--r--sftp-client.c409
-rw-r--r--sftp-client.h76
-rw-r--r--sftp-glob.c28
-rw-r--r--sftp-usergroup.c8
-rw-r--r--sftp.c138
-rw-r--r--ssh-agent.06
-rw-r--r--ssh-agent.18
-rw-r--r--ssh-keygen.04
-rw-r--r--ssh-keygen.16
-rw-r--r--ssh-keygen.c10
-rw-r--r--ssh.c11
-rw-r--r--ssh2.h7
-rw-r--r--ssh_config.021
-rw-r--r--ssh_config.533
-rw-r--r--sshd.04
-rw-r--r--sshd.86
-rw-r--r--sshd.c2
-rw-r--r--sshkey.c3
-rw-r--r--sshsig.c27
-rw-r--r--version.h4
57 files changed, 1711 insertions, 1633 deletions
diff --git a/.github/ci-status.md b/.github/ci-status.md
index f3e088fd6043..8d4cea10dba4 100644
--- a/.github/ci-status.md
+++ b/.github/ci-status.md
@@ -6,6 +6,10 @@ master :
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh)
[![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable)
+9.4 :
+[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_4)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_4)
+[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_4)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_4)
+
9.3 :
[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_3)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_3)
[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_3)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_3)
diff --git a/.github/configs b/.github/configs
index e054eb3196b5..c7d6a55ab962 100755
--- a/.github/configs
+++ b/.github/configs
@@ -30,6 +30,13 @@ case "$config" in
default|sol64)
;;
c89)
+ # If we don't have LLONG_MAX, configure will figure out that it can
+ # get it by setting -std=gnu99, at which point we won't be testing
+ # C89 any more. To avoid this, feed it in via CFLAGS.
+ llong_max=`gcc -E -dM - </dev/null | \
+ awk '$2=="__LONG_LONG_MAX__"{print $3}'`
+ CPPFLAGS="-DLLONG_MAX=${llong_max}"
+
CC="gcc"
CFLAGS="-Wall -std=c89 -pedantic -Werror=vla"
CONFIGFLAGS="--without-zlib"
@@ -205,6 +212,10 @@ case "$config" in
;;
esac
;;
+ zlib-develop)
+ INSTALL_ZLIB=develop
+ CONFIGFLAGS="--with-zlib=/opt/zlib --with-rpath=-Wl,-rpath,"
+ ;;
*)
echo "Unknown configuration $config"
exit 1
diff --git a/.github/setup_ci.sh b/.github/setup_ci.sh
index 154f51bdc205..010a333a6642 100755
--- a/.github/setup_ci.sh
+++ b/.github/setup_ci.sh
@@ -133,6 +133,8 @@ for TARGET in $TARGETS; do
valgrind*)
PACKAGES="$PACKAGES valgrind"
;;
+ zlib-*)
+ ;;
*) echo "Invalid option '${TARGET}'"
exit 1
;;
@@ -214,3 +216,9 @@ if [ ! -z "${INSTALL_BORINGSSL}" ]; then
cp ${HOME}/boringssl/build/crypto/libcrypto.a /opt/boringssl/lib &&
cp -r ${HOME}/boringssl/include /opt/boringssl)
fi
+
+if [ ! -z "${INSTALL_ZLIB}" ]; then
+ (cd ${HOME} && git clone https://github.com/madler/zlib.git &&
+ cd ${HOME}/zlib && ./configure && make &&
+ sudo make install prefix=/opt/zlib)
+fi
diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml
index e4e2a64e05d2..be0c97f84cfd 100644
--- a/.github/workflows/c-cpp.yml
+++ b/.github/workflows/c-cpp.yml
@@ -73,6 +73,7 @@ jobs:
- { target: ubuntu-latest, config: openssl-3.1.0 }
- { target: ubuntu-latest, config: openssl-1.1.1_stable }
- { target: ubuntu-latest, config: openssl-3.0 } # 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 }
diff --git a/.github/workflows/selfhosted.yml b/.github/workflows/selfhosted.yml
index e84db699ea31..de0a4125bf08 100644
--- a/.github/workflows/selfhosted.yml
+++ b/.github/workflows/selfhosted.yml
@@ -40,6 +40,8 @@ jobs:
- obsd67
- obsd69
- obsd70
+ - obsd72
+ - obsd73
- obsdsnap
- obsdsnap-i386
- openindiana
@@ -76,6 +78,7 @@ jobs:
- { 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:
diff --git a/ChangeLog b/ChangeLog
index 3e16fbfd346d..61725d3a136b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,22 +1,509 @@
-commit daa5b2d869ee5a16f3ef9035aa0ad3c70cf4028e
+commit 80a2f64b8c1d27383cc83d182b73920d1e6a91f1
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 4 15:34:10 2023 +1100
+
+ crank version numbers
+
+commit f65f187b105d9b5c12fd750a211397d08c17c6d4
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 4 04:04:09 2023 +0000
+
+ upstream: openssh-9.5
+
+ OpenBSD-Commit-ID: 5e0af680480bd3b6f5560cf840ad032d48fd6b16
+
+commit ffe27e54a4bb18d5d3bbd3f4cc93a41b8d94dfd2
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Oct 4 04:03:50 2023 +0000
+
+ upstream: add some cautionary text about % token expansion and
+
+ shell metacharacters; based on report from vinci AT protonmail.ch
+
+ OpenBSD-Commit-ID: aa1450a54fcee2f153ef70368d90edb1e7019113
+
+commit 60ec3d54fd1ebfe2dda75893fa1e870b8dffbb0d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Oct 3 23:56:10 2023 +0000
+
+ upstream: fix link to agent draft; spotted by Jann Horn
+
+ OpenBSD-Commit-ID: ff5bda21a83ec013db683e282256a85201d2dc4b
+
+commit 12e2d4b13f6f63ce2de13cbfcc9e4d0d4b4ab231
+Author: Damien Miller <djm@mindrot.org>
+Date: Wed Oct 4 10:54:04 2023 +1100
+
+ use portable provider allowlist path in manpage
+
+ spotted by Jann Horn
+
+commit 6c2c6ffde75df95fd838039850d3dd3d84956d87
+Author: deraadt@openbsd.org <deraadt@openbsd.org>
+Date: Tue Sep 19 20:37:07 2023 +0000
+
+ upstream: typo; from Jim Spath
+
+ OpenBSD-Commit-ID: 2f5fba917b5d4fcf93d9e0b0756c7f63189e228e
+
+commit b6b49130a0089b297245ee39e769231d7c763014
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 10 23:12:32 2023 +0000
+
+ upstream: rename remote_glob() -> sftp_glob() to match other API
+
+ OpenBSD-Commit-ID: d9dfb3708d824ec02970a84d96cf5937e0887229
+
+commit 21b79af6c8d2357c822c84cef3fbdb8001ed263b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 10 03:51:55 2023 +0000
+
+ upstream: typo in comment
+
+ OpenBSD-Commit-ID: 69285e0ce962a7c6b0ab5f17a293c60a0a360a18
+
+commit 41232d25532b4d2ef6c5db62efc0cf50a79d26ca
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Sep 10 15:45:38 2023 +1000
+
+ Use zero-call-used-regs=used with Apple compilers.
+
+ Apple's versions of clang have version numbers that do not match the
+ corresponding upstream clang versions. Unfortunately, they do still
+ have the clang-15 zero-call-used-regs=all bug, so for now use the value
+ that doesn't result in segfaults. We could allowlist future versions
+ that are known to work. bz#3584 (and probably also our github CI
+ failures).
+
+commit 90ccc5918ea505bf156c31148b6b59a1bf5d6dc6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 10 03:25:53 2023 +0000
+
+ upstream: randomise keystroke obfuscation intervals and average
+
+ interval rate. ok dtucker@
+
+ OpenBSD-Commit-ID: 05f61d051ab418fcfc4857ff306e420037502382
+
+commit bd1b9e52f5fa94d87223c90905c5fdc1a7c32aa6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 8 06:34:24 2023 +0000
+
+ upstream: fix sizeof(*ptr) instead sizeof(ptr) in realloc (pointer here
+
+ is char**, so harmless); spotted in CID 416964
+
+ OpenBSD-Commit-ID: c61caa4a5a667ee20bb1042098861e6c72c69002
+
+commit c4f966482983e18601eec70a1563115de836616f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 8 06:10:57 2023 +0000
+
+ upstream: regress test recursive remote-remote directories copies where
+
+ the directory contains a symlink to another directory.
+
+ also remove errant `set -x` that snuck in at some point
+
+ OpenBSD-Regress-ID: 1c94a48bdbd633ef2285954ee257725cd7bc456f
+
+commit 5e1dfe5014ebc194641678303e22ab3bba15f4e5
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 8 06:10:02 2023 +0000
+
+ upstream: fix recursive remote-remote copies of directories that
+
+ contain symlinks to other directories (similar to bz3611)
+
+ OpenBSD-Commit-ID: 7e19d2ae09b4f941bf8eecc3955c9120171da37f
+
+commit 7c0ce2bf98b303b6ad91493ee3247d96c18ba1f6
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 8 05:50:57 2023 +0000
+
+ upstream: regress test for recursive copies of directories containing
+
+ symlinks to other directories. bz3611, ok dtucker@
+
+ OpenBSD-Regress-ID: eaa4c29cc5cddff4e72a16bcce14aeb1ecfc94b9
+
+commit 2de990142a83bf60ef694378b8598706bc654b08
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 8 05:56:13 2023 +0000
+
+ upstream: the sftp code was one of my first contributions to
+
+ OpenSSH and it shows - the function names are terrible.
+
+ Rename do_blah() to sftp_blah() to make them less so.
+
+ Completely mechanical except for sftp_stat() and sftp_lstat() which
+ change from returning a pointer to a static variable (error-prone) to
+ taking a pointer to a caller-provided receiver.
+
+ OpenBSD-Commit-ID: eb54d6a72d0bbba4d623e2175cf5cc4c75dc2ba4
+
+commit 249d8bd0472b53e3a2a0e138b4c030a31e83346a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Sep 8 05:50:12 2023 +0000
+
+ upstream: fix scp in SFTP mode recursive upload and download of
+
+ directories that contain symlinks to other directories. In scp mode, the
+ links would be followed, but in SFTP mode they were not. bz3611, ok dtucker@
+
+ OpenBSD-Commit-ID: 9760fda668eaa94a992250d7670dfbc62a45197c
+
+commit 0e1f4401c466fa4fdaea81b6dadc8dd1fc4cf0af
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 6 23:36:09 2023 +0000
+
+ upstream: regression test for override of subsystem in match blocks
+
+ OpenBSD-Regress-ID: 5f8135da3bfda71067084c048d717b0e8793e87c
+
+commit 8a1450c62035e834d8a79a5d0d1c904236f9dcfe
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 6 23:35:35 2023 +0000
+
+ upstream: allow override of Sybsystem directives in sshd Match
+
+ blocks
+
+ OpenBSD-Commit-ID: 3911d18a826a2d2fe7e4519075cf3e57af439722
+
+commit 6e52826e2a74d077147a82ead8d4fbd5b54f4e3b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 6 23:26:37 2023 +0000
+
+ upstream: allocate the subsystems array as necessary and remove the
+
+ fixed limit of subsystems. Saves a few kb of memory in the server and makes
+ it more like the other options.
+
+ OpenBSD-Commit-ID: e683dfca6bdcbc3cc339bb6c6517c0c4736a547f
+
+commit e19069c9fac4c111d6496b19c7f7db43b4f07b4f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 6 23:23:53 2023 +0000
+
+ upstream: preserve quoting of Subsystem commands and arguments.
+
+ This may change behaviour of exotic configurations, but the most common
+ subsystem configuration (sftp-server) is unlikely to be affected.
+
+ OpenBSD-Commit-ID: 8ffa296aeca981de5b0945242ce75aa6dee479bf
+
+commit 52dfe3c72d98503d8b7c6f64fc7e19d685636c0b
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 6 23:21:36 2023 +0000
+
+ upstream: downgrade duplicate Subsystem directives from being a
+
+ fatal error to being a debug message to match behaviour with just about all
+ other directives.
+
+ OpenBSD-Commit-ID: fc90ed2cc0c18d4eb8e33d2c5e98d25f282588ce
+
+commit 1ee0a16e07b6f0847ff463d7b5221c4bf1876e25
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Sep 6 23:18:15 2023 +0000
+
+ upstream: handle cr+lf (instead of just cr) in sshsig signature
+
+ files
+
+ OpenBSD-Commit-ID: 647460a212b916540016d066568816507375fd7f
+
+commit e1c284d60a928bcdd60bc575c6f9604663502770
+Author: job@openbsd.org <job@openbsd.org>
+Date: Mon Sep 4 10:29:58 2023 +0000
+
+ upstream: Generate Ed25519 keys when invoked without arguments
+
+ Ed25519 public keys are very convenient due to their small size.
+ OpenSSH has supported Ed25519 since version 6.5 (January 2014).
+
+ OK djm@ markus@ sthen@ deraadt@
+
+ OpenBSD-Commit-ID: f498beaad19c8cdcc357381a60df4a9c69858b3f
+
+commit 694150ad92765574ff82a18f4e86322bd3231e68
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 4 00:08:14 2023 +0000
+
+ upstream: trigger keystroke timing obfucation only if the channels
+
+ layer enqueud some data in the last poll() cycle; this avoids triggering the
+ obfuscatior for non-channels data like ClientAlive probes and also fixes a
+ related problem were the obfucations would be triggered on fully quiescent
+ connections.
+
+ Based on / tested by naddy@
+
+ OpenBSD-Commit-ID: d98f32dc62d7663ff4660e4556e184032a0db123
+
+commit b5fd97896b59a3a46245cf438cc8b16c795d9f74
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 4 00:04:02 2023 +0000
+
+ upstream: avoid bogus "obfuscate_keystroke_timing: stopping ..."
+
+ debug messages when keystroke timing obfuscation was never started; spotted
+ by naddy@
+
+ OpenBSD-Commit-ID: 5c270d35f7d2974db5c1646e9c64188f9393be31
+
+commit ccf7d913db34e49b7a6db1b8331bd402004c840d
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Sep 4 00:01:46 2023 +0000
+
+ upstream: make channel_output_poll() return a flag indicating
+
+ whether channel data was enqueued. Will be used to improve keystroke timing
+ obfuscation. Problem spotted by / tested by naddy@
+
+ OpenBSD-Commit-ID: f9776c7b0065ba7c3bbe50431fd3b629f44314d0
+
+commit 43254b326ac6e2131dbd750f9464dc62c14bd5a7
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Sun Sep 3 23:59:32 2023 +0000
+
+ upstream: set interactive mode for ControlPersist sessions if they
+
+ originally requested a tty; enables keystroke timing obfuscation for most
+ ControlPersist sessions. Spotted by naddy@
+
+ OpenBSD-Commit-ID: 72783a26254202e2f3f41a2818a19956fe49a772
+
+commit ff3eda68ceb2e2bb8f48e3faceb96076c3e85c20
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Aug 31 23:02:35 2023 +1000
+
+ Set LLONG_MAX for C89 test.
+
+ If we don't have LLONG_MAX, configure will figure out that it can get it
+ by setting -std=gnu99, at which point we won't be testing C89 any more.
+ To avoid this, feed it in via CFLAGS.
+
+commit f98031773db361424d59e3301aa92aacf423d920
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Tue Aug 29 02:50:10 2023 +0000
+
+ upstream: make PerSourceMaxStartups first-match-wins; ok dtucker@
+
+ OpenBSD-Commit-ID: dac0c24cb709e3c595b8b4f422a0355dc5a3b4e7
+
+commit cfa66857db90cd908de131e0041a50ffc17c7df8
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 28 09:52:09 2023 +0000
+
+ upstream: descriptive text shouldn't be under .Cm
+
+ OpenBSD-Commit-ID: b1afaeb456a52bc8a58f4f9f8b2f9fa8f6bf651b
+
+commit 01dbf3d46651b7d6ddf5e45d233839bbfffaeaec
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 28 09:48:11 2023 +0000
+
+ upstream: limit artificial login delay to a reasonable maximum (5s)
+
+ and don't delay at all for the "none" authentication mechanism. Patch by
+ Dmitry Belyavskiy in bz3602 with polish/ok dtucker@
+
+ OpenBSD-Commit-ID: 85b364676dd84cf1de0e98fc2fbdcb1a844ce515
+
+commit 528da5b9d7c5da01ed7a73ff21c722e1b5326006
+Author: jmc@openbsd.org <jmc@openbsd.org>
+Date: Mon Aug 28 05:32:28 2023 +0000
+
+ upstream: add spacing for punctuation when macro args;
+
+ OpenBSD-Commit-ID: e80343c16ce0420b2aec98701527cf90371bd0db
+
+commit 3867361ca691d0956ef7d5fb8181cf554a91d84a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 28 04:06:52 2023 +0000
+
+ upstream: explicit long long type in timing calculations (doesn't
+
+ matter, since the range is pre-clamped)
+
+ OpenBSD-Commit-ID: f786ed902d04a5b8ecc581d068fea1a79aa772de
+
+commit 7603ba71264e7fa938325c37eca993e2fa61272f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 28 03:31:16 2023 +0000
+
+ upstream: Add keystroke timing obfuscation to the client.
+
+ This attempts to hide inter-keystroke timings by sending interactive
+ traffic at fixed intervals (default: every 20ms) when there is only a
+ small amount of data being sent. It also sends fake "chaff" keystrokes
+ for a random interval after the last real keystroke. These are
+ controlled by a new ssh_config ObscureKeystrokeTiming keyword/
+
+ feedback/ok markus@
+
+ OpenBSD-Commit-ID: 02231ddd4f442212820976068c34a36e3c1b15be
+
+commit dce6d80d2ed3cad2c516082682d5f6ca877ef714
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 28 03:28:43 2023 +0000
+
+ upstream: Introduce a transport-level ping facility
+
+ This adds a pair of SSH transport protocol messages SSH2_MSG_PING/PONG
+ to implement a ping capability. These messages use numbers in the "local
+ extensions" number space and are advertised using a "ping@openssh.com"
+ ext-info message with a string version number of "0".
+
+ ok markus@
+
+ OpenBSD-Commit-ID: b6b3c4cb2084c62f85a8dc67cf74954015eb547f
+
+commit d2d247938b38b928f8a6e1a47a330c5584d3a358
+Author: tobhe@openbsd.org <tobhe@openbsd.org>
+Date: Mon Aug 21 21:16:18 2023 +0000
+
+ upstream: Log errors in kex_exchange_identification() with level
+
+ verbose instead of error to reduce preauth log spam. All of those get logged
+ with a more generic error message by sshpkt_fatal().
+
+ feedback from sthen@
+ ok djm@
+
+ OpenBSD-Commit-ID: bd47dab4695b134a44c379f0e9a39eed33047809
+
+commit 9d7193a8359639801193ad661a59d1ae4dc3d302
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 21 04:59:54 2023 +0000
+
+ upstream: correct math for ClientAliveInterval that caused the
+
+ probes to be sent less frequently than configured; from Dawid Majchrzak
+
+ OpenBSD-Commit-ID: 641153e7c05117436ddfc58267aa267ca8b80038
+
+commit 3c6ab63b383b0b7630da175941e01de9db32a256
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Fri Aug 25 14:48:02 2023 +1000
+
+ Include Portable version in sshd version string.
+
+ bz#3608, ok djm@
+
+commit 17fa6cd10a26e193bb6f65d21264d2fe553bcd87
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 21 19:47:58 2023 +1000
+
+ obsd-arm64 host is real hardware...
+
+ so put in the correct config location.
+
+commit 598ca75c85acaaacee5ef954251e489cc20d7be9
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 21 18:38:36 2023 +1000
+
+ Add OpenBSD ARM64 test host.
+
+commit 1acac79bfbe207e8db639e8043524962037c8feb
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 21 18:05:26 2023 +1000
+
+ Add test for zlib development branch.
+
+commit 84efebf352fc700e9040c8065707c63caedd36a3
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 21 04:36:46 2023 +0000
+
+ upstream: want stdlib.h for free(3)
+
+ OpenBSD-Commit-ID: 743af3c6e3ce5e6cecd051668f0327a01f44af29
+
+commit cb4ed12ffc332d1f72d054ed92655b5f1c38f621
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sat Aug 19 07:39:08 2023 +1000
+
+ Fix zlib version check for 1.3 and future version.
+
+ bz#3604.
+
+commit 25b75e21f16bccdaa472ea1889b293c9bd51a87b
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Mon Aug 14 11:10:08 2023 +1000
+
+ Add 9.4 branch to CI status page.
+
+commit 803e22eabd3ba75485eedd8b7b44d6ace79f2052
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Fri Aug 18 01:37:41 2023 +0000
+
+ upstream: fix regression in OpenSSH 9.4 (mux.c r1.99) that caused
+
+ multiplexed sessions to ignore SIGINT under some circumstances. Reported by /
+ feedback naddy@, ok dtucker@
+
+ OpenBSD-Commit-ID: 4d5c6c894664f50149153fd4764f21f43e7d7e5a
+
+commit e706bca324a70f68dadfd0ec69edfdd486eed23a
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Wed Aug 16 16:14:11 2023 +0000
+
+ upstream: defence-in-depth MaxAuthTries check in monitor; ok markus
+
+ OpenBSD-Commit-ID: 65a4225dc708e2dae71315adf93677edace46c21
+
+commit d1ab7eb90474df656d5e9935bae6df0bd000d343
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Mon Aug 14 03:37:00 2023 +0000
+
+ upstream: add message number of SSH2_MSG_NEWCOMPRESS defined in RFC8308
+
+ OpenBSD-Commit-ID: 6c984171c96ed67effd7b5092f3d3975d55d6028
+
+commit fa8da52934cb7dff6f660a143276bdb28bb9bbe1
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Sun Aug 13 15:01:27 2023 +1000
+
+ Add obsd72 and obsd73 test targets.
+
+commit f9f18006678d2eac8b0c5a5dddf17ab7c50d1e9f
+Author: djm@openbsd.org <djm@openbsd.org>
+Date: Thu Aug 10 23:05:48 2023 +0000
+
+ upstream: better debug logging of sessions' exit status
+
+ OpenBSD-Commit-ID: 82237567fcd4098797cbdd17efa6ade08e1a36b0
+
+commit a8c57bcb077f0cfdffcf9f23866bf73bb93e185c
+Author: naddy@openbsd.org <naddy@openbsd.org>
+Date: Thu Aug 10 14:37:32 2023 +0000
+
+ upstream: drop a wayward comma, ok jmc@
+
+ OpenBSD-Commit-ID: 5c11fbb9592a29b37bbf36f66df50db9d38182c6
+
+commit e962f9b318a238db1becc53c2bf79dd3a49095b4
Author: Damien Miller <djm@mindrot.org>
Date: Thu Aug 10 11:10:22 2023 +1000
depend
-commit 41bfb63f5101fbacde9d8d2ada863f9ee16df194
+commit 0fcb60bf83130dfa428bc4422b3a3ac20fb528af
Author: Damien Miller <djm@mindrot.org>
Date: Thu Aug 10 11:05:42 2023 +1000
update versions in RPM specs
-commit e598b92b1eecedac21667edf1fe92078eaf8f2b1
+commit d0cee4298491314f09afa1c4383a66d913150b26
Author: Damien Miller <djm@mindrot.org>
Date: Thu Aug 10 11:05:14 2023 +1000
update version in README
-commit e797e5ffa74377c8696e3b0559a258d836479239
+commit 78b4dc6684f4d35943b46b24ee645edfdb9974f5
Author: djm@openbsd.org <djm@openbsd.org>
Date: Thu Aug 10 01:01:07 2023 +0000
@@ -24,6 +511,12 @@ Date: Thu Aug 10 01:01:07 2023 +0000
OpenBSD-Commit-ID: 71fc1e01a4c4ea061b252bd399cda7be757e6e35
+commit 58ca4f0aa8c4306ac0a629c9a85fb1efaf4ff092
+Author: Darren Tucker <dtucker@dtucker.net>
+Date: Thu Aug 10 11:30:24 2023 +1000
+
+ Only include unistd.h once.
+
commit 3961ed02dc578517a9d2535128cff5c3a5460d28
Author: Damien Miller <djm@mindrot.org>
Date: Thu Aug 10 09:08:49 2023 +1000
@@ -9062,1113 +9555,3 @@ Date: Wed Oct 6 13:16:21 2021 +1100
fix broken OPENSSL_HAS_ECC test
spotted by dtucker
-
-commit 16a25414f303cd6790eb967aeb962040e32c9c7a
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 22:40:06 2021 +1000
-
- make sk-dummy.so work without libcrypto installed
-
-commit dee22129bbc61e25b1003adfa2bc584c5406ef2d
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 16:35:49 2021 +1000
-
- make OPENSSL_HAS_ECC checks more thorough
-
- ok dtucker
-
-commit 872595572b6c9a584ed754165e8b7c4c9e7e1d61
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 16:35:05 2021 +1000
-
- fix FIDO key support for !OPENSSL_HAS_ECC case
-
- ok dtucker
-
-commit 489741dc68366940d369ac670b210b4834a6c272
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 14:51:37 2021 +1000
-
- enable security key support for --without-openssl
-
-commit c978565c8589acfe4ea37ab5099d39c84158c713
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Oct 1 13:27:50 2021 +1000
-
- need stdlib.h for free(3)
-
-commit 76a398edfb51951b2d65d522d7b02c72304db300
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 30 05:26:26 2021 +0000
-
- upstream: Fix up whitespace left by previous
-
- change removing privsep. No other changes.
-
- OpenBSD-Regress-ID: 87adec225d8afaee4d6a91b2b71203f52bf14b15
-
-commit ddcb53b7a7b29be65d57562302b2d5f41733e8dd
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 30 05:20:08 2021 +0000
-
- upstream: Remove references to privsep.
-
- This removes several do..while loops but does not change the
- indentation of the now-shallower loops, which will be done in a separate
- whitespace-only commit to keep changes of style and substance separate.
-
- OpenBSD-Regress-ID: 4bed1a0249df7b4a87c965066ce689e79472a8f7
-
-commit ece2fbe486164860de8df3f8b943cccca3085eff
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Thu Sep 30 04:22:50 2021 +0000
-
- upstream: Use "skip" instead of "fatal"
-
- if SUDO isn't set for the *-command tests. This means running "make tests"
- without SUDO set will perform all of the tests that it can instead of
- failing on the ones it cannot run.
-
- OpenBSD-Regress-ID: bd4dbbb02f34b2e8c890558ad4a696248def763a
-
-commit bb754b470c360e787a99fb4e88e2668198e97b41
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Oct 1 04:50:36 2021 +0000
-
- upstream: unbreak FIDO sk-ed25519 key enrollment for OPENSSL=no builds;
-
- ok dtucker@
-
- OpenBSD-Commit-ID: 6323a5241728626cbb2bf0452cf6a5bcbd7ff709
-
-commit 207648d7a6415dc915260ca75850404dbf9f0a0b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 20:03:58 2021 +1000
-
- Include stdlib.h for arc4random_uniform prototype.
-
-commit 696aadc854582c164d5fc04933d2f3e212dc0e06
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 20:00:30 2021 +1000
-
- Look for clang after cc and gcc.
-
-commit a3c6375555026d85dbf811fab566b9f76f196144
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 19:30:59 2021 +1000
-
- Use backticks instead of $(..) for portability.
-
- Older shells (eg /bin/sh on Solaris 10) don't support $() syntax.
-
-commit 958aaa0387133d51f84fe9c8f30bca03025f2867
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 18:53:32 2021 +1000
-
- Skip file-based tests by default on Mac OS.
-
- The file-based tests need OpenSSL so skip them.
-
-commit 55c8bdf6e9afb0f9fa8e4f10c25c7f0081b48fd0
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 18:42:47 2021 +1000
-
- Build without OpenSSL on Mac OS.
-
- Modern versions don't ship enough libcrypto to build against.
-
-commit c9172193ea975415facf0afb356d87df21535f88
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 18:33:38 2021 +1000
-
- Remove TEST_SSH_ECC.
-
- Convert the only remaining user of it to runtime detection using ssh -Q.
-
-commit 5e6d28b7874b0deae95d2c68947c45212d32e599
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:48:09 2021 +1000
-
- Split c89 test openssl setting out.
-
-commit c4ac7f98e230e83c015678dc958b1ffe828564ad
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:40:50 2021 +1000
-
- Expand TEST_SHELL consistently with other vars.
-
-commit cfe5f7b0eb7621bfb0a756222de0431315c2ab8b
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:26:50 2021 +1000
-
- Replace `pwd` with make variable in regress cmd.
-
-commit 899be59da5fbc3372444bd0fbe74af48313bed33
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 17:14:33 2021 +1000
-
- Get BUILDDIR from autoconf.
-
- Use this to replace `pwd`s in regress test command line.
-
-commit c8d92d3d4f7d560146f2f936156ec4dac3fc5811
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 13:28:56 2021 +1000
-
- Add make clean step to tests.
-
-commit 360fb41ef8359619ab90b0d131c914494e55d3dd
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 11:36:13 2021 +1000
-
- Test all available clang and gcc versions.
-
-commit 4fb49899d7da22952d35a4bc4c9bdb2311087893
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 29 01:32:21 2021 +0000
-
- upstream: Test certificate hostkeys held in ssh-agent too. Would have
-
- caught regression fixed in sshd r1.575
-
- ok markus@
-
- OpenBSD-Regress-ID: 1f164d7bd89f83762db823eec4ddf2d2556145ed
-
-commit ce4854e12e749a05646e5775e9deb8cfaf49a755
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 29 01:33:32 2021 +0000
-
- upstream: add some debug output showing how many key file/command lines
-
- were processed. Useful to see whether a file or command actually has keys
- present
-
- OpenBSD-Commit-ID: 0bd9ff94e84e03a22df8e6c12f6074a95d27f23c
-
-commit 15abdd523501c349b703d9a27e2bb4252ad921ef
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Sep 28 11:14:50 2021 +0000
-
- upstream: Make prototype for rijndaelEncrypt match function
-
- including the bounds. Fixes error in portable where GCC>=11 takes notice of
- the bounds. ok deraadt@
-
- OpenBSD-Commit-ID: cdd2f05fd1549e1786a70871e513cf9e9cf099a6
-
-commit d1d29ea1d1ef1a1a54b209f062ec1dcc8399cf03
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Sep 28 11:10:05 2021 +0000
-
- upstream: Import regenerated moduli.
-
- OpenBSD-Commit-ID: 4bec5db13b736b64b06a0fca704cbecc2874c8e1
-
-commit 39f2111b1d5f00206446257377dcce58cc72369f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 29 10:53:55 2021 +1000
-
- Add new compiler hardening flags.
-
- Add -fzero-call-used-regs and -ftrivial-auto-var-init to the list of
- compiler hardening flags that configure checks for. These are supported
- by clang and gcc, and make ROP gadgets less useful and mitigate
- stack-based infoleaks respectively. ok djm@
-
-commit bf944e3794eff5413f2df1ef37cddf96918c6bde
-Author: Damien Miller <djm@mindrot.org>
-Date: Mon Sep 27 00:03:19 2021 +1000
-
- initgroups needs grp.h
-
-commit 8c5b5655149bd76ea21026d7fe73ab387dbc3bc7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 26 14:01:11 2021 +0000
-
- upstream: openssh-8.8
-
- OpenBSD-Commit-ID: 12357794602ac979eb7312a1fb190c453f492ec4
-
-commit f3cbe43e28fe71427d41cfe3a17125b972710455
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Sep 26 14:01:03 2021 +0000
-
- upstream: need initgroups() before setresgid(); reported by anton@,
-
- ok deraadt@
-
- OpenBSD-Commit-ID: 6aa003ee658b316960d94078f2a16edbc25087ce
-
-commit 8acaff41f7518be40774c626334157b1b1c5583c
-Author: Damien Miller <djm@mindrot.org>
-Date: Sun Sep 26 22:16:36 2021 +1000
-
- update version numbers for release
-
-commit d39039ddc0010baa91c70a0fa0753a2699bbf435
-Author: kn@openbsd.org <kn@openbsd.org>
-Date: Sat Sep 25 09:40:33 2021 +0000
-
- upstream: RSA/SHA-1 is not used by default anymore
-
- OK dtucker deraadt djm
-
- OpenBSD-Commit-ID: 055c51a221c3f099dd75c95362f902da1b8678c6
-
-commit 9b2ee74e3aa8c461eb5552a6ebf260449bb06f7e
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 24 11:08:03 2021 +1000
-
- Move the fgrep replacement to hostkey-rotate.sh.
-
- The fgrep replacement for buggy greps doesn't work in the sftp-glob test
- so move it to just where we know it's needed.
-
-commit f7039541570d4b66d76e6f574544db176d8d5c02
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 24 08:04:14 2021 +1000
-
- Replacement function for buggy fgrep.
-
- GNU (f)grep <=2.18, as shipped by FreeBSD<=12 and NetBSD<=9 will
- occasionally fail to find ssh host keys in the hostkey-rotate test.
- If we have those versions, use awk instead.
-
-commit f6a660e5bf28a01962af87568e118a2d2e79eaa0
-Author: David Manouchehri <david.manouchehri@riseup.net>
-Date: Thu Sep 23 17:03:18 2021 -0400
-
- Don't prompt for yes/no questions.
-
-commit 7ed1a3117c09f8c3f1add35aad77d3ebe1b85b4d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 20 06:53:56 2021 +0000
-
- upstream: fix missing -s in SYNOPSYS and usage() as well as a
-
- capitalisation mistake; spotted by jmc@
-
- OpenBSD-Commit-ID: 0ed8ee085c7503c60578941d8b45f3a61d4c9710
-
-commit 8c07170135dde82a26886b600a8bf6fb290b633d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Mon Sep 20 04:02:13 2021 +0000
-
- upstream: Fix "Allocated port" debug message
-
- for unix domain sockets. From peder.stray at gmail.com via github PR#272,
- ok deraadt@
-
- OpenBSD-Commit-ID: 8d5ef3fbdcdd29ebb0792b5022a4942db03f017e
-
-commit 277d3c6adfb128b4129db08e3d65195d94b55fe7
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Sep 20 01:55:42 2021 +0000
-
- upstream: Switch scp back to use the old protocol by default, ahead of
-
- release. We'll wait a little longer for people to pick up sftp-server(8) that
- supports the extension that scp needs for ~user paths to continue working in
- SFTP protocol mode. Discussed with deraadt@
-
- OpenBSD-Commit-ID: f281f603a705fba317ff076e7b11bcf2df941871
-
-commit ace19b34cc15bea3482be90450c1ed0cd0dd0669
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 18 02:03:25 2021 +0000
-
- upstream: better error message for ~user failures when the
-
- sftp-server lacks the expand-path extension; ok deraadt@
-
- OpenBSD-Commit-ID: 9c1d965d389411f7e86f0a445158bf09b8f9e4bc
-
-commit 6b1238ba971ee722a310d95037b498ede5539c03
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 16 15:22:22 2021 +0000
-
- upstream: make some more scp-in-SFTP mode better match Unix idioms
-
- suggested by deraadt@
-
- OpenBSD-Commit-ID: 0f2439404ed4cf0b0be8bf49a1ee734836e1ac87
-
-commit e694f8ac4409931e67d08ac44ed251b20b10a957
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 16 15:11:19 2021 +0000
-
- upstream: allow log_stderr==2 to prefix log messages with argv[0]
-
- use this to make scp's SFTP mode error messages more scp-like
-
- prompted by and ok deraadt@
-
- OpenBSD-Commit-ID: 0e821dbde423fc2280e47414bdc22aaa5b4e0733
-
-commit 8a7a06ee505cb833e613f74a07392e9296286c30
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Sep 17 13:03:31 2021 +1000
-
- Test against LibreSSL 3.2.6, 3.3.4, 3.4.0.
-
-commit c25c84074a47f700dd6534995b4af4b456927150
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Sep 16 05:36:03 2021 +0000
-
- upstream: missing space character in ssh -G output broke the
-
- t-sshcfgparse regression test; spotted by anton@
-
- OpenBSD-Commit-ID: bcc36fae2f233caac4baa8e58482da4aa350eed0
-
-commit a4bee1934bf5e5575fea486628f4123d6a29dff8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 15 06:56:01 2021 +0000
-
- upstream: allow CanonicalizePermittedCNAMEs=none in ssh_config; ok
-
- markus@
-
- OpenBSD-Commit-ID: 668a82ba8e56d731b26ffc5703213bfe071df623
-
-commit d0fffc88c8fe90c1815c6f4097bc8cbcabc0f3dd
-Author: mbuhl@openbsd.org <mbuhl@openbsd.org>
-Date: Tue Sep 14 11:04:21 2021 +0000
-
- upstream: put back the mux_ctx memleak fix for SSH_CHANNEL_MUX_CLIENT
-
- OK mfriedl@
-
- OpenBSD-Commit-ID: 1aba1da828956cacaadb81a637338734697d9798
-
-commit 19b3d846f06697c85957ab79a63454f57f8e22d6
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Sat Sep 11 09:05:50 2021 +0000
-
- upstream: Do not ignore SIGINT while waiting for input if editline(3)
-
- is not used. Instead, in non-interactive mode, exit sftp(1), like for other
- serious errors. As pointed out by dtucker@, when compiled without editline(3)
- support in portable OpenSSH, the el == NULL branch is also used for
- interactive mode. In that case, discard the input line and provide a fresh
- prompt to the user just like in the case where editline(3) is used. OK djm@
-
- OpenBSD-Commit-ID: 7d06f4d3ebba62115527fafacf38370d09dfb393
-
-commit ba61123eef9c6356d438c90c1199a57a0d7bcb0a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sat Sep 11 00:40:24 2021 +0000
-
- upstream: when using SFTP protocol, continue transferring files after a
-
- transfer error occurs. This matches original scp/rcp behaviour. ok dtucker@
-
- OpenBSD-Commit-ID: dfe4558d71dd09707e9b5d6e7d2e53b793da69fa
-
-commit b0ec59a708b493c6f3940336b1a537bcb64dd2a7
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 10 11:38:38 2021 +0000
-
- upstream: Document that non-interactive commands are run via the user's
-
- shell using the -c flag. ok jmc@
-
- OpenBSD-Commit-ID: 4f0d912077732eead10423afd1acf4fc0ceec477
-
-commit 66a658b5d9e009ea11f8a0ca6e69c7feb2d851ea
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 10 10:26:02 2021 +0000
-
- upstream: Document behaviour of arguments following non-interactive
-
- commands. Prompted by github PR#139 from EvanTheB, feedback & ok djm@ jmc@
-
- OpenBSD-Commit-ID: fc758d1fe0471dfab4304fcad6cd4ecc3d79162a
-
-commit 1d47e28e407d1f95fdf8f799be23f48dcfa5206b
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 10 07:11:11 2021 +0000
-
- upstream: Clarify which file's attributes -p preserves, and that
-
- it's specifically the file mode bits. bz#3340 from calestyo at scientia.net,
- ok djm@ jmc@
-
- OpenBSD-Commit-ID: f09e6098ed1c4be00c730873049825f8ee7cb884
-
-commit b344db7a413478e4c21e4cadba4a970ad3e6128a
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Sep 10 05:46:09 2021 +0000
-
- upstream: openssh-7.4 was incorrectly listed twice; spotted by
-
- Dmitry Belyavskiy, ok dtucker@
-
- OpenBSD-Commit-ID: 4b823ae448f6e899927ce7b04225ac9e489f58ef
-
-commit 9136d6239ad7a4a293e0418a49b69e70c76d58b8
-Author: jmc@openbsd.org <jmc@openbsd.org>
-Date: Thu Sep 9 06:17:39 2021 +0000
-
- upstream: - move CAVEATS to its correct order - use the term
-
- "legacy" protocol rather than "original", as the latter made the text
- misleading - uppercase SCP
-
- ok djm
-
- OpenBSD-Commit-ID: 8479255746d5fa76a358ee59e7340fecf4245ff0
-
-commit 2d678c5e3bdc2f5c99f7af5122e9d054925d560d
-Author: David Carlier <devnexen@gmail.com>
-Date: Wed Sep 8 19:49:54 2021 +0100
-
- Disable tracing on FreeBSD using procctl.
-
- Placed at the start of platform_disable_tracing() to prevent declaration
- after code errors from strict C89 compilers (in the unlikely event that
- more than one method is enabled).
-
-commit 73050fa38fb36ae3326d768b574806352b97002d
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 8 23:31:39 2021 +0000
-
- upstream: Use the SFTP protocol by default. The original scp/rcp
-
- protocol remains available via the -O flag.
-
- Note that ~user/ prefixed paths in SFTP mode require a protocol extension
- that was first shipped in OpenSSH 8.7.
-
- ok deraadt, after baking in snaps for a while without incident
-
- OpenBSD-Commit-ID: 23588976e28c281ff5988da0848cb821fec9213c
-
-commit c4565e69ffa2485cff715aa842ea7a350296bfb6
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 21:09:49 2021 +1000
-
- Really fix test on OpenSSL 1.1.1 stable.
-
-commit 79f1bb5f56cef3ae9276207316345b8309248478
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 18:51:39 2021 +1000
-
- Correct OpenSSL 1.1.1 stable identifier.
-
-commit b6255593ed5ccbe5e7d3d4b26b2ad31ad4afc232
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 18:39:44 2021 +1000
-
- Increment nfds when coming from startup_pipe.
-
- If we have to increase nfds because startup_pipe[0] is above any of the
- descriptors passed in the fd_sets, we also need to add 1 to nfds since
- select takes highest FD number plus one. bz#3345 from yaroslav.kuzmin
- at vmssoftware.com.
-
-commit a3e92a6794817df6012ac8546aea19652cc91b61
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Sep 8 13:45:10 2021 +1000
-
- Tests for OpenSSL 3.0.0 release & 1.1.1 branch.
-
-commit 4afe431da98ec1cf6a2933fe5658f4fd68dee9e2
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Sep 8 03:23:44 2021 +0000
-
- upstream: correct my mistake in previous fix; spotted by halex
-
- OpenBSD-Commit-ID: 3cc62d92e3f70006bf02468fc146bfc36fffa183
-
-commit ca0e455b9331213ff9505a21b94c38e34faa2bba
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Sep 7 06:03:51 2021 +0000
-
- upstream: avoid NULL deref in -Y find-principals. Report and fix
-
- from Carlo Marcelo Arenas Belón
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
-
- OpenBSD-Commit-ID: 6238486f8ecc888d6ccafcd9ad99e621bb41f1e0
-
-commit 37616807f150fb46610bbd5031c31af4857ad1e9
-Author: millert@openbsd.org <millert@openbsd.org>
-Date: Mon Sep 6 00:36:01 2021 +0000
-
- upstream: revision 1.381 neglected to remove
-
- sChallengeResponseAuthentication from the enum. Noticed by
- christos@zoulas.com. OK dtucker@
-
- OpenBSD-Commit-ID: b533283a4dd6d04a867da411a4c7a8fbc90e34ff
-
-commit 7acb3578cdfec0b3d34501408071f7a96c1684ea
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Sep 5 20:45:42 2021 +1000
-
- Correct version_num for OpenSSL dev branch.
-
-commit 65bb01111320dfd0d25e21e1fd4d3f2b77532669
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Sep 5 19:37:39 2021 +1000
-
- Test against OpenSSL 3 branch as well as dev.
-
- Now that OpenSSL development has moved to 3.1, test against the most
- recent version of the openssl-3.0 branch too.
-
-commit 864ed0d5e04a503b97202c776b7cf3f163f3eeaa
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Sep 5 19:33:22 2021 +1000
-
- OpenSSL development is now 3.1.*
-
-commit a60209a586a928f92ab323bf23bd07f57093342e
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 07:43:23 2021 +0000
-
- upstream: Use .Cm instead of .Dq in StrictHostKeyChecking list for
-
- consistency. Patch from scop via github PR#257, ok jmc@
-
- OpenBSD-Commit-ID: 3652a91564570779431802c31224fb4a9cf39872
-
-commit 8d1d9eb6de37331e872700e9e399a3190cca1242
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 07:27:03 2021 +0000
-
- upstream: Mention using ssh -i for specifying the public key file
-
- in the case where the private key is loaded into ssh-agent but is not present
- locally. Based on patch from rafork via github PR#215, ok jmc@
-
- OpenBSD-Commit-ID: 2282e83b0ff78d2efbe705883b67240745fa5bb2
-
-commit eb4362e5e3aa7ac26138b11e44d8c191910aff64
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 05:25:50 2021 +0000
-
- upstream: Refer to KEX "algorithms" instead of "methods" to match
-
- other references and improve consistency. Patch from scop via github PR#241,
- ok djm@
-
- OpenBSD-Commit-ID: 840bc94ff6861b28d8603c8e8c16499bfb65e32c
-
-commit b3318946ce5725da43c4bf7eeea1b73129c47d2a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 05:12:25 2021 +0000
-
- upstream: Remove redundant attrib_clear in upload_dir_internal.
-
- The subsequent call to stat_to_attrib clears the struct as its first step
- anyway. From pmeinhardt via github PR#220, ok djm@
-
- OpenBSD-Commit-ID: f5234fc6d7425b607e179acb3383f21716f3029e
-
-commit 7cc3fe28896e653956a6a2eed0a25d551b83a029
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Fri Sep 3 04:11:13 2021 +0000
-
- upstream: Add test for client termination status on signal.
-
- Based on patch from Alexxz via github PR#235 with some tweaks, to
- match patch in bz#3281.
-
- OpenBSD-Regress-ID: d87c7446fb8b5f8b45894fbbd6875df326e729e2
-
-commit 5428b0d239f6b516c81d1dd15aa9fe9e60af75d4
-Author: deraadt@openbsd.org <deraadt@openbsd.org>
-Date: Thu Sep 2 21:03:54 2021 +0000
-
- upstream: sys/param.h is not needed for any visible reason
-
- OpenBSD-Commit-ID: 8bdea2d0c75692e4c5777670ac039d4b01c1f368
-
-commit 1ff38f34b4c4545eb28106629cafa1e0496bc726
-Author: Shchelkunov Artem <a.shchelkunov@ideco.ru>
-Date: Wed Aug 11 18:07:58 2021 +0500
-
- Fix memory leak in error path.
-
- *info is allocated via xstrdup but was leaked in the PAM_AUTH_ERR path.
- From github PR#266.
-
-commit cb37e2f0c0ca4fef844ed7edc5d0e3b7d0e83f6a
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Sep 1 03:16:06 2021 +0000
-
- upstream: Fix ssh-rsa fallback for old PuTTY interop tests.
-
- OpenBSD-Regress-ID: a19ac929da604843a5b5f0f48d2c0eb6e0773d37
-
-commit 8b02ef0f28dc24cda8cbcd8b7eb02bda8f8bbe59
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Wed Sep 1 00:50:27 2021 +0000
-
- upstream: Add a function to skip remaining tests.
-
- Many tests skip tests for various reasons but not in a consistent way and
- don't always clean up, so add that and switch the tests that do that over.
-
- OpenBSD-Regress-ID: 72d2ec90a3ee8849486956a808811734281af735
-
-commit d486845c07324c04240f1674ac513985bd356f66
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Aug 31 07:13:59 2021 +0000
-
- upstream: Specify path to PuTTY keys.
-
- Portable needs this and it makes no difference on OpenBSD, so resync
- them. (Id sync only, Portable already had this.)
-
- OpenBSD-Regress-ID: 33f6f66744455886d148527af8368811e4264162
-
-commit d22b299115e27606e846b23490746f69fdd4fb38
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Aug 31 06:13:23 2021 +0000
-
- upstream: Better compat tests with old PuTTY.
-
- When running PuTTY interop tests and using a PuTTY version older than
- 0.76, re-enable the ssh-rsa host key algorithm (the 256 and 512 variants
- of RSA were added some time between 0.73 and 0.76).
-
- OpenBSD-Regress-ID: e6138d6987aa705fa1e4f216db0bb386e1ff38e1
-
-commit 87ad70d605c3e39c9b8aa275db27120d7cc09b77
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 31 17:04:50 2021 +1000
-
- Resync PuTTY interop tests.
-
- Resync behaviour when REGRESS_INTEROP_PUTTY is not set with OpenBSD.
-
-commit e47b82a7bf51021afac218bf59a3be121827653d
-Author: dtucker@openbsd.org <dtucker@openbsd.org>
-Date: Tue Aug 31 01:25:27 2021 +0000
-
- upstream: Specify hostkeyalgorithms in SSHFP test.
-
- Specify host key algorithms in sshd's default set for the SSHFP test,
- from djm@. Make the reason for when the test is skipped a bit clearer.
-
- OpenBSD-Regress-ID: 4f923dfc761480d5411de17ea6f0b30de3e32cea
-
-commit 7db3e0a9e8477c018757b59ee955f7372c0b55fb
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 30 01:15:45 2021 +0000
-
- upstream: adapt to RSA/SHA1 deprectation
-
- OpenBSD-Regress-ID: 952397c39a22722880e4de9d1c50bb1a14f907bb
-
-commit 2344750250247111a6c3c6a4fe84ed583a61cc11
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Aug 29 23:53:10 2021 +0000
-
- upstream: After years of forewarning, disable the RSA/SHA-1
-
- signature algorithm by default. It is feasible to create colliding SHA1
- hashes, so we need to deprecate its use.
-
- RSA/SHA-256/512 remains available and will be transparently selected
- instead of RSA/SHA1 for most SSH servers released in the last five+
- years. There is no need to regenerate RSA keys.
-
- The use of RSA/SHA1 can be re-enabled by adding "ssh-rsa" to the
- PubkeyAcceptedAlgorithms directives on the client and server.
-
- ok dtucker deraadt
-
- OpenBSD-Commit-ID: 189bcc4789c7254e09e23734bdd5def8354ff1d5
-
-commit 56c4455d3b54b7d481c77c82115c830b9c8ce328
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Sun Aug 29 23:44:07 2021 +0000
-
- upstream: wrap at 80 columns
-
- OpenBSD-Commit-ID: 47ca2286d6b52a9747f34da16d742879e1a37bf0
-
-commit 95401eea8503943449f712e5f3de52fc0bc612c5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 18:14:13 2021 +1000
-
- Replace shell function with ssh-keygen -A.
-
- Prevents the init script in the SysV package from trying (and failing)
- to generate unsupported key types. Remove now-unused COMMENT_OUT_ECC.
- ok tim@
-
-commit d83ec9ed995a76ed1d5c65cf10b447222ec86131
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 15:39:05 2021 +1000
-
- Remove obsolete Redhat PAM config and init script.
-
-commit e1a596186c81e65a34ce13076449712d3bf97eb4
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Aug 20 14:03:49 2021 +1000
-
- depend
-
-commit 5450606c8f7f7a0d70211cea78bc2dab74ab35d1
-Author: Damien Miller <djm@mindrot.org>
-Date: Fri Aug 20 13:59:43 2021 +1000
-
- update version numbers
-
-commit feee2384ab8d694c770b7750cfa76a512bdf8246
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Fri Aug 20 03:22:55 2021 +0000
-
- upstream: openssh-8.7
-
- OpenBSD-Commit-ID: 8769dff0fd76ae3193d77bf83b439adee0f300cd
-
-commit 9a2ed62173cc551b2b5f479460bb015b19499de8
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 10:48:13 2021 +1000
-
- Also check pid in pselect_notify_setup.
-
- Spotted by djm@.
-
-commit deaadcb93ca15d4f38aa38fb340156077792ce87
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 08:39:33 2021 +1000
-
- Prefix pselect functions to clarify debug messages
-
-commit 10e45654cff221ca60fd35ee069df67208fcf415
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 20 08:30:42 2021 +1000
-
- Fix race in pselect replacement code.
-
- On the second and subsequent calls to pselect the notify_pipe was not
- added to the select readset, opening up a race that om G. Christensen
- discovered on multiprocessor Solaris <=9 systems.
-
- Also reinitialize notify_pipe if the pid changes. This will prevent a
- parent and child from using the same FD, although this is not an issue
- in the current structure it might be in future.
-
-commit 464ba22f1e38d25402e5ec79a9b8d34a32df5a3f
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 18 12:51:30 2021 +1000
-
- Check compiler for c99 declarations after code.
-
- The sntrup761 reference code contains c99-style declarations after code
- so don't try to build that if the compiler doesn't support it.
-
-commit 7d878679a4b155a359d32104ff473f789501748d
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 17 15:12:04 2021 +1000
-
- Remove trailing backslash on regress-unit-binaries
-
-commit b71b2508f17c68c5d9dbbe537686d81cedb9a781
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Tue Aug 17 07:59:27 2021 +1000
-
- Put stdint.h inside HAVE_STDINT_H.
-
- From Tom G. Christensen.
-
-commit 6a24567a29bd7b4ab64e1afad859ea845cbc6b8c
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 16 14:13:02 2021 +1000
-
- Improve github test driver script.
-
- - use a trap to always output any failed regress logs (since the script
- sets -e, the existing log output is never invoked).
- - pass LTESTS and SKIP_LTESTS when re-running with sshd options (eg.
- UsePAM).
-
-commit b467cf13705f59ed348b620722ac098fe31879b7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Mon Aug 16 11:32:23 2021 +1000
-
- Remove deprecated ubuntu-16.04 test targets.
-
- Github has deprecated ubuntu-16.04 and it will be removed on 20
- September.
-
-commit 20e6eefcdf78394f05e453d456c1212ffaa6b6a4
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Aug 15 23:25:26 2021 +1000
-
- Skip agent ptrace test on hurd.
-
-commit 7c9115bbbf958fbf85259a061c1122e2d046aabf
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Aug 15 19:37:22 2021 +1000
-
- Add hurd test target.
-
-commit 7909a566f6c6a78fcd30708dc49f4e4f9bb80ce3
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Sun Aug 15 12:45:10 2021 +1000
-
- Skip scp3 tests on all dfly58 and 60 configs.
-
-commit e65198e52cb03534e8c846d1bca74c310b1526de
-Author: Tim Rice <tim@multitalents.net>
-Date: Sat Aug 14 13:08:07 2021 -0700
-
- openbsd-compat/openbsd-compat.h: put bsd-signal.h before bsd-misc.h
- to get sigset_t from signal.h needed for the pselect replacement.
-
-commit e50635640f79920d9375e0155cb3f4adb870eee5
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 13 13:21:00 2021 +1000
-
- Test OpenSSH from OpenBSD head on 6.8 and 6.9.
-
-commit e0ba38861c490c680117b7fe0a1d61a181cd00e7
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Fri Aug 13 13:00:14 2021 +1000
-
- Skip scp3 test on dragonfly 58 and 60.
-
- The tests hang, so skip until we figure them out.
-
-commit dcce2a2bcf007bf817a2fb0dce3db83fa9201e92
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Thu Aug 12 23:59:25 2021 +0000
-
- upstream: mention that CASignatureAlgorithms accepts +/- similarly to
-
- the other algorithm list directives; ok jmc bz#3335
-
- OpenBSD-Commit-ID: 0d46b53995817052c78e2dce9dbd133963b073d9
-
-commit 090a82486e5d7a8f7f16613d67e66a673a40367f
-Author: schwarze@openbsd.org <schwarze@openbsd.org>
-Date: Thu Aug 12 09:59:00 2021 +0000
-
- upstream: In the editline(3) branch of the sftp(1) event loop,
-
- handle SIGINT rather than ignoring it, such that the user can use Ctrl-C to
- discard the currently edited command line and get a fresh prompt, just like
- in ftp(1), bc(1), and in shells.
-
- It is critical to not use ssl_signal() for this particular case
- because that function unconditionally sets SA_RESTART, but here we
- need the signal to interrupt the read(2) in the el_gets(3) event loop.
-
- OK dtucker@ deraadt@
-
- OpenBSD-Commit-ID: 8025115a773f52e9bb562eaab37ea2e021cc7299
-
-commit e1371e4f58404d6411d9f95eb774b444cea06a26
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Wed Aug 11 14:07:54 2021 +0000
-
- upstream: scp: tweak man page and error message for -3 by default
-
- Now that the -3 option is enabled by default, flip the documentation
- and error message logic from "requires -3" to "blocked by -R".
-
- ok djm@
-
- OpenBSD-Commit-ID: a872592118444fb3acda5267b2a8c3d4c4252020
-
-commit 49f46f6d77328a3d10a758522b670a3e8c2235e7
-Author: naddy@openbsd.org <naddy@openbsd.org>
-Date: Wed Aug 11 14:05:19 2021 +0000
-
- upstream: scp: do not spawn ssh with two -s flags for
-
- remote-to-remote copies
-
- Do not add another "-s" to the argument vector every time an SFTP
- connection is initiated. Instead, introduce a subsystem flag to
- do_cmd() and add "-s" when the flag is set.
-
- ok djm@
-
- OpenBSD-Commit-ID: 25df69759f323661d31b2e1e790faa22e27966c1
-
-commit 2a2cd00783e1da45ee730b7f453408af1358ef5b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 08:55:04 2021 +0000
-
- upstream: test -Oprint-pubkey
-
- OpenBSD-Regress-ID: 3d51afb6d1f287975fb6fddd7a2c00a3bc5094e0
-
-commit b9f4635ea5bc33ed5ebbacf332d79bae463b0f54
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 08:54:17 2021 +0000
-
- upstream: when verifying sshsig signatures, support an option
-
- (-Oprint-pubkey) to dump the full public key to stdout; based on patch from
- Fabian Stelzer; ok markus@
-
- OpenBSD-Commit-ID: 0598000e5b9adfb45d42afa76ff80daaa12fc3e2
-
-commit 750c1a45ba4e8ad63793d49418a0780e77947b9b
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 05:21:32 2021 +0000
-
- upstream: oops, missed one more %p
-
- OpenBSD-Commit-ID: e7e62818d1564cc5cd9086eaf7a51cbd1a9701eb
-
-commit b5aa27b69ab2e1c13ac2b5ad3f8f7d389bad7489
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Wed Aug 11 05:20:17 2021 +0000
-
- upstream: remove a bunch of %p in format strings; leftovers of
-
- debuggings past. prompted by Michael Forney, ok dtucker@
-
- OpenBSD-Commit-ID: 4853a0d6c9cecaba9ecfcc19066e52d3a8dcb2ac
-
-commit 419aa01123db5ff5dbc68b2376ef23b222862338
-Author: Darren Tucker <dtucker@dtucker.net>
-Date: Wed Aug 11 09:21:09 2021 +1000
-
- Add includes.h to compat tests.
-
- On platforms where closefrom returns void (eg glibc>=2.34) the prototype
- for closefrom in its compat tests would cause compile errors. Remove
- this and have the tests pull in the compat headers in the same way as
- the main code. bz#3336.
-
-commit 931f592f26239154eea3eb35a086585897b1a185
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Aug 10 03:35:45 2021 +0000
-
- upstream: adapt to scp -M flag change; make scp3.sh test SFTP mode too
-
- OpenBSD-Regress-ID: 43fea26704a0f0b962b53c1fabcb68179638f9c0
-
-commit 391ca67fb978252c48d20c910553f803f988bd37
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Tue Aug 10 03:33:34 2021 +0000
-
- upstream: Prepare for a future where scp(1) uses the SFTP protocol by
-
- default. Replace recently added -M option to select the protocol with -O
- (olde) and -s (SFTP) flags, and label the -s flag with a clear warning that
- it will be removed in the near future (so no, don't use it in scripts!).
-
- prompted by/feedback from deraadt@
-
- OpenBSD-Commit-ID: 92ad72cc6f0023c9be9e316d8b30eb6d8d749cfc
-
-commit bfdd4b722f124a4fa9173d20dd64dd0fc69856be
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:56:36 2021 +0000
-
- upstream: make scp -3 the default for remote-to-remote copies. It
-
- provides a much better and more intuitive user experience and doesn't require
- exposing credentials to the source host.
-
- thanks naddy@ for catching the missing argument in usage()
-
- "Yes please!" - markus@
- "makes a lot of sense" - deraadt@
- "the right thing to do" - dtucker@
-
- OpenBSD-Commit-ID: d0d2af5f0965c5192ba5b2fa461c9f9b130e5dd9
-
-commit 2f7a3b51cef689ad9e93d0c6c17db5a194eb5555
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:49:31 2021 +0000
-
- upstream: make scp in SFTP mode try to use relative paths as much
-
- as possible. Previosuly, it would try to make relative and ~/-rooted paths
- absolute before requesting transfers.
-
- prompted by and much discussion deraadt@
- ok markus@
-
- OpenBSD-Commit-ID: 46639d382ea99546a4914b545fa7b00fa1be5566
-
-commit 2ab864010e0a93c5dd95116fb5ceaf430e2fc23c
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:47:44 2021 +0000
-
- upstream: SFTP protocol extension to allow the server to expand
-
- ~-prefixed paths, in particular ~user ones. Allows scp in sftp mode to accept
- these paths, like scp in rcp mode does.
-
- prompted by and much discussion deraadt@
- ok markus@
-
- OpenBSD-Commit-ID: 7d794def9e4de348e1e777f6030fc9bafdfff392
-
-commit 41b019ac067f1d1f7d99914d0ffee4d2a547c3d8
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 23:44:32 2021 +0000
-
- upstream: when scp is in SFTP mode, try to deal better with ~
-
- prefixed paths. ~user paths aren't supported, but ~/ paths will be accepted
- and prefixed with the SFTP server starting directory (more to come)
-
- prompted by and discussed with deraadt@
- ok markus@
-
- OpenBSD-Commit-ID: 263a071f14555c045fd03132a8fb6cbd983df00d
-
-commit b4b3f3da6cdceb3fd168b5fab69d11fba73bd0ae
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:21:01 2021 +0000
-
- upstream: on fatal errors, make scp wait for ssh connection before
-
- exiting avoids LogLevel=verbose (or greater) messages from ssh appearing
- after scp has returned exited and control has returned to the shell; ok
- markus@
-
- (this was originally committed as r1.223 along with unrelated stuff that
- I rolled back in r1.224)
-
- OpenBSD-Commit-ID: 1261fd667ad918484889ed3d7aec074f3956a74b
-
-commit 2ae7771749e0b4cecb107f9d4860bec16c3f4245
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:19:12 2021 +0000
-
- upstream: rever r1.223 - I accidentally committed unrelated changes
-
- OpenBSD-Commit-ID: fb73f3865b2647a27dd94db73d6589506a9625f9
-
-commit 986abe94d481a1e82a01747360bd767b96b41eda
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:16:09 2021 +0000
-
- upstream: show only the final path component in the progress meter;
-
- more useful with long paths (that may truncate) and better matches
- traditional scp behaviour; spotted by naddy@ ok deraadt@
-
- OpenBSD-Commit-ID: 26b544d0074f03ebb8a3ebce42317d8d7ee291a3
-
-commit 2b67932bb3176dee4fd447af4368789e04a82b93
-Author: djm@openbsd.org <djm@openbsd.org>
-Date: Mon Aug 9 07:13:54 2021 +0000
-
- upstream: on fatal errors, make scp wait for ssh connection before
-
- exiting avoids LogLevel=verbose (or greater) messages from ssh appearing
- after scp has returned exited and control has returned to the shell; ok
- markus@
-
- OpenBSD-Commit-ID: ef9dab5ef5ae54a6a4c3b15d380568e94263456c
diff --git a/PROTOCOL b/PROTOCOL
index 27804d0cadbd..d453c779be92 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -104,6 +104,39 @@ http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.o
This is identical to curve25519-sha256 as later published in RFC8731.
+1.9 transport: ping facility
+
+OpenSSH implements a transport level ping message SSH2_MSG_PING
+and a corresponding SSH2_MSG_PONG reply.
+
+#define SSH2_MSG_PING 192
+#define SSH2_MSG_PONG 193
+
+The ping message is simply:
+
+ byte SSH_MSG_PING
+ string data
+
+The reply copies the data (which may be the empty string) from the
+ping:
+
+ byte SSH_MSG_PONG
+ string data
+
+Replies are sent in order. They are sent immediately except when rekeying
+is in progress, in which case they are queued until rekeying completes.
+
+The server advertises support for these messages using the
+SSH2_MSG_EXT_INFO mechanism (RFC8308), with the following message:
+
+ string "ping@openssh.com"
+ string "0" (version)
+
+The ping/reply message is implemented at the transport layer rather
+than as a named global or channel request to allow pings with very
+short packet lengths, which would not be possible with other
+approaches.
+
2. Connection protocol changes
2.1. connection: Channel write close extension "eow@openssh.com"
@@ -712,4 +745,4 @@ master instance and later clients.
OpenSSH extends the usual agent protocol. These changes are documented
in the PROTOCOL.agent file.
-$OpenBSD: PROTOCOL,v 1.48 2022/11/07 01:53:01 dtucker Exp $
+$OpenBSD: PROTOCOL,v 1.49 2023/08/28 03:28:43 djm Exp $
diff --git a/PROTOCOL.agent b/PROTOCOL.agent
index 44e463674f19..1c4841147a2d 100644
--- a/PROTOCOL.agent
+++ b/PROTOCOL.agent
@@ -1,5 +1,5 @@
The SSH agent protocol is described in
-https://tools.ietf.org/html/draft-miller-ssh-agent-04
+https://tools.ietf.org/html/draft-miller-ssh-agent
This file documents OpenSSH's extensions to the agent protocol.
@@ -81,4 +81,4 @@ the constraint is:
This option is only valid for XMSS keys.
-$OpenBSD: PROTOCOL.agent,v 1.19 2023/04/12 08:53:54 jsg Exp $
+$OpenBSD: PROTOCOL.agent,v 1.20 2023/10/03 23:56:10 djm Exp $
diff --git a/README b/README
index e44e44ced60b..6e41c8657b82 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-See https://www.openssh.com/releasenotes.html#9.4p1 for the release
+See https://www.openssh.com/releasenotes.html#9.5p1 for the release
notes.
Please read https://www.openssh.com/report.html for bug reporting
diff --git a/auth2.c b/auth2.c
index 34346e5731de..c628999e0bb6 100644
--- a/auth2.c
+++ b/auth2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.166 2023/03/08 04:43:12 guenther Exp $ */
+/* $OpenBSD: auth2.c,v 1.167 2023/08/28 09:48:11 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -218,6 +218,7 @@ input_service_request(int type, u_int32_t seq, struct ssh *ssh)
}
#define MIN_FAIL_DELAY_SECONDS 0.005
+#define MAX_FAIL_DELAY_SECONDS 5.0
static double
user_specific_delay(const char *user)
{
@@ -243,6 +244,12 @@ ensure_minimum_time_since(double start, double seconds)
struct timespec ts;
double elapsed = monotime_double() - start, req = seconds, remain;
+ if (elapsed > MAX_FAIL_DELAY_SECONDS) {
+ debug3_f("elapsed %0.3lfms exceeded the max delay "
+ "requested %0.3lfms)", elapsed*1000, req*1000);
+ return;
+ }
+
/* if we've already passed the requested time, scale up */
while ((remain = seconds - elapsed) < 0.0)
seconds *= 2;
@@ -334,7 +341,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
debug2("input_userauth_request: try method %s", method);
authenticated = m->userauth(ssh, method);
}
- if (!authctxt->authenticated)
+ if (!authctxt->authenticated && strcmp(method, "none") != 0)
ensure_minimum_time_since(tstart,
user_specific_delay(authctxt->user));
userauth_finish(ssh, authenticated, method, NULL);
diff --git a/channels.c b/channels.c
index da66b7b3494c..598ff322a175 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.432 2023/07/04 03:59:21 dlg Exp $ */
+/* $OpenBSD: channels.c,v 1.433 2023/09/04 00:01:46 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2890,8 +2890,9 @@ channel_after_poll(struct ssh *ssh, struct pollfd *pfd, u_int npfd)
/*
* Enqueue data for channels with open or draining c->input.
+ * Returns non-zero if a packet was enqueued.
*/
-static void
+static int
channel_output_poll_input_open(struct ssh *ssh, Channel *c)
{
size_t len, plen;
@@ -2914,7 +2915,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
else
chan_ibuf_empty(ssh, c);
}
- return;
+ return 0;
}
if (!c->have_remote_id)
@@ -2931,7 +2932,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
*/
if (plen > c->remote_window || plen > c->remote_maxpacket) {
debug("channel %d: datagram too big", c->self);
- return;
+ return 0;
}
/* Enqueue it */
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
@@ -2940,7 +2941,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
(r = sshpkt_send(ssh)) != 0)
fatal_fr(r, "channel %i: send datagram", c->self);
c->remote_window -= plen;
- return;
+ return 1;
}
/* Enqueue packet for buffered data. */
@@ -2949,7 +2950,7 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len == 0)
- return;
+ return 0;
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_DATA)) != 0 ||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
(r = sshpkt_put_string(ssh, sshbuf_ptr(c->input), len)) != 0 ||
@@ -2958,19 +2959,21 @@ channel_output_poll_input_open(struct ssh *ssh, Channel *c)
if ((r = sshbuf_consume(c->input, len)) != 0)
fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
+ return 1;
}
/*
* Enqueue data for channels with open c->extended in read mode.
+ * Returns non-zero if a packet was enqueued.
*/
-static void
+static int
channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
{
size_t len;
int r;
if ((len = sshbuf_len(c->extended)) == 0)
- return;
+ return 0;
debug2("channel %d: rwin %u elen %zu euse %d", c->self,
c->remote_window, sshbuf_len(c->extended), c->extended_usage);
@@ -2979,7 +2982,7 @@ channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len == 0)
- return;
+ return 0;
if (!c->have_remote_id)
fatal_f("channel %d: no remote id", c->self);
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA)) != 0 ||
@@ -2992,15 +2995,20 @@ channel_output_poll_extended_read(struct ssh *ssh, Channel *c)
fatal_fr(r, "channel %i: consume", c->self);
c->remote_window -= len;
debug2("channel %d: sent ext data %zu", c->self, len);
+ return 1;
}
-/* If there is data to send to the connection, enqueue some of it now. */
-void
+/*
+ * If there is data to send to the connection, enqueue some of it now.
+ * Returns non-zero if data was enqueued.
+ */
+int
channel_output_poll(struct ssh *ssh)
{
struct ssh_channels *sc = ssh->chanctxt;
Channel *c;
u_int i;
+ int ret = 0;
for (i = 0; i < sc->channels_alloc; i++) {
c = sc->channels[i];
@@ -3023,12 +3031,13 @@ channel_output_poll(struct ssh *ssh)
/* Get the amount of buffered data for this channel. */
if (c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN)
- channel_output_poll_input_open(ssh, c);
+ ret |= channel_output_poll_input_open(ssh, c);
/* Send extended data, i.e. stderr */
if (!(c->flags & CHAN_EOF_SENT) &&
c->extended_usage == CHAN_EXTENDED_READ)
- channel_output_poll_extended_read(ssh, c);
+ ret |= channel_output_poll_extended_read(ssh, c);
}
+ return ret;
}
/* -- mux proxy support */
diff --git a/channels.h b/channels.h
index 7afba78377e0..58019a84e71c 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.151 2023/07/04 03:59:21 dlg Exp $ */
+/* $OpenBSD: channels.h,v 1.152 2023/09/04 00:01:46 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -335,7 +335,7 @@ struct timespec;
void channel_prepare_poll(struct ssh *, struct pollfd **,
u_int *, u_int *, u_int, struct timespec *);
void channel_after_poll(struct ssh *, struct pollfd *, u_int);
-void channel_output_poll(struct ssh *);
+int channel_output_poll(struct ssh *);
int channel_not_very_much_buffered_data(struct ssh *);
void channel_close_all(struct ssh *);
diff --git a/clientloop.c b/clientloop.c
index 99846a978397..3e9fa3220b7d 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.392 2023/04/03 08:10:54 dtucker Exp $ */
+/* $OpenBSD: clientloop.c,v 1.398 2023/09/10 03:51:55 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -118,6 +118,9 @@
/* Permitted RSA signature algorithms for UpdateHostkeys proofs */
#define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256"
+/* Uncertainty (in percent) of keystroke timing intervals */
+#define SSH_KEYSTROKE_TIMING_FUZZ 10
+
/* import options */
extern Options options;
@@ -507,17 +510,181 @@ server_alive_check(struct ssh *ssh)
schedule_server_alive_check();
}
+/* Try to send a dummy keystroke */
+static int
+send_chaff(struct ssh *ssh)
+{
+ int r;
+
+ if ((ssh->kex->flags & KEX_HAS_PING) == 0)
+ return 0;
+ /* XXX probabilistically send chaff? */
+ /*
+ * a SSH2_MSG_CHANNEL_DATA payload is 9 bytes:
+ * 4 bytes channel ID + 4 bytes string length + 1 byte string data
+ * simulate that here.
+ */
+ if ((r = sshpkt_start(ssh, SSH2_MSG_PING)) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "PING!")) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ fatal_fr(r, "send packet");
+ return 1;
+}
+
+/* Sets the next interval to send a keystroke or chaff packet */
+static void
+set_next_interval(const struct timespec *now, struct timespec *next_interval,
+ u_int interval_ms, int starting)
+{
+ struct timespec tmp;
+ long long interval_ns, fuzz_ns;
+ static long long rate_fuzz;
+
+ interval_ns = interval_ms * (1000LL * 1000);
+ fuzz_ns = (interval_ns * SSH_KEYSTROKE_TIMING_FUZZ) / 100;
+ /* Center fuzz around requested interval */
+ if (fuzz_ns > INT_MAX)
+ fuzz_ns = INT_MAX;
+ if (fuzz_ns > interval_ns) {
+ /* Shouldn't happen */
+ fatal_f("internal error: fuzz %u%% %lldns > interval %lldns",
+ SSH_KEYSTROKE_TIMING_FUZZ, fuzz_ns, interval_ns);
+ }
+ /*
+ * Randomise the keystroke/chaff intervals in two ways:
+ * 1. Each interval has some random jitter applied to make the
+ * interval-to-interval time unpredictable.
+ * 2. The overall interval rate is also randomly perturbed for each
+ * chaffing session to make the average rate unpredictable.
+ */
+ if (starting)
+ rate_fuzz = arc4random_uniform(fuzz_ns);
+ interval_ns -= fuzz_ns;
+ interval_ns += arc4random_uniform(fuzz_ns) + rate_fuzz;
+
+ tmp.tv_sec = interval_ns / (1000 * 1000 * 1000);
+ tmp.tv_nsec = interval_ns % (1000 * 1000 * 1000);
+
+ timespecadd(now, &tmp, next_interval);
+}
+
+/*
+ * Performs keystroke timing obfuscation. Returns non-zero if the
+ * output fd should be polled.
+ */
+static int
+obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout,
+ int channel_did_enqueue)
+{
+ static int active;
+ static struct timespec next_interval, chaff_until;
+ struct timespec now, tmp;
+ int just_started = 0, had_keystroke = 0;
+ static unsigned long long nchaff;
+ char *stop_reason = NULL;
+ long long n;
+
+ monotime_ts(&now);
+
+ if (options.obscure_keystroke_timing_interval <= 0)
+ return 1; /* disabled in config */
+
+ if (!channel_still_open(ssh) || quit_pending) {
+ /* Stop if no channels left of we're waiting for one to close */
+ stop_reason = "no active channels";
+ } else if (ssh_packet_is_rekeying(ssh)) {
+ /* Stop if we're rekeying */
+ stop_reason = "rekeying started";
+ } else if (!ssh_packet_interactive_data_to_write(ssh) &&
+ ssh_packet_have_data_to_write(ssh)) {
+ /* Stop if the output buffer has more than a few keystrokes */
+ stop_reason = "output buffer filling";
+ } else if (active && channel_did_enqueue &&
+ ssh_packet_have_data_to_write(ssh)) {
+ /* Still in active mode and have a keystroke queued. */
+ had_keystroke = 1;
+ } else if (active) {
+ if (timespeccmp(&now, &chaff_until, >=)) {
+ /* Stop if there have been no keystrokes for a while */
+ stop_reason = "chaff time expired";
+ } else if (timespeccmp(&now, &next_interval, >=)) {
+ /* Otherwise if we were due to send, then send chaff */
+ if (send_chaff(ssh))
+ nchaff++;
+ }
+ }
+
+ if (stop_reason != NULL) {
+ if (active) {
+ debug3_f("stopping: %s (%llu chaff packets sent)",
+ stop_reason, nchaff);
+ active = 0;
+ }
+ return 1;
+ }
+
+ /*
+ * If we're in interactive mode, and only have a small amount
+ * of outbound data, then we assume that the user is typing
+ * interactively. In this case, start quantising outbound packets to
+ * fixed time intervals to hide inter-keystroke timing.
+ */
+ if (!active && ssh_packet_interactive_data_to_write(ssh) &&
+ channel_did_enqueue && ssh_packet_have_data_to_write(ssh)) {
+ debug3_f("starting: interval ~%dms",
+ options.obscure_keystroke_timing_interval);
+ just_started = had_keystroke = active = 1;
+ nchaff = 0;
+ set_next_interval(&now, &next_interval,
+ options.obscure_keystroke_timing_interval, 1);
+ }
+
+ /* Don't hold off if obfuscation inactive */
+ if (!active)
+ return 1;
+
+ if (had_keystroke) {
+ /*
+ * Arrange to send chaff packets for a random interval after
+ * the last keystroke was sent.
+ */
+ ms_to_timespec(&tmp, SSH_KEYSTROKE_CHAFF_MIN_MS +
+ arc4random_uniform(SSH_KEYSTROKE_CHAFF_RNG_MS));
+ timespecadd(&now, &tmp, &chaff_until);
+ }
+
+ ptimeout_deadline_monotime_tsp(timeout, &next_interval);
+
+ if (just_started)
+ return 1;
+
+ /* Don't arm output fd for poll until the timing interval has elapsed */
+ if (timespeccmp(&now, &next_interval, <))
+ return 0;
+
+ /* Calculate number of intervals missed since the last check */
+ n = (now.tv_sec - next_interval.tv_sec) * 1000LL * 1000 * 1000;
+ n += now.tv_nsec - next_interval.tv_nsec;
+ n /= options.obscure_keystroke_timing_interval * 1000LL * 1000;
+ n = (n < 0) ? 1 : n + 1;
+
+ /* Advance to the next interval */
+ set_next_interval(&now, &next_interval,
+ options.obscure_keystroke_timing_interval * n, 0);
+ return 1;
+}
+
/*
* Waits until the client can do something (some data becomes available on
* one of the file descriptors).
*/
static void
client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
- u_int *npfd_allocp, u_int *npfd_activep, int rekeying,
+ u_int *npfd_allocp, u_int *npfd_activep, int channel_did_enqueue,
int *conn_in_readyp, int *conn_out_readyp)
{
struct timespec timeout;
- int ret;
+ int ret, oready;
u_int p;
*conn_in_readyp = *conn_out_readyp = 0;
@@ -537,11 +704,14 @@ client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
return;
}
+ oready = obfuscate_keystroke_timing(ssh, &timeout, channel_did_enqueue);
+
/* Monitor server connection on reserved pollfd entries */
(*pfdp)[0].fd = connection_in;
(*pfdp)[0].events = POLLIN;
(*pfdp)[1].fd = connection_out;
- (*pfdp)[1].events = ssh_packet_have_data_to_write(ssh) ? POLLOUT : 0;
+ (*pfdp)[1].events = (oready && ssh_packet_have_data_to_write(ssh)) ?
+ POLLOUT : 0;
/*
* Wait for something to happen. This will suspend the process until
@@ -553,12 +723,12 @@ client_wait_until_can_do_something(struct ssh *ssh, struct pollfd **pfdp,
ptimeout_deadline_monotime(&timeout, control_persist_exit_time);
if (options.server_alive_interval > 0)
ptimeout_deadline_monotime(&timeout, server_alive_time);
- if (options.rekey_interval > 0 && !rekeying) {
+ if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) {
ptimeout_deadline_sec(&timeout,
ssh_packet_get_rekey_timeout(ssh));
}
- ret = poll(*pfdp, *npfd_activep, ptimeout_get_ms(&timeout));
+ ret = ppoll(*pfdp, *npfd_activep, ptimeout_get_tsp(&timeout), NULL);
if (ret == -1) {
/*
@@ -1275,7 +1445,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
struct pollfd *pfd = NULL;
u_int npfd_alloc = 0, npfd_active = 0;
double start_time, total_time;
- int r, len;
+ int channel_did_enqueue = 0, r, len;
u_int64_t ibytes, obytes;
int conn_in_ready, conn_out_ready;
@@ -1365,6 +1535,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
/* Main loop of the client for the interactive session mode. */
while (!quit_pending) {
+ channel_did_enqueue = 0;
/* Process buffered packets sent by the server. */
client_process_buffered_input_packets(ssh);
@@ -1386,7 +1557,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
* enqueue them for sending to the server.
*/
if (ssh_packet_not_very_much_data_to_write(ssh))
- channel_output_poll(ssh);
+ channel_did_enqueue = channel_output_poll(ssh);
/*
* Check if the window size has changed, and buffer a
@@ -1402,7 +1573,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
* available on one of the descriptors).
*/
client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc,
- &npfd_active, ssh_packet_is_rekeying(ssh),
+ &npfd_active, channel_did_enqueue,
&conn_in_ready, &conn_out_ready);
if (quit_pending)
diff --git a/configure b/configure
index d38df9738d71..5f5986e923de 100755
--- a/configure
+++ b/configure
@@ -6083,7 +6083,13 @@ printf "%s\n" "$GCC_VER" >&6; }
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking clang version" >&5
printf %s "checking clang version... " >&6; }
- CLANG_VER=`$CC -v 2>&1 | $AWK '/clang version /{print $3}'`
+ ver="`$CC -v 2>&1`"
+ if echo "$ver" | grep "Apple" >/dev/null; then
+ CLANG_VER="apple-`echo "$ver" | \
+ awk '/Apple LLVM/ {print $4"-"$5}'`"
+ else
+ CLANG_VER=`echo "$ver" | $AWK '/clang version /{print $3}'`
+ fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CLANG_VER" >&5
printf "%s\n" "$CLANG_VER" >&6; }
@@ -7492,7 +7498,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
# https://bugzilla.mindrot.org/show_bug.cgi?id=3475 and
# https://github.com/llvm/llvm-project/issues/59242
case "$CLANG_VER" in
- 15.*) {
+ 15.*|apple*) {
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fzero-call-used-regs=used" >&5
printf %s "checking if $CC supports compile flag -fzero-call-used-regs=used... " >&6; }
saved_CFLAGS="$CFLAGS"
@@ -10889,7 +10895,7 @@ main (void)
int a=0, b=0, c=0, d=0, n, v;
n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d);
- if (n != 3 && n != 4)
+ if (n < 1)
exit(1);
v = a*1000000 + b*10000 + c*100 + d;
fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v);
diff --git a/configure.ac b/configure.ac
index 07893e870659..d8816e3f65de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -187,7 +187,13 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
AC_MSG_RESULT([$GCC_VER])
AC_MSG_CHECKING([clang version])
- CLANG_VER=`$CC -v 2>&1 | $AWK '/clang version /{print $3}'`
+ ver="`$CC -v 2>&1`"
+ if echo "$ver" | grep "Apple" >/dev/null; then
+ CLANG_VER="apple-`echo "$ver" | \
+ awk '/Apple LLVM/ {print $4"-"$5}'`"
+ else
+ CLANG_VER=`echo "$ver" | $AWK '/clang version /{print $3}'`
+ fi
AC_MSG_RESULT([$CLANG_VER])
OSSH_CHECK_CFLAG_COMPILE([-pipe])
@@ -225,7 +231,7 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
# https://bugzilla.mindrot.org/show_bug.cgi?id=3475 and
# https://github.com/llvm/llvm-project/issues/59242
case "$CLANG_VER" in
- 15.*) OSSH_CHECK_CFLAG_COMPILE([-fzero-call-used-regs=used]) ;;
+ 15.*|apple*) OSSH_CHECK_CFLAG_COMPILE([-fzero-call-used-regs=used]) ;;
*) OSSH_CHECK_CFLAG_COMPILE([-fzero-call-used-regs=all]) ;;
esac
OSSH_CHECK_CFLAG_COMPILE([-ftrivial-auto-var-init=zero])
@@ -1464,7 +1470,7 @@ else
[[
int a=0, b=0, c=0, d=0, n, v;
n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d);
- if (n != 3 && n != 4)
+ if (n < 1)
exit(1);
v = a*1000000 + b*10000 + c*100 + d;
fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v);
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec
index 7d6fe3cfd2fe..7a167d4456d1 100644
--- a/contrib/redhat/openssh.spec
+++ b/contrib/redhat/openssh.spec
@@ -1,4 +1,4 @@
-%global ver 9.4p1
+%global ver 9.5p1
%global rel 1%{?dist}
# OpenSSH privilege separation requires a user & group ID
diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec
index 77736276638c..921d0f5a4d67 100644
--- a/contrib/suse/openssh.spec
+++ b/contrib/suse/openssh.spec
@@ -13,7 +13,7 @@
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
-Version: 9.4p1
+Version: 9.5p1
URL: https://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz
diff --git a/kex.c b/kex.c
index b4e2ab75f541..8ff92f2a2d5e 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.178 2023/03/12 10:40:39 dtucker Exp $ */
+/* $OpenBSD: kex.c,v 1.181 2023/08/28 03:28:43 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -492,12 +492,14 @@ kex_send_ext_info(struct ssh *ssh)
return SSH_ERR_ALLOC_FAIL;
/* XXX filter algs list by allowed pubkey/hostbased types */
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
- (r = sshpkt_put_u32(ssh, 2)) != 0 ||
+ (r = sshpkt_put_u32(ssh, 3)) != 0 ||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
(r = sshpkt_put_cstring(ssh, algs)) != 0 ||
(r = sshpkt_put_cstring(ssh,
"publickey-hostbound@openssh.com")) != 0 ||
(r = sshpkt_put_cstring(ssh, "0")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "ping@openssh.com")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "0")) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
error_fr(r, "compose");
goto out;
@@ -527,6 +529,23 @@ kex_send_newkeys(struct ssh *ssh)
return 0;
}
+/* Check whether an ext_info value contains the expected version string */
+static int
+kex_ext_info_check_ver(struct kex *kex, const char *name,
+ const u_char *val, size_t len, const char *want_ver, u_int flag)
+{
+ if (memchr(val, '\0', len) != NULL) {
+ error("SSH2_MSG_EXT_INFO: %s value contains nul byte", name);
+ return SSH_ERR_INVALID_FORMAT;
+ }
+ debug_f("%s=<%s>", name, val);
+ if (strcmp(val, want_ver) == 0)
+ kex->flags |= flag;
+ else
+ debug_f("unsupported version of %s extension", name);
+ return 0;
+}
+
int
kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
{
@@ -557,6 +576,8 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
/* Ensure no \0 lurking in value */
if (memchr(val, '\0', vlen) != NULL) {
error_f("nul byte in %s", name);
+ free(name);
+ free(val);
return SSH_ERR_INVALID_FORMAT;
}
debug_f("%s=<%s>", name, val);
@@ -564,18 +585,18 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
val = NULL;
} else if (strcmp(name,
"publickey-hostbound@openssh.com") == 0) {
- /* XXX refactor */
- /* Ensure no \0 lurking in value */
- if (memchr(val, '\0', vlen) != NULL) {
- error_f("nul byte in %s", name);
- return SSH_ERR_INVALID_FORMAT;
+ if ((r = kex_ext_info_check_ver(kex, name, val, vlen,
+ "0", KEX_HAS_PUBKEY_HOSTBOUND)) != 0) {
+ free(name);
+ free(val);
+ return r;
}
- debug_f("%s=<%s>", name, val);
- if (strcmp(val, "0") == 0)
- kex->flags |= KEX_HAS_PUBKEY_HOSTBOUND;
- else {
- debug_f("unsupported version of %s extension",
- name);
+ } else if (strcmp(name, "ping@openssh.com") == 0) {
+ if ((r = kex_ext_info_check_ver(kex, name, val, vlen,
+ "0", KEX_HAS_PING)) != 0) {
+ free(name);
+ free(val);
+ return r;
}
} else
debug_f("%s (unrecognised)", name);
@@ -1334,7 +1355,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
for (;;) {
if (timeout_ms > 0) {
r = waitrfd(ssh_packet_get_connection_in(ssh),
- &timeout_ms);
+ &timeout_ms, NULL);
if (r == -1 && errno == ETIMEDOUT) {
send_error(ssh, "Timed out waiting "
"for SSH identification string.");
@@ -1353,7 +1374,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
len = atomicio(read, ssh_packet_get_connection_in(ssh),
&c, 1);
if (len != 1 && errno == EPIPE) {
- error_f("Connection closed by remote host");
+ verbose_f("Connection closed by remote host");
r = SSH_ERR_CONN_CLOSED;
goto out;
} else if (len != 1) {
@@ -1369,7 +1390,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
if (c == '\n')
break;
if (c == '\0' || expect_nl) {
- error_f("banner line contains invalid "
+ verbose_f("banner line contains invalid "
"characters");
goto invalid;
}
@@ -1379,7 +1400,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
goto out;
}
if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
- error_f("banner line too long");
+ verbose_f("banner line too long");
goto invalid;
}
}
@@ -1395,7 +1416,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
}
/* Do not accept lines before the SSH ident from a client */
if (ssh->kex->server) {
- error_f("client sent invalid protocol identifier "
+ verbose_f("client sent invalid protocol identifier "
"\"%.256s\"", cp);
free(cp);
goto invalid;
diff --git a/kex.h b/kex.h
index 8b54e3f4b912..5f7ef784eec9 100644
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.118 2023/03/06 12:14:48 dtucker Exp $ */
+/* $OpenBSD: kex.h,v 1.119 2023/08/28 03:28:43 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -111,6 +111,7 @@ enum kex_exchange {
#define KEX_HAS_PUBKEY_HOSTBOUND 0x0004
#define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */
#define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */
+#define KEX_HAS_PING 0x0020
struct sshenc {
char *name;
diff --git a/misc.c b/misc.c
index 4b87c4090804..42582c61829a 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.185 2023/08/04 06:32:40 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.187 2023/08/28 03:31:16 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2005-2020 Damien Miller. All rights reserved.
@@ -313,20 +313,38 @@ set_sock_tos(int fd, int tos)
* Returns 0 if fd ready or -1 on timeout or error (see errno).
*/
static int
-waitfd(int fd, int *timeoutp, short events)
+waitfd(int fd, int *timeoutp, short events, volatile sig_atomic_t *stop)
{
struct pollfd pfd;
- struct timeval t_start;
- int oerrno, r, have_timeout = (*timeoutp >= 0);
+ struct timespec timeout;
+ int oerrno, r;
+ sigset_t nsigset, osigset;
+ if (timeoutp && *timeoutp == -1)
+ timeoutp = NULL;
pfd.fd = fd;
pfd.events = events;
- for (; !have_timeout || *timeoutp >= 0;) {
- monotime_tv(&t_start);
- r = poll(&pfd, 1, *timeoutp);
+ ptimeout_init(&timeout);
+ if (timeoutp != NULL)
+ ptimeout_deadline_ms(&timeout, *timeoutp);
+ if (stop != NULL)
+ sigfillset(&nsigset);
+ for (; timeoutp == NULL || *timeoutp >= 0;) {
+ if (stop != NULL) {
+ sigprocmask(SIG_BLOCK, &nsigset, &osigset);
+ if (*stop) {
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ errno = EINTR;
+ return -1;
+ }
+ }
+ r = ppoll(&pfd, 1, ptimeout_get_tsp(&timeout),
+ stop != NULL ? &osigset : NULL);
oerrno = errno;
- if (have_timeout)
- ms_subtract_diff(&t_start, timeoutp);
+ if (stop != NULL)
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ if (timeoutp)
+ *timeoutp = ptimeout_get_ms(&timeout);
errno = oerrno;
if (r > 0)
return 0;
@@ -346,8 +364,8 @@ waitfd(int fd, int *timeoutp, short events)
* Returns 0 if fd ready or -1 on timeout or error (see errno).
*/
int
-waitrfd(int fd, int *timeoutp) {
- return waitfd(fd, timeoutp, POLLIN);
+waitrfd(int fd, int *timeoutp, volatile sig_atomic_t *stop) {
+ return waitfd(fd, timeoutp, POLLIN, stop);
}
/*
@@ -381,7 +399,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
break;
}
- if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1)
+ if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT, NULL) == -1)
return -1;
/* Completed or failed */
@@ -2883,24 +2901,35 @@ ptimeout_deadline_ms(struct timespec *pt, long ms)
ptimeout_deadline_tsp(pt, &p);
}
-/* Specify a poll/ppoll deadline at wall clock monotime 'when' */
+/* Specify a poll/ppoll deadline at wall clock monotime 'when' (timespec) */
void
-ptimeout_deadline_monotime(struct timespec *pt, time_t when)
+ptimeout_deadline_monotime_tsp(struct timespec *pt, struct timespec *when)
{
struct timespec now, t;
- t.tv_sec = when;
- t.tv_nsec = 0;
monotime_ts(&now);
- if (timespeccmp(&now, &t, >=))
- ptimeout_deadline_sec(pt, 0);
- else {
- timespecsub(&t, &now, &t);
+ if (timespeccmp(&now, when, >=)) {
+ /* 'when' is now or in the past. Timeout ASAP */
+ pt->tv_sec = 0;
+ pt->tv_nsec = 0;
+ } else {
+ timespecsub(when, &now, &t);
ptimeout_deadline_tsp(pt, &t);
}
}
+/* Specify a poll/ppoll deadline at wall clock monotime 'when' */
+void
+ptimeout_deadline_monotime(struct timespec *pt, time_t when)
+{
+ struct timespec t;
+
+ t.tv_sec = when;
+ t.tv_nsec = 0;
+ ptimeout_deadline_monotime_tsp(pt, &t);
+}
+
/* Get a poll(2) timeout value in milliseconds */
int
ptimeout_get_ms(struct timespec *pt)
diff --git a/misc.h b/misc.h
index fd77a7fd7273..4f941597e9e3 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.103 2023/07/19 14:02:27 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.105 2023/08/28 03:31:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
+#include <signal.h>
/* Data structure for representing a forwarding request. */
struct Forward {
@@ -57,7 +58,7 @@ char *get_rdomain(int);
int set_rdomain(int, const char *);
int get_sock_af(int);
void set_sock_tos(int, int);
-int waitrfd(int, int *);
+int waitrfd(int, int *, volatile sig_atomic_t *);
int timeout_connect(int, const struct sockaddr *, socklen_t, int *);
int a2port(const char *);
int a2tun(const char *, int *);
@@ -213,6 +214,7 @@ struct timespec;
void ptimeout_init(struct timespec *pt);
void ptimeout_deadline_sec(struct timespec *pt, long sec);
void ptimeout_deadline_ms(struct timespec *pt, long ms);
+void ptimeout_deadline_monotime_tsp(struct timespec *pt, struct timespec *when);
void ptimeout_deadline_monotime(struct timespec *pt, time_t when);
int ptimeout_get_ms(struct timespec *pt);
struct timespec *ptimeout_get_tsp(struct timespec *pt);
diff --git a/monitor.c b/monitor.c
index 1489c78d81ec..b3ed515ed0ba 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.236 2023/05/10 10:04:20 dtucker Exp $ */
+/* $OpenBSD: monitor.c,v 1.237 2023/08/16 16:14:11 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -342,6 +342,11 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
auth_method, auth_submethod);
}
}
+ if (authctxt->failures > options.max_authtries) {
+ /* Shouldn't happen */
+ fatal_f("privsep child made too many authentication "
+ "attempts");
+ }
}
if (!authctxt->valid)
diff --git a/mux.c b/mux.c
index 3a0f87674b95..d9d5e7d994ca 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mux.c,v 1.99 2023/08/04 06:32:40 dtucker Exp $ */
+/* $OpenBSD: mux.c,v 1.100 2023/08/18 01:37:41 djm Exp $ */
/*
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
*
@@ -1480,7 +1480,9 @@ mux_client_read(int fd, struct sshbuf *b, size_t need, int timeout_ms)
case EWOULDBLOCK:
#endif
case EAGAIN:
- if (waitrfd(fd, &timeout_ms) == -1)
+ if (waitrfd(fd, &timeout_ms,
+ &muxclient_terminate) == -1 &&
+ errno != EINTR)
return -1; /* timeout */
/* FALLTHROUGH */
case EINTR:
diff --git a/openbsd-compat/bsd-closefrom.c b/openbsd-compat/bsd-closefrom.c
index 704da531fef9..49a4f35ff9c3 100644
--- a/openbsd-compat/bsd-closefrom.c
+++ b/openbsd-compat/bsd-closefrom.c
@@ -28,7 +28,6 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
-#include <unistd.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
diff --git a/packet.c b/packet.c
index fdb8783bc315..52017defb642 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.310 2023/04/06 03:21:31 djm Exp $ */
+/* $OpenBSD: packet.c,v 1.312 2023/08/28 03:31:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1054,6 +1054,8 @@ int
ssh_packet_log_type(u_char type)
{
switch (type) {
+ case SSH2_MSG_PING:
+ case SSH2_MSG_PONG:
case SSH2_MSG_CHANNEL_DATA:
case SSH2_MSG_CHANNEL_EXTENDED_DATA:
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
@@ -1675,7 +1677,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
goto out;
if (ssh_packet_log_type(*typep))
debug3("receive packet: type %u", *typep);
- if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) {
+ if (*typep < SSH2_MSG_MIN) {
if ((r = sshpkt_disconnect(ssh,
"Invalid ssh2 packet type: %d", *typep)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
@@ -1710,6 +1712,8 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
u_int reason, seqnr;
int r;
u_char *msg;
+ const u_char *d;
+ size_t len;
for (;;) {
msg = NULL;
@@ -1753,6 +1757,21 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
seqnr);
break;
+ case SSH2_MSG_PING:
+ if ((r = sshpkt_get_string_direct(ssh, &d, &len)) != 0)
+ return r;
+ DBG(debug("Received SSH2_MSG_PING len %zu", len));
+ if ((r = sshpkt_start(ssh, SSH2_MSG_PONG)) != 0 ||
+ (r = sshpkt_put_string(ssh, d, len)) != 0 ||
+ (r = sshpkt_send(ssh)) != 0)
+ return r;
+ break;
+ case SSH2_MSG_PONG:
+ if ((r = sshpkt_get_string_direct(ssh,
+ NULL, &len)) != 0)
+ return r;
+ DBG(debug("Received SSH2_MSG_PONG len %zu", len));
+ break;
default:
return 0;
}
@@ -2064,6 +2083,18 @@ ssh_packet_not_very_much_data_to_write(struct ssh *ssh)
return sshbuf_len(ssh->state->output) < 128 * 1024;
}
+/*
+ * returns true when there are at most a few keystrokes of data to write
+ * and the connection is in interactive mode.
+ */
+
+int
+ssh_packet_interactive_data_to_write(struct ssh *ssh)
+{
+ return ssh->state->interactive_mode &&
+ sshbuf_len(ssh->state->output) < 256;
+}
+
void
ssh_packet_set_tos(struct ssh *ssh, int tos)
{
diff --git a/packet.h b/packet.h
index 176488b1e5d2..11925a27d438 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.94 2022/01/22 00:49:34 djm Exp $ */
+/* $OpenBSD: packet.h,v 1.95 2023/08/28 03:31:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -145,6 +145,7 @@ int ssh_packet_write_poll(struct ssh *);
int ssh_packet_write_wait(struct ssh *);
int ssh_packet_have_data_to_write(struct ssh *);
int ssh_packet_not_very_much_data_to_write(struct ssh *);
+int ssh_packet_interactive_data_to_write(struct ssh *);
int ssh_packet_connection_is_on_socket(struct ssh *);
int ssh_packet_remaining(struct ssh *);
diff --git a/readconf.c b/readconf.c
index 0d50e89b129f..131c24f526d4 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.380 2023/07/17 06:16:33 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.381 2023/08/28 03:31:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -178,7 +178,7 @@ typedef enum {
oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize,
- oEnableEscapeCommandline,
+ oEnableEscapeCommandline, oObscureKeystrokeTiming,
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
@@ -327,6 +327,7 @@ static struct {
{ "knownhostscommand", oKnownHostsCommand },
{ "requiredrsasize", oRequiredRSASize },
{ "enableescapecommandline", oEnableEscapeCommandline },
+ { "obscurekeystroketiming", oObscureKeystrokeTiming },
{ NULL, oBadOption }
};
@@ -2280,6 +2281,48 @@ parse_pubkey_algos:
intptr = &options->required_rsa_size;
goto parse_int;
+ case oObscureKeystrokeTiming:
+ value = -1;
+ while ((arg = argv_next(&ac, &av)) != NULL) {
+ if (value != -1) {
+ error("%s line %d: invalid arguments",
+ filename, linenum);
+ goto out;
+ }
+ if (strcmp(arg, "yes") == 0 ||
+ strcmp(arg, "true") == 0)
+ value = SSH_KEYSTROKE_DEFAULT_INTERVAL_MS;
+ else if (strcmp(arg, "no") == 0 ||
+ strcmp(arg, "false") == 0)
+ value = 0;
+ else if (strncmp(arg, "interval:", 9) == 0) {
+ if ((errstr = atoi_err(arg + 9,
+ &value)) != NULL) {
+ error("%s line %d: integer value %s.",
+ filename, linenum, errstr);
+ goto out;
+ }
+ if (value <= 0 || value > 1000) {
+ error("%s line %d: value out of range.",
+ filename, linenum);
+ goto out;
+ }
+ } else {
+ error("%s line %d: unsupported argument \"%s\"",
+ filename, linenum, arg);
+ goto out;
+ }
+ }
+ if (value == -1) {
+ error("%s line %d: missing argument",
+ filename, linenum);
+ goto out;
+ }
+ intptr = &options->obscure_keystroke_timing_interval;
+ if (*activep && *intptr == -1)
+ *intptr = value;
+ break;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
@@ -2530,6 +2573,7 @@ initialize_options(Options * options)
options->known_hosts_command = NULL;
options->required_rsa_size = -1;
options->enable_escape_commandline = -1;
+ options->obscure_keystroke_timing_interval = -1;
options->tag = NULL;
}
@@ -2731,6 +2775,10 @@ fill_default_options(Options * options)
options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE;
if (options->enable_escape_commandline == -1)
options->enable_escape_commandline = 0;
+ if (options->obscure_keystroke_timing_interval == -1) {
+ options->obscure_keystroke_timing_interval =
+ SSH_KEYSTROKE_DEFAULT_INTERVAL_MS;
+ }
/* Expand KEX name lists */
all_cipher = cipher_alg_list(',', 0);
@@ -3273,6 +3321,16 @@ lookup_opcode_name(OpCodes code)
static void
dump_cfg_int(OpCodes code, int val)
{
+ if (code == oObscureKeystrokeTiming) {
+ if (val == 0) {
+ printf("%s no\n", lookup_opcode_name(code));
+ return;
+ } else if (val == SSH_KEYSTROKE_DEFAULT_INTERVAL_MS) {
+ printf("%s yes\n", lookup_opcode_name(code));
+ return;
+ }
+ /* FALLTHROUGH */
+ }
printf("%s %d\n", lookup_opcode_name(code), val);
}
@@ -3423,6 +3481,8 @@ dump_client_config(Options *o, const char *host)
dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
dump_cfg_int(oRequiredRSASize, o->required_rsa_size);
+ dump_cfg_int(oObscureKeystrokeTiming,
+ o->obscure_keystroke_timing_interval);
/* String options */
dump_cfg_string(oBindAddress, o->bind_address);
diff --git a/readconf.h b/readconf.h
index dfe5bab0a3ca..ce261bd63642 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.151 2023/07/17 04:08:31 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.152 2023/08/28 03:31:16 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -180,6 +180,7 @@ typedef struct {
int required_rsa_size; /* minimum size of RSA keys */
int enable_escape_commandline; /* ~C commandline */
+ int obscure_keystroke_timing_interval;
char *ignored_unknown; /* Pattern list of unknown tokens to ignore */
} Options;
@@ -222,6 +223,11 @@ typedef struct {
#define SSH_STRICT_HOSTKEY_YES 2
#define SSH_STRICT_HOSTKEY_ASK 3
+/* ObscureKeystrokes parameters */
+#define SSH_KEYSTROKE_DEFAULT_INTERVAL_MS 20
+#define SSH_KEYSTROKE_CHAFF_MIN_MS 1024
+#define SSH_KEYSTROKE_CHAFF_RNG_MS 2048
+
const char *kex_default_pk_alg(void);
char *ssh_connection_hash(const char *thishost, const char *host,
const char *portstr, const char *user);
diff --git a/regress/Makefile b/regress/Makefile
index 5caf9b8e41dd..c21b0215a8cd 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.125 2023/05/17 05:52:01 djm Exp $
+# $OpenBSD: Makefile,v 1.126 2023/09/06 23:36:09 djm Exp $
tests: prep file-tests t-exec unit
@@ -103,7 +103,8 @@ LTESTS= connect \
agent-restrict \
hostbased \
channel-timeout \
- connection-timeout
+ connection-timeout \
+ match-subsystem
INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
#INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp
diff --git a/regress/match-subsystem.sh b/regress/match-subsystem.sh
new file mode 100644
index 000000000000..0b691d8e8884
--- /dev/null
+++ b/regress/match-subsystem.sh
@@ -0,0 +1,90 @@
+# $OpenBSD: match-subsystem.sh,v 1.1 2023/09/06 23:36:09 djm Exp $
+# Placed in the Public Domain.
+
+tid="sshd_config match subsystem"
+
+cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak
+
+try_subsystem() {
+ _id=$1
+ _subsystem=$2
+ _expect=$3
+ ${SSHD} -tf $OBJ/sshd_proxy || fatal "$_id: bad config"
+ ${SSH} -sF $OBJ/ssh_proxy somehost $_subsystem
+ _exit=$?
+ trace "$_id subsystem $_subsystem"
+ if [ $_exit -ne $_expect ] ; then
+ fail "$_id: subsystem $_subsystem exit $_exit expected $_expect"
+ fi
+ return $?
+}
+
+# Simple case: subsystem in main config.
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Subsystem xxx /bin/sh -c "exit 23"
+_EOF
+try_subsystem "main config" xxx 23
+
+# No clobber in main config.
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Subsystem xxx /bin/sh -c "exit 23"
+Subsystem xxx /bin/sh -c "exit 24"
+_EOF
+try_subsystem "main config no clobber" xxx 23
+
+# Subsystem in match all block
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Match all
+Subsystem xxx /bin/sh -c "exit 21"
+_EOF
+try_subsystem "match all" xxx 21
+
+# No clobber in match all block
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Match all
+Subsystem xxx /bin/sh -c "exit 21"
+Subsystem xxx /bin/sh -c "exit 24"
+_EOF
+try_subsystem "match all no clobber" xxx 21
+
+# Subsystem in match user block
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Match user *
+Subsystem xxx /bin/sh -c "exit 20"
+_EOF
+try_subsystem "match user" xxx 20
+
+# No clobber in match user block
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Match user *
+Subsystem xxx /bin/sh -c "exit 20"
+Subsystem xxx /bin/sh -c "exit 24"
+Match all
+Subsystem xxx /bin/sh -c "exit 24"
+_EOF
+try_subsystem "match user no clobber" xxx 20
+
+# Override main with match all
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Subsystem xxx /bin/sh -c "exit 23"
+Match all
+Subsystem xxx /bin/sh -c "exit 19"
+_EOF
+try_subsystem "match all override" xxx 19
+
+# Override main with match user
+cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
+cat >> $OBJ/sshd_proxy << _EOF
+Subsystem xxx /bin/sh -c "exit 23"
+Match user *
+Subsystem xxx /bin/sh -c "exit 18"
+_EOF
+try_subsystem "match user override" xxx 18
+
diff --git a/regress/scp.sh b/regress/scp.sh
index 76c2b2a6bb56..640cf434ff67 100644
--- a/regress/scp.sh
+++ b/regress/scp.sh
@@ -1,4 +1,4 @@
-# $OpenBSD: scp.sh,v 1.18 2023/01/13 04:47:34 dtucker Exp $
+# $OpenBSD: scp.sh,v 1.19 2023/09/08 05:50:57 djm Exp $
# Placed in the Public Domain.
tid="scp"
@@ -30,13 +30,25 @@ scpclean() {
chmod 755 ${DIR} ${DIR2} ${DIR3}
}
+# Create directory structure for recursive copy tests.
+forest() {
+ scpclean
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ ln -s ${DIR}/copy ${DIR}/copy-sym
+ mkdir ${DIR}/subdir
+ cp ${DATA} ${DIR}/subdir/copy
+ ln -s ${DIR}/subdir ${DIR}/subdir-sym
+}
+
for mode in scp sftp ; do
tag="$tid: $mode mode"
if test $mode = scp ; then
scpopts="-O -q -S ${OBJ}/scp-ssh-wrapper.scp"
else
- scpopts="-s -D ${SFTPSERVER}"
+ scpopts="-qs -D ${SFTPSERVER}"
fi
+
verbose "$tag: simple copy local file to local file"
scpclean
$SCP $scpopts ${DATA} ${COPY} || fail "copy failed"
@@ -96,21 +108,19 @@ for mode in scp sftp ; do
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: recursive local dir to remote dir"
- scpclean
- rm -rf ${DIR2}
- cp ${DATA} ${DIR}/copy
+ forest
$SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed"
diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
verbose "$tag: recursive local dir to local dir"
- scpclean
+ forest
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
$SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed"
diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
verbose "$tag: recursive remote dir to local dir"
- scpclean
+ forest
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
$SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed"
diff --git a/regress/scp3.sh b/regress/scp3.sh
index 383121f4519e..eeb7a9dde475 100644
--- a/regress/scp3.sh
+++ b/regress/scp3.sh
@@ -1,10 +1,8 @@
-# $OpenBSD: scp3.sh,v 1.4 2023/01/13 04:47:34 dtucker Exp $
+# $OpenBSD: scp3.sh,v 1.5 2023/09/08 06:10:57 djm Exp $
# Placed in the Public Domain.
tid="scp3"
-set -x
-
COPY2=${OBJ}/copy2
DIR=${COPY}.dd
DIR2=${COPY}.dd2
@@ -22,6 +20,17 @@ scpclean() {
chmod 755 ${DIR} ${DIR2}
}
+# Create directory structure for recursive copy tests.
+forest() {
+ scpclean
+ rm -rf ${DIR2}
+ cp ${DATA} ${DIR}/copy
+ ln -s ${DIR}/copy ${DIR}/copy-sym
+ mkdir ${DIR}/subdir
+ cp ${DATA} ${DIR}/subdir/copy
+ ln -s ${DIR}/subdir ${DIR}/subdir-sym
+}
+
for mode in scp sftp ; do
scpopts="-F${OBJ}/ssh_proxy -S ${SSH} -q"
tag="$tid: $mode mode"
@@ -43,9 +52,7 @@ for mode in scp sftp ; do
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: recursive remote dir to remote dir"
- scpclean
- rm -rf ${DIR2}
- cp ${DATA} ${DIR}/copy
+ forest
$SCP $scpopts -3r hostA:${DIR} hostB:${DIR2} || fail "copy failed"
diff -r ${DIR} ${DIR2} || fail "corrupted copy"
diff -r ${DIR2} ${DIR} || fail "corrupted copy"
diff --git a/scp.c b/scp.c
index 5edb4f07dba6..eaa407cb1de8 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.257 2023/07/14 05:31:44 djm Exp $ */
+/* $OpenBSD: scp.c,v 1.259 2023/09/10 23:12:32 djm Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@@ -186,7 +186,7 @@ size_t sftp_nrequests;
/* Needed for sftp */
volatile sig_atomic_t interrupted = 0;
-int remote_glob(struct sftp_conn *, const char *, int,
+int sftp_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
static void
@@ -1028,7 +1028,7 @@ do_sftp_connect(char *host, char *user, int port, char *sftp_direct,
reminp, remoutp, pidp) < 0)
return NULL;
}
- return do_init(*reminp, *remoutp,
+ return sftp_init(*reminp, *remoutp,
sftp_copy_buflen, sftp_nrequests, limit_kbps);
}
@@ -1324,8 +1324,8 @@ prepare_remote_path(struct sftp_conn *conn, const char *path)
return xstrdup(".");
return xstrdup(path + 2 + nslash);
}
- if (can_expand_path(conn))
- return do_expand_path(conn, path);
+ if (sftp_can_expand_path(conn))
+ return sftp_expand_path(conn, path);
/* No protocol extension */
error("server expand-path extension is required "
"for ~user paths in SFTP mode");
@@ -1353,17 +1353,17 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
*/
if ((target = prepare_remote_path(conn, targ)) == NULL)
cleanup_exit(255);
- target_is_dir = remote_is_dir(conn, target);
+ target_is_dir = sftp_remote_is_dir(conn, target);
if (targetshouldbedirectory && !target_is_dir) {
debug("target directory \"%s\" does not exist", target);
a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = st.st_mode | 0700; /* ensure writable */
- if (do_mkdir(conn, target, &a, 1) != 0)
+ if (sftp_mkdir(conn, target, &a, 1) != 0)
cleanup_exit(255); /* error already logged */
target_is_dir = 1;
}
if (target_is_dir)
- abs_dst = path_append(target, filename);
+ abs_dst = sftp_path_append(target, filename);
else {
abs_dst = target;
target = NULL;
@@ -1371,12 +1371,12 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
debug3_f("copying local %s to remote %s", src, abs_dst);
if (src_is_dir && iamrecursive) {
- if (upload_dir(conn, src, abs_dst, pflag,
+ if (sftp_upload_dir(conn, src, abs_dst, pflag,
SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
error("failed to upload directory %s to %s", src, targ);
errs = 1;
}
- } else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
+ } else if (sftp_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
error("failed to upload file %s to %s", src, targ);
errs = 1;
}
@@ -1568,7 +1568,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
}
debug3_f("copying remote %s to local %s", abs_src, dst);
- if ((r = remote_glob(conn, abs_src, GLOB_NOCHECK|GLOB_MARK,
+ if ((r = sftp_glob(conn, abs_src, GLOB_NOCHECK|GLOB_MARK,
NULL, &g)) != 0) {
if (r == GLOB_NOSPACE)
error("%s: too many glob matches", src);
@@ -1585,7 +1585,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
* a GLOB_NOCHECK result. Check whether the unglobbed path
* exists so we can give a nice error message early.
*/
- if (do_stat(conn, g.gl_pathv[0], 1) == NULL) {
+ if (sftp_stat(conn, g.gl_pathv[0], 1, NULL) != 0) {
error("%s: %s", src, strerror(ENOENT));
err = -1;
goto out;
@@ -1621,17 +1621,17 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
}
if (dst_is_dir)
- abs_dst = path_append(dst, filename);
+ abs_dst = sftp_path_append(dst, filename);
else
abs_dst = xstrdup(dst);
debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
- if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
- if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
+ if (sftp_globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
+ if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst,
+ NULL, pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
err = -1;
} else {
- if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
+ if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag, 0, 0, 1) == -1)
err = -1;
}
@@ -1993,7 +1993,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
cleanup_exit(255);
memset(&g, 0, sizeof(g));
- targetisdir = remote_is_dir(to, target);
+ targetisdir = sftp_remote_is_dir(to, target);
if (!targetisdir && targetshouldbedirectory) {
error("%s: destination is not a directory", targ);
err = -1;
@@ -2001,7 +2001,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
}
debug3_f("copying remote %s to remote %s", abs_src, target);
- if ((r = remote_glob(from, abs_src, GLOB_NOCHECK|GLOB_MARK,
+ if ((r = sftp_glob(from, abs_src, GLOB_NOCHECK|GLOB_MARK,
NULL, &g)) != 0) {
if (r == GLOB_NOSPACE)
error("%s: too many glob matches", src);
@@ -2018,7 +2018,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
* a GLOB_NOCHECK result. Check whether the unglobbed path
* exists so we can give a nice error message early.
*/
- if (do_stat(from, g.gl_pathv[0], 1) == NULL) {
+ if (sftp_stat(from, g.gl_pathv[0], 1, NULL) != 0) {
error("%s: %s", src, strerror(ENOENT));
err = -1;
goto out;
@@ -2034,18 +2034,18 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
}
if (targetisdir)
- abs_dst = path_append(target, filename);
+ abs_dst = sftp_path_append(target, filename);
else
abs_dst = xstrdup(target);
debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
- if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
- if (crossload_dir(from, to, g.gl_pathv[i], abs_dst,
+ if (sftp_globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
+ if (sftp_crossload_dir(from, to, g.gl_pathv[i], abs_dst,
NULL, pflag, SFTP_PROGRESS_ONLY, 1) == -1)
err = -1;
} else {
- if (do_crossload(from, to, g.gl_pathv[i], abs_dst, NULL,
- pflag) == -1)
+ if (sftp_crossload(from, to, g.gl_pathv[i], abs_dst,
+ NULL, pflag) == -1)
err = -1;
}
free(abs_dst);
diff --git a/servconf.c b/servconf.c
index 45a2f2c2781c..49f7f7322e7e 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.396 2023/07/17 05:26:38 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.402 2023/09/08 06:34:24 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -643,7 +643,7 @@ static struct {
{ "macs", sMacs, SSHCFG_GLOBAL },
{ "protocol", sIgnore, SSHCFG_GLOBAL },
{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
- { "subsystem", sSubsystem, SSHCFG_GLOBAL },
+ { "subsystem", sSubsystem, SSHCFG_ALL },
{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
{ "persourcemaxstartups", sPerSourceMaxStartups, SSHCFG_GLOBAL },
{ "persourcenetblocksize", sPerSourceNetBlockSize, SSHCFG_GLOBAL },
@@ -1933,39 +1933,54 @@ process_server_config_line_depth(ServerOptions *options, char *line,
break;
case sSubsystem:
- if (options->num_subsystems >= MAX_SUBSYSTEMS) {
- fatal("%s line %d: too many subsystems defined.",
- filename, linenum);
- }
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0')
fatal("%s line %d: %s missing argument.",
filename, linenum, keyword);
if (!*activep) {
- arg = argv_next(&ac, &av);
+ argv_consume(&ac);
+ break;
+ }
+ found = 0;
+ for (i = 0; i < options->num_subsystems; i++) {
+ if (strcmp(arg, options->subsystem_name[i]) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ debug("%s line %d: Subsystem '%s' already defined.",
+ filename, linenum, arg);
+ argv_consume(&ac);
break;
}
- for (i = 0; i < options->num_subsystems; i++)
- if (strcmp(arg, options->subsystem_name[i]) == 0)
- fatal("%s line %d: Subsystem '%s' "
- "already defined.", filename, linenum, arg);
+ options->subsystem_name = xrecallocarray(
+ options->subsystem_name, options->num_subsystems,
+ options->num_subsystems + 1,
+ sizeof(*options->subsystem_name));
+ options->subsystem_command = xrecallocarray(
+ options->subsystem_command, options->num_subsystems,
+ options->num_subsystems + 1,
+ sizeof(*options->subsystem_command));
+ options->subsystem_args = xrecallocarray(
+ options->subsystem_args, options->num_subsystems,
+ options->num_subsystems + 1,
+ sizeof(*options->subsystem_args));
options->subsystem_name[options->num_subsystems] = xstrdup(arg);
arg = argv_next(&ac, &av);
- if (!arg || *arg == '\0')
+ if (!arg || *arg == '\0') {
fatal("%s line %d: Missing subsystem command.",
filename, linenum);
- options->subsystem_command[options->num_subsystems] = xstrdup(arg);
-
- /* Collect arguments (separate to executable) */
- p = xstrdup(arg);
- len = strlen(p) + 1;
- while ((arg = argv_next(&ac, &av)) != NULL) {
- len += 1 + strlen(arg);
- p = xreallocarray(p, 1, len);
- strlcat(p, " ", len);
- strlcat(p, arg, len);
}
- options->subsystem_args[options->num_subsystems] = p;
+ options->subsystem_command[options->num_subsystems] =
+ xstrdup(arg);
+ /* Collect arguments (separate to executable) */
+ arg = argv_assemble(1, &arg); /* quote command correctly */
+ arg2 = argv_assemble(ac, av); /* rest of command */
+ xasprintf(&options->subsystem_args[options->num_subsystems],
+ "%s %s", arg, arg2);
+ free(arg2);
+ argv_consume(&ac);
options->num_subsystems++;
break;
@@ -2030,7 +2045,7 @@ process_server_config_line_depth(ServerOptions *options, char *line,
fatal("%s line %d: %s integer value %s.",
filename, linenum, keyword, errstr);
}
- if (*activep)
+ if (*activep && options->per_source_max_startups == -1)
options->per_source_max_startups = value;
break;
@@ -2679,6 +2694,47 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
return 0;
}
+void
+servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src)
+{
+ u_int i, j, found;
+
+ for (i = 0; i < src->num_subsystems; i++) {
+ found = 0;
+ for (j = 0; j < dst->num_subsystems; j++) {
+ if (strcmp(src->subsystem_name[i],
+ dst->subsystem_name[j]) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ debug_f("override \"%s\"", dst->subsystem_name[j]);
+ free(dst->subsystem_command[j]);
+ free(dst->subsystem_args[j]);
+ dst->subsystem_command[j] =
+ xstrdup(src->subsystem_command[i]);
+ dst->subsystem_args[j] =
+ xstrdup(src->subsystem_args[i]);
+ continue;
+ }
+ debug_f("add \"%s\"", src->subsystem_name[i]);
+ dst->subsystem_name = xrecallocarray(
+ dst->subsystem_name, dst->num_subsystems,
+ dst->num_subsystems + 1, sizeof(*dst->subsystem_name));
+ dst->subsystem_command = xrecallocarray(
+ dst->subsystem_command, dst->num_subsystems,
+ dst->num_subsystems + 1, sizeof(*dst->subsystem_command));
+ dst->subsystem_args = xrecallocarray(
+ dst->subsystem_args, dst->num_subsystems,
+ dst->num_subsystems + 1, sizeof(*dst->subsystem_args));
+ j = dst->num_subsystems++;
+ dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]);
+ dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]);
+ dst->subsystem_args[j] = xstrdup(src->subsystem_args[i]);
+ }
+}
+
/*
* Copy any supported values that are set.
*
@@ -2785,6 +2841,9 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
free(dst->chroot_directory);
dst->chroot_directory = NULL;
}
+
+ /* Subsystems require merging. */
+ servconf_merge_subsystems(dst, src);
}
#undef M_CP_INTOPT
diff --git a/servconf.h b/servconf.h
index 7ad43de872d9..ed7b72e8e0e3 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.159 2023/01/17 09:44:48 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.160 2023/09/06 23:35:35 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -20,8 +20,6 @@
#define MAX_PORTS 256 /* Max # ports. */
-#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
-
/* permit_root_login */
#define PERMIT_NOT_SET -1
#define PERMIT_NO 0
@@ -165,9 +163,9 @@ typedef struct {
char **deny_groups;
u_int num_subsystems;
- char *subsystem_name[MAX_SUBSYSTEMS];
- char *subsystem_command[MAX_SUBSYSTEMS];
- char *subsystem_args[MAX_SUBSYSTEMS];
+ char **subsystem_name;
+ char **subsystem_command;
+ char **subsystem_args;
u_int num_accept_env;
char **accept_env;
@@ -294,6 +292,9 @@ TAILQ_HEAD(include_list, include_item);
M_CP_STRARRAYOPT(permitted_listens, num_permitted_listens); \
M_CP_STRARRAYOPT(channel_timeouts, num_channel_timeouts); \
M_CP_STRARRAYOPT(log_verbose, num_log_verbose); \
+ M_CP_STRARRAYOPT(subsystem_name, num_subsystems); \
+ M_CP_STRARRAYOPT(subsystem_command, num_subsystems); \
+ M_CP_STRARRAYOPT(subsystem_args, num_subsystems); \
} while (0)
struct connection_info *get_connection_info(struct ssh *, int, int);
@@ -310,6 +311,7 @@ void parse_server_match_config(ServerOptions *,
struct include_list *includes, struct connection_info *);
int parse_server_match_testspec(struct connection_info *, char *);
int server_match_spec_complete(struct connection_info *);
+void servconf_merge_subsystems(ServerOptions *, ServerOptions *);
void copy_set_server_options(ServerOptions *, ServerOptions *, int);
void dump_config(ServerOptions *);
char *derelativise_path(const char *);
diff --git a/serverloop.c b/serverloop.c
index de5fa2e3c2e8..f3683c2e4a6d 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.236 2023/03/08 04:43:12 guenther Exp $ */
+/* $OpenBSD: serverloop.c,v 1.237 2023/08/21 04:59:54 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -253,7 +253,7 @@ wait_until_can_do_something(struct ssh *ssh,
/* ClientAliveInterval probing */
if (client_alive_scheduled) {
if (ret == 0 &&
- now > last_client_time + options.client_alive_interval) {
+ now >= last_client_time + options.client_alive_interval) {
/* ppoll timed out and we're due to probe */
client_alive_check(ssh);
last_client_time = now;
diff --git a/session.c b/session.c
index 89dcfdab628c..aa342e84de4c 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.335 2023/03/07 06:09:14 dtucker Exp $ */
+/* $OpenBSD: session.c,v 1.336 2023/08/10 23:05:48 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@@ -2380,17 +2380,17 @@ session_exit_message(struct ssh *ssh, Session *s, int status)
{
Channel *c;
int r;
+ char *note = NULL;
if ((c = channel_lookup(ssh, s->chanid)) == NULL)
fatal_f("session %d: no channel %d", s->self, s->chanid);
- debug_f("session %d channel %d pid %ld",
- s->self, s->chanid, (long)s->pid);
if (WIFEXITED(status)) {
channel_request_start(ssh, s->chanid, "exit-status", 0);
if ((r = sshpkt_put_u32(ssh, WEXITSTATUS(status))) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
+ xasprintf(&note, "exit %d", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
channel_request_start(ssh, s->chanid, "exit-signal", 0);
#ifndef WCOREDUMP
@@ -2402,11 +2402,18 @@ session_exit_message(struct ssh *ssh, Session *s, int status)
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
sshpkt_fatal(ssh, r, "%s: exit reply", __func__);
+ xasprintf(&note, "signal %d%s", WTERMSIG(status),
+ WCOREDUMP(status) ? " core dumped" : "");
} else {
/* Some weird exit cause. Just exit. */
- ssh_packet_disconnect(ssh, "wait returned status %04x.", status);
+ ssh_packet_disconnect(ssh, "wait returned status %04x.",
+ status);
}
+ debug_f("session %d channel %d pid %ld %s", s->self, s->chanid,
+ (long)s->pid, note == NULL ? "UNKNOWN" : note);
+ free(note);
+
/* disconnect channel */
debug_f("release channel %d", s->chanid);
diff --git a/sftp-client.c b/sftp-client.c
index 098b9121a015..2598029f7bd2 100644
--- a/sftp-client.c
+++ b/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.171 2023/04/30 22:54:22 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.174 2023/09/08 06:10:02 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -342,16 +342,17 @@ get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
return handle;
}
-/* XXX returning &static is error-prone. Refactor to fill *Attrib argument */
-static Attrib *
-get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
+static int
+get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet, Attrib *a)
{
struct sshbuf *msg;
u_int id;
u_char type;
int r;
- static Attrib a;
+ Attrib attr;
+ if (a != NULL)
+ memset(a, '\0', sizeof(*a));
if ((msg = sshbuf_new()) == NULL)
fatal_f("sshbuf_new failed");
get_msg(conn, msg);
@@ -372,21 +373,24 @@ get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
else
error("stat remote: %s", fx2txt(status));
sshbuf_free(msg);
- return(NULL);
+ return -1;
} else if (type != SSH2_FXP_ATTRS) {
fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u",
SSH2_FXP_ATTRS, type);
}
- if ((r = decode_attrib(msg, &a)) != 0) {
+ if ((r = decode_attrib(msg, &attr)) != 0) {
error_fr(r, "decode_attrib");
sshbuf_free(msg);
- return NULL;
+ return -1;
}
+ /* success */
+ if (a != NULL)
+ *a = attr;
debug3("Received stat reply T:%u I:%u F:0x%04x M:%05o",
- type, id, a.flags, a.perm);
+ type, id, attr.flags, attr.perm);
sshbuf_free(msg);
- return &a;
+ return 0;
}
static int
@@ -449,7 +453,7 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
}
struct sftp_conn *
-do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
+sftp_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
u_int64_t limit_kbps)
{
u_char type;
@@ -560,7 +564,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
/* Query the server for its limits */
if (ret->exts & SFTP_EXT_LIMITS) {
struct sftp_limits limits;
- if (do_limits(ret, &limits) != 0)
+ if (sftp_get_limits(ret, &limits) != 0)
fatal_f("limits failed");
/* If the caller did not specify, find a good value */
@@ -614,7 +618,7 @@ sftp_proto_version(struct sftp_conn *conn)
}
int
-do_limits(struct sftp_conn *conn, struct sftp_limits *limits)
+sftp_get_limits(struct sftp_conn *conn, struct sftp_limits *limits)
{
u_int id, msg_id;
u_char type;
@@ -668,7 +672,7 @@ do_limits(struct sftp_conn *conn, struct sftp_limits *limits)
}
int
-do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
+sftp_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
{
u_int id, status;
struct sshbuf *msg;
@@ -696,7 +700,7 @@ do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
static int
-do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
+sftp_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
SFTP_DIRENT ***dir)
{
struct sshbuf *msg;
@@ -821,16 +825,16 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
out:
sshbuf_free(msg);
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
free(handle);
if (status != 0 && dir != NULL) {
/* Don't return results on error */
- free_sftp_dirents(*dir);
+ sftp_free_dirents(*dir);
*dir = NULL;
} else if (interrupted && dir != NULL && *dir != NULL) {
/* Don't return partial matches on interrupt */
- free_sftp_dirents(*dir);
+ sftp_free_dirents(*dir);
*dir = xcalloc(1, sizeof(**dir));
**dir = NULL;
}
@@ -839,12 +843,12 @@ do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
}
int
-do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
+sftp_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
{
- return(do_lsreaddir(conn, path, 0, dir));
+ return sftp_lsreaddir(conn, path, 0, dir);
}
-void free_sftp_dirents(SFTP_DIRENT **s)
+void sftp_free_dirents(SFTP_DIRENT **s)
{
int i;
@@ -859,7 +863,7 @@ void free_sftp_dirents(SFTP_DIRENT **s)
}
int
-do_rm(struct sftp_conn *conn, const char *path)
+sftp_rm(struct sftp_conn *conn, const char *path)
{
u_int status, id;
@@ -874,7 +878,7 @@ do_rm(struct sftp_conn *conn, const char *path)
}
int
-do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
+sftp_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
{
u_int status, id;
@@ -892,7 +896,7 @@ do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
}
int
-do_rmdir(struct sftp_conn *conn, const char *path)
+sftp_rmdir(struct sftp_conn *conn, const char *path)
{
u_int status, id;
@@ -909,8 +913,8 @@ do_rmdir(struct sftp_conn *conn, const char *path)
return status == SSH2_FX_OK ? 0 : -1;
}
-Attrib *
-do_stat(struct sftp_conn *conn, const char *path, int quiet)
+int
+sftp_stat(struct sftp_conn *conn, const char *path, int quiet, Attrib *a)
{
u_int id;
@@ -922,33 +926,31 @@ do_stat(struct sftp_conn *conn, const char *path, int quiet)
conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
path, strlen(path));
- return(get_decode_stat(conn, id, quiet));
+ return get_decode_stat(conn, id, quiet, a);
}
-Attrib *
-do_lstat(struct sftp_conn *conn, const char *path, int quiet)
+int
+sftp_lstat(struct sftp_conn *conn, const char *path, int quiet, Attrib *a)
{
u_int id;
if (conn->version == 0) {
- if (quiet)
- debug("Server version does not support lstat operation");
- else
- logit("Server version does not support lstat operation");
- return(do_stat(conn, path, quiet));
+ do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
+ "Server version does not support lstat operation");
+ return sftp_stat(conn, path, quiet, a);
}
id = conn->msg_id++;
send_string_request(conn, id, SSH2_FXP_LSTAT, path,
strlen(path));
- return(get_decode_stat(conn, id, quiet));
+ return get_decode_stat(conn, id, quiet, a);
}
#ifdef notyet
-Attrib *
-do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
- int quiet)
+int
+sftp_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
+ int quiet, Attrib *a)
{
u_int id;
@@ -958,12 +960,12 @@ do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
handle_len);
- return(get_decode_stat(conn, id, quiet));
+ return get_decode_stat(conn, id, quiet, a);
}
#endif
int
-do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
+sftp_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
{
u_int status, id;
@@ -981,7 +983,7 @@ do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
}
int
-do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
+sftp_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
Attrib *a)
{
u_int status, id;
@@ -1001,7 +1003,7 @@ do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
/* Implements both the realpath and expand-path operations */
static char *
-do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
+sftp_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1076,31 +1078,31 @@ do_realpath_expand(struct sftp_conn *conn, const char *path, int expand)
}
char *
-do_realpath(struct sftp_conn *conn, const char *path)
+sftp_realpath(struct sftp_conn *conn, const char *path)
{
- return do_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0);
}
int
-can_expand_path(struct sftp_conn *conn)
+sftp_can_expand_path(struct sftp_conn *conn)
{
return (conn->exts & SFTP_EXT_PATH_EXPAND) != 0;
}
char *
-do_expand_path(struct sftp_conn *conn, const char *path)
+sftp_expand_path(struct sftp_conn *conn, const char *path)
{
- if (!can_expand_path(conn)) {
+ if (!sftp_can_expand_path(conn)) {
debug3_f("no server support, fallback to realpath");
- return do_realpath_expand(conn, path, 0);
+ return sftp_realpath_expand(conn, path, 0);
}
- return do_realpath_expand(conn, path, 1);
+ return sftp_realpath_expand(conn, path, 1);
}
int
-do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
+sftp_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
- Attrib junk, *a;
+ Attrib junk, attr;
struct sshbuf *msg;
u_char *old_handle, *new_handle;
u_int mode, status, id;
@@ -1114,14 +1116,14 @@ do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
/* Make sure the file exists, and we can copy its perms */
- if ((a = do_stat(conn, oldpath, 0)) == NULL)
+ if (sftp_stat(conn, oldpath, 0, &attr) != 0)
return -1;
/* Do not preserve set[ug]id here, as we do not preserve ownership */
- if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
- mode = a->perm & 0777;
+ if (attr.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
+ mode = attr.perm & 0777;
- if (!S_ISREG(a->perm)) {
+ if (!S_ISREG(attr.perm)) {
error("Cannot copy non-regular file: %s", oldpath);
return -1;
}
@@ -1131,9 +1133,9 @@ do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
/* Set up the new perms for the new file */
- attrib_clear(a);
- a->perm = mode;
- a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
+ attrib_clear(&attr);
+ attr.perm = mode;
+ attr.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
@@ -1167,7 +1169,7 @@ do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
(r = sshbuf_put_cstring(msg, newpath)) != 0 ||
(r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|
SSH2_FXF_TRUNC)) != 0 ||
- (r = encode_attrib(msg, a)) != 0)
+ (r = encode_attrib(msg, &attr)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
send_msg(conn, msg);
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, newpath);
@@ -1204,8 +1206,8 @@ do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
/* Clean up everything */
sshbuf_free(msg);
- do_close(conn, old_handle, old_handle_len);
- do_close(conn, new_handle, new_handle_len);
+ sftp_close(conn, old_handle, old_handle_len);
+ sftp_close(conn, new_handle, new_handle_len);
free(old_handle);
free(new_handle);
@@ -1213,7 +1215,7 @@ do_copy(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
int
-do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
+sftp_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
int force_legacy)
{
struct sshbuf *msg;
@@ -1258,7 +1260,7 @@ do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
}
int
-do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
+sftp_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
struct sshbuf *msg;
u_int status, id;
@@ -1296,7 +1298,7 @@ do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
int
-do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
+sftp_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
{
struct sshbuf *msg;
u_int status, id;
@@ -1332,7 +1334,7 @@ do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
}
int
-do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
+sftp_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
{
struct sshbuf *msg;
u_int status, id;
@@ -1365,7 +1367,7 @@ do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
#ifdef notyet
char *
-do_readlink(struct sftp_conn *conn, const char *path)
+sftp_readlink(struct sftp_conn *conn, const char *path)
{
struct sshbuf *msg;
u_int expected_id, count, id;
@@ -1423,7 +1425,7 @@ do_readlink(struct sftp_conn *conn, const char *path)
#endif
int
-do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
+sftp_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
int quiet)
{
struct sshbuf *msg;
@@ -1454,7 +1456,7 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
#ifdef notyet
int
-do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
+sftp_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
struct sftp_statvfs *st, int quiet)
{
struct sshbuf *msg;
@@ -1484,7 +1486,7 @@ do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
#endif
int
-do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
+sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a)
{
struct sshbuf *msg;
u_int status, id;
@@ -1592,7 +1594,7 @@ progress_meter_path(const char *path)
}
int
-do_download(struct sftp_conn *conn, const char *remote_path,
+sftp_download(struct sftp_conn *conn, const char *remote_path,
const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
int fsync_flag, int inplace_flag)
{
@@ -1608,14 +1610,18 @@ do_download(struct sftp_conn *conn, const char *remote_path,
struct requests requests;
struct request *req;
u_char type;
+ Attrib attr;
debug2_f("download remote \"%s\" to local \"%s\"",
remote_path, local_path);
TAILQ_INIT(&requests);
- if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
- return -1;
+ if (a == NULL) {
+ if (sftp_stat(conn, remote_path, 0, &attr) != 0)
+ return -1;
+ a = &attr;
+ }
/* Do not preserve set[ug]id here, as we do not preserve ownership */
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
@@ -1661,7 +1667,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
error("Unable to resume download of \"%s\": "
"local file is larger than remote", local_path);
fail:
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
free(handle);
if (local_fd != -1)
close(local_fd);
@@ -1836,14 +1842,14 @@ do_download(struct sftp_conn *conn, const char *remote_path,
if (read_error) {
error("read remote \"%s\" : %s", remote_path, fx2txt(status));
status = -1;
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
} else if (write_error) {
error("write local \"%s\": %s", local_path,
strerror(write_errno));
status = SSH2_FX_FAILURE;
- do_close(conn, handle, handle_len);
+ sftp_close(conn, handle, handle_len);
} else {
- if (do_close(conn, handle, handle_len) != 0 || interrupted)
+ if (sftp_close(conn, handle, handle_len) != 0 || interrupted)
status = SSH2_FX_FAILURE;
else
status = SSH2_FX_OK;
@@ -1890,6 +1896,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
SFTP_DIRENT **dir_entries;
char *filename, *new_src = NULL, *new_dst = NULL;
mode_t mode = 0777, tmpmode = mode;
+ Attrib *a, ldirattrib, lsym;
if (depth >= MAX_DIR_DEPTH) {
error("Maximum directory depth exceeded: %d levels", depth);
@@ -1898,10 +1905,12 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
debug2_f("download dir remote \"%s\" to local \"%s\"", src, dst);
- if (dirattrib == NULL &&
- (dirattrib = do_stat(conn, src, 1)) == NULL) {
- error("stat remote \"%s\" directory failed", src);
- return -1;
+ if (dirattrib == NULL) {
+ if (sftp_stat(conn, src, 1, &ldirattrib) != 0) {
+ error("stat remote \"%s\" directory failed", src);
+ return -1;
+ }
+ dirattrib = &ldirattrib;
}
if (!S_ISDIR(dirattrib->perm)) {
error("\"%s\" is not a directory", src);
@@ -1923,7 +1932,7 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
return -1;
}
- if (do_readdir(conn, src, &dir_entries) == -1) {
+ if (sftp_readdir(conn, src, &dir_entries) == -1) {
error("remote readdir \"%s\" failed", src);
return -1;
}
@@ -1933,28 +1942,36 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
free(new_src);
filename = dir_entries[i]->filename;
- new_dst = path_append(dst, filename);
- new_src = path_append(src, filename);
+ new_dst = sftp_path_append(dst, filename);
+ new_src = sftp_path_append(src, filename);
+
+ a = &dir_entries[i]->a;
+ if (S_ISLNK(a->perm)) {
+ if (!follow_link_flag) {
+ logit("download \"%s\": not a regular file",
+ new_src);
+ continue;
+ }
+ /* Replace the stat contents with the symlink target */
+ if (sftp_stat(conn, new_src, 1, &lsym) != 0) {
+ logit("remote stat \"%s\" failed", new_src);
+ ret = -1;
+ continue;
+ }
+ a = &lsym;
+ }
- if (S_ISDIR(dir_entries[i]->a.perm)) {
+ if (S_ISDIR(a->perm)) {
if (strcmp(filename, ".") == 0 ||
strcmp(filename, "..") == 0)
continue;
if (download_dir_internal(conn, new_src, new_dst,
- depth + 1, &(dir_entries[i]->a), preserve_flag,
+ depth + 1, a, preserve_flag,
print_flag, resume_flag,
fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
- } else if (S_ISREG(dir_entries[i]->a.perm) ||
- (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
- /*
- * If this is a symlink then don't send the link's
- * Attrib. do_download() will do a FXP_STAT operation
- * and get the link target's attributes.
- */
- if (do_download(conn, new_src, new_dst,
- S_ISLNK(dir_entries[i]->a.perm) ? NULL :
- &(dir_entries[i]->a),
+ } else if (S_ISREG(a->perm)) {
+ if (sftp_download(conn, new_src, new_dst, a,
preserve_flag, resume_flag, fsync_flag,
inplace_flag) == -1) {
error("Download of file %s to %s failed",
@@ -1986,20 +2003,20 @@ download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
error("local chmod directory \"%s\": %s", dst,
strerror(errno));
- free_sftp_dirents(dir_entries);
+ sftp_free_dirents(dir_entries);
return ret;
}
int
-download_dir(struct sftp_conn *conn, const char *src, const char *dst,
+sftp_download_dir(struct sftp_conn *conn, const char *src, const char *dst,
Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
int fsync_flag, int follow_link_flag, int inplace_flag)
{
char *src_canon;
int ret;
- if ((src_canon = do_realpath(conn, src)) == NULL) {
+ if ((src_canon = sftp_realpath(conn, src)) == NULL) {
error("download \"%s\": path canonicalization failed", src);
return -1;
}
@@ -2012,7 +2029,7 @@ download_dir(struct sftp_conn *conn, const char *src, const char *dst,
}
int
-do_upload(struct sftp_conn *conn, const char *local_path,
+sftp_upload(struct sftp_conn *conn, const char *local_path,
const char *remote_path, int preserve_flag, int resume,
int fsync_flag, int inplace_flag)
{
@@ -2022,7 +2039,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
u_char type, *handle, *data;
struct sshbuf *msg;
struct stat sb;
- Attrib a, t, *c = NULL;
+ Attrib a, t, c;
u_int32_t startid, ackid;
u_int64_t highwater = 0, maxack = 0;
struct request *ack = NULL;
@@ -2058,19 +2075,19 @@ do_upload(struct sftp_conn *conn, const char *local_path,
if (resume) {
/* Get remote file size if it exists */
- if ((c = do_stat(conn, remote_path, 0)) == NULL) {
+ if (sftp_stat(conn, remote_path, 0, &c) != 0) {
close(local_fd);
return -1;
}
- if ((off_t)c->size >= sb.st_size) {
+ if ((off_t)c.size >= sb.st_size) {
error("resume \"%s\": destination file "
"same size or larger", local_path);
close(local_fd);
return -1;
}
- if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) {
+ if (lseek(local_fd, (off_t)c.size, SEEK_SET) == -1) {
close(local_fd);
return -1;
}
@@ -2094,7 +2111,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
data = xmalloc(conn->upload_buflen);
/* Read from local and write to remote */
- offset = progress_counter = (resume ? c->size : 0);
+ offset = progress_counter = (resume ? c.size : 0);
if (showprogress) {
start_progress_meter(progress_meter_path(local_path),
sb.st_size, &progress_counter);
@@ -2206,7 +2223,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
attrib_clear(&t);
t.flags = SSH2_FILEXFER_ATTR_SIZE;
t.size = highwater;
- do_fsetstat(conn, handle, handle_len, &t);
+ sftp_fsetstat(conn, handle, handle_len, &t);
}
if (close(local_fd) == -1) {
@@ -2216,12 +2233,12 @@ do_upload(struct sftp_conn *conn, const char *local_path,
/* Override umask and utimes if asked */
if (preserve_flag)
- do_fsetstat(conn, handle, handle_len, &a);
+ sftp_fsetstat(conn, handle, handle_len, &a);
if (fsync_flag)
- (void)do_fsync(conn, handle, handle_len);
+ (void)sftp_fsync(conn, handle, handle_len);
- if (do_close(conn, handle, handle_len) != 0)
+ if (sftp_close(conn, handle, handle_len) != 0)
status = SSH2_FX_FAILURE;
free(handle);
@@ -2239,7 +2256,7 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
struct dirent *dp;
char *filename, *new_src = NULL, *new_dst = NULL;
struct stat sb;
- Attrib a, *dirattrib;
+ Attrib a, dirattrib;
u_int32_t saved_perm;
debug2_f("upload local dir \"%s\" to remote \"%s\"", src, dst);
@@ -2275,10 +2292,10 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
*/
saved_perm = a.perm;
a.perm |= (S_IWUSR|S_IXUSR);
- if (do_mkdir(conn, dst, &a, 0) != 0) {
- if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
+ if (sftp_mkdir(conn, dst, &a, 0) != 0) {
+ if (sftp_stat(conn, dst, 0, &dirattrib) != 0)
return -1;
- if (!S_ISDIR(dirattrib->perm)) {
+ if (!S_ISDIR(dirattrib.perm)) {
error("\"%s\" exists but is not a directory", dst);
return -1;
}
@@ -2296,25 +2313,37 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
free(new_dst);
free(new_src);
filename = dp->d_name;
- new_dst = path_append(dst, filename);
- new_src = path_append(src, filename);
+ new_dst = sftp_path_append(dst, filename);
+ new_src = sftp_path_append(src, filename);
+ if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
+ continue;
if (lstat(new_src, &sb) == -1) {
logit("local lstat \"%s\": %s", filename,
strerror(errno));
ret = -1;
- } else if (S_ISDIR(sb.st_mode)) {
- if (strcmp(filename, ".") == 0 ||
- strcmp(filename, "..") == 0)
+ continue;
+ }
+ if (S_ISLNK(sb.st_mode)) {
+ if (!follow_link_flag) {
+ logit("%s: not a regular file", filename);
continue;
-
+ }
+ /* Replace the stat contents with the symlink target */
+ if (stat(new_src, &sb) == -1) {
+ logit("local stat \"%s\": %s", filename,
+ strerror(errno));
+ ret = -1;
+ continue;
+ }
+ }
+ if (S_ISDIR(sb.st_mode)) {
if (upload_dir_internal(conn, new_src, new_dst,
depth + 1, preserve_flag, print_flag, resume,
fsync_flag, follow_link_flag, inplace_flag) == -1)
ret = -1;
- } else if (S_ISREG(sb.st_mode) ||
- (follow_link_flag && S_ISLNK(sb.st_mode))) {
- if (do_upload(conn, new_src, new_dst,
+ } else if (S_ISREG(sb.st_mode)) {
+ if (sftp_upload(conn, new_src, new_dst,
preserve_flag, resume, fsync_flag,
inplace_flag) == -1) {
error("upload \"%s\" to \"%s\" failed",
@@ -2327,21 +2356,21 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
free(new_dst);
free(new_src);
- do_setstat(conn, dst, &a);
+ sftp_setstat(conn, dst, &a);
(void) closedir(dirp);
return ret;
}
int
-upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
+sftp_upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
int preserve_flag, int print_flag, int resume, int fsync_flag,
int follow_link_flag, int inplace_flag)
{
char *dst_canon;
int ret;
- if ((dst_canon = do_realpath(conn, dst)) == NULL) {
+ if ((dst_canon = sftp_realpath(conn, dst)) == NULL) {
error("upload \"%s\": path canonicalization failed", dst);
return -1;
}
@@ -2400,13 +2429,13 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous,
*write_errorp = status;
}
/*
- * XXX this doesn't do full reply matching like do_upload and
+ * XXX this doesn't do full reply matching like sftp_upload and
* so cannot gracefully truncate terminated uploads at a
* high-water mark. ATM the only caller of this function (scp)
* doesn't support transfer resumption, so this doesn't matter
* a whole lot.
*
- * To be safe, do_crossload truncates the destination file to
+ * To be safe, sftp_crossload truncates the destination file to
* zero length on upload failure, since we can't trust the
* server not to have reordered replies that could have
* inserted holes where none existed in the source file.
@@ -2421,7 +2450,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous,
}
int
-do_crossload(struct sftp_conn *from, struct sftp_conn *to,
+sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *a, int preserve_flag)
{
@@ -2436,13 +2465,17 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
struct requests requests;
struct request *req;
u_char type;
+ Attrib attr;
debug2_f("crossload src \"%s\" to dst \"%s\"", from_path, to_path);
TAILQ_INIT(&requests);
- if (a == NULL && (a = do_stat(from, from_path, 0)) == NULL)
- return -1;
+ if (a == NULL) {
+ if (sftp_stat(from, from_path, 0, &attr) != 0)
+ return -1;
+ a = &attr;
+ }
if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
(!S_ISREG(a->perm))) {
@@ -2472,7 +2505,7 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
if (send_open(to, to_path, "dest",
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
&to_handle, &to_handle_len) != 0) {
- do_close(from, from_handle, from_handle_len);
+ sftp_close(from, from_handle, from_handle_len);
return -1;
}
@@ -2622,7 +2655,7 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
/* Truncate at 0 length on interrupt or error to avoid holes at dest */
if (read_error || write_error || interrupted) {
debug("truncating \"%s\" at 0", to_path);
- do_close(to, to_handle, to_handle_len);
+ sftp_close(to, to_handle, to_handle_len);
free(to_handle);
if (send_open(to, to_path, "dest",
SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC, a,
@@ -2634,17 +2667,17 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
if (read_error) {
error("read origin \"%s\": %s", from_path, fx2txt(status));
status = -1;
- do_close(from, from_handle, from_handle_len);
+ sftp_close(from, from_handle, from_handle_len);
if (to_handle != NULL)
- do_close(to, to_handle, to_handle_len);
+ sftp_close(to, to_handle, to_handle_len);
} else if (write_error) {
error("write dest \"%s\": %s", to_path, fx2txt(write_error));
status = SSH2_FX_FAILURE;
- do_close(from, from_handle, from_handle_len);
+ sftp_close(from, from_handle, from_handle_len);
if (to_handle != NULL)
- do_close(to, to_handle, to_handle_len);
+ sftp_close(to, to_handle, to_handle_len);
} else {
- if (do_close(from, from_handle, from_handle_len) != 0 ||
+ if (sftp_close(from, from_handle, from_handle_len) != 0 ||
interrupted)
status = -1;
else
@@ -2652,8 +2685,8 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
if (to_handle != NULL) {
/* Need to resend utimes after write */
if (preserve_flag)
- do_fsetstat(to, to_handle, to_handle_len, a);
- do_close(to, to_handle, to_handle_len);
+ sftp_fsetstat(to, to_handle, to_handle_len, a);
+ sftp_close(to, to_handle, to_handle_len);
}
}
sshbuf_free(msg);
@@ -2673,7 +2706,7 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
SFTP_DIRENT **dir_entries;
char *filename, *new_from_path = NULL, *new_to_path = NULL;
mode_t mode = 0777;
- Attrib curdir;
+ Attrib *a, curdir, ldirattrib, newdir, lsym;
debug2_f("crossload dir src \"%s\" to dst \"%s\"", from_path, to_path);
@@ -2682,10 +2715,12 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
return -1;
}
- if (dirattrib == NULL &&
- (dirattrib = do_stat(from, from_path, 1)) == NULL) {
- error("stat remote \"%s\" failed", from_path);
- return -1;
+ if (dirattrib == NULL) {
+ if (sftp_stat(from, from_path, 1, &ldirattrib) != 0) {
+ error("stat remote \"%s\" failed", from_path);
+ return -1;
+ }
+ dirattrib = &ldirattrib;
}
if (!S_ISDIR(dirattrib->perm)) {
error("\"%s\" is not a directory", from_path);
@@ -2713,17 +2748,17 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
* the path already existed and is a directory. Ensure we can
* write to the directory we create for the duration of the transfer.
*/
- if (do_mkdir(to, to_path, &curdir, 0) != 0) {
- if ((dirattrib = do_stat(to, to_path, 0)) == NULL)
+ if (sftp_mkdir(to, to_path, &curdir, 0) != 0) {
+ if (sftp_stat(to, to_path, 0, &newdir) != 0)
return -1;
- if (!S_ISDIR(dirattrib->perm)) {
+ if (!S_ISDIR(newdir.perm)) {
error("\"%s\" exists but is not a directory", to_path);
return -1;
}
}
curdir.perm = mode;
- if (do_readdir(from, from_path, &dir_entries) == -1) {
+ if (sftp_readdir(from, from_path, &dir_entries) == -1) {
error("origin readdir \"%s\" failed", from_path);
return -1;
}
@@ -2733,28 +2768,36 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
free(new_to_path);
filename = dir_entries[i]->filename;
- new_from_path = path_append(from_path, filename);
- new_to_path = path_append(to_path, filename);
+ new_from_path = sftp_path_append(from_path, filename);
+ new_to_path = sftp_path_append(to_path, filename);
- if (S_ISDIR(dir_entries[i]->a.perm)) {
+ a = &dir_entries[i]->a;
+ if (S_ISLNK(a->perm)) {
+ if (!follow_link_flag) {
+ logit("%s: not a regular file", filename);
+ continue;
+ }
+ /* Replace the stat contents with the symlink target */
+ if (sftp_stat(from, new_from_path, 1, &lsym) != 0) {
+ logit("remote stat \"%s\" failed",
+ new_from_path);
+ ret = -1;
+ continue;
+ }
+ a = &lsym;
+ }
+ if (S_ISDIR(a->perm)) {
if (strcmp(filename, ".") == 0 ||
strcmp(filename, "..") == 0)
continue;
if (crossload_dir_internal(from, to,
new_from_path, new_to_path,
- depth + 1, &(dir_entries[i]->a), preserve_flag,
+ depth + 1, a, preserve_flag,
print_flag, follow_link_flag) == -1)
ret = -1;
- } else if (S_ISREG(dir_entries[i]->a.perm) ||
- (follow_link_flag && S_ISLNK(dir_entries[i]->a.perm))) {
- /*
- * If this is a symlink then don't send the link's
- * Attrib. do_download() will do a FXP_STAT operation
- * and get the link target's attributes.
- */
- if (do_crossload(from, to, new_from_path, new_to_path,
- S_ISLNK(dir_entries[i]->a.perm) ? NULL :
- &(dir_entries[i]->a), preserve_flag) == -1) {
+ } else if (S_ISREG(a->perm)) {
+ if (sftp_crossload(from, to, new_from_path,
+ new_to_path, a, preserve_flag) == -1) {
error("crossload \"%s\" to \"%s\" failed",
new_from_path, new_to_path);
ret = -1;
@@ -2767,22 +2810,22 @@ crossload_dir_internal(struct sftp_conn *from, struct sftp_conn *to,
free(new_to_path);
free(new_from_path);
- do_setstat(to, to_path, &curdir);
+ sftp_setstat(to, to_path, &curdir);
- free_sftp_dirents(dir_entries);
+ sftp_free_dirents(dir_entries);
return ret;
}
int
-crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
+sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *dirattrib, int preserve_flag, int print_flag, int follow_link_flag)
{
char *from_path_canon;
int ret;
- if ((from_path_canon = do_realpath(from, from_path)) == NULL) {
+ if ((from_path_canon = sftp_realpath(from, from_path)) == NULL) {
error("crossload \"%s\": path canonicalization failed",
from_path);
return -1;
@@ -2795,13 +2838,13 @@ crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
}
int
-can_get_users_groups_by_id(struct sftp_conn *conn)
+sftp_can_get_users_groups_by_id(struct sftp_conn *conn)
{
return (conn->exts & SFTP_EXT_GETUSERSGROUPS_BY_ID) != 0;
}
int
-do_get_users_groups_by_id(struct sftp_conn *conn,
+sftp_get_users_groups_by_id(struct sftp_conn *conn,
const u_int *uids, u_int nuids,
const u_int *gids, u_int ngids,
char ***usernamesp, char ***groupnamesp)
@@ -2813,7 +2856,7 @@ do_get_users_groups_by_id(struct sftp_conn *conn,
int r;
*usernamesp = *groupnamesp = NULL;
- if (!can_get_users_groups_by_id(conn))
+ if (!sftp_can_get_users_groups_by_id(conn))
return SSH_ERR_FEATURE_UNSUPPORTED;
if ((msg = sshbuf_new()) == NULL ||
@@ -2909,7 +2952,7 @@ do_get_users_groups_by_id(struct sftp_conn *conn,
}
char *
-path_append(const char *p1, const char *p2)
+sftp_path_append(const char *p1, const char *p2)
{
char *ret;
size_t len = strlen(p1) + strlen(p2) + 2;
@@ -2928,13 +2971,13 @@ path_append(const char *p1, const char *p2)
* freed and a replacement allocated. Caller must free returned string.
*/
char *
-make_absolute(char *p, const char *pwd)
+sftp_make_absolute(char *p, const char *pwd)
{
char *abs_str;
/* Derelativise */
if (p && !path_absolute(p)) {
- abs_str = path_append(pwd, p);
+ abs_str = sftp_path_append(pwd, p);
free(p);
return(abs_str);
} else
@@ -2942,34 +2985,22 @@ make_absolute(char *p, const char *pwd)
}
int
-remote_is_dir(struct sftp_conn *conn, const char *path)
+sftp_remote_is_dir(struct sftp_conn *conn, const char *path)
{
- Attrib *a;
+ Attrib a;
/* XXX: report errors? */
- if ((a = do_stat(conn, path, 1)) == NULL)
+ if (sftp_stat(conn, path, 1, &a) != 0)
return(0);
- if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
+ if (!(a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
return(0);
- return(S_ISDIR(a->perm));
+ return S_ISDIR(a.perm);
}
-int
-local_is_dir(const char *path)
-{
- struct stat sb;
-
- /* XXX: report errors? */
- if (stat(path, &sb) == -1)
- return(0);
-
- return(S_ISDIR(sb.st_mode));
-}
-
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
int
-globpath_is_dir(const char *pathname)
+sftp_globpath_is_dir(const char *pathname)
{
size_t l = strlen(pathname);
diff --git a/sftp-client.h b/sftp-client.h
index d7deab17e4cb..74cdae7dc687 100644
--- a/sftp-client.h
+++ b/sftp-client.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.h,v 1.38 2022/09/19 10:43:12 djm Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.39 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@@ -70,107 +70,106 @@ struct sftp_limits {
* Initialise a SSH filexfer connection. Returns NULL on error or
* a pointer to a initialized sftp_conn struct on success.
*/
-struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t);
+struct sftp_conn *sftp_init(int, int, u_int, u_int, u_int64_t);
u_int sftp_proto_version(struct sftp_conn *);
/* Query server limits */
-int do_limits(struct sftp_conn *, struct sftp_limits *);
+int sftp_get_limits(struct sftp_conn *, struct sftp_limits *);
/* Close file referred to by 'handle' */
-int do_close(struct sftp_conn *, const u_char *, u_int);
+int sftp_close(struct sftp_conn *, const u_char *, u_int);
/* Read contents of 'path' to NULL-terminated array 'dir' */
-int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
+int sftp_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
-/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
-void free_sftp_dirents(SFTP_DIRENT **);
+/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from sftp_readdir) */
+void sftp_free_dirents(SFTP_DIRENT **);
/* Delete file 'path' */
-int do_rm(struct sftp_conn *, const char *);
+int sftp_rm(struct sftp_conn *, const char *);
/* Create directory 'path' */
-int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
+int sftp_mkdir(struct sftp_conn *, const char *, Attrib *, int);
/* Remove directory 'path' */
-int do_rmdir(struct sftp_conn *, const char *);
+int sftp_rmdir(struct sftp_conn *, const char *);
/* Get file attributes of 'path' (follows symlinks) */
-Attrib *do_stat(struct sftp_conn *, const char *, int);
+int sftp_stat(struct sftp_conn *, const char *, int, Attrib *);
/* Get file attributes of 'path' (does not follow symlinks) */
-Attrib *do_lstat(struct sftp_conn *, const char *, int);
+int sftp_lstat(struct sftp_conn *, const char *, int, Attrib *);
/* Set file attributes of 'path' */
-int do_setstat(struct sftp_conn *, const char *, Attrib *);
+int sftp_setstat(struct sftp_conn *, const char *, Attrib *);
/* Set file attributes of open file 'handle' */
-int do_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
+int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
/* Set file attributes of 'path', not following symlinks */
-int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
+int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
-char *do_realpath(struct sftp_conn *, const char *);
+char *sftp_realpath(struct sftp_conn *, const char *);
/* Canonicalisation with tilde expansion (requires server extension) */
-char *do_expand_path(struct sftp_conn *, const char *);
+char *sftp_expand_path(struct sftp_conn *, const char *);
/* Returns non-zero if server can tilde-expand paths */
-int can_expand_path(struct sftp_conn *);
+int sftp_can_expand_path(struct sftp_conn *);
/* Get statistics for filesystem hosting file at "path" */
-int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
+int sftp_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
/* Rename 'oldpath' to 'newpath' */
-int do_rename(struct sftp_conn *, const char *, const char *, int);
+int sftp_rename(struct sftp_conn *, const char *, const char *, int);
/* Copy 'oldpath' to 'newpath' */
-int do_copy(struct sftp_conn *, const char *, const char *);
+int sftp_copy(struct sftp_conn *, const char *, const char *);
/* Link 'oldpath' to 'newpath' */
-int do_hardlink(struct sftp_conn *, const char *, const char *);
+int sftp_hardlink(struct sftp_conn *, const char *, const char *);
/* Rename 'oldpath' to 'newpath' */
-int do_symlink(struct sftp_conn *, const char *, const char *);
+int sftp_symlink(struct sftp_conn *, const char *, const char *);
/* Call fsync() on open file 'handle' */
-int do_fsync(struct sftp_conn *conn, u_char *, u_int);
+int sftp_fsync(struct sftp_conn *conn, u_char *, u_int);
/*
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
+int sftp_download(struct sftp_conn *, const char *, const char *, Attrib *,
int, int, int, int);
/*
* Recursively download 'remote_directory' to 'local_directory'. Preserve
* times if 'pflag' is set
*/
-int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
+int sftp_download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
int, int, int, int, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_upload(struct sftp_conn *, const char *, const char *,
+int sftp_upload(struct sftp_conn *, const char *, const char *,
int, int, int, int);
/*
* Recursively upload 'local_directory' to 'remote_directory'. Preserve
* times if 'pflag' is set
*/
-int upload_dir(struct sftp_conn *, const char *, const char *,
+int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
* to 'to' connection at 'to_path'.
*/
-int
-do_crossload(struct sftp_conn *from, struct sftp_conn *to,
+int sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *a, int preserve_flag);
@@ -178,7 +177,7 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
* Recursively download a directory from 'from_path' from the 'from'
* connection and upload it to 'to' connection at 'to_path'.
*/
-int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
+int sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *dirattrib, int preserve_flag, int print_flag,
int follow_link_flag);
@@ -186,26 +185,23 @@ int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
/*
* User/group ID to name translation.
*/
-int can_get_users_groups_by_id(struct sftp_conn *conn);
-int do_get_users_groups_by_id(struct sftp_conn *conn,
+int sftp_can_get_users_groups_by_id(struct sftp_conn *conn);
+int sftp_get_users_groups_by_id(struct sftp_conn *conn,
const u_int *uids, u_int nuids,
const u_int *gids, u_int ngids,
char ***usernamesp, char ***groupnamesp);
/* Concatenate paths, taking care of slashes. Caller must free result. */
-char *path_append(const char *, const char *);
+char *sftp_path_append(const char *, const char *);
/* Make absolute path if relative path and CWD is given. Does not modify
* original if the path is already absolute. */
-char *make_absolute(char *, const char *);
+char *sftp_make_absolute(char *, const char *);
/* Check if remote path is directory */
-int remote_is_dir(struct sftp_conn *conn, const char *path);
-
-/* Check if local path is directory */
-int local_is_dir(const char *path);
+int sftp_remote_is_dir(struct sftp_conn *conn, const char *path);
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
-int globpath_is_dir(const char *pathname);
+int sftp_globpath_is_dir(const char *pathname);
#endif
diff --git a/sftp-glob.c b/sftp-glob.c
index afeb15f9ec11..1b82759b04d6 100644
--- a/sftp-glob.c
+++ b/sftp-glob.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-glob.c,v 1.31 2022/10/24 21:51:55 djm Exp $ */
+/* $OpenBSD: sftp-glob.c,v 1.33 2023/09/10 23:12:32 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -32,7 +32,7 @@
#include "sftp-common.h"
#include "sftp-client.h"
-int remote_glob(struct sftp_conn *, const char *, int,
+int sftp_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *);
struct SFTP_OPENDIR {
@@ -51,7 +51,7 @@ fudge_opendir(const char *path)
r = xcalloc(1, sizeof(*r));
- if (do_readdir(cur.conn, path, &r->dir)) {
+ if (sftp_readdir(cur.conn, path, &r->dir)) {
free(r);
return(NULL);
}
@@ -103,38 +103,38 @@ fudge_readdir(struct SFTP_OPENDIR *od)
static void
fudge_closedir(struct SFTP_OPENDIR *od)
{
- free_sftp_dirents(od->dir);
+ sftp_free_dirents(od->dir);
free(od);
}
static int
fudge_lstat(const char *path, struct stat *st)
{
- Attrib *a;
+ Attrib a;
- if (!(a = do_lstat(cur.conn, path, 1)))
- return(-1);
+ if (sftp_lstat(cur.conn, path, 1, &a) != 0)
+ return -1;
- attrib_to_stat(a, st);
+ attrib_to_stat(&a, st);
- return(0);
+ return 0;
}
static int
fudge_stat(const char *path, struct stat *st)
{
- Attrib *a;
+ Attrib a;
- if (!(a = do_stat(cur.conn, path, 1)))
- return(-1);
+ if (sftp_stat(cur.conn, path, 1, &a) != 0)
+ return -1;
- attrib_to_stat(a, st);
+ attrib_to_stat(&a, st);
return(0);
}
int
-remote_glob(struct sftp_conn *conn, const char *pattern, int flags,
+sftp_glob(struct sftp_conn *conn, const char *pattern, int flags,
int (*errfunc)(const char *, int), glob_t *pglob)
{
int r;
diff --git a/sftp-usergroup.c b/sftp-usergroup.c
index 083930a4a327..93396ffc63db 100644
--- a/sftp-usergroup.c
+++ b/sftp-usergroup.c
@@ -106,9 +106,9 @@ lookup_and_record(struct sftp_conn *conn,
u_int i;
char **usernames = NULL, **groupnames = NULL;
- if ((r = do_get_users_groups_by_id(conn, uids, nuids, gids, ngids,
+ if ((r = sftp_get_users_groups_by_id(conn, uids, nuids, gids, ngids,
&usernames, &groupnames)) != 0) {
- debug_fr(r, "do_get_users_groups_by_id");
+ debug_fr(r, "sftp_get_users_groups_by_id");
return;
}
for (i = 0; i < nuids; i++) {
@@ -176,7 +176,7 @@ get_remote_user_groups_from_glob(struct sftp_conn *conn, glob_t *g)
{
u_int *uids = NULL, nuids = 0, *gids = NULL, ngids = 0;
- if (!can_get_users_groups_by_id(conn))
+ if (!sftp_can_get_users_groups_by_id(conn))
return;
collect_ids_from_glob(g, 1, &uids, &nuids);
@@ -215,7 +215,7 @@ get_remote_user_groups_from_dirents(struct sftp_conn *conn, SFTP_DIRENT **d)
{
u_int *uids = NULL, nuids = 0, *gids = NULL, ngids = 0;
- if (!can_get_users_groups_by_id(conn))
+ if (!sftp_can_get_users_groups_by_id(conn))
return;
collect_ids_from_dirents(d, 1, &uids, &nuids);
diff --git a/sftp.c b/sftp.c
index b113f930973d..c609b4153d79 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.234 2023/04/12 08:53:54 jsg Exp $ */
+/* $OpenBSD: sftp.c,v 1.236 2023/09/10 23:12:32 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@@ -110,7 +110,7 @@ struct complete_ctx {
char **remote_pathp;
};
-int remote_glob(struct sftp_conn *, const char *, int,
+int sftp_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */
extern char *__progname;
@@ -628,12 +628,22 @@ make_absolute_pwd_glob(char *p, const char *pwd)
escpwd = escape_glob(pwd);
if (p == NULL)
return escpwd;
- ret = make_absolute(p, escpwd);
+ ret = sftp_make_absolute(p, escpwd);
free(escpwd);
return ret;
}
static int
+local_is_dir(const char *path)
+{
+ struct stat sb;
+
+ if (stat(path, &sb) == -1)
+ return 0;
+ return S_ISDIR(sb.st_mode);
+}
+
+static int
process_get(struct sftp_conn *conn, const char *src, const char *dst,
const char *pwd, int pflag, int rflag, int resume, int fflag)
{
@@ -645,7 +655,7 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
memset(&g, 0, sizeof(g));
debug3("Looking up %s", abs_src);
- if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
+ if ((r = sftp_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
if (r == GLOB_NOSPACE) {
error("Too many matches for \"%s\".", abs_src);
} else {
@@ -677,12 +687,12 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
if (g.gl_matchc == 1 && dst) {
if (local_is_dir(dst)) {
- abs_dst = path_append(dst, filename);
+ abs_dst = sftp_path_append(dst, filename);
} else {
abs_dst = xstrdup(dst);
}
} else if (dst) {
- abs_dst = path_append(dst, filename);
+ abs_dst = sftp_path_append(dst, filename);
} else {
abs_dst = xstrdup(filename);
}
@@ -696,13 +706,14 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
mprintf("Fetching %s to %s\n",
g.gl_pathv[i], abs_dst);
/* XXX follow link flag */
- if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
- if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
- pflag || global_pflag, 1, resume,
+ if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
+ (rflag || global_rflag)) {
+ if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst,
+ NULL, pflag || global_pflag, 1, resume,
fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
- if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
+ if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
@@ -731,7 +742,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
if (dst) {
tmp_dst = xstrdup(dst);
- tmp_dst = make_absolute(tmp_dst, pwd);
+ tmp_dst = sftp_make_absolute(tmp_dst, pwd);
}
memset(&g, 0, sizeof(g));
@@ -744,7 +755,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
/* If we aren't fetching to pwd then stash this status for later */
if (tmp_dst != NULL)
- dst_is_dir = remote_is_dir(conn, tmp_dst);
+ dst_is_dir = sftp_remote_is_dir(conn, tmp_dst);
/* If multiple matches, dst may be directory or unspecified */
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
@@ -774,13 +785,13 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
if (g.gl_matchc == 1 && tmp_dst) {
/* If directory specified, append filename */
if (dst_is_dir)
- abs_dst = path_append(tmp_dst, filename);
+ abs_dst = sftp_path_append(tmp_dst, filename);
else
abs_dst = xstrdup(tmp_dst);
} else if (tmp_dst) {
- abs_dst = path_append(tmp_dst, filename);
+ abs_dst = sftp_path_append(tmp_dst, filename);
} else {
- abs_dst = make_absolute(xstrdup(filename), pwd);
+ abs_dst = sftp_make_absolute(xstrdup(filename), pwd);
}
free(tmp);
@@ -792,13 +803,14 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
mprintf("Uploading %s to %s\n",
g.gl_pathv[i], abs_dst);
/* XXX follow_link_flag */
- if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
- if (upload_dir(conn, g.gl_pathv[i], abs_dst,
+ if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
+ (rflag || global_rflag)) {
+ if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
- if (do_upload(conn, g.gl_pathv[i], abs_dst,
+ if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
@@ -839,7 +851,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
u_int c = 1, colspace = 0, columns = 1;
SFTP_DIRENT **d;
- if ((n = do_readdir(conn, path, &d)) != 0)
+ if ((n = sftp_readdir(conn, path, &d)) != 0)
return (n);
if (!(lflag & LS_SHORT_VIEW)) {
@@ -881,13 +893,13 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
continue;
- tmp = path_append(path, d[n]->filename);
+ tmp = sftp_path_append(path, d[n]->filename);
fname = path_strip(tmp, strip_path);
free(tmp);
if (lflag & LS_LONG_VIEW) {
if ((lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) != 0 ||
- can_get_users_groups_by_id(conn)) {
+ sftp_can_get_users_groups_by_id(conn)) {
char *lname;
struct stat sb;
@@ -916,7 +928,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
if (!(lflag & LS_LONG_VIEW) && (c != 1))
printf("\n");
- free_sftp_dirents(d);
+ sftp_free_dirents(d);
return (0);
}
@@ -965,7 +977,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
memset(&g, 0, sizeof(g));
- if ((r = remote_glob(conn, path,
+ if ((r = sftp_glob(conn, path,
GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT|GLOB_NOSORT,
NULL, &g)) != 0 ||
(g.gl_pathc && !g.gl_matchc)) {
@@ -1070,7 +1082,7 @@ do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];
char s_icapacity[16], s_dcapacity[16];
- if (do_statvfs(conn, path, &st, 1) == -1)
+ if (sftp_statvfs(conn, path, &st, 1) == -1)
return -1;
if (st.f_files == 0)
strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
@@ -1544,7 +1556,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
- Attrib a, *aa;
+ Attrib a, aa;
char path_buf[PATH_MAX];
int err = 0;
glob_t g;
@@ -1585,66 +1597,67 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
rflag, aflag, fflag);
break;
case I_COPY:
- path1 = make_absolute(path1, *pwd);
- path2 = make_absolute(path2, *pwd);
- err = do_copy(conn, path1, path2);
+ path1 = sftp_make_absolute(path1, *pwd);
+ path2 = sftp_make_absolute(path2, *pwd);
+ err = sftp_copy(conn, path1, path2);
break;
case I_RENAME:
- path1 = make_absolute(path1, *pwd);
- path2 = make_absolute(path2, *pwd);
- err = do_rename(conn, path1, path2, lflag);
+ path1 = sftp_make_absolute(path1, *pwd);
+ path2 = sftp_make_absolute(path2, *pwd);
+ err = sftp_rename(conn, path1, path2, lflag);
break;
case I_SYMLINK:
sflag = 1;
/* FALLTHROUGH */
case I_LINK:
if (!sflag)
- path1 = make_absolute(path1, *pwd);
- path2 = make_absolute(path2, *pwd);
- err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
+ path1 = sftp_make_absolute(path1, *pwd);
+ path2 = sftp_make_absolute(path2, *pwd);
+ err = (sflag ? sftp_symlink : sftp_hardlink)(conn,
+ path1, path2);
break;
case I_RM:
path1 = make_absolute_pwd_glob(path1, *pwd);
- remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ sftp_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Removing %s\n", g.gl_pathv[i]);
- err = do_rm(conn, g.gl_pathv[i]);
+ err = sftp_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
}
break;
case I_MKDIR:
- path1 = make_absolute(path1, *pwd);
+ path1 = sftp_make_absolute(path1, *pwd);
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
- err = do_mkdir(conn, path1, &a, 1);
+ err = sftp_mkdir(conn, path1, &a, 1);
break;
case I_RMDIR:
- path1 = make_absolute(path1, *pwd);
- err = do_rmdir(conn, path1);
+ path1 = sftp_make_absolute(path1, *pwd);
+ err = sftp_rmdir(conn, path1);
break;
case I_CHDIR:
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
- path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(conn, path1)) == NULL) {
+ path1 = sftp_make_absolute(path1, *pwd);
+ if ((tmp = sftp_realpath(conn, path1)) == NULL) {
err = 1;
break;
}
- if ((aa = do_stat(conn, tmp, 0)) == NULL) {
+ if (sftp_stat(conn, tmp, 0, &aa) != 0) {
free(tmp);
err = 1;
break;
}
- if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
+ if (!(aa.flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
error("Can't change directory: Can't check target");
free(tmp);
err = 1;
break;
}
- if (!S_ISDIR(aa->perm)) {
+ if (!S_ISDIR(aa.perm)) {
error("Can't change directory: \"%s\" is not "
"a directory", tmp);
free(tmp);
@@ -1672,7 +1685,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
/* Default to current directory if no path specified */
if (path1 == NULL)
path1 = xstrdup(*pwd);
- path1 = make_absolute(path1, *pwd);
+ path1 = sftp_make_absolute(path1, *pwd);
err = do_df(conn, path1, hflag, iflag);
break;
case I_LCHDIR:
@@ -1709,12 +1722,12 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = n_arg;
- remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ sftp_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Changing mode on %s\n",
g.gl_pathv[i]);
- err = (hflag ? do_lsetstat : do_setstat)(conn,
+ err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
@@ -1723,17 +1736,17 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
case I_CHOWN:
case I_CHGRP:
path1 = make_absolute_pwd_glob(path1, *pwd);
- remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ sftp_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
- if (!(aa = (hflag ? do_lstat : do_stat)(conn,
- g.gl_pathv[i], 0))) {
+ if ((hflag ? sftp_lstat : sftp_stat)(conn,
+ g.gl_pathv[i], 0, &aa) != 0) {
if (err_abort) {
err = -1;
break;
} else
continue;
}
- if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
+ if (!(aa.flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
if (err_abort) {
@@ -1742,20 +1755,20 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
} else
continue;
}
- aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
+ aa.flags &= SSH2_FILEXFER_ATTR_UIDGID;
if (cmdnum == I_CHOWN) {
if (!quiet)
mprintf("Changing owner on %s\n",
g.gl_pathv[i]);
- aa->uid = n_arg;
+ aa.uid = n_arg;
} else {
if (!quiet)
mprintf("Changing group on %s\n",
g.gl_pathv[i]);
- aa->gid = n_arg;
+ aa.gid = n_arg;
}
- err = (hflag ? do_lsetstat : do_setstat)(conn,
- g.gl_pathv[i], aa);
+ err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
+ g.gl_pathv[i], &aa);
if (err != 0 && err_abort)
break;
}
@@ -2004,7 +2017,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,
memset(&g, 0, sizeof(g));
if (remote != LOCAL) {
tmp = make_absolute_pwd_glob(tmp, remote_path);
- remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
+ sftp_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
} else
(void)glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);
@@ -2234,16 +2247,15 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
}
#endif /* USE_LIBEDIT */
- remote_path = do_realpath(conn, ".");
- if (remote_path == NULL)
+ if ((remote_path = sftp_realpath(conn, ".")) == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);
if (file1 != NULL) {
dir = xstrdup(file1);
- dir = make_absolute(dir, remote_path);
+ dir = sftp_make_absolute(dir, remote_path);
- if (remote_is_dir(conn, dir) && file2 == NULL) {
+ if (sftp_remote_is_dir(conn, dir) && file2 == NULL) {
if (!quiet)
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
@@ -2652,7 +2664,7 @@ main(int argc, char **argv)
}
freeargs(&args);
- conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
+ conn = sftp_init(in, out, copy_buffer_len, num_requests, limit_kbps);
if (conn == NULL)
fatal("Couldn't initialise connection to server");
diff --git a/ssh-agent.0 b/ssh-agent.0
index dbd4f17b76b5..9be740d30e63 100644
--- a/ssh-agent.0
+++ b/ssh-agent.0
@@ -48,7 +48,7 @@ DESCRIPTION
only local clients may perform this operation. Note that
signalling that an ssh-agent client is remote is performed by
ssh(1), and use of other tools to forward access to the agent
- socket, may circumvent this restriction.
+ socket may circumvent this restriction.
The no-restrict-websafe option instructs ssh-agent to permit
signatures using FIDO keys that might be web authentication
@@ -66,7 +66,7 @@ DESCRIPTION
used with the -S or -s options to ssh-add(1). Libraries that do
not match the pattern list will be refused. See PATTERNS in
ssh_config(5) for a description of pattern-list syntax. The
- default list is M-bM-^@M-^\/usr/lib/*,/usr/local/lib/*M-bM-^@M-^].
+ default list is M-bM-^@M-^\usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^].
-s Generate Bourne shell commands on stdout. This is the default if
SHELL does not look like it's a csh style of shell.
@@ -137,4 +137,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 7.3 July 23, 2023 OpenBSD 7.3
+OpenBSD 7.3 August 10, 2023 OpenBSD 7.3
diff --git a/ssh-agent.1 b/ssh-agent.1
index 327f0e196644..0b93d03a3d2e 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.78 2023/07/23 20:04:45 naddy Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.79 2023/08/10 14:37:32 naddy Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 23 2023 $
+.Dd $Mdocdate: August 10 2023 $
.Dt SSH-AGENT 1
.Os
.Sh NAME
@@ -122,7 +122,7 @@ Note that signalling that an
.Nm
client is remote is performed by
.Xr ssh 1 ,
-and use of other tools to forward access to the agent socket, may circumvent
+and use of other tools to forward access to the agent socket may circumvent
this restriction.
.Pp
The
@@ -156,7 +156,7 @@ See PATTERNS in
.Xr ssh_config 5
for a description of pattern-list syntax.
The default list is
-.Dq /usr/lib/*,/usr/local/lib/* .
+.Dq usr/lib*/*,/usr/local/lib*/* .
.It Fl s
Generate Bourne shell commands on
.Dv stdout .
diff --git a/ssh-keygen.0 b/ssh-keygen.0
index fbd389cf0e1b..95e4aa364ad1 100644
--- a/ssh-keygen.0
+++ b/ssh-keygen.0
@@ -46,7 +46,7 @@ DESCRIPTION
ssh(1). ssh-keygen can create keys for use by SSH protocol version 2.
The type of key to be generated is specified with the -t option. If
- invoked without any arguments, ssh-keygen will generate an RSA key.
+ invoked without any arguments, ssh-keygen will generate an Ed25519 key.
ssh-keygen is also used to generate groups for use in Diffie-Hellman
group exchange (DH-GEX). See the MODULI GENERATION section for details.
@@ -907,4 +907,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 7.3 July 23, 2023 OpenBSD 7.3
+OpenBSD 7.3 September 4, 2023 OpenBSD 7.3
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index c760f91be14f..c392141ea127 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.229 2023/07/23 20:04:45 naddy Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.230 2023/09/04 10:29:58 job Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 23 2023 $
+.Dd $Mdocdate: September 4 2023 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@@ -185,7 +185,7 @@ The type of key to be generated is specified with the
option.
If invoked without any arguments,
.Nm
-will generate an RSA key.
+will generate an Ed25519 key.
.Pp
.Nm
is also used to generate groups for use in Diffie-Hellman group
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 9ccea624cd90..5b945a849202 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keygen.c,v 1.470 2023/07/17 04:01:10 djm Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.471 2023/09/04 10:29:58 job Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -67,11 +67,7 @@
#include "sk-api.h" /* XXX for SSH_SK_USER_PRESENCE_REQD; remove */
#include "cipher.h"
-#ifdef WITH_OPENSSL
-# define DEFAULT_KEY_TYPE_NAME "rsa"
-#else
-# define DEFAULT_KEY_TYPE_NAME "ed25519"
-#endif
+#define DEFAULT_KEY_TYPE_NAME "ed25519"
/*
* Default number of bits in the RSA, DSA and ECDSA keys. These value can be
@@ -263,7 +259,7 @@ ask_filename(struct passwd *pw, const char *prompt)
char *name = NULL;
if (key_type_name == NULL)
- name = _PATH_SSH_CLIENT_ID_RSA;
+ name = _PATH_SSH_CLIENT_ID_ED25519;
else {
switch (sshkey_type_from_name(key_type_name)) {
case KEY_DSA_CERT:
diff --git a/ssh.c b/ssh.c
index caf3c692c7dd..1dbbda7d6e36 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.593 2023/07/26 23:06:00 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.594 2023/09/03 23:59:32 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2140,7 +2140,7 @@ ssh_session2_open(struct ssh *ssh)
static int
ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
{
- int r, id = -1;
+ int r, interactive, id = -1;
char *cp, *tun_fwd_ifname = NULL;
/* XXX should be pre-session */
@@ -2197,8 +2197,11 @@ ssh_session2(struct ssh *ssh, const struct ssh_conn_info *cinfo)
if (options.session_type != SESSION_TYPE_NONE)
id = ssh_session2_open(ssh);
else {
- ssh_packet_set_interactive(ssh,
- options.control_master == SSHCTL_MASTER_NO,
+ interactive = options.control_master == SSHCTL_MASTER_NO;
+ /* ControlPersist may have clobbered ControlMaster, so check */
+ if (need_controlpersist_detach)
+ interactive = otty_flag != 0;
+ ssh_packet_set_interactive(ssh, interactive,
options.ip_qos_interactive, options.ip_qos_bulk);
}
diff --git a/ssh2.h b/ssh2.h
index 32ddae89b33b..0d48d052782f 100644
--- a/ssh2.h
+++ b/ssh2.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh2.h,v 1.19 2020/11/19 23:05:05 dtucker Exp $ */
+/* $OpenBSD: ssh2.h,v 1.21 2023/08/28 03:28:43 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -85,6 +85,7 @@
#define SSH2_MSG_SERVICE_REQUEST 5
#define SSH2_MSG_SERVICE_ACCEPT 6
#define SSH2_MSG_EXT_INFO 7
+#define SSH2_MSG_NEWCOMPRESS 8
/* transport layer: alg negotiation */
@@ -107,6 +108,10 @@
#define SSH2_MSG_KEX_ECDH_INIT 30
#define SSH2_MSG_KEX_ECDH_REPLY 31
+/* transport layer: OpenSSH extensions */
+#define SSH2_MSG_PING 192
+#define SSH2_MSG_PONG 193
+
/* user authentication: generic */
#define SSH2_MSG_USERAUTH_REQUEST 50
diff --git a/ssh_config.0 b/ssh_config.0
index 1b2a0e5d6d24..aec4901e946c 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -805,6 +805,18 @@ DESCRIPTION
Specifies the number of password prompts before giving up. The
argument to this keyword must be an integer. The default is 3.
+ ObscureKeystrokeTiming
+ Specifies whether ssh(1) should try to obscure inter-keystroke
+ timings from passive observers of network traffic. If enabled,
+ then for interactive sessions, ssh(1) will send keystrokes at
+ fixed intervals of a few tens of milliseconds and will send fake
+ keystroke packets for some time after typing ceases. The
+ argument to this keyword must be yes, no or an interval specifier
+ of the form interval:milliseconds (e.g. interval:80 for 80
+ milliseconds). The default is to obscure keystrokes using a 20ms
+ packet interval. Note that smaller intervals will result in
+ higher fake keystroke packet rates.
+
PasswordAuthentication
Specifies whether to use password authentication. The argument
to this keyword must be yes (the default) or no.
@@ -1306,6 +1318,13 @@ TOKENS
ProxyCommand and ProxyJump accept the tokens %%, %h, %n, %p, and %r.
+ Note that some of these directives build commands for execution via the
+ shell. Because ssh(1) performs no filtering or escaping of characters
+ that have special meaning in shell commands (e.g. quotes), it is the
+ user's reposibility to ensure that the arguments passed to ssh(1) do not
+ contain such characters and that tokens are appropriately quoted when
+ used.
+
ENVIRONMENT VARIABLES
Arguments to some keywords can be expanded at runtime from environment
variables on the client by enclosing them in ${}, for example
@@ -1341,4 +1360,4 @@ AUTHORS
created OpenSSH. Markus Friedl contributed the support for SSH protocol
versions 1.5 and 2.0.
-OpenBSD 7.3 July 17, 2023 OpenBSD 7.3
+OpenBSD 7.3 October 4, 2023 OpenBSD 7.3
diff --git a/ssh_config.5 b/ssh_config.5
index ab8d1021d6cb..367305d2cf9d 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
.\" (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: ssh_config.5,v 1.383 2023/07/17 05:36:14 jsg Exp $
-.Dd $Mdocdate: July 17 2023 $
+.\" $OpenBSD: ssh_config.5,v 1.387 2023/10/04 04:03:50 djm Exp $
+.Dd $Mdocdate: October 4 2023 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -1358,6 +1358,25 @@ or
Specifies the number of password prompts before giving up.
The argument to this keyword must be an integer.
The default is 3.
+.It Cm ObscureKeystrokeTiming
+Specifies whether
+.Xr ssh 1
+should try to obscure inter-keystroke timings from passive observers of
+network traffic.
+If enabled, then for interactive sessions,
+.Xr ssh 1
+will send keystrokes at fixed intervals of a few tens of milliseconds
+and will send fake keystroke packets for some time after typing ceases.
+The argument to this keyword must be
+.Cm yes ,
+.Cm no
+or an interval specifier of the form
+.Cm interval:milliseconds
+(e.g.\&
+.Cm interval:80
+for 80 milliseconds).
+The default is to obscure keystrokes using a 20ms packet interval.
+Note that smaller intervals will result in higher fake keystroke packet rates.
.It Cm PasswordAuthentication
Specifies whether to use password authentication.
The argument to this keyword must be
@@ -2187,6 +2206,16 @@ accepts all tokens.
and
.Cm ProxyJump
accept the tokens %%, %h, %n, %p, and %r.
+.Pp
+Note that some of these directives build commands for execution via the shell.
+Because
+.Xr ssh 1
+performs no filtering or escaping of characters that have special meaning in
+shell commands (e.g. quotes), it is the user's reposibility to ensure that
+the arguments passed to
+.Xr ssh 1
+do not contain such characters and that tokens are appropriately quoted
+when used.
.Sh ENVIRONMENT VARIABLES
Arguments to some keywords can be expanded at runtime from environment
variables on the client by enclosing them in
diff --git a/sshd.0 b/sshd.0
index c048037105ea..98855e8d129d 100644
--- a/sshd.0
+++ b/sshd.0
@@ -168,7 +168,7 @@ AUTHENTICATION
secure channel.
After this, the client either requests an interactive shell or execution
- or a non-interactive command, which sshd will execute via the user's
+ of a non-interactive command, which sshd will execute via the user's
shell using its -c option. The sides then enter session mode. In this
mode, either side may send data at any time, and such data is forwarded
to/from the shell or command on the server side, and the user terminal in
@@ -683,4 +683,4 @@ AUTHORS
versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support
for privilege separation.
-OpenBSD 7.3 February 10, 2023 OpenBSD 7.3
+OpenBSD 7.3 September 19, 2023 OpenBSD 7.3
diff --git a/sshd.8 b/sshd.8
index 9c8f2fcaa86a..73d5e9232702 100644
--- a/sshd.8
+++ b/sshd.8
@@ -33,8 +33,8 @@
.\" (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: sshd.8,v 1.324 2023/02/10 06:39:27 jmc Exp $
-.Dd $Mdocdate: February 10 2023 $
+.\" $OpenBSD: sshd.8,v 1.325 2023/09/19 20:37:07 deraadt Exp $
+.Dd $Mdocdate: September 19 2023 $
.Dt SSHD 8
.Os
.Sh NAME
@@ -320,7 +320,7 @@ forwarding TCP connections, or forwarding the authentication agent
connection over the secure channel.
.Pp
After this, the client either requests an interactive shell or execution
-or a non-interactive command, which
+of a non-interactive command, which
.Nm
will execute via the user's shell using its
.Fl c
diff --git a/sshd.c b/sshd.c
index 264e81ac705b..8524808f94b9 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1697,7 +1697,7 @@ main(int ac, char **av)
break;
case 'V':
fprintf(stderr, "%s, %s\n",
- SSH_VERSION, SSH_OPENSSL_VERSION);
+ SSH_RELEASE, SSH_OPENSSL_VERSION);
exit(0);
default:
usage();
diff --git a/sshkey.c b/sshkey.c
index 727728536b34..2d3906ad8475 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.137 2023/07/27 22:23:05 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.138 2023/08/21 04:36:46 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@@ -41,6 +41,7 @@
#include <errno.h>
#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <resolv.h>
#include <time.h>
diff --git a/sshsig.c b/sshsig.c
index 854d67322409..d219db90e9a3 100644
--- a/sshsig.c
+++ b/sshsig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshsig.c,v 1.32 2023/04/06 03:56:02 djm Exp $ */
+/* $OpenBSD: sshsig.c,v 1.33 2023/09/06 23:18:15 djm Exp $ */
/*
* Copyright (c) 2019 Google LLC
*
@@ -38,7 +38,7 @@
#define SIG_VERSION 0x01
#define MAGIC_PREAMBLE "SSHSIG"
#define MAGIC_PREAMBLE_LEN (sizeof(MAGIC_PREAMBLE) - 1)
-#define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----\n"
+#define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----"
#define END_SIGNATURE "-----END SSH SIGNATURE-----"
#define RSA_SIGN_ALG "rsa-sha2-512" /* XXX maybe make configurable */
#define RSA_SIGN_ALLOWED "rsa-sha2-512,rsa-sha2-256"
@@ -59,8 +59,7 @@ sshsig_armor(const struct sshbuf *blob, struct sshbuf **out)
goto out;
}
- if ((r = sshbuf_put(buf, BEGIN_SIGNATURE,
- sizeof(BEGIN_SIGNATURE)-1)) != 0) {
+ if ((r = sshbuf_putf(buf, "%s\n", BEGIN_SIGNATURE)) != 0) {
error_fr(r, "sshbuf_putf");
goto out;
}
@@ -99,23 +98,35 @@ sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out)
return SSH_ERR_ALLOC_FAIL;
}
+ /* Expect and consume preamble + lf/crlf */
if ((r = sshbuf_cmp(sbuf, 0,
BEGIN_SIGNATURE, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
error("Couldn't parse signature: missing header");
goto done;
}
-
if ((r = sshbuf_consume(sbuf, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
error_fr(r, "consume");
goto done;
}
-
+ if ((r = sshbuf_cmp(sbuf, 0, "\r\n", 2)) == 0)
+ eoffset = 2;
+ else if ((r = sshbuf_cmp(sbuf, 0, "\n", 1)) == 0)
+ eoffset = 1;
+ else {
+ r = SSH_ERR_INVALID_FORMAT;
+ error_f("no header eol");
+ goto done;
+ }
+ if ((r = sshbuf_consume(sbuf, eoffset)) != 0) {
+ error_fr(r, "consume eol");
+ goto done;
+ }
+ /* Find and consume lf + suffix (any prior cr would be ignored) */
if ((r = sshbuf_find(sbuf, 0, "\n" END_SIGNATURE,
- sizeof("\n" END_SIGNATURE)-1, &eoffset)) != 0) {
+ sizeof(END_SIGNATURE), &eoffset)) != 0) {
error("Couldn't parse signature: missing footer");
goto done;
}
-
if ((r = sshbuf_consume_end(sbuf, sshbuf_len(sbuf)-eoffset)) != 0) {
error_fr(r, "consume");
goto done;
diff --git a/version.h b/version.h
index e5b1e719d4d6..1363d4706812 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
-/* $OpenBSD: version.h,v 1.98 2023/08/10 01:01:07 djm Exp $ */
+/* $OpenBSD: version.h,v 1.99 2023/10/04 04:04:09 djm Exp $ */
-#define SSH_VERSION "OpenSSH_9.4"
+#define SSH_VERSION "OpenSSH_9.5"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE