diff --git a/crypto/openssh/.cvsignore b/crypto/openssh/.cvsignore new file mode 100644 index 000000000000..9baaa3b4e3f6 --- /dev/null +++ b/crypto/openssh/.cvsignore @@ -0,0 +1,28 @@ +*.0 +*.out +Makefile +autom4te.cache +buildit.sh +buildpkg.sh +config.cache +config.h +config.h.in +config.log +config.status +configure +openssh.xml +opensshd.init +scp +sftp +sftp-server +ssh +ssh-add +ssh-agent +ssh-keygen +ssh-keyscan +ssh-keysign +ssh-pkcs11-helper +sshd +stamp-h.in +survey +survey.sh diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog index 63aeae5564a4..092cc48ef89b 100644 --- a/crypto/openssh/ChangeLog +++ b/crypto/openssh/ChangeLog @@ -1,3817 +1,8584 @@ -20131006 - - (djm) Release OpenSSH-6.7 +commit 9f82e5a9042f2d872e98f48a876fcab3e25dd9bb +Author: Tim Rice +Date: Mon Mar 16 22:49:20 2015 -0700 -20141003 - - (djm) [sshd_config.5] typo; from Iain Morgan + portability fix: Solaris systems may not have a grep that understands -q -20141001 - - (djm) [openbsd-compat/Makefile.in openbsd-compat/kludge-fd_set.c] - [openbsd-compat/openbsd-compat.h] Kludge around bad glibc - _FORTIFY_SOURCE check that doesn't grok heap-allocated fd_sets; - ok dtucker@ +commit 8ef691f7d9ef500257a549d0906d78187490668f +Author: Damien Miller +Date: Wed Mar 11 10:35:26 2015 +1100 -20140910 - - (djm) [sandbox-seccomp-filter.c] Allow mremap and exit for DietLibc; - patch from Felix von Leitner; ok dtucker + fix compile with clang -20140908 - - (dtucker) [INSTALL] Update info about egd. ok djm@ +commit 4df590cf8dc799e8986268d62019b487a8ed63ad +Author: Damien Miller +Date: Wed Mar 11 10:02:39 2015 +1100 -20140904 - - (djm) [openbsd-compat/arc4random.c] Zero seed after keying PRNG + make unit tests work for !OPENSSH_HAS_ECC -20140903 - - (djm) [defines.h sshbuf.c] Move __predict_true|false to defines.h and - conditionalise to avoid duplicate definition. - - (djm) [contrib/cygwin/ssh-host-config] Fix old code leading to - permissions/ACLs; from Corinna Vinschen +commit 307bb40277ca2c32e97e61d70d1ed74b571fd6ba +Author: djm@openbsd.org +Date: Sat Mar 7 04:41:48 2015 +0000 -20140830 - - (djm) [openbsd-compat/openssl-compat.h] add - OPENSSL_[RD]SA_MAX_MODULUS_BITS defines for OpenSSL that lacks them - - (djm) [misc.c] Missing newline between functions - - (djm) [openbsd-compat/openssl-compat.h] add include guard - - (djm) [Makefile.in] Make TEST_SHELL a variable; "good idea" tim@ + upstream commit + + unbreak for w/SSH1 (default) case; ok markus@ deraadt@ -20140827 - - (djm) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] - [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] - [regress/unittests/sshkey/common.c] - [regress/unittests/sshkey/test_file.c] - [regress/unittests/sshkey/test_fuzz.c] - [regress/unittests/sshkey/test_sshkey.c] Don't include openssl/ec.h - on !ECC OpenSSL systems - - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth - monitor, not preauth; bz#2263 - - (djm) [openbsd-compat/explicit_bzero.c] implement explicit_bzero() - using memset_s() where possible; improve fallback to indirect bzero - via a volatile pointer to give it more of a chance to avoid being - optimised away. +commit b44ee0c998fb4c5f3c3281f2398af5ce42840b6f +Author: Damien Miller +Date: Thu Mar 5 18:39:20 2015 -0800 -20140825 - - (djm) [bufec.c] Skip this file on !ECC OpenSSL - - (djm) [INSTALL] Recommend libcrypto be built -fPIC, mention LibreSSL, - update OpenSSL version requirement. + unbreak hostkeys test for w/ SSH1 case -20140824 - - (djm) [sftp-server.c] Some systems (e.g. Irix) have prctl() but not - PR_SET_DUMPABLE, so adjust ifdef; reported by Tom Christensen +commit 55e5bdeb519cb60cc18b7ba0545be581fb8598b4 +Author: djm@openbsd.org +Date: Fri Mar 6 01:40:56 2015 +0000 -20140823 - - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on - lastlog writing on platforms with high UIDs; bz#2263 - - (djm) [configure.ac] We now require a working vsnprintf everywhere (not - just for systems that lack asprintf); check for it always and extend - test to catch more brokenness. Fixes builds on Solaris <= 9 + upstream commit + + fix sshkey_certify() return value for unsupported key types; + ok markus@ deraadt@ -20140822 - - (djm) [configure.ac] include leading zero characters in OpenSSL version - number; fixes test for unsupported versions - - (djm) [sshbuf-getput-crypto.c] Fix compilation when OpenSSL lacks ECC - - (djm) [openbsd-compat/bsd-snprintf.c] Fix compilation failure (prototype/ - definition mismatch) and warning for broken/missing snprintf case. - - (djm) [configure.ac] double braces to appease autoconf +commit be8f658e550a434eac04256bfbc4289457a24e99 +Author: Damien Miller +Date: Wed Mar 4 15:38:03 2015 -0800 -20140821 - - (djm) [Makefile.in] fix reference to libtest_helper.a in sshkey test too. - - (djm) [key.h] Fix ifdefs for no-ECC OpenSSL - - (djm) [regress/unittests/test_helper/test_helper.c] Fix for systems that - don't set __progname. Diagnosed by Tom Christensen. + update version numbers to match version.h -20140820 - - (djm) [configure.ac] Check OpenSSL version is supported at configure time; - suggested by Kevin Brott - - (djm) [Makefile.in] refer to libtest_helper.a by explicit path rather than - -L/-l; fixes linking problems on some platforms - - (djm) [sshkey.h] Fix compilation when OpenSSL lacks ECC - - (djm) [contrib/cygwin/README] Correct build instructions; from Corinna +commit ac5e8acefa253eb5e5ba186e34236c0e8007afdc +Author: djm@openbsd.org +Date: Wed Mar 4 23:22:35 2015 +0000 -20140819 - - (djm) [serverloop.c] Fix syntax error on Cygwin; from Corinna Vinschen - - (djm) [sshbuf.h] Fix compilation on systems without OPENSSL_HAS_ECC. - - (djm) [ssh-dss.c] Include openssl/dsa.h for DSA_SIG - - (djm) [INSTALL contrib/caldera/openssh.spec contrib/cygwin/README] - [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Remove mentions - of TCP wrappers. + upstream commit + + make these work with !SSH1; ok markus@ deraadt@ -20140811 - - (djm) [myproposal.h] Make curve25519 KEX dependent on - HAVE_EVP_SHA256 instead of OPENSSL_HAS_ECC. +commit 2f04af92f036b0c87a23efb259c37da98cd81fe6 +Author: djm@openbsd.org +Date: Wed Mar 4 21:12:59 2015 +0000 -20140810 - - (djm) [README contrib/caldera/openssh.spec] - [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Update versions + upstream commit + + make ssh-add -D work with !SSH1 agent -20140801 - - (djm) [regress/multiplex.sh] Skip test for non-OpenBSD netcat. We need - a better solution, but this will have to do for now. - - (djm) [regress/multiplex.sh] Instruct nc not to quit as soon as stdin - is closed; avoid regress failures when stdin is /dev/null - - (djm) [regress/multiplex.sh] Use -d (detach stdin) flag to disassociate - nc from stdin, it's more portable +commit a05adf95d2af6abb2b7826ddaa7a0ec0cdc1726b +Author: Damien Miller +Date: Wed Mar 4 00:55:48 2015 -0800 -20140730 - - OpenBSD CVS Sync - - millert@cvs.openbsd.org 2014/07/24 22:57:10 - [ssh.1] - Mention UNIX-domain socket forwarding too. OK jmc@ deraadt@ - - dtucker@cvs.openbsd.org 2014/07/25 21:22:03 - [ssh-agent.c] - Clear buffer used for handling messages. This prevents keys being - left in memory after they have been expired or deleted in some cases - (but note that ssh-agent is setgid so you would still need root to - access them). Pointed out by Kevin Burns, ok deraadt - - schwarze@cvs.openbsd.org 2014/07/28 15:40:08 - [sftp-server.8 sshd_config.5] - some systems no longer need /dev/log; - issue noticed by jirib; - ok deraadt + netcat needs poll.h portability goop -20140725 - - (djm) [regress/multiplex.sh] restore incorrectly deleted line; - pointed out by Christian Hesse +commit dad2b1892b4c1b7e58df483a8c5b983c4454e099 +Author: markus@openbsd.org +Date: Tue Mar 3 22:35:19 2015 +0000 -20140722 - - (djm) [regress/multiplex.sh] ssh mux master lost -N somehow; - put it back - - (djm) [regress/multiplex.sh] change the test for still-open Unix - domain sockets to be robust against nc implementations that produce - error messages. - - (dtucker) [regress/unittests/sshkey/test_{file,fuzz,sshkey}.c] Wrap ecdsa- - specific tests inside OPENSSL_HAS_ECC. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2014/07/22 01:18:50 - [key.c] - Prevent spam from key_load_private_pem during hostbased auth. ok djm@ - - guenther@cvs.openbsd.org 2014/07/22 07:13:42 - [umac.c] - Convert from to the shiney new - ok dtucker@, who also confirmed that -portable handles this already - (ID sync only, includes.h pulls in endian.h if available.) - - djm@cvs.openbsd.org 2014/07/22 01:32:12 - [regress/multiplex.sh] - change the test for still-open Unix domain sockets to be robust against - nc implementations that produce error messages. from -portable - (Id sync only) - - dtucker@cvs.openbsd.org 2014/07/22 23:23:22 - [regress/unittests/sshkey/mktestdata.sh] - Sign test certs with ed25519 instead of ecdsa so that they'll work in - -portable on platforms that don't have ECDSA in their OpenSSL. ok djm - - dtucker@cvs.openbsd.org 2014/07/22 23:57:40 - [regress/unittests/sshkey/mktestdata.sh] - Add $OpenBSD tag to make syncs easier - - dtucker@cvs.openbsd.org 2014/07/22 23:35:38 - [regress/unittests/sshkey/testdata/*] - Regenerate test keys with certs signed with ed25519 instead of ecdsa. - These can be used in -portable on platforms that don't support ECDSA. + upstream commit + + make it possible to run tests w/o ssh1 support; ok djm@ -20140721 - - OpenBSD CVS Sync - - millert@cvs.openbsd.org 2014/07/15 15:54:15 - [forwarding.sh multiplex.sh] - Add support for Unix domain socket forwarding. A remote TCP port - may be forwarded to a local Unix domain socket and vice versa or - both ends may be a Unix domain socket. This is a reimplementation - of the streamlocal patches by William Ahern from: - http://www.25thandclement.com/~william/projects/streamlocal.html - OK djm@ markus@ - - (djm) [regress/multiplex.sh] Not all netcat accept the -N option. - - (dtucker) [sshkey.c] ifdef out unused variable when compiling without - OPENSSL_HAS_ECC. +commit d48a22601bdd3eec054794c535f4ae8d8ae4c6e2 +Author: djm@openbsd.org +Date: Wed Mar 4 18:53:53 2015 +0000 -20140721 - - (dtucker) [cipher.c openbsd-compat/openssl-compat.h] Restore the bits - needed to build AES CTR mode against OpenSSL 0.9.8f and above. ok djm - - (dtucker) [regress/unittests/sshkey/ - {common,test_file,test_fuzz,test_sshkey}.c] Wrap stdint.h includes in - ifdefs. + upstream commit + + crank; ok markus, deraadt -20140719 - - (tim) [openbsd-compat/port-uw.c] Include misc.h for fwd_opts, used - in servconf.h. +commit bbffb23daa0b002dd9f296e396a9ab8a5866b339 +Author: Damien Miller +Date: Tue Mar 3 13:50:27 2015 -0800 -20140718 - - OpenBSD CVS Sync - - millert@cvs.openbsd.org 2014/07/15 15:54:14 - [PROTOCOL auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] - [auth-rsa.c auth.c auth1.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] - [auth2-passwd.c auth2-pubkey.c auth2.c canohost.c channels.c channels.h] - [clientloop.c misc.c misc.h monitor.c mux.c packet.c readconf.c] - [readconf.h servconf.c servconf.h serverloop.c session.c ssh-agent.c] - [ssh.c ssh_config.5 sshconnect.c sshconnect1.c sshconnect2.c sshd.c] - [sshd_config.5 sshlogin.c] - Add support for Unix domain socket forwarding. A remote TCP port - may be forwarded to a local Unix domain socket and vice versa or - both ends may be a Unix domain socket. This is a reimplementation - of the streamlocal patches by William Ahern from: - http://www.25thandclement.com/~william/projects/streamlocal.html - OK djm@ markus@ - - jmc@cvs.openbsd.org 2014/07/16 14:48:57 - [ssh.1] - add the streamlocal* options to ssh's -o list; millert says they're - irrelevant for scp/sftp; - ok markus millert - - djm@cvs.openbsd.org 2014/07/17 00:10:56 - [sandbox-systrace.c] - ifdef SYS_sendsyslog so this will compile without patching on -stable - - djm@cvs.openbsd.org 2014/07/17 00:10:18 - [mux.c] - preserve errno across syscall - - djm@cvs.openbsd.org 2014/07/17 00:12:03 - [key.c] - silence "incorrect passphrase" error spam; reported and ok dtucker@ - - djm@cvs.openbsd.org 2014/07/17 07:22:19 - [mux.c ssh.c] - reflect stdio-forward ("ssh -W host:port ...") failures in exit status. - previously we were always returning 0. bz#2255 reported by Brendan - Germain; ok dtucker - - djm@cvs.openbsd.org 2014/07/18 02:46:01 - [ssh-agent.c] - restore umask around listener socket creation (dropped in streamlocal patch - merge) - - (dtucker) [auth2-gss.c gss-serv-krb5.c] Include misc.h for fwd_opts, used - in servconf.h. - - (dtucker) [Makefile.in] Add a t-exec target to run just the executable - tests. - - (dtucker) [key.c sshkey.c] Put new ecdsa bits inside ifdef OPENSSL_HAS_ECC. + more --without-ssh1 fixes -20140717 - - (djm) [digest-openssl.c] Preserve array order when disabling digests. - Reported by Petr Lautrbach. - - OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2014/07/11 08:09:54 - [sandbox-systrace.c] - Permit use of SYS_sendsyslog from inside the sandbox. Clock is ticking, - update your kernels and sshd soon.. libc will start using sendsyslog() - in about 4 days. - - tedu@cvs.openbsd.org 2014/07/11 13:54:34 - [myproposal.h] - by popular demand, add back hamc-sha1 to server proposal for better compat - with many clients still in use. ok deraadt +commit 6c2039286f503e2012a58a1d109e389016e7a99b +Author: Damien Miller +Date: Tue Mar 3 13:48:48 2015 -0800 -20140715 - - (djm) [configure.ac] Delay checks for arc4random* until after libcrypto - has been located; fixes builds agains libressl-portable + fix merge both that broke --without-ssh1 compile -20140711 - - OpenBSD CVS Sync - - benno@cvs.openbsd.org 2014/07/09 14:15:56 - [ssh-add.c] - fix ssh-add crash while loading more than one key - ok markus@ +commit 111dfb225478a76f89ecbcd31e96eaf1311b59d3 +Author: djm@openbsd.org +Date: Tue Mar 3 21:21:13 2015 +0000 -20140709 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/07/07 08:19:12 - [ssh_config.5] - mention that ProxyCommand is executed using shell "exec" to avoid - a lingering process; bz#1977 - - djm@cvs.openbsd.org 2014/07/09 01:45:10 - [sftp.c] - more useful error message when GLOB_NOSPACE occurs; - bz#2254, patch from Orion Poplawski - - djm@cvs.openbsd.org 2014/07/09 03:02:15 - [key.c] - downgrade more error() to debug() to better match what old authfile.c - did; suppresses spurious errors with hostbased authentication enabled - - djm@cvs.openbsd.org 2014/07/06 07:42:03 - [multiplex.sh test-exec.sh] - add a hook to the cleanup() function to kill $SSH_PID if it is set - - use it to kill the mux master started in multiplex.sh (it was being left - around on fatal failures) - - djm@cvs.openbsd.org 2014/07/07 08:15:26 - [multiplex.sh] - remove forced-fatal that I stuck in there to test the new cleanup - logic and forgot to remove... + upstream commit + + add SSH1 Makefile knob to make it easier to build without + SSH1 support; ok markus@ -20140706 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/07/03 23:18:35 - [authfile.h] - remove leakmalloc droppings - - djm@cvs.openbsd.org 2014/07/05 23:11:48 - [channels.c] - fix remote-forward cancel regression; ok markus@ +commit 3f7f5e6c5d2aa3f6710289c1a30119e534e56c5c +Author: djm@openbsd.org +Date: Tue Mar 3 20:42:49 2015 +0000 -20140704 - - OpenBSD CVS Sync - - jsing@cvs.openbsd.org 2014/07/03 12:42:16 - [cipher-chachapoly.c] - Call chacha_ivsetup() immediately before chacha_encrypt_bytes() - this - makes it easier to verify that chacha_encrypt_bytes() is only called once - per chacha_ivsetup() call. - ok djm@ - - djm@cvs.openbsd.org 2014/07/03 22:23:46 - [sshconnect.c] - when rekeying, skip file/DNS lookup if it is the same as the key sent - during initial key exchange. bz#2154 patch from Iain Morgan; ok markus@ - - djm@cvs.openbsd.org 2014/07/03 22:33:41 - [channels.c] - allow explicit ::1 and 127.0.0.1 forwarding bind addresses when - GatewayPorts=no; allows client to choose address family; - bz#2222 ok markus@ - - djm@cvs.openbsd.org 2014/07/03 22:40:43 - [servconf.c servconf.h session.c sshd.8 sshd_config.5] - Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is - executed, mirroring the no-user-rc authorized_keys option; - bz#2160; ok markus@ + upstream commit + + expand __unused to full __attribute__ for better portability -20140703 - - (djm) [digest-openssl.c configure.ac] Disable RIPEMD160 if libcrypto - doesn't support it. - - (djm) [monitor_fdpass.c] Use sys/poll.h if poll.h doesn't exist; - bz#2237 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/07/03 01:45:38 - [sshkey.c] - make Ed25519 keys' title fit properly in the randomart border; bz#2247 - based on patch from Christian Hesse - - djm@cvs.openbsd.org 2014/07/03 03:11:03 - [ssh-agent.c] - Only cleanup agent socket in the main agent process and not in any - subprocesses it may have started (e.g. forked askpass). Fixes - agent sockets being zapped when askpass processes fatal(); - bz#2236 patch from Dmitry V. Levin - - djm@cvs.openbsd.org 2014/07/03 03:15:01 - [ssh-add.c] - make stdout line-buffered; saves partial output getting lost when - ssh-add fatal()s part-way through (e.g. when listing keys from an - agent that supports key types that ssh-add doesn't); - bz#2234, reported by Phil Pennock - - djm@cvs.openbsd.org 2014/07/03 03:26:43 - [digest-openssl.c] - use EVP_Digest() for one-shot hash instead of creating, updating, - finalising and destroying a context. - bz#2231, based on patch from Timo Teras - - djm@cvs.openbsd.org 2014/07/03 03:34:09 - [gss-serv.c session.c ssh-keygen.c] - standardise on NI_MAXHOST for gethostname() string lengths; about - 1/2 the cases were using it already. Fixes bz#2239 en passant - - djm@cvs.openbsd.org 2014/07/03 03:47:27 - [ssh-keygen.c] - When hashing or removing hosts using ssh-keygen, don't choke on - @revoked markers and don't remove @cert-authority markers; - bz#2241, reported by mlindgren AT runelind.net - - djm@cvs.openbsd.org 2014/07/03 04:36:45 - [digest.h] - forward-declare struct sshbuf so consumers don't need to include sshbuf.h - - djm@cvs.openbsd.org 2014/07/03 05:32:36 - [ssh_config.5] - mention '%%' escape sequence in HostName directives and how it may - be used to specify IPv6 link-local addresses - - djm@cvs.openbsd.org 2014/07/03 05:38:17 - [ssh.1] - document that -g will only work in the multiplexed case if applied to - the mux master - - djm@cvs.openbsd.org 2014/07/03 06:39:19 - [ssh.c ssh_config.5] - Add a %C escape sequence for LocalCommand and ControlPath that expands - to a unique identifer based on a has of the tuple of (local host, - remote user, hostname, port). - - Helps avoid exceeding sockaddr_un's miserly pathname limits for mux - control paths. - - bz#2220, based on patch from mancha1 AT zoho.com; ok markus@ - - jmc@cvs.openbsd.org 2014/07/03 07:45:27 - [ssh_config.5] - escape %C since groff thinks it part of an Rs/Re block; - - djm@cvs.openbsd.org 2014/07/03 11:16:55 - [auth.c auth.h auth1.c auth2.c] - make the "Too many authentication failures" message include the - user, source address, port and protocol in a format similar to the - authentication success / failure messages; bz#2199, ok dtucker +commit 2fab9b0f8720baf990c931e3f68babb0bf9949c6 +Author: Damien Miller +Date: Wed Mar 4 07:41:27 2015 +1100 -20140702 - - OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2014/06/13 08:26:29 - [sandbox-systrace.c] - permit SYS_getentropy - from matthew - - matthew@cvs.openbsd.org 2014/06/18 02:59:13 - [sandbox-systrace.c] - Now that we have a dedicated getentropy(2) system call for - arc4random(3), we can disallow __sysctl(2) in OpenSSH's systrace - sandbox. - - ok djm - - naddy@cvs.openbsd.org 2014/06/18 15:42:09 - [sshbuf-getput-crypto.c] - The ssh_get_bignum functions must accept the same range of bignums - the corresponding ssh_put_bignum functions create. This fixes the - use of 16384-bit RSA keys (bug reported by Eivind Evensen). - ok djm@ - - djm@cvs.openbsd.org 2014/06/24 00:52:02 - [krl.c] - fix bug in KRL generation: multiple consecutive revoked certificate - serial number ranges could be serialised to an invalid format. - - Readers of a broken KRL caused by this bug will fail closed, so no - should-have-been-revoked key will be accepted. - - djm@cvs.openbsd.org 2014/06/24 01:13:21 - [Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c - [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c - [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h - [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h - [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h - [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c - [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c - [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c - [sshconnect2.c sshd.c sshkey.c sshkey.h - [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h] - New key API: refactor key-related functions to be more library-like, - existing API is offered as a set of wrappers. - - with and ok markus@ - - Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew - Dempsky and Ron Bowes for a detailed review a few months ago. - NB. This commit also removes portable OpenSSH support for OpenSSL - <0.9.8e. - - djm@cvs.openbsd.org 2014/06/24 02:19:48 - [ssh.c] - don't fatal() when hostname canonicalisation fails with a - ProxyCommand in use; continue and allow the ProxyCommand to - connect anyway (e.g. to a host with a name outside the DNS - behind a bastion) - - djm@cvs.openbsd.org 2014/06/24 02:21:01 - [scp.c] - when copying local->remote fails during read, don't send uninitialised - heap to the remote end. Reported by Jann Horn - - deraadt@cvs.openbsd.org 2014/06/25 14:16:09 - [sshbuf.c] - unblock SIGSEGV before raising it - ok djm - - markus@cvs.openbsd.org 2014/06/27 16:41:56 - [channels.c channels.h clientloop.c ssh.c] - fix remote fwding with same listen port but different listen address - with gerhard@, ok djm@ - - markus@cvs.openbsd.org 2014/06/27 18:50:39 - [ssh-add.c] - fix loading of private keys - - djm@cvs.openbsd.org 2014/06/30 12:54:39 - [key.c] - suppress spurious error message when loading key with a passphrase; - reported by kettenis@ ok markus@ - - djm@cvs.openbsd.org 2014/07/02 04:59:06 - [cipher-3des1.c] - fix ssh protocol 1 on the server that regressed with the sshkey change - (sometimes fatal() after auth completed), make file return useful status - codes. - NB. Id sync only for these two. They were bundled into the sshkey merge - above, since it was easier to sync the entire file and then apply - portable-specific changed atop it. - - djm@cvs.openbsd.org 2014/04/30 05:32:00 - [regress/Makefile] - unit tests for new buffer API; including basic fuzz testing - NB. Id sync only. - - djm@cvs.openbsd.org 2014/05/21 07:04:21 - [regress/integrity.sh] - when failing because of unexpected output, show the offending output - - djm@cvs.openbsd.org 2014/06/24 01:04:43 - [regress/krl.sh] - regress test for broken consecutive revoked serial number ranges - - djm@cvs.openbsd.org 2014/06/24 01:14:17 - [Makefile.in regress/Makefile regress/unittests/Makefile] - [regress/unittests/sshkey/Makefile] - [regress/unittests/sshkey/common.c] - [regress/unittests/sshkey/common.h] - [regress/unittests/sshkey/mktestdata.sh] - [regress/unittests/sshkey/test_file.c] - [regress/unittests/sshkey/test_fuzz.c] - [regress/unittests/sshkey/test_sshkey.c] - [regress/unittests/sshkey/tests.c] - [regress/unittests/sshkey/testdata/dsa_1] - [regress/unittests/sshkey/testdata/dsa_1-cert.fp] - [regress/unittests/sshkey/testdata/dsa_1-cert.pub] - [regress/unittests/sshkey/testdata/dsa_1.fp] - [regress/unittests/sshkey/testdata/dsa_1.fp.bb] - [regress/unittests/sshkey/testdata/dsa_1.param.g] - [regress/unittests/sshkey/testdata/dsa_1.param.priv] - [regress/unittests/sshkey/testdata/dsa_1.param.pub] - [regress/unittests/sshkey/testdata/dsa_1.pub] - [regress/unittests/sshkey/testdata/dsa_1_pw] - [regress/unittests/sshkey/testdata/dsa_2] - [regress/unittests/sshkey/testdata/dsa_2.fp] - [regress/unittests/sshkey/testdata/dsa_2.fp.bb] - [regress/unittests/sshkey/testdata/dsa_2.pub] - [regress/unittests/sshkey/testdata/dsa_n] - [regress/unittests/sshkey/testdata/dsa_n_pw] - [regress/unittests/sshkey/testdata/ecdsa_1] - [regress/unittests/sshkey/testdata/ecdsa_1-cert.fp] - [regress/unittests/sshkey/testdata/ecdsa_1-cert.pub] - [regress/unittests/sshkey/testdata/ecdsa_1.fp] - [regress/unittests/sshkey/testdata/ecdsa_1.fp.bb] - [regress/unittests/sshkey/testdata/ecdsa_1.param.curve] - [regress/unittests/sshkey/testdata/ecdsa_1.param.priv] - [regress/unittests/sshkey/testdata/ecdsa_1.param.pub] - [regress/unittests/sshkey/testdata/ecdsa_1.pub] - [regress/unittests/sshkey/testdata/ecdsa_1_pw] - [regress/unittests/sshkey/testdata/ecdsa_2] - [regress/unittests/sshkey/testdata/ecdsa_2.fp] - [regress/unittests/sshkey/testdata/ecdsa_2.fp.bb] - [regress/unittests/sshkey/testdata/ecdsa_2.param.curve] - [regress/unittests/sshkey/testdata/ecdsa_2.param.priv] - [regress/unittests/sshkey/testdata/ecdsa_2.param.pub] - [regress/unittests/sshkey/testdata/ecdsa_2.pub] - [regress/unittests/sshkey/testdata/ecdsa_n] - [regress/unittests/sshkey/testdata/ecdsa_n_pw] - [regress/unittests/sshkey/testdata/ed25519_1] - [regress/unittests/sshkey/testdata/ed25519_1-cert.fp] - [regress/unittests/sshkey/testdata/ed25519_1-cert.pub] - [regress/unittests/sshkey/testdata/ed25519_1.fp] - [regress/unittests/sshkey/testdata/ed25519_1.fp.bb] - [regress/unittests/sshkey/testdata/ed25519_1.pub] - [regress/unittests/sshkey/testdata/ed25519_1_pw] - [regress/unittests/sshkey/testdata/ed25519_2] - [regress/unittests/sshkey/testdata/ed25519_2.fp] - [regress/unittests/sshkey/testdata/ed25519_2.fp.bb] - [regress/unittests/sshkey/testdata/ed25519_2.pub] - [regress/unittests/sshkey/testdata/pw] - [regress/unittests/sshkey/testdata/rsa1_1] - [regress/unittests/sshkey/testdata/rsa1_1.fp] - [regress/unittests/sshkey/testdata/rsa1_1.fp.bb] - [regress/unittests/sshkey/testdata/rsa1_1.param.n] - [regress/unittests/sshkey/testdata/rsa1_1.pub] - [regress/unittests/sshkey/testdata/rsa1_1_pw] - [regress/unittests/sshkey/testdata/rsa1_2] - [regress/unittests/sshkey/testdata/rsa1_2.fp] - [regress/unittests/sshkey/testdata/rsa1_2.fp.bb] - [regress/unittests/sshkey/testdata/rsa1_2.param.n] - [regress/unittests/sshkey/testdata/rsa1_2.pub] - [regress/unittests/sshkey/testdata/rsa_1] - [regress/unittests/sshkey/testdata/rsa_1-cert.fp] - [regress/unittests/sshkey/testdata/rsa_1-cert.pub] - [regress/unittests/sshkey/testdata/rsa_1.fp] - [regress/unittests/sshkey/testdata/rsa_1.fp.bb] - [regress/unittests/sshkey/testdata/rsa_1.param.n] - [regress/unittests/sshkey/testdata/rsa_1.param.p] - [regress/unittests/sshkey/testdata/rsa_1.param.q] - [regress/unittests/sshkey/testdata/rsa_1.pub] - [regress/unittests/sshkey/testdata/rsa_1_pw] - [regress/unittests/sshkey/testdata/rsa_2] - [regress/unittests/sshkey/testdata/rsa_2.fp] - [regress/unittests/sshkey/testdata/rsa_2.fp.bb] - [regress/unittests/sshkey/testdata/rsa_2.param.n] - [regress/unittests/sshkey/testdata/rsa_2.param.p] - [regress/unittests/sshkey/testdata/rsa_2.param.q] - [regress/unittests/sshkey/testdata/rsa_2.pub] - [regress/unittests/sshkey/testdata/rsa_n] - [regress/unittests/sshkey/testdata/rsa_n_pw] - unit and fuzz tests for new key API - - (djm) [sshkey.c] Conditionalise inclusion of util.h - - (djm) [regress/Makefile] fix execution of sshkey unit/fuzz test + avoid warning -20140618 - - (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare +commit d1bc844322461f882b4fd2277ba9a8d4966573d2 +Author: Damien Miller +Date: Wed Mar 4 06:31:45 2015 +1100 -20140617 - - (dtucker) [entropy.c openbsd-compat/openssl-compat.{c,h} - openbsd-compat/regress/{.cvsignore,Makefile.in,opensslvertest.c}] - Move the OpenSSL header/library version test into its own function and add - tests for it. Fix it to allow fix version upgrades (but not downgrades). - Prompted by chl@ via OpenSMTPD (issue #462) and Debian (bug #748150). - ok djm@ chl@ + Revert "define __unused to nothing if not already defined" + + This reverts commit 1598419e38afbaa8aa5df8dd6b0af98301e2c908. + + Some system headers have objects named __unused -20140616 - - (dtucker) [defines.h] Fix undef of _PATH_MAILDIR. From rak at debian via - OpenSMTPD and chl@ +commit 00797e86b2d98334d1bb808f65fa1fd47f328ff1 +Author: Damien Miller +Date: Wed Mar 4 05:02:45 2015 +1100 -20140612 - - (dtucker) [configure.ac] Remove tcpwrappers support, support has already - been removed from sshd.c. + check for crypt and DES_crypt in openssl block + + fixes builds on systems that use DES_crypt; based on patch + from Roumen Petrov -20140611 - - (dtucker) [defines.h] Add va_copy if we don't already have it, taken from - openbsd-compat/bsd-asprintf.c. - - (dtucker) [regress/unittests/sshbuf/*.c regress/unittests/test_helper/*] - Wrap stdlib.h include an ifdef for platforms that don't have it. - - (tim) [regress/unittests/test_helper/test_helper.h] Add includes.h for - u_intXX_t types. +commit 1598419e38afbaa8aa5df8dd6b0af98301e2c908 +Author: Damien Miller +Date: Wed Mar 4 04:59:13 2015 +1100 -20140610 - - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c - regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] Only do NISTP256 - curve tests if OpenSSL has them. - - (dtucker) [myprosal.h] Don't include curve25519-sha256@libssh.org in - the proposal if the version of OpenSSL we're using doesn't support ECC. - - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] ifdef - ECC variable too. - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/06/05 22:17:50 - [sshconnect2.c] - fix inverted test that caused PKCS#11 keys that were explicitly listed - not to be preferred. Reported by Dirk-Willem van Gulik - - dtucker@cvs.openbsd.org 2014/06/10 21:46:11 - [sshbuf.h] - Group ECC functions together to make things a little easier in -portable. - "doesn't bother me" deraadt@ - - (dtucker) [sshbuf.h] Only declare ECC functions if building without - OpenSSL or if OpenSSL has ECC. - - (dtucker) [openbsd-compat/arc4random.c] Use explicit_bzero instead of an - assigment that might get optimized out. ok djm@ - - (dtucker) [bufaux.c bufbn.c bufec.c buffer.c] Pull in includes.h for - compat stuff, specifically whether or not OpenSSL has ECC. + define __unused to nothing if not already defined + + fixes builds on BSD/OS -20140527 - - (djm) [cipher.c] Fix merge botch. - - (djm) [contrib/cygwin/ssh-host-config] Updated Cygwin ssh-host-config - from Corinna Vinschen, fixing a number of bugs and preparing for - Cygwin 1.7.30. - - (djm) [configure.ac openbsd-compat/bsd-cygwin_util.c] - [openbsd-compat/bsd-cygwin_util.h] On Cygwin, determine privilege - separation user at runtime, since it may need to be a domain account. - Patch from Corinna Vinschen. +commit d608a51daad4f14ad6ab43d7cf74ef4801cc3fe9 +Author: djm@openbsd.org +Date: Tue Mar 3 17:53:40 2015 +0000 -20140522 - - (djm) [Makefile.in] typo in path + upstream commit + + reorder logic for better portability; patch from Roumen + Petrov -20140521 - - (djm) [commit configure.ac defines.h sshpty.c] don't attempt to use - vhangup on Linux. It doens't work for non-root users, and for them - it just messes up the tty settings. - - (djm) [misc.c] Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC - when it is available. It takes into account time spent suspended, - thereby ensuring timeouts (e.g. for expiring agent keys) fire - correctly. bz#2228 reported by John Haxby +commit 68d2dfc464fbcdf8d6387884260f9801f4352393 +Author: djm@openbsd.org +Date: Tue Mar 3 06:48:58 2015 +0000 -20140519 - - (djm) [rijndael.c rijndael.h] Sync with newly-ressurected versions ine - OpenBSD - - OpenBSD CVS Sync - - logan@cvs.openbsd.org 2014/04/20 09:24:26 - [dns.c dns.h ssh-keygen.c] - Add support for SSHFP DNS records for ED25519 key types. - OK from djm@ - - logan@cvs.openbsd.org 2014/04/21 14:36:16 - [sftp-client.c sftp-client.h sftp.c] - Implement sftp upload resume support. - OK from djm@, with input from guenther@, mlarkin@ and - okan@ - - logan@cvs.openbsd.org 2014/04/22 10:07:12 - [sftp.c] - Sort the sftp command list. - OK from djm@ - - logan@cvs.openbsd.org 2014/04/22 12:42:04 - [sftp.1] - Document sftp upload resume. - OK from djm@, with feedback from okan@. - - jmc@cvs.openbsd.org 2014/04/22 14:16:30 - [sftp.1] - zap eol whitespace; - - djm@cvs.openbsd.org 2014/04/23 12:42:34 - [readconf.c] - don't record duplicate IdentityFiles - - djm@cvs.openbsd.org 2014/04/28 03:09:18 - [authfile.c bufaux.c buffer.h channels.c krl.c mux.c packet.c packet.h] - [ssh-keygen.c] - buffer_get_string_ptr's return should be const to remind - callers that futzing with it will futz with the actual buffer - contents - - djm@cvs.openbsd.org 2014/04/29 13:10:30 - [clientloop.c serverloop.c] - bz#1818 - don't send channel success/failre replies on channels that - have sent a close already; analysis and patch from Simon Tatham; - ok markus@ - - markus@cvs.openbsd.org 2014/04/29 18:01:49 - [auth.c authfd.c authfile.c bufaux.c cipher.c cipher.h hostfile.c] - [kex.c key.c mac.c monitor.c monitor_wrap.c myproposal.h packet.c] - [roaming_client.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c] - [ssh-pkcs11.h ssh.c sshconnect.c sshconnect2.c sshd.c] - make compiling against OpenSSL optional (make OPENSSL=no); - reduces algorithms to curve25519, aes-ctr, chacha, ed25519; - allows us to explore further options; with and ok djm - - dtucker@cvs.openbsd.org 2014/04/29 19:58:50 - [sftp.c] - Move nulling of variable next to where it's freed. ok markus@ - - dtucker@cvs.openbsd.org 2014/04/29 20:36:51 - [sftp.c] - Don't attempt to append a nul quote char to the filename. Should prevent - fatal'ing with "el_insertstr failed" when there's a single quote char - somewhere in the string. bz#2238, ok markus@ - - djm@cvs.openbsd.org 2014/04/30 05:29:56 - [bufaux.c bufbn.c bufec.c buffer.c buffer.h sshbuf-getput-basic.c] - [sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c sshbuf.h ssherr.c] - [ssherr.h] - New buffer API; the first installment of the conversion/replacement - of OpenSSH's internals to make them usable as a standalone library. - - This includes a set of wrappers to make it compatible with the - existing buffer API so replacement can occur incrementally. - - With and ok markus@ - - Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew - Dempsky and Ron Bowes for a detailed review. - - naddy@cvs.openbsd.org 2014/04/30 19:07:48 - [mac.c myproposal.h umac.c] - UMAC can use our local fallback implementation of AES when OpenSSL isn't - available. Glue code straight from Ted Krovetz's original umac.c. - ok markus@ - - djm@cvs.openbsd.org 2014/05/02 03:27:54 - [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c] - [misc.h poly1305.h ssh-pkcs11.c defines.h] - revert __bounded change; it causes way more problems for portable than - it solves; pointed out by dtucker@ - - markus@cvs.openbsd.org 2014/05/03 17:20:34 - [monitor.c packet.c packet.h] - unbreak compression, by re-init-ing the compression code in the - post-auth child. the new buffer code is more strict, and requires - buffer_init() while the old code was happy after a bzero(); - originally from djm@ - - logan@cvs.openbsd.org 2014/05/05 07:02:30 - [sftp.c] - Zap extra whitespace. - - OK from djm@ and dtucker@ - - (djm) [configure.ac] Unconditionally define WITH_OPENSSL until we write - portability glue to support building without libcrypto - - (djm) [Makefile.in configure.ac sshbuf-getput-basic.c] - [sshbuf-getput-crypto.c sshbuf.c] compilation and portability fixes - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/03/13 20:44:49 - [login-timeout.sh] - this test is a sorry mess of race conditions; add another sleep - to avoid a failure on slow machines (at least until I find a - better way) - - djm@cvs.openbsd.org 2014/04/21 22:15:37 - [dhgex.sh integrity.sh kextype.sh rekey.sh try-ciphers.sh] - repair regress tests broken by server-side default cipher/kex/mac changes - by ensuring that the option under test is included in the server's - algorithm list - - dtucker@cvs.openbsd.org 2014/05/03 18:46:14 - [proxy-connect.sh] - Add tests for with and without compression, with and without privsep. - - logan@cvs.openbsd.org 2014/05/04 10:40:59 - [connect-privsep.sh] - Remove the Z flag from the list of malloc options as it - was removed from malloc.c 10 days ago. - - OK from miod@ - - (djm) [regress/unittests/Makefile] - [regress/unittests/Makefile.inc] - [regress/unittests/sshbuf/Makefile] - [regress/unittests/sshbuf/test_sshbuf.c] - [regress/unittests/sshbuf/test_sshbuf_fixed.c] - [regress/unittests/sshbuf/test_sshbuf_fuzz.c] - [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] - [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] - [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] - [regress/unittests/sshbuf/test_sshbuf_misc.c] - [regress/unittests/sshbuf/tests.c] - [regress/unittests/test_helper/Makefile] - [regress/unittests/test_helper/fuzz.c] - [regress/unittests/test_helper/test_helper.c] - [regress/unittests/test_helper/test_helper.h] - Import new unit tests from OpenBSD; not yet hooked up to build. - - (djm) [regress/Makefile Makefile.in] - [regress/unittests/sshbuf/test_sshbuf.c - [regress/unittests/sshbuf/test_sshbuf_fixed.c] - [regress/unittests/sshbuf/test_sshbuf_fuzz.c] - [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] - [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] - [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] - [regress/unittests/sshbuf/test_sshbuf_misc.c] - [regress/unittests/sshbuf/tests.c] - [regress/unittests/test_helper/fuzz.c] - [regress/unittests/test_helper/test_helper.c] - Hook new unit tests into the build and "make tests" - - (djm) [sshbuf.c] need __predict_false - -20140430 - - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already - have it. Only attempt to use __attribute__(__bounded__) for gcc. - -20140420 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/03/03 22:22:30 - [session.c] - ignore enviornment variables with embedded '=' or '\0' characters; - spotted by Jann Horn; ok deraadt@ - Id sync only - portable already has this. - - djm@cvs.openbsd.org 2014/03/12 04:44:58 - [ssh-keyscan.c] - scan for Ed25519 keys by default too - - djm@cvs.openbsd.org 2014/03/12 04:50:32 - [auth-bsdauth.c ssh-keygen.c] - don't count on things that accept arguments by reference to clear - things for us on error; most things do, but it's unsafe form. - - djm@cvs.openbsd.org 2014/03/12 04:51:12 - [authfile.c] - correct test that kdf name is not "none" or "bcrypt" - - naddy@cvs.openbsd.org 2014/03/12 13:06:59 - [ssh-keyscan.1] - scan for Ed25519 keys by default too - - deraadt@cvs.openbsd.org 2014/03/15 17:28:26 - [ssh-agent.c ssh-keygen.1 ssh-keygen.c] - Improve usage() and documentation towards the standard form. - In particular, this line saves a lot of man page reading time. - usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] - [-N new_passphrase] [-C comment] [-f output_keyfile] - ok schwarze jmc - - tedu@cvs.openbsd.org 2014/03/17 19:44:10 - [ssh.1] - old descriptions of des and blowfish are old. maybe ok deraadt - - tedu@cvs.openbsd.org 2014/03/19 14:42:44 - [scp.1] - there is no need for rcp anymore - ok deraadt millert - - markus@cvs.openbsd.org 2014/03/25 09:40:03 - [myproposal.h] - trimm default proposals. - - This commit removes the weaker pre-SHA2 hashes, the broken ciphers - (arcfour), and the broken modes (CBC) from the default configuration - (the patch only changes the default, all the modes are still available - for the config files). - - ok djm@, reminded by tedu@ & naddy@ and discussed with many - - deraadt@cvs.openbsd.org 2014/03/26 17:16:26 - [myproposal.h] - The current sharing of myproposal[] between both client and server code - makes the previous diff highly unpallatable. We want to go in that - direction for the server, but not for the client. Sigh. - Brought up by naddy. - - markus@cvs.openbsd.org 2014/03/27 23:01:27 - [myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] - disable weak proposals in sshd, but keep them in ssh; ok djm@ - - djm@cvs.openbsd.org 2014/03/26 04:55:35 - [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c - [misc.h poly1305.h ssh-pkcs11.c] - use __bounded(...) attribute recently added to sys/cdefs.h instead of - longform __attribute__(__bounded(...)); - - for brevity and a warning free compilation with llvm/clang - - tedu@cvs.openbsd.org 2014/03/26 19:58:37 - [sshd.8 sshd.c] - remove libwrap support. ok deraadt djm mfriedl - - naddy@cvs.openbsd.org 2014/03/28 05:17:11 - [ssh_config.5 sshd_config.5] - sync available and default algorithms, improve algorithm list formatting - help from jmc@ and schwarze@, ok deraadt@ - - jmc@cvs.openbsd.org 2014/03/31 13:39:34 - [ssh-keygen.1] - the text for the -K option was inserted in the wrong place in -r1.108; - fix From: Matthew Clarke - - djm@cvs.openbsd.org 2014/04/01 02:05:27 - [ssh-keysign.c] - include fingerprint of key not found - use arc4random_buf() instead of loop+arc4random() - - djm@cvs.openbsd.org 2014/04/01 03:34:10 - [sshconnect.c] - When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any - certificate keys to plain keys and attempt SSHFP resolution. - - Prevents a server from skipping SSHFP lookup and forcing a new-hostkey - dialog by offering only certificate keys. - - Reported by mcv21 AT cam.ac.uk - - djm@cvs.openbsd.org 2014/04/01 05:32:57 - [packet.c] - demote a debug3 to PACKET_DEBUG; ok markus@ - - djm@cvs.openbsd.org 2014/04/12 04:55:53 - [sshd.c] - avoid crash at exit: check that pmonitor!=NULL before dereferencing; - bz#2225, patch from kavi AT juniper.net - - djm@cvs.openbsd.org 2014/04/16 23:22:45 - [bufaux.c] - skip leading zero bytes in buffer_put_bignum2_from_string(); - reported by jan AT mojzis.com; ok markus@ - - djm@cvs.openbsd.org 2014/04/16 23:28:12 - [ssh-agent.1] - remove the identity files from this manpage - ssh-agent doesn't deal - with them at all and the same information is duplicated in ssh-add.1 - (which does deal with them); prodded by deraadt@ - - djm@cvs.openbsd.org 2014/04/18 23:52:25 - [compat.c compat.h sshconnect2.c sshd.c version.h] - OpenSSH 6.5 and 6.6 have a bug that causes ~0.2% of connections - using the curve25519-sha256@libssh.org KEX exchange method to fail - when connecting with something that implements the spec properly. - - Disable this KEX method when speaking to one of the affected - versions. - - reported by Aris Adamantiadis; ok markus@ - - djm@cvs.openbsd.org 2014/04/19 05:54:59 - [compat.c] - missing wildcard; pointed out by naddy@ - - tedu@cvs.openbsd.org 2014/04/19 14:53:48 - [ssh-keysign.c sshd.c] - Delete futile calls to RAND_seed. ok djm - NB. Id sync only. This only applies to OpenBSD's libcrypto slashathon - - tedu@cvs.openbsd.org 2014/04/19 18:15:16 - [sshd.8] - remove some really old rsh references - - tedu@cvs.openbsd.org 2014/04/19 18:42:19 - [ssh.1] - delete .xr to hosts.equiv. there's still an unfortunate amount of - documentation referring to rhosts equivalency in here. - - djm@cvs.openbsd.org 2014/04/20 02:30:25 - [misc.c misc.h umac.c] - use get/put_u32 to load values rather than *((UINT32 *)p) that breaks on - strict-alignment architectures; reported by and ok stsp@ - - djm@cvs.openbsd.org 2014/04/20 02:49:32 - [compat.c] - add a canonical 6.6 + curve25519 bignum fix fake version that I can - recommend people use ahead of the openssh-6.7 release - -20140401 - - (djm) On platforms that support it, use prctl() to prevent sftp-server - from accessing /proc/self/{mem,maps}; patch from jann AT thejh.net - - (djm) Use full release (e.g. 6.5p1) in debug output rather than just - version. From des@des.no - -20140317 - - (djm) [sandbox-seccomp-filter.c] Soft-fail stat() syscalls. Add XXX to - remind myself to add sandbox violation logging via the log socket. - -20140314 - - (tim) [opensshd.init.in] Add support for ed25519 - -20140313 - - (djm) Release OpenSSH 6.6 - -20140304 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/03/03 22:22:30 - [session.c] - ignore enviornment variables with embedded '=' or '\0' characters; - spotted by Jann Horn; ok deraadt@ - -20140301 - - (djm) [regress/Makefile] Disable dhgex regress test; it breaks when - no moduli file exists at the expected location. - -20140228 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/02/27 00:41:49 - [bufbn.c] - fix unsigned overflow that could lead to reading a short ssh protocol - 1 bignum value; found by Ben Hawkes; ok deraadt@ - - djm@cvs.openbsd.org 2014/02/27 08:25:09 - [bufbn.c] - off by one in range check - - djm@cvs.openbsd.org 2014/02/27 22:47:07 - [sshd_config.5] - bz#2184 clarify behaviour of a keyword that appears in multiple - matching Match blocks; ok dtucker@ - - djm@cvs.openbsd.org 2014/02/27 22:57:40 - [version.h] - openssh-6.6 - - dtucker@cvs.openbsd.org 2014/01/19 23:43:02 - [regress/sftp-chroot.sh] - Don't use -q on sftp as it suppresses logging, instead redirect the - output to the regress logfile. - - dtucker@cvs.openbsd.org 2014/01/20 00:00:30 - [sregress/ftp-chroot.sh] - append to rather than truncating the log file - - dtucker@cvs.openbsd.org 2014/01/25 04:35:32 - [regress/Makefile regress/dhgex.sh] - Add a test for DH GEX sizes - - djm@cvs.openbsd.org 2014/01/26 10:22:10 - [regress/cert-hostkey.sh] - automatically generate revoked keys from listed keys rather than - manually specifying each type; from portable - (Id sync only) - - djm@cvs.openbsd.org 2014/01/26 10:49:17 - [scp-ssh-wrapper.sh scp.sh] - make sure $SCP is tested on the remote end rather than whichever one - happens to be in $PATH; from portable - (Id sync only) - - djm@cvs.openbsd.org 2014/02/27 20:04:16 - [login-timeout.sh] - remove any existing LoginGraceTime from sshd_config before adding - a specific one for the test back in - - djm@cvs.openbsd.org 2014/02/27 21:21:25 - [agent-ptrace.sh agent.sh] - keep return values that are printed in error messages; - from portable - (Id sync only) - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank version numbers - - (djm) [regress/host-expand.sh] Add RCS Id - -20140227 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/02/26 20:18:37 - [ssh.c] - bz#2205: avoid early hostname lookups unless canonicalisation is enabled; - ok dtucker@ markus@ - - djm@cvs.openbsd.org 2014/02/26 20:28:44 - [auth2-gss.c gss-serv.c ssh-gss.h sshd.c] - bz#2107 - cache OIDs of supported GSSAPI mechanisms before privsep - sandboxing, as running this code in the sandbox can cause violations; - ok markus@ - - djm@cvs.openbsd.org 2014/02/26 20:29:29 - [channels.c] - don't assume that the socks4 username is \0 terminated; - spotted by Ben Hawkes; ok markus@ - - markus@cvs.openbsd.org 2014/02/26 21:53:37 - [sshd.c] - ssh_gssapi_prepare_supported_oids needs GSSAPI - -20140224 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/02/07 06:55:54 - [cipher.c mac.c] - remove some logging that makes ssh debugging output very verbose; - ok markus - - djm@cvs.openbsd.org 2014/02/15 23:05:36 - [channels.c] - avoid spurious "getsockname failed: Bad file descriptor" errors in ssh -W; - bz#2200, debian#738692 via Colin Watson; ok dtucker@ - - djm@cvs.openbsd.org 2014/02/22 01:32:19 - [readconf.c] - when processing Match blocks, skip 'exec' clauses if previous predicates - failed to match; ok markus@ - - djm@cvs.openbsd.org 2014/02/23 20:03:42 - [ssh-ed25519.c] - check for unsigned overflow; not reachable in OpenSSH but others might - copy our code... - - djm@cvs.openbsd.org 2014/02/23 20:11:36 - [readconf.c readconf.h ssh.c ssh_config.5] - reparse ssh_config and ~/.ssh/config if hostname canonicalisation changes - the hostname. This allows users to write configurations that always - refer to canonical hostnames, e.g. - - CanonicalizeHostname yes - CanonicalDomains int.example.org example.org - CanonicalizeFallbackLocal no - - Host *.int.example.org - Compression off - Host *.example.org - User djm - - ok markus@ - -20140213 - - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add compat - code for older OpenSSL versions that don't have EVP_MD_CTX_copy_ex. - -20140207 - - OpenBSD CVS Sync - - naddy@cvs.openbsd.org 2014/02/05 20:13:25 - [ssh-keygen.1 ssh-keygen.c] - tweak synopsis: calling ssh-keygen without any arguments is fine; ok jmc@ - while here, fix ordering in usage(); requested by jmc@ - - djm@cvs.openbsd.org 2014/02/06 22:21:01 - [sshconnect.c] - in ssh_create_socket(), only do the getaddrinfo for BindAddress when - BindAddress is actually specified. Fixes regression in 6.5 for - UsePrivilegedPort=yes; patch from Corinna Vinschen - -20140206 - - (dtucker) [openbsd-compat/bsd-poll.c] Don't bother checking for non-NULL - before freeing since free(NULL) is a no-op. ok djm. - - (djm) [sandbox-seccomp-filter.c] Not all Linux architectures define - __NR_shutdown; some go via the socketcall(2) multiplexer. - -20140205 - - (djm) [sandbox-capsicum.c] Don't fatal if Capsicum is offered by - headers/libc but not supported by the kernel. Patch from Loganaden - Velvindron @ AfriNIC - -20140204 - - OpenBSD CVS Sync - - markus@cvs.openbsd.org 2014/01/27 18:58:14 - [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h] - replace openssl HMAC with an implementation based on our ssh_digest_* - ok and feedback djm@ - - markus@cvs.openbsd.org 2014/01/27 19:18:54 - [auth-rsa.c cipher.c ssh-agent.c sshconnect1.c sshd.c] - replace openssl MD5 with our ssh_digest_*; ok djm@ - - markus@cvs.openbsd.org 2014/01/27 20:13:46 - [digest.c digest-openssl.c digest-libc.c Makefile.in] - rename digest.c to digest-openssl.c and add libc variant; ok djm@ - - jmc@cvs.openbsd.org 2014/01/28 14:13:39 - [ssh-keyscan.1] - kill some bad Pa; - From: Jan Stary - - djm@cvs.openbsd.org 2014/01/29 00:19:26 - [sshd.c] - use kill(0, ...) instead of killpg(0, ...); on most operating systems - they are equivalent, but SUSv2 describes the latter as having undefined - behaviour; from portable; ok dtucker - (Id sync only; change is already in portable) - - djm@cvs.openbsd.org 2014/01/29 06:18:35 - [Makefile.in auth.h auth2-jpake.c auth2.c jpake.c jpake.h monitor.c] - [monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h] - [schnorr.c schnorr.h servconf.c servconf.h ssh2.h sshconnect2.c] - remove experimental, never-enabled JPAKE code; ok markus@ - - jmc@cvs.openbsd.org 2014/01/29 14:04:51 - [sshd_config.5] - document kbdinteractiveauthentication; - requested From: Ross L Richardson - - dtucker/markus helped explain its workings; - - djm@cvs.openbsd.org 2014/01/30 22:26:14 - [sandbox-systrace.c] - allow shutdown(2) syscall in sandbox - it may be called by packet_close() - from portable - (Id sync only; change is already in portable) - - tedu@cvs.openbsd.org 2014/01/31 16:39:19 - [auth2-chall.c authfd.c authfile.c bufaux.c bufec.c canohost.c] - [channels.c cipher-chachapoly.c clientloop.c configure.ac hostfile.c] - [kexc25519.c krl.c monitor.c sandbox-systrace.c session.c] - [sftp-client.c ssh-keygen.c ssh.c sshconnect2.c sshd.c sshlogin.c] - [openbsd-compat/explicit_bzero.c openbsd-compat/openbsd-compat.h] - replace most bzero with explicit_bzero, except a few that cna be memset - ok djm dtucker - - djm@cvs.openbsd.org 2014/02/02 03:44:32 - [auth1.c auth2-chall.c auth2-passwd.c authfile.c bufaux.c bufbn.c] - [buffer.c cipher-3des1.c cipher.c clientloop.c gss-serv.c kex.c] - [kexdhc.c kexdhs.c kexecdhc.c kexgexc.c kexecdhs.c kexgexs.c key.c] - [monitor.c monitor_wrap.c packet.c readpass.c rsa.c serverloop.c] - [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c] - [ssh-keygen.c ssh-rsa.c sshconnect.c sshconnect1.c sshconnect2.c] - [sshd.c] - convert memset of potentially-private data to explicit_bzero() - - djm@cvs.openbsd.org 2014/02/03 23:28:00 - [ssh-ecdsa.c] - fix memory leak; ECDSA_SIG_new() allocates 'r' and 's' for us, unlike - DSA_SIG_new. Reported by Batz Spear; ok markus@ - - djm@cvs.openbsd.org 2014/02/02 03:44:31 - [digest-libc.c digest-openssl.c] - convert memset of potentially-private data to explicit_bzero() - - djm@cvs.openbsd.org 2014/02/04 00:24:29 - [ssh.c] - delay lowercasing of hostname until right before hostname - canonicalisation to unbreak case-sensitive matching of ssh_config; - reported by Ike Devolder; ok markus@ - - (djm) [openbsd-compat/Makefile.in] Add missing explicit_bzero.o - - (djm) [regress/setuid-allowed.c] Missing string.h for strerror() - -20140131 - - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2) - syscall from sandboxes; it may be called by packet_close. - - (dtucker) [readconf.c] Include for the hton macros. Fixes - build with HP-UX's compiler. Patch from Kevin Brott. - - (tim) [Makefile.in] build regress/setuid-allow. - -20140130 - - (djm) [configure.ac] Only check for width-specified integer types - in headers that actually exist. patch from Tom G. Christensen; - ok dtucker@ - - (djm) [configure.ac atomicio.c] Kludge around NetBSD offering - different symbols for 'read' when various compiler flags are - in use, causing atomicio.c comparisons against it to break and - read/write operations to hang; ok dtucker - - (djm) Release openssh-6.5p1 - -20140129 - - (djm) [configure.ac] Fix broken shell test '==' vs '='; patch from - Tom G. Christensen - -20140128 - - (djm) [configure.ac] Search for inet_ntop in libnsl and libresovl; - ok dtucker - - (djm) [sshd.c] Use kill(0, ...) instead of killpg(0, ...); the - latter being specified to have undefined behaviour in SUSv3; - ok dtucker - - (tim) [regress/agent.sh regress/agent-ptrace.sh] Assign $? to a variable - when used as an error message inside an if statement so we display the - correct into. agent.sh patch from Petr Lautrbach. - -20140127 - - (dtucker) [Makefile.in] Remove trailing backslash which some make - implementations (eg older Solaris) do not cope with. - -20140126 - - OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2014/01/25 10:12:50 - [cipher.c cipher.h kex.c kex.h kexgexc.c] - Add a special case for the DH group size for 3des-cbc, which has an - effective strength much lower than the key size. This causes problems - with some cryptlib implementations, which don't support group sizes larger - than 4k but also don't use the largest group size it does support as - specified in the RFC. Based on a patch from Petr Lautrbach at Redhat, - reduced by me with input from Markus. ok djm@ markus@ - - markus@cvs.openbsd.org 2014/01/25 20:35:37 - [kex.c] - dh_need needs to be set to max(seclen, blocksize, ivlen, mac_len) - ok dtucker@, noted by mancha - - (djm) [configure.ac sandbox-capsicum.c sandbox-rlimit.c] Disable - RLIMIT_NOFILE pseudo-sandbox on FreeBSD. In some configurations, - libc will attempt to open additional file descriptors for crypto - offload and crash if they cannot be opened. - - (djm) [configure.ac] correct AC_DEFINE for previous. - -20140125 - - (djm) [configure.ac] Fix detection of capsicum sandbox on FreeBSD - - (djm) [configure.ac] Do not attempt to use capsicum sandbox unless - sys/capability.h exists and cap_rights_limit is in libc. Fixes - build on FreeBSD9x which provides the header but not the libc - support. - - (djm) [configure.ac] autoconf sets finds to 'yes' not '1', so test - against the correct thing. - -20140124 - - (djm) [Makefile.in regress/scp-ssh-wrapper.sh regress/scp.sh] Make - the scp regress test actually test the built scp rather than the one - in $PATH. ok dtucker@ - -20140123 - - (tim) [session.c] Improve error reporting on set_id(). - - (dtucker) [configure.ac] NetBSD's (and FreeBSD's) strnvis is gratuitously - incompatible with OpenBSD's despite post-dating it by more than a decade. - Declare it as broken, and document FreeBSD's as the same. ok djm@ - -20140122 - - (djm) [openbsd-compat/setproctitle.c] Don't fail to compile if a - platform that is expected to use the reuse-argv style setproctitle - hack surprises us by providing a setproctitle in libc; ok dtucker - - (djm) [configure.ac] Unless specifically requested, only attempt - to build Position Independent Executables on gcc >= 4.x; ok dtucker - - (djm) [configure.ac aclocal.m4] More tests to detect fallout from - platform hardening options: include some long long int arithmatic - to detect missing support functions for -ftrapv in libgcc and - equivalents, actually test linking when -ftrapv is supplied and - set either both -pie/-fPIE or neither. feedback and ok dtucker@ - -20140121 - - (dtucker) [configure.ac] Make PIE a configure-time option which defaults - to on platforms where it's known to be reliably detected and off elsewhere. - Works around platforms such as FreeBSD 9.1 where it does not interop with - -ftrapv (it seems to work but fails when trying to link ssh). ok djm@ - - (dtucker) [aclocal.m4] Differentiate between compile-time and link-time - tests in the configure output. ok djm. - - (tim) [platform.c session.c] Fix bug affecting SVR5 platforms introduced - with sftp chroot support. Move set_id call after chroot. - - (djm) [aclocal.m4] Flesh out the code run in the OSSH_CHECK_CFLAG_COMPILE - and OSSH_CHECK_LDFLAG_LINK tests to give them a better chance of - detecting toolchain-related problems; ok dtucker - -20140120 - - (dtucker) [gss-serv-krb5.c] Fall back to krb5_cc_gen_new if the Kerberos - implementation does not have krb5_cc_new_unique, similar to what we do - in auth-krb5.c. - - (djm) [regress/cert-hostkey.sh] Fix regress failure on platforms that - skip one or more key types (e.g. RHEL/CentOS 6.5); ok dtucker@ - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/01/20 00:08:48 - [digest.c] - memleak; found by Loganaden Velvindron @ AfriNIC; ok markus@ - -20140119 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2014/01/17 06:23:24 - [sftp-server.c] - fix log message statvfs. ok djm - - dtucker@cvs.openbsd.org 2014/01/18 09:36:26 - [session.c] - explicitly define USE_PIPES to 1 to prevent redefinition warnings in - portable on platforms that use pipes for everything. From vinschen at - redhat. - - dtucker@cvs.openbsd.org 2014/01/19 04:17:29 - [canohost.c addrmatch.c] - Cast socklen_t when comparing to size_t and use socklen_t to iterate over - the ip options, both to prevent signed/unsigned comparison warnings. - Patch from vinschen at redhat via portable openssh, begrudging ok deraadt. - - djm@cvs.openbsd.org 2014/01/19 04:48:08 - [ssh_config.5] - fix inverted meaning of 'no' and 'yes' for CanonicalizeFallbackLocal - - dtucker@cvs.openbsd.org 2014/01/19 11:21:51 - [addrmatch.c] - Cast the sizeof to socklen_t so it'll work even if the supplied len is - negative. Suggested by and ok djm, ok deraadt. - -20140118 - - (dtucker) [uidswap.c] Prevent unused variable warnings on Cygwin. Patch - from vinschen at redhat.com - - (dtucker) [openbsd-compat/bsd-cygwin_util.h] Add missing function - declarations that stopped being included when we stopped including - from openbsd-compat/bsd-cygwin_util.h. Patch from vinschen at - redhat.com. - - (dtucker) [configure.ac] On Cygwin the getopt variables (like optargs, - optind) are defined in getopt.h already. Unfortunately they are defined as - "declspec(dllimport)" for historical reasons, because the GNU linker didn't - allow auto-import on PE/COFF targets way back when. The problem is the - dllexport attributes collide with the definitions in the various source - files in OpenSSH, which obviousy define the variables without - declspec(dllimport). The least intrusive way to get rid of these warnings - is to disable warnings for GCC compiler attributes when building on Cygwin. - Patch from vinschen at redhat.com. - - (dtucker) [sandbox-capsicum.c] Correct some error messages and make the - return value check for cap_enter() consistent with the other uses in - FreeBSD. From by Loganaden Velvindron @ AfriNIC via bz#2140. - -20140117 - - (dtucker) [aclocal.m4 configure.ac] Add some additional compiler/toolchain - hardening flags including -fstack-protector-strong. These default to on - if the toolchain supports them, but there is a configure-time knob - (--without-hardening) to disable them if necessary. ok djm@ - - (djm) [sftp-client.c] signed/unsigned comparison fix - - (dtucker) [loginrec.c] Cast to the types specfied in the format - specification to prevent warnings. - - (dtucker) [crypto_api.h] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. - - (dtucker) [poly1305.c] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. - - (dtucker) [blocks.c fe25519.c ge25519.c hash.c sc25519.c verify.c] Include - includes.h to pull in all of the compatibility stuff. - - (dtucker) [openbsd-compat/bcrypt_pbkdf.c] Wrap stdlib.h include inside - #ifdef HAVE_STDINT_H. - - (dtucker) [defines.h] Add typedefs for uintXX_t types for platforms that - don't have them. - - (dtucker) [configure.ac] Split AC_CHECK_FUNCS for OpenSSL functions into - separate lines and alphabetize for easier diffing of changes. - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/01/17 00:21:06 - [sftp-client.c] - signed/unsigned comparison warning fix; from portable (Id sync only) - - dtucker@cvs.openbsd.org 2014/01/17 05:26:41 - [digest.c] - remove unused includes. ok djm@ - - (djm) [Makefile.in configure.ac sandbox-capsicum.c sandbox-darwin.c] - [sandbox-null.c sandbox-rlimit.c sandbox-seccomp-filter.c] - [sandbox-systrace.c ssh-sandbox.h sshd.c] Support preauth sandboxing - using the Capsicum API introduced in FreeBSD 10. Patch by Dag-Erling - Smorgrav, updated by Loganaden Velvindron @ AfriNIC; ok dtucker@ - - (dtucker) [configure.ac digest.c openbsd-compat/openssl-compat.c - openbsd-compat/openssl-compat.h] Add compatibility layer for older - openssl versions. ok djm@ - - (dtucker) Fix typo in #ifndef. - - (dtucker) [configure.ac openbsd-compat/bsd-statvfs.c - openbsd-compat/bsd-statvfs.h] Implement enough of statvfs on top of statfs - to be useful (and for the regression tests to pass) on platforms that - have statfs and fstatfs. ok djm@ - - (dtucker) [openbsd-compat/bsd-statvfs.h] Only start including headers if we - need them to cut down on the name collisions. - - (dtucker) [configure.ac] Also look in inttypes.h for uintXX_t types. - - (dtucker) [configure.ac] Have --without-hardening not turn off - stack-protector since that has a separate flag that's been around a while. - - (dtucker) [readconf.c] Wrap paths.h inside an ifdef. Allows building on - Solaris. - - (dtucker) [defines.h] Move our definitions of uintXX_t types down to after - they're defined if we have to define them ourselves. Fixes builds on old - AIX. - -20140118 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/01/16 07:31:09 - [sftp-client.c] - needless and incorrect cast to size_t can break resumption of - large download; patch from tobias@ - - djm@cvs.openbsd.org 2014/01/16 07:32:00 - [version.h] - openssh-6.5 - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank RPM spec version numbers. - - (djm) [README] update release notes URL. - -20140112 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2014/01/10 05:59:19 - [sshd_config] - the /etc/ssh/ssh_host_ed25519_key is loaded by default too - - djm@cvs.openbsd.org 2014/01/12 08:13:13 - [bufaux.c buffer.h kex.c kex.h kexc25519.c kexc25519c.c kexc25519s.c] - [kexdhc.c kexdhs.c kexecdhc.c kexecdhs.c kexgexc.c kexgexs.c] - avoid use of OpenSSL BIGNUM type and functions for KEX with - Curve25519 by adding a buffer_put_bignum2_from_string() that stores - a string using the bignum encoding rules. Will make it easier to - build a reduced-feature OpenSSH without OpenSSL in the future; - ok markus@ - -20140110 - - (djm) OpenBSD CVS Sync - - tedu@cvs.openbsd.org 2014/01/04 17:50:55 - [mac.c monitor_mm.c monitor_mm.h xmalloc.c] - use standard types and formats for size_t like variables. ok dtucker - - guenther@cvs.openbsd.org 2014/01/09 03:26:00 - [sftp-common.c] - When formating the time for "ls -l"-style output, show dates in the future - with the year, and rearrange a comparison to avoid a potentional signed - arithmetic overflow that would give the wrong result. - ok djm@ - - djm@cvs.openbsd.org 2014/01/09 23:20:00 - [digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c] - [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c] - [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c] - [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c] - Introduce digest API and use it to perform all hashing operations - rather than calling OpenSSL EVP_Digest* directly. Will make it easier - to build a reduced-feature OpenSSH without OpenSSL in future; - feedback, ok markus@ - - djm@cvs.openbsd.org 2014/01/09 23:26:48 - [sshconnect.c sshd.c] - ban clients/servers that suffer from SSH_BUG_DERIVEKEY, they are ancient, - deranged and might make some attacks on KEX easier; ok markus@ - -20140108 - - (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@ - -20131231 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/12/30 23:52:28 - [auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c] - [sshconnect.c sshconnect2.c sshd.c] - refuse RSA keys from old proprietary clients/servers that use the - obsolete RSA+MD5 signature scheme. it will still be possible to connect - with these clients/servers but only DSA keys will be accepted, and we'll - deprecate them entirely in a future release. ok markus@ - -20131229 - - (djm) [loginrec.c] Check for username truncation when looking up lastlog - entries - - (djm) [regress/Makefile] Add some generated files for cleaning - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/12/19 00:10:30 - [ssh-add.c] - skip requesting smartcard PIN when removing keys from agent; bz#2187 - patch from jay AT slushpupie.com; ok dtucker - - dtucker@cvs.openbsd.org 2013/12/19 00:19:12 - [serverloop.c] - Cast client_alive_interval to u_int64_t before assinging to - max_time_milliseconds to avoid potential integer overflow in the timeout. - bz#2170, patch from Loganaden Velvindron, ok djm@ - - djm@cvs.openbsd.org 2013/12/19 00:27:57 - [auth-options.c] - simplify freeing of source-address certificate restriction - - djm@cvs.openbsd.org 2013/12/19 01:04:36 - [channels.c] - bz#2147: fix multiple remote forwardings with dynamically assigned - listen ports. In the s->c message to open the channel we were sending - zero (the magic number to request a dynamic port) instead of the actual - listen port. The client therefore had no way of discriminating between - them. - - Diagnosis and fix by ronf AT timeheart.net - - djm@cvs.openbsd.org 2013/12/19 01:19:41 - [ssh-agent.c] - bz#2186: don't crash (NULL deref) when deleting PKCS#11 keys from an agent - that has a mix of normal and PKCS#11 keys; fix from jay AT slushpupie.com; - ok dtucker - - djm@cvs.openbsd.org 2013/12/19 22:57:13 - [poly1305.c poly1305.h] - use full name for author, with his permission - - tedu@cvs.openbsd.org 2013/12/21 07:10:47 - [ssh-keygen.1] - small typo - - djm@cvs.openbsd.org 2013/12/27 22:30:17 - [ssh-dss.c ssh-ecdsa.c ssh-rsa.c] - make the original RSA and DSA signing/verification code look more like - the ECDSA/Ed25519 ones: use key_type_plain() when checking the key type - rather than tediously listing all variants, use __func__ for debug/ - error messages - - djm@cvs.openbsd.org 2013/12/27 22:37:18 - [ssh-rsa.c] - correct comment - - djm@cvs.openbsd.org 2013/12/29 02:28:10 - [key.c] - allow ed25519 keys to appear as certificate authorities - - djm@cvs.openbsd.org 2013/12/29 02:37:04 - [key.c] - correct comment for key_to_certified() - - djm@cvs.openbsd.org 2013/12/29 02:49:52 - [key.c] - correct comment for key_drop_cert() - - djm@cvs.openbsd.org 2013/12/29 04:20:04 - [key.c] - to make sure we don't omit any key types as valid CA keys again, - factor the valid key type check into a key_type_is_valid_ca() - function - - djm@cvs.openbsd.org 2013/12/29 04:29:25 - [authfd.c] - allow deletion of ed25519 keys from the agent - - djm@cvs.openbsd.org 2013/12/29 04:35:50 - [authfile.c] - don't refuse to load Ed25519 certificates - - djm@cvs.openbsd.org 2013/12/29 05:42:16 - [ssh.c] - don't forget to load Ed25519 certs too - - djm@cvs.openbsd.org 2013/12/29 05:57:02 - [sshconnect.c] - when showing other hostkeys, don't forget Ed25519 keys - -20131221 - - (dtucker) [regress/keytype.sh] Actually test ecdsa key types. - -20131219 - - (dtucker) [configure.ac] bz#2178: Don't try to use BSM on Solaris versions - greater than 11 either rather than just 11. Patch from Tomas Kuthan. - - (dtucker) [auth-pam.c] bz#2163: check return value from pam_get_item(). - Patch from Loganaden Velvindron. - -20131218 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/12/07 08:08:26 - [ssh-keygen.1] - document -a and -o wrt new key format - - naddy@cvs.openbsd.org 2013/12/07 11:58:46 - [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8 ssh.1] - [ssh_config.5 sshd.8 sshd_config.5] - add missing mentions of ed25519; ok djm@ - - dtucker@cvs.openbsd.org 2013/12/08 09:53:27 - [sshd_config.5] - Use a literal for the default value of KEXAlgorithms. ok deraadt jmc - - markus@cvs.openbsd.org 2013/12/09 11:03:45 - [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] - [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] - Add Authors for the public domain ed25519/nacl code. - see also http://nacl.cr.yp.to/features.html - All of the NaCl software is in the public domain. - and http://ed25519.cr.yp.to/software.html - The Ed25519 software is in the public domain. - - markus@cvs.openbsd.org 2013/12/09 11:08:17 - [crypto_api.h] - remove unused defines - - pascal@cvs.openbsd.org 2013/12/15 18:17:26 - [ssh-add.c] - Make ssh-add also add .ssh/id_ed25519; fixes lie in manual page. - ok markus@ - - djm@cvs.openbsd.org 2013/12/15 21:42:35 - [cipher-chachapoly.c] - add some comments and constify a constant - - markus@cvs.openbsd.org 2013/12/17 10:36:38 - [crypto_api.h] - I've assempled the header file by cut&pasting from generated headers - and the source files. - -20131208 - - (djm) [openbsd-compat/bsd-setres_id.c] Missing header; from Corinna - Vinschen - - (djm) [Makefile.in regress/Makefile regress/agent-ptrace.sh] - [regress/setuid-allowed.c] Check that ssh-agent is not on a no-setuid - filesystem before running agent-ptrace.sh; ok dtucker - -20131207 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/12/05 22:59:45 - [sftp-client.c] - fix memory leak in error path in do_readdir(); pointed out by - Loganaden Velvindron @ AfriNIC in bz#2163 - - djm@cvs.openbsd.org 2013/12/06 03:40:51 - [ssh-keygen.c] - remove duplicated character ('g') in getopt() string; - document the (few) remaining option characters so we don't have to - rummage next time. - - markus@cvs.openbsd.org 2013/12/06 13:30:08 - [authfd.c key.c key.h ssh-agent.c] - move private key (de)serialization to key.c; ok djm - - markus@cvs.openbsd.org 2013/12/06 13:34:54 - [authfile.c authfile.h cipher.c cipher.h key.c packet.c ssh-agent.c] - [ssh-keygen.c PROTOCOL.key] new private key format, bcrypt as KDF by - default; details in PROTOCOL.key; feedback and lots help from djm; - ok djm@ - - markus@cvs.openbsd.org 2013/12/06 13:39:49 - [authfd.c authfile.c key.c key.h myproposal.h pathnames.h readconf.c] - [servconf.c ssh-agent.c ssh-keygen.c ssh-keyscan.1 ssh-keyscan.c] - [ssh-keysign.c ssh.c ssh_config.5 sshd.8 sshd.c verify.c ssh-ed25519.c] - [sc25519.h sc25519.c hash.c ge25519_base.data ge25519.h ge25519.c] - [fe25519.h fe25519.c ed25519.c crypto_api.h blocks.c] - support ed25519 keys (hostkeys and user identities) using the public - domain ed25519 reference code from SUPERCOP, see - http://ed25519.cr.yp.to/software.html - feedback, help & ok djm@ - - jmc@cvs.openbsd.org 2013/12/06 15:29:07 - [sshd.8] - missing comma; - - djm@cvs.openbsd.org 2013/12/07 00:19:15 - [key.c] - set k->cert = NULL after freeing it - - markus@cvs.openbsd.org 2013/12/06 13:52:46 - [regress/Makefile regress/agent.sh regress/cert-hostkey.sh] - [regress/cert-userkey.sh regress/keytype.sh] - test ed25519 support; from djm@ - - (djm) [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] - [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] Fix RCS idents - - (djm) [Makefile.in] Add ed25519 sources - - (djm) [authfile.c] Conditionalise inclusion of util.h - - (djm) [configure.ac openbsd-compat/Makefile.in openbsd-compat/bcrypt_pbkdf.c] - [openbsd-compat/blf.h openbsd-compat/blowfish.c] - [openbsd-compat/openbsd-compat.h] Start at supporting bcrypt_pbkdf in - portable. - - (djm) [ed25519.c ssh-ed25519.c openbsd-compat/Makefile.in] - [openbsd-compat/bcrypt_pbkdf.c] Make ed25519/new key format compile on - Linux - - (djm) [regress/cert-hostkey.sh] Fix merge botch - - (djm) [Makefile.in] PATHSUBS and keygen bits for Ed25519; from - Loganaden Velvindron @ AfriNIC in bz#2179 - -20131205 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2013/11/21 08:05:09 - [ssh_config.5 sshd_config.5] - no need for .Pp before displays; - - deraadt@cvs.openbsd.org 2013/11/25 18:04:21 - [ssh.1 ssh.c] - improve -Q usage and such. One usage change is that the option is now - case-sensitive - ok dtucker markus djm - - jmc@cvs.openbsd.org 2013/11/26 12:14:54 - [ssh.1 ssh.c] - - put -Q in the right place - - Ar was a poor choice for the arguments to -Q. i've chosen an - admittedly equally poor Cm, at least consistent with the rest - of the docs. also no need for multiple instances - - zap a now redundant Nm - - usage() sync - - deraadt@cvs.openbsd.org 2013/11/26 19:15:09 - [pkcs11.h] - cleanup 1 << 31 idioms. Resurrection of this issue pointed out by - Eitan Adler ok markus for ssh, implies same change in kerberosV - - djm@cvs.openbsd.org 2013/12/01 23:19:05 - [PROTOCOL] - mention curve25519-sha256@libssh.org key exchange algorithm - - djm@cvs.openbsd.org 2013/12/02 02:50:27 - [PROTOCOL.chacha20poly1305] - typo; from Jon Cave - - djm@cvs.openbsd.org 2013/12/02 02:56:17 - [ssh-pkcs11-helper.c] - use-after-free; bz#2175 patch from Loganaden Velvindron @ AfriNIC - - djm@cvs.openbsd.org 2013/12/02 03:09:22 - [key.c] - make key_to_blob() return a NULL blob on failure; part of - bz#2175 from Loganaden Velvindron @ AfriNIC - - djm@cvs.openbsd.org 2013/12/02 03:13:14 - [cipher.c] - correct bzero of chacha20+poly1305 key context. bz#2177 from - Loganaden Velvindron @ AfriNIC - - Also make it a memset for consistency with the rest of cipher.c - - djm@cvs.openbsd.org 2013/12/04 04:20:01 - [sftp-client.c] - bz#2171: don't leak local_fd on error; from Loganaden Velvindron @ - AfriNIC - - djm@cvs.openbsd.org 2013/12/05 01:16:41 - [servconf.c servconf.h] - bz#2161 - fix AuthorizedKeysCommand inside a Match block and - rearrange things so the same error is harder to make next time; - with and ok dtucker@ - - (dtucker) [configure.ac] bz#2173: use pkg-config --libs to include correct - -L location for libedit. Patch from Serge van den Boom. - -20131121 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/11/08 11:15:19 - [bufaux.c bufbn.c buffer.c sftp-client.c sftp-common.c sftp-glob.c] - [uidswap.c] Include stdlib.h for free() as per the man page. - - markus@cvs.openbsd.org 2013/11/13 13:48:20 - [ssh-pkcs11.c] - add missing braces found by pedro - - djm@cvs.openbsd.org 2013/11/20 02:19:01 - [sshd.c] - delay closure of in/out fds until after "Bad protocol version - identification..." message, as get_remote_ipaddr/get_remote_port - require them open. - - deraadt@cvs.openbsd.org 2013/11/20 20:53:10 - [scp.c] - unsigned casts for ctype macros where neccessary - ok guenther millert markus - - deraadt@cvs.openbsd.org 2013/11/20 20:54:10 - [canohost.c clientloop.c match.c readconf.c sftp.c] - unsigned casts for ctype macros where neccessary - ok guenther millert markus - - djm@cvs.openbsd.org 2013/11/21 00:45:44 - [Makefile.in PROTOCOL PROTOCOL.chacha20poly1305 authfile.c chacha.c] - [chacha.h cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h] - [dh.c myproposal.h packet.c poly1305.c poly1305.h servconf.c ssh.1] - [ssh.c ssh_config.5 sshd_config.5] Add a new protocol 2 transport - cipher "chacha20-poly1305@openssh.com" that combines Daniel - Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an - authenticated encryption mode. - - Inspired by and similar to Adam Langley's proposal for TLS: - http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 - but differs in layout used for the MAC calculation and the use of a - second ChaCha20 instance to separately encrypt packet lengths. - Details are in the PROTOCOL.chacha20poly1305 file. - - Feedback markus@, naddy@; manpage bits Loganden Velvindron @ AfriNIC - ok markus@ naddy@ - - naddy@cvs.openbsd.org 2013/11/18 05:09:32 - [regress/forward-control.sh] - bump timeout to 10 seconds to allow slow machines (e.g. Alpha PC164) - to successfully run this; ok djm@ - - djm@cvs.openbsd.org 2013/11/21 03:15:46 - [regress/krl.sh] - add some reminders for additional tests that I'd like to implement - - djm@cvs.openbsd.org 2013/11/21 03:16:47 - [regress/modpipe.c] - use unsigned long long instead of u_int64_t here to avoid warnings - on some systems portable OpenSSH is built on. - - djm@cvs.openbsd.org 2013/11/21 03:18:51 - [regress/cipher-speed.sh regress/integrity.sh regress/rekey.sh] - [regress/try-ciphers.sh] - use new "ssh -Q cipher-auth" query to obtain lists of authenticated - encryption ciphers instead of specifying them manually; ensures that - the new chacha20poly1305@openssh.com mode is tested; - - ok markus@ and naddy@ as part of the diff to add - chacha20poly1305@openssh.com - -20131110 - - (dtucker) [regress/keytype.sh] Populate ECDSA key types to be tested by - querying the ones that are compiled in. - -20131109 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/11/09 05:41:34 - [regress/test-exec.sh regress/rekey.sh] - Use smaller test data files to speed up tests. Grow test datafiles - where necessary for a specific test. - - (dtucker) [configure.ac kex.c key.c myproposal.h] Test for the presence of - NID_X9_62_prime256v1, NID_secp384r1 and NID_secp521r1 and test that the - latter actually works before using it. Fedora (at least) has NID_secp521r1 - that doesn't work (see https://bugzilla.redhat.com/show_bug.cgi?id=1021897). - - (dtucker) [configure.ac] Fix brackets in NID_secp521r1 test. - - (dtucker) [configure.ac] Add missing "test". - - (dtucker) [key.c] Check for the correct defines for NID_secp521r1. - -20131108 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/11/08 01:06:14 - [regress/rekey.sh] - Rekey less frequently during tests to speed them up - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/11/07 11:58:27 - [cipher.c cipher.h kex.c kex.h mac.c mac.h servconf.c ssh.c] - Output the effective values of Ciphers, MACs and KexAlgorithms when - the default has not been overridden. ok markus@ - - djm@cvs.openbsd.org 2013/11/08 00:39:15 - [auth-options.c auth2-chall.c authfd.c channels.c cipher-3des1.c] - [clientloop.c gss-genr.c monitor_mm.c packet.c schnorr.c umac.c] - [sftp-client.c sftp-glob.c] - use calloc for all structure allocations; from markus@ - - djm@cvs.openbsd.org 2013/11/08 01:38:11 - [version.h] - openssh-6.4 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update version numbers following release. - - (dtucker) [openbsd-compat/openbsd-compat.h] Add null implementation of - arc4random_stir for platforms that have arc4random but don't have - arc4random_stir (right now this is only OpenBSD -current). - - (dtucker) [kex.c] Only enable CURVE25519_SHA256 if we actually have - EVP_sha256. - - (dtucker) [myproposal.h] Conditionally enable CURVE25519_SHA256. - - (dtucker) [openbsd-compat/bsd-poll.c] Add headers to prevent compile - warnings. - - (dtucker) [Makefile.in configure.ac] Set MALLOC_OPTIONS per platform - and pass in TEST_ENV. use stderr to get polluted - and the stderr-data test to fail. - - (dtucker) [contrib/cygwin/ssh-host-config] Simplify host key generation: - rather than testing and generating each key, call ssh-keygen -A. - Patch from vinschen at redhat.com. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/11/09 05:41:34 - [regress/test-exec.sh regress/rekey.sh] - Use smaller test data files to speed up tests. Grow test datafiles - where necessary for a specific test. - -20131107 - - (djm) [ssh-pkcs11.c] Bring back "non-constant initialiser" fix (rev 1.5) - that got lost in recent merge. - - (djm) [Makefile.in monitor.c] Missed chunks of curve25519 KEX diff - - (djm) [regress/modpipe.c regress/rekey.sh] Never intended to commit these - - (djm) [configure.ac defines.h] Skip arc4random_stir() calls on platforms - that lack it but have arc4random_uniform() - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2013/11/04 11:51:16 - [monitor.c] - fix rekeying for KEX_C25519_SHA256; noted by dtucker@ - RCSID sync only; I thought this was a merge botch and fixed it already - - markus@cvs.openbsd.org 2013/11/06 16:52:11 - [monitor_wrap.c] - fix rekeying for AES-GCM modes; ok deraadt - - djm@cvs.openbsd.org 2013/11/06 23:05:59 - [ssh-pkcs11.c] - from portable: s/true/true_val/ to avoid name collisions on dump platforms - RCSID sync only - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/10/09 23:44:14 - [regress/Makefile] (ID sync only) - regression test for sftp request white/blacklisting and readonly mode. - - markus@cvs.openbsd.org 2013/11/02 22:39:53 - [regress/kextype.sh] - add curve25519-sha256@libssh.org - - dtucker@cvs.openbsd.org 2013/11/04 12:27:42 - [regress/rekey.sh] - Test rekeying with all KexAlgorithms. - - dtucker@cvs.openbsd.org 2013/11/07 00:12:05 - [regress/rekey.sh] - Test rekeying for every Cipher, MAC and KEX, plus test every KEX with - the GCM ciphers. - - dtucker@cvs.openbsd.org 2013/11/07 01:12:51 - [regress/rekey.sh] - Factor out the data transfer rekey tests - - dtucker@cvs.openbsd.org 2013/11/07 02:48:38 - [regress/integrity.sh regress/cipher-speed.sh regress/try-ciphers.sh] - Use ssh -Q instead of hardcoding lists of ciphers or MACs. - - dtucker@cvs.openbsd.org 2013/11/07 03:55:41 - [regress/kextype.sh] - Use ssh -Q to get kex types instead of a static list. - - dtucker@cvs.openbsd.org 2013/11/07 04:26:56 - [regress/kextype.sh] - trailing space - - (dtucker) [Makefile.in configure.ac] Remove TEST_SSH_SHA256 environment - variable. It's no longer used now that we get the supported MACs from - ssh -Q. - -20131104 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2013/11/02 20:03:54 - [ssh-pkcs11.c] - support pkcs#11 tokes that only provide x509 zerts instead of raw pubkeys; - fixes bz#1908; based on patch from Laurent Barbe; ok djm - - markus@cvs.openbsd.org 2013/11/02 21:59:15 - [kex.c kex.h myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] - use curve25519 for default key exchange (curve25519-sha256@libssh.org); - initial patch from Aris Adamantiadis; ok djm@ - - markus@cvs.openbsd.org 2013/11/02 22:10:15 - [kexdhs.c kexecdhs.c] - no need to include monitor_wrap.h - - markus@cvs.openbsd.org 2013/11/02 22:24:24 - [kexdhs.c kexecdhs.c] - no need to include ssh-gss.h - - markus@cvs.openbsd.org 2013/11/02 22:34:01 - [auth-options.c] - no need to include monitor_wrap.h and ssh-gss.h - - markus@cvs.openbsd.org 2013/11/02 22:39:19 - [ssh_config.5 sshd_config.5] - the default kex is now curve25519-sha256@libssh.org - - djm@cvs.openbsd.org 2013/11/03 10:37:19 - [roaming_common.c] - fix a couple of function definitions foo() -> foo(void) - (-Wold-style-definition) - - (djm) [kexc25519.c kexc25519c.c kexc25519s.c] Import missed files from - KEX/curve25519 change - -20131103 - - (dtucker) [openbsd-compat/bsd-misc.c] Include time.h for nanosleep. - From OpenSMTPD where it prevents "implicit declaration" warnings (it's - a no-op in OpenSSH). From chl at openbsd. - - (dtucker) [openbsd-compat/setproctitle.c] Handle error case form the 2nd - vsnprintf. From eric at openbsd via chl@. - - (dtucker) [configure.ac defines.h] Add typedefs for intmax_t and uintmax_t - for platforms that don't have them. - -20131030 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/10/29 09:42:11 - [key.c key.h] - fix potential stack exhaustion caused by nested certificates; - report by Mateusz Kocielski; ok dtucker@ markus@ - - djm@cvs.openbsd.org 2013/10/29 09:48:02 - [servconf.c servconf.h session.c sshd_config sshd_config.5] - shd_config PermitTTY to disallow TTY allocation, mirroring the - longstanding no-pty authorized_keys option; - bz#2070, patch from Teran McKinney; ok markus@ - - jmc@cvs.openbsd.org 2013/10/29 18:49:32 - [sshd_config.5] - pty(4), not pty(7); - -20131026 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/10/25 23:04:51 - [ssh.c] - fix crash when using ProxyCommand caused by previous commit - was calling - freeaddrinfo(NULL); spotted by sthen@ and Tim Ruehsen, patch by sthen@ - -20131025 - - (djm) [ssh-keygen.c ssh-keysign.c sshconnect1.c sshd.c] Remove - unnecessary arc4random_stir() calls. The only ones left are to ensure - that the PRNG gets a different state after fork() for platforms that - have broken the API. - -20131024 - - (djm) [auth-krb5.c] bz#2032 - use local username in krb5_kuserok check - rather than full client name which may be of form user@REALM; - patch from Miguel Sanders; ok dtucker@ - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/10/23 05:40:58 - [servconf.c] - fix comment - - djm@cvs.openbsd.org 2013/10/23 23:35:32 - [sshd.c] - include local address and port in "Connection from ..." message (only - shown at loglevel>=verbose) - - dtucker@cvs.openbsd.org 2013/10/24 00:49:49 - [moduli.c] - Periodically print progress and, if possible, expected time to completion - when screening moduli for DH groups. ok deraadt djm - - dtucker@cvs.openbsd.org 2013/10/24 00:51:48 - [readconf.c servconf.c ssh_config.5 sshd_config.5] - Disallow empty Match statements and add "Match all" which matches - everything. ok djm, man page help jmc@ - - djm@cvs.openbsd.org 2013/10/24 08:19:36 - [ssh.c] - fix bug introduced in hostname canonicalisation commit: don't try to - resolve hostnames when a ProxyCommand is set unless the user has forced - canonicalisation; spotted by Iain Morgan - - (tim) [regress/sftp-perm.sh] We need a shell that understands "! somecmd" - -20131023 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/10/20 04:39:28 - [ssh_config.5] - document % expansions performed by "Match command ..." - - djm@cvs.openbsd.org 2013/10/20 06:19:28 - [readconf.c ssh_config.5] - rename "command" subclause of the recently-added "Match" keyword to - "exec"; it's shorter, clearer in intent and we might want to add the - ability to match against the command being executed at the remote end in - the future. - - djm@cvs.openbsd.org 2013/10/20 09:51:26 - [scp.1 sftp.1] - add canonicalisation options to -o lists - - jmc@cvs.openbsd.org 2013/10/20 18:00:13 - [ssh_config.5] - tweak the "exec" description, as worded by djm; - - djm@cvs.openbsd.org 2013/10/23 03:03:07 - [readconf.c] - Hostname may have %h sequences that should be expanded prior to Match - evaluation; spotted by Iain Morgan - - djm@cvs.openbsd.org 2013/10/23 03:05:19 - [readconf.c ssh.c] - comment - - djm@cvs.openbsd.org 2013/10/23 04:16:22 - [ssh-keygen.c] - Make code match documentation: relative-specified certificate expiry time - should be relative to current time and not the validity start time. - Reported by Petr Lautrbach; ok deraadt@ - -20131018 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/10/09 23:44:14 - [regress/Makefile regress/sftp-perm.sh] - regression test for sftp request white/blacklisting and readonly mode. - - jmc@cvs.openbsd.org 2013/10/17 07:35:48 - [sftp.1 sftp.c] - tweak previous; - - djm@cvs.openbsd.org 2013/10/17 22:08:04 - [sshd.c] - include remote port in bad banner message; bz#2162 - -20131017 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2013/10/15 14:10:25 - [ssh.1 ssh_config.5] - tweak previous; - - djm@cvs.openbsd.org 2013/10/16 02:31:47 - [readconf.c readconf.h roaming_client.c ssh.1 ssh.c ssh_config.5] - [sshconnect.c sshconnect.h] - Implement client-side hostname canonicalisation to allow an explicit - search path of domain suffixes to use to convert unqualified host names - to fully-qualified ones for host key matching. - This is particularly useful for host certificates, which would otherwise - need to list unqualified names alongside fully-qualified ones (and this - causes a number of problems). - "looks fine" markus@ - - jmc@cvs.openbsd.org 2013/10/16 06:42:25 - [ssh_config.5] - tweak previous; - - djm@cvs.openbsd.org 2013/10/16 22:49:39 - [readconf.c readconf.h ssh.1 ssh.c ssh_config.5] - s/canonicalise/canonicalize/ for consistency with existing spelling, - e.g. authorized_keys; pointed out by naddy@ - - djm@cvs.openbsd.org 2013/10/16 22:58:01 - [ssh.c ssh_config.5] - one I missed in previous: s/isation/ization/ - - djm@cvs.openbsd.org 2013/10/17 00:30:13 - [PROTOCOL sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c] - fsync@openssh.com protocol extension for sftp-server - client support to allow calling fsync() faster successful transfer - patch mostly by imorgan AT nas.nasa.gov; bz#1798 - "fine" markus@ "grumble OK" deraadt@ "doesn't sound bad to me" millert@ - - djm@cvs.openbsd.org 2013/10/17 00:46:49 - [ssh.c] - rearrange check to reduce diff against -portable - (Id sync only) - -20131015 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/10/09 23:42:17 - [sftp-server.8 sftp-server.c] - Add ability to whitelist and/or blacklist sftp protocol requests by name. - Refactor dispatch loop and consolidate read-only mode checks. - Make global variables static, since sftp-server is linked into sshd(8). - ok dtucker@ - - djm@cvs.openbsd.org 2013/10/10 00:53:25 - [sftp-server.c] - add -Q, -P and -p to usage() before jmc@ catches me - - djm@cvs.openbsd.org 2013/10/10 01:43:03 - [sshd.c] - bz#2139: fix re-exec fallback by ensuring that startup_pipe is correctly - updated; ok dtucker@ - - djm@cvs.openbsd.org 2013/10/11 02:45:36 - [sftp-client.c] - rename flag arguments to be more clear and consistent. - reorder some internal function arguments to make adding additional flags - easier. - no functional change - - djm@cvs.openbsd.org 2013/10/11 02:52:23 - [sftp-client.c] - missed one arg reorder - - djm@cvs.openbsd.org 2013/10/11 02:53:45 - [sftp-client.h] - obsolete comment - - jmc@cvs.openbsd.org 2013/10/14 14:18:56 - [sftp-server.8 sftp-server.c] - tweak previous; - ok djm - - djm@cvs.openbsd.org 2013/10/14 21:20:52 - [session.c session.h] - Add logging of session starts in a useful format; ok markus@ feedback and - ok dtucker@ - - djm@cvs.openbsd.org 2013/10/14 22:22:05 - [readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5] - add a "Match" keyword to ssh_config that allows matching on hostname, - user and result of arbitrary commands. "nice work" markus@ - - djm@cvs.openbsd.org 2013/10/14 23:28:23 - [canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] - refactor client config code a little: - add multistate option partsing to readconf.c, similar to servconf.c's - existing code. - move checking of options that accept "none" as an argument to readconf.c - add a lowercase() function and use it instead of explicit tolower() in - loops - part of a larger diff that was ok markus@ - - djm@cvs.openbsd.org 2013/10/14 23:31:01 - [ssh.c] - whitespace at EOL; pointed out by markus@ - - [ssh.c] g/c unused variable. - -20131010 - - (dtucker) OpenBSD CVS Sync - - sthen@cvs.openbsd.org 2013/09/16 11:35:43 - [ssh_config] - Remove gssapi config parts from ssh_config, as was already done for - sshd_config. Req by/ok ajacoutot@ - ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular - - djm@cvs.openbsd.org 2013/09/19 00:24:52 - [progressmeter.c] - store the initial file offset so the progress meter doesn't freak out - when resuming sftp transfers. bz#2137; patch from Iain Morgan; ok dtucker@` - - djm@cvs.openbsd.org 2013/09/19 00:49:12 - [sftp-client.c] - fix swapped pflag and printflag in sftp upload_dir; from Iain Morgan - - djm@cvs.openbsd.org 2013/09/19 01:24:46 - [channels.c] - bz#1297 - tell the client (via packet_send_debug) when their preferred - listen address has been overridden by the server's GatewayPorts; - ok dtucker@ - - djm@cvs.openbsd.org 2013/09/19 01:26:29 - [sshconnect.c] - bz#1211: make BindAddress work with UsePrivilegedPort=yes; patch from - swp AT swp.pp.ru; ok dtucker@ - - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 - [dh.c dh.h] - Increase the size of the Diffie-Hellman groups requested for a each - symmetric key size. New values from NIST Special Publication 800-57 with - the upper limit specified by RFC4419. Pointed out by Peter Backes, ok - djm@. - -20131009 - - (djm) [openbsd-compat/arc4random.c openbsd-compat/chacha_private.h] Pull - in OpenBSD implementation of arc4random, shortly to replace the existing - bsd-arc4random.c - - (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c] - [openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random - implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@, - tested tim@ - -20130922 - - (dtucker) [platform.c platform.h sshd.c] bz#2156: restore Linux oom_adj - setting when handling SIGHUP to maintain behaviour over retart. Patch - from Matthew Ife. - -20130918 - - (dtucker) [sshd_config] Trailing whitespace; from jstjohn at purdue edu. - -20130914 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/08/22 19:02:21 - [sshd.c] - Stir PRNG after post-accept fork. The child gets a different PRNG state - anyway via rexec and explicit privsep reseeds, but it's good to be sure. - ok markus@ - - mikeb@cvs.openbsd.org 2013/08/28 12:34:27 - [ssh-keygen.c] - improve batch processing a bit by making use of the quite flag a bit - more often and exit with a non zero code if asked to find a hostname - in a known_hosts file and it wasn't there; - originally from reyk@, ok djm - - djm@cvs.openbsd.org 2013/08/31 00:13:54 - [sftp.c] - make ^w match ksh behaviour (delete previous word instead of entire line) - - deraadt@cvs.openbsd.org 2013/09/02 22:00:34 - [ssh-keygen.c sshconnect1.c sshd.c] - All the instances of arc4random_stir() are bogus, since arc4random() - does this itself, inside itself, and has for a very long time.. Actually, - this was probably reducing the entropy available. - ok djm - ID SYNC ONLY for portable; we don't trust other arc4random implementations - to do this right. - - sthen@cvs.openbsd.org 2013/09/07 13:53:11 - [sshd_config] - Remove commented-out kerberos/gssapi config options from sample config, - kerberos support is currently not enabled in ssh in OpenBSD. Discussed with - various people; ok deraadt@ - ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular - - djm@cvs.openbsd.org 2013/09/12 01:41:12 - [clientloop.c] - fix connection crash when sending break (~B) on ControlPersist'd session; - ok dtucker@ - - djm@cvs.openbsd.org 2013/09/13 06:54:34 - [channels.c] - avoid unaligned access in code that reused a buffer to send a - struct in_addr in a reply; simpler just use use buffer_put_int(); - from portable; spotted by and ok dtucker@ - -20130828 - - (djm) [openbsd-compat/bsd-snprintf.c] teach our local snprintf code the - 'j' (intmax_t/uintmax_t) and 'z' (size_t/ssize_t) conversions in case we - start to use them in the future. - - (djm) [openbsd-compat/bsd-snprintf.c] #ifdef noytet for intmax_t bits - until we have configure support. - -20130821 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/08/06 23:03:49 - [sftp.c] - fix some whitespace at EOL - make list of commands an enum rather than a long list of defines - add -a to usage() - - djm@cvs.openbsd.org 2013/08/06 23:05:01 - [sftp.1] - document top-level -a option (the -a option to 'get' was already - documented) - - djm@cvs.openbsd.org 2013/08/06 23:06:01 - [servconf.c] - add cast to avoid format warning; from portable - - jmc@cvs.openbsd.org 2013/08/07 06:24:51 - [sftp.1 sftp.c] - sort -a; - - djm@cvs.openbsd.org 2013/08/08 04:52:04 - [sftp.c] - fix two year old regression: symlinking a file would incorrectly - canonicalise the target path. bz#2129 report from delphij AT freebsd.org - - djm@cvs.openbsd.org 2013/08/08 05:04:03 - [sftp-client.c sftp-client.h sftp.c] - add a "-l" flag for the rename command to force it to use the silly - standard SSH_FXP_RENAME command instead of the POSIX-rename- like - posix-rename@openssh.com extension. - - intended for use in regress tests, so no documentation. - - djm@cvs.openbsd.org 2013/08/09 03:37:25 - [sftp.c] - do getopt parsing for all sftp commands (with an empty optstring for - commands without arguments) to ensure consistent behaviour - - djm@cvs.openbsd.org 2013/08/09 03:39:13 - [sftp-client.c] - two problems found by a to-be-committed regress test: 1) msg_id was not - being initialised so was starting at a random value from the heap - (harmless, but confusing). 2) some error conditions were not being - propagated back to the caller - - djm@cvs.openbsd.org 2013/08/09 03:56:42 - [sftp.c] - enable ctrl-left-arrow and ctrl-right-arrow to move forward/back a word; - matching ksh's relatively recent change. - - djm@cvs.openbsd.org 2013/08/13 18:32:08 - [ssh-keygen.c] - typo in error message; from Stephan Rickauer - - djm@cvs.openbsd.org 2013/08/13 18:33:08 - [ssh-keygen.c] - another of the same typo - - jmc@cvs.openbsd.org 2013/08/14 08:39:27 - [scp.1 ssh.1] - some Bx/Ox conversion; - From: Jan Stary - - djm@cvs.openbsd.org 2013/08/20 00:11:38 - [readconf.c readconf.h ssh_config.5 sshconnect.c] - Add a ssh_config ProxyUseFDPass option that supports the use of - ProxyCommands that establish a connection and then pass a connected - file descriptor back to ssh(1). This allows the ProxyCommand to exit - rather than have to shuffle data back and forth and enables ssh to use - getpeername, etc. to obtain address information just like it does with - regular directly-connected sockets. ok markus@ - - jmc@cvs.openbsd.org 2013/08/20 06:56:07 - [ssh.1 ssh_config.5] - some proxyusefdpass tweaks; - -20130808 - - (dtucker) [regress/Makefile regress/test-exec.sh] Don't try to use test -nt - since some platforms (eg really old FreeBSD) don't have it. Instead, - run "make clean" before a complete regress run. ok djm. - - (dtucker) [misc.c] Fall back to time(2) at runtime if clock_gettime( - CLOCK_MONOTONIC...) fails. Some older versions of RHEL have the - CLOCK_MONOTONIC define but don't actually support it. Found and tested - by Kevin Brott, ok djm. - - (dtucker) [misc.c] Remove define added for fallback testing that was - mistakenly included in the previous commit. - - (dtucker) [regress/Makefile regress/test-exec.sh] Roll back the -nt - removal. The "make clean" removes modpipe which is built by the top-level - directory before running the tests. Spotted by tim@ - - (djm) Release 6.3p1 - -20130804 - - (dtucker) [auth-krb5.c configure.ac openbsd-compat/bsd-misc.h] Add support - for building with older Heimdal versions. ok djm. - -20130801 - - (djm) [channels.c channels.h] bz#2135: On Solaris, isatty() on a non- - blocking connecting socket will clear any stored errno that might - otherwise have been retrievable via getsockopt(). A hack to limit writes - to TTYs on AIX was triggering this. Since only AIX needs the hack, wrap - it in an #ifdef. Diagnosis and patch from Ivo Raisr. - - (djm) [sshlogin.h] Fix prototype merge botch from 2006; bz#2134 - -20130725 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/07/20 22:20:42 - [krl.c] - fix verification error in (as-yet usused) KRL signature checking path - - djm@cvs.openbsd.org 2013/07/22 05:00:17 - [umac.c] - make MAC key, data to be hashed and nonce for final hash const; - checked with -Wcast-qual - - djm@cvs.openbsd.org 2013/07/22 12:20:02 - [umac.h] - oops, forgot to commit corresponding header change; - spotted by jsg and jasper - - djm@cvs.openbsd.org 2013/07/25 00:29:10 - [ssh.c] - daemonise backgrounded (ControlPersist'ed) multiplexing master to ensure - it is fully detached from its controlling terminal. based on debugging - - djm@cvs.openbsd.org 2013/07/25 00:56:52 - [sftp-client.c sftp-client.h sftp.1 sftp.c] - sftp support for resuming partial downloads; patch mostly by Loganaden - Velvindron/AfriNIC with some tweaks by me; feedback and ok dtucker@ - "Just be careful" deraadt@ - - djm@cvs.openbsd.org 2013/07/25 00:57:37 - [version.h] - openssh-6.3 for release - - dtucker@cvs.openbsd.org 2013/05/30 20:12:32 - [regress/test-exec.sh] - use ssh and sshd as testdata since it needs to be >256k for the rekey test - - dtucker@cvs.openbsd.org 2013/06/10 21:56:43 - [regress/forwarding.sh] - Add test for forward config parsing - - djm@cvs.openbsd.org 2013/06/21 02:26:26 - [regress/sftp-cmds.sh regress/test-exec.sh] - unbreak sftp-cmds for renamed test data (s/ls/data/) - - (tim) [sftp-client.c] Use of a gcc extension trips up native compilers on - Solaris and UnixWare. Feedback and OK djm@ - - (tim) [regress/forwarding.sh] Fix for building outside source tree. - -20130720 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2013/07/19 07:37:48 - [auth.h kex.h kexdhs.c kexecdhs.c kexgexs.c monitor.c servconf.c] - [servconf.h session.c sshd.c sshd_config.5] - add ssh-agent(1) support to sshd(8); allows encrypted hostkeys, - or hostkeys on smartcards; most of the work by Zev Weiss; bz #1974 - ok djm@ - - djm@cvs.openbsd.org 2013/07/20 01:43:46 - [umac.c] - use a union to ensure correct alignment; ok deraadt - - djm@cvs.openbsd.org 2013/07/20 01:44:37 - [ssh-keygen.c ssh.c] - More useful error message on missing current user in /etc/passwd - - djm@cvs.openbsd.org 2013/07/20 01:50:20 - [ssh-agent.c] - call cleanup_handler on SIGINT when in debug mode to ensure sockets - are cleaned up on manual exit; bz#2120 - - djm@cvs.openbsd.org 2013/07/20 01:55:13 - [auth-krb5.c gss-serv-krb5.c gss-serv.c] - fix kerberos/GSSAPI deprecation warnings and linking; "looks okay" millert@ - -20130718 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/06/10 19:19:44 - [readconf.c] - revert 1.203 while we investigate crashes reported by okan@ - - guenther@cvs.openbsd.org 2013/06/17 04:48:42 - [scp.c] - Handle time_t values as long long's when formatting them and when - parsing them from remote servers. - Improve error checking in parsing of 'T' lines. - ok dtucker@ deraadt@ - - markus@cvs.openbsd.org 2013/06/20 19:15:06 - [krl.c] - don't leak the rdata blob on errors; ok djm@ - - djm@cvs.openbsd.org 2013/06/21 00:34:49 - [auth-rsa.c auth.h auth2-hostbased.c auth2-pubkey.c monitor.c] - for hostbased authentication, print the client host and user on - the auth success/failure line; bz#2064, ok dtucker@ - - djm@cvs.openbsd.org 2013/06/21 00:37:49 - [ssh_config.5] - explicitly mention that IdentitiesOnly can be used with IdentityFile - to control which keys are offered from an agent. - - djm@cvs.openbsd.org 2013/06/21 05:42:32 - [dh.c] - sprinkle in some error() to explain moduli(5) parse failures - - djm@cvs.openbsd.org 2013/06/21 05:43:10 - [scp.c] - make this -Wsign-compare clean after time_t conversion - - djm@cvs.openbsd.org 2013/06/22 06:31:57 - [scp.c] - improved time_t overflow check suggested by guenther@ - - jmc@cvs.openbsd.org 2013/06/27 14:05:37 - [ssh-keygen.1 ssh.1 ssh_config.5 sshd.8 sshd_config.5] - do not use Sx for sections outwith the man page - ingo informs me that - stuff like html will render with broken links; - issue reported by Eric S. Raymond, via djm - - markus@cvs.openbsd.org 2013/07/02 12:31:43 - [dh.c] - remove extra whitespace - - djm@cvs.openbsd.org 2013/07/12 00:19:59 - [auth-options.c auth-rsa.c bufaux.c buffer.h channels.c hostfile.c] - [hostfile.h mux.c packet.c packet.h roaming_common.c serverloop.c] - fix pointer-signedness warnings from clang/llvm-3.3; "seems nice" deraadt@ - - djm@cvs.openbsd.org 2013/07/12 00:20:00 - [sftp.c ssh-keygen.c ssh-pkcs11.c] - fix pointer-signedness warnings from clang/llvm-3.3; "seems nice" deraadt@ - - djm@cvs.openbsd.org 2013/07/12 00:43:50 - [misc.c] - in ssh_gai_strerror() don't fallback to strerror for EAI_SYSTEM when - errno == 0. Avoids confusing error message in some broken resolver - cases. bz#2122 patch from plautrba AT redhat.com; ok dtucker - - djm@cvs.openbsd.org 2013/07/12 05:42:03 - [ssh-keygen.c] - do_print_resource_record() can never be called with a NULL filename, so - don't attempt (and bungle) asking for one if it has not been specified - bz#2127 ok dtucker@ - - djm@cvs.openbsd.org 2013/07/12 05:48:55 - [ssh.c] - set TCP nodelay for connections started with -N; bz#2124 ok dtucker@ - - schwarze@cvs.openbsd.org 2013/07/16 00:07:52 - [scp.1 sftp-server.8 ssh-keyscan.1 ssh-keysign.8 ssh-pkcs11-helper.8] - use .Mt for email addresses; from Jan Stary ; ok jmc@ - - djm@cvs.openbsd.org 2013/07/18 01:12:26 - [ssh.1] - be more exact wrt perms for ~/.ssh/config; bz#2078 - -20130702 - - (dtucker) [contrib/cygwin/README contrib/cygwin/ssh-host-config - contrib/cygwin/ssh-user-config] Modernizes and improve readability of - the Cygwin README file (which hasn't been updated for ages), drop - unsupported OSes from the ssh-host-config help text, and drop an - unneeded option from ssh-user-config. Patch from vinschen at redhat com. - -20130610 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/06/07 15:37:52 - [channels.c channels.h clientloop.c] - Add an "ABANDONED" channel state and use for mux sessions that are - disconnected via the ~. escape sequence. Channels in this state will - be able to close if the server responds, but do not count as active channels. - This means that if you ~. all of the mux clients when using ControlPersist - on a broken network, the backgrounded mux master will exit when the - Control Persist time expires rather than hanging around indefinitely. - bz#1917, also reported and tested by tedu@. ok djm@ markus@. - - (dtucker) [Makefile.in configure.ac fixalgorithms] Remove unsupported - algorithms (Ciphers, MACs and HostKeyAlgorithms) from man pages. - - (dtucker) [myproposal.h] Do not advertise AES GSM ciphers if we don't have - the required OpenSSL support. Patch from naddy at freebsd. - - (dtucker) [myproposal.h] Make the conditional algorithm support consistent - and add some comments so it's clear what goes where. - -20130605 - - (dtucker) [myproposal.h] Enable sha256 kex methods based on the presence of - the necessary functions, not from the openssl version. - - (dtucker) [contrib/ssh-copy-id] bz#2117: Use portable operator in test. - Patch from cjwatson at debian. - - (dtucker) [regress/forwarding.sh] For (as yet unknown) reason, the - forwarding test is extremely slow copying data on some machines so switch - back to copying the much smaller ls binary until we can figure out why - this is. - - (dtucker) [Makefile.in] append $CFLAGS to compiler options when building - modpipe in case there's anything in there we need. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/06/02 21:01:51 - [channels.h] - typo in comment - - dtucker@cvs.openbsd.org 2013/06/02 23:36:29 - [clientloop.h clientloop.c mux.c] - No need for the mux cleanup callback to be visible so restore it to static - and call it through the detach_user function pointer. ok djm@ - - dtucker@cvs.openbsd.org 2013/06/03 00:03:18 - [mac.c] - force the MAC output to be 64-bit aligned so umac won't see unaligned - accesses on strict-alignment architectures. bz#2101, patch from - tomas.kuthan at oracle.com, ok djm@ - - dtucker@cvs.openbsd.org 2013/06/04 19:12:23 - [scp.c] - use MAXPATHLEN for buffer size instead of fixed value. ok markus - - dtucker@cvs.openbsd.org 2013/06/04 20:42:36 - [sftp.c] - Make sftp's libedit interface marginally multibyte aware by building up - the quoted string by character instead of by byte. Prevents failures - when linked against a libedit built with wide character support (bz#1990). - "looks ok" djm - - dtucker@cvs.openbsd.org 2013/06/05 02:07:29 - [mux.c] - fix leaks in mux error paths, from Zhenbo Xu, found by Melton. bz#1967, - ok djm - - dtucker@cvs.openbsd.org 2013/06/05 02:27:50 - [sshd.c] - When running sshd -D, close stderr unless we have explicitly requesting - logging to stderr. From james.hunt at ubuntu.com via bz#1976, djm's patch - so, err, ok dtucker. - - dtucker@cvs.openbsd.org 2013/06/05 12:52:38 - [sshconnect2.c] - Fix memory leaks found by Zhenbo Xu and the Melton tool. bz#1967, ok djm - - dtucker@cvs.openbsd.org 2013/06/05 22:00:28 - [readconf.c] - plug another memleak. bz#1967, from Zhenbo Xu, detected by Melton, ok djm - - (dtucker) [configure.ac sftp.c openbsd-compat/openbsd-compat.h] Cater for - platforms that don't have multibyte character support (specifically, - mblen). - -20130602 - - (tim) [Makefile.in] Make Solaris, UnixWare, & OpenServer linkers happy - linking regress/modpipe. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/06/02 13:33:05 - [progressmeter.c] - Add misc.h for monotime prototype. (ID sync only). - - dtucker@cvs.openbsd.org 2013/06/02 13:35:58 - [ssh-agent.c] - Make parent_alive_interval time_t to avoid signed/unsigned comparison - - (dtucker) [configure.ac] sys/un.h needs sys/socket.h on some platforms - to prevent noise from configure. Patch from Nathan Osman. (bz#2114). - - (dtucker) [configure.ac] bz#2111: don't try to use lastlog on Android. - Patch from Nathan Osman. - - (tim) [configure.ac regress/Makefile] With rev 1.47 of test-exec.sh we - need a shell that can handle "[ file1 -nt file2 ]". Rather than keep - dealing with shell portability issues in regression tests, we let - configure find us a capable shell on those platforms with an old /bin/sh. - - (tim) [aclocal.m4] Enhance OSSH_CHECK_CFLAG_COMPILE to check stderr. - feedback and ok dtucker - - (tim) [regress/sftp-chroot.sh] skip if no sudo. ok dtucker - - (dtucker) [configure.ac] Some platforms need sys/types.h before sys/un.h. - - (dtucker) [configure.ac] Some other platforms need sys/types.h before - sys/socket.h. - -20130601 - - (dtucker) [configure.ac openbsd-compat/xcrypt.c] bz#2112: fall back to - using openssl's DES_crypt function on platorms that don't have a native - one, eg Android. Based on a patch from Nathan Osman. - - (dtucker) [configure.ac defines.h] Test for fd_mask, howmany and NFDBITS - rather than trying to enumerate the plaforms that don't have them. - Based on a patch from Nathan Osman, with help from tim@. - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/05/17 00:13:13 - [xmalloc.h cipher.c sftp-glob.c ssh-keyscan.c ssh.c sftp-common.c - ssh-ecdsa.c auth2-chall.c compat.c readconf.c kexgexs.c monitor.c - gss-genr.c cipher-3des1.c kex.c monitor_wrap.c ssh-pkcs11-client.c - auth-options.c rsa.c auth2-pubkey.c sftp.c hostfile.c auth2.c - servconf.c auth.c authfile.c xmalloc.c uuencode.c sftp-client.c - auth2-gss.c sftp-server.c bufaux.c mac.c session.c jpake.c kexgexc.c - sshconnect.c auth-chall.c auth2-passwd.c sshconnect1.c buffer.c - kexecdhs.c kexdhs.c ssh-rsa.c auth1.c ssh-pkcs11.c auth2-kbdint.c - kexdhc.c sshd.c umac.c ssh-dss.c auth2-jpake.c bufbn.c clientloop.c - monitor_mm.c scp.c roaming_client.c serverloop.c key.c auth-rsa.c - ssh-pkcs11-helper.c ssh-keysign.c ssh-keygen.c match.c channels.c - sshconnect2.c addrmatch.c mux.c canohost.c kexecdhc.c schnorr.c - ssh-add.c misc.c auth2-hostbased.c ssh-agent.c bufec.c groupaccess.c - dns.c packet.c readpass.c authfd.c moduli.c] - bye, bye xfree(); ok markus@ - - djm@cvs.openbsd.org 2013/05/19 02:38:28 - [auth2-pubkey.c] - fix failure to recognise cert-authority keys if a key of a different type - appeared in authorized_keys before it; ok markus@ - - djm@cvs.openbsd.org 2013/05/19 02:42:42 - [auth.h auth.c key.c monitor.c auth-rsa.c auth2.c auth1.c key.h] - Standardise logging of supplemental information during userauth. Keys - and ruser is now logged in the auth success/failure message alongside - the local username, remote host/port and protocol in use. Certificates - contents and CA are logged too. - Pushing all logging onto a single line simplifies log analysis as it is - no longer necessary to relate information scattered across multiple log - entries. "I like it" markus@ - - dtucker@cvs.openbsd.org 2013/05/31 12:28:10 - [ssh-agent.c] - Use time_t where appropriate. ok djm - - dtucker@cvs.openbsd.org 2013/06/01 13:15:52 - [ssh-agent.c clientloop.c misc.h packet.c progressmeter.c misc.c - channels.c sandbox-systrace.c] - Use clock_gettime(CLOCK_MONOTONIC ...) for ssh timers so that things like - keepalives and rekeying will work properly over clock steps. Suggested by - markus@, "looks good" djm@. - - dtucker@cvs.openbsd.org 2013/06/01 20:59:25 - [scp.c sftp-client.c] - Replace S_IWRITE, which isn't standardized, with S_IWUSR, which is. Patch - from Nathan Osman via bz#2085. ok deraadt. - - dtucker@cvs.openbsd.org 2013/06/01 22:34:50 - [sftp-client.c] - Update progressmeter when data is acked, not when it's sent. bz#2108, from - Debian via Colin Watson, ok djm@ - - (dtucker) [M auth-chall.c auth-krb5.c auth-pam.c cipher-aes.c cipher-ctr.c - groupaccess.c loginrec.c monitor.c monitor_wrap.c session.c sshd.c - sshlogin.c uidswap.c openbsd-compat/bsd-cygwin_util.c - openbsd-compat/getrrsetbyname-ldns.c openbsd-compat/port-aix.c - openbsd-compat/port-linux.c] Replace portable-specific instances of xfree - with the equivalent calls to free. - - (dtucker) [configure.ac misc.c] Look for clock_gettime in librt and fall - back to time(NULL) if we can't find it anywhere. - - (dtucker) [sandbox-seccomp-filter.c] Allow clock_gettimeofday. - -20130529 - - (dtucker) [configure.ac openbsd-compat/bsd-misc.h] bz#2087: Add a null - implementation of endgrent for platforms that don't have it (eg Android). - Loosely based on a patch from Nathan Osman, ok djm - - 20130517 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/03/07 00:20:34 - [regress/proxy-connect.sh] - repeat test with a style appended to the username - - dtucker@cvs.openbsd.org 2013/03/23 11:09:43 - [regress/test-exec.sh] - Only regenerate host keys if they don't exist or if ssh-keygen has changed - since they were. Reduces test runtime by 5-30% depending on machine - speed. - - dtucker@cvs.openbsd.org 2013/04/06 06:00:22 - [regress/rekey.sh regress/test-exec.sh regress/integrity.sh - regress/multiplex.sh Makefile regress/cfgmatch.sh] - Split the regress log into 3 parts: the debug output from ssh, the debug - log from sshd and the output from the client command (ssh, scp or sftp). - Somewhat functional now, will become more useful when ssh/sshd -E is added. - - dtucker@cvs.openbsd.org 2013/04/07 02:16:03 - [regress/Makefile regress/rekey.sh regress/integrity.sh - regress/sshd-log-wrapper.sh regress/forwarding.sh regress/test-exec.sh] - use -E option for ssh and sshd to write debuging logs to ssh{,d}.log and - save the output from any failing tests. If a test fails the debug output - from ssh and sshd for the failing tests (and only the failing tests) should - be available in failed-ssh{,d}.log. - - djm@cvs.openbsd.org 2013/04/18 02:46:12 - [regress/Makefile regress/sftp-chroot.sh] - test sshd ChrootDirectory+internal-sftp; feedback & ok dtucker@ - - dtucker@cvs.openbsd.org 2013/04/22 07:23:08 - [regress/multiplex.sh] - Write mux master logs to regress.log instead of ssh.log to keep separate - - djm@cvs.openbsd.org 2013/05/10 03:46:14 - [regress/modpipe.c] - sync some portability changes from portable OpenSSH (id sync only) - - dtucker@cvs.openbsd.org 2013/05/16 02:10:35 - [regress/rekey.sh] - Add test for time-based rekeying - - dtucker@cvs.openbsd.org 2013/05/16 03:33:30 - [regress/rekey.sh] - test rekeying when there's no data being transferred - - dtucker@cvs.openbsd.org 2013/05/16 04:26:10 - [regress/rekey.sh] - add server-side rekey test - - dtucker@cvs.openbsd.org 2013/05/16 05:48:31 - [regress/rekey.sh] - add tests for RekeyLimit parsing - - dtucker@cvs.openbsd.org 2013/05/17 00:37:40 - [regress/agent.sh regress/keytype.sh regress/cfgmatch.sh - regress/forcecommand.sh regress/proto-version.sh regress/test-exec.sh - regress/cipher-speed.sh regress/cert-hostkey.sh regress/cert-userkey.sh - regress/ssh-com.sh] - replace 'echo -n' with 'printf' since it's more portable - also remove "echon" hack. - - dtucker@cvs.openbsd.org 2013/05/17 01:16:09 - [regress/agent-timeout.sh] - Pull back some portability changes from -portable: - - TIMEOUT is a read-only variable in some shells - - not all greps have -q so redirect to /dev/null instead. - (ID sync only) - - dtucker@cvs.openbsd.org 2013/05/17 01:32:11 - [regress/integrity.sh] - don't print output from ssh before getting it (it's available in ssh.log) - - dtucker@cvs.openbsd.org 2013/05/17 04:29:14 - [regress/sftp.sh regress/putty-ciphers.sh regress/cipher-speed.sh - regress/test-exec.sh regress/sftp-batch.sh regress/dynamic-forward.sh - regress/putty-transfer.sh regress/conch-ciphers.sh regress/sftp-cmds.sh - regress/scp.sh regress/ssh-com-sftp.sh regress/rekey.sh - regress/putty-kex.sh regress/stderr-data.sh regress/stderr-after-eof.sh - regress/sftp-badcmds.sh regress/reexec.sh regress/ssh-com-client.sh - regress/sftp-chroot.sh regress/forwarding.sh regress/transfer.sh - regress/multiplex.sh] - Move the setting of DATA and COPY into test-exec.sh - - dtucker@cvs.openbsd.org 2013/05/17 10:16:26 - [regress/try-ciphers.sh] - use expr for math to keep diffs vs portable down - (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:23:52 - [regress/login-timeout.sh regress/reexec.sh regress/test-exec.sh] - Use SUDO when cat'ing pid files and running the sshd log wrapper so that - it works with a restrictive umask and the pid files are not world readable. - Changes from -portable. (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:24:48 - [regress/localcommand.sh] - use backticks for portability. (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:26:26 - [regress/sftp-badcmds.sh] - remove unused BATCH variable. (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:28:11 - [regress/sftp.sh] - only compare copied data if sftp succeeds. from portable (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:30:07 - [regress/test-exec.sh] - wait a bit longer for startup and use case for absolute path. - from portable (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:33:09 - [regress/agent-getpeereid.sh] - don't redirect stdout from sudo. from portable (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:34:30 - [regress/portnum.sh] - use a more portable negated if structure. from portable (id sync only) - - dtucker@cvs.openbsd.org 2013/05/17 10:35:43 - [regress/scp.sh] - use a file extention that's not special on some platforms. from portable - (id sync only) - - (dtucker) [regress/bsd.regress.mk] Remove unused file. We've never used it - in portable and it's long gone in openbsd. - - (dtucker) [regress/integrity.sh]. Force fixed Diffie-Hellman key exchange - methods. When the openssl version doesn't support ECDH then next one on - the list is DH group exchange, but that causes a bit more traffic which can - mean that the tests flip bits in the initial exchange rather than the MACed - traffic and we get different errors to what the tests look for. - - (dtucker) [openbsd-compat/getopt.h] Remove unneeded bits. - - (dtucker) [regress/cfgmatch.sh] Resync config file setup with openbsd. - - (dtucker) [regress/agent-getpeereid.sh] Resync spaces with openbsd. - - (dtucker) [regress/integrity.sh regress/krl.sh regress/test-exec.sh] - Move the jot helper function to portable-specific part of test-exec.sh. - - (dtucker) [regress/test-exec.sh] Move the portable-specific functions - together and add a couple of missing lines from openbsd. - - (dtucker) [regress/stderr-after-eof.sh regress/test-exec.sh] Move the md5 - helper function to the portable part of test-exec.sh. - - (dtucker) [regress/runtests.sh] Remove obsolete test driver script. - - (dtucker) [regress/cfgmatch.sh] Remove unneeded sleep renderd obsolete by - rev 1.6 which calls wait. - -20130516 - - (djm) [contrib/ssh-copy-id] Fix bug that could cause "rm *" to be - executed if mktemp failed; bz#2105 ok dtucker@ - - (dtucker) OpenBSD CVS Sync - - tedu@cvs.openbsd.org 2013/04/23 17:49:45 - [misc.c] - use xasprintf instead of a series of strlcats and strdup. ok djm - - tedu@cvs.openbsd.org 2013/04/24 16:01:46 - [misc.c] - remove extra parens noticed by nicm - - dtucker@cvs.openbsd.org 2013/05/06 07:35:12 - [sftp-server.8] - Reference the version of the sftp draft we actually implement. ok djm@ - - djm@cvs.openbsd.org 2013/05/10 03:40:07 - [sshconnect2.c] - fix bzero(ptr_to_struct, sizeof(ptr_to_struct)); bz#2100 from - Colin Watson - - djm@cvs.openbsd.org 2013/05/10 04:08:01 - [key.c] - memleak in cert_free(), wasn't actually freeing the struct; - bz#2096 from shm AT digitalsun.pl - - dtucker@cvs.openbsd.org 2013/05/10 10:13:50 - [ssh-pkcs11-helper.c] - remove unused extern optarg. ok markus@ - - dtucker@cvs.openbsd.org 2013/05/16 02:00:34 - [ssh_config sshconnect2.c packet.c readconf.h readconf.c clientloop.c - ssh_config.5 packet.h] - Add an optional second argument to RekeyLimit in the client to allow - rekeying based on elapsed time in addition to amount of traffic. - with djm@ jmc@, ok djm - - dtucker@cvs.openbsd.org 2013/05/16 04:09:14 - [sshd_config.5 servconf.c servconf.h packet.c serverloop.c monitor.c sshd_config - sshd.c] Add RekeyLimit to sshd with the same syntax as the client allowing - rekeying based on traffic volume or time. ok djm@, help & ok jmc@ for the man - page. - - djm@cvs.openbsd.org 2013/05/16 04:27:50 - [ssh_config.5 readconf.h readconf.c] - add the ability to ignore specific unrecognised ssh_config options; - bz#866; ok markus@ - - jmc@cvs.openbsd.org 2013/05/16 06:28:45 - [ssh_config.5] - put IgnoreUnknown in the right place; - - jmc@cvs.openbsd.org 2013/05/16 06:30:06 - [sshd_config.5] - oops! avoid Xr to self; - - dtucker@cvs.openbsd.org 2013/05/16 09:08:41 - [log.c scp.c sshd.c serverloop.c schnorr.c sftp.c] - Fix some "unused result" warnings found via clang and -portable. - ok markus@ - - dtucker@cvs.openbsd.org 2013/05/16 09:12:31 - [readconf.c servconf.c] - switch RekeyLimit traffic volume parsing to scan_scaled. ok djm@ - - dtucker@cvs.openbsd.org 2013/05/16 10:43:34 - [servconf.c readconf.c] - remove now-unused variables - - dtucker@cvs.openbsd.org 2013/05/16 10:44:06 - [servconf.c] - remove another now-unused variable - - (dtucker) [configure.ac readconf.c servconf.c - openbsd-compat/openbsd-compat.h] Add compat bits for scan_scaled. - -20130510 - - (dtucker) [configure.ac] Enable -Wsizeof-pointer-memaccess if the compiler - supports it. Mentioned by Colin Watson in bz#2100, ok djm. - - (dtucker) [openbsd-compat/getopt.c] Factor out portibility changes to - getopt.c. Preprocessed source is identical other than line numbers. - - (dtucker) [openbsd-compat/getopt_long.c] Import from OpenBSD. No - portability changes yet. - - (dtucker) [openbsd-compat/Makefile.in openbsd-compat/getopt.c - openbsd-compat/getopt_long.c regress/modpipe.c] Remove getopt.c, add - portability code to getopt_long.c and switch over Makefile and the ugly - hack in modpipe.c. Fixes bz#1448. - - (dtucker) [openbsd-compat/getopt.h openbsd-compat/getopt_long.c - openbsd-compat/openbsd-compat.h] pull in getopt.h from openbsd and plumb - in to use it when we're using our own getopt. - - (dtucker) [kex.c] Only include sha256 and ECC key exchange methods when the - underlying libraries support them. - - (dtucker) [configure.ac] Add -Werror to the -Qunused-arguments test so - we don't get a warning on compilers that *don't* support it. Add - -Wno-unknown-warning-option. Move both to the start of the list for - maximum noise suppression. Tested with gcc 4.6.3, gcc 2.95.4 and clang 2.9. - -20130423 - - (djm) [auth.c configure.ac misc.c monitor.c monitor_wrap.c] Support - platforms, such as Android, that lack struct passwd.pw_gecos. Report - and initial patch from Nathan Osman bz#2086; feedback tim@ ok dtucker@ - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2013/03/05 20:16:09 - [sshconnect2.c] - reset pubkey order on partial success; ok djm@ - - djm@cvs.openbsd.org 2013/03/06 23:35:23 - [session.c] - fatal() when ChrootDirectory specified by running without root privileges; - ok markus@ - - djm@cvs.openbsd.org 2013/03/06 23:36:53 - [readconf.c] - g/c unused variable (-Wunused) - - djm@cvs.openbsd.org 2013/03/07 00:19:59 - [auth2-pubkey.c monitor.c] - reconstruct the original username that was sent by the client, which may - have included a style (e.g. "root:skey") when checking public key - signatures. Fixes public key and hostbased auth when the client specified - a style; ok markus@ - - markus@cvs.openbsd.org 2013/03/07 19:27:25 - [auth.h auth2-chall.c auth2.c monitor.c sshd_config.5] - add submethod support to AuthenticationMethods; ok and freedback djm@ - - djm@cvs.openbsd.org 2013/03/08 06:32:58 - [ssh.c] - allow "ssh -f none ..." ok markus@ - - djm@cvs.openbsd.org 2013/04/05 00:14:00 - [auth2-gss.c krl.c sshconnect2.c] - hush some {unused, printf type} warnings - - djm@cvs.openbsd.org 2013/04/05 00:31:49 - [pathnames.h] - use the existing _PATH_SSH_USER_RC define to construct the other - pathnames; bz#2077, ok dtucker@ (no binary change) - - djm@cvs.openbsd.org 2013/04/05 00:58:51 - [mux.c] - cleanup mux-created channels that are in SSH_CHANNEL_OPENING state too - (in addition to ones already in OPEN); bz#2079, ok dtucker@ - - markus@cvs.openbsd.org 2013/04/06 16:07:00 - [channels.c sshd.c] - handle ECONNABORTED for accept(); ok deraadt some time ago... - - dtucker@cvs.openbsd.org 2013/04/07 02:10:33 - [log.c log.h ssh.1 ssh.c sshd.8 sshd.c] - Add -E option to ssh and sshd to append debugging logs to a specified file - instead of stderr or syslog. ok markus@, man page help jmc@ - - dtucker@cvs.openbsd.org 2013/04/07 09:40:27 - [sshd.8] - clarify -e text. suggested by & ok jmc@ - - djm@cvs.openbsd.org 2013/04/11 02:27:50 - [packet.c] - quiet disconnect notifications on the server from error() back to logit() - if it is a normal client closure; bz#2057 ok+feedback dtucker@ - - dtucker@cvs.openbsd.org 2013/04/17 09:04:09 - [session.c] - revert rev 1.262; it fails because uid is already set here. ok djm@ - - djm@cvs.openbsd.org 2013/04/18 02:16:07 - [sftp.c] - make "sftp -q" do what it says on the sticker: hush everything but errors; - ok dtucker@ - - djm@cvs.openbsd.org 2013/04/19 01:00:10 - [sshd_config.5] - document the requirment that the AuthorizedKeysCommand be owned by root; - ok dtucker@ markus@ - - djm@cvs.openbsd.org 2013/04/19 01:01:00 - [ssh-keygen.c] - fix some memory leaks; bz#2088 ok dtucker@ - - djm@cvs.openbsd.org 2013/04/19 01:03:01 - [session.c] - reintroduce 1.262 without the connection-killing bug: - fatal() when ChrootDirectory specified by running without root privileges; - ok markus@ - - djm@cvs.openbsd.org 2013/04/19 01:06:50 - [authfile.c cipher.c cipher.h kex.c kex.h kexecdh.c kexecdhc.c kexecdhs.c] - [key.c key.h mac.c mac.h packet.c ssh.1 ssh.c] - add the ability to query supported ciphers, MACs, key type and KEX - algorithms to ssh. Includes some refactoring of KEX and key type handling - to be table-driven; ok markus@ - - djm@cvs.openbsd.org 2013/04/19 11:10:18 - [ssh.c] - add -Q to usage; reminded by jmc@ - - djm@cvs.openbsd.org 2013/04/19 12:07:08 - [kex.c] - remove duplicated list entry pointed out by naddy@ - - dtucker@cvs.openbsd.org 2013/04/22 01:17:18 - [mux.c] - typo in debug output: evitval->exitval - -20130418 - - (djm) [config.guess config.sub] Update to last versions before they switch - to GPL3. ok dtucker@ - - (dtucker) [configure.ac] Use -Qunused-arguments to suppress warnings from - unused argument warnings (in particular, -fno-builtin-memset) from clang. - -20130404 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2013/02/17 23:16:57 - [readconf.c ssh.c readconf.h sshconnect2.c] - Keep track of which IndentityFile options were manually supplied and which - were default options, and don't warn if the latter are missing. - ok markus@ - - dtucker@cvs.openbsd.org 2013/02/19 02:12:47 - [krl.c] - Remove bogus include. ok djm - - dtucker@cvs.openbsd.org 2013/02/22 04:45:09 - [ssh.c readconf.c readconf.h] - Don't complain if IdentityFiles specified in system-wide configs are - missing. ok djm, deraadt. - - markus@cvs.openbsd.org 2013/02/22 19:13:56 - [sshconnect.c] - support ProxyCommand=- (stdin/out already point to the proxy); ok djm@ - - djm@cvs.openbsd.org 2013/02/22 22:09:01 - [ssh.c] - Allow IdenityFile=none; ok markus deraadt (and dtucker for an earlier - version) - -20130401 - - (dtucker) [openbsd-compat/bsd-cygwin_util.{c,h}] Don't include windows.h - to avoid conflicting definitions of __int64, adding the required bits. - Patch from Corinna Vinschen. - -20130323 - - (tim) [Makefile.in] remove some duplication introduced in 20130220 commit. - -20130322 - - (djm) [contrib/ssh-copy-id contrib/ssh-copy-id.1] Updated to Phil - Hands' greatly revised version. - - (djm) Release 6.2p1 - - (dtucker) [configure.ac] Add stdlib.h to zlib check for exit() prototype. - - (dtucker) [includes.h] Check if _GNU_SOURCE is already defined before - defining it again. Prevents warnings if someone, eg, sets it in CFLAGS. - -20130318 - - (djm) [configure.ac log.c scp.c sshconnect2.c openbsd-compat/vis.c] - [openbsd-compat/vis.h] FreeBSD's strnvis isn't compatible with OpenBSD's - so mark it as broken. Patch from des AT des.no - -20130317 - - (tim) [configure.ac] OpenServer 5 wants lastlog even though it has none - of the bits the configure test looks for. - -20130316 - - (djm) [configure.ac] Disable utmp, wtmp and/or lastlog if the platform - is unable to successfully compile them. Based on patch from des AT - des.no - - (djm) [configure.ac openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] - Add a usleep replacement for platforms that lack it; ok dtucker - - (djm) [session.c] FreeBSD needs setusercontext(..., LOGIN_SETUMASK) to - occur after UID switch; patch from John Marshall via des AT des.no; - ok dtucker@ - -20130312 - - (dtucker) [regress/Makefile regress/cipher-speed.sh regress/test-exec.sh] - Improve portability of cipher-speed test, based mostly on a patch from - Iain Morgan. - - (dtucker) [auth.c configure.ac platform.c platform.h] Accept uid 2 ("bin") - in addition to root as an owner of system directories on AIX and HP-UX. - ok djm@ - -20130307 - - (dtucker) [INSTALL] Bump documented autoconf version to what we're - currently using. - - (dtucker) [defines.h] Remove SIZEOF_CHAR bits since the test for it - was removed in configure.ac rev 1.481 as it was redundant. - - (tim) [Makefile.in] Add another missing $(EXEEXT) I should have seen 3 days - ago. - - (djm) [configure.ac] Add a timeout to the select/rlimit test to give it a - chance to complete on broken systems; ok dtucker@ - -20130306 - - (dtucker) [regress/forward-control.sh] Wait longer for the forwarding - connection to start so that the test works on slower machines. - - (dtucker) [configure.ac] test that we can set number of file descriptors - to zero with setrlimit before enabling the rlimit sandbox. This affects - (at least) HPUX 11.11. - -20130305 - - (djm) [regress/modpipe.c] Compilation fix for AIX and parsing fix for - HP/UX. Spotted by Kevin Brott - - (dtucker) [configure.ac] use "=" for shell test and not "==". Spotted by - Amit Kulkarni and Kevin Brott. - - (dtucker) [Makefile.in] Remove trailing "\" on PATHS, which caused obscure - build breakage on (at least) HP-UX 11.11. Found by Amit Kulkarni and Kevin - Brott. - - (tim) [Makefile.in] Add missing $(EXEEXT). Found by Roumen Petrov. - -20130227 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank version numbers - - (tim) [regress/forward-control.sh] use sh in case login shell is csh. - - (tim) [regress/integrity.sh] shell portability fix. - - (tim) [regress/integrity.sh] keep old solaris awk from hanging. - - (tim) [regress/krl.sh] keep old solaris awk from hanging. - -20130226 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/02/20 08:27:50 - [integrity.sh] - Add an option to modpipe that warns if the modification offset it not - reached in it's stream and turn it on for t-integrity. This should catch - cases where the session is not fuzzed for being too short (cf. my last - "oops" commit) - - (djm) [regress/integrity.sh] Run sshd via $SUDO; fixes tinderbox breakage - for UsePAM=yes configuration - -20130225 - - (dtucker) [configure.ac ssh-gss.h] bz#2073: additional #includes needed - to use Solaris native GSS libs. Patch from Pierre Ossman. - -20130223 - - (djm) [configure.ac includes.h loginrec.c mux.c sftp.c] Prefer - bsd/libutil.h to libutil.h to avoid deprecation warnings on Ubuntu. - ok tim - -20130222 - - (dtucker) [Makefile.in configure.ac] bz#2072: don't link krb5 libs to - ssh(1) since they're not needed. Patch from Pierre Ossman, ok djm. - - (dtucker) [configure.ac] bz#2073: look for Solaris' differently-named - libgss too. Patch from Pierre Ossman, ok djm. - - (djm) [configure.ac sandbox-seccomp-filter.c] Support for Linux - seccomp-bpf sandbox on ARM. Patch from shawnlandden AT gmail.com; - ok dtucker - -20130221 - - (tim) [regress/forward-control.sh] shell portability fix. - -20130220 - - (tim) [regress/cipher-speed.sh regress/try-ciphers.sh] shell portability fix. - - (tim) [krl.c Makefile.in regress/Makefile regress/modpipe.c] remove unneeded - err.h include from krl.c. Additional portability fixes for modpipe. OK djm - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/02/20 08:27:50 - [regress/integrity.sh regress/modpipe.c] - Add an option to modpipe that warns if the modification offset it not - reached in it's stream and turn it on for t-integrity. This should catch - cases where the session is not fuzzed for being too short (cf. my last - "oops" commit) - - djm@cvs.openbsd.org 2013/02/20 08:29:27 - [regress/modpipe.c] - s/Id/OpenBSD/ in RCS tag - -20130219 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/02/18 22:26:47 - [integrity.sh] - crank the offset yet again; it was still fuzzing KEX one of Darren's - portable test hosts at 2800 - - djm@cvs.openbsd.org 2013/02/19 02:14:09 - [integrity.sh] - oops, forgot to increase the output of the ssh command to ensure that - we actually reach $offset - - (djm) [regress/integrity.sh] Skip SHA2-based MACs on configurations that - lack support for SHA2. - - (djm) [regress/modpipe.c] Add local err, and errx functions for platforms - that do not have them. - -20130217 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/02/17 23:16:55 - [integrity.sh] - make the ssh command generates some output to ensure that there are at - least offset+tries bytes in the stream. - -20130216 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/02/16 06:08:45 - [integrity.sh] - make sure the fuzz offset is actually past the end of KEX for all KEX - types. diffie-hellman-group-exchange-sha256 requires an offset around - 2700. Noticed via test failures in portable OpenSSH on platforms that - lack ECC and this the more byte-frugal ECDH KEX algorithms. - -20130215 - - (djm) [contrib/suse/rc.sshd] Use SSHD_BIN consistently; bz#2056 from - Iain Morgan - - (dtucker) [configure.ac openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] - Use getpgrp() if we don't have getpgid() (old BSDs, maybe others). - - (dtucker) [configure.ac openbsd-compat/Makefile.in openbsd-compat/strtoull.c - openbsd-compat/openbsd-compat.h] Add strtoull to compat library for - platforms that don't have it. - - (dtucker) [openbsd-compat/openbsd-compat.h] Add prototype for strtoul, - group strto* function prototypes together. - - (dtucker) [openbsd-compat/bsd-misc.c] Handle the case where setpgrp() takes - an argument. Pointed out by djm. - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/02/14 21:35:59 - [auth2-pubkey.c] - Correct error message that had a typo and was logging the wrong thing; - patch from Petr Lautrbach - - dtucker@cvs.openbsd.org 2013/02/15 00:21:01 - [sshconnect2.c] - Warn more loudly if an IdentityFile provided by the user cannot be read. - bz #1981, ok djm@ - -20130214 - - (djm) [regress/krl.sh] Don't use ecdsa keys in environment that lack ECC. - - (djm) [regress/krl.sh] typo; found by Iain Morgan - - (djm) [regress/integrity.sh] Start fuzzing from offset 2500 (instead - of 2300) to avoid clobbering the end of (non-MAC'd) KEX. Verified by - Iain Morgan - -20130212 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/01/24 21:45:37 - [krl.c] - fix handling of (unused) KRL signatures; skip string in correct buffer - - djm@cvs.openbsd.org 2013/01/24 22:08:56 - [krl.c] - skip serial lookup when cert's serial number is zero - - krw@cvs.openbsd.org 2013/01/25 05:00:27 - [krl.c] - Revert last. Breaks due to likely typo. Let djm@ fix later. - ok djm@ via dlg@ - - djm@cvs.openbsd.org 2013/01/25 10:22:19 - [krl.c] - redo last commit without the vi-vomit that snuck in: - skip serial lookup when cert's serial number is zero - (now with 100% better comment) - - djm@cvs.openbsd.org 2013/01/26 06:11:05 - [Makefile.in acss.c acss.h cipher-acss.c cipher.c] - [openbsd-compat/openssl-compat.h] - remove ACSS, now that it is gone from libcrypto too - - djm@cvs.openbsd.org 2013/01/27 10:06:12 - [krl.c] - actually use the xrealloc() return value; spotted by xi.wang AT gmail.com - - dtucker@cvs.openbsd.org 2013/02/06 00:20:42 - [servconf.c sshd_config sshd_config.5] - Change default of MaxStartups to 10:30:100 to start doing random early - drop at 10 connections up to 100 connections. This will make it harder - to DoS as CPUs have come a long way since the original value was set - back in 2000. Prompted by nion at debian org, ok markus@ - - dtucker@cvs.openbsd.org 2013/02/06 00:22:21 - [auth.c] - Fix comment, from jfree.e1 at gmail - - djm@cvs.openbsd.org 2013/02/08 00:41:12 - [sftp.c] - fix NULL deref when built without libedit and control characters - entered as command; debugging and patch from Iain Morgan an - Loganaden Velvindron in bz#1956 - - markus@cvs.openbsd.org 2013/02/10 21:19:34 - [version.h] - openssh 6.2 - - djm@cvs.openbsd.org 2013/02/10 23:32:10 - [ssh-keygen.c] - append to moduli file when screening candidates rather than overwriting. - allows resumption of interrupted screen; patch from Christophe Garault - in bz#1957; ok dtucker@ - - djm@cvs.openbsd.org 2013/02/10 23:35:24 - [packet.c] - record "Received disconnect" messages at ERROR rather than INFO priority, - since they are abnormal and result in a non-zero ssh exit status; patch - from Iain Morgan in bz#2057; ok dtucker@ - - dtucker@cvs.openbsd.org 2013/02/11 21:21:58 - [sshd.c] - Add openssl version to debug output similar to the client. ok markus@ - - djm@cvs.openbsd.org 2013/02/11 23:58:51 - [regress/try-ciphers.sh] - remove acss here too - - (djm) [regress/try-ciphers.sh] clean up CVS merge botch - -20130211 - - (djm) [configure.ac openbsd-compat/openssl-compat.h] Repair build on old - libcrypto that lacks EVP_CIPHER_CTX_ctrl - -20130208 - - (djm) [contrib/redhat/sshd.init] treat RETVAL as an integer; - patch from Iain Morgan in bz#2059 - - (dtucker) [configure.ac openbsd-compat/sys-tree.h] Test if compiler allows - __attribute__ on return values and work around if necessary. ok djm@ - -20130207 - - (djm) [configure.ac] Don't probe seccomp capability of running kernel - at configure time; the seccomp sandbox will fall back to rlimit at - runtime anyway. Patch from plautrba AT redhat.com in bz#2011 - -20130120 - - (djm) [cipher-aes.c cipher-ctr.c openbsd-compat/openssl-compat.h] - Move prototypes for replacement ciphers to openssl-compat.h; fix EVP - prototypes for openssl-1.0.0-fips. - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2013/01/18 07:57:47 - [ssh-keygen.1] - tweak previous; - - jmc@cvs.openbsd.org 2013/01/18 07:59:46 - [ssh-keygen.c] - -u before -V in usage(); - - jmc@cvs.openbsd.org 2013/01/18 08:00:49 - [sshd_config.5] - tweak previous; - - jmc@cvs.openbsd.org 2013/01/18 08:39:04 - [ssh-keygen.1] - add -Q to the options list; ok djm - - jmc@cvs.openbsd.org 2013/01/18 21:48:43 - [ssh-keygen.1] - command-line (adj.) -> command line (n.); - - jmc@cvs.openbsd.org 2013/01/19 07:13:25 - [ssh-keygen.1] - fix some formatting; ok djm - - markus@cvs.openbsd.org 2013/01/19 12:34:55 - [krl.c] - RB_INSERT does not remove existing elments; ok djm@ - - (djm) [openbsd-compat/sys-tree.h] Sync with OpenBSD. krl.c needs newer - version. - - (djm) [regress/krl.sh] replacement for jot; most platforms lack it - -20130118 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/01/17 23:00:01 - [auth.c key.c key.h ssh-keygen.1 ssh-keygen.c sshd_config.5] - [krl.c krl.h PROTOCOL.krl] - add support for Key Revocation Lists (KRLs). These are a compact way to - represent lists of revoked keys and certificates, taking as little as - a single bit of incremental cost to revoke a certificate by serial number. - KRLs are loaded via the existing RevokedKeys sshd_config option. - feedback and ok markus@ - - djm@cvs.openbsd.org 2013/01/18 00:45:29 - [regress/Makefile regress/cert-userkey.sh regress/krl.sh] - Tests for Key Revocation Lists (KRLs) - - djm@cvs.openbsd.org 2013/01/18 03:00:32 - [krl.c] - fix KRL generation bug for list sections - -20130117 - - (djm) [regress/cipher-speed.sh regress/integrity.sh regress/try-ciphers.sh] - check for GCM support before testing GCM ciphers. - -20130112 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2013/01/12 11:22:04 - [cipher.c] - improve error message for integrity failure in AES-GCM modes; ok markus@ - - djm@cvs.openbsd.org 2013/01/12 11:23:53 - [regress/cipher-speed.sh regress/integrity.sh regress/try-ciphers.sh] - test AES-GCM modes; feedback markus@ - - (djm) [regress/integrity.sh] repair botched merge - -20130109 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/12/14 05:26:43 - [auth.c] - use correct string in error message; from rustybsd at gmx.fr - - djm@cvs.openbsd.org 2013/01/02 00:32:07 - [clientloop.c mux.c] - channel_setup_local_fwd_listener() returns 0 on failure, not -ve - bz#2055 reported by mathieu.lacage AT gmail.com - - djm@cvs.openbsd.org 2013/01/02 00:33:49 - [PROTOCOL.agent] - correct format description for SSH_AGENTC_ADD_RSA_ID_CONSTRAINED - bz#2051 from david AT lechnology.com - - djm@cvs.openbsd.org 2013/01/03 05:49:36 - [servconf.h] - add a couple of ServerOptions members that should be copied to the privsep - child (for consistency, in this case they happen only to be accessed in - the monitor); ok dtucker@ - - djm@cvs.openbsd.org 2013/01/03 12:49:01 - [PROTOCOL] - fix description of MAC calculation for EtM modes; ok markus@ - - djm@cvs.openbsd.org 2013/01/03 12:54:49 - [sftp-server.8 sftp-server.c] - allow specification of an alternate start directory for sftp-server(8) - "I like this" markus@ - - djm@cvs.openbsd.org 2013/01/03 23:22:58 - [ssh-keygen.c] - allow fingerprinting of keys hosted in PKCS#11 tokens: ssh-keygen -lD ... - ok markus@ - - jmc@cvs.openbsd.org 2013/01/04 19:26:38 - [sftp-server.8 sftp-server.c] - sftp-server.8: add argument name to -d - sftp-server.c: add -d to usage() - ok djm - - markus@cvs.openbsd.org 2013/01/08 18:49:04 - [PROTOCOL authfile.c cipher.c cipher.h kex.c kex.h monitor_wrap.c] - [myproposal.h packet.c ssh_config.5 sshd_config.5] - support AES-GCM as defined in RFC 5647 (but with simpler KEX handling) - ok and feedback djm@ - - djm@cvs.openbsd.org 2013/01/09 05:40:17 - [ssh-keygen.c] - correctly initialise fingerprint type for fingerprinting PKCS#11 keys - - (djm) [cipher.c configure.ac openbsd-compat/openssl-compat.h] - Fix merge botch, automatically detect AES-GCM in OpenSSL, move a little - cipher compat code to openssl-compat.h - -20121217 - - (dtucker) [Makefile.in] Add some scaffolding so that the new regress - tests will work with VPATH directories. - -20121213 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2012/12/12 16:45:52 - [packet.c] - reset incoming_packet buffer for each new packet in EtM-case, too; - this happens if packets are parsed only parially (e.g. ignore - messages sent when su/sudo turn off echo); noted by sthen/millert - - naddy@cvs.openbsd.org 2012/12/12 16:46:10 - [cipher.c] - use OpenSSL's EVP_aes_{128,192,256}_ctr() API and remove our hand-rolled - counter mode code; ok djm@ - - (djm) [configure.ac cipher-ctr.c] Adapt EVP AES CTR change to retain our - compat code for older OpenSSL - - (djm) [cipher.c] Fix missing prototype for compat code - -20121212 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2012/12/11 22:16:21 - [monitor.c] - drain the log messages after receiving the keystate from the unpriv - child. otherwise it might block while sending. ok djm@ - - markus@cvs.openbsd.org 2012/12/11 22:31:18 - [PROTOCOL authfile.c cipher.c cipher.h kex.h mac.c myproposal.h] - [packet.c ssh_config.5 sshd_config.5] - add encrypt-then-mac (EtM) modes to openssh by defining new mac algorithms - that change the packet format and compute the MAC over the encrypted - message (including the packet size) instead of the plaintext data; - these EtM modes are considered more secure and used by default. - feedback and ok djm@ - - sthen@cvs.openbsd.org 2012/12/11 22:51:45 - [mac.c] - fix typo, s/tem/etm in hmac-ripemd160-tem. ok markus@ - - markus@cvs.openbsd.org 2012/12/11 22:32:56 - [regress/try-ciphers.sh] - add etm modes - - markus@cvs.openbsd.org 2012/12/11 22:42:11 - [regress/Makefile regress/modpipe.c regress/integrity.sh] - test the integrity of the packets; with djm@ - - markus@cvs.openbsd.org 2012/12/11 23:12:13 - [try-ciphers.sh] - add hmac-ripemd160-etm@openssh.com - - (djm) [mac.c] fix merge botch - - (djm) [regress/Makefile regress/integrity.sh] Make the integrity.sh test - work on platforms without 'jot' - - (djm) [regress/integrity.sh] Fix awk quoting, packet length skip - - (djm) [regress/Makefile] fix t-exec rule - -20121207 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/12/06 06:06:54 - [regress/keys-command.sh] - Fix some problems with the keys-command test: - - use string comparison rather than numeric comparison - - check for existing KEY_COMMAND file and don't clobber if it exists - - clean up KEY_COMMAND file if we do create it. - - check that KEY_COMMAND is executable (which it won't be if eg /var/run - is mounted noexec). - ok djm. - - jmc@cvs.openbsd.org 2012/12/03 08:33:03 - [ssh-add.1 sshd_config.5] - tweak previous; - - markus@cvs.openbsd.org 2012/12/05 15:42:52 - [ssh-add.c] - prevent double-free of comment; ok djm@ - - dtucker@cvs.openbsd.org 2012/12/07 01:51:35 - [serverloop.c] - Cast signal to int for logging. A no-op on openbsd (they're always ints) - but will prevent warnings in portable. ok djm@ - -20121205 - - (tim) [defines.h] Some platforms are missing ULLONG_MAX. Feedback djm@. - -20121203 - - (djm) [openbsd-compat/sys-queue.h] Sync with OpenBSD to get - TAILQ_FOREACH_SAFE needed for upcoming changes. - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2012/12/02 20:26:11 - [ssh_config.5 sshconnect2.c] - Make IdentitiesOnly apply to keys obtained from a PKCS11Provider. - This allows control of which keys are offered from tokens using - IdentityFile. ok markus@ - - djm@cvs.openbsd.org 2012/12/02 20:42:15 - [ssh-add.1 ssh-add.c] - make deleting explicit keys "ssh-add -d" symmetric with adding keys - - try to delete the corresponding certificate too and respect the -k option - to allow deleting of the key only; feedback and ok markus@ - - djm@cvs.openbsd.org 2012/12/02 20:46:11 - [auth-options.c channels.c servconf.c servconf.h serverloop.c session.c] - [sshd_config.5] - make AllowTcpForwarding accept "local" and "remote" in addition to its - current "yes"/"no" to allow the server to specify whether just local or - remote TCP forwarding is enabled. ok markus@ - - dtucker@cvs.openbsd.org 2012/10/05 02:20:48 - [regress/cipher-speed.sh regress/try-ciphers.sh] - Add umac-128@openssh.com to the list of MACs to be tested - - djm@cvs.openbsd.org 2012/10/19 05:10:42 - [regress/cert-userkey.sh] - include a serial number when generating certs - - djm@cvs.openbsd.org 2012/11/22 22:49:30 - [regress/Makefile regress/keys-command.sh] - regress for AuthorizedKeysCommand; hints from markus@ - - djm@cvs.openbsd.org 2012/12/02 20:47:48 - [Makefile regress/forward-control.sh] - regress for AllowTcpForwarding local/remote; ok markus@ - - djm@cvs.openbsd.org 2012/12/03 00:14:06 - [auth2-chall.c ssh-keygen.c] - Fix compilation with -Wall -Werror (trivial type fixes) - - (djm) [configure.ac] Turn on -g for gcc compilers. Helps pre-installation - debugging. ok dtucker@ - - (djm) [configure.ac] Revert previous. configure.ac already does this - for us. - -20121114 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2012/11/14 02:24:27 - [auth2-pubkey.c] - fix username passed to helper program - prepare stdio fds before closefrom() - spotted by landry@ - - djm@cvs.openbsd.org 2012/11/14 02:32:15 - [ssh-keygen.c] - allow the full range of unsigned serial numbers; 'fine' deraadt@ - - djm@cvs.openbsd.org 2012/12/02 20:34:10 - [auth.c auth.h auth1.c auth2-chall.c auth2-gss.c auth2-jpake.c auth2.c] - [monitor.c monitor.h] - Fixes logging of partial authentication when privsep is enabled - Previously, we recorded "Failed xxx" since we reset authenticated before - calling auth_log() in auth2.c. This adds an explcit "Partial" state. - - Add a "submethod" to auth_log() to report which submethod is used - for keyboard-interactive. - - Fix multiple authentication when one of the methods is - keyboard-interactive. - - ok markus@ - - dtucker@cvs.openbsd.org 2012/10/05 02:05:30 - [regress/multiplex.sh] - Use 'kill -0' to test for the presence of a pid since it's more portable - -20121107 - - (djm) OpenBSD CVS Sync - - eric@cvs.openbsd.org 2011/11/28 08:46:27 - [moduli.5] - fix formula - ok djm@ - - jmc@cvs.openbsd.org 2012/09/26 17:34:38 - [moduli.5] - last stage of rfc changes, using consistent Rs/Re blocks, and moving the - references into a STANDARDS section; - -20121105 - - (dtucker) [uidswap.c openbsd-compat/Makefile.in - openbsd-compat/bsd-setres_id.c openbsd-compat/bsd-setres_id.h - openbsd-compat/openbsd-compat.h] Move the fallback code for setting uids - and gids from uidswap.c to the compat library, which allows it to work with - the new setresuid calls in auth2-pubkey. with tim@, ok djm@ - - (dtucker) [auth2-pubkey.c] wrap paths.h in an ifdef for platforms that - don't have it. Spotted by tim@. - -20121104 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2012/10/31 08:04:50 - [sshd_config.5] - tweak previous; - - djm@cvs.openbsd.org 2012/11/04 10:38:43 - [auth2-pubkey.c sshd.c sshd_config.5] - Remove default of AuthorizedCommandUser. Administrators are now expected - to explicitly specify a user. feedback and ok markus@ - - djm@cvs.openbsd.org 2012/11/04 11:09:15 - [auth.h auth1.c auth2.c monitor.c servconf.c servconf.h sshd.c] - [sshd_config.5] - Support multiple required authentication via an AuthenticationMethods - option. This option lists one or more comma-separated lists of - authentication method names. Successful completion of all the methods in - any list is required for authentication to complete; - feedback and ok markus@ - -20121030 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2012/10/05 12:34:39 - [sftp.c] - fix signed vs unsigned warning; feedback & ok: djm@ - - djm@cvs.openbsd.org 2012/10/30 21:29:55 - [auth-rsa.c auth.c auth.h auth2-pubkey.c servconf.c servconf.h] - [sshd.c sshd_config sshd_config.5] - new sshd_config option AuthorizedKeysCommand to support fetching - authorized_keys from a command in addition to (or instead of) from - the filesystem. The command is run as the target server user unless - another specified via a new AuthorizedKeysCommandUser option. - - patch originally by jchadima AT redhat.com, reworked by me; feedback + upstream commit + + Allow "ssh -Q protocol-version" to list supported SSH + protocol versions. Useful for detecting builds without SSH v.1 support; idea and ok markus@ -20121019 - - (tim) [buildpkg.sh.in] Double up on some backslashes so they end up in - the generated file as intended. +commit 39e2f1229562e1195169905607bc12290d21f021 +Author: millert@openbsd.org +Date: Sun Mar 1 15:44:40 2015 +0000 -20121005 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2012/09/17 09:54:44 - [sftp.c] - an XXX for later - - markus@cvs.openbsd.org 2012/09/17 13:04:11 - [packet.c] - clear old keys on rekeing; ok djm - - dtucker@cvs.openbsd.org 2012/09/18 10:36:12 - [sftp.c] - Add bounds check on sftp tab-completion. Part of a patch from from - Jean-Marc Robert via tech@, ok djm - - dtucker@cvs.openbsd.org 2012/09/21 10:53:07 - [sftp.c] - Fix improper handling of absolute paths when PWD is part of the completed - path. Patch from Jean-Marc Robert via tech@, ok djm. - - dtucker@cvs.openbsd.org 2012/09/21 10:55:04 - [sftp.c] - Fix handling of filenames containing escaped globbing characters and - escape "#" and "*". Patch from Jean-Marc Robert via tech@, ok djm. - - jmc@cvs.openbsd.org 2012/09/26 16:12:13 - [ssh.1] - last stage of rfc changes, using consistent Rs/Re blocks, and moving the - references into a STANDARDS section; - - naddy@cvs.openbsd.org 2012/10/01 13:59:51 - [monitor_wrap.c] - pasto; ok djm@ - - djm@cvs.openbsd.org 2012/10/02 07:07:45 - [ssh-keygen.c] - fix -z option, broken in revision 1.215 - - markus@cvs.openbsd.org 2012/10/04 13:21:50 - [myproposal.h ssh_config.5 umac.h sshd_config.5 ssh.1 sshd.8 mac.c] - add umac128 variant; ok djm@ at n2k12 - - dtucker@cvs.openbsd.org 2012/09/06 04:11:07 - [regress/try-ciphers.sh] - Restore missing space. (Id sync only). - - dtucker@cvs.openbsd.org 2012/09/09 11:51:25 - [regress/multiplex.sh] - Add test for ssh -Ostop - - dtucker@cvs.openbsd.org 2012/09/10 00:49:21 - [regress/multiplex.sh] - Log -O cmd output to the log file and make logging consistent with the - other tests. Test clean shutdown of an existing channel when testing - "stop". - - dtucker@cvs.openbsd.org 2012/09/10 01:51:19 - [regress/multiplex.sh] - use -Ocheck and waiting for completions by PID to make multiplexing test - less racy and (hopefully) more reliable on slow hardware. - - [Makefile umac.c] Add special-case target to build umac128.o. - - [umac.c] Enforce allowed umac output sizes. From djm@. - - [Makefile.in] "Using $< in a non-suffix rule context is a GNUmake idiom". + upstream commit + + Make sure we only call getnameinfo() for AF_INET or AF_INET6 + sockets. getpeername() of a Unix domain socket may return without error on + some systems without actually setting ss_family so getnameinfo() was getting + called with ss_family set to AF_UNSPEC. OK djm@ -20120917 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/09/13 23:37:36 - [servconf.c] - Fix comment line length - - markus@cvs.openbsd.org 2012/09/14 16:51:34 - [sshconnect.c] - remove unused variable +commit e47536ba9692d271b8ad89078abdecf0a1c11707 +Author: Damien Miller +Date: Sat Feb 28 08:20:11 2015 -0800 -20120907 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/09/06 09:50:13 - [clientloop.c] - Make the escape command help (~?) context sensitive so that only commands - that will work in the current session are shown. ok markus@ - - jmc@cvs.openbsd.org 2012/09/06 13:57:42 - [ssh.1] - missing letter in previous; - - dtucker@cvs.openbsd.org 2012/09/07 00:30:19 - [clientloop.c] - Print '^Z' instead of a raw ^Z when the sequence is not supported. ok djm@ - - dtucker@cvs.openbsd.org 2012/09/07 01:10:21 - [clientloop.c] - Merge escape help text for ~v and ~V; ok djm@ - - dtucker@cvs.openbsd.org 2012/09/07 06:34:21 - [clientloop.c] - when muxmaster is run with -N, make it shut down gracefully when a client - sends it "-O stop" rather than hanging around (bz#1985). ok djm@ + portability fixes for regress/netcat.c + + Mostly avoiding "err(1, NULL)" -20120906 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2012/08/15 18:25:50 - [ssh-keygen.1] - a little more info on certificate validity; - requested by Ross L Richardson, and provided by djm - - dtucker@cvs.openbsd.org 2012/08/17 00:45:45 - [clientloop.c clientloop.h mux.c] - Force a clean shutdown of ControlMaster client sessions when the ~. escape - sequence is used. This means that ~. should now work in mux clients even - if the server is no longer responding. Found by tedu, ok djm. - - djm@cvs.openbsd.org 2012/08/17 01:22:56 - [kex.c] - add some comments about better handling first-KEX-follows notifications - from the server. Nothing uses these right now. No binary change - - djm@cvs.openbsd.org 2012/08/17 01:25:58 - [ssh-keygen.c] - print details of which host lines were deleted when using - "ssh-keygen -R host"; ok markus@ - - djm@cvs.openbsd.org 2012/08/17 01:30:00 - [compat.c sshconnect.c] - Send client banner immediately, rather than waiting for the server to - move first for SSH protocol 2 connections (the default). Patch based on - one in bz#1999 by tls AT panix.com, feedback dtucker@ ok markus@ - - dtucker@cvs.openbsd.org 2012/09/06 04:37:39 - [clientloop.c log.c ssh.1 log.h] - Add ~v and ~V escape sequences to raise and lower the logging level - respectively. Man page help from jmc, ok deraadt jmc +commit 02973ad5f6f49d8420e50a392331432b0396c100 +Author: Damien Miller +Date: Sat Feb 28 08:05:27 2015 -0800 -20120830 - - (dtucker) [moduli] Import new moduli file. + twiddle another test for portability + + from Tom G. Christensen -20120828 - - (djm) Release openssh-6.1 +commit f7f3116abf2a6e2f309ab096b08c58d19613e5d0 +Author: Damien Miller +Date: Fri Feb 27 15:52:49 2015 -0800 -20120828 - - (dtucker) [openbsd-compat/bsd-cygwin_util.h] define WIN32_LEAN_AND_MEAN - for compatibility with future mingw-w64 headers. Patch from vinschen at - redhat com. + twiddle test for portability -20120822 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update version numbers +commit 1ad3a77cc9d5568f5437ff99d377aa7a41859b83 +Author: Damien Miller +Date: Thu Feb 26 20:33:22 2015 -0800 -20120731 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2012/07/06 06:38:03 - [ssh-keygen.c] - missing full stop in usage(); - - djm@cvs.openbsd.org 2012/07/10 02:19:15 - [servconf.c servconf.h sshd.c sshd_config] - Turn on systrace sandboxing of pre-auth sshd by default for new installs - by shipping a config that overrides the current UsePrivilegeSeparation=yes - default. Make it easier to flip the default in the future by adding too. - prodded markus@ feedback dtucker@ "get it in" deraadt@ - - dtucker@cvs.openbsd.org 2012/07/13 01:35:21 - [servconf.c] - handle long comments in config files better. bz#2025, ok markus - - markus@cvs.openbsd.org 2012/07/22 18:19:21 - [version.h] - openssh 6.1 + make regress/netcat.c fd passing (more) portable -20120720 - - (dtucker) Import regened moduli file. +commit 9e1cfca7e1fe9cf8edb634fc894e43993e4da1ea +Author: Damien Miller +Date: Thu Feb 26 20:32:58 2015 -0800 -20120706 - - (djm) [sandbox-seccomp-filter.c] fallback to rlimit if seccomp filter is - not available. Allows use of sshd compiled on host with a filter-capable - kernel on hosts that lack the support. bz#2011 ok dtucker@ - - (djm) [configure.ac] Recursively expand $(bindir) to ensure it has no - unexpanded $(prefix) embedded. bz#2007 patch from nix-corp AT - esperi.org.uk; ok dtucker@ -- (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/07/06 00:41:59 - [moduli.c ssh-keygen.1 ssh-keygen.c] - Add options to specify starting line number and number of lines to process - when screening moduli candidates. This allows processing of different - parts of a candidate moduli file in parallel. man page help jmc@, ok djm@ - - djm@cvs.openbsd.org 2012/07/06 01:37:21 - [mux.c] - fix memory leak of passed-in environment variables and connection - context when new session message is malformed; bz#2003 from Bert.Wesarg - AT googlemail.com - - djm@cvs.openbsd.org 2012/07/06 01:47:38 - [ssh.c] - move setting of tty_flag to after config parsing so RequestTTY options - are correctly picked up. bz#1995 patch from przemoc AT gmail.com; + create OBJ/valgrind-out before running unittests + +commit bd58853102cee739f0e115e6d4b5334332ab1442 +Author: Damien Miller +Date: Wed Feb 25 16:58:22 2015 -0800 + + valgrind support + +commit f43d17269194761eded9e89f17456332f4c83824 +Author: djm@openbsd.org +Date: Thu Feb 26 20:45:47 2015 +0000 + + upstream commit + + don't printf NULL key comments; reported by Tom Christensen + +commit 6e6458b476ec854db33e3e68ebf4f489d0ab3df8 +Author: djm@openbsd.org +Date: Wed Feb 25 23:05:47 2015 +0000 + + upstream commit + + zero cmsgbuf before use; we initialise the bits we use + but valgrind still spams warning on it + +commit a63cfa26864b93ab6afefad0b630e5358ed8edfa +Author: djm@openbsd.org +Date: Wed Feb 25 19:54:02 2015 +0000 + + upstream commit + + fix small memory leak when UpdateHostkeys=no + +commit e6b950341dd75baa8526f1862bca39e52f5b879b +Author: Tim Rice +Date: Wed Feb 25 09:56:48 2015 -0800 + + Revert "Work around finicky USL linker so netcat will build." + + This reverts commit d1db656021d0cd8c001a6692f772f1de29b67c8b. + + No longer needed with commit 678e473e2af2e4802f24dd913985864d9ead7fb3 + +commit 6f621603f9cff2a5d6016a404c96cb2f8ac2dec0 +Author: djm@openbsd.org +Date: Wed Feb 25 17:29:38 2015 +0000 + + upstream commit + + don't leak validity of user in "too many authentication + failures" disconnect message; reported by Sebastian Reitenbach + +commit 6288e3a935494df12519164f52ca5c8c65fc3ca5 +Author: naddy@openbsd.org +Date: Tue Feb 24 15:24:05 2015 +0000 + + upstream commit + + add -v (show ASCII art) to -l's synopsis; ok djm@ + +commit 678e473e2af2e4802f24dd913985864d9ead7fb3 +Author: Darren Tucker +Date: Thu Feb 26 04:12:58 2015 +1100 + + Remove dependency on xmalloc. + + Remove ssh_get_progname's dependency on xmalloc, which should reduce + link order problems. ok djm@ + +commit 5d5ec165c5b614b03678afdad881f10e25832e46 +Author: Darren Tucker +Date: Wed Feb 25 15:32:49 2015 +1100 + + Restrict ECDSA and ECDH tests. + + ifdef out some more ECDSA and ECDH tests when built against an OpenSSL + that does not have eliptic curve functionality. + +commit 1734e276d99b17e92d4233fac7aef3a3180aaca7 +Author: Darren Tucker +Date: Wed Feb 25 13:40:45 2015 +1100 + + Move definition of _NSIG. + + _NSIG is only unsed in one file, so move it there prevent redefinition + warnings reported by Kevin Brott. + +commit a47ead7c95cfbeb72721066c4da2312e5b1b9f3d +Author: Darren Tucker +Date: Wed Feb 25 13:17:40 2015 +1100 + + Add includes.h for compatibility stuff. + +commit 38806bda6d2e48ad32812b461eebe17672ada771 +Author: Damien Miller +Date: Tue Feb 24 16:50:06 2015 -0800 + + include netdb.h to look for MAXHOSTNAMELEN; ok tim + +commit d1db656021d0cd8c001a6692f772f1de29b67c8b +Author: Tim Rice +Date: Tue Feb 24 10:42:08 2015 -0800 + + Work around finicky USL linker so netcat will build. + +commit cb030ce25f555737e8ba97bdd7883ac43f3ff2a3 +Author: Damien Miller +Date: Tue Feb 24 09:23:04 2015 -0800 + + include includes.h to avoid build failure on AIX + +commit 13af342458f5064144abbb07e5ac9bbd4eb42567 +Author: Tim Rice +Date: Tue Feb 24 07:56:47 2015 -0800 + + Original portability patch from djm@ for platforms missing err.h. + Fix name space clash on Solaris 10. Still more to do for Solaris 10 + to deal with msghdr structure differences. ok djm@ + +commit 910209203d0cd60c5083901cbcc0b7b44d9f48d2 +Author: Tim Rice +Date: Mon Feb 23 22:06:56 2015 -0800 + + cleaner way fix dispatch.h portion of commit + a88dd1da119052870bb2654c1a32c51971eade16 + (some systems have sig_atomic_t in signal.h, some in sys/signal.h) + Sounds good to me djm@ + +commit 676c38d7cbe65b76bbfff796861bb6615cc6a596 +Author: Tim Rice +Date: Mon Feb 23 21:51:33 2015 -0800 + + portability fix: if we can't dind a better define for HOST_NAME_MAX, use 255 + +commit 1221b22023dce38cbc90ba77eae4c5d78c77a5e6 +Author: Tim Rice +Date: Mon Feb 23 21:50:34 2015 -0800 + + portablity fix: s/__inline__/inline/ + +commit 4c356308a88d309c796325bb75dce90ca16591d5 +Author: Darren Tucker +Date: Tue Feb 24 13:49:31 2015 +1100 + + Wrap stdint.h includes in HAVE_STDINT_H. + +commit c9c88355c6a27a908e7d1e5003a2b35ea99c1614 +Author: Darren Tucker +Date: Tue Feb 24 13:43:57 2015 +1100 + + Add AI_NUMERICSERV to fake-rfc2553. + + Our getaddrinfo implementation always returns numeric values already. + +commit ef342ab1ce6fb9a4b30186c89c309d0ae9d0eeb4 +Author: Darren Tucker +Date: Tue Feb 24 13:39:57 2015 +1100 + + Include OpenSSL's objects.h before bn.h. + + Prevents compile errors on some platforms (at least old GCCs and AIX's + XLC compilers). + +commit dcc8997d116f615195aa7c9ec019fb36c28c6228 +Author: Darren Tucker +Date: Tue Feb 24 12:30:59 2015 +1100 + + Convert two macros into functions. + + Convert packet_send_debug and packet_disconnect from macros to + functions. Some older GCCs (2.7.x, 2.95.x) see to have problems with + variadic macros with only one argument so we convert these two into + functions. ok djm@ + +commit 2285c30d51b7e2052c6526445abe7e7cc7e170a1 +Author: djm@openbsd.org +Date: Mon Feb 23 22:21:21 2015 +0000 + + upstream commit + + further silence spurious error message even when -v is + specified (e.g. to get visual host keys); reported by naddy@ + +commit 9af21979c00652029e160295e988dea40758ece2 +Author: Damien Miller +Date: Tue Feb 24 09:04:32 2015 +1100 + + don't include stdint.h unless HAVE_STDINT_H set + +commit 62f678dd51660d6f8aee1da33d3222c5de10a89e +Author: Damien Miller +Date: Tue Feb 24 09:02:54 2015 +1100 + + nother sys/queue.h -> sys-queue.h fix + + spotted by Tom Christensen + +commit b3c19151cba2c0ed01b27f55de0d723ad07ca98f +Author: djm@openbsd.org +Date: Mon Feb 23 20:32:15 2015 +0000 + + upstream commit + + fix a race condition by using a mux socket rather than an + ineffectual wait statement + +commit a88dd1da119052870bb2654c1a32c51971eade16 +Author: Damien Miller +Date: Tue Feb 24 06:30:29 2015 +1100 + + various include fixes for portable + +commit 5248429b5ec524d0a65507cff0cdd6e0cb99effd +Author: djm@openbsd.org +Date: Mon Feb 23 16:55:51 2015 +0000 + + upstream commit + + add an XXX to remind me to improve sshkey_load_public + +commit e94e4b07ef2eaead38b085a60535df9981cdbcdb +Author: djm@openbsd.org +Date: Mon Feb 23 16:55:31 2015 +0000 + + upstream commit + + silence a spurious error message when listing + fingerprints for known_hosts; bz#2342 + +commit f2293a65392b54ac721f66bc0b44462e8d1d81f8 +Author: djm@openbsd.org +Date: Mon Feb 23 16:33:25 2015 +0000 + + upstream commit + + fix setting/clearing of TTY raw mode around + UpdateHostKeys=ask confirmation question; reported by Herb Goldman + +commit f2004cd1adf34492eae0a44b1ef84e0e31b06088 +Author: Darren Tucker +Date: Mon Feb 23 05:04:21 2015 +1100 + + Repair for non-ECC OpenSSL. + + Ifdef out the ECC parts when building with an OpenSSL that doesn't have + it. + +commit 37f9220db8d1a52c75894c3de1e5f2ae5bd71b6f +Author: Darren Tucker +Date: Mon Feb 23 03:07:24 2015 +1100 + + Wrap stdint.h includes in ifdefs. + +commit f81f1bbc5b892c8614ea740b1f92735652eb43f0 +Author: Tim Rice +Date: Sat Feb 21 18:12:10 2015 -0800 + + out of tree build fix + +commit 2e13a1e4d22f3b503c3bfc878562cc7386a1d1ae +Author: Tim Rice +Date: Sat Feb 21 18:08:51 2015 -0800 + + mkdir kex unit test directory so testing out of tree builds works + +commit 1797f49b1ba31e8700231cd6b1d512d80bb50d2c +Author: halex@openbsd.org +Date: Sat Feb 21 21:46:57 2015 +0000 + + upstream commit + + make "ssh-add -d" properly remove a corresponding + certificate, and also not whine and fail if there is none + + ok djm@ + +commit 7faaa32da83a609059d95dbfcb0649fdb04caaf6 +Author: Damien Miller +Date: Sun Feb 22 07:57:27 2015 +1100 + + mkdir hostkey and bitmap unit test directories + +commit bd49da2ef197efac5e38f5399263a8b47990c538 +Author: djm@openbsd.org +Date: Fri Feb 20 23:46:01 2015 +0000 + + upstream commit + + sort options useable under Match case-insensitively; prodded + jmc@ + +commit 1a779a0dd6cd8b4a1a40ea33b5415ab8408128ac +Author: djm@openbsd.org +Date: Sat Feb 21 20:51:02 2015 +0000 + + upstream commit + + correct paths to configuration files being written/updated; + they live in $OBJ not cwd; some by Roumen Petrov + +commit 28ba006c1acddff992ae946d0bc0b500b531ba6b +Author: Darren Tucker +Date: Sat Feb 21 15:41:07 2015 +1100 + + More correct checking of HAVE_DECL_AI_NUMERICSERV. + +commit e50e8c97a9cecae1f28febccaa6ca5ab3bc10f54 +Author: Darren Tucker +Date: Sat Feb 21 15:10:33 2015 +1100 + + Add null declaration of AI_NUMERICINFO. + + Some platforms (older FreeBSD and DragonFly versions) do have + getaddrinfo() but do not have AI_NUMERICINFO. so define it to zero + in those cases. + +commit 18a208d6a460d707a45916db63a571e805f5db46 +Author: djm@openbsd.org +Date: Fri Feb 20 22:40:32 2015 +0000 + + upstream commit + + more options that are available under Match; bz#2353 reported + by calestyo AT scientia.net + +commit 44732de06884238049f285f1455b2181baa7dc82 +Author: djm@openbsd.org +Date: Fri Feb 20 22:17:21 2015 +0000 + + upstream commit + + UpdateHostKeys fixes: + + I accidentally changed the format of the hostkeys@openssh.com messages + last week without changing the extension name, and this has been causing + connection failures for people who are running -current. First reported + by sthen@ + + s/hostkeys@openssh.com/hostkeys-00@openssh.com/ + Change the name of the proof message too, and reorder it a little. + + Also, UpdateHostKeys=ask is incompatible with ControlPersist (no TTY + available to read the response) so disable UpdateHostKeys if it is in + ask mode and ControlPersist is active (and document this) + +commit 13a39414d25646f93e6d355521d832a03aaaffe2 +Author: djm@openbsd.org +Date: Tue Feb 17 00:14:05 2015 +0000 + + upstream commit + + Regression: I broke logging of public key fingerprints in + 1.46. Pointed out by Pontus Lundkvist + +commit 773dda25e828c4c9a52f7bdce6e1e5924157beab +Author: Damien Miller +Date: Fri Jan 30 23:10:17 2015 +1100 + + repair --without-openssl; broken in refactor + +commit e89c780886b23600de1e1c8d74aabd1ff61f43f0 +Author: Damien Miller +Date: Tue Feb 17 10:04:55 2015 +1100 + + hook up hostkeys unittest to portable Makefiles + +commit 0abf41f99aa16ff09b263bead242d6cb2dbbcf99 +Author: djm@openbsd.org +Date: Mon Feb 16 22:21:03 2015 +0000 + + upstream commit + + enable hostkeys unit tests + +commit 68a5d647ccf0fb6782b2f749433a1eee5bc9044b +Author: djm@openbsd.org +Date: Mon Feb 16 22:20:50 2015 +0000 + + upstream commit + + check string/memory compare arguments aren't NULL + +commit ef575ef20d09f20722e26b45dab80b3620469687 +Author: djm@openbsd.org +Date: Mon Feb 16 22:18:34 2015 +0000 + + upstream commit + + unit tests for hostfile.c code, just hostkeys_foreach so + far + +commit 8ea3365e6aa2759ccf5c76eaea62cbc8a280b0e7 +Author: markus@openbsd.org +Date: Sat Feb 14 12:43:16 2015 +0000 + + upstream commit + + test server rekey limit + +commit ce63c4b063c39b2b22d4ada449c9e3fbde788cb3 +Author: djm@openbsd.org +Date: Mon Feb 16 22:30:03 2015 +0000 + + upstream commit + + partial backout of: + + revision 1.441 + date: 2015/01/31 20:30:05; author: djm; state: Exp; lines: +17 -10; commitid + : x8klYPZMJSrVlt3O; + Let sshd load public host keys even when private keys are missing. + Allows sshd to advertise additional keys for future key rotation. + Also log fingerprint of hostkeys loaded; ok markus@ + + hostkey updates now require access to the private key, so we can't + load public keys only. The improved log messages (fingerprints of keys + loaded) are kept. + +commit 523463a3a2a9bfc6cfc5afa01bae9147f76a37cc +Author: djm@openbsd.org +Date: Mon Feb 16 22:13:32 2015 +0000 + + upstream commit + + Revise hostkeys@openssh.com hostkey learning extension. + + The client will not ask the server to prove ownership of the private + halves of any hitherto-unseen hostkeys it offers to the client. + + Allow UpdateHostKeys option to take an 'ask' argument to let the + user manually review keys offered. + + ok markus@ + +commit 6c5c949782d86a6e7d58006599c7685bfcd01685 +Author: djm@openbsd.org +Date: Mon Feb 16 22:08:57 2015 +0000 + + upstream commit + + Refactor hostkeys_foreach() and dependent code Deal with + IP addresses (i.e. CheckHostIP) Don't clobber known_hosts when nothing + changed ok markus@ as part of larger commit + +commit 51b082ccbe633dc970df1d1f4c9c0497115fe721 +Author: miod@openbsd.org +Date: Mon Feb 16 18:26:26 2015 +0000 + + upstream commit + + Declare ge25519_base as extern, to prevent it from + becoming a common. Gets us rid of ``lignment 4 of symbol + `crypto_sign_ed25519_ref_ge25519_base' in mod_ge25519.o is smaller than 16 in + mod_ed25519.o'' warnings at link time. + +commit 02db468bf7e3281a8e3c058ced571b38b6407c34 +Author: markus@openbsd.org +Date: Fri Feb 13 18:57:00 2015 +0000 + + upstream commit + + make rekey_limit for sshd w/privsep work; ok djm@ + dtucker@ + +commit 8ec67d505bd23c8bf9e17b7a364b563a07a58ec8 +Author: dtucker@openbsd.org +Date: Thu Feb 12 20:34:19 2015 +0000 + + upstream commit + + Prevent sshd spamming syslog with + "ssh_dispatch_run_fatal: disconnected". ok markus@ + +commit d4c0295d1afc342057ba358237acad6be8af480b +Author: djm@openbsd.org +Date: Wed Feb 11 01:20:38 2015 +0000 + + upstream commit + + Some packet error messages show the address of the peer, + but might be generated after the socket to the peer has suffered a TCP reset. + In these cases, getpeername() won't work so cache the address earlier. + + spotted in the wild via deraadt@ and tedu@ + +commit 4af1709cf774475ce5d1bc3ddcc165f6c222897d +Author: jsg@openbsd.org +Date: Mon Feb 9 23:22:37 2015 +0000 + + upstream commit + + fix some leaks in error paths ok markus@ + +commit fd36834871d06a03e1ff8d69e41992efa1bbf85f +Author: millert@openbsd.org +Date: Fri Feb 6 23:21:59 2015 +0000 + + upstream commit + + SIZE_MAX is standard, we should be using it in preference to + the obsolete SIZE_T_MAX. OK miod@ beck@ + +commit 1910a286d7771eab84c0b047f31c0a17505236fa +Author: millert@openbsd.org +Date: Thu Feb 5 12:59:57 2015 +0000 + + upstream commit + + Include stdint.h, not limits.h to get SIZE_MAX. OK guenther@ + +commit ce4f59b2405845584f45e0b3214760eb0008c06c +Author: deraadt@openbsd.org +Date: Tue Feb 3 08:07:20 2015 +0000 + + upstream commit + + missing ; djm and mlarkin really having great + interactions recently + +commit 5d34aa94938abb12b877a25be51862757f25d54b +Author: halex@openbsd.org +Date: Tue Feb 3 00:34:14 2015 +0000 + + upstream commit + + slightly extend the passphrase prompt if running with -c + in order to give the user a chance to notice if unintentionally running + without it + + wording tweak and ok djm@ + +commit cb3bde373e80902c7d5d0db429f85068d19b2918 +Author: djm@openbsd.org +Date: Mon Feb 2 22:48:53 2015 +0000 + + upstream commit + + handle PKCS#11 C_Login returning + CKR_USER_ALREADY_LOGGED_IN; based on patch from Yuri Samoilenko; ok markus@ + +commit 15ad750e5ec3cc69765b7eba1ce90060e7083399 +Author: djm@openbsd.org +Date: Mon Feb 2 07:41:40 2015 +0000 + + upstream commit + + turn UpdateHostkeys off by default until I figure out + mlarkin@'s warning message; requested by deraadt@ + +commit 3cd5103c1e1aaa59bd66f7f52f6ebbcd5deb12f9 +Author: deraadt@openbsd.org +Date: Mon Feb 2 01:57:44 2015 +0000 + + upstream commit + + increasing encounters with difficult DNS setups in + darknets has convinced me UseDNS off by default is better ok djm + +commit 6049a548a8a68ff0bbe581ab1748ea6a59ecdc38 +Author: djm@openbsd.org +Date: Sat Jan 31 20:30:05 2015 +0000 + + upstream commit + + Let sshd load public host keys even when private keys are + missing. Allows sshd to advertise additional keys for future key rotation. + Also log fingerprint of hostkeys loaded; ok markus@ + +commit 46347ed5968f582661e8a70a45f448e0179ca0ab +Author: djm@openbsd.org +Date: Fri Jan 30 11:43:14 2015 +0000 + + upstream commit + + Add a ssh_config HostbasedKeyType option to control which + host public key types are tried during hostbased authentication. + + This may be used to prevent too many keys being sent to the server, + and blowing past its MaxAuthTries limit. + + bz#2211 based on patch by Iain Morgan; ok markus@ + +commit 802660cb70453fa4d230cb0233bc1bbdf8328de1 +Author: djm@openbsd.org +Date: Fri Jan 30 10:44:49 2015 +0000 + + upstream commit + + set a timeout to prevent hangs when talking to busted + servers; ok markus@ + +commit 86936ec245a15c7abe71a0722610998b0a28b194 +Author: djm@openbsd.org +Date: Fri Jan 30 01:11:39 2015 +0000 + + upstream commit + + regression test for 'wildcard CA' serial/key ID revocations + +commit 4509b5d4a4fa645a022635bfa7e86d09b285001f +Author: djm@openbsd.org +Date: Fri Jan 30 01:13:33 2015 +0000 + + upstream commit + + avoid more fatal/exit in the packet.c paths that + ssh-keyscan uses; feedback and "looks good" markus@ + +commit 669aee994348468af8b4b2ebd29b602cf2860b22 +Author: djm@openbsd.org +Date: Fri Jan 30 01:10:33 2015 +0000 + + upstream commit + + permit KRLs that revoke certificates by serial number or + key ID without scoping to a particular CA; ok markus@ + +commit 7a2c368477e26575d0866247d3313da4256cb2b5 +Author: djm@openbsd.org +Date: Fri Jan 30 00:59:19 2015 +0000 + + upstream commit + + missing parentheses after if in do_convert_from() broke + private key conversion from other formats some time in 2010; bz#2345 reported + by jjelen AT redhat.com + +commit 25f5f78d8bf5c22d9cea8b49de24ebeee648a355 +Author: djm@openbsd.org +Date: Fri Jan 30 00:22:25 2015 +0000 + + upstream commit + + fix ssh protocol 1, spotted by miod@ + +commit 9ce86c926dfa6e0635161b035e3944e611cbccf0 +Author: djm@openbsd.org +Date: Wed Jan 28 22:36:00 2015 +0000 + + upstream commit + + update to new API (key_fingerprint => sshkey_fingerprint) + check sshkey_fingerprint return values; ok markus + +commit 9125525c37bf73ad3ee4025520889d2ce9d10f29 +Author: djm@openbsd.org +Date: Wed Jan 28 22:05:31 2015 +0000 + + upstream commit + + avoid fatal() calls in packet code makes ssh-keyscan more + reliable against server failures ok dtucker@ markus@ + +commit fae7bbe544cba7a9e5e4ab47ff6faa3d978646eb +Author: djm@openbsd.org +Date: Wed Jan 28 21:15:47 2015 +0000 + + upstream commit + + avoid fatal() calls in packet code makes ssh-keyscan more + reliable against server failures ok dtucker@ markus@ + +commit 1a3d14f6b44a494037c7deab485abe6496bf2c60 +Author: djm@openbsd.org +Date: Wed Jan 28 11:07:25 2015 +0000 + + upstream commit + + remove obsolete comment + +commit 80c25b7bc0a71d75c43a4575d9a1336f589eb639 +Author: okan@openbsd.org +Date: Tue Jan 27 12:54:06 2015 +0000 + + upstream commit + + Since r1.2 removed the use of PRI* macros, inttypes.h is + no longer required. + + ok djm@ + +commit 69ff64f69615c2a21c97cb5878a0996c21423257 +Author: Damien Miller +Date: Tue Jan 27 23:07:43 2015 +1100 + + compile on systems without TCP_MD5SIG (e.g. OSX) + +commit 358964f3082fb90b2ae15bcab07b6105cfad5a43 +Author: Damien Miller +Date: Tue Jan 27 23:07:25 2015 +1100 + + use ssh-keygen under test rather than system's + +commit a2c95c1bf33ea53038324d1fdd774bc953f98236 +Author: Damien Miller +Date: Tue Jan 27 23:06:59 2015 +1100 + + OSX lacks HOST_NAME_MAX, has _POSIX_HOST_NAME_MAX + +commit ade31d7b6f608a19b85bee29a7a00b1e636a2919 +Author: Damien Miller +Date: Tue Jan 27 23:06:23 2015 +1100 + + these need active_state defined to link on OSX + + temporary measure until active_state goes away entirely + +commit e56aa87502f22c5844918c10190e8b4f785f067b +Author: djm@openbsd.org +Date: Tue Jan 27 12:01:36 2015 +0000 + + upstream commit + + use printf instead of echo -n to reduce diff against + -portable + +commit 9f7637f56eddfaf62ce3c0af89c25480f2cf1068 +Author: jmc@openbsd.org +Date: Mon Jan 26 13:55:29 2015 +0000 + + upstream commit + + sort previous; + +commit 3076ee7d530d5b16842fac7a6229706c7e5acd26 +Author: djm@openbsd.org +Date: Mon Jan 26 13:36:53 2015 +0000 + + upstream commit + + properly restore umask + +commit d411d395556b73ba1b9e451516a0bd6697c4b03d +Author: djm@openbsd.org +Date: Mon Jan 26 06:12:18 2015 +0000 + + upstream commit + + regression test for host key rotation + +commit fe8a3a51699afbc6407a8fae59b73349d01e49f8 +Author: djm@openbsd.org +Date: Mon Jan 26 06:11:28 2015 +0000 + + upstream commit + + adapt to sshkey API tweaks + +commit 7dd355fb1f0038a3d5cdca57ebab4356c7a5b434 +Author: miod@openbsd.org +Date: Sat Jan 24 10:39:21 2015 +0000 + + upstream commit + + Move -lz late in the linker commandline for things to + build on static arches. + +commit 0dad3b806fddb93c475b30853b9be1a25d673a33 +Author: miod@openbsd.org +Date: Fri Jan 23 21:21:23 2015 +0000 + + upstream commit + + -Wpointer-sign is supported by gcc 4 only. + +commit 2b3b1c1e4bd9577b6e780c255c278542ea66c098 +Author: djm@openbsd.org +Date: Tue Jan 20 22:58:57 2015 +0000 + + upstream commit + + use SUBDIR to recuse into unit tests; makes "make obj" + actually work + +commit 1d1092bff8db27080155541212b420703f8b9c92 +Author: djm@openbsd.org +Date: Mon Jan 26 12:16:36 2015 +0000 + + upstream commit + + correct description of UpdateHostKeys in ssh_config.5 and + add it to -o lists for ssh, scp and sftp; pointed out by jmc@ + +commit 5104db7cbd6cdd9c5971f4358e74414862fc1022 +Author: djm@openbsd.org +Date: Mon Jan 26 06:10:03 2015 +0000 + + upstream commit + + correctly match ECDSA subtype (== curve) for + offered/recevied host keys. Fixes connection-killing host key mismatches when + a server offers multiple ECDSA keys with different curve type (an extremely + unlikely configuration). + + ok markus, "looks mechanical" deraadt@ + +commit 8d4f87258f31cb6def9b3b55b6a7321d84728ff2 +Author: djm@openbsd.org +Date: Mon Jan 26 03:04:45 2015 +0000 + + upstream commit + + Host key rotation support. + + Add a hostkeys@openssh.com protocol extension (global request) for + a server to inform a client of all its available host key after + authentication has completed. The client may record the keys in + known_hosts, allowing it to upgrade to better host key algorithms + and a server to gracefully rotate its keys. + + The client side of this is controlled by a UpdateHostkeys config + option (default on). + + ok markus@ + +commit 60b1825262b1f1e24fc72050b907189c92daf18e +Author: djm@openbsd.org +Date: Mon Jan 26 02:59:11 2015 +0000 + + upstream commit + + small refactor and add some convenience functions; ok + markus + +commit a5a3e3328ddce91e76f71ff479022d53e35c60c9 +Author: jmc@openbsd.org +Date: Thu Jan 22 21:00:42 2015 +0000 + + upstream commit + + heirarchy -> hierarchy; + +commit dcff5810a11195c57e1b3343c0d6b6f2b9974c11 +Author: deraadt@openbsd.org +Date: Thu Jan 22 20:24:41 2015 +0000 + + upstream commit + + Provide a warning about chroot misuses (which sadly, seem + to have become quite popular because shiny). sshd cannot detect/manage/do + anything about these cases, best we can do is warn in the right spot in the + man page. ok markus + +commit 087266ec33c76fc8d54ac5a19efacf2f4a4ca076 +Author: deraadt@openbsd.org +Date: Tue Jan 20 23:14:00 2015 +0000 + + upstream commit + + Reduce use of and transition to + throughout. ok djm markus + +commit 57e783c8ba2c0797f93977e83b2a8644a03065d8 +Author: markus@openbsd.org +Date: Tue Jan 20 20:16:21 2015 +0000 + + upstream commit + + kex_setup errors are fatal() + +commit 1d6424a6ff94633c221297ae8f42d54e12a20912 +Author: djm@openbsd.org +Date: Tue Jan 20 08:02:33 2015 +0000 + + upstream commit + + this test would accidentally delete agent.sh if run without + obj/ + +commit 12b5f50777203e12575f1b08568281e447249ed3 +Author: djm@openbsd.org +Date: Tue Jan 20 07:56:44 2015 +0000 + + upstream commit + + make this compile with KERBEROS5 enabled + +commit e2cc6bef08941256817d44d146115b3478586ad4 +Author: djm@openbsd.org +Date: Tue Jan 20 07:55:33 2015 +0000 + + upstream commit + + fix hostkeys in agent; ok markus@ + +commit 1ca3e2155aa5d3801a7ae050f85c71f41fcb95b1 +Author: Damien Miller +Date: Tue Jan 20 10:11:31 2015 +1100 + + fix kex test + +commit c78a578107c7e6dcf5d30a2f34cb6581bef14029 +Author: markus@openbsd.org +Date: Mon Jan 19 20:45:25 2015 +0000 + + upstream commit + + finally enable the KEX tests I wrote some years ago... + +commit 31821d7217e686667d04935aeec99e1fc4a46e7e +Author: markus@openbsd.org +Date: Mon Jan 19 20:42:31 2015 +0000 + + upstream commit + + adapt to new error message (SSH_ERR_MAC_INVALID) + +commit d3716ca19e510e95d956ae14d5b367e364bff7f1 +Author: djm@openbsd.org +Date: Mon Jan 19 17:31:13 2015 +0000 + + upstream commit + + this test was broken in at least two ways, such that it + wasn't checking that a KRL was not excluding valid keys + +commit 3f797653748e7c2b037dacb57574c01d9ef3b4d3 +Author: markus@openbsd.org +Date: Mon Jan 19 20:32:39 2015 +0000 + + upstream commit + + switch ssh-keyscan from setjmp to multiple ssh transport + layer instances ok djm@ + +commit f582f0e917bb0017b00944783cd5f408bf4b0b5e +Author: markus@openbsd.org +Date: Mon Jan 19 20:30:23 2015 +0000 + + upstream commit + + add experimental api for packet layer; ok djm@ + +commit 48b3b2ba75181f11fca7f327058a591f4426cade +Author: markus@openbsd.org +Date: Mon Jan 19 20:20:20 2015 +0000 + + upstream commit + + store compat flags in struct ssh; ok djm@ + +commit 57d10cbe861a235dd269c74fb2fe248469ecee9d +Author: markus@openbsd.org +Date: Mon Jan 19 20:16:15 2015 +0000 + + upstream commit + + adapt kex to sshbuf and struct ssh; ok djm@ + +commit 3fdc88a0def4f86aa88a5846ac079dc964c0546a +Author: markus@openbsd.org +Date: Mon Jan 19 20:07:45 2015 +0000 + + upstream commit + + move dispatch to struct ssh; ok djm@ + +commit 091c302829210c41e7f57c3f094c7b9c054306f0 +Author: markus@openbsd.org +Date: Mon Jan 19 19:52:16 2015 +0000 + + upstream commit + + update packet.c & isolate, introduce struct ssh a) switch + packet.c to buffer api and isolate per-connection info into struct ssh b) + (de)serialization of the state is moved from monitor to packet.c c) the old + packet.c API is implemented in opacket.[ch] d) compress.c/h is removed and + integrated into packet.c with and ok djm@ + +commit 4e62cc68ce4ba20245d208b252e74e91d3785b74 +Author: djm@openbsd.org +Date: Mon Jan 19 17:35:48 2015 +0000 + + upstream commit + + fix format strings in (disabled) debugging + +commit d85e06245907d49a2cd0cfa0abf59150ad616f42 +Author: djm@openbsd.org +Date: Mon Jan 19 06:01:32 2015 +0000 + + upstream commit + + be a bit more careful in these tests to ensure that + known_hosts is clean + +commit 7947810eab5fe0ad311f32a48f4d4eb1f71be6cf +Author: djm@openbsd.org +Date: Sun Jan 18 22:00:18 2015 +0000 + + upstream commit + + regression test for known_host file editing using + ssh-keygen (-H / -R / -F) after hostkeys_foreach() change; feedback and ok + markus@ + +commit 3a2b09d147a565d8a47edf37491e149a02c0d3a3 +Author: djm@openbsd.org +Date: Sun Jan 18 19:54:46 2015 +0000 + + upstream commit + + more and better key tests + + test signatures and verification + test certificate generation + flesh out nested cert test + + removes most of the XXX todo markers + +commit 589e69fd82724cfc9738f128e4771da2e6405d0d +Author: djm@openbsd.org +Date: Sun Jan 18 19:53:58 2015 +0000 + + upstream commit + + make the signature fuzzing test much more rigorous: + ensure that the fuzzed input cases do not match the original (using new + fuzz_matches_original() function) and check that the verification fails in + each case + +commit 80603c0daa2538c349c1c152405580b164d5475f +Author: djm@openbsd.org +Date: Sun Jan 18 19:52:44 2015 +0000 + + upstream commit + + add a fuzz_matches_original() function to the fuzzer to + detect fuzz cases that are identical to the original data. Hacky + implementation, but very useful when you need the fuzz to be different, e.g. + when verifying signature + +commit 87d5495bd337e358ad69c524fcb9495208c0750b +Author: djm@openbsd.org +Date: Sun Jan 18 19:50:55 2015 +0000 + + upstream commit + + better dumps from the fuzzer (shown on errors) - + include the original data as well as the fuzzed copy. + +commit d59ec478c453a3fff05badbbfd96aa856364f2c2 +Author: djm@openbsd.org +Date: Sun Jan 18 19:47:55 2015 +0000 + + upstream commit + + enable hostkey-agent.sh test + +commit 26b3425170bf840e4b095e1c10bf25a0a3e3a105 +Author: djm@openbsd.org +Date: Sat Jan 17 18:54:30 2015 +0000 + + upstream commit + + unit test for hostkeys in ssh-agent + +commit 9e06a0fb23ec55d9223b26a45bb63c7649e2f2f2 +Author: markus@openbsd.org +Date: Thu Jan 15 23:41:29 2015 +0000 + + upstream commit + + add kex unit tests + +commit d2099dec6da21ae627f6289aedae6bc1d41a22ce +Author: deraadt@openbsd.org +Date: Mon Jan 19 00:32:54 2015 +0000 + + upstream commit + + djm, your /usr/include tree is old + +commit 2b3c3c76c30dc5076fe09d590f5b26880f148a54 +Author: djm@openbsd.org +Date: Sun Jan 18 21:51:19 2015 +0000 + + upstream commit + + some feedback from markus@: comment hostkeys_foreach() + context and avoid a member in it. + +commit cecb30bc2ba6d594366e657d664d5c494b6c8a7f +Author: djm@openbsd.org +Date: Sun Jan 18 21:49:42 2015 +0000 + + upstream commit + + make ssh-keygen use hostkeys_foreach(). Removes some + horrendous code; ok markus@ + +commit ec3d065df3a9557ea96b02d061fd821a18c1a0b9 +Author: djm@openbsd.org +Date: Sun Jan 18 21:48:09 2015 +0000 + + upstream commit + + convert load_hostkeys() (hostkey ordering and + known_host matching) to use the new hostkey_foreach() iterator; ok markus + +commit c29811cc480a260e42fd88849fc86a80c1e91038 +Author: djm@openbsd.org +Date: Sun Jan 18 21:40:23 2015 +0000 + + upstream commit + + introduce hostkeys_foreach() to allow iteration over a + known_hosts file or controlled subset thereof. This will allow us to pull out + some ugly and duplicated code, and will be used to implement hostkey rotation + later. + + feedback and ok markus + +commit f101d8291da01bbbfd6fb8c569cfd0cc61c0d346 +Author: deraadt@openbsd.org +Date: Sun Jan 18 14:01:00 2015 +0000 + + upstream commit + + string truncation due to sizeof(size) ok djm markus + +commit 35d6022b55b7969fc10c261cb6aa78cc4a5fcc41 +Author: djm@openbsd.org +Date: Sun Jan 18 13:33:34 2015 +0000 + + upstream commit + + avoid trailing ',' in host key algorithms + +commit 7efb455789a0cb76bdcdee91c6060a3dc8f5c007 +Author: djm@openbsd.org +Date: Sun Jan 18 13:22:28 2015 +0000 + + upstream commit + + infer key length correctly when user specified a fully- + qualified key name instead of using the -b bits option; ok markus@ + +commit 83f8ffa6a55ccd0ce9d8a205e3e7439ec18fedf5 +Author: djm@openbsd.org +Date: Sat Jan 17 18:53:34 2015 +0000 + + upstream commit + + fix hostkeys on ssh agent; found by unit test I'm about + to commit + +commit 369d61f17657b814124268f99c033e4dc6e436c1 +Author: schwarze@openbsd.org +Date: Fri Jan 16 16:20:23 2015 +0000 + + upstream commit + + garbage collect empty .No macros mandoc warns about + +commit bb8b442d32dbdb8521d610e10d8b248d938bd747 +Author: djm@openbsd.org +Date: Fri Jan 16 15:55:07 2015 +0000 + + upstream commit + + regression: incorrect error message on + otherwise-successful ssh-keygen -A. Reported by Dmitry Orlov, via deraadt@ + +commit 9010902954a40b59d0bf3df3ccbc3140a653e2bc +Author: djm@openbsd.org +Date: Fri Jan 16 07:19:48 2015 +0000 + + upstream commit + + when hostname canonicalisation is enabled, try to parse + hostnames as addresses before looking them up for canonicalisation. fixes + bz#2074 and avoids needless DNS lookups in some cases; ok markus + +commit 2ae4f337b2a5fb2841b6b0053b49496fef844d1c +Author: deraadt@openbsd.org +Date: Fri Jan 16 06:40:12 2015 +0000 + + upstream commit + + Replace with and other less + dirty headers where possible. Annotate lines with their + current reasons. Switch to PATH_MAX, NGROUPS_MAX, HOST_NAME_MAX+1, + LOGIN_NAME_MAX, etc. Change MIN() and MAX() to local definitions of + MINIMUM() and MAXIMUM() where sensible to avoid pulling in the pollution. + These are the files confirmed through binary verification. ok guenther, + millert, doug (helped with the verification protocol) + +commit 3c4726f4c24118e8f1bb80bf75f1456c76df072c +Author: markus@openbsd.org +Date: Thu Jan 15 21:38:50 2015 +0000 + + upstream commit + + remove xmalloc, switch to sshbuf + +commit e17ac01f8b763e4b83976b9e521e90a280acc097 +Author: markus@openbsd.org +Date: Thu Jan 15 21:37:14 2015 +0000 + + upstream commit + + switch to sshbuf + +commit ddef9995a1fa6c7a8ff3b38bfe6cf724bebf13d0 +Author: naddy@openbsd.org +Date: Thu Jan 15 18:32:54 2015 +0000 + + upstream commit + + handle UMAC128 initialization like UMAC; ok djm@ markus@ + +commit f14564c1f7792446bca143580aef0e7ac25dcdae +Author: djm@openbsd.org +Date: Thu Jan 15 11:04:36 2015 +0000 + + upstream commit + + fix regression reported by brad@ for passworded keys without + agent present + +commit 45c0fd70bb2a88061319dfff20cb12ef7b1bc47e +Author: Damien Miller +Date: Thu Jan 15 22:08:23 2015 +1100 + + make bitmap test compile + +commit d333f89abf7179021e5c3f28673f469abe032062 +Author: djm@openbsd.org +Date: Thu Jan 15 07:36:28 2015 +0000 + + upstream commit + + unit tests for KRL bitmap + +commit 7613f828f49c55ff356007ae9645038ab6682556 +Author: markus@openbsd.org +Date: Wed Jan 14 09:58:21 2015 +0000 + + upstream commit + + re-add comment about full path + +commit 6c43b48b307c41cd656b415621a644074579a578 +Author: markus@openbsd.org +Date: Wed Jan 14 09:54:38 2015 +0000 + + upstream commit + + don't reset to the installed sshd; connect before + reconfigure, too + +commit 771bb47a1df8b69061f09462e78aa0b66cd594bf +Author: djm@openbsd.org +Date: Tue Jan 13 14:51:51 2015 +0000 + + upstream commit + + implement a SIGINFO handler so we can discern a stuck + fuzz test from a merely glacial one; prompted by and ok markus + +commit cfaa57962f8536f3cf0fd7daf4d6a55d6f6de45f +Author: djm@openbsd.org +Date: Tue Jan 13 08:23:26 2015 +0000 + + upstream commit + + use $SSH instead of installed ssh to allow override; + spotted by markus@ + +commit 0920553d0aee117a596b03ed5b49b280d34a32c5 +Author: djm@openbsd.org +Date: Tue Jan 13 07:49:49 2015 +0000 + + upstream commit + + regress test for PubkeyAcceptedKeyTypes; ok markus@ + +commit 27ca1a5c0095eda151934bca39a77e391f875d17 +Author: markus@openbsd.org +Date: Mon Jan 12 20:13:27 2015 +0000 + + upstream commit + + unbreak parsing of pubkey comments; with gerhard; ok + djm/deraadt + +commit 55358f0b4e0b83bc0df81c5f854c91b11e0bb4dc +Author: djm@openbsd.org +Date: Mon Jan 12 11:46:32 2015 +0000 + + upstream commit + + fatal if soft-PKCS11 library is missing rather (rather + than continue and fail with a more cryptic error) + +commit c3554cdd2a1a62434b8161017aa76fa09718a003 +Author: djm@openbsd.org +Date: Mon Jan 12 11:12:38 2015 +0000 + + upstream commit + + let this test all supporte key types; pointed out/ok + markus@ + +commit 1129dcfc5a3e508635004bcc05a3574cb7687167 +Author: djm@openbsd.org +Date: Thu Jan 15 09:40:00 2015 +0000 + + upstream commit + + sync ssh-keysign, ssh-keygen and some dependencies to the + new buffer/key API; mostly mechanical, ok markus@ + +commit e4ebf5586452bf512da662ac277aaf6ecf0efe7c +Author: djm@openbsd.org +Date: Thu Jan 15 07:57:08 2015 +0000 + + upstream commit + + remove commented-out test code now that it has moved to a + proper unit test + +commit e81cba066c1e9eb70aba0f6e7c0ff220611b370f +Author: djm@openbsd.org +Date: Wed Jan 14 20:54:29 2015 +0000 + + upstream commit + + whitespace + +commit 141efe49542f7156cdbc2e4cd0a041d8b1aab622 +Author: djm@openbsd.org +Date: Wed Jan 14 20:05:27 2015 +0000 + + upstream commit + + move authfd.c and its tentacles to the new buffer/key + API; ok markus@ + +commit 0088c57af302cda278bd26d8c3ae81d5b6f7c289 +Author: djm@openbsd.org +Date: Wed Jan 14 19:33:41 2015 +0000 + + upstream commit + + fix small regression: ssh-agent would return a success + message but an empty signature if asked to sign using an unknown key; ok + markus@ + +commit b03ebe2c22b8166e4f64c37737f4278676e3488d +Author: Damien Miller +Date: Thu Jan 15 03:08:58 2015 +1100 + + more --without-openssl + + fix some regressions caused by upstream merges + + enable KRLs now that they no longer require BIGNUMs + +commit bc42cc6fe784f36df225c44c93b74830027cb5a2 +Author: Damien Miller +Date: Thu Jan 15 03:08:29 2015 +1100 + + kludge around tun API mismatch betterer + +commit c332110291089b624fa0951fbf2d1ee6de525b9f +Author: Damien Miller +Date: Thu Jan 15 02:59:51 2015 +1100 + + some systems lack SO_REUSEPORT + +commit 83b9678a62cbdc74eb2031cf1e1e4ffd58e233ae +Author: Damien Miller +Date: Thu Jan 15 02:35:50 2015 +1100 + + fix merge botch + +commit 0cdc5a3eb6fb383569a4da2a30705d9b90428d6b +Author: Damien Miller +Date: Thu Jan 15 02:35:33 2015 +1100 + + unbreak across API change + +commit 6e2549ac2b5e7f96cbc2d83a6e0784b120444b47 +Author: Damien Miller +Date: Thu Jan 15 02:30:18 2015 +1100 + + need includes.h for portable OpenSSH + +commit 72ef7c148c42db7d5632a29f137f8b87b579f2d9 +Author: Damien Miller +Date: Thu Jan 15 02:21:31 2015 +1100 + + support --without-openssl at configure time + + Disables and removes dependency on OpenSSL. Many features don't + work and the set of crypto options is greatly restricted. This + will only work on system with native arc4random or /dev/urandom. + + Considered highly experimental for now. + +commit 4f38c61c68ae7e3f9ee4b3c38bc86cd39f65ece9 +Author: Damien Miller +Date: Thu Jan 15 02:28:00 2015 +1100 + + add files missed in last commit + +commit a165bab605f7be55940bb8fae977398e8c96a46d +Author: djm@openbsd.org +Date: Wed Jan 14 15:02:39 2015 +0000 + + upstream commit + + avoid BIGNUM in KRL code by using a simple bitmap; + feedback and ok markus + +commit 7d845f4a0b7ec97887be204c3760e44de8bf1f32 +Author: djm@openbsd.org +Date: Wed Jan 14 13:54:13 2015 +0000 + + upstream commit + + update sftp client and server to new buffer API. pretty + much just mechanical changes; with & ok markus + +commit 139ca81866ec1b219c717d17061e5e7ad1059e2a +Author: markus@openbsd.org +Date: Wed Jan 14 13:09:09 2015 +0000 + + upstream commit + + switch to sshbuf/sshkey; with & ok djm@ + +commit 81bfbd0bd35683de5d7f2238b985e5f8150a9180 +Author: Damien Miller +Date: Wed Jan 14 21:48:18 2015 +1100 + + support --without-openssl at configure time + + Disables and removes dependency on OpenSSL. Many features don't + work and the set of crypto options is greatly restricted. This + will only work on system with native arc4random or /dev/urandom. + + Considered highly experimental for now. + +commit 54924b53af15ccdcbb9f89984512b5efef641a31 +Author: djm@openbsd.org +Date: Wed Jan 14 10:46:28 2015 +0000 + + upstream commit + + avoid an warning for the !OPENSSL case + +commit ae8b463217f7c9b66655bfc3945c050ffdaeb861 +Author: markus@openbsd.org +Date: Wed Jan 14 10:30:34 2015 +0000 + + upstream commit + + swith auth-options to new sshbuf/sshkey; ok djm@ + +commit 540e891191b98b89ee90aacf5b14a4a68635e763 +Author: djm@openbsd.org +Date: Wed Jan 14 10:29:45 2015 +0000 + + upstream commit + + make non-OpenSSL aes-ctr work on sshd w/ privsep; ok + markus@ + +commit 60c2c4ea5e1ad0ddfe8b2877b78ed5143be79c53 +Author: markus@openbsd.org +Date: Wed Jan 14 10:24:42 2015 +0000 + + upstream commit + + remove unneeded includes, sync my copyright across files + & whitespace; ok djm@ + +commit 128343bcdb0b60fc826f2733df8cf979ec1627b4 +Author: markus@openbsd.org +Date: Tue Jan 13 19:31:40 2015 +0000 + + upstream commit + + adapt mac.c to ssherr.h return codes (de-fatal) and + simplify dependencies ok djm@ + +commit e7fd952f4ea01f09ceb068721a5431ac2fd416ed +Author: djm@openbsd.org +Date: Tue Jan 13 19:04:35 2015 +0000 + + upstream commit + + sync changes from libopenssh; prepared by markus@ mostly + debug output tweaks, a couple of error return value changes and some other + minor stuff + +commit 76c0480a85675f03a1376167cb686abed01a3583 +Author: Damien Miller +Date: Tue Jan 13 19:38:18 2015 +1100 + + add --without-ssh1 option to configure + + Allows disabling support for SSH protocol 1. + +commit 1f729f0614d1376c3332fa1edb6a5e5cec7e9e03 +Author: djm@openbsd.org +Date: Tue Jan 13 07:39:19 2015 +0000 + + upstream commit + + add sshd_config HostbasedAcceptedKeyTypes and + PubkeyAcceptedKeyTypes options to allow sshd to control what public key types + will be accepted. Currently defaults to all. Feedback & ok markus@ + +commit 816d1538c24209a93ba0560b27c4fda57c3fff65 +Author: markus@openbsd.org +Date: Mon Jan 12 20:13:27 2015 +0000 + + upstream commit + + unbreak parsing of pubkey comments; with gerhard; ok + djm/deraadt + +commit 0097565f849851812df610b7b6b3c4bd414f6c62 +Author: markus@openbsd.org +Date: Mon Jan 12 19:22:46 2015 +0000 + + upstream commit + + missing error assigment on sshbuf_put_string() + +commit a7f49dcb527dd17877fcb8d5c3a9a6f550e0bba5 +Author: djm@openbsd.org +Date: Mon Jan 12 15:18:07 2015 +0000 + + upstream commit + + apparently memcpy(x, NULL, 0) is undefined behaviour + according to C99 (cf. sections 7.21.1 and 7.1.4), so check skip memcpy calls + when length==0; ok markus@ + +commit 905fe30fca82f38213763616d0d26eb6790bde33 +Author: markus@openbsd.org +Date: Mon Jan 12 14:05:19 2015 +0000 + + upstream commit + + free->sshkey_free; ok djm@ + +commit f067cca2bc20c86b110174c3fef04086a7f57b13 +Author: markus@openbsd.org +Date: Mon Jan 12 13:29:27 2015 +0000 + + upstream commit + + allow WITH_OPENSSL w/o WITH_SSH1; ok djm@ + +commit c4bfafcc2a9300d9cfb3c15e75572d3a7d74670d +Author: djm@openbsd.org +Date: Thu Jan 8 13:10:58 2015 +0000 + + upstream commit + + adjust for sshkey_load_file() API change + +commit e752c6d547036c602b89e9e704851463bd160e32 +Author: djm@openbsd.org +Date: Thu Jan 8 13:44:36 2015 +0000 + + upstream commit + + fix ssh_config FingerprintHash evaluation order; from Petr + Lautrbach + +commit ab24ab847b0fc94c8d5e419feecff0bcb6d6d1bf +Author: djm@openbsd.org +Date: Thu Jan 8 10:15:45 2015 +0000 + + upstream commit + + reorder hostbased key attempts to better match the + default hostkey algorithms order in myproposal.h; ok markus@ + +commit 1195f4cb07ef4b0405c839293c38600b3e9bdb46 +Author: djm@openbsd.org +Date: Thu Jan 8 10:14:08 2015 +0000 + + upstream commit + + deprecate key_load_private_pem() and + sshkey_load_private_pem() interfaces. Refactor the generic key loading API to + not require pathnames to be specified (they weren't really used). + + Fixes a few other things en passant: + + Makes ed25519 keys work for hostbased authentication (ssh-keysign + previously used the PEM-only routines). + + Fixes key comment regression bz#2306: key pathnames were being lost as + comment fields. + + ok markus@ + +commit febbe09e4e9aff579b0c5cc1623f756862e4757d +Author: tedu@openbsd.org +Date: Wed Jan 7 18:15:07 2015 +0000 + + upstream commit + + workaround for the Meyer, et al, Bleichenbacher Side + Channel Attack. fake up a bignum key before RSA decryption. discussed/ok djm + markus + +commit 5191df927db282d3123ca2f34a04d8d96153911a +Author: djm@openbsd.org +Date: Tue Dec 23 22:42:48 2014 +0000 + + upstream commit + + KNF and add a little more debug() + +commit 8abd80315d3419b20e6938f74d37e2e2b547f0b7 +Author: jmc@openbsd.org +Date: Mon Dec 22 09:26:31 2014 +0000 + + upstream commit + + add fingerprinthash to the options list; + +commit 296ef0560f60980da01d83b9f0e1a5257826536f +Author: jmc@openbsd.org +Date: Mon Dec 22 09:24:59 2014 +0000 + + upstream commit + + tweak previous; + +commit 462082eacbd37778a173afb6b84c6f4d898a18b5 +Author: Damien Miller +Date: Tue Dec 30 08:16:11 2014 +1100 + + avoid uninitialised free of ldns_res + + If an invalid rdclass was passed to getrrsetbyname() then + this would execute a free on an uninitialised pointer. + OpenSSH only ever calls this with a fixed and valid rdclass. + + Reported by Joshua Rogers + +commit 01b63498801053f131a0740eb9d13faf35d636c8 +Author: Damien Miller +Date: Mon Dec 29 18:10:18 2014 +1100 + + pull updated OpenBSD BCrypt PBKDF implementation + + Includes fix for 1 byte output overflow for large key length + requests (not reachable in OpenSSH). + + Pointed out by Joshua Rogers + +commit c528c1b4af2f06712177b3de9b30705752f7cbcb +Author: Damien Miller +Date: Tue Dec 23 15:26:13 2014 +1100 + + fix variable name for IPv6 case in construct_utmpx + + patch from writeonce AT midipix.org via bz#2296 + +commit 293cac52dcda123244b2e594d15592e5e481c55e +Author: Damien Miller +Date: Mon Dec 22 16:30:42 2014 +1100 + + include and use OpenBSD netcat in regress/ + +commit 8f6784f0cb56dc4fd00af3e81a10050a5785228d +Author: djm@openbsd.org +Date: Mon Dec 22 09:05:17 2014 +0000 + + upstream commit + + mention ssh -Q feature to list supported { MAC, cipher, + KEX, key } algorithms in more places and include the query string used to + list the relevant information; bz#2288 + +commit 449e11b4d7847079bd0a2daa6e3e7ea03d8ef700 +Author: jmc@openbsd.org +Date: Mon Dec 22 08:24:17 2014 +0000 + + upstream commit + + tweak previous; + +commit 4bea0ab3290c0b9dd2aa199e932de8e7e18062d6 +Author: djm@openbsd.org +Date: Mon Dec 22 08:06:03 2014 +0000 + + upstream commit + + regression test for multiple required pubkey authentication; + ok markus@ + +commit f1c4d8ec52158b6f57834b8cd839605b0a33e7f2 +Author: djm@openbsd.org +Date: Mon Dec 22 08:04:23 2014 +0000 + + upstream commit + + correct description of what will happen when a + AuthorizedKeysCommand is specified but AuthorizedKeysCommandUser is not (sshd + will refuse to start) + +commit 161cf419f412446635013ac49e8c660cadc36080 +Author: djm@openbsd.org +Date: Mon Dec 22 07:55:51 2014 +0000 + + upstream commit + + make internal handling of filename arguments of "none" + more consistent with ssh. "none" arguments are now replaced with NULL when + the configuration is finalised. + + Simplifies checking later on (just need to test not-NULL rather than + that + strcmp) and cleans up some inconsistencies. ok markus@ + +commit f69b69b8625be447b8826b21d87713874dac25a6 +Author: djm@openbsd.org +Date: Mon Dec 22 07:51:30 2014 +0000 + + upstream commit + + remember which public keys have been used for + authentication and refuse to accept previously-used keys. + + This allows AuthenticationMethods=publickey,publickey to require + that users authenticate using two _different_ pubkeys. + + ok markus@ + +commit 46ac2ed4677968224c4ca825bc98fc68dae183f0 +Author: djm@openbsd.org +Date: Mon Dec 22 07:24:11 2014 +0000 + + upstream commit + + fix passing of wildcard forward bind addresses when + connection multiplexing is in use; patch from Sami Hartikainen via bz#2324; ok dtucker@ -20120704 - - (dtucker) [configure.ac openbsd-compat/bsd-misc.h] Add setlinebuf for - platforms that don't have it. "looks good" tim@ +commit 0d1b241a262e4d0a6bbfdd595489ab1b853c43a1 +Author: djm@openbsd.org +Date: Mon Dec 22 06:14:29 2014 +0000 -20120703 - - (dtucker) [configure.ac] Detect platforms that can't use select(2) with - setrlimit(RLIMIT_NOFILE, rl_zero) and disable the rlimit sandbox on those. - - (dtucker) [configure.ac sandbox-rlimit.c] Test whether or not - setrlimit(RLIMIT_FSIZE, rl_zero) and skip it if it's not supported. Its - benefit is minor, so it's not worth disabling the sandbox if it doesn't - work. + upstream commit + + make this slightly easier to diff against portable -20120702 -- (dtucker) OpenBSD CVS Sync - - naddy@cvs.openbsd.org 2012/06/29 13:57:25 - [ssh_config.5 sshd_config.5] - match the documented MAC order of preference to the actual one; - ok dtucker@ - - markus@cvs.openbsd.org 2012/06/30 14:35:09 - [sandbox-systrace.c sshd.c] - fix a during the load of the sandbox policies (child can still make - the read-syscall and wait forever for systrace-answers) by replacing - the read/write synchronisation with SIGSTOP/SIGCONT; - report and help hshoexer@; ok djm@, dtucker@ - - dtucker@cvs.openbsd.org 2012/07/02 08:50:03 - [ssh.c] - set interactive ToS for forwarded X11 sessions. ok djm@ - - dtucker@cvs.openbsd.org 2012/07/02 12:13:26 - [ssh-pkcs11-helper.c sftp-client.c] - fix a couple of "assigned but not used" warnings. ok markus@ - - dtucker@cvs.openbsd.org 2012/07/02 14:37:06 - [regress/connect-privsep.sh] - remove exit from end of test since it prevents reporting failure - - (dtucker) [regress/reexec.sh regress/sftp-cmds.sh regress/test-exec.sh] - Move cygwin detection to test-exec and use to skip reexec test on cygwin. - - (dtucker) [regress/test-exec.sh] Correct uname for cygwin/w2k. +commit 0715bcdddbf68953964058f17255bf54734b8737 +Author: Damien Miller +Date: Mon Dec 22 13:47:07 2014 +1100 -20120629 - - OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/06/21 00:16:07 - [addrmatch.c] - fix strlcpy truncation check. from carsten at debian org, ok markus - - dtucker@cvs.openbsd.org 2012/06/22 12:30:26 - [monitor.c sshconnect2.c] - remove dead code following 'for (;;)' loops. - From Steve.McClellan at radisys com, ok markus@ - - dtucker@cvs.openbsd.org 2012/06/22 14:36:33 - [sftp.c] - Remove unused variable leftover from tab-completion changes. - From Steve.McClellan at radisys com, ok markus@ - - dtucker@cvs.openbsd.org 2012/06/26 11:02:30 - [sandbox-systrace.c] - Add mquery to the list of allowed syscalls for "UsePrivilegeSeparation - sandbox" since malloc now uses it. From johnw.mail at gmail com. - - dtucker@cvs.openbsd.org 2012/06/28 05:07:45 - [mac.c myproposal.h ssh_config.5 sshd_config.5] - Remove hmac-sha2-256-96 and hmac-sha2-512-96 MACs since they were removed - from draft6 of the spec and will not be in the RFC when published. Patch - from mdb at juniper net via bz#2023, ok markus. - - naddy@cvs.openbsd.org 2012/06/29 13:57:25 - [ssh_config.5 sshd_config.5] - match the documented MAC order of preference to the actual one; ok dtucker@ - - dtucker@cvs.openbsd.org 2012/05/13 01:42:32 - [regress/addrmatch.sh] - Add "Match LocalAddress" and "Match LocalPort" to sshd and adjust tests - to match. Feedback and ok djm@ markus@. - - djm@cvs.openbsd.org 2012/06/01 00:47:35 - [regress/multiplex.sh regress/forwarding.sh] - append to rather than truncate test log; bz#2013 from openssh AT - roumenpetrov.info - - djm@cvs.openbsd.org 2012/06/01 00:52:52 - [regress/sftp-cmds.sh] - don't delete .* on cleanup due to unintended env expansion; pointed out in - bz#2014 by openssh AT roumenpetrov.info - - dtucker@cvs.openbsd.org 2012/06/26 12:06:59 - [regress/connect-privsep.sh] - test sandbox with every malloc option - - dtucker@cvs.openbsd.org 2012/06/28 05:07:45 - [regress/try-ciphers.sh regress/cipher-speed.sh] - Remove hmac-sha2-256-96 and hmac-sha2-512-96 MACs since they were removed - from draft6 of the spec and will not be in the RFC when published. Patch - from mdb at juniper net via bz#2023, ok markus. - - (dtucker) [myproposal.h] Remove trailing backslash to fix compile error. - - (dtucker) [key.c] ifdef out sha256 key types on platforms that don't have - the required functions in libcrypto. + add missing regress output file -20120628 - - (dtucker) [openbsd-compat/getrrsetbyname-ldns.c] bz #2022: prevent null - pointer deref in the client when built with LDNS and using DNSSEC with a - CNAME. Patch from gregdlg+mr at hochet info. +commit 1e30483c8ad2c2f39445d4a4b6ab20c241e40593 +Author: djm@openbsd.org +Date: Mon Dec 22 02:15:52 2014 +0000 -20120622 - - (dtucker) [contrib/cygwin/ssh-host-config] Ensure that user sshd runs as - can logon as a service. Patch from vinschen at redhat com. + upstream commit + + adjust for new SHA256 key fingerprints and + slightly-different MD5 hex fingerprint format -20120620 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2011/12/02 00:41:56 - [mux.c] - fix bz#1948: ssh -f doesn't fork for multiplexed connection. - ok dtucker@ - - djm@cvs.openbsd.org 2011/12/04 23:16:12 - [mux.c] - revert: - > revision 1.32 - > date: 2011/12/02 00:41:56; author: djm; state: Exp; lines: +4 -1 - > fix bz#1948: ssh -f doesn't fork for multiplexed connection. - > ok dtucker@ - it interacts badly with ControlPersist - - djm@cvs.openbsd.org 2012/01/07 21:11:36 - [mux.c] - fix double-free in new session handler - NB. Id sync only - - djm@cvs.openbsd.org 2012/05/23 03:28:28 - [dns.c dns.h key.c key.h ssh-keygen.c] - add support for RFC6594 SSHFP DNS records for ECDSA key types. - patch from bugzilla-m67 AT nulld.me in bz#1978; ok + tweak markus@ - (Original authors OndÅ™ej Surý, OndÅ™ej Caletka and Daniel Black) - - djm@cvs.openbsd.org 2012/06/01 00:49:35 - [PROTOCOL.mux] - correct types of port numbers (integers, not strings); bz#2004 from - bert.wesarg AT googlemail.com - - djm@cvs.openbsd.org 2012/06/01 01:01:22 - [mux.c] - fix memory leak when mux socket creation fails; bz#2002 from bert.wesarg - AT googlemail.com - - dtucker@cvs.openbsd.org 2012/06/18 11:43:53 - [jpake.c] - correct sizeof usage. patch from saw at online.de, ok deraadt - - dtucker@cvs.openbsd.org 2012/06/18 11:49:58 - [ssh_config.5] - RSA instead of DSA twice. From Steve.McClellan at radisys com - - dtucker@cvs.openbsd.org 2012/06/18 12:07:07 - [ssh.1 sshd.8] - Remove mention of 'three' key files since there are now four. From - Steve.McClellan at radisys com. - - dtucker@cvs.openbsd.org 2012/06/18 12:17:18 - [ssh.1] - Clarify description of -W. Noted by Steve.McClellan at radisys com, - ok jmc - - markus@cvs.openbsd.org 2012/06/19 18:25:28 - [servconf.c servconf.h sshd_config.5] - sshd_config: extend Match to allow AcceptEnv and {Allow,Deny}{Users,Groups} - this allows 'Match LocalPort 1022' combined with 'AllowUser bauer' - ok djm@ (back in March) - - jmc@cvs.openbsd.org 2012/06/19 21:35:54 - [sshd_config.5] - tweak previous; ok markus - - djm@cvs.openbsd.org 2012/06/20 04:42:58 - [clientloop.c serverloop.c] - initialise accept() backoff timer to avoid EINVAL from select(2) in - rekeying +commit 6b40567ed722df98593ad8e6a2d2448fc2b4b151 +Author: djm@openbsd.org +Date: Mon Dec 22 01:14:49 2014 +0000 -20120519 - - (dtucker) [configure.ac] bz#2010: fix non-portable shell construct. Patch - from cjwatson at debian org. - - (dtucker) [configure.ac contrib/Makefile] bz#1996: use AC_PATH_TOOL to find - pkg-config so it does the right thing when cross-compiling. Patch from - cjwatson at debian org. -- (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2012/05/13 01:42:32 - [servconf.h servconf.c sshd.8 sshd.c auth.c sshd_config.5] - Add "Match LocalAddress" and "Match LocalPort" to sshd and adjust tests - to match. Feedback and ok djm@ markus@. - - dtucker@cvs.openbsd.org 2012/05/19 06:30:30 - [sshd_config.5] - Document PermitOpen none. bz#2001, patch from Loganaden Velvindron + upstream commit + + poll changes to netcat (usr.bin/netcat.c r1.125) broke + this test; fix it by ensuring more stdio fds are sent to devnull -20120504 - - (dtucker) [configure.ac] Include rather than - to fix building on some plaforms. Fom bowman at math utah edu and - des at des no. +commit a5375ccb970f49dddf7d0ef63c9b713ede9e7260 +Author: jmc@openbsd.org +Date: Sun Dec 21 23:35:14 2014 +0000 -20120427 - - (dtucker) [regress/addrmatch.sh] skip tests when running on a non-ipv6 - platform rather than exiting early, so that we still clean up and return - success or failure to test-exec.sh + upstream commit + + tweak previous; -20120426 - - (djm) [auth-passwd.c] Handle crypt() returning NULL; from Paul Wouters - via Niels - - (djm) [auth-krb5.c] Save errno across calls that might modify it; - ok dtucker@ +commit b79efde5c3badf5ce4312fe608d8307eade533c5 +Author: djm@openbsd.org +Date: Sun Dec 21 23:12:42 2014 +0000 -20120423 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2012/04/23 08:18:17 - [channels.c] - fix function proto/source mismatch + upstream commit + + document FingerprintHash here too -20120422 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2012/02/29 11:21:26 - [ssh-keygen.c] - allow conversion of RSA1 keys to public PEM and PKCS8; "nice" markus@ - - guenther@cvs.openbsd.org 2012/03/15 03:10:27 - [session.c] - root should always be excluded from the test for /etc/nologin instead - of having it always enforced even when marked as ignorenologin. This - regressed when the logic was incompletely flipped around in rev 1.251 - ok halex@ millert@ - - djm@cvs.openbsd.org 2012/03/28 07:23:22 - [PROTOCOL.certkeys] - explain certificate extensions/crit split rationale. Mention requirement - that each appear at most once per cert. - - dtucker@cvs.openbsd.org 2012/03/29 23:54:36 - [channels.c channels.h servconf.c] - Add PermitOpen none option based on patch from Loganaden Velvindron - (bz #1949). ok djm@ - - djm@cvs.openbsd.org 2012/04/11 13:16:19 - [channels.c channels.h clientloop.c serverloop.c] - don't spin in accept() when out of fds (ENFILE/ENFILE) - back off for a - while; ok deraadt@ markus@ - - djm@cvs.openbsd.org 2012/04/11 13:17:54 - [auth.c] - Support "none" as an argument for AuthorizedPrincipalsFile to indicate - no file should be read. - - djm@cvs.openbsd.org 2012/04/11 13:26:40 - [sshd.c] - don't spin in accept() when out of fds (ENFILE/ENFILE) - back off for a - while; ok deraadt@ markus@ - - djm@cvs.openbsd.org 2012/04/11 13:34:17 - [ssh-keyscan.1 ssh-keyscan.c] - now that sshd defaults to offering ECDSA keys, ssh-keyscan should also - look for them by default; bz#1971 - - djm@cvs.openbsd.org 2012/04/12 02:42:32 - [servconf.c servconf.h sshd.c sshd_config sshd_config.5] - VersionAddendum option to allow server operators to append some arbitrary - text to the SSH-... banner; ok deraadt@ "don't care" markus@ - - djm@cvs.openbsd.org 2012/04/12 02:43:55 - [sshd_config sshd_config.5] - mention AuthorizedPrincipalsFile=none default - - djm@cvs.openbsd.org 2012/04/20 03:24:23 - [sftp.c] - setlinebuf(3) is more readable than setvbuf(.., _IOLBF, ...) - - jmc@cvs.openbsd.org 2012/04/20 16:26:22 - [ssh.1] - use "brackets" instead of "braces", for consistency; +commit d16bdd8027dd116afa01324bb071a4016cdc1a75 +Author: Damien Miller +Date: Mon Dec 22 10:18:09 2014 +1100 -20120420 - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update for release 6.0 - - (djm) [README] Update URL to release notes. - - (djm) Release openssh-6.0 + missing include for base64 encoding + +commit 56d1c83cdd1ac76f1c6bd41e01e80dad834f3994 +Author: djm@openbsd.org +Date: Sun Dec 21 22:27:55 2014 +0000 + + upstream commit + + Add FingerprintHash option to control algorithm used for + key fingerprints. Default changes from MD5 to SHA256 and format from hex to + base64. + + Feedback and ok naddy@ markus@ + +commit 058f839fe15c51be8b3a844a76ab9a8db550be4f +Author: djm@openbsd.org +Date: Thu Dec 18 23:58:04 2014 +0000 + + upstream commit + + don't count partial authentication success as a failure + against MaxAuthTries; ok deraadt@ + +commit c7219f4f54d64d6dde66dbcf7a2699daa782d2a1 +Author: djm@openbsd.org +Date: Fri Dec 12 00:02:17 2014 +0000 + + upstream commit + + revert chunk I didn't mean to commit yet; via jmc@ + +commit 7de5991aa3997e2981440f39c1ea01273a0a2c7b +Author: Damien Miller +Date: Thu Dec 18 11:44:06 2014 +1100 + + upstream libc change + + revision 1.2 + date: 2014/12/08 03:45:00; author: bcook; state: Exp; lines: +2 -2; commitid: 7zWEBgJJOCZ2hvTV; + avoid left shift overflow in reallocarray. + + Some 64-bit platforms (e.g. Windows 64) have a 32-bit long. So, shifting + 1UL 32-bits to the left causes an overflow. This replaces the constant 1UL with + (size_t)1 so that we get the correct constant size for the platform. + + discussed with tedu@ & deraadt@ + +commit 2048f85a5e6da8bc6e0532efe02ecfd4e63c978c +Author: Damien Miller +Date: Thu Dec 18 10:15:49 2014 +1100 + + include CFLAGS in gnome askpass targets + + from Fedora + +commit 48b68ce19ca42fa488960028048dec023f7899bb +Author: djm@openbsd.org +Date: Thu Dec 11 08:20:09 2014 +0000 + + upstream commit + + explicitly include sys/param.h in files that use the + howmany() macro; from portable + +commit d663bea30a294d440fef4398e5cd816317bd4518 +Author: djm@openbsd.org +Date: Thu Dec 11 05:25:06 2014 +0000 + + upstream commit + + mention AuthorizedKeysCommandUser must be set for + AuthorizedKeysCommand to be run; bz#2287 + +commit 17bf3d81e00f2abb414a4fd271118cf4913f049f +Author: djm@openbsd.org +Date: Thu Dec 11 05:13:28 2014 +0000 + + upstream commit + + show in debug output which hostkeys are being tried when + attempting hostbased auth; patch from Iain Morgan + +commit da0277e3717eadf5b15e03379fc29db133487e94 +Author: djm@openbsd.org +Date: Thu Dec 11 04:16:14 2014 +0000 + + upstream commit + + Make manual reflect reality: sftp-server's -d option + accepts a "%d" option, not a "%h" one. + + bz#2316; reported by Kirk Wolf + +commit 4cf87f4b81fa9380bce5fcff7b0f8382ae3ad996 +Author: djm@openbsd.org +Date: Wed Dec 10 01:24:09 2014 +0000 + + upstream commit + + better error value for invalid signature length + +commit 4bfad14ca56f8ae04f418997816b4ba84e2cfc3c +Author: Darren Tucker +Date: Wed Dec 10 02:12:51 2014 +1100 + + Resync more with OpenBSD's rijndael.c, in particular "#if 0"-ing out some + unused code. Should fix compile error reported by plautrba at redhat. + +commit 642652d280499691c8212ec6b79724b50008ce09 +Author: Darren Tucker +Date: Wed Dec 10 01:32:23 2014 +1100 + + Add reallocarray to compat library + +commit 3dfd8d93dfcc69261f5af99df56f3ff598581979 +Author: djm@openbsd.org +Date: Thu Dec 4 22:31:50 2014 +0000 + + upstream commit + + add tests for new client RevokedHostKeys option; refactor + to make it a bit more readable + +commit a31046cad1aed16a0b55171192faa6d02665ccec +Author: krw@openbsd.org +Date: Wed Nov 19 13:35:37 2014 +0000 + + upstream commit + + Nuke yet more obvious #include duplications. + + ok deraadt@ + +commit a7c762e5b2c1093542c0bc1df25ccec0b4cf479f +Author: djm@openbsd.org +Date: Thu Dec 4 20:47:36 2014 +0000 + + upstream commit + + key_in_file() wrapper is no longer used + +commit 5e39a49930d885aac9c76af3129332b6e772cd75 +Author: djm@openbsd.org +Date: Thu Dec 4 02:24:32 2014 +0000 + + upstream commit + + add RevokedHostKeys option for the client + + Allow textfile or KRL-based revocation of hostkeys. + +commit 74de254bb92c684cf53461da97f52d5ba34ded80 +Author: djm@openbsd.org +Date: Thu Dec 4 01:49:59 2014 +0000 + + upstream commit + + convert KRL code to new buffer API + + ok markus@ + +commit db995f2eed5fc432598626fa3e30654503bf7151 +Author: millert@openbsd.org +Date: Wed Nov 26 18:34:51 2014 +0000 + + upstream commit + + Prefer setvbuf() to setlinebuf() for portability; ok + deraadt@ + +commit 72bba3d179ced8b425272efe6956a309202a91f3 +Author: jsg@openbsd.org +Date: Mon Nov 24 03:39:22 2014 +0000 + + upstream commit + + Fix crashes in the handling of the sshd config file found + with the afl fuzzer. + + ok deraadt@ djm@ + +commit 867f49c666adcfe92bf539d9c37c1accdea08bf6 +Author: Damien Miller +Date: Wed Nov 26 13:22:41 2014 +1100 + + Avoid Cygwin ssh-host-config reading /etc/group + + Patch from Corinna Vinschen + +commit 8b66f36291a721b1ba7c44f24a07fdf39235593e +Author: Damien Miller +Date: Wed Nov 26 13:20:35 2014 +1100 + + allow custom service name for sshd on Cygwin + + Permits the use of multiple sshd running with different service names. + + Patch by Florian Friesdorf via Corinna Vinschen + +commit 08c0eebf55d70a9ae1964399e609288ae3186a0c +Author: jmc@openbsd.org +Date: Sat Nov 22 19:21:03 2014 +0000 + + upstream commit + + restore word zapped in previous, and remove some useless + "No" macros; + +commit a1418a0033fba43f061513e992e1cbcc3343e563 +Author: deraadt@openbsd.org +Date: Sat Nov 22 18:15:41 2014 +0000 + + upstream commit + + /dev/random has created the same effect as /dev/arandom + (and /dev/urandom) for quite some time. Mop up the last few, by using + /dev/random where we actually want it, or not even mentioning arandom where + it is irrelevant. + +commit b6de5ac9ed421362f479d1ad4fa433d2e25dad5b +Author: djm@openbsd.org +Date: Fri Nov 21 01:00:38 2014 +0000 + + upstream commit + + fix NULL pointer dereference crash on invalid timestamp + + found using Michal Zalewski's afl fuzzer + +commit a1f8110cd5ed818d59b3a2964fab7de76e92c18e +Author: mikeb@openbsd.org +Date: Tue Nov 18 22:38:48 2014 +0000 + + upstream commit + + Sync AES code to the one shipped in OpenSSL/LibreSSL. + + This includes a commit made by Andy Polyakov + to the OpenSSL source tree on Wed, 28 Jun 2006 with the following + message: "Mitigate cache-collision timing attack on last round." + + OK naddy, miod, djm + +commit 335c83d5f35d8620e16b8aa26592d4f836e09ad2 +Author: krw@openbsd.org +Date: Tue Nov 18 20:54:28 2014 +0000 + + upstream commit + + Nuke more obvious #include duplications. + + ok deraadt@ millert@ tedu@ + +commit 51b64e44121194ae4bf153dee391228dada2abcb +Author: djm@openbsd.org +Date: Mon Nov 17 00:21:40 2014 +0000 + + upstream commit + + fix KRL generation when multiple CAs are in use + + We would generate an invalid KRL when revoking certs by serial + number for multiple CA keys due to a section being written out + twice. + + Also extend the regress test to catch this case by having it + produce a multi-CA KRL. + + Reported by peter AT pean.org + +commit d2d51003a623e21fb2b25567c4878d915e90aa2a +Author: djm@openbsd.org +Date: Tue Nov 18 01:02:25 2014 +0000 + + upstream commit + + fix NULL pointer dereference crash in key loading + + found by Michal Zalewski's AFL fuzzer + +commit 9f9fad0191028edc43d100d0ded39419b6895fdf +Author: djm@openbsd.org +Date: Mon Nov 17 00:21:40 2014 +0000 + + upstream commit + + fix KRL generation when multiple CAs are in use + + We would generate an invalid KRL when revoking certs by serial + number for multiple CA keys due to a section being written out + twice. + + Also extend the regress test to catch this case by having it + produce a multi-CA KRL. + + Reported by peter AT pean.org + +commit da8af83d3f7ec00099963e455010e0ed1d7d0140 +Author: bentley@openbsd.org +Date: Sat Nov 15 14:41:03 2014 +0000 + + upstream commit + + Reduce instances of `` '' in manuals. + + troff displays these as typographic quotes, but nroff implementations + almost always print them literally, which rarely has the intended effect + with modern fonts, even in stock xterm. + + These uses of `` '' can be replaced either with more semantic alternatives + or with Dq, which prints typographic quotes in a UTF-8 locale (but will + automatically fall back to `` '' in an ASCII locale). + + improvements and ok schwarze@ + +commit fc302561369483bb755b17f671f70fb894aec01d +Author: djm@openbsd.org +Date: Mon Nov 10 22:25:49 2014 +0000 + + upstream commit + + mux-related manual tweaks + + mention ControlPersist=0 is the same as ControlPersist=yes + + recommend that ControlPath sockets be placed in a og-w directory + +commit 0e4cff5f35ed11102fe3783779960ef07e0cd381 +Author: Damien Miller +Date: Wed Nov 5 11:01:31 2014 +1100 + + Prepare scripts for next Cygwin release + + Makes the Cygwin-specific ssh-user-config script independent of the + existence of /etc/passwd. The next Cygwin release will allow to + generate passwd and group entries from the Windows account DBs, so the + scripts have to adapt. + + from Corinna Vinschen + +commit 7d0ba5336651731949762eb8877ce9e3b52df436 +Author: Damien Miller +Date: Thu Oct 30 10:45:41 2014 +1100 + + include version number in OpenSSL-too-old error + +commit 3bcb92e04d9207e9f78d82f7918c6d3422054ce9 +Author: lteo@openbsd.org +Date: Fri Oct 24 02:01:20 2014 +0000 + + upstream commit + + Remove unnecessary include: netinet/in_systm.h is not needed + by these programs. + + NB. skipped for portable + + ok deraadt@ millert@ + +commit 6fdcaeb99532e28a69f1a1599fbd540bb15b70a0 +Author: djm@openbsd.org +Date: Mon Oct 20 03:43:01 2014 +0000 + + upstream commit + + whitespace + +commit 165bc8786299e261706ed60342985f9de93a7461 +Author: daniel@openbsd.org +Date: Tue Oct 14 03:09:59 2014 +0000 + + upstream commit + + plug a memory leak; from Maxime Villard. + + ok djm@ + +commit b1ba15f3885947c245c2dbfaad0a04ba050abea0 +Author: jmc@openbsd.org +Date: Thu Oct 9 06:21:31 2014 +0000 + + upstream commit + + tweak previous; + +commit 259a02ebdf74ad90b41d116ecf70aa823fa4c6e7 +Author: djm@openbsd.org +Date: Mon Oct 13 00:38:35 2014 +0000 + + upstream commit + + whitespace + +commit 957fbceb0f3166e41b76fdb54075ab3b9cc84cba +Author: djm@openbsd.org +Date: Wed Oct 8 22:20:25 2014 +0000 + + upstream commit + + Tweak config reparsing with host canonicalisation + + Make the second pass through the config files always run when + hostname canonicalisation is enabled. + + Add a "Match canonical" criteria that allows ssh_config Match + blocks to trigger only in the second config pass. + + Add a -G option to ssh that causes it to parse its configuration + and dump the result to stdout, similar to "sshd -T" + + Allow ssh_config Port options set in the second config parse + phase to be applied (they were being ignored). + + bz#2267 bz#2286; ok markus + +commit 5c0dafd38bf66feeeb45fa0741a5baf5ad8039ba +Author: djm@openbsd.org +Date: Wed Oct 8 22:15:27 2014 +0000 + + upstream commit + + another -Wpointer-sign from clang + +commit bb005dc815ebda9af3ae4b39ca101c4da918f835 +Author: djm@openbsd.org +Date: Wed Oct 8 22:15:06 2014 +0000 + + upstream commit + + fix a few -Wpointer-sign warnings from clang + +commit 3cc1fbb4fb0e804bfb873fd363cea91b27fc8188 +Author: djm@openbsd.org +Date: Wed Oct 8 21:45:48 2014 +0000 + + upstream commit + + parse cert sections using nested buffers to reduce + copies; ok markus + +commit 4a45922aebf99164e2fc83d34fe55b11ae1866ef +Author: djm@openbsd.org +Date: Mon Oct 6 00:47:15 2014 +0000 + + upstream commit + + correct options in usage(); from mancha1 AT zoho.com + +commit 48dffd5bebae6fed0556dc5c36cece0370690618 +Author: djm@openbsd.org +Date: Tue Sep 9 09:45:36 2014 +0000 + + upstream commit + + mention permissions on tun(4) devices in PermitTunnel + documentation; bz#2273 + +commit a5883d4eccb94b16c355987f58f86a7dee17a0c2 +Author: djm@openbsd.org +Date: Wed Sep 3 18:55:07 2014 +0000 + + upstream commit + + tighten permissions on pty when the "tty" group does + not exist; pointed out by Corinna Vinschen; ok markus + +commit 180bcb406b58bf30723c01a6b010e48ee626dda8 +Author: sobrado@openbsd.org +Date: Sat Aug 30 16:32:25 2014 +0000 + + upstream commit + + typo. + +commit f70b22bcdd52f6bf127047b3584371e6e5d45627 +Author: sobrado@openbsd.org +Date: Sat Aug 30 15:33:50 2014 +0000 + + upstream commit + + improve capitalization for the Ed25519 public-key + signature system. + + ok djm@ + +commit 7df8818409c752cf3f0c3f8044fe9aebed8647bd +Author: doug@openbsd.org +Date: Thu Aug 21 01:08:52 2014 +0000 + + upstream commit + + Free resources on error in mkstemp and fdopen + + ok djm@ + +commit 40ba4c9733aaed08304714faeb61529f18da144b +Author: deraadt@openbsd.org +Date: Wed Aug 20 01:28:55 2014 +0000 + + upstream commit + + djm how did you make a typo like that... + +commit 57d378ec9278ba417a726f615daad67d157de666 +Author: djm@openbsd.org +Date: Tue Aug 19 23:58:28 2014 +0000 + + upstream commit + + When dumping the server configuration (sshd -T), print + correct KEX, MAC and cipher defaults. Spotted by Iain Morgan + +commit 7ff880ede5195d0b17e7f1e3b6cfbc4cb6f85240 +Author: djm@openbsd.org +Date: Tue Aug 19 23:57:18 2014 +0000 + + upstream commit + + ~-expand lcd paths + +commit 4460a7ad0c78d4cd67c467f6e9f4254d0404ed59 +Author: Damien Miller +Date: Sun Oct 12 12:35:48 2014 +1100 + + remove duplicated KEX_DH1 entry + +commit c9b8426a616138d0d762176c94f51aff3faad5ff +Author: Damien Miller +Date: Thu Oct 9 10:34:06 2014 +1100 + + remove ChangeLog file + + Commit logs will be generated from git at release time. + +commit 81d18ff7c93a04affbf3903e0963859763219aed +Author: Damien Miller +Date: Tue Oct 7 21:24:25 2014 +1100 + + delete contrib/caldera directory + +commit 0ec9e87d3638206456968202f05bb5123670607a +Author: Damien Miller +Date: Tue Oct 7 19:57:27 2014 +1100 + + test commit + +commit 8fb65a44568701b779f3d77326bceae63412d28d +Author: Damien Miller +Date: Tue Oct 7 09:21:49 2014 +1100 + + - (djm) Release OpenSSH-6.7 + +commit e8c9f2602c46f6781df5e52e6cd8413dab4602a3 +Author: Damien Miller +Date: Fri Oct 3 09:24:56 2014 +1000 + + - (djm) [sshd_config.5] typo; from Iain Morgan + +commit 703b98a26706f5083801d11059486d77491342ae +Author: Damien Miller +Date: Wed Oct 1 09:43:07 2014 +1000 + + - (djm) [openbsd-compat/Makefile.in openbsd-compat/kludge-fd_set.c] + [openbsd-compat/openbsd-compat.h] Kludge around bad glibc + _FORTIFY_SOURCE check that doesn't grok heap-allocated fd_sets; + ok dtucker@ + +commit 0fa0ed061bbfedb0daa705e220748154a84c3413 +Author: Damien Miller +Date: Wed Sep 10 08:15:34 2014 +1000 + + - (djm) [sandbox-seccomp-filter.c] Allow mremap and exit for DietLibc; + patch from Felix von Leitner; ok dtucker + +commit ad7d23d461c3b7e1dcb15db13aee5f4b94dc1a95 +Author: Darren Tucker +Date: Tue Sep 9 12:23:10 2014 +1000 + + 20140908 + - (dtucker) [INSTALL] Update info about egd. ok djm@ + +commit 2a8699f37cc2515e3bc60e0c677ba060f4d48191 +Author: Damien Miller +Date: Thu Sep 4 03:46:05 2014 +1000 + + - (djm) [openbsd-compat/arc4random.c] Zero seed after keying PRNG + +commit 44988defb1f5e3afe576d86000365e1f07a1b494 +Author: Damien Miller +Date: Wed Sep 3 05:35:32 2014 +1000 + + - (djm) [contrib/cygwin/ssh-host-config] Fix old code leading to + permissions/ACLs; from Corinna Vinschen + +commit 23f269562b7537b2f6f5014e50a25e5dcc55a837 +Author: Damien Miller +Date: Wed Sep 3 05:33:25 2014 +1000 + + - (djm) [defines.h sshbuf.c] Move __predict_true|false to defines.h and + conditionalise to avoid duplicate definition. + +commit 41c8de2c0031cf59e7cf0c06b5bcfbf4852c1fda +Author: Damien Miller +Date: Sat Aug 30 16:23:06 2014 +1000 + + - (djm) [Makefile.in] Make TEST_SHELL a variable; "good idea" tim@ + +commit d7c81e216a7bd9eed6e239c970d9261bb1651947 +Author: Damien Miller +Date: Sat Aug 30 04:18:28 2014 +1000 + + - (djm) [openbsd-compat/openssl-compat.h] add include guard + +commit 4687802dda57365b984b897fc3c8e2867ea09b22 +Author: Damien Miller +Date: Sat Aug 30 03:29:19 2014 +1000 + + - (djm) [misc.c] Missing newline between functions + +commit 51c77e29220dee87c53be2dc47092934acab26fe +Author: Damien Miller +Date: Sat Aug 30 02:30:30 2014 +1000 + + - (djm) [openbsd-compat/openssl-compat.h] add + OPENSSL_[RD]SA_MAX_MODULUS_BITS defines for OpenSSL that lacks them + +commit 3d673d103bad35afaec6e7ef73e5277216ce33a3 +Author: Damien Miller +Date: Wed Aug 27 06:32:01 2014 +1000 + + - (djm) [openbsd-compat/explicit_bzero.c] implement explicit_bzero() + using memset_s() where possible; improve fallback to indirect bzero + via a volatile pointer to give it more of a chance to avoid being + optimised away. + +commit 146218ac11a1eb0dcade6f793d7acdef163b5ddc +Author: Damien Miller +Date: Wed Aug 27 04:11:55 2014 +1000 + + - (djm) [monitor.c sshd.c] SIGXFSZ needs to be ignored in postauth + monitor, not preauth; bz#2263 + +commit 1b215c098b3b37e38aa4e4c91bb908eee41183b1 +Author: Damien Miller +Date: Wed Aug 27 04:04:40 2014 +1000 + + - (djm) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] + [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] + [regress/unittests/sshkey/common.c] + [regress/unittests/sshkey/test_file.c] + [regress/unittests/sshkey/test_fuzz.c] + [regress/unittests/sshkey/test_sshkey.c] Don't include openssl/ec.h + on !ECC OpenSSL systems + +commit ad013944af0a19e3f612089d0099bb397cf6502d +Author: Damien Miller +Date: Tue Aug 26 09:27:28 2014 +1000 + + - (djm) [INSTALL] Recommend libcrypto be built -fPIC, mention LibreSSL, + update OpenSSL version requirement. + +commit ed126de8ee04c66640a0ea2697c4aaf36801f100 +Author: Damien Miller +Date: Tue Aug 26 08:37:47 2014 +1000 + + - (djm) [bufec.c] Skip this file on !ECC OpenSSL + +commit 9c1dede005746864a4fdb36a7cdf6c51296ca909 +Author: Damien Miller +Date: Sun Aug 24 03:01:06 2014 +1000 + + - (djm) [sftp-server.c] Some systems (e.g. Irix) have prctl() but not + PR_SET_DUMPABLE, so adjust ifdef; reported by Tom Christensen + +commit d244a5816fd1312a33404b436e4dd83594f1119e +Author: Damien Miller +Date: Sat Aug 23 17:06:49 2014 +1000 + + - (djm) [configure.ac] We now require a working vsnprintf everywhere (not + just for systems that lack asprintf); check for it always and extend + test to catch more brokenness. Fixes builds on Solaris <= 9 + +commit 4cec036362a358e398e6a2e6d19d8e5780558634 +Author: Damien Miller +Date: Sat Aug 23 03:11:09 2014 +1000 + + - (djm) [sshd.c] Ignore SIGXFSZ in preauth monitor child; can explode on + lastlog writing on platforms with high UIDs; bz#2263 + +commit 394a60f2598d28b670d934b93942a3370b779b39 +Author: Damien Miller +Date: Fri Aug 22 18:06:20 2014 +1000 + + - (djm) [configure.ac] double braces to appease autoconf + +commit 4d69aeabd6e60afcdc7cca177ca751708ab79a9d +Author: Damien Miller +Date: Fri Aug 22 17:48:27 2014 +1000 + + - (djm) [openbsd-compat/bsd-snprintf.c] Fix compilation failure (prototype/ + definition mismatch) and warning for broken/missing snprintf case. + +commit 0c11f1ac369d2c0aeb0ab0458a7cd04c72fe5e9e +Author: Damien Miller +Date: Fri Aug 22 17:36:56 2014 +1000 + + - (djm) [sshbuf-getput-crypto.c] Fix compilation when OpenSSL lacks ECC + +commit 6d62784b8973340b251fea6b04890f471adf28db +Author: Damien Miller +Date: Fri Aug 22 17:36:19 2014 +1000 + + - (djm) [configure.ac] include leading zero characters in OpenSSL version + number; fixes test for unsupported versions + +commit 4f1ff1ed782117f5d5204d4e91156ed5da07cbb7 +Author: Damien Miller +Date: Thu Aug 21 15:54:50 2014 +1000 + + - (djm) [regress/unittests/test_helper/test_helper.c] Fix for systems that + don't set __progname. Diagnosed by Tom Christensen. + +commit 005a64da0f457410045ef0bfa93c863c2450447d +Author: Damien Miller +Date: Thu Aug 21 10:48:41 2014 +1000 + + - (djm) [key.h] Fix ifdefs for no-ECC OpenSSL + +commit aa6598ebb3343c7380e918388e10e8ca5852b613 +Author: Damien Miller +Date: Thu Aug 21 10:47:54 2014 +1000 + + - (djm) [Makefile.in] fix reference to libtest_helper.a in sshkey test too. + +commit 54703e3cf63f0c80d4157e5ad7dbc2b363ee2c56 +Author: Damien Miller +Date: Wed Aug 20 11:10:51 2014 +1000 + + - (djm) [contrib/cygwin/README] Correct build instructions; from Corinna + +commit f0935698f0461f24d8d1f1107b476ee5fd4db1cb +Author: Damien Miller +Date: Wed Aug 20 11:06:50 2014 +1000 + + - (djm) [sshkey.h] Fix compilation when OpenSSL lacks ECC + +commit c5089ecaec3b2c02f014f4e67518390702a4ba14 +Author: Damien Miller +Date: Wed Aug 20 11:06:20 2014 +1000 + + - (djm) [Makefile.in] refer to libtest_helper.a by explicit path rather than + -L/-l; fixes linking problems on some platforms + +commit 2195847e503a382f83ee969b0a8bd3dfe0e55c18 +Author: Damien Miller +Date: Wed Aug 20 11:05:03 2014 +1000 + + - (djm) [configure.ac] Check OpenSSL version is supported at configure time; + suggested by Kevin Brott + +commit a75aca1bbc989aa9f8b1b08489d37855f3d24d1a +Author: Damien Miller +Date: Tue Aug 19 11:36:07 2014 +1000 + + - (djm) [INSTALL contrib/caldera/openssh.spec contrib/cygwin/README] + [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Remove mentions + of TCP wrappers. + +commit 3f022b5a9477abceeb1bbeab04b055f3cc7ca8f6 +Author: Damien Miller +Date: Tue Aug 19 11:32:34 2014 +1000 + + - (djm) [ssh-dss.c] Include openssl/dsa.h for DSA_SIG + +commit 88137902632aceb923990e98cf5dc923bb3ef2f5 +Author: Damien Miller +Date: Tue Aug 19 11:28:11 2014 +1000 + + - (djm) [sshbuf.h] Fix compilation on systems without OPENSSL_HAS_ECC. + +commit 2f3d1e7fb2eabd3cfbfd8d0f7bdd2f9a1888690b +Author: Damien Miller +Date: Tue Aug 19 11:14:36 2014 +1000 + + - (djm) [myproposal.h] Make curve25519 KEX dependent on + HAVE_EVP_SHA256 instead of OPENSSL_HAS_ECC. + +commit d4e7d59d01a6c7f59e8c1f94a83c086e9a33d8aa +Author: Damien Miller +Date: Tue Aug 19 11:14:17 2014 +1000 + + - (djm) [serverloop.c] Fix syntax error on Cygwin; from Corinna Vinschen + +commit 9eaeea2cf2b6af5f166cfa9ad3c7a90711a147a9 +Author: Damien Miller +Date: Sun Aug 10 11:35:05 2014 +1000 + + - (djm) [README contrib/caldera/openssh.spec] + [contrib/redhat/openssh.spec contrib/suse/openssh.spec] Update versions + +commit f8988fbef0c9801d19fa2f8f4f041690412bec37 +Author: Damien Miller +Date: Fri Aug 1 13:31:52 2014 +1000 + + - (djm) [regress/multiplex.sh] Use -d (detach stdin) flag to disassociate + nc from stdin, it's more portable + +commit 5b3879fd4b7a4e3d43bab8f40addda39bc1169d0 +Author: Damien Miller +Date: Fri Aug 1 12:28:31 2014 +1000 + + - (djm) [regress/multiplex.sh] Instruct nc not to quit as soon as stdin + is closed; avoid regress failures when stdin is /dev/null + +commit a9c46746d266f8a1b092a72b2150682d1af8ebfc +Author: Damien Miller +Date: Fri Aug 1 12:26:49 2014 +1000 + + - (djm) [regress/multiplex.sh] Skip test for non-OpenBSD netcat. We need + a better solution, but this will have to do for now. + +commit 426117b2e965e43f47015942b5be8dd88fe74b88 +Author: Damien Miller +Date: Wed Jul 30 12:33:20 2014 +1000 + + - schwarze@cvs.openbsd.org 2014/07/28 15:40:08 + [sftp-server.8 sshd_config.5] + some systems no longer need /dev/log; + issue noticed by jirib; + ok deraadt + +commit f497794b6962eaf802ab4ac2a7b22ae591cca1d5 +Author: Damien Miller +Date: Wed Jul 30 12:32:46 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/25 21:22:03 + [ssh-agent.c] + Clear buffer used for handling messages. This prevents keys being + left in memory after they have been expired or deleted in some cases + (but note that ssh-agent is setgid so you would still need root to + access them). Pointed out by Kevin Burns, ok deraadt + +commit a8a0f65c57c8ecba94d65948e9090da54014dfef +Author: Damien Miller +Date: Wed Jul 30 12:32:28 2014 +1000 + + - OpenBSD CVS Sync + - millert@cvs.openbsd.org 2014/07/24 22:57:10 + [ssh.1] + Mention UNIX-domain socket forwarding too. OK jmc@ deraadt@ + +commit 56b840f2b81e14a2f95c203403633a72566736f8 +Author: Damien Miller +Date: Fri Jul 25 08:11:30 2014 +1000 + + - (djm) [regress/multiplex.sh] restore incorrectly deleted line; + pointed out by Christian Hesse + +commit dd417b60d5ca220565d1014e92b7f8f43dc081eb +Author: Darren Tucker +Date: Wed Jul 23 10:41:21 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 23:35:38 + [regress/unittests/sshkey/testdata/*] + Regenerate test keys with certs signed with ed25519 instead of ecdsa. + These can be used in -portable on platforms that don't support ECDSA. + +commit 40e50211896369dba8f64f3b5e5fd58b76f5ac3f +Author: Darren Tucker +Date: Wed Jul 23 10:35:45 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 23:57:40 + [regress/unittests/sshkey/mktestdata.sh] + Add $OpenBSD tag to make syncs easier + +commit 07e644251e809b1d4c062cf85bd1146a7e3f5a8a +Author: Darren Tucker +Date: Wed Jul 23 10:34:26 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 23:23:22 + [regress/unittests/sshkey/mktestdata.sh] + Sign test certs with ed25519 instead of ecdsa so that they'll work in + -portable on platforms that don't have ECDSA in their OpenSSL. ok djm + +commit cea099a7c4eaecb01b001e5453bb4e5c25006c22 +Author: Darren Tucker +Date: Wed Jul 23 10:04:02 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/22 01:32:12 + [regress/multiplex.sh] + change the test for still-open Unix domain sockets to be robust against + nc implementations that produce error messages. from -portable + (Id sync only) + +commit 31eb78078d349b32ea41952ecc944b3ad6cb0d45 +Author: Darren Tucker +Date: Wed Jul 23 09:43:42 2014 +1000 + + - guenther@cvs.openbsd.org 2014/07/22 07:13:42 + [umac.c] + Convert from to the shiney new + ok dtucker@, who also confirmed that -portable handles this already + (ID sync only, includes.h pulls in endian.h if available.) + +commit 820763efef2d19d965602533036c2b4badc9d465 +Author: Darren Tucker +Date: Wed Jul 23 09:40:46 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/07/22 01:18:50 + [key.c] + Prevent spam from key_load_private_pem during hostbased auth. ok djm@ + +commit c4ee219a66f3190fa96cbd45b4d11015685c6306 +Author: Darren Tucker +Date: Wed Jul 23 04:27:50 2014 +1000 + + - (dtucker) [regress/unittests/sshkey/test_{file,fuzz,sshkey}.c] Wrap ecdsa- + specific tests inside OPENSSL_HAS_ECC. + +commit 04f4824940ea3edd60835416ececbae16438968a +Author: Damien Miller +Date: Tue Jul 22 11:31:47 2014 +1000 + + - (djm) [regress/multiplex.sh] change the test for still-open Unix + domain sockets to be robust against nc implementations that produce + error messages. + +commit 5ea4fe00d55453aaa44007330bb4c3181bd9b796 +Author: Damien Miller +Date: Tue Jul 22 09:39:19 2014 +1000 + + - (djm) [regress/multiplex.sh] ssh mux master lost -N somehow; + put it back + +commit 948a1774a79a85f9deba6d74db95f402dee32c69 +Author: Darren Tucker +Date: Tue Jul 22 01:07:11 2014 +1000 + + - (dtucker) [sshkey.c] ifdef out unused variable when compiling without + OPENSSL_HAS_ECC. + +commit c8f610f6cc57ae129758052439d9baf13699097b +Author: Damien Miller +Date: Mon Jul 21 10:23:27 2014 +1000 + + - (djm) [regress/multiplex.sh] Not all netcat accept the -N option. + +commit 0e4e95566cd95c887f69272499b8f3880b3ec0f5 +Author: Damien Miller +Date: Mon Jul 21 09:52:54 2014 +1000 + + - millert@cvs.openbsd.org 2014/07/15 15:54:15 + [forwarding.sh multiplex.sh] + Add support for Unix domain socket forwarding. A remote TCP port + may be forwarded to a local Unix domain socket and vice versa or + both ends may be a Unix domain socket. This is a reimplementation + of the streamlocal patches by William Ahern from: + http://www.25thandclement.com/~william/projects/streamlocal.html + OK djm@ markus@ + +commit 93a87ab27ecdc709169fb24411133998f81e2761 +Author: Darren Tucker +Date: Mon Jul 21 06:30:25 2014 +1000 + + - (dtucker) [regress/unittests/sshkey/ + {common,test_file,test_fuzz,test_sshkey}.c] Wrap stdint.h includes in + ifdefs. + +commit 5573171352ea23df2dc6d2fe0324d023b7ba697c +Author: Darren Tucker +Date: Mon Jul 21 02:24:59 2014 +1000 + + - (dtucker) [cipher.c openbsd-compat/openssl-compat.h] Restore the bits + needed to build AES CTR mode against OpenSSL 0.9.8f and above. ok djm + +commit 74e28682711d005026c7c8f15f96aea9d3c8b5a3 +Author: Tim Rice +Date: Fri Jul 18 20:00:11 2014 -0700 + + - (tim) [openbsd-compat/port-uw.c] Include misc.h for fwd_opts, used + in servconf.h. + +commit d1a0421f8e5e933fee6fb58ee6b9a22c63c8a613 +Author: Darren Tucker +Date: Sat Jul 19 07:23:55 2014 +1000 + + - (dtucker) [key.c sshkey.c] Put new ecdsa bits inside ifdef OPENSSL_HAS_ECC. + +commit f0fe9ea1be62227c130b317769de3d1e736b6dc1 +Author: Darren Tucker +Date: Sat Jul 19 06:33:12 2014 +1000 + + - (dtucker) [Makefile.in] Add a t-exec target to run just the executable + tests. + +commit 450bc1180d4b061434a4b733c5c8814fa30b022b +Author: Darren Tucker +Date: Sat Jul 19 06:23:18 2014 +1000 + + - (dtucker) [auth2-gss.c gss-serv-krb5.c] Include misc.h for fwd_opts, used + in servconf.h. + +commit ab2ec586baad122ed169285c31927ccf58bc7b28 +Author: Damien Miller +Date: Fri Jul 18 15:04:47 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/18 02:46:01 + [ssh-agent.c] + restore umask around listener socket creation (dropped in streamlocal patch + merge) + +commit 357610d15946381ae90c271837dcdd0cdce7145f +Author: Damien Miller +Date: Fri Jul 18 15:04:10 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 07:22:19 + [mux.c ssh.c] + reflect stdio-forward ("ssh -W host:port ...") failures in exit status. + previously we were always returning 0. bz#2255 reported by Brendan + Germain; ok dtucker + +commit dad9a4a0b7c2b5d78605f8df28718f116524134e +Author: Damien Miller +Date: Fri Jul 18 15:03:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 00:12:03 + [key.c] + silence "incorrect passphrase" error spam; reported and ok dtucker@ + +commit f42f7684ecbeec6ce50e0310f80b3d6da2aaf533 +Author: Damien Miller +Date: Fri Jul 18 15:03:27 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 00:10:18 + [mux.c] + preserve errno across syscall + +commit 1b83320628cb0733e3688b85bfe4d388a7c51909 +Author: Damien Miller +Date: Fri Jul 18 15:03:02 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/17 00:10:56 + [sandbox-systrace.c] + ifdef SYS_sendsyslog so this will compile without patching on -stable + +commit 6d57656331bcd754d912950e4a18ad259d596e61 +Author: Damien Miller +Date: Fri Jul 18 15:02:06 2014 +1000 + + - jmc@cvs.openbsd.org 2014/07/16 14:48:57 + [ssh.1] + add the streamlocal* options to ssh's -o list; millert says they're + irrelevant for scp/sftp; + + ok markus millert + +commit 7acefbbcbeab725420ea07397ae35992f505f702 +Author: Damien Miller +Date: Fri Jul 18 14:11:24 2014 +1000 + + - millert@cvs.openbsd.org 2014/07/15 15:54:14 + [PROTOCOL auth-options.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c] + [auth-rsa.c auth.c auth1.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] + [auth2-passwd.c auth2-pubkey.c auth2.c canohost.c channels.c channels.h] + [clientloop.c misc.c misc.h monitor.c mux.c packet.c readconf.c] + [readconf.h servconf.c servconf.h serverloop.c session.c ssh-agent.c] + [ssh.c ssh_config.5 sshconnect.c sshconnect1.c sshconnect2.c sshd.c] + [sshd_config.5 sshlogin.c] + Add support for Unix domain socket forwarding. A remote TCP port + may be forwarded to a local Unix domain socket and vice versa or + both ends may be a Unix domain socket. This is a reimplementation + of the streamlocal patches by William Ahern from: + http://www.25thandclement.com/~william/projects/streamlocal.html + OK djm@ markus@ + +commit 6262d760e00714523633bd989d62e273a3dca99a +Author: Damien Miller +Date: Thu Jul 17 09:52:07 2014 +1000 + + - tedu@cvs.openbsd.org 2014/07/11 13:54:34 + [myproposal.h] + by popular demand, add back hamc-sha1 to server proposal for better compat + with many clients still in use. ok deraadt + +commit 9d69d937b46ecba17f16d923e538ceda7b705c7a +Author: Damien Miller +Date: Thu Jul 17 09:49:37 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/07/11 08:09:54 + [sandbox-systrace.c] + Permit use of SYS_sendsyslog from inside the sandbox. Clock is ticking, + update your kernels and sshd soon.. libc will start using sendsyslog() + in about 4 days. + +commit f6293a0b4129826fc2e37e4062f96825df43c326 +Author: Damien Miller +Date: Thu Jul 17 09:01:25 2014 +1000 + + - (djm) [digest-openssl.c] Preserve array order when disabling digests. + Reported by Petr Lautrbach. + +commit 00f9cd230709c04399ef5ff80492d70a55230694 +Author: Damien Miller +Date: Tue Jul 15 10:41:38 2014 +1000 + + - (djm) [configure.ac] Delay checks for arc4random* until after libcrypto + has been located; fixes builds agains libressl-portable + +commit 1d0df3249c87019556b83306c28d4769375c2edc +Author: Damien Miller +Date: Fri Jul 11 09:19:04 2014 +1000 + + - OpenBSD CVS Sync + - benno@cvs.openbsd.org 2014/07/09 14:15:56 + [ssh-add.c] + fix ssh-add crash while loading more than one key + ok markus@ + +commit 7a57eb3d105aa4ced15fb47001092c58811e6d9d +Author: Damien Miller +Date: Wed Jul 9 13:22:31 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/07 08:15:26 + [multiplex.sh] + remove forced-fatal that I stuck in there to test the new cleanup + logic and forgot to remove... + +commit 612f965239a30fe536b11ece1834d9f470aeb029 +Author: Damien Miller +Date: Wed Jul 9 13:22:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/06 07:42:03 + [multiplex.sh test-exec.sh] + add a hook to the cleanup() function to kill $SSH_PID if it is set + + use it to kill the mux master started in multiplex.sh (it was being left + around on fatal failures) + +commit d0bb950485ba121e43a77caf434115ed6417b46f +Author: Damien Miller +Date: Wed Jul 9 13:07:28 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/09 03:02:15 + [key.c] + downgrade more error() to debug() to better match what old authfile.c + did; suppresses spurious errors with hostbased authentication enabled + +commit 0070776a038655c57f57e70cd05e4c38a5de9d84 +Author: Damien Miller +Date: Wed Jul 9 13:07:06 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/09 01:45:10 + [sftp.c] + more useful error message when GLOB_NOSPACE occurs; + bz#2254, patch from Orion Poplawski + +commit 079bac2a43c74ef7cf56850afbab3b1932534c50 +Author: Damien Miller +Date: Wed Jul 9 13:06:25 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/07 08:19:12 + [ssh_config.5] + mention that ProxyCommand is executed using shell "exec" to avoid + a lingering process; bz#1977 + +commit 3a48cc090096cf99b9de592deb5f90e444edebfb +Author: Damien Miller +Date: Sun Jul 6 09:32:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/05 23:11:48 + [channels.c] + fix remote-forward cancel regression; ok markus@ + +commit 48bae3a38cb578713e676708164f6e7151cc64fa +Author: Damien Miller +Date: Sun Jul 6 09:27:06 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 23:18:35 + [authfile.h] + remove leakmalloc droppings + +commit 72e6b5c9ed5e72ca3a6ccc3177941b7c487a0826 +Author: Damien Miller +Date: Fri Jul 4 09:00:04 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 22:40:43 + [servconf.c servconf.h session.c sshd.8 sshd_config.5] + Add a sshd_config PermitUserRC option to control whether ~/.ssh/rc is + executed, mirroring the no-user-rc authorized_keys option; + bz#2160; ok markus@ + +commit 602943d1179a08dfa70af94f62296ea5e3d6ebb8 +Author: Damien Miller +Date: Fri Jul 4 08:59:41 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 22:33:41 + [channels.c] + allow explicit ::1 and 127.0.0.1 forwarding bind addresses when + GatewayPorts=no; allows client to choose address family; + bz#2222 ok markus@ + +commit 6b37fbb7921d156b31e2c8f39d9e1b6746c34983 +Author: Damien Miller +Date: Fri Jul 4 08:59:24 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 22:23:46 + [sshconnect.c] + when rekeying, skip file/DNS lookup if it is the same as the key sent + during initial key exchange. bz#2154 patch from Iain Morgan; ok markus@ + +commit d2c3cd5f2e47ee24cf7093ce8e948c2e79dfc3fd +Author: Damien Miller +Date: Fri Jul 4 08:59:01 2014 +1000 + + - jsing@cvs.openbsd.org 2014/07/03 12:42:16 + [cipher-chachapoly.c] + Call chacha_ivsetup() immediately before chacha_encrypt_bytes() - this + makes it easier to verify that chacha_encrypt_bytes() is only called once + per chacha_ivsetup() call. + ok djm@ + +commit 686feb560ec43a06ba04da82b50f3c183c947309 +Author: Damien Miller +Date: Thu Jul 3 21:29:38 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 11:16:55 + [auth.c auth.h auth1.c auth2.c] + make the "Too many authentication failures" message include the + user, source address, port and protocol in a format similar to the + authentication success / failure messages; bz#2199, ok dtucker + +commit 0f12341402e18fd9996ec23189b9418d2722453f +Author: Damien Miller +Date: Thu Jul 3 21:28:09 2014 +1000 + + - jmc@cvs.openbsd.org 2014/07/03 07:45:27 + [ssh_config.5] + escape %C since groff thinks it part of an Rs/Re block; + +commit 9c38643c5cd47a19db2cc28279dcc28abadc22b3 +Author: Damien Miller +Date: Thu Jul 3 21:27:46 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 06:39:19 + [ssh.c ssh_config.5] + Add a %C escape sequence for LocalCommand and ControlPath that expands + to a unique identifer based on a has of the tuple of (local host, + remote user, hostname, port). + + Helps avoid exceeding sockaddr_un's miserly pathname limits for mux + control paths. + + bz#2220, based on patch from mancha1 AT zoho.com; ok markus@ + +commit 49d9bfe2b2f3e90cc158a215dffa7675e57e7830 +Author: Damien Miller +Date: Thu Jul 3 21:26:42 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 05:38:17 + [ssh.1] + document that -g will only work in the multiplexed case if applied to + the mux master + +commit ef9f13ba4c58057b2166d1f2e790535da402fbe5 +Author: Damien Miller +Date: Thu Jul 3 21:26:21 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 05:32:36 + [ssh_config.5] + mention '%%' escape sequence in HostName directives and how it may + be used to specify IPv6 link-local addresses + +commit e6a407789e5432dd2e53336fb73476cc69048c54 +Author: Damien Miller +Date: Thu Jul 3 21:25:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 04:36:45 + [digest.h] + forward-declare struct sshbuf so consumers don't need to include sshbuf.h + +commit 4a1d3d50f02d0a8a4ef95ea4749293cbfb89f919 +Author: Damien Miller +Date: Thu Jul 3 21:24:40 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:47:27 + [ssh-keygen.c] + When hashing or removing hosts using ssh-keygen, don't choke on + @revoked markers and don't remove @cert-authority markers; + bz#2241, reported by mlindgren AT runelind.net + +commit e5c0d52ceb575c3db8c313e0b1aa3845943d7ba8 +Author: Damien Miller +Date: Thu Jul 3 21:24:19 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:34:09 + [gss-serv.c session.c ssh-keygen.c] + standardise on NI_MAXHOST for gethostname() string lengths; about + 1/2 the cases were using it already. Fixes bz#2239 en passant + +commit c174a3b7c14e0d178c61219de2aa1110e209950c +Author: Damien Miller +Date: Thu Jul 3 21:23:24 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:26:43 + [digest-openssl.c] + use EVP_Digest() for one-shot hash instead of creating, updating, + finalising and destroying a context. + bz#2231, based on patch from Timo Teras + +commit d7ca2cd31ecc4d63a055e2dcc4bf35c13f2db4c5 +Author: Damien Miller +Date: Thu Jul 3 21:23:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:15:01 + [ssh-add.c] + make stdout line-buffered; saves partial output getting lost when + ssh-add fatal()s part-way through (e.g. when listing keys from an + agent that supports key types that ssh-add doesn't); + bz#2234, reported by Phil Pennock + +commit b1e967c8d7c7578dd0c172d85b3046cf54ea42ba +Author: Damien Miller +Date: Thu Jul 3 21:22:40 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 03:11:03 + [ssh-agent.c] + Only cleanup agent socket in the main agent process and not in any + subprocesses it may have started (e.g. forked askpass). Fixes + agent sockets being zapped when askpass processes fatal(); + bz#2236 patch from Dmitry V. Levin + +commit 61e28e55c3438d796b02ef878bcd28620d452670 +Author: Damien Miller +Date: Thu Jul 3 21:22:22 2014 +1000 + + - djm@cvs.openbsd.org 2014/07/03 01:45:38 + [sshkey.c] + make Ed25519 keys' title fit properly in the randomart border; bz#2247 + based on patch from Christian Hesse + +commit 9eb4cd9a32c32d40d36450b68ed93badc6a94c68 +Author: Damien Miller +Date: Thu Jul 3 13:29:50 2014 +1000 + + - (djm) [monitor_fdpass.c] Use sys/poll.h if poll.h doesn't exist; + bz#2237 + +commit 8da0fa24934501909408327298097b1629b89eaa +Author: Damien Miller +Date: Thu Jul 3 11:54:19 2014 +1000 + + - (djm) [digest-openssl.c configure.ac] Disable RIPEMD160 if libcrypto + doesn't support it. + +commit 81309c857dd0dbc0a1245a16d621c490ad48cfbb +Author: Damien Miller +Date: Wed Jul 2 17:45:55 2014 +1000 + + - (djm) [regress/Makefile] fix execution of sshkey unit/fuzz test + +commit 82b2482ce68654815ee049b9bf021bb362a35ff2 +Author: Damien Miller +Date: Wed Jul 2 17:43:41 2014 +1000 + + - (djm) [sshkey.c] Conditionalise inclusion of util.h + +commit dd8b1dd7933eb6f5652641b0cdced34a387f2e80 +Author: Damien Miller +Date: Wed Jul 2 17:38:31 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 01:14:17 + [Makefile.in regress/Makefile regress/unittests/Makefile] + [regress/unittests/sshkey/Makefile] + [regress/unittests/sshkey/common.c] + [regress/unittests/sshkey/common.h] + [regress/unittests/sshkey/mktestdata.sh] + [regress/unittests/sshkey/test_file.c] + [regress/unittests/sshkey/test_fuzz.c] + [regress/unittests/sshkey/test_sshkey.c] + [regress/unittests/sshkey/tests.c] + [regress/unittests/sshkey/testdata/dsa_1] + [regress/unittests/sshkey/testdata/dsa_1-cert.fp] + [regress/unittests/sshkey/testdata/dsa_1-cert.pub] + [regress/unittests/sshkey/testdata/dsa_1.fp] + [regress/unittests/sshkey/testdata/dsa_1.fp.bb] + [regress/unittests/sshkey/testdata/dsa_1.param.g] + [regress/unittests/sshkey/testdata/dsa_1.param.priv] + [regress/unittests/sshkey/testdata/dsa_1.param.pub] + [regress/unittests/sshkey/testdata/dsa_1.pub] + [regress/unittests/sshkey/testdata/dsa_1_pw] + [regress/unittests/sshkey/testdata/dsa_2] + [regress/unittests/sshkey/testdata/dsa_2.fp] + [regress/unittests/sshkey/testdata/dsa_2.fp.bb] + [regress/unittests/sshkey/testdata/dsa_2.pub] + [regress/unittests/sshkey/testdata/dsa_n] + [regress/unittests/sshkey/testdata/dsa_n_pw] + [regress/unittests/sshkey/testdata/ecdsa_1] + [regress/unittests/sshkey/testdata/ecdsa_1-cert.fp] + [regress/unittests/sshkey/testdata/ecdsa_1-cert.pub] + [regress/unittests/sshkey/testdata/ecdsa_1.fp] + [regress/unittests/sshkey/testdata/ecdsa_1.fp.bb] + [regress/unittests/sshkey/testdata/ecdsa_1.param.curve] + [regress/unittests/sshkey/testdata/ecdsa_1.param.priv] + [regress/unittests/sshkey/testdata/ecdsa_1.param.pub] + [regress/unittests/sshkey/testdata/ecdsa_1.pub] + [regress/unittests/sshkey/testdata/ecdsa_1_pw] + [regress/unittests/sshkey/testdata/ecdsa_2] + [regress/unittests/sshkey/testdata/ecdsa_2.fp] + [regress/unittests/sshkey/testdata/ecdsa_2.fp.bb] + [regress/unittests/sshkey/testdata/ecdsa_2.param.curve] + [regress/unittests/sshkey/testdata/ecdsa_2.param.priv] + [regress/unittests/sshkey/testdata/ecdsa_2.param.pub] + [regress/unittests/sshkey/testdata/ecdsa_2.pub] + [regress/unittests/sshkey/testdata/ecdsa_n] + [regress/unittests/sshkey/testdata/ecdsa_n_pw] + [regress/unittests/sshkey/testdata/ed25519_1] + [regress/unittests/sshkey/testdata/ed25519_1-cert.fp] + [regress/unittests/sshkey/testdata/ed25519_1-cert.pub] + [regress/unittests/sshkey/testdata/ed25519_1.fp] + [regress/unittests/sshkey/testdata/ed25519_1.fp.bb] + [regress/unittests/sshkey/testdata/ed25519_1.pub] + [regress/unittests/sshkey/testdata/ed25519_1_pw] + [regress/unittests/sshkey/testdata/ed25519_2] + [regress/unittests/sshkey/testdata/ed25519_2.fp] + [regress/unittests/sshkey/testdata/ed25519_2.fp.bb] + [regress/unittests/sshkey/testdata/ed25519_2.pub] + [regress/unittests/sshkey/testdata/pw] + [regress/unittests/sshkey/testdata/rsa1_1] + [regress/unittests/sshkey/testdata/rsa1_1.fp] + [regress/unittests/sshkey/testdata/rsa1_1.fp.bb] + [regress/unittests/sshkey/testdata/rsa1_1.param.n] + [regress/unittests/sshkey/testdata/rsa1_1.pub] + [regress/unittests/sshkey/testdata/rsa1_1_pw] + [regress/unittests/sshkey/testdata/rsa1_2] + [regress/unittests/sshkey/testdata/rsa1_2.fp] + [regress/unittests/sshkey/testdata/rsa1_2.fp.bb] + [regress/unittests/sshkey/testdata/rsa1_2.param.n] + [regress/unittests/sshkey/testdata/rsa1_2.pub] + [regress/unittests/sshkey/testdata/rsa_1] + [regress/unittests/sshkey/testdata/rsa_1-cert.fp] + [regress/unittests/sshkey/testdata/rsa_1-cert.pub] + [regress/unittests/sshkey/testdata/rsa_1.fp] + [regress/unittests/sshkey/testdata/rsa_1.fp.bb] + [regress/unittests/sshkey/testdata/rsa_1.param.n] + [regress/unittests/sshkey/testdata/rsa_1.param.p] + [regress/unittests/sshkey/testdata/rsa_1.param.q] + [regress/unittests/sshkey/testdata/rsa_1.pub] + [regress/unittests/sshkey/testdata/rsa_1_pw] + [regress/unittests/sshkey/testdata/rsa_2] + [regress/unittests/sshkey/testdata/rsa_2.fp] + [regress/unittests/sshkey/testdata/rsa_2.fp.bb] + [regress/unittests/sshkey/testdata/rsa_2.param.n] + [regress/unittests/sshkey/testdata/rsa_2.param.p] + [regress/unittests/sshkey/testdata/rsa_2.param.q] + [regress/unittests/sshkey/testdata/rsa_2.pub] + [regress/unittests/sshkey/testdata/rsa_n] + [regress/unittests/sshkey/testdata/rsa_n_pw] + unit and fuzz tests for new key API + +commit c1dc24b71f087f385b92652b9673f52af64e0428 +Author: Damien Miller +Date: Wed Jul 2 17:02:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 01:04:43 + [regress/krl.sh] + regress test for broken consecutive revoked serial number ranges + +commit 43d3ed2dd3feca6d0326c7dc82588d2faa115e92 +Author: Damien Miller +Date: Wed Jul 2 17:01:08 2014 +1000 + + - djm@cvs.openbsd.org 2014/05/21 07:04:21 + [regress/integrity.sh] + when failing because of unexpected output, show the offending output + +commit 5a96707ffc8d227c2e7d94fa6b0317f8a152cf4e +Author: Damien Miller +Date: Wed Jul 2 15:38:05 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/30 05:32:00 + [regress/Makefile] + unit tests for new buffer API; including basic fuzz testing + NB. Id sync only. + +commit 3ff92ba756aee48e4ae3e0aeff7293517b3dd185 +Author: Damien Miller +Date: Wed Jul 2 15:33:09 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/30 12:54:39 + [key.c] + suppress spurious error message when loading key with a passphrase; + reported by kettenis@ ok markus@ + - djm@cvs.openbsd.org 2014/07/02 04:59:06 + [cipher-3des1.c] + fix ssh protocol 1 on the server that regressed with the sshkey change + (sometimes fatal() after auth completed), make file return useful status + codes. + NB. Id sync only for these two. They were bundled into the sshkey merge + above, since it was easier to sync the entire file and then apply + portable-specific changed atop it. + +commit ec3d0e24a1e46873d80507f5cd8ee6d0d03ac5dc +Author: Damien Miller +Date: Wed Jul 2 15:30:00 2014 +1000 + + - markus@cvs.openbsd.org 2014/06/27 18:50:39 + [ssh-add.c] + fix loading of private keys + +commit 4b3ed647d5b328cf68e6a8ffbee490d8e0683e82 +Author: Damien Miller +Date: Wed Jul 2 15:29:40 2014 +1000 + + - markus@cvs.openbsd.org 2014/06/27 16:41:56 + [channels.c channels.h clientloop.c ssh.c] + fix remote fwding with same listen port but different listen address + with gerhard@, ok djm@ + +commit 9e01ff28664921ce9b6500681333e42fb133b4d0 +Author: Damien Miller +Date: Wed Jul 2 15:29:21 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/06/25 14:16:09 + [sshbuf.c] + unblock SIGSEGV before raising it + ok djm + +commit 1845fe6bda0729e52f4c645137f4fc3070b5438a +Author: Damien Miller +Date: Wed Jul 2 15:29:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 02:21:01 + [scp.c] + when copying local->remote fails during read, don't send uninitialised + heap to the remote end. Reported by Jann Horn + +commit 19439e9a2a0ac0b4b3b1210e89695418beb1c883 +Author: Damien Miller +Date: Wed Jul 2 15:28:40 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 02:19:48 + [ssh.c] + don't fatal() when hostname canonicalisation fails with a + ProxyCommand in use; continue and allow the ProxyCommand to + connect anyway (e.g. to a host with a name outside the DNS + behind a bastion) + +commit 8668706d0f52654fe64c0ca41a96113aeab8d2b8 +Author: Damien Miller +Date: Wed Jul 2 15:28:02 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 01:13:21 + [Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c + [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c + [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h + [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h + [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h + [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c + [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c + [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c + [sshconnect2.c sshd.c sshkey.c sshkey.h + [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h] + New key API: refactor key-related functions to be more library-like, + existing API is offered as a set of wrappers. + + with and ok markus@ + + Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew + Dempsky and Ron Bowes for a detailed review a few months ago. + + NB. This commit also removes portable OpenSSH support for OpenSSL + <0.9.8e. + +commit 2cd7929250cf9e9f658d70dcd452f529ba08c942 +Author: Damien Miller +Date: Wed Jul 2 12:48:30 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/24 00:52:02 + [krl.c] + fix bug in KRL generation: multiple consecutive revoked certificate + serial number ranges could be serialised to an invalid format. + + Readers of a broken KRL caused by this bug will fail closed, so no + should-have-been-revoked key will be accepted. + +commit 99db840ee8dbbd2b3fbc6c45d0ee2f6a65e96898 +Author: Damien Miller +Date: Wed Jul 2 12:48:04 2014 +1000 + + - naddy@cvs.openbsd.org 2014/06/18 15:42:09 + [sshbuf-getput-crypto.c] + The ssh_get_bignum functions must accept the same range of bignums + the corresponding ssh_put_bignum functions create. This fixes the + use of 16384-bit RSA keys (bug reported by Eivind Evensen). + ok djm@ + +commit 84a89161a9629239b64171ef3e22ef6a3e462d51 +Author: Damien Miller +Date: Wed Jul 2 12:47:48 2014 +1000 + + - matthew@cvs.openbsd.org 2014/06/18 02:59:13 + [sandbox-systrace.c] + Now that we have a dedicated getentropy(2) system call for + arc4random(3), we can disallow __sysctl(2) in OpenSSH's systrace + sandbox. + + ok djm + +commit 51504ceec627c0ad57b9f75585c7b3d277f326be +Author: Damien Miller +Date: Wed Jul 2 12:47:25 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/06/13 08:26:29 + [sandbox-systrace.c] + permit SYS_getentropy + from matthew + +commit a261b8df59117f7dc52abb3a34b35a40c2c9fa88 +Author: Tim Rice +Date: Wed Jun 18 16:17:28 2014 -0700 + + - (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare + +commit 316fac6f18f87262a315c79bcf68b9f92c9337e4 +Author: Darren Tucker +Date: Tue Jun 17 23:06:07 2014 +1000 + + - (dtucker) [entropy.c openbsd-compat/openssl-compat.{c,h} + openbsd-compat/regress/{.cvsignore,Makefile.in,opensslvertest.c}] + Move the OpenSSL header/library version test into its own function and add + tests for it. Fix it to allow fix version upgrades (but not downgrades). + Prompted by chl@ via OpenSMTPD (issue #462) and Debian (bug #748150). + ok djm@ chl@ + +commit af665bb7b092a59104db1e65577851cf35b86e32 +Author: Darren Tucker +Date: Mon Jun 16 22:50:55 2014 +1000 + + - (dtucker) [defines.h] Fix undef of _PATH_MAILDIR. From rak at debian via + OpenSMTPD and chl@ + +commit f9696566fb41320820f3b257ab564fa321bb3751 +Author: Darren Tucker +Date: Fri Jun 13 11:06:04 2014 +1000 + + - (dtucker) [configure.ac] Remove tcpwrappers support, support has already + been removed from sshd.c. + +commit 5e2b8894b0b24af4ad0a2f7aa33ebf255df7a8bc +Author: Tim Rice +Date: Wed Jun 11 18:31:10 2014 -0700 + + - (tim) [regress/unittests/test_helper/test_helper.h] Add includes.h for + u_intXX_t types. + +commit 985ee2cbc3e43bc65827c3c0d4df3faa99160c37 +Author: Darren Tucker +Date: Thu Jun 12 05:32:29 2014 +1000 + + - (dtucker) [regress/unittests/sshbuf/*.c regress/unittests/test_helper/*] + Wrap stdlib.h include an ifdef for platforms that don't have it. + +commit cf5392c2db2bb1dbef9818511d34056404436109 +Author: Darren Tucker +Date: Thu Jun 12 05:22:49 2014 +1000 + + - (dtucker) [defines.h] Add va_copy if we don't already have it, taken from + openbsd-compat/bsd-asprintf.c. + +commit 58538d795e0b662f2f4e5a7193f1204bbe992ddd +Author: Darren Tucker +Date: Wed Jun 11 13:39:24 2014 +1000 + + - (dtucker) [bufaux.c bufbn.c bufec.c buffer.c] Pull in includes.h for + compat stuff, specifically whether or not OpenSSL has ECC. + +commit eb012ac581fd0abc16ee86ee3a68cf07c8ce4d08 +Author: Darren Tucker +Date: Wed Jun 11 13:10:00 2014 +1000 + + - (dtucker) [openbsd-compat/arc4random.c] Use explicit_bzero instead of an + assigment that might get optimized out. ok djm@ + +commit b9609fd86c623d6d440e630f5f9a63295f7aea20 +Author: Darren Tucker +Date: Wed Jun 11 08:04:02 2014 +1000 + + - (dtucker) [sshbuf.h] Only declare ECC functions if building without + OpenSSL or if OpenSSL has ECC. + +commit a54a040f66944c6e8913df8635a01a2327219be9 +Author: Darren Tucker +Date: Wed Jun 11 07:58:35 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/06/10 21:46:11 + [sshbuf.h] + Group ECC functions together to make things a little easier in -portable. + "doesn't bother me" deraadt@ + +commit 9f92c53bad04a89067756be8198d4ec2d8a08875 +Author: Darren Tucker +Date: Wed Jun 11 07:57:58 2014 +1000 + + - djm@cvs.openbsd.org 2014/06/05 22:17:50 + [sshconnect2.c] + fix inverted test that caused PKCS#11 keys that were explicitly listed + not to be preferred. Reported by Dirk-Willem van Gulik + +commit 15c254a25394f96643da2ad0f674acdc51e89856 +Author: Darren Tucker +Date: Wed Jun 11 07:38:49 2014 +1000 + + - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] ifdef + ECC variable too. + +commit d7af0cc5bf273eeed0897a99420bc26841d07d8f +Author: Darren Tucker +Date: Wed Jun 11 07:37:25 2014 +1000 + + - (dtucker) [myprosal.h] Don't include curve25519-sha256@libssh.org in + the proposal if the version of OpenSSL we're using doesn't support ECC. + +commit 67508ac2563c33d582be181a3e777c65f549d22f +Author: Darren Tucker +Date: Wed Jun 11 06:27:16 2014 +1000 + + - (dtucker) [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c + regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] Only do NISTP256 + curve tests if OpenSSL has them. + +commit 6482d90a65459a88c18c925368525855832272b3 +Author: Damien Miller +Date: Tue May 27 14:34:42 2014 +1000 + + - (djm) [configure.ac openbsd-compat/bsd-cygwin_util.c] + [openbsd-compat/bsd-cygwin_util.h] On Cygwin, determine privilege + separation user at runtime, since it may need to be a domain account. + Patch from Corinna Vinschen. + +commit f9eb5e0734f7a7f6e975809eb54684d2a06a7ffc +Author: Damien Miller +Date: Tue May 27 14:31:58 2014 +1000 + + - (djm) [contrib/cygwin/ssh-host-config] Updated Cygwin ssh-host-config + from Corinna Vinschen, fixing a number of bugs and preparing for + Cygwin 1.7.30. + +commit eae88744662e6b149f43ef071657727f1a157d95 +Author: Damien Miller +Date: Tue May 27 14:27:02 2014 +1000 + + - (djm) [cipher.c] Fix merge botch. + +commit 564b5e253c1d95c26a00e8288f0089a2571661c3 +Author: Damien Miller +Date: Thu May 22 08:23:59 2014 +1000 + + - (djm) [Makefile.in] typo in path + +commit e84d10302aeaf7a1acb05c451f8718143656856a +Author: Damien Miller +Date: Wed May 21 17:13:36 2014 +1000 + + revert a diff I didn't mean to commit + +commit 795b86313f1f1aab9691666c4f2d5dae6e4acd50 +Author: Damien Miller +Date: Wed May 21 17:12:53 2014 +1000 + + - (djm) [misc.c] Use CLOCK_BOOTTIME in preference to CLOCK_MONOTONIC + when it is available. It takes into account time spent suspended, + thereby ensuring timeouts (e.g. for expiring agent keys) fire + correctly. bz#2228 reported by John Haxby + +commit 18912775cb97c0b1e75e838d3c7d4b56648137b5 +Author: Damien Miller +Date: Wed May 21 17:06:46 2014 +1000 + + - (djm) [commit configure.ac defines.h sshpty.c] don't attempt to use + vhangup on Linux. It doens't work for non-root users, and for them + it just messes up the tty settings. + +commit 7f1c264d3049cd95234e91970ccb5406e1d15b27 +Author: Damien Miller +Date: Thu May 15 18:01:52 2014 +1000 + + - (djm) [sshbuf.c] need __predict_false + +commit e7429f2be8643e1100380a8a7389d85cc286c8fe +Author: Damien Miller +Date: Thu May 15 18:01:01 2014 +1000 + + - (djm) [regress/Makefile Makefile.in] + [regress/unittests/sshbuf/test_sshbuf.c + [regress/unittests/sshbuf/test_sshbuf_fixed.c] + [regress/unittests/sshbuf/test_sshbuf_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] + [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] + [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_misc.c] + [regress/unittests/sshbuf/tests.c] + [regress/unittests/test_helper/fuzz.c] + [regress/unittests/test_helper/test_helper.c] + Hook new unit tests into the build and "make tests" + +commit def1de086707b0e6b046fe7e115c60aca0227a99 +Author: Damien Miller +Date: Thu May 15 15:17:15 2014 +1000 + + - (djm) [regress/unittests/Makefile] + [regress/unittests/Makefile.inc] + [regress/unittests/sshbuf/Makefile] + [regress/unittests/sshbuf/test_sshbuf.c] + [regress/unittests/sshbuf/test_sshbuf_fixed.c] + [regress/unittests/sshbuf/test_sshbuf_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_getput_basic.c] + [regress/unittests/sshbuf/test_sshbuf_getput_crypto.c] + [regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c] + [regress/unittests/sshbuf/test_sshbuf_misc.c] + [regress/unittests/sshbuf/tests.c] + [regress/unittests/test_helper/Makefile] + [regress/unittests/test_helper/fuzz.c] + [regress/unittests/test_helper/test_helper.c] + [regress/unittests/test_helper/test_helper.h] + Import new unit tests from OpenBSD; not yet hooked up to build. + +commit 167685756fde8bc213a8df2c8e1848e312db0f46 +Author: Damien Miller +Date: Thu May 15 15:08:40 2014 +1000 + + - logan@cvs.openbsd.org 2014/05/04 10:40:59 + [connect-privsep.sh] + Remove the Z flag from the list of malloc options as it + was removed from malloc.c 10 days ago. + + OK from miod@ + +commit d0b69fe90466920d69c96069312e24b581771bd7 +Author: Damien Miller +Date: Thu May 15 15:08:19 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/05/03 18:46:14 + [proxy-connect.sh] + Add tests for with and without compression, with and without privsep. + +commit edb1af50441d19fb2dd9ccb4d75bf14473fca584 +Author: Damien Miller +Date: Thu May 15 15:07:53 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/21 22:15:37 + [dhgex.sh integrity.sh kextype.sh rekey.sh try-ciphers.sh] + repair regress tests broken by server-side default cipher/kex/mac changes + by ensuring that the option under test is included in the server's + algorithm list + +commit 54343e95c70994695f8842fb22836321350198d3 +Author: Damien Miller +Date: Thu May 15 15:07:33 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/13 20:44:49 + [login-timeout.sh] + this test is a sorry mess of race conditions; add another sleep + to avoid a failure on slow machines (at least until I find a + better way) + +commit e5b9f0f2ee6e133894307e44e862b66426990733 +Author: Damien Miller +Date: Thu May 15 14:58:07 2014 +1000 + + - (djm) [Makefile.in configure.ac sshbuf-getput-basic.c] + [sshbuf-getput-crypto.c sshbuf.c] compilation and portability fixes + +commit b9c566788a9ebd6a9d466f47a532124f111f0542 +Author: Damien Miller +Date: Thu May 15 14:43:37 2014 +1000 + + - (djm) [configure.ac] Unconditionally define WITH_OPENSSL until we write + portability glue to support building without libcrypto + +commit 3dc27178b42234b653a32f7a87292d7994045ee3 +Author: Damien Miller +Date: Thu May 15 14:37:59 2014 +1000 + + - logan@cvs.openbsd.org 2014/05/05 07:02:30 + [sftp.c] + Zap extra whitespace. + + OK from djm@ and dtucker@ + +commit c31a0cd5b31961f01c5b731f62a6cb9d4f767472 +Author: Damien Miller +Date: Thu May 15 14:37:39 2014 +1000 + + - markus@cvs.openbsd.org 2014/05/03 17:20:34 + [monitor.c packet.c packet.h] + unbreak compression, by re-init-ing the compression code in the + post-auth child. the new buffer code is more strict, and requires + buffer_init() while the old code was happy after a bzero(); + originally from djm@ + +commit 686c7d9ee6f44b2be4128d7860b6b37adaeba733 +Author: Damien Miller +Date: Thu May 15 14:37:03 2014 +1000 + + - djm@cvs.openbsd.org 2014/05/02 03:27:54 + [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c] + [misc.h poly1305.h ssh-pkcs11.c defines.h] + revert __bounded change; it causes way more problems for portable than + it solves; pointed out by dtucker@ + +commit 294c58a007cfb2f3bddc4fc3217e255857ffb9bf +Author: Damien Miller +Date: Thu May 15 14:35:03 2014 +1000 + + - naddy@cvs.openbsd.org 2014/04/30 19:07:48 + [mac.c myproposal.h umac.c] + UMAC can use our local fallback implementation of AES when OpenSSL isn't + available. Glue code straight from Ted Krovetz's original umac.c. + ok markus@ + +commit 05e82c3b963c33048128baf72a6f6b3a1c10b4c1 +Author: Damien Miller +Date: Thu May 15 14:33:43 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/30 05:29:56 + [bufaux.c bufbn.c bufec.c buffer.c buffer.h sshbuf-getput-basic.c] + [sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c sshbuf.h ssherr.c] + [ssherr.h] + New buffer API; the first installment of the conversion/replacement + of OpenSSH's internals to make them usable as a standalone library. + + This includes a set of wrappers to make it compatible with the + existing buffer API so replacement can occur incrementally. + + With and ok markus@ + + Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew + Dempsky and Ron Bowes for a detailed review. + +commit 380948180f847a26f2d0c85b4dad3dca2ed2fd8b +Author: Damien Miller +Date: Thu May 15 14:25:18 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/04/29 20:36:51 + [sftp.c] + Don't attempt to append a nul quote char to the filename. Should prevent + fatal'ing with "el_insertstr failed" when there's a single quote char + somewhere in the string. bz#2238, ok markus@ + +commit d7fd8bedd4619a2ec7fd02aae4c4e1db4431ad9f +Author: Damien Miller +Date: Thu May 15 14:24:59 2014 +1000 + + - dtucker@cvs.openbsd.org 2014/04/29 19:58:50 + [sftp.c] + Move nulling of variable next to where it's freed. ok markus@ + +commit 1f0311c7c7d10c94ff7f823de9c5b2ed79368b14 +Author: Damien Miller +Date: Thu May 15 14:24:09 2014 +1000 + + - markus@cvs.openbsd.org 2014/04/29 18:01:49 + [auth.c authfd.c authfile.c bufaux.c cipher.c cipher.h hostfile.c] + [kex.c key.c mac.c monitor.c monitor_wrap.c myproposal.h packet.c] + [roaming_client.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c] + [ssh-pkcs11.h ssh.c sshconnect.c sshconnect2.c sshd.c] + make compiling against OpenSSL optional (make OPENSSL=no); + reduces algorithms to curve25519, aes-ctr, chacha, ed25519; + allows us to explore further options; with and ok djm + +commit c5893785564498cea73cb60d2cf199490483e080 +Author: Damien Miller +Date: Thu May 15 13:48:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/29 13:10:30 + [clientloop.c serverloop.c] + bz#1818 - don't send channel success/failre replies on channels that + have sent a close already; analysis and patch from Simon Tatham; + ok markus@ + +commit 633de33b192d808d87537834c316dc8b75fe1880 +Author: Damien Miller +Date: Thu May 15 13:48:26 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/28 03:09:18 + [authfile.c bufaux.c buffer.h channels.c krl.c mux.c packet.c packet.h] + [ssh-keygen.c] + buffer_get_string_ptr's return should be const to remind + callers that futzing with it will futz with the actual buffer + contents + +commit 15271907843e4ae50dcfc83b3594014cf5e9607b +Author: Damien Miller +Date: Thu May 15 13:47:56 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/23 12:42:34 + [readconf.c] + don't record duplicate IdentityFiles + +commit 798a02568b13a2e46efebd81f08c8f4bb33a6dc7 +Author: Damien Miller +Date: Thu May 15 13:47:37 2014 +1000 + + - jmc@cvs.openbsd.org 2014/04/22 14:16:30 + [sftp.1] + zap eol whitespace; + +commit d875ff78d2b8436807381051de112f0ebf9b9ae1 +Author: Damien Miller +Date: Thu May 15 13:47:15 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/22 12:42:04 + [sftp.1] + Document sftp upload resume. + OK from djm@, with feedback from okan@. + +commit b15cd7bb097fd80dc99520f45290ef775da1ef19 +Author: Damien Miller +Date: Thu May 15 13:46:52 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/22 10:07:12 + [sftp.c] + Sort the sftp command list. + OK from djm@ + +commit d8accc0aa72656ba63d50937165c5ae49db1dcd6 +Author: Damien Miller +Date: Thu May 15 13:46:25 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/21 14:36:16 + [sftp-client.c sftp-client.h sftp.c] + Implement sftp upload resume support. + OK from djm@, with input from guenther@, mlarkin@ and + okan@ + +commit 16cd3928a87d20c77b13592a74b60b08621d3ce6 +Author: Damien Miller +Date: Thu May 15 13:45:58 2014 +1000 + + - logan@cvs.openbsd.org 2014/04/20 09:24:26 + [dns.c dns.h ssh-keygen.c] + Add support for SSHFP DNS records for ED25519 key types. + OK from djm@ + +commit ec0b67eb3b4e12f296ced1fafa01860c374f7eea +Author: Damien Miller +Date: Thu May 15 13:45:26 2014 +1000 + + - (djm) [rijndael.c rijndael.h] Sync with newly-ressurected versions ine + OpenBSD + +commit f028460d0b2e5a584355321015cde69bf6fd933e +Author: Darren Tucker +Date: Thu May 1 02:24:35 2014 +1000 + + - (dtucker) [defines.h] Define __GNUC_PREREQ__ macro if we don't already + have it. Only attempt to use __attribute__(__bounded__) for gcc. + +commit b628cc4c3e4a842bab5e4584d18c2bc5fa4d0edf +Author: Damien Miller +Date: Sun Apr 20 13:33:58 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/20 02:49:32 + [compat.c] + add a canonical 6.6 + curve25519 bignum fix fake version that I can + recommend people use ahead of the openssh-6.7 release + +commit 888566913933a802f3a329ace123ebcb7154cf78 +Author: Damien Miller +Date: Sun Apr 20 13:33:19 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/20 02:30:25 + [misc.c misc.h umac.c] + use get/put_u32 to load values rather than *((UINT32 *)p) that breaks on + strict-alignment architectures; reported by and ok stsp@ + +commit 16f85cbc7e5139950e6a38317e7c8b368beafa5d +Author: Damien Miller +Date: Sun Apr 20 13:29:28 2014 +1000 + + - tedu@cvs.openbsd.org 2014/04/19 18:42:19 + [ssh.1] + delete .xr to hosts.equiv. there's still an unfortunate amount of + documentation referring to rhosts equivalency in here. + +commit 69cb24b7356ec3f0fc5ff04a68f98f2c55c766f4 +Author: Damien Miller +Date: Sun Apr 20 13:29:06 2014 +1000 + + - tedu@cvs.openbsd.org 2014/04/19 18:15:16 + [sshd.8] + remove some really old rsh references + +commit 84c1e7bca8c4ceaccf4d5557e39a833585a3c77e +Author: Damien Miller +Date: Sun Apr 20 13:27:53 2014 +1000 + + - tedu@cvs.openbsd.org 2014/04/19 14:53:48 + [ssh-keysign.c sshd.c] + Delete futile calls to RAND_seed. ok djm + NB. Id sync only. This only applies to OpenBSD's libcrypto slashathon + +commit 0e6b67423b8662f9ca4c92750309e144fd637ef1 +Author: Damien Miller +Date: Sun Apr 20 13:27:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/19 05:54:59 + [compat.c] + missing wildcard; pointed out by naddy@ + +commit 9395b28223334826837c15e8c1bb4dfb3b0d2ca5 +Author: Damien Miller +Date: Sun Apr 20 13:25:30 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/18 23:52:25 + [compat.c compat.h sshconnect2.c sshd.c version.h] + OpenSSH 6.5 and 6.6 have a bug that causes ~0.2% of connections + using the curve25519-sha256@libssh.org KEX exchange method to fail + when connecting with something that implements the spec properly. + + Disable this KEX method when speaking to one of the affected + versions. + + reported by Aris Adamantiadis; ok markus@ + +commit 8c492da58f8ceb85cf5f7066f23e26fb813a963d +Author: Damien Miller +Date: Sun Apr 20 13:25:09 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/16 23:28:12 + [ssh-agent.1] + remove the identity files from this manpage - ssh-agent doesn't deal + with them at all and the same information is duplicated in ssh-add.1 + (which does deal with them); prodded by deraadt@ + +commit adbfdbbdccc70c9bd70d81ae096db115445c6e26 +Author: Damien Miller +Date: Sun Apr 20 13:24:49 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/16 23:22:45 + [bufaux.c] + skip leading zero bytes in buffer_put_bignum2_from_string(); + reported by jan AT mojzis.com; ok markus@ + +commit 75c62728dc87af6805696eeb520b9748faa136c8 +Author: Damien Miller +Date: Sun Apr 20 13:24:31 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/12 04:55:53 + [sshd.c] + avoid crash at exit: check that pmonitor!=NULL before dereferencing; + bz#2225, patch from kavi AT juniper.net + +commit 2a328437fb1b0976f2f4522d8645803d5a5d0967 +Author: Damien Miller +Date: Sun Apr 20 13:24:01 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/01 05:32:57 + [packet.c] + demote a debug3 to PACKET_DEBUG; ok markus@ + +commit 7d6a9fb660c808882d064e152d6070ffc3844c3f +Author: Damien Miller +Date: Sun Apr 20 13:23:43 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/01 03:34:10 + [sshconnect.c] + When using VerifyHostKeyDNS with a DNSSEC resolver, down-convert any + certificate keys to plain keys and attempt SSHFP resolution. + + Prevents a server from skipping SSHFP lookup and forcing a new-hostkey + dialog by offering only certificate keys. + + Reported by mcv21 AT cam.ac.uk + +commit fcd62c0b66b8415405ed0af29c236329eb88cc0f +Author: Damien Miller +Date: Sun Apr 20 13:23:21 2014 +1000 + + - djm@cvs.openbsd.org 2014/04/01 02:05:27 + [ssh-keysign.c] + include fingerprint of key not found + use arc4random_buf() instead of loop+arc4random() + +commit 43b156cf72f900f88065b0a1c1ebd09ab733ca46 +Author: Damien Miller +Date: Sun Apr 20 13:23:03 2014 +1000 + + - jmc@cvs.openbsd.org 2014/03/31 13:39:34 + [ssh-keygen.1] + the text for the -K option was inserted in the wrong place in -r1.108; + fix From: Matthew Clarke + +commit c1621c84f2dc1279065ab9fde2aa9327af418900 +Author: Damien Miller +Date: Sun Apr 20 13:22:46 2014 +1000 + + - naddy@cvs.openbsd.org 2014/03/28 05:17:11 + [ssh_config.5 sshd_config.5] + sync available and default algorithms, improve algorithm list formatting + help from jmc@ and schwarze@, ok deraadt@ + +commit f2719b7c2b8a3b14d778d8a6d8dc729b5174b054 +Author: Damien Miller +Date: Sun Apr 20 13:22:18 2014 +1000 + + - tedu@cvs.openbsd.org 2014/03/26 19:58:37 + [sshd.8 sshd.c] + remove libwrap support. ok deraadt djm mfriedl + +commit 4f40209aa4060b9c066a2f0d9332ace7b8dfb391 +Author: Damien Miller +Date: Sun Apr 20 13:21:22 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/26 04:55:35 + [chacha.h cipher-chachapoly.h digest.h hmac.h kex.h kexc25519.c + [misc.h poly1305.h ssh-pkcs11.c] + use __bounded(...) attribute recently added to sys/cdefs.h instead of + longform __attribute__(__bounded(...)); + + for brevity and a warning free compilation with llvm/clang + +commit 9235a030ad1b16903fb495d81544e0f7c7449523 +Author: Damien Miller +Date: Sun Apr 20 13:17:20 2014 +1000 + + Three commits in one (since they touch the same heavily-diverged file + repeatedly): + + - markus@cvs.openbsd.org 2014/03/25 09:40:03 + [myproposal.h] + trimm default proposals. + + This commit removes the weaker pre-SHA2 hashes, the broken ciphers + (arcfour), and the broken modes (CBC) from the default configuration + (the patch only changes the default, all the modes are still available + for the config files). + + ok djm@, reminded by tedu@ & naddy@ and discussed with many + - deraadt@cvs.openbsd.org 2014/03/26 17:16:26 + [myproposal.h] + The current sharing of myproposal[] between both client and server code + makes the previous diff highly unpallatable. We want to go in that + direction for the server, but not for the client. Sigh. + Brought up by naddy. + - markus@cvs.openbsd.org 2014/03/27 23:01:27 + [myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] + disable weak proposals in sshd, but keep them in ssh; ok djm@ + +commit 6e1777f592f15f4559728c78204617537b1ac076 +Author: Damien Miller +Date: Sun Apr 20 13:02:58 2014 +1000 + + - tedu@cvs.openbsd.org 2014/03/19 14:42:44 + [scp.1] + there is no need for rcp anymore + ok deraadt millert + +commit eb1b7c514d2a7b1802ccee8cd50e565a4d419887 +Author: Damien Miller +Date: Sun Apr 20 13:02:26 2014 +1000 + + - tedu@cvs.openbsd.org 2014/03/17 19:44:10 + [ssh.1] + old descriptions of des and blowfish are old. maybe ok deraadt + +commit f0858de6e1324ec730752387074b111b8551081e +Author: Damien Miller +Date: Sun Apr 20 13:01:30 2014 +1000 + + - deraadt@cvs.openbsd.org 2014/03/15 17:28:26 + [ssh-agent.c ssh-keygen.1 ssh-keygen.c] + Improve usage() and documentation towards the standard form. + In particular, this line saves a lot of man page reading time. + usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] + [-N new_passphrase] [-C comment] [-f output_keyfile] + ok schwarze jmc + +commit 94bfe0fbd6e91a56b5b0ab94ac955d2a67d101aa +Author: Damien Miller +Date: Sun Apr 20 13:00:51 2014 +1000 + + - naddy@cvs.openbsd.org 2014/03/12 13:06:59 + [ssh-keyscan.1] + scan for Ed25519 keys by default too + +commit 3819519288b2b3928c6882f5883b0f55148f4fc0 +Author: Damien Miller +Date: Sun Apr 20 13:00:28 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/12 04:51:12 + [authfile.c] + correct test that kdf name is not "none" or "bcrypt" + +commit 8f9cd709c7cf0655d414306a0ed28306b33802be +Author: Damien Miller +Date: Sun Apr 20 13:00:11 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/12 04:50:32 + [auth-bsdauth.c ssh-keygen.c] + don't count on things that accept arguments by reference to clear + things for us on error; most things do, but it's unsafe form. + +commit 1c7ef4be83f6dec84509a312518b9df00ab491d9 +Author: Damien Miller +Date: Sun Apr 20 12:59:46 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/12 04:44:58 + [ssh-keyscan.c] + scan for Ed25519 keys by default too + +commit c10bf4d051c97939b30a1616c0499310057d07da +Author: Damien Miller +Date: Sun Apr 20 12:58:04 2014 +1000 + + - djm@cvs.openbsd.org 2014/03/03 22:22:30 + [session.c] + ignore enviornment variables with embedded '=' or '\0' characters; + spotted by Jann Horn; ok deraadt@ + Id sync only - portable already has this. + +commit c2e49062faccbcd7135c40d1c78c5c329c58fc2e +Author: Damien Miller +Date: Tue Apr 1 14:42:46 2014 +1100 + + - (djm) Use full release (e.g. 6.5p1) in debug output rather than just + version. From des@des.no + +commit 14928b7492abec82afa4c2b778fc03f78cd419b6 +Author: Damien Miller +Date: Tue Apr 1 14:38:07 2014 +1100 + + - (djm) On platforms that support it, use prctl() to prevent sftp-server + from accessing /proc/self/{mem,maps}; patch from jann AT thejh.net + +commit 48abc47e60048461fe9117e108a7e99ea1ac2bb8 +Author: Damien Miller +Date: Mon Mar 17 14:45:56 2014 +1100 + + - (djm) [sandbox-seccomp-filter.c] Soft-fail stat() syscalls. Add XXX to + remind myself to add sandbox violation logging via the log socket. + +commit 9c36698ca2f554ec221dc7ef29c7a89e97c88705 +Author: Tim Rice +Date: Fri Mar 14 12:45:01 2014 -0700 + + 20140314 + - (tim) [opensshd.init.in] Add support for ed25519 + +commit 19158b2447e35838d69b2b735fb640d1e86061ea +Author: Damien Miller +Date: Thu Mar 13 13:14:21 2014 +1100 + + - (djm) Release OpenSSH 6.6 + +commit 8569eba5d7f7348ce3955eeeb399f66f25c52ece +Author: Damien Miller +Date: Tue Mar 4 09:35:17 2014 +1100 + + - djm@cvs.openbsd.org 2014/03/03 22:22:30 + [session.c] + ignore enviornment variables with embedded '=' or '\0' characters; + spotted by Jann Horn; ok deraadt@ + +commit 2476c31b96e89aec7d4e73cb6fbfb9a4290de3a7 +Author: Damien Miller +Date: Sun Mar 2 04:01:00 2014 +1100 + + - (djm) [regress/Makefile] Disable dhgex regress test; it breaks when + no moduli file exists at the expected location. + +commit c83fdf30e9db865575b2521b1fe46315cf4c70ae +Author: Damien Miller +Date: Fri Feb 28 10:34:03 2014 +1100 + + - (djm) [regress/host-expand.sh] Add RCS Id + +commit 834aeac3555e53f7d29a6fcf3db010dfb99681c7 +Author: Damien Miller +Date: Fri Feb 28 10:25:16 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 21:21:25 + [agent-ptrace.sh agent.sh] + keep return values that are printed in error messages; + from portable + (Id sync only) + +commit 4f7f1a9a0de24410c30952c7e16d433240422182 +Author: Damien Miller +Date: Fri Feb 28 10:24:11 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 20:04:16 + [login-timeout.sh] + remove any existing LoginGraceTime from sshd_config before adding + a specific one for the test back in + +commit d705d987c27f68080c8798eeb5262adbdd6b4ffd +Author: Damien Miller +Date: Fri Feb 28 10:23:26 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/26 10:49:17 + [scp-ssh-wrapper.sh scp.sh] + make sure $SCP is tested on the remote end rather than whichever one + happens to be in $PATH; from portable + (Id sync only) + +commit 624a3ca376e3955a4b9d936c9e899e241b65d357 +Author: Damien Miller +Date: Fri Feb 28 10:22:37 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/26 10:22:10 + [regress/cert-hostkey.sh] + automatically generate revoked keys from listed keys rather than + manually specifying each type; from portable + (Id sync only) + +commit b84392328425e4b9a71f8bde5fe6a4a4c48d3ec4 +Author: Damien Miller +Date: Fri Feb 28 10:21:26 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/25 04:35:32 + [regress/Makefile regress/dhgex.sh] + Add a test for DH GEX sizes + +commit 1e2aa3d90472293ea19008f02336d6d68aa05793 +Author: Damien Miller +Date: Fri Feb 28 10:19:51 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/20 00:00:30 + [sftp-chroot.sh] + append to rather than truncating the log file + +commit f483cc16fe7314e24a37aa3a4422b03c013c3213 +Author: Damien Miller +Date: Fri Feb 28 10:19:11 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/19 23:43:02 + [regress/sftp-chroot.sh] + Don't use -q on sftp as it suppresses logging, instead redirect the + output to the regress logfile. + +commit 6486f16f1c0ebd6f39286f6ab5e08286d90a994a +Author: Damien Miller +Date: Fri Feb 28 10:03:52 2014 +1100 + + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank version numbers + +commit 92cf5adea194140380e6af6ec32751f9ad540794 +Author: Damien Miller +Date: Fri Feb 28 10:01:53 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 22:57:40 + [version.h] + openssh-6.6 + +commit fc5d6759aba71eb205b296b5f148010ffc828583 +Author: Damien Miller +Date: Fri Feb 28 10:01:28 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 22:47:07 + [sshd_config.5] + bz#2184 clarify behaviour of a keyword that appears in multiple + matching Match blocks; ok dtucker@ + +commit 172ec7e0af1a5f1d682f6a2dca335c6c186153d5 +Author: Damien Miller +Date: Fri Feb 28 10:00:57 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 08:25:09 + [bufbn.c] + off by one in range check + +commit f9a9aaba437c2787e40cf7cc928281950e161678 +Author: Damien Miller +Date: Fri Feb 28 10:00:27 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/27 00:41:49 + [bufbn.c] + fix unsigned overflow that could lead to reading a short ssh protocol + 1 bignum value; found by Ben Hawkes; ok deraadt@ + +commit fb3423b612713d9cde67c8a75f6f51188d6a3de3 +Author: Damien Miller +Date: Thu Feb 27 10:20:07 2014 +1100 + + - markus@cvs.openbsd.org 2014/02/26 21:53:37 + [sshd.c] + ssh_gssapi_prepare_supported_oids needs GSSAPI + +commit 1348129a34f0f7728c34d86c100a32dcc8d1f922 +Author: Damien Miller +Date: Thu Feb 27 10:18:32 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/26 20:29:29 + [channels.c] + don't assume that the socks4 username is \0 terminated; + spotted by Ben Hawkes; ok markus@ + +commit e6a74aeeacd01d885262ff8e50eb28faee8c8039 +Author: Damien Miller +Date: Thu Feb 27 10:17:49 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/26 20:28:44 + [auth2-gss.c gss-serv.c ssh-gss.h sshd.c] + bz#2107 - cache OIDs of supported GSSAPI mechanisms before privsep + sandboxing, as running this code in the sandbox can cause violations; + ok markus@ + +commit 08b57c67f3609340ff703fe2782d7058acf2529e +Author: Damien Miller +Date: Thu Feb 27 10:17:13 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/26 20:18:37 + [ssh.c] + bz#2205: avoid early hostname lookups unless canonicalisation is enabled; + ok dtucker@ markus@ + +commit 13f97b2286142fd0b8eab94e4ce84fe124eeb752 +Author: Damien Miller +Date: Mon Feb 24 15:57:55 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/23 20:11:36 + [readconf.c readconf.h ssh.c ssh_config.5] + reparse ssh_config and ~/.ssh/config if hostname canonicalisation changes + the hostname. This allows users to write configurations that always + refer to canonical hostnames, e.g. + + CanonicalizeHostname yes + CanonicalDomains int.example.org example.org + CanonicalizeFallbackLocal no + + Host *.int.example.org + Compression off + Host *.example.org + User djm + + ok markus@ + +commit bee3a234f3d1ad4244952bcff1b4b7c525330dc2 +Author: Damien Miller +Date: Mon Feb 24 15:57:22 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/23 20:03:42 + [ssh-ed25519.c] + check for unsigned overflow; not reachable in OpenSSH but others might + copy our code... + +commit 0628780abe61e7e50cba48cdafb1837f49ff23b2 +Author: Damien Miller +Date: Mon Feb 24 15:56:45 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/22 01:32:19 + [readconf.c] + when processing Match blocks, skip 'exec' clauses if previous predicates + failed to match; ok markus@ + +commit 0890dc8191bb201eb01c3429feec0300a9d3a930 +Author: Damien Miller +Date: Mon Feb 24 15:56:07 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/15 23:05:36 + [channels.c] + avoid spurious "getsockname failed: Bad file descriptor" errors in ssh -W; + bz#2200, debian#738692 via Colin Watson; ok dtucker@ + +commit d3cf67e1117c25d151d0f86396e77ee3a827045a +Author: Damien Miller +Date: Mon Feb 24 15:55:36 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/07 06:55:54 + [cipher.c mac.c] + remove some logging that makes ssh debugging output very verbose; + ok markus + +commit 03ae081aeaa118361c81ece76eb7cc1aaa2b40c5 +Author: Tim Rice +Date: Fri Feb 21 09:09:34 2014 -0800 + + 20140221 + - (tim) [configure.ac] Fix cut-and-paste error. Patch from Bryan Drewery. + +commit 4a20959d2e3c90e9d66897c0b4032c785672d815 +Author: Darren Tucker +Date: Thu Feb 13 16:38:32 2014 +1100 + + - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add compat + code for older OpenSSL versions that don't have EVP_MD_CTX_copy_ex. + +commit d1a7a9c0fd1ac2e3314cceb2891959fd2cd9eabb +Author: Damien Miller +Date: Fri Feb 7 09:24:33 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/06 22:21:01 + [sshconnect.c] + in ssh_create_socket(), only do the getaddrinfo for BindAddress when + BindAddress is actually specified. Fixes regression in 6.5 for + UsePrivilegedPort=yes; patch from Corinna Vinschen + +commit 6ce35b6cc4ead1bf98abec34cb2e2d6ca0abb15e +Author: Damien Miller +Date: Fri Feb 7 09:24:14 2014 +1100 + + - naddy@cvs.openbsd.org 2014/02/05 20:13:25 + [ssh-keygen.1 ssh-keygen.c] + tweak synopsis: calling ssh-keygen without any arguments is fine; ok jmc@ + while here, fix ordering in usage(); requested by jmc@ + +commit 6434cb2cfbbf0a46375d2d22f2ff9927feb5e478 +Author: Damien Miller +Date: Thu Feb 6 11:17:50 2014 +1100 + + - (djm) [sandbox-seccomp-filter.c] Not all Linux architectures define + __NR_shutdown; some go via the socketcall(2) multiplexer. + +commit 8d36f9ac71eff2e9f5770c0518b73d875f270647 +Author: Darren Tucker +Date: Thu Feb 6 10:44:13 2014 +1100 + + - (dtucker) [openbsd-compat/bsd-poll.c] Don't bother checking for non-NULL + before freeing since free(NULL) is a no-op. ok djm. + +commit a0959da3680b4ce8cf911caf3293a6d90f88eeb7 +Author: Damien Miller +Date: Wed Feb 5 10:33:45 2014 +1100 + + - (djm) [sandbox-capsicum.c] Don't fatal if Capsicum is offered by + headers/libc but not supported by the kernel. Patch from Loganaden + Velvindron @ AfriNIC + +commit 9c449bc183b256c84d8f740727b0bc54d247b15e +Author: Damien Miller +Date: Tue Feb 4 11:38:28 2014 +1100 + + - (djm) [regress/setuid-allowed.c] Missing string.h for strerror() + +commit bf7e0f03be661b6f5b3bfe325135ce19391f9c4d +Author: Damien Miller +Date: Tue Feb 4 11:37:50 2014 +1100 + + - (djm) [openbsd-compat/Makefile.in] Add missing explicit_bzero.o + +commit eb6d870a0ea8661299bb2ea8f013d3ace04e2024 +Author: Damien Miller +Date: Tue Feb 4 11:26:34 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/04 00:24:29 + [ssh.c] + delay lowercasing of hostname until right before hostname + canonicalisation to unbreak case-sensitive matching of ssh_config; + reported by Ike Devolder; ok markus@ + +commit d56b44d2dfa093883a5c4e91be3f72d99946b170 +Author: Damien Miller +Date: Tue Feb 4 11:26:04 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/04 00:24:29 + [ssh.c] + delay lowercasing of hostname until right before hostname + canonicalisation to unbreak case-sensitive matching of ssh_config; + reported by Ike Devolder; ok markus@ + +commit db3c595ea74ea9ccd5aa644d7e1f8dc675710731 +Author: Damien Miller +Date: Tue Feb 4 11:25:45 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/02 03:44:31 + [digest-libc.c digest-openssl.c] + convert memset of potentially-private data to explicit_bzero() + +commit aae07e2e2000dd318418fd7fd4597760904cae32 +Author: Damien Miller +Date: Tue Feb 4 11:20:40 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/03 23:28:00 + [ssh-ecdsa.c] + fix memory leak; ECDSA_SIG_new() allocates 'r' and 's' for us, unlike + DSA_SIG_new. Reported by Batz Spear; ok markus@ + +commit a5103f413bde6f31bff85d6e1fd29799c647d765 +Author: Damien Miller +Date: Tue Feb 4 11:20:14 2014 +1100 + + - djm@cvs.openbsd.org 2014/02/02 03:44:32 + [auth1.c auth2-chall.c auth2-passwd.c authfile.c bufaux.c bufbn.c] + [buffer.c cipher-3des1.c cipher.c clientloop.c gss-serv.c kex.c] + [kexdhc.c kexdhs.c kexecdhc.c kexgexc.c kexecdhs.c kexgexs.c key.c] + [monitor.c monitor_wrap.c packet.c readpass.c rsa.c serverloop.c] + [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c] + [ssh-keygen.c ssh-rsa.c sshconnect.c sshconnect1.c sshconnect2.c] + [sshd.c] + convert memset of potentially-private data to explicit_bzero() + +commit 1d2c4564265ee827147af246a16f3777741411ed +Author: Damien Miller +Date: Tue Feb 4 11:18:20 2014 +1100 + + - tedu@cvs.openbsd.org 2014/01/31 16:39:19 + [auth2-chall.c authfd.c authfile.c bufaux.c bufec.c canohost.c] + [channels.c cipher-chachapoly.c clientloop.c configure.ac hostfile.c] + [kexc25519.c krl.c monitor.c sandbox-systrace.c session.c] + [sftp-client.c ssh-keygen.c ssh.c sshconnect2.c sshd.c sshlogin.c] + [openbsd-compat/explicit_bzero.c openbsd-compat/openbsd-compat.h] + replace most bzero with explicit_bzero, except a few that cna be memset + ok djm dtucker + +commit 3928de067c286683a95fbdbdb5fdb3c78a0e5efd +Author: Damien Miller +Date: Tue Feb 4 11:13:54 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/30 22:26:14 + [sandbox-systrace.c] + allow shutdown(2) syscall in sandbox - it may be called by packet_close() + from portable + (Id sync only; change is already in portable) + +commit e1e480aee8a9af6cfbe7188667b7b940d6b57f9f +Author: Damien Miller +Date: Tue Feb 4 11:13:17 2014 +1100 + + - jmc@cvs.openbsd.org 2014/01/29 14:04:51 + [sshd_config.5] + document kbdinteractiveauthentication; + requested From: Ross L Richardson + + dtucker/markus helped explain its workings; + +commit 7cc194f70d4a5ec9a82d19422eaf18db4a6624c6 +Author: Damien Miller +Date: Tue Feb 4 11:12:56 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/29 06:18:35 + [Makefile.in auth.h auth2-jpake.c auth2.c jpake.c jpake.h monitor.c] + [monitor.h monitor_wrap.c monitor_wrap.h readconf.c readconf.h] + [schnorr.c schnorr.h servconf.c servconf.h ssh2.h sshconnect2.c] + remove experimental, never-enabled JPAKE code; ok markus@ + +commit b0f26544cf6f4feeb1a4f6db09fca834f5c9867d +Author: Damien Miller +Date: Tue Feb 4 11:10:01 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/29 00:19:26 + [sshd.c] + use kill(0, ...) instead of killpg(0, ...); on most operating systems + they are equivalent, but SUSv2 describes the latter as having undefined + behaviour; from portable; ok dtucker + (Id sync only; change is already in portable) + +commit f8f35bc471500348bb262039fb1fc43175d251b0 +Author: Damien Miller +Date: Tue Feb 4 11:09:12 2014 +1100 + + - jmc@cvs.openbsd.org 2014/01/28 14:13:39 + [ssh-keyscan.1] + kill some bad Pa; + From: Jan Stary + +commit 0ba85d696ae9daf66002c2e4ab0d6bb111e1a787 +Author: Damien Miller +Date: Tue Feb 4 11:08:38 2014 +1100 + + ignore a few more regress droppings + +commit ec93d15170b7a6ddf63fd654bd0f6a752acc19dd +Author: Damien Miller +Date: Tue Feb 4 11:07:13 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/27 20:13:46 + [digest.c digest-openssl.c digest-libc.c Makefile.in] + rename digest.c to digest-openssl.c and add libc variant; ok djm@ + +commit 4a1c7aa640fb97d3472d51b215b6a0ec0fd025c7 +Author: Damien Miller +Date: Tue Feb 4 11:03:36 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/27 19:18:54 + [auth-rsa.c cipher.c ssh-agent.c sshconnect1.c sshd.c] + replace openssl MD5 with our ssh_digest_*; ok djm@ + +commit 4e8d937af79ce4e253f77ec93489d098b25becc3 +Author: Damien Miller +Date: Tue Feb 4 11:02:42 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/27 18:58:14 + [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h] + replace openssl HMAC with an implementation based on our ssh_digest_* + ok and feedback djm@ + +commit 69d0d09f76bab5aec86fbf78489169f63bd16475 +Author: Tim Rice +Date: Fri Jan 31 14:25:18 2014 -0800 + + - (tim) [Makefile.in] build regress/setuid-allow. + +commit 0eeafcd76b972a3d159f3118227c149a4d7817fe +Author: Darren Tucker +Date: Fri Jan 31 14:18:51 2014 +1100 + + - (dtucker) [readconf.c] Include for the hton macros. Fixes + build with HP-UX's compiler. Patch from Kevin Brott. + +commit 7e5cec6070673e9f9785ffc749837ada22fbe99f +Author: Damien Miller +Date: Fri Jan 31 09:25:34 2014 +1100 + + - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2) + syscall from sandboxes; it may be called by packet_close. + +commit cdb6c90811caa5df2df856be9b0b16db020fe31d +Author: Damien Miller +Date: Thu Jan 30 12:50:17 2014 +1100 + + - (djm) Release openssh-6.5p1 + +commit 996ea80b1884b676a901439f1f2681eb6ff68501 +Author: Damien Miller +Date: Thu Jan 30 12:49:55 2014 +1100 + + trim entries prior to openssh-6.0p1 + +commit f5bbd3b657b6340551c8a95f74a70857ff8fac79 +Author: Damien Miller +Date: Thu Jan 30 11:26:46 2014 +1100 + + - (djm) [configure.ac atomicio.c] Kludge around NetBSD offering + different symbols for 'read' when various compiler flags are + in use, causing atomicio.c comparisons against it to break and + read/write operations to hang; ok dtucker + +commit c2868192ddc4e1420a50389e18c05db20b0b1f32 +Author: Damien Miller +Date: Thu Jan 30 10:21:19 2014 +1100 + + - (djm) [configure.ac] Only check for width-specified integer types + in headers that actually exist. patch from Tom G. Christensen; + ok dtucker@ + +commit c161fc90fc86e2035710570238a9e1ca7a68d2a5 +Author: Damien Miller +Date: Wed Jan 29 21:01:33 2014 +1100 + + - (djm) [configure.ac] Fix broken shell test '==' vs '='; patch from + Tom G. Christensen + +commit 6f917ad376481995ab7d29fb53b08ec8d507eb9e +Author: Tim Rice +Date: Tue Jan 28 10:26:25 2014 -0800 + + - (tim) [regress/agent.sh regress/agent-ptrace.sh] Assign $? to a variable + when used as an error message inside an if statement so we display the + correct into. agent.sh patch from Petr Lautrbach. + +commit ab16ef4152914d44ce6f76e48167d26d22f66a06 +Author: Damien Miller +Date: Tue Jan 28 15:08:12 2014 +1100 + + - (djm) [sshd.c] Use kill(0, ...) instead of killpg(0, ...); the + latter being specified to have undefined behaviour in SUSv3; + ok dtucker + +commit ab0394905884dc6e58c3721211c6b38fb8fc2ca8 +Author: Damien Miller +Date: Tue Jan 28 15:07:10 2014 +1100 + + - (djm) [configure.ac] Search for inet_ntop in libnsl and libresovl; + ok dtucker + +commit 4ab20a82d4d4168d62318923f62382f6ef242fcd +Author: Darren Tucker +Date: Mon Jan 27 17:35:04 2014 +1100 + + - (dtucker) [Makefile.in] Remove trailing backslash which some make + implementations (eg older Solaris) do not cope with. + +commit e7e8b3cfe9f8665faaf0e68b33df5bbb431bd129 +Author: Darren Tucker +Date: Mon Jan 27 17:32:50 2014 +1100 + + Welcome to 2014 + +commit 5b447c0aac0dd444251e276f6bb3bbbe1c05331c +Author: Damien Miller +Date: Sun Jan 26 09:46:53 2014 +1100 + + - (djm) [configure.ac] correct AC_DEFINE for previous. + +commit 2035b2236d3b1f76c749c642a43e03c85eae76e6 +Author: Damien Miller +Date: Sun Jan 26 09:39:53 2014 +1100 + + - (djm) [configure.ac sandbox-capsicum.c sandbox-rlimit.c] Disable + RLIMIT_NOFILE pseudo-sandbox on FreeBSD. In some configurations, + libc will attempt to open additional file descriptors for crypto + offload and crash if they cannot be opened. + +commit a92ac7410475fbb00383c7402aa954dc0a75ae19 +Author: Damien Miller +Date: Sun Jan 26 09:38:03 2014 +1100 + + - markus@cvs.openbsd.org 2014/01/25 20:35:37 + [kex.c] + dh_need needs to be set to max(seclen, blocksize, ivlen, mac_len) + ok dtucker@, noted by mancha + +commit 76eea4ab4e658670ca6e76dd1e6d17f262208b57 +Author: Damien Miller +Date: Sun Jan 26 09:37:25 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/25 10:12:50 + [cipher.c cipher.h kex.c kex.h kexgexc.c] + Add a special case for the DH group size for 3des-cbc, which has an + effective strength much lower than the key size. This causes problems + with some cryptlib implementations, which don't support group sizes larger + than 4k but also don't use the largest group size it does support as + specified in the RFC. Based on a patch from Petr Lautrbach at Redhat, + reduced by me with input from Markus. ok djm@ markus@ + +commit 603b8f47f1cd9ed95a2017447db8e60ca6704594 +Author: Damien Miller +Date: Sat Jan 25 13:16:59 2014 +1100 + + - (djm) [configure.ac] autoconf sets finds to 'yes' not '1', so test + against the correct thing. + +commit c96d85376d779b6ac61525b5440010d344d2f23f +Author: Damien Miller +Date: Sat Jan 25 13:12:28 2014 +1100 + + - (djm) [configure.ac] Do not attempt to use capsicum sandbox unless + sys/capability.h exists and cap_rights_limit is in libc. Fixes + build on FreeBSD9x which provides the header but not the libc + support. + +commit f62ecef9939cb3dbeb10602fd705d4db3976d822 +Author: Damien Miller +Date: Sat Jan 25 12:34:38 2014 +1100 + + - (djm) [configure.ac] Fix detection of capsicum sandbox on FreeBSD + +commit b0e0f760b861676a3fe5c40133b270713d5321a9 +Author: Damien Miller +Date: Fri Jan 24 14:27:04 2014 +1100 + + - (djm) [Makefile.in regress/scp-ssh-wrapper.sh regress/scp.sh] Make + the scp regress test actually test the built scp rather than the one + in $PATH. ok dtucker@ + +commit 42a092530159637da9cb7f9e1b5f4679e34a85e6 +Author: Darren Tucker +Date: Thu Jan 23 23:14:39 2014 +1100 + + - (dtucker) [configure.ac] NetBSD's (and FreeBSD's) strnvis is gratuitously + incompatible with OpenBSD's despite post-dating it by more than a decade. + Declare it as broken, and document FreeBSD's as the same. ok djm@ + +commit 617da33c20cb59f9ea6c99c881d92493371ef7b8 +Author: Tim Rice +Date: Wed Jan 22 19:16:10 2014 -0800 + + - (tim) [session.c] Improve error reporting on set_id(). + +commit 5c2ff5e31f57d303ebb414d84a934c02728fa568 +Author: Damien Miller +Date: Wed Jan 22 21:30:12 2014 +1100 + + - (djm) [configure.ac aclocal.m4] More tests to detect fallout from + platform hardening options: include some long long int arithmatic + to detect missing support functions for -ftrapv in libgcc and + equivalents, actually test linking when -ftrapv is supplied and + set either both -pie/-fPIE or neither. feedback and ok dtucker@ + +commit 852472a54b8a0dc3e53786b313baaa86850a4273 +Author: Damien Miller +Date: Wed Jan 22 16:31:18 2014 +1100 + + - (djm) [configure.ac] Unless specifically requested, only attempt + to build Position Independent Executables on gcc >= 4.x; ok dtucker + +commit ee87838786cef0194db36ae0675b3e7c4e8ec661 +Author: Damien Miller +Date: Wed Jan 22 16:30:15 2014 +1100 + + - (djm) [openbsd-compat/setproctitle.c] Don't fail to compile if a + platform that is expected to use the reuse-argv style setproctitle + hack surprises us by providing a setproctitle in libc; ok dtucker + +commit 5c96a154c7940fa67b1f11c421e390dbbc159f27 +Author: Damien Miller +Date: Tue Jan 21 13:10:26 2014 +1100 + + - (djm) [aclocal.m4] Flesh out the code run in the OSSH_CHECK_CFLAG_COMPILE + and OSSH_CHECK_LDFLAG_LINK tests to give them a better chance of + detecting toolchain-related problems; ok dtucker + +commit 9464ba6fb34bb42eb3501ec3c5143662e75674bf +Author: Tim Rice +Date: Mon Jan 20 17:59:28 2014 -0800 + + - (tim) [platform.c session.c] Fix bug affecting SVR5 platforms introduced + with sftp chroot support. Move set_id call after chroot. + +commit a6d573caa14d490e6c42fb991bcb5c6860ec704b +Author: Darren Tucker +Date: Tue Jan 21 12:50:46 2014 +1100 + + - (dtucker) [aclocal.m4] Differentiate between compile-time and link-time + tests in the configure output. ok djm. + +commit 096118dc73ab14810b3c12785c0b5acb01ad6123 +Author: Darren Tucker +Date: Tue Jan 21 12:48:51 2014 +1100 + + - (dtucker) [configure.ac] Make PIE a configure-time option which defaults + to on platforms where it's known to be reliably detected and off elsewhere. + Works around platforms such as FreeBSD 9.1 where it does not interop with + -ftrapv (it seems to work but fails when trying to link ssh). ok djm@ + +commit f9df7f6f477792254eab33cdef71a6d66488cb88 +Author: Damien Miller +Date: Mon Jan 20 20:07:15 2014 +1100 + + - (djm) [regress/cert-hostkey.sh] Fix regress failure on platforms that + skip one or more key types (e.g. RHEL/CentOS 6.5); ok dtucker@ + +commit c74e70eb52ccc0082bd5a70b5798bb01c114d138 +Author: Darren Tucker +Date: Mon Jan 20 13:18:09 2014 +1100 + + - (dtucker) [gss-serv-krb5.c] Fall back to krb5_cc_gen_new if the Kerberos + implementation does not have krb5_cc_new_unique, similar to what we do + in auth-krb5.c. + +commit 3510979e83b6a18ec8773c64c3fa04aa08b2e783 +Author: Damien Miller +Date: Mon Jan 20 12:41:53 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/20 00:08:48 + [digest.c] + memleak; found by Loganaden Velvindron @ AfriNIC; ok markus@ + +commit 7eee358d7a6580479bee5cd7e52810ebfd03e5b2 +Author: Darren Tucker +Date: Sun Jan 19 22:37:02 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/19 11:21:51 + [addrmatch.c] + Cast the sizeof to socklen_t so it'll work even if the supplied len is + negative. Suggested by and ok djm, ok deraadt. + +commit b7e01c09b56ab26e8fac56bbce0fd25e36d12bb0 +Author: Darren Tucker +Date: Sun Jan 19 22:36:13 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/19 04:48:08 + [ssh_config.5] + fix inverted meaning of 'no' and 'yes' for CanonicalizeFallbackLocal + +commit 7b1ded04adce42efa25ada7c3a39818d3109b724 +Author: Darren Tucker +Date: Sun Jan 19 15:30:02 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/19 04:17:29 + [canohost.c addrmatch.c] + Cast socklen_t when comparing to size_t and use socklen_t to iterate over + the ip options, both to prevent signed/unsigned comparison warnings. + Patch from vinschen at redhat via portable openssh, begrudging ok deraadt. + +commit 293ee3c9f0796d99ebb033735f0e315f2e0180bf +Author: Darren Tucker +Date: Sun Jan 19 15:28:01 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/18 09:36:26 + [session.c] + explicitly define USE_PIPES to 1 to prevent redefinition warnings in + portable on platforms that use pipes for everything. From redhat @ + redhat. + +commit 2aca159d05f9e7880d1d8f1ce49a218840057f53 +Author: Darren Tucker +Date: Sun Jan 19 15:25:34 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/17 06:23:24 + [sftp-server.c] + fix log message statvfs. ok djm + +commit 841f7da89ae8b367bb502d61c5c41916c6e7ae4c +Author: Darren Tucker +Date: Sat Jan 18 22:12:15 2014 +1100 + + - (dtucker) [sandbox-capsicum.c] Correct some error messages and make the + return value check for cap_enter() consistent with the other uses in + FreeBSD. From by Loganaden Velvindron @ AfriNIC via bz#2140. + +commit fdce3731660699b2429e93e822f2ccbaccd163ae +Author: Darren Tucker +Date: Sat Jan 18 21:12:42 2014 +1100 + + - (dtucker) [configure.ac] On Cygwin the getopt variables (like optargs, + optind) are defined in getopt.h already. Unfortunately they are defined as + "declspec(dllimport)" for historical reasons, because the GNU linker didn't + allow auto-import on PE/COFF targets way back when. The problem is the + dllexport attributes collide with the definitions in the various source + files in OpenSSH, which obviousy define the variables without + declspec(dllimport). The least intrusive way to get rid of these warnings + is to disable warnings for GCC compiler attributes when building on Cygwin. + Patch from vinschen at redhat.com. + +commit 1411c9263f46e1ee49d0d302bf7258ebe69ce827 +Author: Darren Tucker +Date: Sat Jan 18 21:03:59 2014 +1100 + + - (dtucker) [openbsd-compat/bsd-cygwin_util.h] Add missing function + declarations that stopped being included when we stopped including + from openbsd-compat/bsd-cygwin_util.h. Patch from vinschen at + redhat.com. + +commit 89c532d843c95a085777c66365067d64d1937eb9 +Author: Darren Tucker +Date: Sat Jan 18 20:43:49 2014 +1100 + + - (dtucker) [uidswap.c] Prevent unused variable warnings on Cygwin. Patch + from vinschen at redhat.com + +commit 355f861022be7b23d3009fae8f3c9f6f7fc685f7 +Author: Darren Tucker +Date: Sat Jan 18 00:12:38 2014 +1100 + + - (dtucker) [defines.h] Move our definitions of uintXX_t types down to after + they're defined if we have to define them ourselves. Fixes builds on old + AIX. + +commit a3357661ee1d5d553294f36e4940e8285c7f1332 +Author: Darren Tucker +Date: Sat Jan 18 00:03:57 2014 +1100 + + - (dtucker) [readconf.c] Wrap paths.h inside an ifdef. Allows building on + Solaris. + +commit 9edcbff46ff01c8d5dee9c1aa843f09e9ad8a80e +Author: Darren Tucker +Date: Fri Jan 17 21:54:32 2014 +1100 + + - (dtucker) [configure.ac] Have --without-toolchain-hardening not turn off + stack-protector since that has a separate flag that's been around a while. + +commit 6d725687c490d4ba957a1bbc0ba0a2956c09fa69 +Author: Darren Tucker +Date: Fri Jan 17 19:17:34 2014 +1100 + + - (dtucker) [configure.ac] Also look in inttypes.h for uintXX_t types. + +commit 5055699c7f7c7ef21703a443ec73117da392f6ae +Author: Darren Tucker +Date: Fri Jan 17 18:48:22 2014 +1100 + + - (dtucker) [openbsd-compat/bsd-statvfs.h] Only start including headers if we + need them to cut down on the name collisions. + +commit a5cf1e220def07290260e4125e74f41ac75cf88d +Author: Darren Tucker +Date: Fri Jan 17 18:10:58 2014 +1100 + + - (dtucker) [configure.ac openbsd-compat/bsd-statvfs.c + openbsd-compat/bsd-statvfs.h] Implement enough of statvfs on top of statfs + to be useful (and for the regression tests to pass) on platforms that + have statfs and fstatfs. ok djm@ + +commit 1357d71d7b6d269969520aaa3e84d312ec971d5b +Author: Darren Tucker +Date: Fri Jan 17 18:00:40 2014 +1100 + + - (dtucker) Fix typo in #ifndef. + +commit d23a91ffb289d3553a58b7a60cec39fba9f0f506 +Author: Darren Tucker +Date: Fri Jan 17 17:32:30 2014 +1100 + + - (dtucker) [configure.ac digest.c openbsd-compat/openssl-compat.c + openbsd-compat/openssl-compat.h] Add compatibility layer for older + openssl versions. ok djm@ + +commit 868ea1ea1c1bfdbee5dbad78f81999c5983ecf31 +Author: Damien Miller +Date: Fri Jan 17 16:47:04 2014 +1100 + + - (djm) [Makefile.in configure.ac sandbox-capsicum.c sandbox-darwin.c] + [sandbox-null.c sandbox-rlimit.c sandbox-seccomp-filter.c] + [sandbox-systrace.c ssh-sandbox.h sshd.c] Support preauth sandboxing + using the Capsicum API introduced in FreeBSD 10. Patch by Dag-Erling + Smorgrav, updated by Loganaden Velvindron @ AfriNIC; ok dtucker@ + +commit a9d186a8b50d18869a10e9203abf71c83ddb1f79 +Author: Darren Tucker +Date: Fri Jan 17 16:30:49 2014 +1100 + + - dtucker@cvs.openbsd.org 2014/01/17 05:26:41 + [digest.c] + remove unused includes. ok djm@ + +commit 5f1c57a7a7eb39c0e4fee3367712337dbcaef024 +Author: Darren Tucker +Date: Fri Jan 17 16:29:45 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/17 00:21:06 + [sftp-client.c] + signed/unsigned comparison warning fix; from portable (Id sync only) + +commit c548722361d89fb12c108528f96b306a26477b18 +Author: Darren Tucker +Date: Fri Jan 17 15:12:16 2014 +1100 + + - (dtucker) [configure.ac] Split AC_CHECK_FUNCS for OpenSSL functions into + separate lines and alphabetize for easier diffing of changes. + +commit acad351a5b1c37de9130c9c1710445cc45a7f6b9 +Author: Darren Tucker +Date: Fri Jan 17 14:20:05 2014 +1100 + + - (dtucker) [defines.h] Add typedefs for uintXX_t types for platforms that + don't have them. + +commit c3ed065ce8417aaa46490836648c173a5010f226 +Author: Darren Tucker +Date: Fri Jan 17 14:18:45 2014 +1100 + + - (dtucker) [openbsd-compat/bcrypt_pbkdf.c] Wrap stdlib.h include inside + #ifdef HAVE_STDINT_H. + +commit f45f78ae437062c7d9506c5f475b7215f486be44 +Author: Darren Tucker +Date: Fri Jan 17 12:43:43 2014 +1100 + + - (dtucker) [blocks.c fe25519.c ge25519.c hash.c sc25519.c verify.c] Include + includes.h to pull in all of the compatibility stuff. + +commit 99df369d0340caac145d57f700d830147ff18b87 +Author: Darren Tucker +Date: Fri Jan 17 12:42:17 2014 +1100 + + - (dtucker) [poly1305.c] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. + +commit ac413b62ea1957e80c711acbe0c11b908273fc01 +Author: Darren Tucker +Date: Fri Jan 17 12:31:33 2014 +1100 + + - (dtucker) [crypto_api.h] Wrap stdlib.h include inside #ifdef HAVE_STDINT_H. + +commit 1c4a011e9c939e74815346a560843e1862c300b8 +Author: Darren Tucker +Date: Fri Jan 17 12:23:23 2014 +1100 + + - (dtucker) [loginrec.c] Cast to the types specfied in the format + specification to prevent warnings. + +commit c3d483f9a8275be1113535a1e0d0e384f605f3c4 +Author: Damien Miller +Date: Fri Jan 17 11:20:26 2014 +1100 + + - (djm) [sftp-client.c] signed/unsigned comparison fix + +commit fd994379dd972417d0491767f7cd9b5bf23f4975 +Author: Darren Tucker +Date: Fri Jan 17 09:53:24 2014 +1100 + + - (dtucker) [aclocal.m4 configure.ac] Add some additional compiler/toolchain + hardening flags including -fstack-protector-strong. These default to on + if the toolchain supports them, but there is a configure-time knob + (--without-hardening) to disable them if necessary. ok djm@ + +commit 366224d21768ee8ec28cfbcc5fbade1b32582d58 +Author: Damien Miller +Date: Thu Jan 16 18:51:44 2014 +1100 + + - (djm) [README] update release notes URL. + +commit 2ae77e64f8fa82cbf25c9755e8e847709b978b40 +Author: Damien Miller +Date: Thu Jan 16 18:51:07 2014 +1100 + + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank RPM spec version numbers. + +commit 0fa29e6d777c73a1b4ddd3b996b06ee20022ae8a +Author: Damien Miller +Date: Thu Jan 16 18:42:31 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/16 07:32:00 + [version.h] + openssh-6.5 + +commit 52c371cd6d2598cc73d4e633811b3012119c47e2 +Author: Damien Miller +Date: Thu Jan 16 18:42:10 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/16 07:31:09 + [sftp-client.c] + needless and incorrect cast to size_t can break resumption of + large download; patch from tobias@ + +commit 91b580e4bec55118bf96ab3cdbe5a50839e75d0a +Author: Damien Miller +Date: Sun Jan 12 19:21:22 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/12 08:13:13 + [bufaux.c buffer.h kex.c kex.h kexc25519.c kexc25519c.c kexc25519s.c] + [kexdhc.c kexdhs.c kexecdhc.c kexecdhs.c kexgexc.c kexgexs.c] + avoid use of OpenSSL BIGNUM type and functions for KEX with + Curve25519 by adding a buffer_put_bignum2_from_string() that stores + a string using the bignum encoding rules. Will make it easier to + build a reduced-feature OpenSSH without OpenSSL in the future; + ok markus@ + +commit af5d4481f4c7c8c3c746e68b961bb85ef907800e +Author: Damien Miller +Date: Sun Jan 12 19:20:47 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/10 05:59:19 + [sshd_config] + the /etc/ssh/ssh_host_ed25519_key is loaded by default too + +commit 58cd63bc63038acddfb4051ed14e11179d8f4941 +Author: Damien Miller +Date: Fri Jan 10 10:59:24 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/09 23:26:48 + [sshconnect.c sshd.c] + ban clients/servers that suffer from SSH_BUG_DERIVEKEY, they are ancient, + deranged and might make some attacks on KEX easier; ok markus@ + +commit b3051d01e505c9c2dc00faab472a0d06fa6b0e65 +Author: Damien Miller +Date: Fri Jan 10 10:58:53 2014 +1100 + + - djm@cvs.openbsd.org 2014/01/09 23:20:00 + [digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c] + [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c] + [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c] + [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c] + Introduce digest API and use it to perform all hashing operations + rather than calling OpenSSL EVP_Digest* directly. Will make it easier + to build a reduced-feature OpenSSH without OpenSSL in future; + feedback, ok markus@ + +commit e00e413dd16eb747fb2c15a099971d91c13cf70f +Author: Damien Miller +Date: Fri Jan 10 10:40:45 2014 +1100 + + - guenther@cvs.openbsd.org 2014/01/09 03:26:00 + [sftp-common.c] + When formating the time for "ls -l"-style output, show dates in the future + with the year, and rearrange a comparison to avoid a potentional signed + arithmetic overflow that would give the wrong result. + + ok djm@ + +commit 3e49853650448883685cfa32fa382d0ba6d51d48 +Author: Damien Miller +Date: Fri Jan 10 10:37:05 2014 +1100 + + - tedu@cvs.openbsd.org 2014/01/04 17:50:55 + [mac.c monitor_mm.c monitor_mm.h xmalloc.c] + use standard types and formats for size_t like variables. ok dtucker + +commit a9c1e500ef609795cbc662848edb1a1dca279c81 +Author: Damien Miller +Date: Wed Jan 8 16:13:12 2014 +1100 + + - (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@ + +commit 324541e5264e1489ca0babfaf2b39612eb80dfb3 +Author: Damien Miller +Date: Tue Dec 31 12:25:40 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/30 23:52:28 + [auth2-hostbased.c auth2-pubkey.c compat.c compat.h ssh-rsa.c] + [sshconnect.c sshconnect2.c sshd.c] + refuse RSA keys from old proprietary clients/servers that use the + obsolete RSA+MD5 signature scheme. it will still be possible to connect + with these clients/servers but only DSA keys will be accepted, and we'll + deprecate them entirely in a future release. ok markus@ + +commit 9f4c8e797ea002a883307ca906f1f1f815010e78 +Author: Damien Miller +Date: Sun Dec 29 17:57:46 2013 +1100 + + - (djm) [regress/Makefile] Add some generated files for cleaning + +commit 106bf1ca3c7a5fdc34f9fd7a1fe651ca53085bc5 +Author: Damien Miller +Date: Sun Dec 29 17:54:03 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 05:57:02 + [sshconnect.c] + when showing other hostkeys, don't forget Ed25519 keys + +commit 0fa47cfb32c239117632cab41e4db7d3e6de5e91 +Author: Damien Miller +Date: Sun Dec 29 17:53:39 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 05:42:16 + [ssh.c] + don't forget to load Ed25519 certs too + +commit b9a95490daa04cc307589897f95bfaff324ad2c9 +Author: Damien Miller +Date: Sun Dec 29 17:50:15 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 04:35:50 + [authfile.c] + don't refuse to load Ed25519 certificates + +commit f72cdde6e6fabc51d2a62f4e75b8b926d9d7ee89 +Author: Damien Miller +Date: Sun Dec 29 17:49:55 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 04:29:25 + [authfd.c] + allow deletion of ed25519 keys from the agent + +commit 29ace1cb68cc378a464c72c0fd67aa5f9acd6b5b +Author: Damien Miller +Date: Sun Dec 29 17:49:31 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 04:20:04 + [key.c] + to make sure we don't omit any key types as valid CA keys again, + factor the valid key type check into a key_type_is_valid_ca() + function + +commit 9de4fcdc5a9cff48d49a3e2f6194d3fb2d7ae34d +Author: Damien Miller +Date: Sun Dec 29 17:49:13 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 02:49:52 + [key.c] + correct comment for key_drop_cert() + +commit 5baeacf8a80f054af40731c6f92435f9164b8e02 +Author: Damien Miller +Date: Sun Dec 29 17:48:55 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 02:37:04 + [key.c] + correct comment for key_to_certified() + +commit 83f2fe26cb19330712c952eddbd3c0b621674adc +Author: Damien Miller +Date: Sun Dec 29 17:48:38 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/29 02:28:10 + [key.c] + allow ed25519 keys to appear as certificate authorities + +commit 06122e9a74bb488b0fe0a8f64e1135de870f9cc0 +Author: Damien Miller +Date: Sun Dec 29 17:48:15 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/27 22:37:18 + [ssh-rsa.c] + correct comment + +commit 3e19295c3a253c8dc8660cf45baad7f45fccb969 +Author: Damien Miller +Date: Sun Dec 29 17:47:50 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/27 22:30:17 + [ssh-dss.c ssh-ecdsa.c ssh-rsa.c] + make the original RSA and DSA signing/verification code look more like + the ECDSA/Ed25519 ones: use key_type_plain() when checking the key type + rather than tediously listing all variants, use __func__ for debug/ + error messages + +commit 137977180be6254639e2c90245763e6965f8d815 +Author: Damien Miller +Date: Sun Dec 29 17:47:14 2013 +1100 + + - tedu@cvs.openbsd.org 2013/12/21 07:10:47 + [ssh-keygen.1] + small typo + +commit 339a48fe7ffb3186d22bbaa9efbbc3a053e602fd +Author: Damien Miller +Date: Sun Dec 29 17:46:49 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 22:57:13 + [poly1305.c poly1305.h] + use full name for author, with his permission + +commit 0b36c83148976c7c8268f4f41497359e2fb26251 +Author: Damien Miller +Date: Sun Dec 29 17:45:51 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 01:19:41 + [ssh-agent.c] + bz#2186: don't crash (NULL deref) when deleting PKCS#11 keys from an agent + that has a mix of normal and PKCS#11 keys; fix from jay AT slushpupie.com; + ok dtucker + +commit 4def184e9b6c36be6d965a9705632fc4c0c2a8af +Author: Damien Miller +Date: Sun Dec 29 17:45:26 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 01:04:36 + [channels.c] + bz#2147: fix multiple remote forwardings with dynamically assigned + listen ports. In the s->c message to open the channel we were sending + zero (the magic number to request a dynamic port) instead of the actual + listen port. The client therefore had no way of discriminating between + them. + + Diagnosis and fix by ronf AT timeheart.net + +commit bf25d114e23a803f8feca8926281b1aaedb6191b +Author: Damien Miller +Date: Sun Dec 29 17:44:56 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 00:27:57 + [auth-options.c] + simplify freeing of source-address certificate restriction + +commit bb3dafe7024a5b4e851252e65ee35d45b965e4a8 +Author: Damien Miller +Date: Sun Dec 29 17:44:29 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/12/19 00:19:12 + [serverloop.c] + Cast client_alive_interval to u_int64_t before assinging to + max_time_milliseconds to avoid potential integer overflow in the timeout. + bz#2170, patch from Loganaden Velvindron, ok djm@ + +commit ef275ead3dcadde4db1efe7a0aa02b5e618ed40c +Author: Damien Miller +Date: Sun Dec 29 17:44:07 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/19 00:10:30 + [ssh-add.c] + skip requesting smartcard PIN when removing keys from agent; bz#2187 + patch from jay AT slushpupie.com; ok dtucker + +commit 7d97fd9a1cae778c3eacf16e09f5da3689d616c6 +Author: Damien Miller +Date: Sun Dec 29 17:40:18 2013 +1100 + + - (djm) [loginrec.c] Check for username truncation when looking up lastlog + entries + +commit 77244afe3b6d013b485e0952eaab89b9db83380f +Author: Darren Tucker +Date: Sat Dec 21 17:02:39 2013 +1100 + + 20131221 + - (dtucker) [regress/keytype.sh] Actually test ecdsa key types. + +commit 53f8e784dc431a82d31c9b0e95b144507f9330e9 +Author: Darren Tucker +Date: Thu Dec 19 11:31:44 2013 +1100 + + - (dtucker) [auth-pam.c] bz#2163: check return value from pam_get_item(). + Patch from Loganaden Velvindron. + +commit 1fcec9d4f265e38af248c4c845986ca8c174bd68 +Author: Darren Tucker +Date: Thu Dec 19 11:00:12 2013 +1100 + + - (dtucker) [configure.ac] bz#2178: Don't try to use BSM on Solaris versions + greater than 11 either rather than just 11. Patch from Tomas Kuthan. + +commit 6674eb9683afd1ea4eb35670b5e66815543a759e +Author: Damien Miller +Date: Wed Dec 18 17:50:39 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/17 10:36:38 + [crypto_api.h] + I've assempled the header file by cut&pasting from generated headers + and the source files. + +commit d58a5964426ee014384d67d775d16712e93057f3 +Author: Damien Miller +Date: Wed Dec 18 17:50:13 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/15 21:42:35 + [cipher-chachapoly.c] + add some comments and constify a constant + +commit 059321d19af24d87420de3193f79dfab23556078 +Author: Damien Miller +Date: Wed Dec 18 17:49:48 2013 +1100 + + - pascal@cvs.openbsd.org 2013/12/15 18:17:26 + [ssh-add.c] + Make ssh-add also add .ssh/id_ed25519; fixes lie in manual page. + ok markus@ + +commit 155b5a5bf158767f989215479ded2a57f331e1c6 +Author: Damien Miller +Date: Wed Dec 18 17:48:32 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/09 11:08:17 + [crypto_api.h] + remove unused defines + +commit 8a56dc2b6b48b05590810e7f4c3567508410000c +Author: Damien Miller +Date: Wed Dec 18 17:48:11 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/09 11:03:45 + [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] + [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] + Add Authors for the public domain ed25519/nacl code. + see also http://nacl.cr.yp.to/features.html + All of the NaCl software is in the public domain. + and http://ed25519.cr.yp.to/software.html + The Ed25519 software is in the public domain. + +commit 6575c3acf31fca117352f31f37b16ae46e664837 +Author: Damien Miller +Date: Wed Dec 18 17:47:02 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/12/08 09:53:27 + [sshd_config.5] + Use a literal for the default value of KEXAlgorithms. ok deraadt jmc + +commit 8ba0ead6985ea14999265136b14ffd5aeec516f9 +Author: Damien Miller +Date: Wed Dec 18 17:46:27 2013 +1100 + + - naddy@cvs.openbsd.org 2013/12/07 11:58:46 + [ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8 ssh.1] + [ssh_config.5 sshd.8 sshd_config.5] + add missing mentions of ed25519; ok djm@ + +commit 4f752cf71cf44bf4bc777541156c2bf56daf9ce9 +Author: Damien Miller +Date: Wed Dec 18 17:45:35 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/07 08:08:26 + [ssh-keygen.1] + document -a and -o wrt new key format + +commit 6d6fcd14e23a9053198342bb379815b15e504084 +Author: Damien Miller +Date: Sun Dec 8 15:53:28 2013 +1100 + + - (djm) [Makefile.in regress/Makefile regress/agent-ptrace.sh] + [regress/setuid-allowed.c] Check that ssh-agent is not on a no-setuid + filesystem before running agent-ptrace.sh; ok dtucker + +commit 7e6e42fb532c7dafd7078ef5e9e2d3e47fcf6752 +Author: Damien Miller +Date: Sun Dec 8 08:23:08 2013 +1100 + + - (djm) [openbsd-compat/bsd-setres_id.c] Missing header; from Corinna + Vinschen + +commit da3ca351b49d52ae85db2e3998265dc3c6617068 +Author: Damien Miller +Date: Sat Dec 7 21:43:46 2013 +1100 + + - (djm) [Makefile.in] PATHSUBS and keygen bits for Ed25519; from + Loganaden Velvindron @ AfriNIC in bz#2179 + +commit eb401585bb8336cbf81fe4fc58eb9f7cac3ab874 +Author: Damien Miller +Date: Sat Dec 7 17:07:15 2013 +1100 + + - (djm) [regress/cert-hostkey.sh] Fix merge botch + +commit f54542af3ad07532188b10136ae302314ec69ed6 +Author: Damien Miller +Date: Sat Dec 7 16:32:44 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:52:46 + [regress/Makefile regress/agent.sh regress/cert-hostkey.sh] + [regress/cert-userkey.sh regress/keytype.sh] + test ed25519 support; from djm@ + +commit f104da263de995f66b6861b4f3368264ee483d7f +Author: Damien Miller +Date: Sat Dec 7 12:37:53 2013 +1100 + + - (djm) [ed25519.c ssh-ed25519.c openbsd-compat/Makefile.in] + [openbsd-compat/bcrypt_pbkdf.c] Make ed25519/new key format compile on + Linux + +commit 1ff130dac9b7aea0628f4ad30683431fe35e0020 +Author: Damien Miller +Date: Sat Dec 7 11:51:51 2013 +1100 + + - [configure.ac openbsd-compat/Makefile.in openbsd-compat/bcrypt_pbkdf.c] + [openbsd-compat/blf.h openbsd-compat/blowfish.c] + [openbsd-compat/openbsd-compat.h] Start at supporting bcrypt_pbkdf in + portable. + +commit 4260828a2958ebe8c96f66d8301dac53f4cde556 +Author: Damien Miller +Date: Sat Dec 7 11:38:03 2013 +1100 + + - [authfile.c] Conditionalise inclusion of util.h + +commit a913442bac8a26fd296a3add51293f8f6f9b3b4c +Author: Damien Miller +Date: Sat Dec 7 11:35:36 2013 +1100 + + - [Makefile.in] Add ed25519 sources + +commit ca570a519cb846da61d002c7f46fa92e39c83e45 +Author: Damien Miller +Date: Sat Dec 7 11:29:09 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/07 00:19:15 + [key.c] + set k->cert = NULL after freeing it + +commit 3cccc0e155229a2f2d86b6df40bd4559b4f960ff +Author: Damien Miller +Date: Sat Dec 7 11:27:47 2013 +1100 + + - [blocks.c ed25519.c fe25519.c fe25519.h ge25519.c ge25519.h] + [ge25519_base.data hash.c sc25519.c sc25519.h verify.c] Fix RCS idents + +commit a7827c11b3f0380b7e593664bd62013ff9c131db +Author: Damien Miller +Date: Sat Dec 7 11:24:30 2013 +1100 + + - jmc@cvs.openbsd.org 2013/12/06 15:29:07 + [sshd.8] + missing comma; + +commit 5be9d9e3cbd9c66f24745d25bf2e809c1d158ee0 +Author: Damien Miller +Date: Sat Dec 7 11:24:01 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:39:49 + [authfd.c authfile.c key.c key.h myproposal.h pathnames.h readconf.c] + [servconf.c ssh-agent.c ssh-keygen.c ssh-keyscan.1 ssh-keyscan.c] + [ssh-keysign.c ssh.c ssh_config.5 sshd.8 sshd.c verify.c ssh-ed25519.c] + [sc25519.h sc25519.c hash.c ge25519_base.data ge25519.h ge25519.c] + [fe25519.h fe25519.c ed25519.c crypto_api.h blocks.c] + support ed25519 keys (hostkeys and user identities) using the public + domain ed25519 reference code from SUPERCOP, see + http://ed25519.cr.yp.to/software.html + feedback, help & ok djm@ + +commit bcd00abd8451f36142ae2ee10cc657202149201e +Author: Damien Miller +Date: Sat Dec 7 10:41:55 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:34:54 + [authfile.c authfile.h cipher.c cipher.h key.c packet.c ssh-agent.c] + [ssh-keygen.c PROTOCOL.key] new private key format, bcrypt as KDF by + default; details in PROTOCOL.key; feedback and lots help from djm; + ok djm@ + +commit f0e9060d236c0e38bec2fa1c6579fb0a2ea6458d +Author: Damien Miller +Date: Sat Dec 7 10:40:26 2013 +1100 + + - markus@cvs.openbsd.org 2013/12/06 13:30:08 + [authfd.c key.c key.h ssh-agent.c] + move private key (de)serialization to key.c; ok djm + +commit 0f8536da23a6ef26e6495177c0d8a4242b710289 +Author: Damien Miller +Date: Sat Dec 7 10:31:37 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/06 03:40:51 + [ssh-keygen.c] + remove duplicated character ('g') in getopt() string; + document the (few) remaining option characters so we don't have to + rummage next time. + +commit 393920745fd328d3fe07f739a3cf7e1e6db45b60 +Author: Damien Miller +Date: Sat Dec 7 10:31:08 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/05 22:59:45 + [sftp-client.c] + fix memory leak in error path in do_readdir(); pointed out by + Loganaden Velvindron @ AfriNIC in bz#2163 + +commit 534b2ccadea5e5e9a8b27226e6faac3ed5552e97 +Author: Damien Miller +Date: Thu Dec 5 14:07:27 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/05 01:16:41 + [servconf.c servconf.h] + bz#2161 - fix AuthorizedKeysCommand inside a Match block and + rearrange things so the same error is harder to make next time; + with and ok dtucker@ + +commit 8369c8e61a3408ec6bb75755fad4ffce29b5fdbe +Author: Darren Tucker +Date: Thu Dec 5 11:00:16 2013 +1100 + + - (dtucker) [configure.ac] bz#2173: use pkg-config --libs to include correct + -L location for libedit. Patch from Serge van den Boom. + +commit 9275df3e0a2a3bc3897f7d664ea86a425c8a092d +Author: Damien Miller +Date: Thu Dec 5 10:26:32 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/04 04:20:01 + [sftp-client.c] + bz#2171: don't leak local_fd on error; from Loganaden Velvindron @ + AfriNIC + +commit 960f6a2b5254e4da082d8aa3700302ed12dc769a +Author: Damien Miller +Date: Thu Dec 5 10:26:14 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 03:13:14 + [cipher.c] + correct bzero of chacha20+poly1305 key context. bz#2177 from + Loganaden Velvindron @ AfriNIC + + Also make it a memset for consistency with the rest of cipher.c + +commit f7e8a8796d661c9d6692ab837e1effd4f5ada1c2 +Author: Damien Miller +Date: Thu Dec 5 10:25:51 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 03:09:22 + [key.c] + make key_to_blob() return a NULL blob on failure; part of + bz#2175 from Loganaden Velvindron @ AfriNIC + +commit f1e44ea9d9a6d4c1a95a0024132e603bd1778c9c +Author: Damien Miller +Date: Thu Dec 5 10:23:21 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 02:56:17 + [ssh-pkcs11-helper.c] + use-after-free; bz#2175 patch from Loganaden Velvindron @ AfriNIC + +commit 114e540b15d57618f9ebf624264298f80bbd8c77 +Author: Damien Miller +Date: Thu Dec 5 10:22:57 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/02 02:50:27 + [PROTOCOL.chacha20poly1305] + typo; from Jon Cave + +commit e4870c090629e32f2cb649dc16d575eeb693f4a8 +Author: Damien Miller +Date: Thu Dec 5 10:22:39 2013 +1100 + + - djm@cvs.openbsd.org 2013/12/01 23:19:05 + [PROTOCOL] + mention curve25519-sha256@libssh.org key exchange algorithm + +commit 1d2f8804a6d33a4e908b876b2e1266b8260ec76b +Author: Damien Miller +Date: Thu Dec 5 10:22:03 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/26 19:15:09 + [pkcs11.h] + cleanup 1 << 31 idioms. Resurrection of this issue pointed out by + Eitan Adler ok markus for ssh, implies same change in kerberosV + +commit bdb352a54f82df94a548e3874b22f2d6ae90328d +Author: Damien Miller +Date: Thu Dec 5 10:20:52 2013 +1100 + + - jmc@cvs.openbsd.org 2013/11/26 12:14:54 + [ssh.1 ssh.c] + - put -Q in the right place + - Ar was a poor choice for the arguments to -Q. i've chosen an + admittedly equally poor Cm, at least consistent with the rest + of the docs. also no need for multiple instances + - zap a now redundant Nm + - usage() sync + +commit d937dc084a087090f1cf5395822c3ac958d33759 +Author: Damien Miller +Date: Thu Dec 5 10:19:54 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/25 18:04:21 + [ssh.1 ssh.c] + improve -Q usage and such. One usage change is that the option is now + case-sensitive + ok dtucker markus djm + +commit dec0393f7ee8aabc7d9d0fc2c5fddb4bc649112e +Author: Damien Miller +Date: Thu Dec 5 10:18:43 2013 +1100 + + - jmc@cvs.openbsd.org 2013/11/21 08:05:09 + [ssh_config.5 sshd_config.5] + no need for .Pp before displays; + +commit 8a073cf57940aabf85e49799f89f5d5e9b072c1b +Author: Damien Miller +Date: Thu Nov 21 14:26:18 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 03:18:51 + [regress/cipher-speed.sh regress/integrity.sh regress/rekey.sh] + [regress/try-ciphers.sh] + use new "ssh -Q cipher-auth" query to obtain lists of authenticated + encryption ciphers instead of specifying them manually; ensures that + the new chacha20poly1305@openssh.com mode is tested; + + ok markus@ and naddy@ as part of the diff to add + chacha20poly1305@openssh.com + +commit ea61b2179f63d48968dd2c9617621002bb658bfe +Author: Damien Miller +Date: Thu Nov 21 14:25:15 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 03:16:47 + [regress/modpipe.c] + use unsigned long long instead of u_int64_t here to avoid warnings + on some systems portable OpenSSH is built on. + +commit 36aba25b0409d2db6afc84d54bc47a2532d38424 +Author: Damien Miller +Date: Thu Nov 21 14:24:42 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 03:15:46 + [regress/krl.sh] + add some reminders for additional tests that I'd like to implement + +commit fa7a20bc289f09b334808d988746bc260a2f60c9 +Author: Damien Miller +Date: Thu Nov 21 14:24:08 2013 +1100 + + - naddy@cvs.openbsd.org 2013/11/18 05:09:32 + [regress/forward-control.sh] + bump timeout to 10 seconds to allow slow machines (e.g. Alpha PC164) + to successfully run this; ok djm@ + (ID sync only; our timeouts are already longer) + +commit 0fde8acdad78a4d20cadae974376cc0165f645ee +Author: Damien Miller +Date: Thu Nov 21 14:12:23 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/21 00:45:44 + [Makefile.in PROTOCOL PROTOCOL.chacha20poly1305 authfile.c chacha.c] + [chacha.h cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h] + [dh.c myproposal.h packet.c poly1305.c poly1305.h servconf.c ssh.1] + [ssh.c ssh_config.5 sshd_config.5] Add a new protocol 2 transport + cipher "chacha20-poly1305@openssh.com" that combines Daniel + Bernstein's ChaCha20 stream cipher and Poly1305 MAC to build an + authenticated encryption mode. + + Inspired by and similar to Adam Langley's proposal for TLS: + http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 + but differs in layout used for the MAC calculation and the use of a + second ChaCha20 instance to separately encrypt packet lengths. + Details are in the PROTOCOL.chacha20poly1305 file. + + Feedback markus@, naddy@; manpage bits Loganden Velvindron @ AfriNIC + ok markus@ naddy@ + +commit fdb2306acdc3eb2bc46b6dfdaaf6005c650af22a +Author: Damien Miller +Date: Thu Nov 21 13:57:15 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/20 20:54:10 + [canohost.c clientloop.c match.c readconf.c sftp.c] + unsigned casts for ctype macros where neccessary + ok guenther millert markus + +commit e00167307e4d3692695441e9bd712f25950cb894 +Author: Damien Miller +Date: Thu Nov 21 13:56:49 2013 +1100 + + - deraadt@cvs.openbsd.org 2013/11/20 20:53:10 + [scp.c] + unsigned casts for ctype macros where neccessary + ok guenther millert markus + +commit 23e00aa6ba9eee0e0c218f2026bf405ad4625832 +Author: Damien Miller +Date: Thu Nov 21 13:56:28 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/20 02:19:01 + [sshd.c] + delay closure of in/out fds until after "Bad protocol version + identification..." message, as get_remote_ipaddr/get_remote_port + require them open. + +commit 867e6934be6521f87f04a5ab86702e2d1b314245 +Author: Damien Miller +Date: Thu Nov 21 13:56:06 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/13 13:48:20 + [ssh-pkcs11.c] + add missing braces found by pedro + +commit 0600c7020f4fe68a780bd7cf21ff541a8d4b568a +Author: Damien Miller +Date: Thu Nov 21 13:55:43 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/08 11:15:19 + [bufaux.c bufbn.c buffer.c sftp-client.c sftp-common.c sftp-glob.c] + [uidswap.c] Include stdlib.h for free() as per the man page. + +commit b6a75b0b93b8faa6f79c3a395ab6c71f3f880b80 +Author: Darren Tucker +Date: Sun Nov 10 20:25:22 2013 +1100 + + - (dtucker) [regress/keytype.sh] Populate ECDSA key types to be tested by + querying the ones that are compiled in. + +commit 2c89430119367eb1bc96ea5ee55de83357e4c926 +Author: Darren Tucker +Date: Sun Nov 10 12:38:42 2013 +1100 + + - (dtucker) [key.c] Check for the correct defines for NID_secp521r1. + +commit dd5264db5f641dbd03186f9e5e83e4b14b3d0003 +Author: Darren Tucker +Date: Sat Nov 9 22:32:51 2013 +1100 + + - (dtucker) [configure.ac] Add missing "test". + +commit 95cb2d4eb08117be061f3ff076adef3e9a5372c3 +Author: Darren Tucker +Date: Sat Nov 9 22:02:31 2013 +1100 + + - (dtucker) [configure.ac] Fix brackets in NID_secp521r1 test. + +commit 37bcef51b3d9d496caecea6394814d2f49a1357f +Author: Darren Tucker +Date: Sat Nov 9 18:39:25 2013 +1100 + + - (dtucker) [configure.ac kex.c key.c myproposal.h] Test for the presence of + NID_X9_62_prime256v1, NID_secp384r1 and NID_secp521r1 and test that the + latter actually works before using it. Fedora (at least) has NID_secp521r1 + that doesn't work (see https://bugzilla.redhat.com/show_bug.cgi?id=1021897). + +commit 6e2fe81f926d995bae4be4a6b5b3c88c1c525187 +Author: Darren Tucker +Date: Sat Nov 9 16:55:03 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/09 05:41:34 + [regress/test-exec.sh regress/rekey.sh] + Use smaller test data files to speed up tests. Grow test datafiles + where necessary for a specific test. + +commit aff7ef1bb8b7c1eeb1f4812129091c5adbf51848 +Author: Darren Tucker +Date: Sat Nov 9 00:19:22 2013 +1100 + + - (dtucker) [contrib/cygwin/ssh-host-config] Simplify host key generation: + rather than testing and generating each key, call ssh-keygen -A. + Patch from vinschen at redhat.com. + +commit 882abfd3fb3c98cfe70b4fc79224770468b570a5 +Author: Darren Tucker +Date: Sat Nov 9 00:17:41 2013 +1100 + + - (dtucker) [Makefile.in configure.ac] Set MALLOC_OPTIONS per platform + and pass in TEST_ENV. Unknown options cause stderr to get polluted + and the stderr-data test to fail. + +commit 8c333ec23bdf7da917aa20ac6803a2cdd79182c5 +Author: Darren Tucker +Date: Fri Nov 8 21:12:58 2013 +1100 + + - (dtucker) [openbsd-compat/bsd-poll.c] Add headers to prevent compile + warnings. + +commit d94240b2f6b376b6e9de187e4a0cd4b89dfc48cb +Author: Darren Tucker +Date: Fri Nov 8 21:10:04 2013 +1100 + + - (dtucker) [myproposal.h] Conditionally enable CURVE25519_SHA256. + +commit 1c8ce34909886288a3932dce770deec5449f7bb5 +Author: Darren Tucker +Date: Fri Nov 8 19:50:32 2013 +1100 + + - (dtucker) [kex.c] Only enable CURVE25519_SHA256 if we actually have + EVP_sha256. + +commit ccdb9bec46bcc88549b26a94aa0bae2b9f51031c +Author: Darren Tucker +Date: Fri Nov 8 18:54:38 2013 +1100 + + - (dtucker) [openbsd-compat/openbsd-compat.h] Add null implementation of + arc4random_stir for platforms that have arc4random but don't have + arc4random_stir (right now this is only OpenBSD -current). + +commit 3420a50169b52cc8d2775d51316f9f866c73398f +Author: Damien Miller +Date: Fri Nov 8 16:48:13 2013 +1100 + + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update version numbers following release. + +commit 3ac4a234df842fd8c94d9cb0ad198e1fe84b895b +Author: Damien Miller +Date: Fri Nov 8 12:39:49 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/08 01:38:11 + [version.h] + openssh-6.4 + +commit 6c81fee693038de7d4a5559043350391db2a2761 +Author: Damien Miller +Date: Fri Nov 8 12:19:55 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/08 00:39:15 + [auth-options.c auth2-chall.c authfd.c channels.c cipher-3des1.c] + [clientloop.c gss-genr.c monitor_mm.c packet.c schnorr.c umac.c] + [sftp-client.c sftp-glob.c] + use calloc for all structure allocations; from markus@ + +commit 690d989008e18af3603a5e03f1276c9bad090370 +Author: Damien Miller +Date: Fri Nov 8 12:16:49 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 11:58:27 + [cipher.c cipher.h kex.c kex.h mac.c mac.h servconf.c ssh.c] + Output the effective values of Ciphers, MACs and KexAlgorithms when + the default has not been overridden. ok markus@ + +commit 08998c5fb9c7c1d248caa73b76e02ca0482e6d85 +Author: Darren Tucker +Date: Fri Nov 8 12:11:46 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/08 01:06:14 + [regress/rekey.sh] + Rekey less frequently during tests to speed them up + +commit 4bf7e50e533aa956366df7402c132f202e841a48 +Author: Darren Tucker +Date: Thu Nov 7 22:33:48 2013 +1100 + + - (dtucker) [Makefile.in configure.ac] Remove TEST_SSH_SHA256 environment + variable. It's no longer used now that we get the supported MACs from + ssh -Q. + +commit 6e9d6f411288374d1dee4b7debbfa90bc7e73035 +Author: Darren Tucker +Date: Thu Nov 7 15:32:37 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 04:26:56 + [regress/kextype.sh] + trailing space + +commit 74cbc22529f3e5de756e1b7677b7624efb28f62c +Author: Darren Tucker +Date: Thu Nov 7 15:26:12 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 03:55:41 + [regress/kextype.sh] + Use ssh -Q to get kex types instead of a static list. + +commit a955041c930e63405159ff7d25ef14272f36eab3 +Author: Darren Tucker +Date: Thu Nov 7 15:21:19 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 02:48:38 + [regress/integrity.sh regress/cipher-speed.sh regress/try-ciphers.sh] + Use ssh -Q instead of hardcoding lists of ciphers or MACs. + +commit 06595d639577577bc15d359e037a31eb83563269 +Author: Darren Tucker +Date: Thu Nov 7 15:08:02 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 01:12:51 + [regress/rekey.sh] + Factor out the data transfer rekey tests + +commit 651dc8b2592202dac6b16ee3b82ce5b331be7da3 +Author: Darren Tucker +Date: Thu Nov 7 15:04:44 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/07 00:12:05 + [regress/rekey.sh] + Test rekeying for every Cipher, MAC and KEX, plus test every KEX with + the GCM ciphers. + +commit 234557762ba1096a867ca6ebdec07efebddb5153 +Author: Darren Tucker +Date: Thu Nov 7 15:00:51 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/11/04 12:27:42 + [regress/rekey.sh] + Test rekeying with all KexAlgorithms. + +commit bbfb9b0f386aab0c3e19d11f136199ef1b9ad0ef +Author: Darren Tucker +Date: Thu Nov 7 14:56:43 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:39:53 + [regress/kextype.sh] + add curve25519-sha256@libssh.org + +commit aa19548a98c0f89283ebd7354abd746ca6bc4fdf +Author: Darren Tucker +Date: Thu Nov 7 14:50:09 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/09 23:44:14 + [regress/Makefile] (ID sync only) + regression test for sftp request white/blacklisting and readonly mode. + +commit c8908aabff252f5da772d4e679479c2b7d18cac1 +Author: Damien Miller +Date: Thu Nov 7 13:38:35 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/06 23:05:59 + [ssh-pkcs11.c] + from portable: s/true/true_val/ to avoid name collisions on dump platforms + RCSID sync only + +commit 49c145c5e89b9d7d48e84328d6347d5ad640b567 +Author: Damien Miller +Date: Thu Nov 7 13:35:39 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/06 16:52:11 + [monitor_wrap.c] + fix rekeying for AES-GCM modes; ok deraadt + +commit 67a8800f290b39fd60e379988c700656ae3f2539 +Author: Damien Miller +Date: Thu Nov 7 13:32:51 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/04 11:51:16 + [monitor.c] + fix rekeying for KEX_C25519_SHA256; noted by dtucker@ + RCSID sync only; I thought this was a merge botch and fixed it already + +commit df8b030b15fcec7baf38ec7944f309f9ca8cc9a7 +Author: Damien Miller +Date: Thu Nov 7 13:28:16 2013 +1100 + + - (djm) [configure.ac defines.h] Skip arc4random_stir() calls on platforms + that lack it but have arc4random_uniform() + +commit a6fd1d3c38a562709374a70fa76423859160aa90 +Author: Damien Miller +Date: Thu Nov 7 12:03:26 2013 +1100 + + - (djm) [regress/modpipe.c regress/rekey.sh] Never intended to commit these + +commit c98319750b0bbdd0d1794420ec97d65dd9244613 +Author: Damien Miller +Date: Thu Nov 7 12:00:23 2013 +1100 + + - (djm) [Makefile.in monitor.c] Missed chunks of curve25519 KEX diff + +commit 61c5c2319e84a58210810d39b062c8b8e3321160 +Author: Damien Miller +Date: Thu Nov 7 11:34:14 2013 +1100 + + - (djm) [ssh-pkcs11.c] Bring back "non-constant initialiser" fix (rev 1.5) + that got lost in recent merge. + +commit 094003f5454a9f5a607674b2739824a7e91835f4 +Author: Damien Miller +Date: Mon Nov 4 22:59:27 2013 +1100 + + - (djm) [kexc25519.c kexc25519c.c kexc25519s.c] Import missed files from + KEX/curve25519 change + +commit ca67a7eaf8766499ba67801d0be8cdaa550b9a50 +Author: Damien Miller +Date: Mon Nov 4 09:05:17 2013 +1100 + + - djm@cvs.openbsd.org 2013/11/03 10:37:19 + [roaming_common.c] + fix a couple of function definitions foo() -> foo(void) + (-Wold-style-definition) + +commit 0bd8f1519d51af8d4229be81e8f2f4903a1d440b +Author: Damien Miller +Date: Mon Nov 4 08:55:43 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:39:19 + [ssh_config.5 sshd_config.5] + the default kex is now curve25519-sha256@libssh.org + +commit 4c3ba0767fbe4a8a2a748df4035aaf86651f6b30 +Author: Damien Miller +Date: Mon Nov 4 08:40:13 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:34:01 + [auth-options.c] + no need to include monitor_wrap.h and ssh-gss.h + +commit 660621b2106b987b874c2f120218bec249d0f6ba +Author: Damien Miller +Date: Mon Nov 4 08:37:51 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:24:24 + [kexdhs.c kexecdhs.c] + no need to include ssh-gss.h + +commit abdca986decfbbc008c895195b85e879ed460ada +Author: Damien Miller +Date: Mon Nov 4 08:30:05 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 22:10:15 + [kexdhs.c kexecdhs.c] + no need to include monitor_wrap.h + +commit 1e1242604eb0fd510fe93f81245c529237ffc513 +Author: Damien Miller +Date: Mon Nov 4 08:26:52 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 21:59:15 + [kex.c kex.h myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] + use curve25519 for default key exchange (curve25519-sha256@libssh.org); + initial patch from Aris Adamantiadis; ok djm@ + +commit d2252c79191d069372ed6effce7c7a2de93448cd +Author: Damien Miller +Date: Mon Nov 4 07:41:48 2013 +1100 + + - markus@cvs.openbsd.org 2013/11/02 20:03:54 + [ssh-pkcs11.c] + support pkcs#11 tokes that only provide x509 zerts instead of raw pubkeys; + fixes bz#1908; based on patch from Laurent Barbe; ok djm + +commit 007e3b357e880caa974d5adf9669298ba0751c78 +Author: Darren Tucker +Date: Sun Nov 3 18:43:55 2013 +1100 + + - (dtucker) [configure.ac defines.h] Add typedefs for intmax_t and uintmax_t + for platforms that don't have them. + +commit 710f3747352fb93a63e5b69b12379da37f5b3fa9 +Author: Darren Tucker +Date: Sun Nov 3 17:20:34 2013 +1100 + + - (dtucker) [openbsd-compat/setproctitle.c] Handle error case form the 2nd + vsnprintf. From eric at openbsd via chl@. + +commit d52770452308e5c2e99f4da6edaaa77ef078b610 +Author: Darren Tucker +Date: Sun Nov 3 16:30:46 2013 +1100 + + - (dtucker) [openbsd-compat/bsd-misc.c] Include time.h for nanosleep. + From OpenSMTPD where it prevents "implicit declaration" warnings (it's + a no-op in OpenSSH). From chl at openbsd. + +commit 63857c9340d3482746a5622ffdacc756751f6448 +Author: Damien Miller +Date: Wed Oct 30 22:31:06 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/29 18:49:32 + [sshd_config.5] + pty(4), not pty(7); + +commit 5ff30c6b68adeee767dd29bf2369763c6a13c0b3 +Author: Damien Miller +Date: Wed Oct 30 22:21:50 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/29 09:48:02 + [servconf.c servconf.h session.c sshd_config sshd_config.5] + shd_config PermitTTY to disallow TTY allocation, mirroring the + longstanding no-pty authorized_keys option; + bz#2070, patch from Teran McKinney; ok markus@ + +commit 4a3a9d4bbf8048473f5cc202cd8db7164d5e6b8d +Author: Damien Miller +Date: Wed Oct 30 22:19:47 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/29 09:42:11 + [key.c key.h] + fix potential stack exhaustion caused by nested certificates; + report by Mateusz Kocielski; ok dtucker@ markus@ + +commit 28631ceaa7acd9bc500f924614431542893c6a21 +Author: Damien Miller +Date: Sat Oct 26 10:07:56 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/25 23:04:51 + [ssh.c] + fix crash when using ProxyCommand caused by previous commit - was calling + freeaddrinfo(NULL); spotted by sthen@ and Tim Ruehsen, patch by sthen@ + +commit 26506ad29350c5681815745cc90b3952a84cf118 +Author: Damien Miller +Date: Sat Oct 26 10:05:46 2013 +1100 + + - (djm) [ssh-keygen.c ssh-keysign.c sshconnect1.c sshd.c] Remove + unnecessary arc4random_stir() calls. The only ones left are to ensure + that the PRNG gets a different state after fork() for platforms that + have broken the API. + +commit bd43e8872325e9bbb3319c89da593614709f317c +Author: Tim Rice +Date: Thu Oct 24 12:22:49 2013 -0700 + + - (tim) [regress/sftp-perm.sh] We need a shell that understands "! somecmd" + +commit a90c0338083ee0e4064c4bdf61f497293a699be0 +Author: Damien Miller +Date: Thu Oct 24 21:03:17 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/24 08:19:36 + [ssh.c] + fix bug introduced in hostname canonicalisation commit: don't try to + resolve hostnames when a ProxyCommand is set unless the user has forced + canonicalisation; spotted by Iain Morgan + +commit cf31f3863425453ffcda540fbefa9df80088c8d1 +Author: Damien Miller +Date: Thu Oct 24 21:02:56 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/24 00:51:48 + [readconf.c servconf.c ssh_config.5 sshd_config.5] + Disallow empty Match statements and add "Match all" which matches + everything. ok djm, man page help jmc@ + +commit 4bedd4032a09ce87322ae5ea80f193f109e5c607 +Author: Damien Miller +Date: Thu Oct 24 21:02:26 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/24 00:49:49 + [moduli.c] + Periodically print progress and, if possible, expected time to completion + when screening moduli for DH groups. ok deraadt djm + +commit 5ecb41629860687b145be63b8877fabb6bae5eda +Author: Damien Miller +Date: Thu Oct 24 21:02:02 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 23:35:32 + [sshd.c] + include local address and port in "Connection from ..." message (only + shown at loglevel>=verbose) + +commit 03bf2e61ad6ac59a362a1f11b105586cb755c147 +Author: Damien Miller +Date: Thu Oct 24 21:01:26 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/23 05:40:58 + [servconf.c] + fix comment + +commit 8f1873191478847773906af961c8984d02a49dd6 +Author: Damien Miller +Date: Thu Oct 24 10:53:02 2013 +1100 + + - (djm) [auth-krb5.c] bz#2032 - use local username in krb5_kuserok check + rather than full client name which may be of form user@REALM; + patch from Miguel Sanders; ok dtucker@ + +commit 5b01b0dcb417eb615df77e7ce1b59319bf04342c +Author: Damien Miller +Date: Wed Oct 23 16:31:31 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 04:16:22 + [ssh-keygen.c] + Make code match documentation: relative-specified certificate expiry time + should be relative to current time and not the validity start time. + Reported by Petr Lautrbach; ok deraadt@ + +commit eff5cada589f25793dbe63a76aba9da39837a148 +Author: Damien Miller +Date: Wed Oct 23 16:31:10 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 03:05:19 + [readconf.c ssh.c] + comment + +commit 084bcd24e9fe874020e4df4e073e7408e1b17fb7 +Author: Damien Miller +Date: Wed Oct 23 16:30:51 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/23 03:03:07 + [readconf.c] + Hostname may have %h sequences that should be expanded prior to Match + evaluation; spotted by Iain Morgan + +commit 8e5a67f46916def40b2758bb7755350dd2eee843 +Author: Damien Miller +Date: Wed Oct 23 16:30:25 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/20 18:00:13 + [ssh_config.5] + tweak the "exec" description, as worded by djm; + +commit c0049bd0bca02890cd792babc594771c563f91f2 +Author: Damien Miller +Date: Wed Oct 23 16:29:59 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/20 09:51:26 + [scp.1 sftp.1] + add canonicalisation options to -o lists + +commit 8a04be795fc28514a09e55a54b2e67968f2e1b3a +Author: Damien Miller +Date: Wed Oct 23 16:29:40 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/20 06:19:28 + [readconf.c ssh_config.5] + rename "command" subclause of the recently-added "Match" keyword to + "exec"; it's shorter, clearer in intent and we might want to add the + ability to match against the command being executed at the remote end in + the future. + +commit 5c86ebdf83b636b6741db4b03569ef4a53b89a58 +Author: Damien Miller +Date: Wed Oct 23 16:29:12 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/20 04:39:28 + [ssh_config.5] + document % expansions performed by "Match command ..." + +commit 4502f88774edc56194707167443f94026d3c7cfa +Author: Damien Miller +Date: Fri Oct 18 10:17:36 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/17 22:08:04 + [sshd.c] + include remote port in bad banner message; bz#2162 + +commit 1edcbf65ebd2febeaf10a836468f35e519eed7ca +Author: Damien Miller +Date: Fri Oct 18 10:17:17 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/17 07:35:48 + [sftp.1 sftp.c] + tweak previous; + +commit a176e1823013dd8533a20235b3a5131f0626f46b +Author: Damien Miller +Date: Fri Oct 18 09:05:41 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/09 23:44:14 + [regress/Makefile regress/sftp-perm.sh] + regression test for sftp request white/blacklisting and readonly mode. + +commit e3ea09494dcfe7ba76536e95765c8328ecfc18fb +Author: Damien Miller +Date: Thu Oct 17 11:57:23 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/17 00:46:49 + [ssh.c] + rearrange check to reduce diff against -portable + (Id sync only) + +commit f29238e67471a7f1088a99c3c3dbafce76b790cf +Author: Damien Miller +Date: Thu Oct 17 11:48:52 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/17 00:30:13 + [PROTOCOL sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c] + fsync@openssh.com protocol extension for sftp-server + client support to allow calling fsync() faster successful transfer + patch mostly by imorgan AT nas.nasa.gov; bz#1798 + "fine" markus@ "grumble OK" deraadt@ "doesn't sound bad to me" millert@ + +commit 51682faa599550a69d8120e5e2bdbdc0625ef4be +Author: Damien Miller +Date: Thu Oct 17 11:48:31 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/16 22:58:01 + [ssh.c ssh_config.5] + one I missed in previous: s/isation/ization/ + +commit 3850559be93f1a442ae9ed370e8c389889dd5f72 +Author: Damien Miller +Date: Thu Oct 17 11:48:13 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/16 22:49:39 + [readconf.c readconf.h ssh.1 ssh.c ssh_config.5] + s/canonicalise/canonicalize/ for consistency with existing spelling, + e.g. authorized_keys; pointed out by naddy@ + +commit 607af3434b75acc7199a5d99d5a9c11068c01f27 +Author: Damien Miller +Date: Thu Oct 17 11:47:51 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/16 06:42:25 + [ssh_config.5] + tweak previous; + +commit 0faf747e2f77f0f7083bcd59cbed30c4b5448444 +Author: Damien Miller +Date: Thu Oct 17 11:47:23 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/16 02:31:47 + [readconf.c readconf.h roaming_client.c ssh.1 ssh.c ssh_config.5] + [sshconnect.c sshconnect.h] + Implement client-side hostname canonicalisation to allow an explicit + search path of domain suffixes to use to convert unqualified host names + to fully-qualified ones for host key matching. + This is particularly useful for host certificates, which would otherwise + need to list unqualified names alongside fully-qualified ones (and this + causes a number of problems). + "looks fine" markus@ + +commit d77b81f856e078714ec6b0f86f61c20249b7ead4 +Author: Damien Miller +Date: Thu Oct 17 11:39:00 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/15 14:10:25 + [ssh.1 ssh_config.5] + tweak previous; + +commit dcd39f29ce3308dc74a0ff27a9056205a932ce05 +Author: Damien Miller +Date: Thu Oct 17 11:31:40 2013 +1100 + + - [ssh.c] g/c unused variable. + +commit 5359a628ce3763408da25d83271a8eddec597a0c +Author: Damien Miller +Date: Tue Oct 15 12:20:37 2013 +1100 + + - [ssh.c] g/c unused variable. + +commit 386feab0c4736b054585ee8ee372865d5cde8d69 +Author: Damien Miller +Date: Tue Oct 15 12:14:49 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 23:31:01 + [ssh.c] + whitespace at EOL; pointed out by markus@ + +commit e9fc72edd6c313b670558cd5219601c38a949b67 +Author: Damien Miller +Date: Tue Oct 15 12:14:12 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 23:28:23 + [canohost.c misc.c misc.h readconf.c sftp-server.c ssh.c] + refactor client config code a little: + add multistate option partsing to readconf.c, similar to servconf.c's + existing code. + move checking of options that accept "none" as an argument to readconf.c + add a lowercase() function and use it instead of explicit tolower() in + loops + part of a larger diff that was ok markus@ + +commit 194fd904d8597a274b93e075b2047afdf5a175d4 +Author: Damien Miller +Date: Tue Oct 15 12:13:05 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 22:22:05 + [readconf.c readconf.h ssh-keysign.c ssh.c ssh_config.5] + add a "Match" keyword to ssh_config that allows matching on hostname, + user and result of arbitrary commands. "nice work" markus@ + +commit 71df752de2a04f423b1cd18d961a79f4fbccbcee +Author: Damien Miller +Date: Tue Oct 15 12:12:02 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/14 21:20:52 + [session.c session.h] + Add logging of session starts in a useful format; ok markus@ feedback and + ok dtucker@ + +commit 6efab27109b82820e8d32a5d811adb7bfc354f65 +Author: Damien Miller +Date: Tue Oct 15 12:07:05 2013 +1100 + + - jmc@cvs.openbsd.org 2013/10/14 14:18:56 + [sftp-server.8 sftp-server.c] + tweak previous; + ok djm + +commit 61c7de8a94156f6d7e9718ded9be8c65bb902b66 +Author: Damien Miller +Date: Tue Oct 15 12:06:45 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/11 02:53:45 + [sftp-client.h] + obsolete comment + +commit 2f93d0556e4892208c9b072624caa8cc5ddd839d +Author: Damien Miller +Date: Tue Oct 15 12:06:27 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/11 02:52:23 + [sftp-client.c] + missed one arg reorder + +commit bda5c8445713ae592d969a5105ed1a65da22bc96 +Author: Damien Miller +Date: Tue Oct 15 12:05:58 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/11 02:45:36 + [sftp-client.c] + rename flag arguments to be more clear and consistent. + reorder some internal function arguments to make adding additional flags + easier. + no functional change + +commit 61ee4d68ca0fcc793a826fc7ec70f3b8ffd12ab6 +Author: Damien Miller +Date: Tue Oct 15 11:56:47 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/10 01:43:03 + [sshd.c] + bz#2139: fix re-exec fallback by ensuring that startup_pipe is correctly + updated; ok dtucker@ + +commit 73600e51af9ee734a19767e0c084bbbc5eb5b8da +Author: Damien Miller +Date: Tue Oct 15 11:56:25 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/10 00:53:25 + [sftp-server.c] + add -Q, -P and -p to usage() before jmc@ catches me + +commit 6eaeebf27d92f39a38c772aa3f20c2250af2dd29 +Author: Damien Miller +Date: Tue Oct 15 11:55:57 2013 +1100 + + - djm@cvs.openbsd.org 2013/10/09 23:42:17 + [sftp-server.8 sftp-server.c] + Add ability to whitelist and/or blacklist sftp protocol requests by name. + Refactor dispatch loop and consolidate read-only mode checks. + Make global variables static, since sftp-server is linked into sshd(8). + ok dtucker@ + +commit df62d71e64d29d1054e7a53d1a801075ef70335f +Author: Darren Tucker +Date: Thu Oct 10 10:32:39 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/10/08 11:42:13 + [dh.c dh.h] + Increase the size of the Diffie-Hellman groups requested for a each + symmetric key size. New values from NIST Special Publication 800-57 with + the upper limit specified by RFC4419. Pointed out by Peter Backes, ok + djm@. + +commit e6e52f8c5dc89a6767702e65bb595aaf7bc8991c +Author: Darren Tucker +Date: Thu Oct 10 10:28:07 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 01:26:29 + [sshconnect.c] + bz#1211: make BindAddress work with UsePrivilegedPort=yes; patch from + swp AT swp.pp.ru; ok dtucker@ + +commit 71152bc9911bc34a98810b2398dac20df3fe8de3 +Author: Darren Tucker +Date: Thu Oct 10 10:27:21 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 01:24:46 + [channels.c] + bz#1297 - tell the client (via packet_send_debug) when their preferred + listen address has been overridden by the server's GatewayPorts; + ok dtucker@ + +commit b59aaf3c4f3f449a4b86d8528668bd979be9aa5f +Author: Darren Tucker +Date: Thu Oct 10 10:26:21 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 00:49:12 + [sftp-client.c] + fix swapped pflag and printflag in sftp upload_dir; from Iain Morgan + +commit 5d80e4522d6238bdefe9d0c634f0e6d35a241e41 +Author: Darren Tucker +Date: Thu Oct 10 10:25:09 2013 +1100 + + - djm@cvs.openbsd.org 2013/09/19 00:24:52 + [progressmeter.c] + store the initial file offset so the progress meter doesn't freak out + when resuming sftp transfers. bz#2137; patch from Iain Morgan; ok dtucker@ + +commit ad92df7e5ed26fea85adfb3f95352d6cd8e86344 +Author: Darren Tucker +Date: Thu Oct 10 10:24:11 2013 +1100 + + - sthen@cvs.openbsd.org 2013/09/16 11:35:43 + [ssh_config] + Remove gssapi config parts from ssh_config, as was already done for + sshd_config. Req by/ok ajacoutot@ + ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular + +commit 720711960b130d36dfdd3d50eb25ef482bdd000e +Author: Damien Miller +Date: Wed Oct 9 10:44:47 2013 +1100 + + - (djm) [openbsd-compat/Makefile.in openbsd-compat/arc4random.c] + [openbsd-compat/bsd-arc4random.c] Replace old RC4-based arc4random + implementation with recent OpenBSD's ChaCha-based PRNG. ok dtucker@, + tested tim@ + +commit 9159310087a218e28940a592896808b8eb76a039 +Author: Damien Miller +Date: Wed Oct 9 10:42:32 2013 +1100 + + - (djm) [openbsd-compat/arc4random.c openbsd-compat/chacha_private.h] Pull + in OpenBSD implementation of arc4random, shortly to replace the existing + bsd-arc4random.c + +commit 67f1d557a68d6fa8966a327d7b6dee3408cf0e72 +Author: Damien Miller +Date: Wed Oct 9 09:33:08 2013 +1100 + + correct incorrect years in datestamps; from des + +commit f2bf36c3eb4d969f85ec8aa342e9aecb61cc8bb1 +Author: Darren Tucker +Date: Sun Sep 22 19:02:40 2013 +1000 + + - (dtucker) [platform.c platform.h sshd.c] bz#2156: restore Linux oom_adj + setting when handling SIGHUP to maintain behaviour over retart. Patch + from Matthew Ife. + +commit e90a06ae570fd259a2f5ced873c7f17390f535a5 +Author: Darren Tucker +Date: Wed Sep 18 15:09:38 2013 +1000 + + - (dtucker) [sshd_config] Trailing whitespace; from jstjohn at purdue edu. + +commit 13840e0103946982cee2a05c40697be7e57dca41 +Author: Damien Miller +Date: Sat Sep 14 09:49:43 2013 +1000 + + - djm@cvs.openbsd.org 2013/09/13 06:54:34 + [channels.c] + avoid unaligned access in code that reused a buffer to send a + struct in_addr in a reply; simpler just use use buffer_put_int(); + from portable; spotted by and ok dtucker@ + +commit 70182522a47d283513a010338cd028cb80dac2ab +Author: Damien Miller +Date: Sat Sep 14 09:49:19 2013 +1000 + + - djm@cvs.openbsd.org 2013/09/12 01:41:12 + [clientloop.c] + fix connection crash when sending break (~B) on ControlPersist'd session; + ok dtucker@ + +commit ff9d6c2a4171ee32e8fe28fc3b86eb33bd5c845b +Author: Damien Miller +Date: Sat Sep 14 09:48:55 2013 +1000 + + - sthen@cvs.openbsd.org 2013/09/07 13:53:11 + [sshd_config] + Remove commented-out kerberos/gssapi config options from sample config, + kerberos support is currently not enabled in ssh in OpenBSD. Discussed with + various people; ok deraadt@ + ID SYNC ONLY for portable; kerberos/gssapi is still pretty popular + +commit 8bab5e7b5ff6721d926b5ebf05a3a24489889c58 +Author: Damien Miller +Date: Sat Sep 14 09:47:00 2013 +1000 + + - deraadt@cvs.openbsd.org 2013/09/02 22:00:34 + [ssh-keygen.c sshconnect1.c sshd.c] + All the instances of arc4random_stir() are bogus, since arc4random() + does this itself, inside itself, and has for a very long time.. Actually, + this was probably reducing the entropy available. + ok djm + ID SYNC ONLY for portable; we don't trust other arc4random implementations + to do this right. + +commit 61353b3208d548fab863e0e0ac5d2400ee5bb340 +Author: Damien Miller +Date: Sat Sep 14 09:45:32 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/31 00:13:54 + [sftp.c] + make ^w match ksh behaviour (delete previous word instead of entire line) + +commit 660854859cad31d234edb9353fb7ca2780df8128 +Author: Damien Miller +Date: Sat Sep 14 09:45:03 2013 +1000 + + - mikeb@cvs.openbsd.org 2013/08/28 12:34:27 + [ssh-keygen.c] + improve batch processing a bit by making use of the quite flag a bit + more often and exit with a non zero code if asked to find a hostname + in a known_hosts file and it wasn't there; + originally from reyk@, ok djm + +commit 045bda5cb8acf0eb9d71c275ee1247e3154fc9e5 +Author: Damien Miller +Date: Sat Sep 14 09:44:37 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/22 19:02:21 + [sshd.c] + Stir PRNG after post-accept fork. The child gets a different PRNG state + anyway via rexec and explicit privsep reseeds, but it's good to be sure. + ok markus@ + +commit ed4af412da60a084891b20412433a27966613fb8 +Author: Damien Miller +Date: Sat Sep 14 09:40:51 2013 +1000 + + add marker for 6.3p1 release at the point of the last included change + +commit 43968a8e66a0aa1afefb11665bf96f86b113f5d9 +Author: Damien Miller +Date: Wed Aug 28 14:00:54 2013 +1000 + + - (djm) [openbsd-compat/bsd-snprintf.c] #ifdef noytet for intmax_t bits + until we have configure support. + +commit 04be8b9e53f8388c94b531ebc5d1bd6e10e930d1 +Author: Damien Miller +Date: Wed Aug 28 12:49:43 2013 +1000 + + - (djm) [openbsd-compat/bsd-snprintf.c] teach our local snprintf code the + 'j' (intmax_t/uintmax_t) and 'z' (size_t/ssize_t) conversions in case we + start to use them in the future. + +commit f2f6c315a920a256937e1b6a3702757f3195a592 +Author: Damien Miller +Date: Wed Aug 21 02:44:58 2013 +1000 + + - jmc@cvs.openbsd.org 2013/08/20 06:56:07 + [ssh.1 ssh_config.5] + some proxyusefdpass tweaks; + +commit 1262b6638f7d01ab110fd373dd90d915c882fe1a +Author: Damien Miller +Date: Wed Aug 21 02:44:24 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/20 00:11:38 + [readconf.c readconf.h ssh_config.5 sshconnect.c] + Add a ssh_config ProxyUseFDPass option that supports the use of + ProxyCommands that establish a connection and then pass a connected + file descriptor back to ssh(1). This allows the ProxyCommand to exit + rather than have to shuffle data back and forth and enables ssh to use + getpeername, etc. to obtain address information just like it does with + regular directly-connected sockets. ok markus@ + +commit b7727df37efde4dbe4f5a33b19cbf42022aabf66 +Author: Damien Miller +Date: Wed Aug 21 02:43:49 2013 +1000 + + - jmc@cvs.openbsd.org 2013/08/14 08:39:27 + [scp.1 ssh.1] + some Bx/Ox conversion; + From: Jan Stary + +commit d5d9d7b1fdacf0551de4c747728bd159be40590a +Author: Damien Miller +Date: Wed Aug 21 02:43:27 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/13 18:33:08 + [ssh-keygen.c] + another of the same typo + +commit d234afb0b3a8de1be78cbeafed5fc86912594c3c +Author: Damien Miller +Date: Wed Aug 21 02:42:58 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/13 18:32:08 + [ssh-keygen.c] + typo in error message; from Stephan Rickauer + +commit e0ee727b8281a7c2ae20630ce83f6b200b404059 +Author: Damien Miller +Date: Wed Aug 21 02:42:35 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/09 03:56:42 + [sftp.c] + enable ctrl-left-arrow and ctrl-right-arrow to move forward/back a word; + matching ksh's relatively recent change. + +commit fec029f1dc2c338f3fae3fa82aabc988dc07868c +Author: Damien Miller +Date: Wed Aug 21 02:42:12 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/09 03:39:13 + [sftp-client.c] + two problems found by a to-be-committed regress test: 1) msg_id was not + being initialised so was starting at a random value from the heap + (harmless, but confusing). 2) some error conditions were not being + propagated back to the caller + +commit 036d30743fc914089f9849ca52d615891d47e616 +Author: Damien Miller +Date: Wed Aug 21 02:41:46 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/09 03:37:25 + [sftp.c] + do getopt parsing for all sftp commands (with an empty optstring for + commands without arguments) to ensure consistent behaviour + +commit c7dba12bf95eb1d69711881a153cc286c1987663 +Author: Damien Miller +Date: Wed Aug 21 02:41:15 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/08 05:04:03 + [sftp-client.c sftp-client.h sftp.c] + add a "-l" flag for the rename command to force it to use the silly + standard SSH_FXP_RENAME command instead of the POSIX-rename- like + posix-rename@openssh.com extension. + + intended for use in regress tests, so no documentation. + +commit 034f27a0c09e69fe3589045b41f03f6e345b63f5 +Author: Damien Miller +Date: Wed Aug 21 02:40:44 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/08 04:52:04 + [sftp.c] + fix two year old regression: symlinking a file would incorrectly + canonicalise the target path. bz#2129 report from delphij AT freebsd.org + +commit c6895c5c67492144dd28589e5788f783be9152ed +Author: Damien Miller +Date: Wed Aug 21 02:40:21 2013 +1000 + + - jmc@cvs.openbsd.org 2013/08/07 06:24:51 + [sftp.1 sftp.c] + sort -a; + +commit a6d6c1f38ac9b4a5e1bd4df889e1020a8370ed55 +Author: Damien Miller +Date: Wed Aug 21 02:40:01 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/06 23:06:01 + [servconf.c] + add cast to avoid format warning; from portable + +commit eec840673bce3f69ad269672fba7ed8ff05f154f +Author: Damien Miller +Date: Wed Aug 21 02:39:39 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/06 23:05:01 + [sftp.1] + document top-level -a option (the -a option to 'get' was already + documented) + +commit 02e878070d0eddad4e11f2c82644b275418eb112 +Author: Damien Miller +Date: Wed Aug 21 02:38:51 2013 +1000 + + - djm@cvs.openbsd.org 2013/08/06 23:03:49 + [sftp.c] + fix some whitespace at EOL + make list of commands an enum rather than a long list of defines + add -a to usage() + +commit acd2060f750c16d48b87b92a10b5a833227baf9d +Author: Darren Tucker +Date: Thu Aug 8 17:02:12 2013 +1000 + + - (dtucker) [regress/Makefile regress/test-exec.sh] Roll back the -nt + removal. The "make clean" removes modpipe which is built by the top-level + directory before running the tests. Spotted by tim@ + +commit 9542de4547beebf707f3640082d471f1a85534c9 +Author: Darren Tucker +Date: Thu Aug 8 12:50:06 2013 +1000 + + - (dtucker) [misc.c] Remove define added for fallback testing that was + mistakenly included in the previous commit. + +commit 94396b7f06f512a0acb230640d7f703fb802a9ee +Author: Darren Tucker +Date: Thu Aug 8 11:52:37 2013 +1000 + + - (dtucker) [misc.c] Fall back to time(2) at runtime if clock_gettime( + CLOCK_MONOTONIC...) fails. Some older versions of RHEL have the + CLOCK_MONOTONIC define but don't actually support it. Found and tested + by Kevin Brott, ok djm. + +commit a5a3cbfa0fb8ef011d3e7b38910a13f6ebbb8818 +Author: Darren Tucker +Date: Thu Aug 8 10:58:49 2013 +1000 + + - (dtucker) [regress/Makefile regress/test-exec.sh] Don't try to use test -nt + since some platforms (eg really old FreeBSD) don't have it. Instead, + run "make clean" before a complete regress run. ok djm. + +commit f3ab2c5f9cf4aed44971eded3ac9eeb1344b2be5 +Author: Darren Tucker +Date: Sun Aug 4 21:48:41 2013 +1000 + + - (dtucker) [auth-krb5.c configure.ac openbsd-compat/bsd-misc.h] Add support + for building with older Heimdal versions. ok djm. + +commit ab3575c055adfbce70fa7405345cf0f80b07c827 +Author: Damien Miller +Date: Thu Aug 1 14:34:16 2013 +1000 + + - (djm) [sshlogin.h] Fix prototype merge botch from 2006; bz#2134 + +commit c192a4c4f6da907dc0e67a3ca61d806f9a92c931 +Author: Damien Miller +Date: Thu Aug 1 14:29:20 2013 +1000 + + - (djm) [channels.c channels.h] bz#2135: On Solaris, isatty() on a non- + blocking connecting socket will clear any stored errno that might + otherwise have been retrievable via getsockopt(). A hack to limit writes + to TTYs on AIX was triggering this. Since only AIX needs the hack, wrap + it in an #ifdef. Diagnosis and patch from Ivo Raisr. + +commit 81f7cf1ec5bc2fd202eda05abc2e5361c54633c5 +Author: Tim Rice +Date: Thu Jul 25 18:41:40 2013 -0700 + + more correct comment for last commit + +commit 0553ad76ffdff35fb31b9e6df935a71a1cc6daa2 +Author: Tim Rice +Date: Thu Jul 25 16:03:16 2013 -0700 + + - (tim) [regress/forwarding.sh] Fix for building outside read only source tree. + +commit ed899eb597a8901ff7322cba809660515ec0d601 +Author: Tim Rice +Date: Thu Jul 25 15:40:00 2013 -0700 + + - (tim) [sftp-client.c] Use of a gcc extension trips up native compilers on + Solaris and UnixWare. Feedback and OK djm@ + +commit e9e936d33b4b1d77ffbaace9438cb2f1469c1dc7 +Author: Damien Miller +Date: Thu Jul 25 12:34:00 2013 +1000 + + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update version numbers + +commit d1e26cf391de31128b4edde118bff5fed98a90ea +Author: Damien Miller +Date: Thu Jul 25 12:11:18 2013 +1000 + + - djm@cvs.openbsd.org 2013/06/21 02:26:26 + [regress/sftp-cmds.sh regress/test-exec.sh] + unbreak sftp-cmds for renamed test data (s/ls/data/) + +commit 78d47b7c5b182e44552913de2b4b7e0363c8e3cc +Author: Damien Miller +Date: Thu Jul 25 12:08:46 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/10 21:56:43 + [regress/forwarding.sh] + Add test for forward config parsing + +commit fea440639e04cea9f2605375a41d654390369402 +Author: Damien Miller +Date: Thu Jul 25 12:08:07 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/30 20:12:32 + [regress/test-exec.sh] + use ssh and sshd as testdata since it needs to be >256k for the rekey test + +commit 53435b2d8773a5d7c78359e9f7bf9df2d93b9ef5 +Author: Damien Miller +Date: Thu Jul 25 11:57:15 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/25 00:57:37 + [version.h] + openssh-6.3 for release + +commit 0d032419ee6e1968fc1cb187af63bf3b77b506ea +Author: Damien Miller +Date: Thu Jul 25 11:56:52 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/25 00:56:52 + [sftp-client.c sftp-client.h sftp.1 sftp.c] + sftp support for resuming partial downloads; patch mostly by Loganaden + Velvindron/AfriNIC with some tweaks by me; feedback and ok dtucker@ + +commit 98e27dcf581647b5bbe9780e8f59685d942d8ea3 +Author: Damien Miller +Date: Thu Jul 25 11:55:52 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/25 00:29:10 + [ssh.c] + daemonise backgrounded (ControlPersist'ed) multiplexing master to ensure + it is fully detached from its controlling terminal. based on debugging + +commit 94c9cd34d1590ea1d4bf76919a15b5688fa90ed1 +Author: Damien Miller +Date: Thu Jul 25 11:55:39 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/22 12:20:02 + [umac.h] + oops, forgot to commit corresponding header change; + spotted by jsg and jasper + +commit c331dbd22297ab9bf351abee659893d139c9f28a +Author: Damien Miller +Date: Thu Jul 25 11:55:20 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/22 05:00:17 + [umac.c] + make MAC key, data to be hashed and nonce for final hash const; + checked with -Wcast-qual + +commit c8669a8cd24952b3f16a44eac63d2b6ce8a6343a +Author: Damien Miller +Date: Thu Jul 25 11:52:48 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/20 22:20:42 + [krl.c] + fix verification error in (as-yet usused) KRL signature checking path + +commit 63ddc899d28cf60045b560891894b9fbf6f822e9 +Author: Damien Miller +Date: Sat Jul 20 13:35:45 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/20 01:55:13 + [auth-krb5.c gss-serv-krb5.c gss-serv.c] + fix kerberos/GSSAPI deprecation warnings and linking; "looks okay" millert@ + +commit 1f0e86f23fcebb026371c0888402a981df2a61c4 +Author: Damien Miller +Date: Sat Jul 20 13:22:49 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/20 01:50:20 + [ssh-agent.c] + call cleanup_handler on SIGINT when in debug mode to ensure sockets + are cleaned up on manual exit; bz#2120 + +commit 3009d3cbb89316b1294fb5cedb54770b5d114d04 +Author: Damien Miller +Date: Sat Jul 20 13:22:31 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/20 01:44:37 + [ssh-keygen.c ssh.c] + More useful error message on missing current user in /etc/passwd + +commit 32ecfa0f7920db31471ca8c1f4adc20ae38ed9d6 +Author: Damien Miller +Date: Sat Jul 20 13:22:13 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/20 01:43:46 + [umac.c] + use a union to ensure correct alignment; ok deraadt + +commit 85b45e09188e7a7fc8f0a900a4c6a0f04a5720a7 +Author: Damien Miller +Date: Sat Jul 20 13:21:52 2013 +1000 + + - markus@cvs.openbsd.org 2013/07/19 07:37:48 + [auth.h kex.h kexdhs.c kexecdhs.c kexgexs.c monitor.c servconf.c] + [servconf.h session.c sshd.c sshd_config.5] + add ssh-agent(1) support to sshd(8); allows encrypted hostkeys, + or hostkeys on smartcards; most of the work by Zev Weiss; bz #1974 + ok djm@ + +commit d93340cbb6bc0fc0dbd4427e0cec6d994a494dd9 +Author: Damien Miller +Date: Thu Jul 18 16:14:34 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/18 01:12:26 + [ssh.1] + be more exact wrt perms for ~/.ssh/config; bz#2078 + +commit bf836e535dc3a8050c1756423539bac127ee5098 +Author: Damien Miller +Date: Thu Jul 18 16:14:13 2013 +1000 + + - schwarze@cvs.openbsd.org 2013/07/16 00:07:52 + [scp.1 sftp-server.8 ssh-keyscan.1 ssh-keysign.8 ssh-pkcs11-helper.8] + use .Mt for email addresses; from Jan Stary ; ok jmc@ + +commit 649fe025a409d0ce88c60a068f3f211193c35873 +Author: Damien Miller +Date: Thu Jul 18 16:13:55 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/12 05:48:55 + [ssh.c] + set TCP nodelay for connections started with -N; bz#2124 ok dtucker@ + +commit 5bb8833e809d827496dffca0dc2c223052c93931 +Author: Damien Miller +Date: Thu Jul 18 16:13:37 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/12 05:42:03 + [ssh-keygen.c] + do_print_resource_record() can never be called with a NULL filename, so + don't attempt (and bungle) asking for one if it has not been specified + bz#2127 ok dtucker@ + +commit 7313fc9222785d0c54a7ffcaf2067f4db02c8d72 +Author: Damien Miller +Date: Thu Jul 18 16:13:19 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/12 00:43:50 + [misc.c] + in ssh_gai_strerror() don't fallback to strerror for EAI_SYSTEM when + errno == 0. Avoids confusing error message in some broken resolver + cases. bz#2122 patch from plautrba AT redhat.com; ok dtucker + +commit 746d1a6c524d2e90ebe98cc29e42573a3e1c3c1b +Author: Damien Miller +Date: Thu Jul 18 16:13:02 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/12 00:20:00 + [sftp.c ssh-keygen.c ssh-pkcs11.c] + fix pointer-signedness warnings from clang/llvm-3.3; "seems nice" deraadt@ + +commit ce98654674648fb7d58f73edf6aa398656a2dba4 +Author: Damien Miller +Date: Thu Jul 18 16:12:44 2013 +1000 + + - djm@cvs.openbsd.org 2013/07/12 00:19:59 + [auth-options.c auth-rsa.c bufaux.c buffer.h channels.c hostfile.c] + [hostfile.h mux.c packet.c packet.h roaming_common.c serverloop.c] + fix pointer-signedness warnings from clang/llvm-3.3; "seems nice" deraadt@ + +commit 0d02c3e10e1ed16d6396748375a133d348127a2a +Author: Damien Miller +Date: Thu Jul 18 16:12:06 2013 +1000 + + - markus@cvs.openbsd.org 2013/07/02 12:31:43 + [dh.c] + remove extra whitespace + +commit fecfd118d6c90df4fcd3cec7b14e4d3ce69a41d5 +Author: Damien Miller +Date: Thu Jul 18 16:11:50 2013 +1000 + + - jmc@cvs.openbsd.org 2013/06/27 14:05:37 + [ssh-keygen.1 ssh.1 ssh_config.5 sshd.8 sshd_config.5] + do not use Sx for sections outwith the man page - ingo informs me that + stuff like html will render with broken links; + + issue reported by Eric S. Raymond, via djm + +commit bc35d92e78fd53c3f32cbdbdf89d8b1919788c50 +Author: Damien Miller +Date: Thu Jul 18 16:11:25 2013 +1000 + + - djm@cvs.openbsd.org 2013/06/22 06:31:57 + [scp.c] + improved time_t overflow check suggested by guenther@ + +commit 8158441d01ab84f33a7e70e27f87c02cbf67e709 +Author: Damien Miller +Date: Thu Jul 18 16:11:07 2013 +1000 + + - djm@cvs.openbsd.org 2013/06/21 05:43:10 + [scp.c] + make this -Wsign-compare clean after time_t conversion + +commit bbeb1dac550bad8e6aff9bd27113c6bd5ebb7413 +Author: Damien Miller +Date: Thu Jul 18 16:10:49 2013 +1000 + + - djm@cvs.openbsd.org 2013/06/21 05:42:32 + [dh.c] + sprinkle in some error() to explain moduli(5) parse failures + +commit 7f2b438ca0b7c3b9684a03d7bf3eaf379da16de9 +Author: Damien Miller +Date: Thu Jul 18 16:10:29 2013 +1000 + + - djm@cvs.openbsd.org 2013/06/21 00:37:49 + [ssh_config.5] + explicitly mention that IdentitiesOnly can be used with IdentityFile + to control which keys are offered from an agent. + +commit 20bdcd72365e8b3d51261993928cc47c5f0d7c8a +Author: Damien Miller +Date: Thu Jul 18 16:10:09 2013 +1000 + + - djm@cvs.openbsd.org 2013/06/21 00:34:49 + [auth-rsa.c auth.h auth2-hostbased.c auth2-pubkey.c monitor.c] + for hostbased authentication, print the client host and user on + the auth success/failure line; bz#2064, ok dtucker@ + +commit 3071070b39e6d1722151c754cdc2b26640eaf45e +Author: Damien Miller +Date: Thu Jul 18 16:09:44 2013 +1000 + + - markus@cvs.openbsd.org 2013/06/20 19:15:06 + [krl.c] + don't leak the rdata blob on errors; ok djm@ + +commit 044bd2a7ddb0b6f6b716c87e57261572e2b89028 +Author: Damien Miller +Date: Thu Jul 18 16:09:25 2013 +1000 + + - guenther@cvs.openbsd.org 2013/06/17 04:48:42 + [scp.c] + Handle time_t values as long long's when formatting them and when + parsing them from remote servers. + Improve error checking in parsing of 'T' lines. + + ok dtucker@ deraadt@ + +commit 9a6615542108118582f64b7161ca0e12176e3712 +Author: Damien Miller +Date: Thu Jul 18 16:09:04 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/10 19:19:44 + [readconf.c] + revert 1.203 while we investigate crashes reported by okan@ + +commit b7482cff46e7e76bfb3cda86c365a08f58d4fca0 +Author: Darren Tucker +Date: Tue Jul 2 20:06:46 2013 +1000 + + - (dtucker) [contrib/cygwin/README contrib/cygwin/ssh-host-config + contrib/cygwin/ssh-user-config] Modernizes and improve readability of + the Cygwin README file (which hasn't been updated for ages), drop + unsupported OSes from the ssh-host-config help text, and drop an + unneeded option from ssh-user-config. Patch from vinschen at redhat com. + +commit b8ae92d08b91beaef34232c6ef34b9941473fdd6 +Author: Darren Tucker +Date: Tue Jun 11 12:10:02 2013 +1000 + + - (dtucker) [myproposal.h] Make the conditional algorithm support consistent + and add some comments so it's clear what goes where. + +commit 97b62f41adcb0dcbeff142d0540793a7ea17c910 +Author: Darren Tucker +Date: Tue Jun 11 11:47:24 2013 +1000 + + - (dtucker) [myproposal.h] Do not advertise AES GSM ciphers if we don't have + the required OpenSSL support. Patch from naddy at freebsd. + +commit 6d8bd57448b45b42809da32857d7804444349ee7 +Author: Darren Tucker +Date: Tue Jun 11 11:26:10 2013 +1000 + + - (dtucker) [Makefile.in configure.ac fixalgorithms] Remove unsupported + algorithms (Ciphers, MACs and HostKeyAlgorithms) from man pages. + +commit 36187093ea0b2d2240c043417b8949611687e105 +Author: Damien Miller +Date: Mon Jun 10 13:07:11 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/07 15:37:52 + [channels.c channels.h clientloop.c] + Add an "ABANDONED" channel state and use for mux sessions that are + disconnected via the ~. escape sequence. Channels in this state will + be able to close if the server responds, but do not count as active channels. + This means that if you ~. all of the mux clients when using ControlPersist + on a broken network, the backgrounded mux master will exit when the + Control Persist time expires rather than hanging around indefinitely. + bz#1917, also reported and tested by tedu@. ok djm@ markus@. + +commit ae133d4b31af05bb232d797419f498f3ae7e9f2d +Author: Darren Tucker +Date: Thu Jun 6 08:30:20 2013 +1000 + + - (dtucker) [configure.ac sftp.c openbsd-compat/openbsd-compat.h] Cater for + platforms that don't have multibyte character support (specifically, + mblen). + +commit 408eaf3ab716096f8faf30f091bd54a2c7a17a09 +Author: Darren Tucker +Date: Thu Jun 6 08:22:46 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/05 22:00:28 + [readconf.c] + plug another memleak. bz#1967, from Zhenbo Xu, detected by Melton, ok djm + +commit e52a260f16888ca75390f97de4606943e61785e8 +Author: Darren Tucker +Date: Thu Jun 6 08:22:05 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/05 12:52:38 + [sshconnect2.c] + Fix memory leaks found by Zhenbo Xu and the Melton tool. bz#1967, ok djm + +commit 0cca17fa1819d3a0ba06a6db41ab3eaa8d769587 +Author: Darren Tucker +Date: Thu Jun 6 08:21:14 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/05 02:27:50 + [sshd.c] + When running sshd -D, close stderr unless we have explicitly requesting + logging to stderr. From james.hunt at ubuntu.com via bz#1976, djm's patch + so, err, ok dtucker. + +commit 746e9067bd9b3501876e1c86f38f3c510a12f895 +Author: Darren Tucker +Date: Thu Jun 6 08:20:13 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/05 02:07:29 + [mux.c] + fix leaks in mux error paths, from Zhenbo Xu, found by Melton. bz#1967, + ok djm + +commit ea64721275a81c4788af36294d94bf4f74012e06 +Author: Darren Tucker +Date: Thu Jun 6 08:19:09 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/04 20:42:36 + [sftp.c] + Make sftp's libedit interface marginally multibyte aware by building up + the quoted string by character instead of by byte. Prevents failures + when linked against a libedit built with wide character support (bz#1990). + "looks ok" djm + +commit 194454d7a8f8cb8ac55f2b9d0199ef9445788bee +Author: Darren Tucker +Date: Thu Jun 6 08:16:04 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/04 19:12:23 + [scp.c] + use MAXPATHLEN for buffer size instead of fixed value. ok markus + +commit 4ac66af091cf6db5a42c18e43738ca9c41e338e5 +Author: Darren Tucker +Date: Thu Jun 6 08:12:37 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/03 00:03:18 + [mac.c] + force the MAC output to be 64-bit aligned so umac won't see unaligned + accesses on strict-alignment architectures. bz#2101, patch from + tomas.kuthan at oracle.com, ok djm@ + +commit ea8342c248ad6c0a4fe1a70de133f954973bd2b2 +Author: Darren Tucker +Date: Thu Jun 6 08:11:40 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/02 23:36:29 + [clientloop.h clientloop.c mux.c] + No need for the mux cleanup callback to be visible so restore it to static + and call it through the detach_user function pointer. ok djm@ + +commit 5d12b8f05d79ba89d0807910a664fa80f6f3bf8c +Author: Darren Tucker +Date: Thu Jun 6 08:09:10 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/02 21:01:51 + [channels.h] + typo in comment + +commit dc62edbf121c41e8b5270904091039450206d98a +Author: Darren Tucker +Date: Thu Jun 6 05:12:35 2013 +1000 + + - (dtucker) [Makefile.in] append $CFLAGS to compiler options when building + modpipe in case there's anything in there we need. + +commit 2a22873cd869679415104bc9f6bb154811ee604c +Author: Darren Tucker +Date: Thu Jun 6 01:59:13 2013 +1000 + + - (dtucker) [regress/forwarding.sh] For (as yet unknown) reason, the + forwarding test is extremely slow copying data on some machines so switch + back to copying the much smaller ls binary until we can figure out why + this is. + +commit b4e00949f01176cd4fae3e0cef5ffa8dea379042 +Author: Darren Tucker +Date: Wed Jun 5 22:48:44 2013 +1000 + + - (dtucker) [contrib/ssh-copy-id] bz#2117: Use portable operator in test. + Patch from cjwatson at debian. + +commit 2ea9eb77a7fcab3190564ef5a6a5377a600aa391 +Author: Darren Tucker +Date: Wed Jun 5 15:04:00 2013 +1000 + + - (dtucker) Enable sha256 kex methods based on the presence of the necessary + functions, not from the openssl version. + +commit 16cac190ebb9b5612cccea63a7c22ac33bc9a07a +Author: Darren Tucker +Date: Tue Jun 4 12:55:24 2013 +1000 + + - (dtucker) [configure.ac] Some other platforms need sys/types.h before + sys/socket.h. + +commit 0b43ffe143a5843703c3755fa040b8684fb04134 +Author: Darren Tucker +Date: Mon Jun 3 09:30:44 2013 +1000 + + - (dtucker) [configure.ac] Some platforms need sys/types.h before sys/un.h. + +commit 3f3064c82238c486706471d300217d73dd0f125e +Author: Tim Rice +Date: Sun Jun 2 15:13:09 2013 -0700 + + - (tim) [regress/sftp-chroot.sh] skip if no sudo. ok dtucker + +commit 01ec0af301f60fefdd0079647f13ef9abadd2db5 +Author: Tim Rice +Date: Sun Jun 2 14:31:27 2013 -0700 + + - (tim) [aclocal.m4] Enhance OSSH_CHECK_CFLAG_COMPILE to check stderr. + feedback and ok dtucker + +commit 5ab9b63468100757479534edeb53f788a61fe08b +Author: Tim Rice +Date: Sun Jun 2 14:05:48 2013 -0700 + + - (tim) [configure.ac regress/Makefile] With rev 1.47 of test-exec.sh we + need a shell that can handle "[ file1 -nt file2 ]". Rather than keep + dealing with shell portability issues in regression tests, we let + configure find us a capable shell on those platforms with an old /bin/sh. + +commit 898ac935e56a7ac5d8b686c590fdb8b7aca27e59 +Author: Darren Tucker +Date: Mon Jun 3 02:03:25 2013 +1000 + + - (dtucker) [configure.ac] bz#2111: don't try to use lastlog on Android. + Patch from Nathan Osman. + +commit ef4901c3eb98c7ab1342c3cd8f2638da1f4b0678 +Author: Darren Tucker +Date: Mon Jun 3 01:59:13 2013 +1000 + + - (dtucker) [configure.ac] sys/un.h needs sys/socket.h on some platforms + to prevent noise from configure. Patch from Nathan Osman. + +commit 073f795bc1c7728c320e5982c0d417376b0907f5 +Author: Darren Tucker +Date: Sun Jun 2 23:47:11 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/02 13:35:58 + [ssh-agent.c] + Make parent_alive_interval time_t to avoid signed/unsigned comparison + +commit 00e1abb1ebe13ab24e812f68715f46e65e7c5271 +Author: Darren Tucker +Date: Sun Jun 2 23:46:24 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/02 13:33:05 + [progressmeter.c] + Add misc.h for monotime prototype. (id sync only) + +commit 86211d1738695e63b2a68f0c3a4f60e1a9d9bda3 +Author: Tim Rice +Date: Sat Jun 1 18:38:23 2013 -0700 + + 20130602 + - (tim) [Makefile.in] Make Solaris, UnixWare, & OpenServer linkers happy + linking regress/modpipe. + +commit e9887d1c37940b9d6c72d55cfad7a40de4c6e28d +Author: Darren Tucker +Date: Sun Jun 2 09:17:09 2013 +1000 + + - (dtucker) [sandbox-seccomp-filter.c] Allow clock_gettimeofday. + +commit 65cf74079a2d563c4ede649116a13ca78c8cc2a4 +Author: Darren Tucker +Date: Sun Jun 2 09:11:19 2013 +1000 + + fix typo + +commit c9a1991b95a4c9f04f9dcef299a8110d2ec80d3e +Author: Darren Tucker +Date: Sun Jun 2 08:37:05 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/01 22:34:50 + [sftp-client.c] + Update progressmeter when data is acked, not when it's sent. bz#2108, from + Debian via Colin Watson, ok djm@ + +commit a710891659202c82545e84725d4e5cd77aef567c +Author: Darren Tucker +Date: Sun Jun 2 08:18:31 2013 +1000 + + - (dtucker) [configure.ac misc.c] Look for clock_gettime in librt and fall + back to time(NULL) if we can't find it anywhere. + +commit f60845fde29cead9d75e812db1c04916b4c58ffd +Author: Darren Tucker +Date: Sun Jun 2 08:07:31 2013 +1000 + + - (dtucker) [M auth-chall.c auth-krb5.c auth-pam.c cipher-aes.c cipher-ctr.c + groupaccess.c loginrec.c monitor.c monitor_wrap.c session.c sshd.c + sshlogin.c uidswap.c openbsd-compat/bsd-cygwin_util.c + openbsd-compat/getrrsetbyname-ldns.c openbsd-compat/port-aix.c + openbsd-compat/port-linux.c] Replace portable-specific instances of xfree + with the equivalent calls to free. + +commit 12f6533215c0a36ab29d11ff52a853fce45573b4 +Author: Darren Tucker +Date: Sun Jun 2 08:01:24 2013 +1000 + + Remove stray '+' accidentally introduced in sync + +commit 3750fce6ac6b287f62584ac55a4406df95c71b92 +Author: Darren Tucker +Date: Sun Jun 2 07:52:21 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/01 20:59:25 + [scp.c sftp-client.c] + Replace S_IWRITE, which isn't standardized, with S_IWUSR, which is. Patch + from Nathan Osman via bz#2113. ok deraadt. + + (note: corrected bug number from 2085) + +commit b759c9c2efebe7b416ab81093ca8eb17836b6933 +Author: Darren Tucker +Date: Sun Jun 2 07:46:16 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/06/01 13:15:52 + [ssh-agent.c clientloop.c misc.h packet.c progressmeter.c misc.c + channels.c sandbox-systrace.c] + Use clock_gettime(CLOCK_MONOTONIC ...) for ssh timers so that things like + keepalives and rekeying will work properly over clock steps. Suggested by + markus@, "looks good" djm@. + +commit 55119253c64808b0d3b2ab5d2bc67ee9dac3430b +Author: Darren Tucker +Date: Sun Jun 2 07:43:59 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/31 12:28:10 + [ssh-agent.c] + Use time_t where appropriate. ok djm + +commit 0acca3797d53d958d240c69a5f222f2aa8444858 +Author: Darren Tucker +Date: Sun Jun 2 07:41:51 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/19 02:42:42 + [auth.h auth.c key.c monitor.c auth-rsa.c auth2.c auth1.c key.h] + Standardise logging of supplemental information during userauth. Keys + and ruser is now logged in the auth success/failure message alongside + the local username, remote host/port and protocol in use. Certificates + contents and CA are logged too. + Pushing all logging onto a single line simplifies log analysis as it is + no longer necessary to relate information scattered across multiple log + entries. "I like it" markus@ + +commit 74836ae0fabcc1a76b9d9eacd1629c88a054b2d0 +Author: Darren Tucker +Date: Sun Jun 2 07:32:00 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/19 02:38:28 + [auth2-pubkey.c] + fix failure to recognise cert-authority keys if a key of a different type + appeared in authorized_keys before it; ok markus@ + +commit a627d42e51ffa71e014d7b2d2c07118122fd3ec3 +Author: Darren Tucker +Date: Sun Jun 2 07:31:17 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/17 00:13:13 + [xmalloc.h cipher.c sftp-glob.c ssh-keyscan.c ssh.c sftp-common.c + ssh-ecdsa.c auth2-chall.c compat.c readconf.c kexgexs.c monitor.c + gss-genr.c cipher-3des1.c kex.c monitor_wrap.c ssh-pkcs11-client.c + auth-options.c rsa.c auth2-pubkey.c sftp.c hostfile.c auth2.c + servconf.c auth.c authfile.c xmalloc.c uuencode.c sftp-client.c + auth2-gss.c sftp-server.c bufaux.c mac.c session.c jpake.c kexgexc.c + sshconnect.c auth-chall.c auth2-passwd.c sshconnect1.c buffer.c + kexecdhs.c kexdhs.c ssh-rsa.c auth1.c ssh-pkcs11.c auth2-kbdint.c + kexdhc.c sshd.c umac.c ssh-dss.c auth2-jpake.c bufbn.c clientloop.c + monitor_mm.c scp.c roaming_client.c serverloop.c key.c auth-rsa.c + ssh-pkcs11-helper.c ssh-keysign.c ssh-keygen.c match.c channels.c + sshconnect2.c addrmatch.c mux.c canohost.c kexecdhc.c schnorr.c + ssh-add.c misc.c auth2-hostbased.c ssh-agent.c bufec.c groupaccess.c + dns.c packet.c readpass.c authfd.c moduli.c] + bye, bye xfree(); ok markus@ + +commit c7aad0058c957afeb26a3f703e8cb0eddeb62365 +Author: Darren Tucker +Date: Sun Jun 2 07:18:47 2013 +1000 + + - (dtucker) [configure.ac defines.h] Test for fd_mask, howmany and NFDBITS + rather than trying to enumerate the plaforms that don't have them. + Based on a patch from Nathan Osman, with help from tim@. + +commit c0c3373216801797053e123b5f62d35bf41b3611 +Author: Darren Tucker +Date: Sun Jun 2 06:28:03 2013 +1000 + + - (dtucker) [configure.ac openbsd-compat/xcrypt.c] bz#2112: fall back to + using openssl's DES_crpyt function on platorms that don't have a native + one, eg Android. Based on a patch from Nathan Osman. + +commit efdf5342143a887013a1daae583167dadf6752a7 +Author: Darren Tucker +Date: Thu May 30 08:29:08 2013 +1000 + + - (dtucker) [configure.ac openbsd-compat/bsd-misc.h] bz#2087: Add a null + implementation of endgrent for platforms that don't have it (eg Android). + Loosely based on a patch from Nathan Osman, ok djm + +commit 9b42d327380e5cd04efde6fb70e1535fecedf0d7 +Author: Darren Tucker +Date: Fri May 17 20:48:59 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:35:43 + [regress/scp.sh] + use a file extention that's not special on some platforms. from portable + (id sync only) + +commit 0a404b0ed79ba45ccaf7ed5528a8f5004c3698cb +Author: Darren Tucker +Date: Fri May 17 20:47:29 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:34:30 + [regress/portnum.sh] + use a more portable negated if structure. from portable (id sync only) + +commit 62ee222e6f3f5ee288434f58b5136ae3d56f5164 +Author: Darren Tucker +Date: Fri May 17 20:46:00 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:33:09 + [regress/agent-getpeereid.sh] + don't redirect stdout from sudo. from portable (id sync only) + +commit 00478d30cb4bcc18dc1ced8144d16b03cdf790f6 +Author: Darren Tucker +Date: Fri May 17 20:45:06 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:30:07 + [regress/test-exec.sh] + wait a bit longer for startup and use case for absolute path. + from portable (id sync only) + +commit 98989eb95eef0aefed7e9fb4e65c2f625be946f6 +Author: Darren Tucker +Date: Fri May 17 20:44:09 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:28:11 + [regress/sftp.sh] + only compare copied data if sftp succeeds. from portable (id sync only) + +commit 438f60eb9a5f7cd40bb242cfec865e4fde71b07c +Author: Darren Tucker +Date: Fri May 17 20:43:13 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:26:26 + [regress/sftp-badcmds.sh] + remove unused BATCH variable. (id sync only) + +commit 1466bd25a8d1ff7ae455a795d2d7d52dc17d2938 +Author: Darren Tucker +Date: Fri May 17 20:42:05 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:24:48 + [localcommand.sh] + use backticks for portability. (id sync only) + +commit 05b5e518c9969d63471f2ccfd85b1de6e724d30b +Author: Darren Tucker +Date: Fri May 17 20:41:07 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:23:52 + [regress/login-timeout.sh regress/reexec.sh regress/test-exec.sh] + Use SUDO when cat'ing pid files and running the sshd log wrapper so that + it works with a restrictive umask and the pid files are not world readable. + Changes from -portable. (id sync only) + +commit dd669173f93ea8c8397e0af758eaf13ab4f1c591 +Author: Darren Tucker +Date: Fri May 17 20:39:57 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 10:16:26 + [regress/try-ciphers.sh] + use expr for math to keep diffs vs portable down + (id sync only) + +commit 044f32f4c6fd342f9f5949bb0ca77624c0db4494 +Author: Darren Tucker +Date: Fri May 17 20:12:57 2013 +1000 + + - (dtucker) [regress/cfgmatch.sh] Remove unneeded sleep renderd obsolete by + rev 1.6 which calls wait. + +commit 9cc8ff7b63f175661c8807006f6d2649d56ac402 +Author: Darren Tucker +Date: Fri May 17 20:01:52 2013 +1000 + + - (dtucker) [regress/runtests.sh] Remove obsolete test driver script. + +commit f8d5b3451726530a864b172c556c311370c244e1 +Author: Darren Tucker +Date: Fri May 17 19:53:25 2013 +1000 + + - (dtucker) [regress/stderr-after-eof.sh regress/test-exec.sh] Move the md5 + helper function to the portable part of test-exec.sh. + +commit 6f66981ed3c6bb83b937959f329323975e356c33 +Author: Darren Tucker +Date: Fri May 17 19:28:51 2013 +1000 + + - (dtucker) [regress/test-exec.sh] Move the portable-specific functions + together and add a couple of missing lines from openbsd. + +commit 5f1a89a3b67264f4aa83e057cd4f74fd60b9ffa4 +Author: Darren Tucker +Date: Fri May 17 19:17:58 2013 +1000 + + - (dtucker) [regress/integrity.sh regress/krl.sh regress/test-exec.sh] + Move the jot helper function to portable-specific part of test-exec.sh. + +commit 96457a54d05dea81f34ecb4e059d2f8b98382b85 +Author: Darren Tucker +Date: Fri May 17 19:03:38 2013 +1000 + + - (dtucker) [regress/agent-getpeereid.sh] Resync spaces with openbsd. + +commit 7f193236594e8328ad133ea05eded31f837b45b5 +Author: Darren Tucker +Date: Fri May 17 19:02:28 2013 +1000 + + - (dtucker) [regress/cfgmatch.sh] Resync config file setup with openbsd. + +commit 8654dd2d737800d09e7730b3dfc2a54411f4cf90 +Author: Darren Tucker +Date: Fri May 17 16:03:48 2013 +1000 + + - (dtucker) [openbsd-compat/getopt.h] Remove unneeded bits. + +commit 59d928d3b47e8298f4a8b4b3fb37fb8c8ce1b098 +Author: Darren Tucker +Date: Fri May 17 15:32:29 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 04:29:14 + [regress/sftp.sh regress/putty-ciphers.sh regress/cipher-speed.sh + regress/test-exec.sh regress/sftp-batch.sh regress/dynamic-forward.sh + regress/putty-transfer.sh regress/conch-ciphers.sh regress/sftp-cmds.sh + regress/scp.sh regress/ssh-com-sftp.sh regress/rekey.sh + regress/putty-kex.sh regress/stderr-data.sh regress/stderr-after-eof.sh + regress/sftp-badcmds.sh regress/reexec.sh regress/ssh-com-client.sh + regress/sftp-chroot.sh regress/forwarding.sh regress/transfer.sh + regress/multiplex.sh] + Move the setting of DATA and COPY into test-exec.sh + +commit 34035be27b7ddd84706fe95c39d37cba7d5c9572 +Author: Darren Tucker +Date: Fri May 17 14:47:51 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 01:32:11 + [regress/integrity.sh] + don't print output from ssh before getting it (it's available in ssh.log) + +commit b8b96b0aa634d440feba4331c80ae4de9dda2081 +Author: Darren Tucker +Date: Fri May 17 14:46:20 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 01:16:09 + [regress/agent-timeout.sh] + Pull back some portability changes from -portable: + - TIMEOUT is a read-only variable in some shells + - not all greps have -q so redirect to /dev/null instead. + (ID sync only) + +commit a40d97ff46831c9081a6a4472036689360847fb1 +Author: Darren Tucker +Date: Fri May 17 14:44:53 2013 +1000 + + sync missing ID + +commit 56347efe796a0506e846621ae65562b978e45f1d +Author: Darren Tucker +Date: Fri May 17 13:28:36 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/17 00:37:40 + [regress/agent.sh regress/keytype.sh regress/cfgmatch.sh + regress/forcecommand.sh regress/proto-version.sh regress/test-exec.sh + regress/cipher-speed.sh regress/cert-hostkey.sh regress/cert-userkey.sh + regress/ssh-com.sh] + replace 'echo -n' with 'printf' since it's more portable + also remove "echon" hack. + +commit 91af05c5167fe0aa5bd41d2e4a83757d9f627c18 +Author: Darren Tucker +Date: Fri May 17 13:16:59 2013 +1000 + + - (dtucker) [regress/integrity.sh]. Force fixed Diffie-Hellman key exchange + methods. When the openssl version doesn't support ECDH then next one on + the list is DH group exchange, but that causes a bit more traffic which can + mean that the tests flip bits in the initial exchange rather than the MACed + traffic and we get different errors to what the tests look for. + +commit 6e1e60c3c2e16c32bb7ca0876caaa6182a4e4b2c +Author: Darren Tucker +Date: Fri May 17 11:23:41 2013 +1000 + + - (dtucker) [regress/bsd.regress.mk] Remove unused file. We've never used it + in portable and it's long gone in openbsd. + +commit 982b0cbc4c2b5ea14725f4b339393cdf343dd0fe +Author: Darren Tucker +Date: Fri May 17 09:45:12 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 05:48:31 + [regress/rekey.sh] + add tests for RekeyLimit parsing + +commit 14490fe7b0f45b1b19f8a3dc10eb3d214f27f5bd +Author: Darren Tucker +Date: Fri May 17 09:44:20 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 04:26:10 + [regress/rekey.sh] + add server-side rekey test + +commit c31c8729c15f83fba14ef9da0d66bda6215ff69a +Author: Darren Tucker +Date: Fri May 17 09:43:33 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 03:33:30 + [regress/rekey.sh] + test rekeying when there's no data being transferred + +commit a8a62fcc46c19997797846197a6256ed9a777a47 +Author: Darren Tucker +Date: Fri May 17 09:42:34 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 02:10:35 + [rekey.sh] + Add test for time-based rekeying + +commit 5e95173715d516e6014485e2b6def1fb3db84036 +Author: Darren Tucker +Date: Fri May 17 09:41:33 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/10 03:46:14 + [modpipe.c] + sync some portability changes from portable OpenSSH (id sync only) + +commit a4df65b9fc68a555a7d8781700475fb03ed6e694 +Author: Darren Tucker +Date: Fri May 17 09:37:31 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/22 07:28:53 + [multiplex.sh] + Add tests for -Oforward and -Ocancel for local and remote forwards + +commit 40aaff7e4bcb05b05e3d24938b6d34885be817da +Author: Darren Tucker +Date: Fri May 17 09:36:20 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/22 07:23:08 + [multiplex.sh] + Write mux master logs to regress.log instead of ssh.log to keep separate + +commit f3568fc62b73b50a0a3c8447e4a00f4892cab25e +Author: Darren Tucker +Date: Fri May 17 09:35:26 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/18 02:46:12 + [Makefile regress/sftp-chroot.sh] + test sshd ChrootDirectory+internal-sftp; feedback & ok dtucker@ + +commit dfea3bcdd7c980c2335402464b7dd8d8721e426d +Author: Darren Tucker +Date: Fri May 17 09:31:39 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/07 02:16:03 + [regress/Makefile regress/rekey.sh regress/integrity.sh + regress/sshd-log-wrapper.sh regress/forwarding.sh regress/test-exec.sh] + use -E option for ssh and sshd to write debuging logs to ssh{,d}.log and + save the output from any failing tests. If a test fails the debug output + from ssh and sshd for the failing tests (and only the failing tests) should + be available in failed-ssh{,d}.log. + +commit 75129025a2d504b630d1718fef0da002f5662f63 +Author: Darren Tucker +Date: Fri May 17 09:19:10 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/06 06:00:22 + [regress/rekey.sh regress/test-exec.sh regress/integrity.sh + regress/multiplex.sh Makefile regress/cfgmatch.sh] + Split the regress log into 3 parts: the debug output from ssh, the debug + log from sshd and the output from the client command (ssh, scp or sftp). + Somewhat functional now, will become more useful when ssh/sshd -E is added. + +commit 7c8b1e72331293b4707dc6f7f68a69e975a3fa70 +Author: Darren Tucker +Date: Fri May 17 09:10:20 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/03/23 11:09:43 + [test-exec.sh] + Only regenerate host keys if they don't exist or if ssh-keygen has changed + since they were. Reduces test runtime by 5-30% depending on machine + speed. + +commit 712de4d1100963b11bc618472f95ce36bf7e2ae3 +Author: Darren Tucker +Date: Fri May 17 09:07:12 2013 +1000 + + - djm@cvs.openbsd.org 2013/03/07 00:20:34 + [regress/proxy-connect.sh] + repeat test with a style appended to the username + +commit 09c0f0325b2f538de9a1073e03b8ef26dece4c16 +Author: Darren Tucker +Date: Thu May 16 20:48:57 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 10:44:06 + [servconf.c] + remove another now-unused variable + +commit 9113d0c2381202412c912a20c8083ab7d6824ec9 +Author: Darren Tucker +Date: Thu May 16 20:48:14 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 10:43:34 + [servconf.c readconf.c] + remove now-unused variables + +commit e194ba4111ffd47cd1f4c8be1ddc8a4cb673d005 +Author: Darren Tucker +Date: Thu May 16 20:47:31 2013 +1000 + + - (dtucker) [configure.ac readconf.c servconf.c + openbsd-compat/openbsd-compat.h] Add compat bits for scan_scaled. + +commit b7ee8521448100e5b268111ff90feb017e657e44 +Author: Darren Tucker +Date: Thu May 16 20:33:10 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 09:12:31 + [readconf.c servconf.c] + switch RekeyLimit traffic volume parsing to scan_scaled. ok djm@ + +commit dbee308253931f8c1aeebf781d7e7730ff6a0dc1 +Author: Darren Tucker +Date: Thu May 16 20:32:29 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 09:08:41 + [log.c scp.c sshd.c serverloop.c schnorr.c sftp.c] + Fix some "unused result" warnings found via clang and -portable. + ok markus@ + +commit 64d22946d664dad8165f1fae9e78b53831ed728d +Author: Darren Tucker +Date: Thu May 16 20:31:29 2013 +1000 + + - jmc@cvs.openbsd.org 2013/05/16 06:30:06 + [sshd_config.5] + oops! avoid Xr to self; + +commit 63e0df2b936770baadc8844617b99e5174b476d0 +Author: Darren Tucker +Date: Thu May 16 20:30:31 2013 +1000 + + - jmc@cvs.openbsd.org 2013/05/16 06:28:45 + [ssh_config.5] + put IgnoreUnknown in the right place; + +commit 0763698f71efef8b3f8460c5700758359219eb7c +Author: Darren Tucker +Date: Thu May 16 20:30:03 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/16 04:27:50 + [ssh_config.5 readconf.h readconf.c] + add the ability to ignore specific unrecognised ssh_config options; + bz#866; ok markus@ + +commit 5f96f3b4bee11ae2b9b32ff9b881c3693e210f96 +Author: Darren Tucker +Date: Thu May 16 20:29:28 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 04:09:14 + [sshd_config.5 servconf.c servconf.h packet.c serverloop.c monitor.c sshd_config + sshd.c] Add RekeyLimit to sshd with the same syntax as the client allowing + rekeying based on traffic volume or time. ok djm@, help & ok jmc@ for the man + page. + +commit c53c2af173cf67fd1c26f98e7900299b1b65b6ec +Author: Darren Tucker +Date: Thu May 16 20:28:16 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/16 02:00:34 + [ssh_config sshconnect2.c packet.c readconf.h readconf.c clientloop.c + ssh_config.5 packet.h] + Add an optional second argument to RekeyLimit in the client to allow + rekeying based on elapsed time in addition to amount of traffic. + with djm@ jmc@, ok djm + +commit 64c6fceecd27e1739040b42de8f3759454260b39 +Author: Darren Tucker +Date: Thu May 16 20:27:14 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/10 10:13:50 + [ssh-pkcs11-helper.c] + remove unused extern optarg. ok markus@ + +commit caf00109346e4ab6bb495b0e22bc5b1e7ee22f26 +Author: Darren Tucker +Date: Thu May 16 20:26:18 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/10 04:08:01 + [key.c] + memleak in cert_free(), wasn't actually freeing the struct; + bz#2096 from shm AT digitalsun.pl + +commit 7e831edbf7a1b0b9aeeb08328b9fceafaad1bf22 +Author: Darren Tucker +Date: Thu May 16 20:25:40 2013 +1000 + + add missing attribution + +commit 54da6be320495604ddf65d10ac4cc8cf7849c533 +Author: Darren Tucker +Date: Thu May 16 20:25:04 2013 +1000 + + - djm@cvs.openbsd.org 2013/05/10 03:40:07 + [sshconnect2.c] + fix bzero(ptr_to_struct, sizeof(ptr_to_struct)); bz#2100 from + +commit 5d8b702d95c0dfc338726fecfbb709695afd1377 +Author: Darren Tucker +Date: Thu May 16 20:24:23 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/05/06 07:35:12 + [sftp-server.8] + Reference the version of the sftp draft we actually implement. ok djm@ + +commit 026d9db3fbe311b5a7e98d62472cb666aa559648 +Author: Darren Tucker +Date: Thu May 16 20:23:52 2013 +1000 + + - tedu@cvs.openbsd.org 2013/04/24 16:01:46 + [misc.c] + remove extra parens noticed by nicm + +commit 2ca51bf140ef2c2409fd220778529dc17c11d8fa +Author: Darren Tucker +Date: Thu May 16 20:22:46 2013 +1000 + + - tedu@cvs.openbsd.org 2013/04/23 17:49:45 + [misc.c] + use xasprintf instead of a series of strlcats and strdup. ok djm + +commit 6aa3eacc5e5f39702b6dd5b27970d9fd97bc2383 +Author: Damien Miller +Date: Thu May 16 11:10:17 2013 +1000 + + - (djm) [contrib/ssh-copy-id] Fix bug that could cause "rm *" to be + executed if mktemp failed; bz#2105 ok dtucker@ + +commit c54e3e0741a27119b3badd8ff92b1988b7e9bd50 +Author: Darren Tucker +Date: Fri May 10 18:53:14 2013 +1000 + + - (dtucker) [configure.ac] Add -Werror to the -Qunused-arguments test so + we don't get a warning on compilers that *don't* support it. Add + -Wno-unknown-warning-option. Move both to the start of the list for + maximum noise suppression. Tested with gcc 4.6.3, gcc 2.95.4 and clang 2.9. + +commit a75d247a18a5099c60226395354eb252c097ac86 +Author: Darren Tucker +Date: Fri May 10 18:11:55 2013 +1000 + + - (dtucker) [kex.c] Only include sha256 and ECC key exchange methods when the + underlying libraries support them. + +commit 0abfb559e3f79d1f217773510d7626c3722aa3c1 +Author: Darren Tucker +Date: Fri May 10 18:08:49 2013 +1000 + + - (dtucker) [openbsd-compat/getopt.h openbsd-compat/getopt_long.c + openbsd-compat/openbsd-compat.h] pull in getopt.h from openbsd and plumb + in to use it when we're using our own getopt. + +commit ccfdfceacb7e23d1479ed4cc91976c5ac6e23c56 +Author: Darren Tucker +Date: Fri May 10 16:28:55 2013 +1000 + + - (dtucker) [openbsd-compat/Makefile.in openbsd-compat/getopt.c + openbsd-compat/getopt_long.c regress/modpipe.c] Remove getopt.c, add + portability code to getopt_long.c and switch over Makefile and the ugly + hack in modpipe.c. Fixes bz#1448. + +commit 39332020078aa8fd4fc28e00b336438dc64b0f5a +Author: Darren Tucker +Date: Fri May 10 15:38:11 2013 +1000 + + - (dtucker) [openbsd-compat/getopt_long.c] Import from OpenBSD. No + portability changes yet. + +commit 35b2fe99bee4f332d1c1efa49107cdb3c67da07a +Author: Darren Tucker +Date: Fri May 10 15:35:26 2013 +1000 + + - (dtucker) [openbsd-compat/getopt.c] Factor out portibility changes to + getopt.c. Preprocessed source is identical other than line numbers. + +commit abbc7a7c02e45787d023f50a30f62d7a3e14fe9e +Author: Darren Tucker +Date: Fri May 10 13:54:23 2013 +1000 + + - (dtucker) [configure.ac] Enable -Wsizeof-pointer-memaccess if the compiler + supports it. Mentioned by Colin Watson in bz#2100, ok djm. + +commit bc02f163f6e882d390abfb925b47b41e13ae523b +Author: Damien Miller +Date: Tue Apr 23 19:25:49 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/22 01:17:18 + [mux.c] + typo in debug output: evitval->exitval + +commit f8b894e31dc3530c7eb6d0a378848260d54f74c4 +Author: Damien Miller +Date: Tue Apr 23 19:25:29 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/19 12:07:08 + [kex.c] + remove duplicated list entry pointed out by naddy@ + +commit 34bd20a1e53b63ceb01f06c1654d9112e6784b0a +Author: Damien Miller +Date: Tue Apr 23 19:25:00 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/19 11:10:18 + [ssh.c] + add -Q to usage; reminded by jmc@ + +commit ea11119eee3c5e2429b1f5f8688b25b028fa991a +Author: Damien Miller +Date: Tue Apr 23 19:24:32 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/19 01:06:50 + [authfile.c cipher.c cipher.h kex.c kex.h kexecdh.c kexecdhc.c kexecdhs.c] + [key.c key.h mac.c mac.h packet.c ssh.1 ssh.c] + add the ability to query supported ciphers, MACs, key type and KEX + algorithms to ssh. Includes some refactoring of KEX and key type handling + to be table-driven; ok markus@ + +commit a56086b9903b62c1c4fdedf01b68338fe4dc90e4 +Author: Damien Miller +Date: Tue Apr 23 15:24:18 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/19 01:03:01 + [session.c] + reintroduce 1.262 without the connection-killing bug: + fatal() when ChrootDirectory specified by running without root privileges; + ok markus@ + +commit 0d6771b4648889ae5bc4235f9e3fc6cd82b710bd +Author: Damien Miller +Date: Tue Apr 23 15:23:24 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/19 01:01:00 + [ssh-keygen.c] + fix some memory leaks; bz#2088 ok dtucker@ + +commit 467b00c38ba244f9966466e57a89d003f3afb159 +Author: Damien Miller +Date: Tue Apr 23 15:23:07 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/19 01:00:10 + [sshd_config.5] + document the requirment that the AuthorizedKeysCommand be owned by root; + ok dtucker@ markus@ + +commit 9303e6527bb5ca7630c765f28624702c212bfd6c +Author: Damien Miller +Date: Tue Apr 23 15:22:40 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/18 02:16:07 + [sftp.c] + make "sftp -q" do what it says on the sticker: hush everything but errors; + +commit f1a02aea35504e8bef2ed9eef6f9ddeab12bacb3 +Author: Damien Miller +Date: Tue Apr 23 15:22:13 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/17 09:04:09 + [session.c] + revert rev 1.262; it fails because uid is already set here. ok djm@ + +commit d5edefd27a30768cc7a4817302e964b6cb2f9be7 +Author: Damien Miller +Date: Tue Apr 23 15:21:39 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/11 02:27:50 + [packet.c] + quiet disconnect notifications on the server from error() back to logit() + if it is a normal client closure; bz#2057 ok+feedback dtucker@ + +commit 6901032b05291fc5d2bd4067fc47904de3506fda +Author: Damien Miller +Date: Tue Apr 23 15:21:24 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/07 09:40:27 + [sshd.8] + clarify -e text. suggested by & ok jmc@ + +commit 03d4d7e60b16f913c75382e32e136ddfa8d6485f +Author: Damien Miller +Date: Tue Apr 23 15:21:06 2013 +1000 + + - dtucker@cvs.openbsd.org 2013/04/07 02:10:33 + [log.c log.h ssh.1 ssh.c sshd.8 sshd.c] + Add -E option to ssh and sshd to append debugging logs to a specified file + instead of stderr or syslog. ok markus@, man page help jmc@ + +commit 37f1c08473b1ef2a188ee178ce2e11e841f88563 +Author: Damien Miller +Date: Tue Apr 23 15:20:43 2013 +1000 + + - markus@cvs.openbsd.org 2013/04/06 16:07:00 + [channels.c sshd.c] + handle ECONNABORTED for accept(); ok deraadt some time ago... + +commit 172859cff7df9fd8a29a1f0a4de568f644bbda50 +Author: Damien Miller +Date: Tue Apr 23 15:19:27 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/05 00:58:51 + [mux.c] + cleanup mux-created channels that are in SSH_CHANNEL_OPENING state too + (in addition to ones already in OPEN); bz#2079, ok dtucker@ + +commit 9f12b5dcd5f7772e633fb2786c63bfcbea1f1aea +Author: Damien Miller +Date: Tue Apr 23 15:19:11 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/05 00:31:49 + [pathnames.h] + use the existing _PATH_SSH_USER_RC define to construct the other + pathnames; bz#2077, ok dtucker@ (no binary change) + +commit d677ad14ff7efedf21745ee1694058350e758e18 +Author: Damien Miller +Date: Tue Apr 23 15:18:51 2013 +1000 + + - djm@cvs.openbsd.org 2013/04/05 00:14:00 + [auth2-gss.c krl.c sshconnect2.c] + hush some {unused, printf type} warnings + +commit 508b6c3d3b95c8ec078fd4801368597ab29b2db9 +Author: Damien Miller +Date: Tue Apr 23 15:18:28 2013 +1000 + + - djm@cvs.openbsd.org 2013/03/08 06:32:58 + [ssh.c] + allow "ssh -f none ..." ok markus@ + +commit 91a55f28f35431f9000b95815c343b5a18fda712 +Author: Damien Miller +Date: Tue Apr 23 15:18:10 2013 +1000 + + - markus@cvs.openbsd.org 2013/03/07 19:27:25 + [auth.h auth2-chall.c auth2.c monitor.c sshd_config.5] + add submethod support to AuthenticationMethods; ok and freedback djm@ + +commit 4ce189d9108c62090a0dd5dea973d175328440db +Author: Damien Miller +Date: Tue Apr 23 15:17:52 2013 +1000 + + - djm@cvs.openbsd.org 2013/03/07 00:19:59 + [auth2-pubkey.c monitor.c] + reconstruct the original username that was sent by the client, which may + have included a style (e.g. "root:skey") when checking public key + signatures. Fixes public key and hostbased auth when the client specified + a style; ok markus@ + +commit 5cbec4c25954b184e43bf3d3ac09e65eb474f5f9 +Author: Damien Miller +Date: Tue Apr 23 15:17:12 2013 +1000 + + - djm@cvs.openbsd.org 2013/03/06 23:36:53 + [readconf.c] + g/c unused variable (-Wunused) + +commit 998cc56b65682d490c9bbf5977dceb1aa84a0233 +Author: Damien Miller +Date: Tue Apr 23 15:16:43 2013 +1000 + + - djm@cvs.openbsd.org 2013/03/06 23:35:23 + [session.c] + fatal() when ChrootDirectory specified by running without root privileges; + ok markus@ + +commit 62e9c4f9b6027620f9091a2f43328e057bdb33f1 +Author: Damien Miller +Date: Tue Apr 23 15:15:49 2013 +1000 + + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2013/03/05 20:16:09 + [sshconnect2.c] + reset pubkey order on partial success; ok djm@ + +commit 6332da2ae88db623d7da8070dd807efa26d9dfe8 +Author: Damien Miller +Date: Tue Apr 23 14:25:52 2013 +1000 + + - (djm) [auth.c configure.ac misc.c monitor.c monitor_wrap.c] Support + platforms, such as Android, that lack struct passwd.pw_gecos. Report + and initial patch from Nathan Osman bz#2086; feedback tim@ ok dtucker@ + +commit ce1c9574fcfaf753a062276867335c1e237f725c +Author: Darren Tucker +Date: Thu Apr 18 21:36:19 2013 +1000 + + - (dtucker) [configure.ac] Use -Qunused-arguments to suppress warnings from + unused argument warnings (in particular, -fno-builtin-memset) from clang. + +commit bc68f2451b836e6a3fa65df8774a8b1f10049ded +Author: Damien Miller +Date: Thu Apr 18 11:26:25 2013 +1000 + + - (djm) [config.guess config.sub] Update to last versions before they switch + to GPL3. ok dtucker@ + +commit 15fd19c4c9943cf02bc6f462d52c86ee6a8f422e +Author: Darren Tucker +Date: Fri Apr 5 11:22:26 2013 +1100 + + - djm@cvs.openbsd.org 2013/02/22 22:09:01 + [ssh.c] + Allow IdenityFile=none; ok markus deraadt (and dtucker for an earlier + version) + +commit 5d1d9541a7c83963cd887b6b36e25b46463a05d4 +Author: Darren Tucker +Date: Fri Apr 5 11:20:00 2013 +1100 + + - markus@cvs.openbsd.org 2013/02/22 19:13:56 + [sshconnect.c] + support ProxyCommand=- (stdin/out already point to the proxy); ok djm@ + +commit aefa3682431f59cf1ad9a0f624114b135135aa44 +Author: Darren Tucker +Date: Fri Apr 5 11:18:35 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/02/22 04:45:09 + [ssh.c readconf.c readconf.h] + Don't complain if IdentityFiles specified in system-wide configs are + missing. ok djm, deraadt + +commit f3c38142435622d056582e851579d8647a233c7f +Author: Darren Tucker +Date: Fri Apr 5 11:16:52 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/02/19 02:12:47 + [krl.c] + Remove bogus include. ok djm + (id sync only) + +commit 1910478c2d2c3d0e1edacaeff21ed388d70759e9 +Author: Darren Tucker +Date: Fri Apr 5 11:13:08 2013 +1100 + + - dtucker@cvs.openbsd.org 2013/02/17 23:16:57 + [readconf.c ssh.c readconf.h sshconnect2.c] + Keep track of which IndentityFile options were manually supplied and which + were default options, and don't warn if the latter are missing. + ok markus@ + +commit c9627cdbc65b25da943f24e6a953da899f08eefc +Author: Darren Tucker +Date: Mon Apr 1 12:40:48 2013 +1100 + + - (dtucker) [openbsd-compat/bsd-cygwin_util.{c,h}] Don't include windows.h + to avoid conflicting definitions of __int64, adding the required bits. + Patch from Corinna Vinschen. + +commit 75db01d2ce29a85f8e5a2aff2011446896cf3f8a +Author: Tim Rice +Date: Fri Mar 22 10:14:32 2013 -0700 + + - (tim) [Makefile.in] remove some duplication introduced in 20130220 commit. + +commit 221b4b2436ac78a65c3b775c25ccd396a1fed208 +Author: Darren Tucker +Date: Fri Mar 22 12:51:09 2013 +1100 + + - (dtucker) [includes.h] Check if _GNU_SOURCE is already defined before + defining it again. Prevents warnings if someone, eg, sets it in CFLAGS. + +commit c8a0f27c6d761d1335d13ed84d773e9ddf1d95c8 +Author: Darren Tucker +Date: Fri Mar 22 12:49:14 2013 +1100 + + - (dtucker) [configure.ac] Add stdlib.h to zlib check for exit() prototype. + +commit eed8dc261018aea4d6b8606ca3addc9f8cf9ed1e +Author: Damien Miller +Date: Fri Mar 22 10:25:22 2013 +1100 + + - (djm) Release 6.2p1 + +commit 83efe7c86168cc07b8e6cc6df6b54f7ace3b64a3 +Author: Damien Miller +Date: Fri Mar 22 10:17:36 2013 +1100 + + - (djm) [contrib/ssh-copy-id contrib/ssh-copy-id.1] Updated to Phil + Hands' greatly revised version. + +commit 63b4bcd04e1c57b77eabb4e4d359508a4b2af685 +Author: Damien Miller +Date: Wed Mar 20 12:55:14 2013 +1100 + + - (djm) [configure.ac log.c scp.c sshconnect2.c openbsd-compat/vis.c] + [openbsd-compat/vis.h] FreeBSD's strnvis isn't compatible with OpenBSD's + so mark it as broken. Patch from des AT des.no diff --git a/crypto/openssh/Makefile.in b/crypto/openssh/Makefile.in index 06be3d5d5ae4..40cc7aae1ed0 100644 --- a/crypto/openssh/Makefile.in +++ b/crypto/openssh/Makefile.in @@ -65,28 +65,33 @@ MANFMT=@MANFMT@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) LIBOPENSSH_OBJS=\ + ssh_api.o \ ssherr.o \ sshbuf.o \ sshkey.o \ sshbuf-getput-basic.o \ sshbuf-misc.o \ - sshbuf-getput-crypto.o + sshbuf-getput-crypto.o \ + krl.o \ + bitmap.o LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-aes.o \ + authfd.o authfile.o bufaux.o bufbn.o bufec.o buffer.o \ + canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \ cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ - compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ - log.o match.o md-sha256.o moduli.o nchan.o packet.o \ + compat.o crc32.o deattack.o fatal.o hostfile.o \ + log.o match.o md-sha256.o moduli.o nchan.o packet.o opacket.o \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ - atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ + atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ - kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ - ssh-pkcs11.o krl.o smult_curve25519_ref.o \ - kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ - ssh-ed25519.o digest-openssl.o hmac.o \ - sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o + ssh-pkcs11.o smult_curve25519_ref.o \ + poly1305.o chacha.o cipher-chachapoly.o \ + ssh-ed25519.o digest-openssl.o digest-libc.o hmac.o \ + sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \ + kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ + kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ + kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ @@ -99,8 +104,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth-chall.o auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ - monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ - kexc25519s.o auth-krb5.o \ + monitor_mm.o monitor.o monitor_wrap.o auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ sftp-server.o sftp-common.o \ @@ -230,6 +234,12 @@ clean: regressclean rm -f regress/unittests/sshbuf/test_sshbuf rm -f regress/unittests/sshkey/*.o rm -f regress/unittests/sshkey/test_sshkey + rm -f regress/unittests/bitmap/*.o + rm -f regress/unittests/bitmap/test_bitmap + rm -f regress/unittests/hostkeys/*.o + rm -f regress/unittests/hostkeys/test_hostkeys + rm -f regress/unittests/kex/*.o + rm -f regress/unittests/kex/test_kex (cd openbsd-compat && $(MAKE) clean) distclean: regressclean @@ -244,6 +254,12 @@ distclean: regressclean rm -f regress/unittests/sshbuf/test_sshbuf rm -f regress/unittests/sshkey/*.o rm -f regress/unittests/sshkey/test_sshkey + rm -f regress/unittests/bitmap/*.o + rm -f regress/unittests/bitmap/test_bitmap + rm -f regress/unittests/hostkeys/*.o + rm -f regress/unittests/hostkeys/test_hostkeys + rm -f regress/unittests/kex/*.o + rm -f regress/unittests/kex/test_kex (cd openbsd-compat && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ @@ -417,15 +433,21 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 regress-prep: - [ -d `pwd`/regress ] || mkdir -p `pwd`/regress - [ -d `pwd`/regress/unittests ] || mkdir -p `pwd`/regress/unittests - [ -d `pwd`/regress/unittests/test_helper ] || \ + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress + [ -d `pwd`/regress/unittests ] || mkdir -p `pwd`/regress/unittests + [ -d `pwd`/regress/unittests/test_helper ] || \ mkdir -p `pwd`/regress/unittests/test_helper - [ -d `pwd`/regress/unittests/sshbuf ] || \ + [ -d `pwd`/regress/unittests/sshbuf ] || \ mkdir -p `pwd`/regress/unittests/sshbuf - [ -d `pwd`/regress/unittests/sshkey ] || \ + [ -d `pwd`/regress/unittests/sshkey ] || \ mkdir -p `pwd`/regress/unittests/sshkey - [ -f `pwd`/regress/Makefile ] || \ + [ -d `pwd`/regress/unittests/bitmap ] || \ + mkdir -p `pwd`/regress/unittests/bitmap + [ -d `pwd`/regress/unittests/hostkeys ] || \ + mkdir -p `pwd`/regress/unittests/hostkeys + [ -d `pwd`/regress/unittests/kex ] || \ + mkdir -p `pwd`/regress/unittests/kex + [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c @@ -436,6 +458,10 @@ regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ + $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + UNITTESTS_TEST_HELPER_OBJS=\ regress/unittests/test_helper/test_helper.o \ regress/unittests/test_helper/fuzz.o @@ -473,11 +499,46 @@ regress/unittests/sshkey/test_sshkey$(EXEEXT): ${UNITTESTS_TEST_SSHKEY_OBJS} \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +UNITTESTS_TEST_BITMAP_OBJS=\ + regress/unittests/bitmap/tests.o + +regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \ + regress/unittests/test_helper/libtest_helper.a libssh.a + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_BITMAP_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + +UNITTESTS_TEST_KEX_OBJS=\ + regress/unittests/kex/tests.o \ + regress/unittests/kex/test_kex.o \ + roaming_dummy.o + +regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ + regress/unittests/test_helper/libtest_helper.a libssh.a + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_KEX_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + +UNITTESTS_TEST_HOSTKEYS_OBJS=\ + regress/unittests/hostkeys/tests.o \ + regress/unittests/hostkeys/test_iterate.o + +regress/unittests/hostkeys/test_hostkeys$(EXEEXT): \ + ${UNITTESTS_TEST_HOSTKEYS_OBJS} \ + regress/unittests/test_helper/libtest_helper.a libssh.a + $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_HOSTKEYS_OBJS) \ + regress/unittests/test_helper/libtest_helper.a \ + -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + REGRESS_BINARIES=\ regress/modpipe$(EXEEXT) \ regress/setuid-allowed$(EXEEXT) \ + regress/netcat$(EXEEXT) \ regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ - regress/unittests/sshkey/test_sshkey$(EXEEXT) + regress/unittests/sshkey/test_sshkey$(EXEEXT) \ + regress/unittests/bitmap/test_bitmap$(EXEEXT) \ + regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \ + regress/unittests/kex/test_kex$(EXEEXT) tests interop-tests t-exec: regress-prep $(TARGETS) $(REGRESS_BINARIES) BUILDDIR=`pwd`; \ diff --git a/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL index aa59f584eeb4..91bfe270d933 100644 --- a/crypto/openssh/PROTOCOL +++ b/crypto/openssh/PROTOCOL @@ -40,8 +40,8 @@ http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt "ecdsa-sha2-nistp521-cert-v01@openssh.com" OpenSSH introduces new public key algorithms to support certificate -authentication for users and hostkeys. These methods are documented in -the file PROTOCOL.certkeys +authentication for users and host keys. These methods are documented +in the file PROTOCOL.certkeys 1.4. transport: Elliptic Curve cryptography @@ -282,6 +282,53 @@ by the client cancel the forwarding of a Unix domain socket. boolean FALSE string socket path +2.5. connection: hostkey update and rotation "hostkeys-00@openssh.com" +and "hostkeys-prove-00@openssh.com" + +OpenSSH supports a protocol extension allowing a server to inform +a client of all its protocol v.2 host keys after user-authentication +has completed. + + byte SSH_MSG_GLOBAL_REQUEST + string "hostkeys-00@openssh.com" + string[] hostkeys + +Upon receiving this message, a client should check which of the +supplied host keys are present in known_hosts. For keys that are +not present, it should send a "hostkeys-prove@openssh.com" message +to request the server prove ownership of the private half of the +key. + + byte SSH_MSG_GLOBAL_REQUEST + string "hostkeys-prove-00@openssh.com" + char 1 /* want-reply */ + string[] hostkeys + +When a server receives this message, it should generate a signature +using each requested key over the following: + + string "hostkeys-prove-00@openssh.com" + string session identifier + string hostkey + +These signatures should be included in the reply, in the order matching +the hostkeys in the request: + + byte SSH_MSG_REQUEST_SUCCESS + string[] signatures + +When the client receives this reply (and not a failure), it should +validate the signatures and may update its known_hosts file, adding keys +that it has not seen before and deleting keys for the server host that +are no longer offered. + +These extensions let a client learn key types that it had not previously +encountered, thereby allowing it to potentially upgrade from weaker +key algorithms to better ones. It also supports graceful key rotation: +a server may offer multiple keys of the same type for a period (to +give clients an opportunity to learn them using this extension) before +removing the deprecated key from those offered. + 3. SFTP protocol changes 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK @@ -406,4 +453,4 @@ respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". -$OpenBSD: PROTOCOL,v 1.24 2014/07/15 15:54:14 millert Exp $ +$OpenBSD: PROTOCOL,v 1.27 2015/02/20 22:17:21 djm Exp $ diff --git a/crypto/openssh/PROTOCOL.krl b/crypto/openssh/PROTOCOL.krl index e8caa4527ab3..b9695107bac7 100644 --- a/crypto/openssh/PROTOCOL.krl +++ b/crypto/openssh/PROTOCOL.krl @@ -37,7 +37,7 @@ The available section types are: #define KRL_SECTION_FINGERPRINT_SHA1 3 #define KRL_SECTION_SIGNATURE 4 -3. Certificate serial section +2. Certificate section These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by serial number or key ID. The consist of the CA key that issued the @@ -47,6 +47,11 @@ ignored. string ca_key string reserved +Where "ca_key" is the standard SSH wire serialisation of the CA's +public key. Alternately, "ca_key" may be an empty string to indicate +the certificate section applies to all CAs (this is most useful when +revoking key IDs). + Followed by one or more sections: byte cert_section_type @@ -161,4 +166,4 @@ Implementations that retrieve KRLs over untrusted channels must verify signatures. Signature sections are optional for KRLs distributed by trusted means. -$OpenBSD: PROTOCOL.krl,v 1.2 2013/01/18 00:24:58 djm Exp $ +$OpenBSD: PROTOCOL.krl,v 1.3 2015/01/30 01:10:33 djm Exp $ diff --git a/crypto/openssh/README b/crypto/openssh/README index b21441ae0683..f1f7e7fc0451 100644 --- a/crypto/openssh/README +++ b/crypto/openssh/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-6.7 for the release notes. +See http://www.openssh.com/txt/release-6.8 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c index 2bac36c91cd7..b1ec234f5851 100644 --- a/crypto/openssh/atomicio.c +++ b/crypto/openssh/atomicio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 djm Exp $ */ +/* $OpenBSD: atomicio.c,v 1.27 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -41,6 +41,7 @@ #endif #include #include +#include #include "atomicio.h" diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c index f3d9c9df820f..4f0da9c04d33 100644 --- a/crypto/openssh/auth-options.c +++ b/crypto/openssh/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.64 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth-options.c,v 1.65 2015/01/14 10:30:34 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -21,15 +21,19 @@ #include #include "openbsd-compat/sys-queue.h" + +#include "key.h" /* XXX for typedef */ +#include "buffer.h" /* XXX for typedef */ #include "xmalloc.h" #include "match.h" +#include "ssherr.h" #include "log.h" #include "canohost.h" -#include "buffer.h" +#include "sshbuf.h" #include "misc.h" #include "channels.h" #include "servconf.h" -#include "key.h" +#include "sshkey.h" #include "auth-options.h" #include "hostfile.h" #include "auth.h" @@ -417,7 +421,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) #define OPTIONS_CRITICAL 1 #define OPTIONS_EXTENSIONS 2 static int -parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, +parse_option_list(struct sshbuf *oblob, struct passwd *pw, u_int which, int crit, int *cert_no_port_forwarding_flag, int *cert_no_agent_forwarding_flag, @@ -430,26 +434,25 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, char *command, *allowed; const char *remote_ip; char *name = NULL; - u_char *data_blob = NULL; - u_int nlen, dlen, clen; - Buffer c, data; - int ret = -1, result, found; + struct sshbuf *c = NULL, *data = NULL; + int r, ret = -1, result, found; - buffer_init(&data); + if ((c = sshbuf_fromb(oblob)) == NULL) { + error("%s: sshbuf_fromb failed", __func__); + goto out; + } - /* Make copy to avoid altering original */ - buffer_init(&c); - buffer_append(&c, optblob, optblob_len); - - while (buffer_len(&c) > 0) { - if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL || - (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { - error("Certificate options corrupt"); + while (sshbuf_len(c) > 0) { + sshbuf_free(data); + data = NULL; + if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 || + (r = sshbuf_froms(c, &data)) != 0) { + error("Unable to parse certificate options: %s", + ssh_err(r)); goto out; } - buffer_append(&data, data_blob, dlen); - debug3("found certificate option \"%.100s\" len %u", - name, dlen); + debug3("found certificate option \"%.100s\" len %zu", + name, sshbuf_len(data)); found = 0; if ((which & OPTIONS_EXTENSIONS) != 0) { if (strcmp(name, "permit-X11-forwarding") == 0) { @@ -473,10 +476,10 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, } if (!found && (which & OPTIONS_CRITICAL) != 0) { if (strcmp(name, "force-command") == 0) { - if ((command = buffer_get_cstring_ret(&data, - &clen)) == NULL) { - error("Certificate constraint \"%s\" " - "corrupt", name); + if ((r = sshbuf_get_cstring(data, &command, + NULL)) != 0) { + error("Unable to parse \"%s\" " + "section: %s", name, ssh_err(r)); goto out; } if (*cert_forced_command != NULL) { @@ -489,10 +492,10 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, found = 1; } if (strcmp(name, "source-address") == 0) { - if ((allowed = buffer_get_cstring_ret(&data, - &clen)) == NULL) { - error("Certificate constraint " - "\"%s\" corrupt", name); + if ((r = sshbuf_get_cstring(data, &allowed, + NULL)) != 0) { + error("Unable to parse \"%s\" " + "section: %s", name, ssh_err(r)); goto out; } if ((*cert_source_address_done)++) { @@ -540,16 +543,13 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, logit("Certificate extension \"%s\" " "is not supported", name); } - } else if (buffer_len(&data) != 0) { + } else if (sshbuf_len(data) != 0) { error("Certificate option \"%s\" corrupt " "(extra data)", name); goto out; } - buffer_clear(&data); free(name); - free(data_blob); name = NULL; - data_blob = NULL; } /* successfully parsed all options */ ret = 0; @@ -563,10 +563,8 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, } if (name != NULL) free(name); - if (data_blob != NULL) - free(data_blob); - buffer_free(&data); - buffer_free(&c); + sshbuf_free(data); + sshbuf_free(c); return ret; } @@ -575,7 +573,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, * options so this must be called after auth_parse_options(). */ int -auth_cert_options(Key *k, struct passwd *pw) +auth_cert_options(struct sshkey *k, struct passwd *pw) { int cert_no_port_forwarding_flag = 1; int cert_no_agent_forwarding_flag = 1; @@ -585,10 +583,9 @@ auth_cert_options(Key *k, struct passwd *pw) char *cert_forced_command = NULL; int cert_source_address_done = 0; - if (key_cert_is_legacy(k)) { + if (sshkey_cert_is_legacy(k)) { /* All options are in the one field for v00 certs */ - if (parse_option_list(buffer_ptr(k->cert->critical), - buffer_len(k->cert->critical), pw, + if (parse_option_list(k->cert->critical, pw, OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1, &cert_no_port_forwarding_flag, &cert_no_agent_forwarding_flag, @@ -600,14 +597,12 @@ auth_cert_options(Key *k, struct passwd *pw) return -1; } else { /* Separate options and extensions for v01 certs */ - if (parse_option_list(buffer_ptr(k->cert->critical), - buffer_len(k->cert->critical), pw, + if (parse_option_list(k->cert->critical, pw, OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL, &cert_forced_command, &cert_source_address_done) == -1) return -1; - if (parse_option_list(buffer_ptr(k->cert->extensions), - buffer_len(k->cert->extensions), pw, + if (parse_option_list(k->cert->extensions, pw, OPTIONS_EXTENSIONS, 1, &cert_no_port_forwarding_flag, &cert_no_agent_forwarding_flag, diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h index 7455c945465a..34852e5c0bb3 100644 --- a/crypto/openssh/auth-options.h +++ b/crypto/openssh/auth-options.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.h,v 1.20 2010/05/07 11:30:29 djm Exp $ */ +/* $OpenBSD: auth-options.h,v 1.21 2015/01/14 10:30:34 markus Exp $ */ /* * Author: Tatu Ylonen @@ -35,6 +35,6 @@ extern char *authorized_principals; int auth_parse_options(struct passwd *, char *, char *, u_long); void auth_clear_options(void); -int auth_cert_options(Key *, struct passwd *); +int auth_cert_options(struct sshkey *, struct passwd *); #endif diff --git a/crypto/openssh/auth-rh-rsa.c b/crypto/openssh/auth-rh-rsa.c index b7fd064e7dc8..2e20396ea779 100644 --- a/crypto/openssh/auth-rh-rsa.c +++ b/crypto/openssh/auth-rh-rsa.c @@ -15,6 +15,8 @@ #include "includes.h" +#ifdef WITH_SSH1 + #include #include @@ -102,3 +104,5 @@ auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key) packet_send_debug("Rhosts with RSA host authentication accepted."); return 1; } + +#endif /* WITH_SSH1 */ diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c index b5bedee8d40d..ee9e827afd08 100644 --- a/crypto/openssh/auth-rhosts.c +++ b/crypto/openssh/auth-rhosts.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rhosts.c,v 1.45 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth-rhosts.c,v 1.46 2014/12/23 22:42:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -57,7 +57,8 @@ check_rhosts_file(const char *filename, const char *hostname, const char *server_user) { FILE *f; - char buf[1024]; /* Must not be larger than host, user, dummy below. */ +#define RBUFLN 1024 + char buf[RBUFLN];/* Must not be larger than host, user, dummy below. */ int fd; struct stat st; @@ -80,8 +81,9 @@ check_rhosts_file(const char *filename, const char *hostname, return 0; } while (fgets(buf, sizeof(buf), f)) { - /* All three must be at least as big as buf to avoid overflows. */ - char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; + /* All three must have length >= buf to avoid overflows. */ + char hostbuf[RBUFLN], userbuf[RBUFLN], dummy[RBUFLN]; + char *host, *user, *cp; int negated; for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) @@ -140,8 +142,8 @@ check_rhosts_file(const char *filename, const char *hostname, /* Check for empty host/user names (particularly '+'). */ if (!host[0] || !user[0]) { /* We come here if either was '+' or '-'. */ - auth_debug_add("Ignoring wild host/user names in %.100s.", - filename); + auth_debug_add("Ignoring wild host/user names " + "in %.100s.", filename); continue; } /* Verify that host name matches. */ @@ -149,7 +151,8 @@ check_rhosts_file(const char *filename, const char *hostname, if (!innetgr(host + 1, hostname, NULL, NULL) && !innetgr(host + 1, ipaddr, NULL, NULL)) continue; - } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0) + } else if (strcasecmp(host, hostname) && + strcmp(host, ipaddr) != 0) continue; /* Different hostname. */ /* Verify that user name matches. */ @@ -208,7 +211,8 @@ auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostnam /* Switch to the user's uid. */ temporarily_use_uid(pw); /* - * Quick check: if the user has no .shosts or .rhosts files, return + * Quick check: if the user has no .shosts or .rhosts files and + * no system hosts.equiv/shosts.equiv files exist then return * failure immediately without doing costly lookups from name * servers. */ @@ -223,27 +227,38 @@ auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostnam /* Switch back to privileged uid. */ restore_uid(); - /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */ + /* + * Deny if The user has no .shosts or .rhosts file and there + * are no system-wide files. + */ if (!rhosts_files[rhosts_file_index] && stat(_PATH_RHOSTS_EQUIV, &st) < 0 && - stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) + stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) { + debug3("%s: no hosts access files exist", __func__); return 0; + } - /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ - if (pw->pw_uid != 0) { + /* + * If not logging in as superuser, try /etc/hosts.equiv and + * shosts.equiv. + */ + if (pw->pw_uid == 0) + debug3("%s: root user, ignoring system hosts files", __func__); + else { if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, client_user, pw->pw_name)) { - auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.", - hostname, ipaddr); + auth_debug_add("Accepted for %.100s [%.100s] by " + "/etc/hosts.equiv.", hostname, ipaddr); return 1; } if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr, client_user, pw->pw_name)) { - auth_debug_add("Accepted for %.100s [%.100s] by %.100s.", - hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV); + auth_debug_add("Accepted for %.100s [%.100s] by " + "%.100s.", hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV); return 1; } } + /* * Check that the home directory is owned by root or the user, and is * not group or world writable. @@ -290,20 +305,25 @@ auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostnam auth_debug_add("Bad file modes for %.200s", buf); continue; } - /* Check if we have been configured to ignore .rhosts and .shosts files. */ + /* + * Check if we have been configured to ignore .rhosts + * and .shosts files. + */ if (options.ignore_rhosts) { - auth_debug_add("Server has been configured to ignore %.100s.", - rhosts_files[rhosts_file_index]); + auth_debug_add("Server has been configured to " + "ignore %.100s.", rhosts_files[rhosts_file_index]); continue; } /* Check if authentication is permitted by the file. */ - if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) { + if (check_rhosts_file(buf, hostname, ipaddr, + client_user, pw->pw_name)) { auth_debug_add("Accepted by %.100s.", rhosts_files[rhosts_file_index]); /* Restore the privileged uid. */ restore_uid(); - auth_debug_add("Accepted host %s ip %s client_user %s server_user %s", - hostname, ipaddr, client_user, pw->pw_name); + auth_debug_add("Accepted host %s ip %s client_user " + "%s server_user %s", hostname, ipaddr, + client_user, pw->pw_name); return 1; } } diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c index e9f4ede26a77..cbd971be1f17 100644 --- a/crypto/openssh/auth-rsa.c +++ b/crypto/openssh/auth-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rsa.c,v 1.88 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth-rsa.c,v 1.90 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -16,6 +16,8 @@ #include "includes.h" +#ifdef WITH_SSH1 + #include #include @@ -236,7 +238,9 @@ rsa_key_allowed_in_file(struct passwd *pw, char *file, "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + continue; debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(key), fp); free(fp); @@ -341,3 +345,5 @@ auth_rsa(Authctxt *authctxt, BIGNUM *client_n) packet_send_debug("RSA authentication accepted."); return (1); } + +#endif /* WITH_SSH1 */ diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 2b79cfe9724e..d569ab6f7c83 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.106 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth.c,v 1.110 2015/02/25 17:29:38 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -28,7 +28,6 @@ __RCSID("$FreeBSD$"); #include #include -#include #include @@ -51,6 +50,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include "xmalloc.h" #include "match.h" @@ -72,7 +72,8 @@ __RCSID("$FreeBSD$"); #endif #include "authfile.h" #include "monitor_wrap.h" -#include "krl.h" +#include "authfile.h" +#include "ssherr.h" #include "compat.h" /* import */ @@ -331,13 +332,14 @@ auth_log(Authctxt *authctxt, int authenticated, int partial, void auth_maxtries_exceeded(Authctxt *authctxt) { - packet_disconnect("Too many authentication failures for " + error("maximum authentication attempts exceeded for " "%s%.100s from %.200s port %d %s", authctxt->valid ? "" : "invalid user ", authctxt->user, get_remote_ipaddr(), get_remote_port(), compat20 ? "ssh2" : "ssh1"); + packet_disconnect("Too many authentication failures"); /* NOTREACHED */ } @@ -376,7 +378,7 @@ auth_root_allowed(const char *method) char * expand_authorized_keys(const char *filename, struct passwd *pw) { - char *file, ret[MAXPATHLEN]; + char *file, ret[PATH_MAX]; int i; file = percent_expand(filename, "h", pw->pw_dir, @@ -468,7 +470,7 @@ int auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, uid_t uid, char *err, size_t errlen) { - char buf[MAXPATHLEN], homedir[MAXPATHLEN]; + char buf[PATH_MAX], homedir[PATH_MAX]; char *cp; int comparehome = 0; struct stat st; @@ -674,43 +676,39 @@ getpwnamallow(const char *user) int auth_key_is_revoked(Key *key) { -#ifdef WITH_OPENSSL - char *key_fp; + char *fp = NULL; + int r; if (options.revoked_keys_file == NULL) return 0; - switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) { + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + error("%s: fingerprint key: %s", __func__, ssh_err(r)); + goto out; + } + + r = sshkey_check_revoked(key, options.revoked_keys_file); + switch (r) { case 0: - return 0; /* Not revoked */ - case -2: - break; /* Not a KRL */ + break; /* not revoked */ + case SSH_ERR_KEY_REVOKED: + error("Authentication key %s %s revoked by file %s", + sshkey_type(key), fp, options.revoked_keys_file); + goto out; default: - goto revoked; + error("Error checking authentication key %s %s in " + "revoked keys file %s: %s", sshkey_type(key), fp, + options.revoked_keys_file, ssh_err(r)); + goto out; } -#endif - debug3("%s: treating %s as a key list", __func__, - options.revoked_keys_file); - switch (key_in_file(key, options.revoked_keys_file, 0)) { - case 0: - /* key not revoked */ - return 0; - case -1: - /* Error opening revoked_keys_file: refuse all keys */ - error("Revoked keys file is unreadable: refusing public key " - "authentication"); - return 1; -#ifdef WITH_OPENSSL - case 1: - revoked: - /* Key revoked */ - key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - error("WARNING: authentication attempt with a revoked " - "%s key %s ", key_type(key), key_fp); - free(key_fp); - return 1; -#endif - } - fatal("key_in_file returned junk"); + + /* Success */ + r = 0; + + out: + free(fp); + return r == 0 ? 0 : 1; } void diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h index d081c94a6f36..db86037603df 100644 --- a/crypto/openssh/auth.h +++ b/crypto/openssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.78 2014/07/03 11:16:55 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.82 2015/02/16 22:13:32 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -42,6 +42,9 @@ #include #endif +struct ssh; +struct sshkey; + typedef struct Authctxt Authctxt; typedef struct Authmethod Authmethod; typedef struct KbdintDevice KbdintDevice; @@ -75,6 +78,9 @@ struct Authctxt { #endif Buffer *loginmsg; void *methoddata; + + struct sshkey **prev_userkeys; + u_int nprev_userkeys; }; /* * Every authentication method has to handle authentication requests for @@ -123,6 +129,8 @@ int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); int user_key_allowed(struct passwd *, Key *); void pubkey_auth_info(Authctxt *, const Key *, const char *, ...) __attribute__((__format__ (printf, 3, 4))); +void auth2_record_userkey(Authctxt *, struct sshkey *); +int auth2_userkey_already_used(Authctxt *, struct sshkey *); struct stat; int auth_secure_path(const char *, struct stat *, const char *, uid_t, @@ -195,12 +203,13 @@ check_key_in_hostfiles(struct passwd *, Key *, const char *, /* hostkey handling */ Key *get_hostkey_by_index(int); -Key *get_hostkey_public_by_index(int); -Key *get_hostkey_public_by_type(int); -Key *get_hostkey_private_by_type(int); -int get_hostkey_index(Key *); +Key *get_hostkey_public_by_index(int, struct ssh *); +Key *get_hostkey_public_by_type(int, int, struct ssh *); +Key *get_hostkey_private_by_type(int, int, struct ssh *); +int get_hostkey_index(Key *, int, struct ssh *); int ssh1_session_key(BIGNUM *); -void sshd_hostkey_sign(Key *, Key *, u_char **, u_int *, u_char *, u_int); +int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, + const u_char *, size_t, u_int); /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c index 50388285ce4c..5073c49bb37d 100644 --- a/crypto/openssh/auth1.c +++ b/crypto/openssh/auth1.c @@ -12,6 +12,8 @@ #include "includes.h" +#ifdef WITH_SSH1 + #include #include @@ -438,3 +440,5 @@ do_authentication(Authctxt *authctxt) packet_send(); packet_write_wait(); } + +#endif /* WITH_SSH1 */ diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c index 065361d3ec22..e4d4a17770f2 100644 --- a/crypto/openssh/auth2-chall.c +++ b/crypto/openssh/auth2-chall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-chall.c,v 1.41 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: auth2-chall.c,v 1.42 2015/01/19 20:07:45 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Per Allansson. All rights reserved. @@ -49,7 +49,7 @@ extern ServerOptions options; static int auth2_challenge_start(Authctxt *); static int send_userauth_info_request(Authctxt *); -static void input_userauth_info_response(int, u_int32_t, void *); +static int input_userauth_info_response(int, u_int32_t, void *); #ifdef BSD_AUTH extern KbdintDevice bsdauth_device; @@ -284,7 +284,7 @@ send_userauth_info_request(Authctxt *authctxt) return 1; } -static void +static int input_userauth_info_response(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -349,6 +349,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) } userauth_finish(authctxt, authenticated, "keyboard-interactive", devicename); + return 0; } void diff --git a/crypto/openssh/auth2-gss.c b/crypto/openssh/auth2-gss.c index 447f896f2b55..1ca8357731ca 100644 --- a/crypto/openssh/auth2-gss.c +++ b/crypto/openssh/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.21 2014/02/26 20:28:44 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -48,10 +48,10 @@ extern ServerOptions options; -static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); -static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); -static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); -static void input_gssapi_errtok(int, u_int32_t, void *); +static int input_gssapi_token(int type, u_int32_t plen, void *ctxt); +static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); +static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); +static int input_gssapi_errtok(int, u_int32_t, void *); /* * We only support those mechanisms that we know about (ie ones that we know @@ -126,7 +126,7 @@ userauth_gssapi(Authctxt *authctxt) return (0); } -static void +static int input_gssapi_token(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -178,9 +178,10 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt) } gss_release_buffer(&min_status, &send_tok); + return 0; } -static void +static int input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -212,6 +213,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) /* The client will have already moved on to the next auth */ gss_release_buffer(&maj_status, &send_tok); + return 0; } /* @@ -220,7 +222,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) * which only enables it once the GSSAPI exchange is complete. */ -static void +static int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -244,9 +246,10 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); + return 0; } -static void +static int input_gssapi_mic(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -284,6 +287,7 @@ input_gssapi_mic(int type, u_int32_t plen, void *ctxt) dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); + return 0; } Authmethod method_gssapi = { diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c index 6787e4ca4186..eebfe8fc3354 100644 --- a/crypto/openssh/auth2-hostbased.c +++ b/crypto/openssh/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.18 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.24 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -48,6 +48,7 @@ #endif #include "monitor_wrap.h" #include "pathnames.h" +#include "match.h" /* import */ extern ServerOptions options; @@ -107,6 +108,14 @@ userauth_hostbased(Authctxt *authctxt) "signature format"); goto done; } + if (match_pattern_list(sshkey_ssh_name(key), + options.hostbased_key_types, + strlen(options.hostbased_key_types), 0) != 1) { + logit("%s: key type %s not in HostbasedAcceptedKeyTypes", + __func__, sshkey_type(key)); + goto done; + } + service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : authctxt->service; buffer_init(&b); @@ -163,7 +172,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, resolvedname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); - debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", + debug2("%s: chost %s resolvedname %s ipaddr %s", __func__, chost, resolvedname, ipaddr); if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { @@ -172,19 +181,27 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, } if (options.hostbased_uses_name_from_packet_only) { - if (auth_rhosts2(pw, cuser, chost, chost) == 0) + if (auth_rhosts2(pw, cuser, chost, chost) == 0) { + debug2("%s: auth_rhosts2 refused " + "user \"%.100s\" host \"%.100s\" (from packet)", + __func__, cuser, chost); return 0; + } lookup = chost; } else { if (strcasecmp(resolvedname, chost) != 0) logit("userauth_hostbased mismatch: " "client sends %s, but we resolve %s to %s", chost, ipaddr, resolvedname); - if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) + if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) { + debug2("%s: auth_rhosts2 refused " + "user \"%.100s\" host \"%.100s\" addr \"%.100s\"", + __func__, cuser, resolvedname, ipaddr); return 0; + } lookup = resolvedname; } - debug2("userauth_hostbased: access allowed by auth_rhosts2"); + debug2("%s: access allowed by auth_rhosts2", __func__); if (key_is_cert(key) && key_cert_check_authority(key, 1, 0, lookup, &reason)) { @@ -207,14 +224,17 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, if (host_status == HOST_OK) { if (key_is_cert(key)) { - fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); verbose("Accepted certificate ID \"%s\" signed by " "%s CA %s from %s@%s", key->cert->key_id, key_type(key->cert->signature_key), fp, cuser, lookup); } else { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); verbose("Accepted %s public key %s from %s@%s", key_type(key), fp, cuser, lookup); } diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c index f3ca96592b95..d943efa1e7e2 100644 --- a/crypto/openssh/auth2-pubkey.c +++ b/crypto/openssh/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.41 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.47 2015/02/17 00:14:05 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -41,6 +41,7 @@ #include #include #include +#include #include "xmalloc.h" #include "ssh.h" @@ -122,6 +123,17 @@ userauth_pubkey(Authctxt *authctxt) "signature scheme"); goto done; } + if (auth2_userkey_already_used(authctxt, key)) { + logit("refusing previously-used %s key", key_type(key)); + goto done; + } + if (match_pattern_list(sshkey_ssh_name(key), options.pubkey_key_types, + strlen(options.pubkey_key_types), 0) != 1) { + logit("%s: key type %s not in PubkeyAcceptedKeyTypes", + __func__, sshkey_ssh_name(key)); + goto done; + } + if (have_sig) { sig = packet_get_string(&slen); packet_check_eom(); @@ -159,8 +171,12 @@ userauth_pubkey(Authctxt *authctxt) authenticated = 0; if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), - buffer_len(&b))) == 1) + buffer_len(&b))) == 1) { authenticated = 1; + /* Record the successful key to prevent reuse */ + auth2_record_userkey(authctxt, key); + key = NULL; /* Don't free below */ + } buffer_free(&b); free(sig); } else { @@ -212,17 +228,20 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...) } if (key_is_cert(key)) { - fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT); auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", key_type(key), key->cert->key_id, (unsigned long long)key->cert->serial, - key_type(key->cert->signature_key), fp, + key_type(key->cert->signature_key), + fp == NULL ? "(null)" : fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } else { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - auth_info(authctxt, "%s %s%s%s", key_type(key), fp, + fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); + auth_info(authctxt, "%s %s%s%s", key_type(key), + fp == NULL ? "(null)" : fp, extra == NULL ? "" : ", ", extra == NULL ? "" : extra); free(fp); } @@ -365,8 +384,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) continue; if (!key_is_cert_authority) continue; - fp = key_fingerprint(found, SSH_FP_MD5, - SSH_FP_HEX); + if ((fp = sshkey_fingerprint(found, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + continue; debug("matching CA found: file %s, line %lu, %s %s", file, linenum, key_type(found), fp); /* @@ -405,11 +425,13 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) continue; if (key_is_cert_authority) continue; - found_key = 1; - fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(found, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + continue; debug("matching key found: file %s, line %lu %s %s", file, linenum, key_type(found), fp); free(fp); + found_key = 1; break; } } @@ -431,11 +453,12 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) return 0; - ca_fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + return 0; - if (key_in_file(key->cert->signature_key, - options.trusted_user_ca_keys, 1) != 1) { + if (sshkey_in_file(key->cert->signature_key, + options.trusted_user_ca_keys, 1, 0) != 0) { debug2("%s: CA %s %s is not listed in %s", __func__, key_type(key->cert->signature_key), ca_fp, options.trusted_user_ca_keys); @@ -680,6 +703,35 @@ user_key_allowed(struct passwd *pw, Key *key) return success; } +/* Records a public key in the list of previously-successful keys */ +void +auth2_record_userkey(Authctxt *authctxt, struct sshkey *key) +{ + struct sshkey **tmp; + + if (authctxt->nprev_userkeys >= INT_MAX || + (tmp = reallocarray(authctxt->prev_userkeys, + authctxt->nprev_userkeys + 1, sizeof(*tmp))) == NULL) + fatal("%s: reallocarray failed", __func__); + authctxt->prev_userkeys = tmp; + authctxt->prev_userkeys[authctxt->nprev_userkeys] = key; + authctxt->nprev_userkeys++; +} + +/* Checks whether a key has already been used successfully for authentication */ +int +auth2_userkey_already_used(Authctxt *authctxt, struct sshkey *key) +{ + u_int i; + + for (i = 0; i < authctxt->nprev_userkeys; i++) { + if (sshkey_equal_public(key, authctxt->prev_userkeys[i])) { + return 1; + } + } + return 0; +} + Authmethod method_pubkey = { "publickey", userauth_pubkey, diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 2398f363d288..1d9aab037dd6 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.132 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: auth2.c,v 1.135 2015/01/19 20:07:45 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -89,8 +89,8 @@ Authmethod *authmethods[] = { /* protocol */ -static void input_service_request(int, u_int32_t, void *); -static void input_userauth_request(int, u_int32_t, void *); +static int input_service_request(int, u_int32_t, void *); +static int input_userauth_request(int, u_int32_t, void *); /* helper */ static Authmethod *authmethod_lookup(Authctxt *, const char *); @@ -153,9 +153,7 @@ userauth_banner(void) { char *banner = NULL; - if (options.banner == NULL || - strcasecmp(options.banner, "none") == 0 || - (datafellows & SSH_BUG_BANNER) != 0) + if (options.banner == NULL || (datafellows & SSH_BUG_BANNER) != 0) return; if ((banner = PRIVSEP(auth2_read_banner())) == NULL) @@ -178,7 +176,7 @@ do_authentication2(Authctxt *authctxt) } /*ARGSUSED*/ -static void +static int input_service_request(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -209,10 +207,11 @@ input_service_request(int type, u_int32_t seq, void *ctxt) packet_disconnect("bad service request %s", service); } free(service); + return 0; } /*ARGSUSED*/ -static void +static int input_userauth_request(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -316,6 +315,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) free(service); free(user); free(method); + return 0; } void @@ -386,7 +386,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, const char *method, } else { /* Allow initial try of "none" auth without failure penalty */ - if (!authctxt->server_caused_failure && + if (!partial && !authctxt->server_caused_failure && (authctxt->attempt > 1 || strcmp(method, "none") != 0)) authctxt->failures++; if (authctxt->failures >= options.max_authtries) { diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c index 2d5a8dd5bb49..5d9414faf543 100644 --- a/crypto/openssh/authfd.c +++ b/crypto/openssh/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.93 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: authfd.c,v 1.94 2015/01/14 20:05:27 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -47,124 +47,121 @@ #include #include #include +#include #include "xmalloc.h" #include "ssh.h" #include "rsa.h" -#include "buffer.h" -#include "key.h" +#include "sshbuf.h" +#include "sshkey.h" #include "authfd.h" #include "cipher.h" -#include "kex.h" #include "compat.h" #include "log.h" #include "atomicio.h" #include "misc.h" +#include "ssherr.h" -static int agent_present = 0; - -/* helper */ -int decode_reply(int type); +#define MAX_AGENT_IDENTITIES 2048 /* Max keys in agent reply */ +#define MAX_AGENT_REPLY_LEN (256 * 1024) /* Max bytes in agent reply */ /* macro to check for "agent failure" message */ #define agent_failed(x) \ - ((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE) || \ + ((x == SSH_AGENT_FAILURE) || \ + (x == SSH_COM_AGENT2_FAILURE) || \ (x == SSH2_AGENT_FAILURE)) -int -ssh_agent_present(void) +/* Convert success/failure response from agent to a err.h status */ +static int +decode_reply(u_char type) { - int authfd; - - if (agent_present) - return 1; - if ((authfd = ssh_get_authentication_socket()) == -1) + if (agent_failed(type)) + return SSH_ERR_AGENT_FAILURE; + else if (type == SSH_AGENT_SUCCESS) return 0; - else { - ssh_close_authentication_socket(authfd); - return 1; - } + else + return SSH_ERR_INVALID_FORMAT; } /* Returns the number of the authentication fd, or -1 if there is none. */ - int -ssh_get_authentication_socket(void) +ssh_get_authentication_socket(int *fdp) { const char *authsocket; - int sock; + int sock, oerrno; struct sockaddr_un sunaddr; + if (fdp != NULL) + *fdp = -1; + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); if (!authsocket) - return -1; + return SSH_ERR_AGENT_NOT_PRESENT; memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - return -1; + if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return SSH_ERR_SYSTEM_ERROR; /* close on exec */ - if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { + if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1 || + connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { + oerrno = errno; close(sock); - return -1; + errno = oerrno; + return SSH_ERR_SYSTEM_ERROR; } - if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) { + if (fdp != NULL) + *fdp = sock; + else close(sock); - return -1; - } - agent_present = 1; - return sock; + return 0; } +/* Communicate with agent: send request and read reply */ static int -ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply) +ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) { - u_int l, len; + int r; + size_t l, len; char buf[1024]; /* Get the length of the message, and format it in the buffer. */ - len = buffer_len(request); + len = sshbuf_len(request); put_u32(buf, len); /* Send the length and then the packet to the agent. */ - if (atomicio(vwrite, auth->fd, buf, 4) != 4 || - atomicio(vwrite, auth->fd, buffer_ptr(request), - buffer_len(request)) != buffer_len(request)) { - error("Error writing to authentication socket."); - return 0; - } + if (atomicio(vwrite, sock, buf, 4) != 4 || + atomicio(vwrite, sock, (u_char *)sshbuf_ptr(request), + sshbuf_len(request)) != sshbuf_len(request)) + return SSH_ERR_AGENT_COMMUNICATION; /* * Wait for response from the agent. First read the length of the * response packet. */ - if (atomicio(read, auth->fd, buf, 4) != 4) { - error("Error reading response length from authentication socket."); - return 0; - } + if (atomicio(read, sock, buf, 4) != 4) + return SSH_ERR_AGENT_COMMUNICATION; /* Extract the length, and check it for sanity. */ len = get_u32(buf); - if (len > 256 * 1024) - fatal("Authentication response too long: %u", len); + if (len > MAX_AGENT_REPLY_LEN) + return SSH_ERR_INVALID_FORMAT; /* Read the rest of the response in to the buffer. */ - buffer_clear(reply); + sshbuf_reset(reply); while (len > 0) { l = len; if (l > sizeof(buf)) l = sizeof(buf); - if (atomicio(read, auth->fd, buf, l) != l) { - error("Error reading response from authentication socket."); - return 0; - } - buffer_append(reply, buf, l); + if (atomicio(read, sock, buf, l) != l) + return SSH_ERR_AGENT_COMMUNICATION; + if ((r = sshbuf_put(reply, buf, l)) != 0) + return r; len -= l; } - return 1; + return 0; } /* @@ -172,7 +169,6 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply * obtained). The argument must have been returned by * ssh_get_authentication_socket(). */ - void ssh_close_authentication_socket(int sock) { @@ -180,80 +176,103 @@ ssh_close_authentication_socket(int sock) close(sock); } -/* - * Opens and connects a private socket for communication with the - * authentication agent. Returns the file descriptor (which must be - * shut down and closed by the caller when no longer needed). - * Returns NULL if an error occurred and the connection could not be - * opened. - */ - -AuthenticationConnection * -ssh_get_authentication_connection(void) -{ - AuthenticationConnection *auth; - int sock; - - sock = ssh_get_authentication_socket(); - - /* - * Fail if we couldn't obtain a connection. This happens if we - * exited due to a timeout. - */ - if (sock < 0) - return NULL; - - auth = xcalloc(1, sizeof(*auth)); - auth->fd = sock; - buffer_init(&auth->identities); - auth->howmany = 0; - - return auth; -} - -/* - * Closes the connection to the authentication agent and frees any associated - * memory. - */ - -void -ssh_close_authentication_connection(AuthenticationConnection *auth) -{ - buffer_free(&auth->identities); - close(auth->fd); - free(auth); -} - /* Lock/unlock agent */ int -ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password) +ssh_lock_agent(int sock, int lock, const char *password) { - int type; - Buffer msg; + int r; + u_char type = lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK; + struct sshbuf *msg; - buffer_init(&msg); - buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK); - buffer_put_cstring(&msg, password); + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_u8(msg, type)) != 0 || + (r = sshbuf_put_cstring(msg, password)) != 0) + goto out; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; + r = decode_reply(type); + out: + sshbuf_free(msg); + return r; +} - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; +#ifdef WITH_SSH1 +static int +deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp) +{ + struct sshkey *key; + int r, keybits; + u_int32_t bits; + char *comment = NULL; + + if ((key = sshkey_new(KEY_RSA1)) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_get_u32(ids, &bits)) != 0 || + (r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 || + (r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 || + (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) + goto out; + keybits = BN_num_bits(key->rsa->n); + /* XXX previously we just warned here. I think we should be strict */ + if (keybits < 0 || bits != (u_int)keybits) { + r = SSH_ERR_KEY_BITS_MISMATCH; + goto out; } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); + if (keyp != NULL) { + *keyp = key; + key = NULL; + } + if (commentp != NULL) { + *commentp = comment; + comment = NULL; + } + r = 0; + out: + sshkey_free(key); + free(comment); + return r; +} +#endif + +static int +deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp) +{ + int r; + char *comment = NULL; + const u_char *blob; + size_t blen; + + if ((r = sshbuf_get_string_direct(ids, &blob, &blen)) != 0 || + (r = sshbuf_get_cstring(ids, &comment, NULL)) != 0) + goto out; + if ((r = sshkey_from_blob(blob, blen, keyp)) != 0) + goto out; + if (commentp != NULL) { + *commentp = comment; + comment = NULL; + } + r = 0; + out: + free(comment); + return r; } /* - * Returns the first authentication identity held by the agent. + * Fetch list of identities held by the agent. */ - int -ssh_get_num_identities(AuthenticationConnection *auth, int version) +ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp) { - int type, code1 = 0, code2 = 0; - Buffer request; + u_char type, code1 = 0, code2 = 0; + u_int32_t num, i; + struct sshbuf *msg; + struct ssh_identitylist *idl = NULL; + int r; + /* Determine request and expected response types */ switch (version) { case 1: code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES; @@ -264,238 +283,270 @@ ssh_get_num_identities(AuthenticationConnection *auth, int version) code2 = SSH2_AGENT_IDENTITIES_ANSWER; break; default: - return 0; + return SSH_ERR_INVALID_ARGUMENT; } /* * Send a message to the agent requesting for a list of the * identities it can represent. */ - buffer_init(&request); - buffer_put_char(&request, code1); + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_u8(msg, code1)) != 0) + goto out; - buffer_clear(&auth->identities); - if (ssh_request_reply(auth, &request, &auth->identities) == 0) { - buffer_free(&request); - return 0; - } - buffer_free(&request); + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; /* Get message type, and verify that we got a proper answer. */ - type = buffer_get_char(&auth->identities); + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; if (agent_failed(type)) { - return 0; + r = SSH_ERR_AGENT_FAILURE; + goto out; } else if (type != code2) { - fatal("Bad authentication reply message type: %d", type); + r = SSH_ERR_INVALID_FORMAT; + goto out; } /* Get the number of entries in the response and check it for sanity. */ - auth->howmany = buffer_get_int(&auth->identities); - if ((u_int)auth->howmany > 1024) - fatal("Too many identities in authentication reply: %d", - auth->howmany); - - return auth->howmany; -} - -Key * -ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) -{ - /* get number of identities and return the first entry (if any). */ - if (ssh_get_num_identities(auth, version) > 0) - return ssh_get_next_identity(auth, comment, version); - return NULL; -} - -Key * -ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version) -{ -#ifdef WITH_SSH1 - int keybits; - u_int bits; -#endif - u_char *blob; - u_int blen; - Key *key = NULL; - - /* Return failure if no more entries. */ - if (auth->howmany <= 0) - return NULL; - - /* - * Get the next entry from the packet. These will abort with a fatal - * error if the packet is too short or contains corrupt data. - */ - switch (version) { -#ifdef WITH_SSH1 - case 1: - key = key_new(KEY_RSA1); - bits = buffer_get_int(&auth->identities); - buffer_get_bignum(&auth->identities, key->rsa->e); - buffer_get_bignum(&auth->identities, key->rsa->n); - *comment = buffer_get_string(&auth->identities, NULL); - keybits = BN_num_bits(key->rsa->n); - if (keybits < 0 || bits != (u_int)keybits) - logit("Warning: identity keysize mismatch: actual %d, announced %u", - BN_num_bits(key->rsa->n), bits); - break; -#endif - case 2: - blob = buffer_get_string(&auth->identities, &blen); - *comment = buffer_get_string(&auth->identities, NULL); - key = key_from_blob(blob, blen); - free(blob); - break; - default: - return NULL; + if ((r = sshbuf_get_u32(msg, &num)) != 0) + goto out; + if (num > MAX_AGENT_IDENTITIES) { + r = SSH_ERR_INVALID_FORMAT; + goto out; } - /* Decrement the number of remaining entries. */ - auth->howmany--; - return key; + if (num == 0) { + r = SSH_ERR_AGENT_NO_IDENTITIES; + goto out; + } + + /* Deserialise the response into a list of keys/comments */ + if ((idl = calloc(1, sizeof(*idl))) == NULL || + (idl->keys = calloc(num, sizeof(*idl->keys))) == NULL || + (idl->comments = calloc(num, sizeof(*idl->comments))) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + for (i = 0; i < num;) { + switch (version) { + case 1: +#ifdef WITH_SSH1 + if ((r = deserialise_identity1(msg, + &(idl->keys[i]), &(idl->comments[i]))) != 0) + goto out; +#endif + break; + case 2: + if ((r = deserialise_identity2(msg, + &(idl->keys[i]), &(idl->comments[i]))) != 0) { + if (r == SSH_ERR_KEY_TYPE_UNKNOWN) { + /* Gracefully skip unknown key types */ + num--; + continue; + } else + goto out; + } + break; + } + i++; + } + idl->nkeys = num; + *idlp = idl; + idl = NULL; + r = 0; + out: + sshbuf_free(msg); + if (idl != NULL) + ssh_free_identitylist(idl); + return r; +} + +void +ssh_free_identitylist(struct ssh_identitylist *idl) +{ + size_t i; + + if (idl == NULL) + return; + for (i = 0; i < idl->nkeys; i++) { + if (idl->keys != NULL) + sshkey_free(idl->keys[i]); + if (idl->comments != NULL) + free(idl->comments[i]); + } + free(idl); } /* - * Generates a random challenge, sends it to the agent, and waits for - * response from the agent. Returns true (non-zero) if the agent gave the - * correct answer, zero otherwise. Response type selects the style of - * response desired, with 0 corresponding to protocol version 1.0 (no longer - * supported) and 1 corresponding to protocol version 1.1. + * Sends a challenge (typically from a server via ssh(1)) to the agent, + * and waits for a response from the agent. + * Returns true (non-zero) if the agent gave the correct answer, zero + * otherwise. */ #ifdef WITH_SSH1 int -ssh_decrypt_challenge(AuthenticationConnection *auth, - Key* key, BIGNUM *challenge, - u_char session_id[16], - u_int response_type, - u_char response[16]) +ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, + u_char session_id[16], u_char response[16]) { - Buffer buffer; - int success = 0; - int i; - int type; + struct sshbuf *msg; + int r; + u_char type; if (key->type != KEY_RSA1) - return 0; - if (response_type == 0) { - logit("Compatibility with ssh protocol version 1.0 no longer supported."); - return 0; - } - buffer_init(&buffer); - buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE); - buffer_put_int(&buffer, BN_num_bits(key->rsa->n)); - buffer_put_bignum(&buffer, key->rsa->e); - buffer_put_bignum(&buffer, key->rsa->n); - buffer_put_bignum(&buffer, challenge); - buffer_append(&buffer, session_id, 16); - buffer_put_int(&buffer, response_type); - - if (ssh_request_reply(auth, &buffer, &buffer) == 0) { - buffer_free(&buffer); - return 0; - } - type = buffer_get_char(&buffer); - + return SSH_ERR_INVALID_ARGUMENT; + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 || + (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || + (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || + (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 || + (r = sshbuf_put_bignum1(msg, challenge)) != 0 || + (r = sshbuf_put(msg, session_id, 16)) != 0 || + (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */ + goto out; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; if (agent_failed(type)) { - logit("Agent admitted failure to authenticate using the key."); + r = SSH_ERR_AGENT_FAILURE; + goto out; } else if (type != SSH_AGENT_RSA_RESPONSE) { - fatal("Bad authentication response: %d", type); - } else { - success = 1; - /* - * Get the response from the packet. This will abort with a - * fatal error if the packet is corrupt. - */ - for (i = 0; i < 16; i++) - response[i] = (u_char)buffer_get_char(&buffer); + r = SSH_ERR_INVALID_FORMAT; + goto out; } - buffer_free(&buffer); - return success; + if ((r = sshbuf_get(msg, response, 16)) != 0) + goto out; + r = 0; + out: + sshbuf_free(msg); + return r; } #endif -/* ask agent to sign data, returns -1 on error, 0 on success */ +/* ask agent to sign data, returns err.h code on error, 0 on success */ int -ssh_agent_sign(AuthenticationConnection *auth, - Key *key, - u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) +ssh_agent_sign(int sock, struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, u_int compat) { - extern int datafellows; - Buffer msg; - u_char *blob; - u_int blen; - int type, flags = 0; - int ret = -1; + struct sshbuf *msg; + u_char *blob = NULL, type; + size_t blen = 0, len = 0; + u_int flags = 0; + int r = SSH_ERR_INTERNAL_ERROR; - if (key_to_blob(key, &blob, &blen) == 0) - return -1; + if (sigp != NULL) + *sigp = NULL; + if (lenp != NULL) + *lenp = 0; - if (datafellows & SSH_BUG_SIGBLOB) - flags = SSH_AGENT_OLD_SIGNATURE; - - buffer_init(&msg); - buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); - buffer_put_string(&msg, blob, blen); - buffer_put_string(&msg, data, datalen); - buffer_put_int(&msg, flags); - free(blob); - - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return -1; - } - type = buffer_get_char(&msg); + if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE) + return SSH_ERR_INVALID_ARGUMENT; + if (compat & SSH_BUG_SIGBLOB) + flags |= SSH_AGENT_OLD_SIGNATURE; + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) + goto out; + if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 || + (r = sshbuf_put_string(msg, blob, blen)) != 0 || + (r = sshbuf_put_string(msg, data, datalen)) != 0 || + (r = sshbuf_put_u32(msg, flags)) != 0) + goto out; + if ((r = ssh_request_reply(sock, msg, msg) != 0)) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; if (agent_failed(type)) { - logit("Agent admitted failure to sign using the key."); + r = SSH_ERR_AGENT_FAILURE; + goto out; } else if (type != SSH2_AGENT_SIGN_RESPONSE) { - fatal("Bad authentication response: %d", type); - } else { - ret = 0; - *sigp = buffer_get_string(&msg, lenp); + r = SSH_ERR_INVALID_FORMAT; + goto out; } - buffer_free(&msg); - return ret; + if ((r = sshbuf_get_string(msg, sigp, &len)) != 0) + goto out; + *lenp = len; + r = 0; + out: + if (blob != NULL) { + explicit_bzero(blob, blen); + free(blob); + } + sshbuf_free(msg); + return r; } /* Encode key for a message to the agent. */ #ifdef WITH_SSH1 -static void -ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment) +static int +ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment) { - buffer_put_int(b, BN_num_bits(key->n)); - buffer_put_bignum(b, key->n); - buffer_put_bignum(b, key->e); - buffer_put_bignum(b, key->d); + int r; + /* To keep within the protocol: p < q for ssh. in SSL p > q */ - buffer_put_bignum(b, key->iqmp); /* ssh key->u */ - buffer_put_bignum(b, key->q); /* ssh key->p, SSL key->q */ - buffer_put_bignum(b, key->p); /* ssh key->q, SSL key->p */ - buffer_put_cstring(b, comment); + if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 || + (r = sshbuf_put_bignum1(b, key->n)) != 0 || + (r = sshbuf_put_bignum1(b, key->e)) != 0 || + (r = sshbuf_put_bignum1(b, key->d)) != 0 || + (r = sshbuf_put_bignum1(b, key->iqmp)) != 0 || + (r = sshbuf_put_bignum1(b, key->q)) != 0 || + (r = sshbuf_put_bignum1(b, key->p)) != 0 || + (r = sshbuf_put_cstring(b, comment)) != 0) + return r; + return 0; } #endif -static void -ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) +static int +ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key, + const char *comment) { - key_private_serialize(key, b); - buffer_put_cstring(b, comment); + int r; + + if ((r = sshkey_private_serialize(key, b)) != 0 || + (r = sshbuf_put_cstring(b, comment)) != 0) + return r; + return 0; +} + +static int +encode_constraints(struct sshbuf *m, u_int life, u_int confirm) +{ + int r; + + if (life != 0) { + if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_LIFETIME)) != 0 || + (r = sshbuf_put_u32(m, life)) != 0) + goto out; + } + if (confirm != 0) { + if ((r = sshbuf_put_u8(m, SSH_AGENT_CONSTRAIN_CONFIRM)) != 0) + goto out; + } + r = 0; + out: + return r; } /* - * Adds an identity to the authentication server. This call is not meant to - * be used by normal applications. + * Adds an identity to the authentication server. + * This call is intended only for use by ssh-add(1) and like applications. */ - int -ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, - const char *comment, u_int life, u_int confirm) +ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment, + u_int life, u_int confirm) { - Buffer msg; - int type, constrained = (life || confirm); + struct sshbuf *msg; + int r, constrained = (life || confirm); + u_char type; - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; switch (key->type) { #ifdef WITH_SSH1 @@ -503,8 +554,9 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, type = constrained ? SSH_AGENTC_ADD_RSA_ID_CONSTRAINED : SSH_AGENTC_ADD_RSA_IDENTITY; - buffer_put_char(&msg, type); - ssh_encode_identity_rsa1(&msg, key->rsa, comment); + if ((r = sshbuf_put_u8(msg, type)) != 0 || + (r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0) + goto out; break; #endif #ifdef WITH_OPENSSL @@ -522,77 +574,88 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; - buffer_put_char(&msg, type); - ssh_encode_identity_ssh2(&msg, key, comment); + if ((r = sshbuf_put_u8(msg, type)) != 0 || + (r = ssh_encode_identity_ssh2(msg, key, comment)) != 0) + goto out; break; default: - buffer_free(&msg); - return 0; + r = SSH_ERR_INVALID_ARGUMENT; + goto out; } - if (constrained) { - if (life != 0) { - buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); - buffer_put_int(&msg, life); - } - if (confirm != 0) - buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM); - } - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); + if (constrained && + (r = encode_constraints(msg, life, confirm)) != 0) + goto out; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; + r = decode_reply(type); + out: + sshbuf_free(msg); + return r; } /* - * Removes an identity from the authentication server. This call is not - * meant to be used by normal applications. + * Removes an identity from the authentication server. + * This call is intended only for use by ssh-add(1) and like applications. */ - int -ssh_remove_identity(AuthenticationConnection *auth, Key *key) +ssh_remove_identity(int sock, struct sshkey *key) { - Buffer msg; - int type; - u_char *blob; - u_int blen; + struct sshbuf *msg; + int r; + u_char type, *blob = NULL; + size_t blen; - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; #ifdef WITH_SSH1 if (key->type == KEY_RSA1) { - buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); - buffer_put_int(&msg, BN_num_bits(key->rsa->n)); - buffer_put_bignum(&msg, key->rsa->e); - buffer_put_bignum(&msg, key->rsa->n); + if ((r = sshbuf_put_u8(msg, + SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 || + (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || + (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || + (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0) + goto out; } else #endif if (key->type != KEY_UNSPEC) { - key_to_blob(key, &blob, &blen); - buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); - buffer_put_string(&msg, blob, blen); - free(blob); + if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) + goto out; + if ((r = sshbuf_put_u8(msg, + SSH2_AGENTC_REMOVE_IDENTITY)) != 0 || + (r = sshbuf_put_string(msg, blob, blen)) != 0) + goto out; } else { - buffer_free(&msg); - return 0; + r = SSH_ERR_INVALID_ARGUMENT; + goto out; } - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; + r = decode_reply(type); + out: + if (blob != NULL) { + explicit_bzero(blob, blen); + free(blob); } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); + sshbuf_free(msg); + return r; } +/* + * Add/remove an token-based identity from the authentication server. + * This call is intended only for use by ssh-add(1) and like applications. + */ int -ssh_update_card(AuthenticationConnection *auth, int add, - const char *reader_id, const char *pin, u_int life, u_int confirm) +ssh_update_card(int sock, int add, const char *reader_id, const char *pin, + u_int life, u_int confirm) { - Buffer msg; - int type, constrained = (life || confirm); + struct sshbuf *msg; + int r, constrained = (life || confirm); + u_char type; if (add) { type = constrained ? @@ -601,69 +664,48 @@ ssh_update_card(AuthenticationConnection *auth, int add, } else type = SSH_AGENTC_REMOVE_SMARTCARD_KEY; - buffer_init(&msg); - buffer_put_char(&msg, type); - buffer_put_cstring(&msg, reader_id); - buffer_put_cstring(&msg, pin); - - if (constrained) { - if (life != 0) { - buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); - buffer_put_int(&msg, life); - } - if (confirm != 0) - buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM); - } - - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_u8(msg, type)) != 0 || + (r = sshbuf_put_cstring(msg, reader_id)) != 0 || + (r = sshbuf_put_cstring(msg, pin)) != 0) + goto out; + if (constrained && + (r = encode_constraints(msg, life, confirm)) != 0) + goto out; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; + r = decode_reply(type); + out: + sshbuf_free(msg); + return r; } /* - * Removes all identities from the agent. This call is not meant to be used - * by normal applications. + * Removes all identities from the agent. + * This call is intended only for use by ssh-add(1) and like applications. */ - int -ssh_remove_all_identities(AuthenticationConnection *auth, int version) +ssh_remove_all_identities(int sock, int version) { - Buffer msg; - int type; - int code = (version==1) ? - SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : - SSH2_AGENTC_REMOVE_ALL_IDENTITIES; + struct sshbuf *msg; + u_char type = (version == 1) ? + SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : + SSH2_AGENTC_REMOVE_ALL_IDENTITIES; + int r; - buffer_init(&msg); - buffer_put_char(&msg, code); - - if (ssh_request_reply(auth, &msg, &msg) == 0) { - buffer_free(&msg); - return 0; - } - type = buffer_get_char(&msg); - buffer_free(&msg); - return decode_reply(type); -} - -int -decode_reply(int type) -{ - switch (type) { - case SSH_AGENT_FAILURE: - case SSH_COM_AGENT2_FAILURE: - case SSH2_AGENT_FAILURE: - logit("SSH_AGENT_FAILURE"); - return 0; - case SSH_AGENT_SUCCESS: - return 1; - default: - fatal("Bad response from authentication agent: %d", type); - } - /* NOTREACHED */ - return 0; + if ((msg = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_u8(msg, type)) != 0) + goto out; + if ((r = ssh_request_reply(sock, msg, msg)) != 0) + goto out; + if ((r = sshbuf_get_u8(msg, &type)) != 0) + goto out; + r = decode_reply(type); + out: + sshbuf_free(msg); + return r; } diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h index 2582a27aa52f..bea20c26bc96 100644 --- a/crypto/openssh/authfd.h +++ b/crypto/openssh/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.37 2009/08/27 17:44:52 djm Exp $ */ +/* $OpenBSD: authfd.h,v 1.38 2015/01/14 20:05:27 djm Exp $ */ /* * Author: Tatu Ylonen @@ -16,6 +16,33 @@ #ifndef AUTHFD_H #define AUTHFD_H +/* List of identities returned by ssh_fetch_identitylist() */ +struct ssh_identitylist { + size_t nkeys; + struct sshkey **keys; + char **comments; +}; + +int ssh_get_authentication_socket(int *fdp); +void ssh_close_authentication_socket(int sock); + +int ssh_lock_agent(int sock, int lock, const char *password); +int ssh_fetch_identitylist(int sock, int version, + struct ssh_identitylist **idlp); +void ssh_free_identitylist(struct ssh_identitylist *idl); +int ssh_add_identity_constrained(int sock, struct sshkey *key, + const char *comment, u_int life, u_int confirm); +int ssh_remove_identity(int sock, struct sshkey *key); +int ssh_update_card(int sock, int add, const char *reader_id, + const char *pin, u_int life, u_int confirm); +int ssh_remove_all_identities(int sock, int version); + +int ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, + u_char session_id[16], u_char response[16]); +int ssh_agent_sign(int sock, struct sshkey *key, + u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, u_int compat); + /* Messages for the authentication agent connection. */ #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 #define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 @@ -60,35 +87,4 @@ #define SSH_AGENT_OLD_SIGNATURE 0x01 -typedef struct { - int fd; - Buffer identities; - int howmany; -} AuthenticationConnection; - -int ssh_agent_present(void); -int ssh_get_authentication_socket(void); -void ssh_close_authentication_socket(int); - -AuthenticationConnection *ssh_get_authentication_connection(void); -void ssh_close_authentication_connection(AuthenticationConnection *); -int ssh_get_num_identities(AuthenticationConnection *, int); -Key *ssh_get_first_identity(AuthenticationConnection *, char **, int); -Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); -int ssh_add_identity_constrained(AuthenticationConnection *, Key *, - const char *, u_int, u_int); -int ssh_remove_identity(AuthenticationConnection *, Key *); -int ssh_remove_all_identities(AuthenticationConnection *, int); -int ssh_lock_agent(AuthenticationConnection *, int, const char *); -int ssh_update_card(AuthenticationConnection *, int, const char *, - const char *, u_int, u_int); - -int -ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16], - u_int, u_char[16]); - -int -ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *, - u_int); - #endif /* AUTHFD_H */ diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c index e93d8673860c..3a81786c7d2b 100644 --- a/crypto/openssh/authfile.c +++ b/crypto/openssh/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: authfile.c,v 1.111 2015/02/23 16:55:51 djm Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include "cipher.h" #include "key.h" @@ -48,6 +48,7 @@ #include "atomicio.h" #include "sshbuf.h" #include "ssherr.h" +#include "krl.h" #define MAX_KEY_FILE_SIZE (1024 * 1024) @@ -94,7 +95,7 @@ sshkey_save_private(struct sshkey *key, const char *filename, /* Load a key from a fd into a buffer */ int -sshkey_load_file(int fd, const char *filename, struct sshbuf *blob) +sshkey_load_file(int fd, struct sshbuf *blob) { u_char buf[1024]; size_t len; @@ -141,8 +142,7 @@ sshkey_load_file(int fd, const char *filename, struct sshbuf *blob) * otherwise. */ static int -sshkey_load_public_rsa1(int fd, const char *filename, - struct sshkey **keyp, char **commentp) +sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp) { struct sshbuf *b = NULL; int r; @@ -153,7 +153,7 @@ sshkey_load_public_rsa1(int fd, const char *filename, if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - if ((r = sshkey_load_file(fd, filename, b)) != 0) + if ((r = sshkey_load_file(fd, b)) != 0) goto out; if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0) goto out; @@ -164,33 +164,6 @@ sshkey_load_public_rsa1(int fd, const char *filename, } #endif /* WITH_SSH1 */ -#ifdef WITH_OPENSSL -/* XXX Deprecate? */ -int -sshkey_load_private_pem(int fd, int type, const char *passphrase, - struct sshkey **keyp, char **commentp) -{ - struct sshbuf *buffer = NULL; - int r; - - *keyp = NULL; - if (commentp != NULL) - *commentp = NULL; - - if ((buffer = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; - if ((r = sshkey_load_file(fd, NULL, buffer)) != 0) - goto out; - if ((r = sshkey_parse_private_pem_fileblob(buffer, type, passphrase, - keyp, commentp)) != 0) - goto out; - r = 0; - out: - sshbuf_free(buffer); - return r; -} -#endif /* WITH_OPENSSL */ - /* XXX remove error() calls from here? */ int sshkey_perm_ok(int fd, const char *filename) @@ -226,7 +199,6 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase, struct sshkey **keyp, char **commentp, int *perm_ok) { int fd, r; - struct sshbuf *buffer = NULL; *keyp = NULL; if (commentp != NULL) @@ -246,18 +218,31 @@ sshkey_load_private_type(int type, const char *filename, const char *passphrase, if (perm_ok != NULL) *perm_ok = 1; + r = sshkey_load_private_type_fd(fd, type, passphrase, keyp, commentp); + out: + close(fd); + return r; +} + +int +sshkey_load_private_type_fd(int fd, int type, const char *passphrase, + struct sshkey **keyp, char **commentp) +{ + struct sshbuf *buffer = NULL; + int r; + if ((buffer = sshbuf_new()) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } - if ((r = sshkey_load_file(fd, filename, buffer)) != 0) - goto out; - if ((r = sshkey_parse_private_fileblob_type(buffer, type, passphrase, - keyp, commentp)) != 0) + if ((r = sshkey_load_file(fd, buffer)) != 0 || + (r = sshkey_parse_private_fileblob_type(buffer, type, + passphrase, keyp, commentp)) != 0) goto out; + + /* success */ r = 0; out: - close(fd); if (buffer != NULL) sshbuf_free(buffer); return r; @@ -286,7 +271,7 @@ sshkey_load_private(const char *filename, const char *passphrase, r = SSH_ERR_ALLOC_FAIL; goto out; } - if ((r = sshkey_load_file(fd, filename, buffer)) != 0 || + if ((r = sshkey_load_file(fd, buffer)) != 0 || (r = sshkey_parse_private_fileblob(buffer, passphrase, filename, keyp, commentp)) != 0) goto out; @@ -350,7 +335,7 @@ int sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) { struct sshkey *pub = NULL; - char file[MAXPATHLEN]; + char file[PATH_MAX]; int r, fd; if (keyp != NULL) @@ -358,11 +343,13 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) if (commentp != NULL) *commentp = NULL; + /* XXX should load file once and attempt to parse each format */ + if ((fd = open(filename, O_RDONLY)) < 0) goto skip; #ifdef WITH_SSH1 /* try rsa1 private key */ - r = sshkey_load_public_rsa1(fd, filename, keyp, commentp); + r = sshkey_load_public_rsa1(fd, keyp, commentp); close(fd); switch (r) { case SSH_ERR_INTERNAL_ERROR: @@ -409,6 +396,7 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp) return 0; } sshkey_free(pub); + return r; } @@ -494,11 +482,14 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, /* * Returns success if the specified "key" is listed in the file "filename", * SSH_ERR_KEY_NOT_FOUND: if the key is not listed or another error. - * If strict_type is set then the key type must match exactly, + * If "strict_type" is set then the key type must match exactly, * otherwise a comparison that ignores certficiate data is performed. + * If "check_ca" is set and "key" is a certificate, then its CA key is + * also checked and sshkey_in_file() will return success if either is found. */ int -sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) +sshkey_in_file(struct sshkey *key, const char *filename, int strict_type, + int check_ca) { FILE *f; char line[SSH_MAX_PUBKEY_BYTES]; @@ -509,12 +500,8 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) int (*sshkey_compare)(const struct sshkey *, const struct sshkey *) = strict_type ? sshkey_equal : sshkey_equal_public; - if ((f = fopen(filename, "r")) == NULL) { - if (errno == ENOENT) - return SSH_ERR_KEY_NOT_FOUND; - else - return SSH_ERR_SYSTEM_ERROR; - } + if ((f = fopen(filename, "r")) == NULL) + return SSH_ERR_SYSTEM_ERROR; while (read_keyfile_line(f, filename, line, sizeof(line), &linenum) != -1) { @@ -538,7 +525,9 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) } if ((r = sshkey_read(pub, &cp)) != 0) goto out; - if (sshkey_compare(key, pub)) { + if (sshkey_compare(key, pub) || + (check_ca && sshkey_is_cert(key) && + sshkey_compare(key->cert->signature_key, pub))) { r = 0; goto out; } @@ -553,3 +542,37 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type) return r; } +/* + * Checks whether the specified key is revoked, returning 0 if not, + * SSH_ERR_KEY_REVOKED if it is or another error code if something + * unexpected happened. + * This will check both the key and, if it is a certificate, its CA key too. + * "revoked_keys_file" may be a KRL or a one-per-line list of public keys. + */ +int +sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file) +{ + int r; + + r = ssh_krl_file_contains_key(revoked_keys_file, key); + /* If this was not a KRL to begin with then continue below */ + if (r != SSH_ERR_KRL_BAD_MAGIC) + return r; + + /* + * If the file is not a KRL or we can't handle KRLs then attempt to + * parse the file as a flat list of keys. + */ + switch ((r = sshkey_in_file(key, revoked_keys_file, 0, 1))) { + case 0: + /* Key found => revoked */ + return SSH_ERR_KEY_REVOKED; + case SSH_ERR_KEY_NOT_FOUND: + /* Key not found => not revoked */ + return 0; + default: + /* Some other error occurred */ + return r; + } +} + diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h index 03bc3958c740..624d269f1bdb 100644 --- a/crypto/openssh/authfile.h +++ b/crypto/openssh/authfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.h,v 1.19 2014/07/03 23:18:35 djm Exp $ */ +/* $OpenBSD: authfile.h,v 1.21 2015/01/08 10:14:08 djm Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. @@ -30,9 +30,12 @@ struct sshbuf; struct sshkey; +/* XXX document these */ +/* XXX some of these could probably be merged/retired */ + int sshkey_save_private(struct sshkey *, const char *, const char *, const char *, int, const char *, int); -int sshkey_load_file(int, const char *, struct sshbuf *); +int sshkey_load_file(int, struct sshbuf *); int sshkey_load_cert(const char *, struct sshkey **); int sshkey_load_public(const char *, struct sshkey **, char **); int sshkey_load_private(const char *, const char *, struct sshkey **, char **); @@ -40,8 +43,10 @@ int sshkey_load_private_cert(int, const char *, const char *, struct sshkey **, int *); int sshkey_load_private_type(int, const char *, const char *, struct sshkey **, char **, int *); -int sshkey_load_private_pem(int, int, const char *, struct sshkey **, char **); +int sshkey_load_private_type_fd(int fd, int type, const char *passphrase, + struct sshkey **keyp, char **commentp); int sshkey_perm_ok(int, const char *); -int sshkey_in_file(struct sshkey *, const char *, int); +int sshkey_in_file(struct sshkey *, const char *, int, int); +int sshkey_check_revoked(struct sshkey *key, const char *revoked_keys_file); #endif diff --git a/crypto/openssh/bitmap.c b/crypto/openssh/bitmap.c new file mode 100644 index 000000000000..19cd2e8e3793 --- /dev/null +++ b/crypto/openssh/bitmap.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2015 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include +#include +#include + +#include "bitmap.h" + +#define BITMAP_WTYPE u_int +#define BITMAP_MAX (1<<24) +#define BITMAP_BYTES (sizeof(BITMAP_WTYPE)) +#define BITMAP_BITS (sizeof(BITMAP_WTYPE) * 8) +#define BITMAP_WMASK ((BITMAP_WTYPE)BITMAP_BITS - 1) +struct bitmap { + BITMAP_WTYPE *d; + size_t len; /* number of words allocated */ + size_t top; /* index of top word allocated */ +}; + +struct bitmap * +bitmap_new(void) +{ + struct bitmap *ret; + + if ((ret = calloc(1, sizeof(*ret))) == NULL) + return NULL; + if ((ret->d = calloc(1, BITMAP_BYTES)) == NULL) { + free(ret); + return NULL; + } + ret->len = 1; + ret->top = 0; + return ret; +} + +void +bitmap_free(struct bitmap *b) +{ + if (b != NULL && b->d != NULL) { + memset(b->d, 0, b->len); + free(b->d); + } + free(b); +} + +void +bitmap_zero(struct bitmap *b) +{ + memset(b->d, 0, b->len * BITMAP_BYTES); + b->top = 0; +} + +int +bitmap_test_bit(struct bitmap *b, u_int n) +{ + if (b->top >= b->len) + return 0; /* invalid */ + if (b->len == 0 || (n / BITMAP_BITS) > b->top) + return 0; + return (b->d[n / BITMAP_BITS] >> (n & BITMAP_WMASK)) & 1; +} + +static int +reserve(struct bitmap *b, u_int n) +{ + BITMAP_WTYPE *tmp; + size_t nlen; + + if (b->top >= b->len || n > BITMAP_MAX) + return -1; /* invalid */ + nlen = (n / BITMAP_BITS) + 1; + if (b->len < nlen) { + if ((tmp = reallocarray(b->d, nlen, BITMAP_BYTES)) == NULL) + return -1; + b->d = tmp; + memset(b->d + b->len, 0, (nlen - b->len) * BITMAP_BYTES); + b->len = nlen; + } + return 0; +} + +int +bitmap_set_bit(struct bitmap *b, u_int n) +{ + int r; + size_t offset; + + if ((r = reserve(b, n)) != 0) + return r; + offset = n / BITMAP_BITS; + if (offset > b->top) + b->top = offset; + b->d[offset] |= (BITMAP_WTYPE)1 << (n & BITMAP_WMASK); + return 0; +} + +/* Resets b->top to point to the most significant bit set in b->d */ +static void +retop(struct bitmap *b) +{ + if (b->top >= b->len) + return; + while (b->top > 0 && b->d[b->top] == 0) + b->top--; +} + +void +bitmap_clear_bit(struct bitmap *b, u_int n) +{ + size_t offset; + + if (b->top >= b->len || n > BITMAP_MAX) + return; /* invalid */ + offset = n / BITMAP_BITS; + if (offset > b->top) + return; + b->d[offset] &= ~((BITMAP_WTYPE)1 << (n & BITMAP_WMASK)); + /* The top may have changed as a result of the clear */ + retop(b); +} + +size_t +bitmap_nbits(struct bitmap *b) +{ + size_t bits; + BITMAP_WTYPE w; + + retop(b); + if (b->top >= b->len) + return 0; /* invalid */ + if (b->len == 0 || (b->top == 0 && b->d[0] == 0)) + return 0; + /* Find MSB set */ + w = b->d[b->top]; + bits = (b->top + 1) * BITMAP_BITS; + while (!(w & ((BITMAP_WTYPE)1 << (BITMAP_BITS - 1)))) { + w <<= 1; + bits--; + } + return bits; +} + +size_t +bitmap_nbytes(struct bitmap *b) +{ + return (bitmap_nbits(b) + 7) / 8; +} + +int +bitmap_to_string(struct bitmap *b, void *p, size_t l) +{ + u_char *s = (u_char *)p; + size_t i, j, k, need = bitmap_nbytes(b); + + if (l < need || b->top >= b->len) + return -1; + if (l > need) + l = need; + /* Put the bytes from LSB backwards */ + for (i = k = 0; i < b->top + 1; i++) { + for (j = 0; j < BITMAP_BYTES; j++) { + if (k >= l) + break; + s[need - 1 - k++] = (b->d[i] >> (j * 8)) & 0xff; + } + } + return 0; +} + +int +bitmap_from_string(struct bitmap *b, const void *p, size_t l) +{ + int r; + size_t i, offset, shift; + u_char *s = (u_char *)p; + + if (l > BITMAP_MAX / 8) + return -1; + if ((r = reserve(b, l * 8)) != 0) + return r; + bitmap_zero(b); + if (l == 0) + return 0; + b->top = offset = ((l + (BITMAP_BYTES - 1)) / BITMAP_BYTES) - 1; + shift = ((l + (BITMAP_BYTES - 1)) % BITMAP_BYTES) * 8; + for (i = 0; i < l; i++) { + b->d[offset] |= (BITMAP_WTYPE)s[i] << shift; + if (shift == 0) { + offset--; + shift = BITMAP_BITS - 8; + } else + shift -= 8; + } + retop(b); + return 0; +} diff --git a/crypto/openssh/bitmap.h b/crypto/openssh/bitmap.h new file mode 100644 index 000000000000..c1bb1741a4fe --- /dev/null +++ b/crypto/openssh/bitmap.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _BITMAP_H +#define _BITMAP_H + +#include + +/* Simple bit vector routines */ + +struct bitmap; + +/* Allocate a new bitmap. Returns NULL on allocation failure. */ +struct bitmap *bitmap_new(void); + +/* Free a bitmap */ +void bitmap_free(struct bitmap *b); + +/* Zero an existing bitmap */ +void bitmap_zero(struct bitmap *b); + +/* Test whether a bit is set in a bitmap. */ +int bitmap_test_bit(struct bitmap *b, u_int n); + +/* Set a bit in a bitmap. Returns 0 on success or -1 on error */ +int bitmap_set_bit(struct bitmap *b, u_int n); + +/* Clear a bit in a bitmap */ +void bitmap_clear_bit(struct bitmap *b, u_int n); + +/* Return the number of bits in a bitmap (i.e. the position of the MSB) */ +size_t bitmap_nbits(struct bitmap *b); + +/* Return the number of bytes needed to represent a bitmap */ +size_t bitmap_nbytes(struct bitmap *b); + +/* Convert a bitmap to a big endian byte string */ +int bitmap_to_string(struct bitmap *b, void *p, size_t l); + +/* Convert a big endian byte string to a bitmap */ +int bitmap_from_string(struct bitmap *b, const void *p, size_t l); + +#endif /* _BITMAP_H */ diff --git a/crypto/openssh/bufbn.c b/crypto/openssh/bufbn.c index b7f7cb122a22..33ae7f73fd9c 100644 --- a/crypto/openssh/bufbn.c +++ b/crypto/openssh/bufbn.c @@ -20,12 +20,15 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include "buffer.h" #include "log.h" #include "ssherr.h" +#ifdef WITH_SSH1 int buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) { @@ -63,6 +66,7 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value) if (buffer_get_bignum_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } +#endif /* WITH_SSH1 */ int buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) @@ -101,3 +105,5 @@ buffer_get_bignum2(Buffer *buffer, BIGNUM *value) if (buffer_get_bignum2_ret(buffer, value) == -1) fatal("%s: buffer error", __func__); } + +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h index 7043b474b4bb..28a9c98beaf7 100644 --- a/crypto/openssh/buffer.h +++ b/crypto/openssh/buffer.h @@ -48,6 +48,7 @@ int buffer_get_ret(Buffer *, void *, u_int); int buffer_consume_ret(Buffer *, u_int); int buffer_consume_end_ret(Buffer *, u_int); +#include #include void buffer_put_bignum(Buffer *, const BIGNUM *); void buffer_put_bignum2(Buffer *, const BIGNUM *); diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c index a3e3bbff80b3..223964ea3bc3 100644 --- a/crypto/openssh/canohost.c +++ b/crypto/openssh/canohost.c @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.c,v 1.71 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: canohost.c,v 1.72 2015/03/01 15:44:40 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -260,24 +260,29 @@ get_socket_address(int sock, int remote, int flags) } /* Work around Linux IPv6 weirdness */ - if (addr.ss_family == AF_INET6) + if (addr.ss_family == AF_INET6) { addrlen = sizeof(struct sockaddr_in6); + ipv64_normalise_mapped(&addr, &addrlen); + } - if (addr.ss_family == AF_UNIX) { + switch (addr.ss_family) { + case AF_INET: + case AF_INET6: + /* Get the address in ascii. */ + if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, + sizeof(ntop), NULL, 0, flags)) != 0) { + error("get_socket_address: getnameinfo %d failed: %s", + flags, ssh_gai_strerror(r)); + return NULL; + } + return xstrdup(ntop); + case AF_UNIX: /* Get the Unix domain socket path. */ return xstrdup(((struct sockaddr_un *)&addr)->sun_path); - } - - ipv64_normalise_mapped(&addr, &addrlen); - - /* Get the address in ascii. */ - if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, - sizeof(ntop), NULL, 0, flags)) != 0) { - error("get_socket_address: getnameinfo %d failed: %s", flags, - ssh_gai_strerror(r)); + default: + /* We can't look up remote Unix domain sockets. */ return NULL; } - return xstrdup(ntop); } char * @@ -390,8 +395,8 @@ get_sock_port(int sock, int local) if (from.ss_family == AF_INET6) fromlen = sizeof(struct sockaddr_in6); - /* Unix domain sockets don't have a port number. */ - if (from.ss_family == AF_UNIX) + /* Non-inet sockets don't have a port number. */ + if (from.ss_family != AF_INET && from.ss_family != AF_INET6) return 0; /* Return port number. */ diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c index b8ee7e8b02f9..ca33e9a2986b 100644 --- a/crypto/openssh/channels.c +++ b/crypto/openssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.336 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: channels.c,v 1.341 2015/02/06 23:21:59 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -43,6 +43,7 @@ __RCSID("$FreeBSD$"); #include +#include /* MIN MAX */ #include #include #include @@ -57,6 +58,9 @@ __RCSID("$FreeBSD$"); #include #include #include +#ifdef HAVE_STDINT_H +#include +#endif #include #include #include @@ -670,7 +674,7 @@ channel_open_message(void) } } buffer_append(&buffer, "\0", 1); - cp = xstrdup(buffer_ptr(&buffer)); + cp = xstrdup((char *)buffer_ptr(&buffer)); buffer_free(&buffer); return cp; } @@ -1056,7 +1060,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) len = sizeof(s4_req); if (have < len) return 0; - p = buffer_ptr(&c->input); + p = (char *)buffer_ptr(&c->input); need = 1; /* SOCKS4A uses an invalid IP address 0.0.0.x */ @@ -1086,7 +1090,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) buffer_get(&c->input, (char *)&s4_req.dest_port, 2); buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); have = buffer_len(&c->input); - p = buffer_ptr(&c->input); + p = (char *)buffer_ptr(&c->input); if (memchr(p, '\0', have) == NULL) fatal("channel %d: decode socks4: user not nul terminated", c->self); @@ -1106,7 +1110,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) c->path = xstrdup(host); } else { /* SOCKS4A: two strings */ have = buffer_len(&c->input); - p = buffer_ptr(&c->input); + p = (char *)buffer_ptr(&c->input); len = strlen(p); debug2("channel %d: decode socks4a: host %s/%d", c->self, p, len); @@ -2183,7 +2187,7 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, nfdset = howmany(n+1, NFDBITS); /* Explicitly test here, because xrealloc isn't always called */ - if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask)) + if (nfdset && SIZE_MAX / nfdset < sizeof(fd_mask)) fatal("channel_prepare_select: max_fd (%d) is too large", n); sz = nfdset * sizeof(fd_mask); @@ -2343,7 +2347,7 @@ channel_output_poll(void) /* -- protocol input */ /* ARGSUSED */ -void +int channel_input_data(int type, u_int32_t seq, void *ctxt) { int id; @@ -2360,7 +2364,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) /* Ignore any data for non-open channels (might happen on close) */ if (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_X11_OPEN) - return; + return 0; /* Get the data. */ data = packet_get_string_ptr(&data_len); @@ -2380,7 +2384,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) c->local_window -= win_len; c->local_consumed += win_len; } - return; + return 0; } if (compat20) { @@ -2391,7 +2395,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) if (win_len > c->local_window) { logit("channel %d: rcvd too much data %d, win %d", c->self, win_len, c->local_window); - return; + return 0; } c->local_window -= win_len; } @@ -2400,10 +2404,11 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) else buffer_append(&c->output, data, data_len); packet_check_eom(); + return 0; } /* ARGSUSED */ -void +int channel_input_extended_data(int type, u_int32_t seq, void *ctxt) { int id; @@ -2419,7 +2424,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt) packet_disconnect("Received extended_data for bad channel %d.", id); if (c->type != SSH_CHANNEL_OPEN) { logit("channel %d: ext data for non open", id); - return; + return 0; } if (c->flags & CHAN_EOF_RCVD) { if (datafellows & SSH_BUG_EXTEOF) @@ -2433,7 +2438,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt) c->extended_usage != CHAN_EXTENDED_WRITE || tcode != SSH2_EXTENDED_DATA_STDERR) { logit("channel %d: bad ext data", c->self); - return; + return 0; } data = packet_get_string(&data_len); packet_check_eom(); @@ -2441,16 +2446,17 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt) logit("channel %d: rcvd too much extended_data %d, win %d", c->self, data_len, c->local_window); free(data); - return; + return 0; } debug2("channel %d: rcvd ext data %d", c->self, data_len); c->local_window -= data_len; buffer_append(&c->extended, data, data_len); free(data); + return 0; } /* ARGSUSED */ -void +int channel_input_ieof(int type, u_int32_t seq, void *ctxt) { int id; @@ -2470,11 +2476,11 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt) if (buffer_len(&c->input) == 0) chan_ibuf_empty(c); } - + return 0; } /* ARGSUSED */ -void +int channel_input_close(int type, u_int32_t seq, void *ctxt) { int id; @@ -2509,11 +2515,12 @@ channel_input_close(int type, u_int32_t seq, void *ctxt) buffer_clear(&c->input); c->type = SSH_CHANNEL_OUTPUT_DRAINING; } + return 0; } /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ /* ARGSUSED */ -void +int channel_input_oclose(int type, u_int32_t seq, void *ctxt) { int id = packet_get_int(); @@ -2523,10 +2530,11 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt) if (c == NULL) packet_disconnect("Received oclose for nonexistent channel %d.", id); chan_rcvd_oclose(c); + return 0; } /* ARGSUSED */ -void +int channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) { int id = packet_get_int(); @@ -2540,10 +2548,11 @@ channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) packet_disconnect("Received close confirmation for " "non-closed channel %d (type %d).", id, c->type); channel_free(c); + return 0; } /* ARGSUSED */ -void +int channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) { int id, remote_id; @@ -2572,6 +2581,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) c->remote_window, c->remote_maxpacket); } packet_check_eom(); + return 0; } static char * @@ -2591,7 +2601,7 @@ reason2txt(int reason) } /* ARGSUSED */ -void +int channel_input_open_failure(int type, u_int32_t seq, void *ctxt) { int id, reason; @@ -2623,10 +2633,11 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt) packet_check_eom(); /* Schedule the channel for cleanup/deletion. */ chan_mark_dead(c); + return 0; } /* ARGSUSED */ -void +int channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) { Channel *c; @@ -2634,7 +2645,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) u_int adjust; if (!compat20) - return; + return 0; /* Get the channel number and verify it. */ id = packet_get_int(); @@ -2642,16 +2653,17 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) if (c == NULL) { logit("Received window adjust for non-open channel %d.", id); - return; + return 0; } adjust = packet_get_int(); packet_check_eom(); debug2("channel %d: rcvd adjust %u", id, adjust); c->remote_window += adjust; + return 0; } /* ARGSUSED */ -void +int channel_input_port_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; @@ -2679,10 +2691,11 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt) packet_send(); } else c->remote_id = remote_id; + return 0; } /* ARGSUSED */ -void +int channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) { Channel *c; @@ -2699,15 +2712,15 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) if ((c = channel_lookup(id)) == NULL) { logit("channel_input_status_confirm: %d: unknown", id); - return; + return 0; } - ; if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) - return; + return 0; cc->cb(type, c, cc->ctx); TAILQ_REMOVE(&c->status_confirms, cc, entry); explicit_bzero(cc, sizeof(*cc)); free(cc); + return 0; } /* -- tcp forwarding */ @@ -4095,7 +4108,7 @@ x11_connect_display(void) */ /* ARGSUSED */ -void +int x11_input_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; @@ -4135,11 +4148,12 @@ x11_input_open(int type, u_int32_t seq, void *ctxt) packet_put_int(c->self); } packet_send(); + return 0; } /* dummy protocol handler that denies SSH-1 requests (agent/x11) */ /* ARGSUSED */ -void +int deny_input_open(int type, u_int32_t seq, void *ctxt) { int rchan = packet_get_int(); @@ -4159,6 +4173,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt) packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_send(); + return 0; } /* diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h index c617ce7b1102..36f763a100ca 100644 --- a/crypto/openssh/channels.h +++ b/crypto/openssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.115 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: channels.h,v 1.116 2015/01/19 20:07:45 markus Exp $ */ /* $FreeBSD$ */ /* @@ -231,17 +231,17 @@ void channel_send_window_changes(void); /* protocol handler */ -void channel_input_close(int, u_int32_t, void *); -void channel_input_close_confirmation(int, u_int32_t, void *); -void channel_input_data(int, u_int32_t, void *); -void channel_input_extended_data(int, u_int32_t, void *); -void channel_input_ieof(int, u_int32_t, void *); -void channel_input_oclose(int, u_int32_t, void *); -void channel_input_open_confirmation(int, u_int32_t, void *); -void channel_input_open_failure(int, u_int32_t, void *); -void channel_input_port_open(int, u_int32_t, void *); -void channel_input_window_adjust(int, u_int32_t, void *); -void channel_input_status_confirm(int, u_int32_t, void *); +int channel_input_close(int, u_int32_t, void *); +int channel_input_close_confirmation(int, u_int32_t, void *); +int channel_input_data(int, u_int32_t, void *); +int channel_input_extended_data(int, u_int32_t, void *); +int channel_input_ieof(int, u_int32_t, void *); +int channel_input_oclose(int, u_int32_t, void *); +int channel_input_open_confirmation(int, u_int32_t, void *); +int channel_input_open_failure(int, u_int32_t, void *); +int channel_input_port_open(int, u_int32_t, void *); +int channel_input_window_adjust(int, u_int32_t, void *); +int channel_input_status_confirm(int, u_int32_t, void *); /* file descriptor handling (read/write) */ @@ -287,10 +287,10 @@ int permitopen_port(const char *); int x11_connect_display(void); int x11_create_display_inet(int, int, int, u_int *, int **); -void x11_input_open(int, u_int32_t, void *); +int x11_input_open(int, u_int32_t, void *); void x11_request_forwarding_with_spoofing(int, const char *, const char *, const char *, int); -void deny_input_open(int, u_int32_t, void *); +int deny_input_open(int, u_int32_t, void *); /* agent forwarding */ diff --git a/crypto/openssh/cipher-3des1.c b/crypto/openssh/cipher-3des1.c index 2753f9a0e147..6a0f1f37b1dd 100644 --- a/crypto/openssh/cipher-3des1.c +++ b/crypto/openssh/cipher-3des1.c @@ -1,15 +1,10 @@ -/* $OpenBSD: cipher-3des1.c,v 1.11 2014/07/02 04:59:06 djm Exp $ */ +/* $OpenBSD: cipher-3des1.c,v 1.12 2015/01/14 10:24:42 markus Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -26,13 +21,9 @@ #include "includes.h" #include - +#include #include -#include - -#include "xmalloc.h" -#include "log.h" #include "ssherr.h" /* @@ -151,7 +142,7 @@ evp_ssh1_3des(void) { static EVP_CIPHER ssh1_3des; - memset(&ssh1_3des, 0, sizeof(EVP_CIPHER)); + memset(&ssh1_3des, 0, sizeof(ssh1_3des)); ssh1_3des.nid = NID_undef; ssh1_3des.block_size = 8; ssh1_3des.iv_len = 0; diff --git a/crypto/openssh/cipher-aesctr.c b/crypto/openssh/cipher-aesctr.c index a4cf61e41e59..eed95c3e6e3c 100644 --- a/crypto/openssh/cipher-aesctr.c +++ b/crypto/openssh/cipher-aesctr.c @@ -1,6 +1,6 @@ -/* $OpenBSD: cipher-aesctr.c,v 1.1 2014/04/29 15:39:33 markus Exp $ */ +/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */ /* - * Copyright (c) 2003 Markus Friedl + * Copyright (c) 2003 Markus Friedl. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,9 +15,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "includes.h" + #include #include +#ifndef WITH_OPENSSL + #include "cipher-aesctr.h" /* @@ -25,7 +29,7 @@ * the counter is of size 'len' bytes and stored in network-byte-order. * (LSB at ctr[len-1], MSB at ctr[0]) */ -static __inline__ void +static inline void aesctr_inc(u8 *ctr, u32 len) { ssize_t i; @@ -76,3 +80,4 @@ aesctr_encrypt_bytes(aesctr_ctx *x,const u8 *m,u8 *c,u32 bytes) n = (n + 1) % AES_BLOCK_SIZE; } } +#endif /* !WITH_OPENSSL */ diff --git a/crypto/openssh/cipher-bf1.c b/crypto/openssh/cipher-bf1.c index 309509dd7806..ee72ac085504 100644 --- a/crypto/openssh/cipher-bf1.c +++ b/crypto/openssh/cipher-bf1.c @@ -1,15 +1,10 @@ -/* $OpenBSD: cipher-bf1.c,v 1.6 2010/10/01 23:05:32 djm Exp $ */ +/* $OpenBSD: cipher-bf1.c,v 1.7 2015/01/14 10:24:42 markus Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -25,15 +20,14 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL -#include +#include #include #include -#include "xmalloc.h" -#include "log.h" +#include #include "openbsd-compat/openssl-compat.h" @@ -106,3 +100,4 @@ evp_ssh1_bf(void) ssh1_bf.key_len = 32; return (&ssh1_bf); } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/cipher-chachapoly.c b/crypto/openssh/cipher-chachapoly.c index 8665b41a308d..7f31ff4ce5a1 100644 --- a/crypto/openssh/cipher-chachapoly.c +++ b/crypto/openssh/cipher-chachapoly.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: cipher-chachapoly.c,v 1.6 2014/07/03 12:42:16 jsing Exp $ */ +/* $OpenBSD: cipher-chachapoly.c,v 1.7 2015/01/14 10:24:42 markus Exp $ */ #include "includes.h" @@ -116,4 +116,3 @@ chachapoly_get_length(struct chachapoly_ctx *ctx, *plenp = PEEK_U32(buf); return 0; } - diff --git a/crypto/openssh/cipher-ctr.c b/crypto/openssh/cipher-ctr.c index ea0f9b3b7422..32771f28743b 100644 --- a/crypto/openssh/cipher-ctr.c +++ b/crypto/openssh/cipher-ctr.c @@ -16,7 +16,7 @@ */ #include "includes.h" -#ifndef OPENSSL_HAVE_EVPCTR +#if defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) #include #include @@ -143,4 +143,4 @@ evp_aes_128_ctr(void) return (&aes_ctr); } -#endif /* OPENSSL_HAVE_EVPCTR */ +#endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_HAVE_EVPCTR) */ diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c index 638ca2d971dd..02dae6f9fa1f 100644 --- a/crypto/openssh/cipher.c +++ b/crypto/openssh/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.99 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: cipher.c,v 1.100 2015/01/14 10:29:45 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -512,6 +512,8 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc) ivlen = 24; else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) ivlen = 0; + else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) + ivlen = sizeof(cc->ac_ctx.ctr); #ifdef WITH_OPENSSL else ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); @@ -532,6 +534,12 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) return SSH_ERR_INVALID_ARGUMENT; return 0; } + if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { + if (len != sizeof(cc->ac_ctx.ctr)) + return SSH_ERR_INVALID_ARGUMENT; + memcpy(iv, cc->ac_ctx.ctr, len); + return 0; + } if ((cc->cipher->flags & CFLAG_NONE) != 0) return 0; diff --git a/crypto/openssh/cipher.h b/crypto/openssh/cipher.h index de74c1e3b38d..62a88b42e643 100644 --- a/crypto/openssh/cipher.h +++ b/crypto/openssh/cipher.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.h,v 1.46 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: cipher.h,v 1.47 2015/01/14 10:24:42 markus Exp $ */ /* * Author: Tatu Ylonen @@ -72,19 +72,19 @@ struct sshcipher_ctx { const struct sshcipher *cipher; }; -typedef struct sshcipher Cipher ; -typedef struct sshcipher_ctx CipherContext ; +typedef struct sshcipher Cipher; +typedef struct sshcipher_ctx CipherContext; u_int cipher_mask_ssh1(int); const struct sshcipher *cipher_by_name(const char *); const struct sshcipher *cipher_by_number(int); int cipher_number(const char *); char *cipher_name(int); +const char *cipher_warning_message(const struct sshcipher_ctx *); int ciphers_valid(const char *); char *cipher_alg_list(char, int); int cipher_init(struct sshcipher_ctx *, const struct sshcipher *, const u_char *, u_int, const u_char *, u_int, int); -const char* cipher_warning_message(const struct sshcipher_ctx *); int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *, u_int, u_int, u_int); int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c index f5326f99da65..defb69f62bfc 100644 --- a/crypto/openssh/clientloop.c +++ b/crypto/openssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.261 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: clientloop.c,v 1.272 2015/02/25 19:54:02 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -62,9 +62,9 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* MIN MAX */ #include #include -#include #ifdef HAVE_SYS_STAT_H # include #endif @@ -86,6 +86,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -111,6 +112,8 @@ __RCSID("$FreeBSD$"); #include "match.h" #include "msg.h" #include "roaming.h" +#include "ssherr.h" +#include "hostfile.h" /* import options */ extern Options options; @@ -192,9 +195,6 @@ TAILQ_HEAD(global_confirms, global_confirm); static struct global_confirms global_confirms = TAILQ_HEAD_INITIALIZER(global_confirms); -/*XXX*/ -extern Kex *xxx_kex; - void ssh_process_session2_setup(int, int, int, Buffer *); /* Restores stdin to blocking mode. */ @@ -342,12 +342,12 @@ client_x11_get_proto(const char *display, const char *xauth_path, display = xdisplay; } if (trusted == 0) { - xauthdir = xmalloc(MAXPATHLEN); - xauthfile = xmalloc(MAXPATHLEN); - mktemp_proto(xauthdir, MAXPATHLEN); + xauthdir = xmalloc(PATH_MAX); + xauthfile = xmalloc(PATH_MAX); + mktemp_proto(xauthdir, PATH_MAX); if (mkdtemp(xauthdir) != NULL) { do_unlink = 1; - snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", + snprintf(xauthfile, PATH_MAX, "%s/xauthfile", xauthdir); snprintf(cmd, sizeof(cmd), "%s -f %s generate %s " SSH_X11_PROTO @@ -539,13 +539,13 @@ client_check_window_change(void) } } -static void +static int client_global_request_reply(int type, u_int32_t seq, void *ctxt) { struct global_confirm *gc; if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) - return; + return 0; if (gc->cb != NULL) gc->cb(type, seq, gc->ctx); if (--gc->ref_count <= 0) { @@ -555,6 +555,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt) } packet_set_alive_timeouts(0); + return 0; } static void @@ -1415,8 +1416,7 @@ client_process_output(fd_set *writeset) static void client_process_buffered_input_packets(void) { - dispatch_run(DISPATCH_NONBLOCK, &quit_pending, - compat20 ? xxx_kex : NULL); + dispatch_run(DISPATCH_NONBLOCK, &quit_pending, active_state); } /* scan buf[] for '~' before sending data to the peer */ @@ -1470,7 +1470,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { fd_set *readset = NULL, *writeset = NULL; double start_time, total_time; - int max_fd = 0, max_fd2 = 0, len, rekeying = 0; + int r, max_fd = 0, max_fd2 = 0, len, rekeying = 0; u_int64_t ibytes, obytes; u_int nalloc = 0; char buf[100]; @@ -1555,7 +1555,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) if (compat20 && session_closed && !channel_still_open()) break; - rekeying = (xxx_kex != NULL && !xxx_kex->done); + rekeying = (active_state->kex != NULL && !active_state->kex->done); if (rekeying) { debug("rekeying in progress"); @@ -1599,8 +1599,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) channel_after_select(readset, writeset); if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); - xxx_kex->done = 0; - kex_send_kexinit(xxx_kex); + active_state->kex->done = 0; + if ((r = kex_send_kexinit(active_state)) != 0) + fatal("%s: kex_send_kexinit: %s", + __func__, ssh_err(r)); need_rekeying = 0; } } @@ -1729,8 +1731,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Report bytes transferred, and transfer rates. */ total_time = get_current_time() - start_time; - packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); - packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); + packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", (unsigned long long)obytes, (unsigned long long)ibytes, total_time); if (total_time > 0) @@ -1743,7 +1744,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /*********/ -static void +static int client_input_stdout_data(int type, u_int32_t seq, void *ctxt) { u_int data_len; @@ -1752,8 +1753,9 @@ client_input_stdout_data(int type, u_int32_t seq, void *ctxt) buffer_append(&stdout_buffer, data, data_len); explicit_bzero(data, data_len); free(data); + return 0; } -static void +static int client_input_stderr_data(int type, u_int32_t seq, void *ctxt) { u_int data_len; @@ -1762,8 +1764,9 @@ client_input_stderr_data(int type, u_int32_t seq, void *ctxt) buffer_append(&stderr_buffer, data, data_len); explicit_bzero(data, data_len); free(data); + return 0; } -static void +static int client_input_exit_status(int type, u_int32_t seq, void *ctxt) { exit_status = packet_get_int(); @@ -1778,12 +1781,14 @@ client_input_exit_status(int type, u_int32_t seq, void *ctxt) packet_write_wait(); /* Flag that we want to exit. */ quit_pending = 1; + return 0; } -static void + +static int client_input_agent_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; - int remote_id, sock; + int r, remote_id, sock; /* Read the remote channel number from the message. */ remote_id = packet_get_int(); @@ -1793,7 +1798,11 @@ client_input_agent_open(int type, u_int32_t seq, void *ctxt) * Get a connection to the local authentication agent (this may again * get forwarded). */ - sock = ssh_get_authentication_socket(); + if ((r = ssh_get_authentication_socket(&sock)) != 0 && + r != SSH_ERR_AGENT_NOT_PRESENT) + debug("%s: ssh_get_authentication_socket: %s", + __func__, ssh_err(r)); + /* * If we could not connect the agent, send an error message back to @@ -1818,6 +1827,7 @@ client_input_agent_open(int type, u_int32_t seq, void *ctxt) packet_put_int(c->self); } packet_send(); + return 0; } static Channel * @@ -1911,7 +1921,7 @@ static Channel * client_request_agent(const char *request_type, int rchan) { Channel *c = NULL; - int sock; + int r, sock; if (!options.forward_agent) { error("Warning: ssh server tried agent forwarding."); @@ -1919,9 +1929,12 @@ client_request_agent(const char *request_type, int rchan) "malicious server."); return NULL; } - sock = ssh_get_authentication_socket(); - if (sock < 0) + if ((r = ssh_get_authentication_socket(&sock)) != 0) { + if (r != SSH_ERR_AGENT_NOT_PRESENT) + debug("%s: ssh_get_authentication_socket: %s", + __func__, ssh_err(r)); return NULL; + } c = channel_new("authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, @@ -1975,7 +1988,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) } /* XXXX move to generic input handler */ -static void +static int client_input_channel_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; @@ -2026,8 +2039,10 @@ client_input_channel_open(int type, u_int32_t seq, void *ctxt) packet_send(); } free(ctype); + return 0; } -static void + +static int client_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; @@ -2072,18 +2087,395 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) packet_send(); } free(rtype); + return 0; } + +struct hostkeys_update_ctx { + /* The hostname and (optionally) IP address string for the server */ + char *host_str, *ip_str; + + /* + * Keys received from the server and a flag for each indicating + * whether they already exist in known_hosts. + * keys_seen is filled in by hostkeys_find() and later (for new + * keys) by client_global_hostkeys_private_confirm(). + */ + struct sshkey **keys; + int *keys_seen; + size_t nkeys; + + size_t nnew; + + /* + * Keys that are in known_hosts, but were not present in the update + * from the server (i.e. scheduled to be deleted). + * Filled in by hostkeys_find(). + */ + struct sshkey **old_keys; + size_t nold; +}; + static void +hostkeys_update_ctx_free(struct hostkeys_update_ctx *ctx) +{ + size_t i; + + if (ctx == NULL) + return; + for (i = 0; i < ctx->nkeys; i++) + sshkey_free(ctx->keys[i]); + free(ctx->keys); + free(ctx->keys_seen); + for (i = 0; i < ctx->nold; i++) + sshkey_free(ctx->old_keys[i]); + free(ctx->old_keys); + free(ctx->host_str); + free(ctx->ip_str); + free(ctx); +} + +static int +hostkeys_find(struct hostkey_foreach_line *l, void *_ctx) +{ + struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; + size_t i; + struct sshkey **tmp; + + if (l->status != HKF_STATUS_MATCHED || l->key == NULL || + l->key->type == KEY_RSA1) + return 0; + + /* Mark off keys we've already seen for this host */ + for (i = 0; i < ctx->nkeys; i++) { + if (sshkey_equal(l->key, ctx->keys[i])) { + debug3("%s: found %s key at %s:%ld", __func__, + sshkey_ssh_name(ctx->keys[i]), l->path, l->linenum); + ctx->keys_seen[i] = 1; + return 0; + } + } + /* This line contained a key that not offered by the server */ + debug3("%s: deprecated %s key at %s:%ld", __func__, + sshkey_ssh_name(l->key), l->path, l->linenum); + if ((tmp = reallocarray(ctx->old_keys, ctx->nold + 1, + sizeof(*ctx->old_keys))) == NULL) + fatal("%s: reallocarray failed nold = %zu", + __func__, ctx->nold); + ctx->old_keys = tmp; + ctx->old_keys[ctx->nold++] = l->key; + l->key = NULL; + + return 0; +} + +static void +update_known_hosts(struct hostkeys_update_ctx *ctx) +{ + int r, was_raw = 0; + int loglevel = options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK ? + SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_VERBOSE; + char *fp, *response; + size_t i; + + for (i = 0; i < ctx->nkeys; i++) { + if (ctx->keys_seen[i] != 2) + continue; + if ((fp = sshkey_fingerprint(ctx->keys[i], + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + do_log2(loglevel, "Learned new hostkey: %s %s", + sshkey_type(ctx->keys[i]), fp); + free(fp); + } + for (i = 0; i < ctx->nold; i++) { + if ((fp = sshkey_fingerprint(ctx->old_keys[i], + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); + do_log2(loglevel, "Deprecating obsolete hostkey: %s %s", + sshkey_type(ctx->old_keys[i]), fp); + free(fp); + } + if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { + if (get_saved_tio() != NULL) { + leave_raw_mode(1); + was_raw = 1; + } + response = NULL; + for (i = 0; !quit_pending && i < 3; i++) { + free(response); + response = read_passphrase("Accept updated hostkeys? " + "(yes/no): ", RP_ECHO); + if (strcasecmp(response, "yes") == 0) + break; + else if (quit_pending || response == NULL || + strcasecmp(response, "no") == 0) { + options.update_hostkeys = 0; + break; + } else { + do_log2(loglevel, "Please enter " + "\"yes\" or \"no\""); + } + } + if (quit_pending || i >= 3 || response == NULL) + options.update_hostkeys = 0; + free(response); + if (was_raw) + enter_raw_mode(1); + } + + /* + * Now that all the keys are verified, we can go ahead and replace + * them in known_hosts (assuming SSH_UPDATE_HOSTKEYS_ASK didn't + * cancel the operation). + */ + if (options.update_hostkeys != 0 && + (r = hostfile_replace_entries(options.user_hostfiles[0], + ctx->host_str, ctx->ip_str, ctx->keys, ctx->nkeys, + options.hash_known_hosts, 0, + options.fingerprint_hash)) != 0) + error("%s: hostfile_replace_entries failed: %s", + __func__, ssh_err(r)); +} + +static void +client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx) +{ + struct ssh *ssh = active_state; /* XXX */ + struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx; + size_t i, ndone; + struct sshbuf *signdata; + int r; + const u_char *sig; + size_t siglen; + + if (ctx->nnew == 0) + fatal("%s: ctx->nnew == 0", __func__); /* sanity */ + if (type != SSH2_MSG_REQUEST_SUCCESS) { + error("Server failed to confirm ownership of " + "private host keys"); + hostkeys_update_ctx_free(ctx); + return; + } + if ((signdata = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + /* Don't want to accidentally accept an unbound signature */ + if (ssh->kex->session_id_len == 0) + fatal("%s: ssh->kex->session_id_len == 0", __func__); + /* + * Expect a signature for each of the ctx->nnew private keys we + * haven't seen before. They will be in the same order as the + * ctx->keys where the corresponding ctx->keys_seen[i] == 0. + */ + for (ndone = i = 0; i < ctx->nkeys; i++) { + if (ctx->keys_seen[i]) + continue; + /* Prepare data to be signed: session ID, unique string, key */ + sshbuf_reset(signdata); + if ( (r = sshbuf_put_cstring(signdata, + "hostkeys-prove-00@openssh.com")) != 0 || + (r = sshbuf_put_string(signdata, ssh->kex->session_id, + ssh->kex->session_id_len)) != 0 || + (r = sshkey_puts(ctx->keys[i], signdata)) != 0) + fatal("%s: failed to prepare signature: %s", + __func__, ssh_err(r)); + /* Extract and verify signature */ + if ((r = sshpkt_get_string_direct(ssh, &sig, &siglen)) != 0) { + error("%s: couldn't parse message: %s", + __func__, ssh_err(r)); + goto out; + } + if ((r = sshkey_verify(ctx->keys[i], sig, siglen, + sshbuf_ptr(signdata), sshbuf_len(signdata), 0)) != 0) { + error("%s: server gave bad signature for %s key %zu", + __func__, sshkey_type(ctx->keys[i]), i); + goto out; + } + /* Key is good. Mark it as 'seen' */ + ctx->keys_seen[i] = 2; + ndone++; + } + if (ndone != ctx->nnew) + fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__, + ndone, ctx->nnew); /* Shouldn't happen */ + ssh_packet_check_eom(ssh); + + /* Make the edits to known_hosts */ + update_known_hosts(ctx); + out: + hostkeys_update_ctx_free(ctx); +} + +/* + * Handle hostkeys-00@openssh.com global request to inform the client of all + * the server's hostkeys. The keys are checked against the user's + * HostkeyAlgorithms preference before they are accepted. + */ +static int +client_input_hostkeys(void) +{ + struct ssh *ssh = active_state; /* XXX */ + const u_char *blob = NULL; + size_t i, len = 0; + struct sshbuf *buf = NULL; + struct sshkey *key = NULL, **tmp; + int r; + char *fp; + static int hostkeys_seen = 0; /* XXX use struct ssh */ + extern struct sockaddr_storage hostaddr; /* XXX from ssh.c */ + struct hostkeys_update_ctx *ctx = NULL; + + if (hostkeys_seen) + fatal("%s: server already sent hostkeys", __func__); + if (options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK && + options.batch_mode) + return 1; /* won't ask in batchmode, so don't even try */ + if (!options.update_hostkeys || options.num_user_hostfiles <= 0) + return 1; + + ctx = xcalloc(1, sizeof(*ctx)); + while (ssh_packet_remaining(ssh) > 0) { + sshkey_free(key); + key = NULL; + if ((r = sshpkt_get_string_direct(ssh, &blob, &len)) != 0) { + error("%s: couldn't parse message: %s", + __func__, ssh_err(r)); + goto out; + } + if ((r = sshkey_from_blob(blob, len, &key)) != 0) { + error("%s: parse key: %s", __func__, ssh_err(r)); + goto out; + } + fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); + debug3("%s: received %s key %s", __func__, + sshkey_type(key), fp); + free(fp); + /* Check that the key is accepted in HostkeyAlgorithms */ + if (options.hostkeyalgorithms != NULL && + match_pattern_list(sshkey_ssh_name(key), + options.hostkeyalgorithms, + strlen(options.hostkeyalgorithms), 0) != 1) { + debug3("%s: %s key not permitted by HostkeyAlgorithms", + __func__, sshkey_ssh_name(key)); + continue; + } + /* Skip certs */ + if (sshkey_is_cert(key)) { + debug3("%s: %s key is a certificate; skipping", + __func__, sshkey_ssh_name(key)); + continue; + } + /* Ensure keys are unique */ + for (i = 0; i < ctx->nkeys; i++) { + if (sshkey_equal(key, ctx->keys[i])) { + error("%s: received duplicated %s host key", + __func__, sshkey_ssh_name(key)); + goto out; + } + } + /* Key is good, record it */ + if ((tmp = reallocarray(ctx->keys, ctx->nkeys + 1, + sizeof(*ctx->keys))) == NULL) + fatal("%s: reallocarray failed nkeys = %zu", + __func__, ctx->nkeys); + ctx->keys = tmp; + ctx->keys[ctx->nkeys++] = key; + key = NULL; + } + + if (ctx->nkeys == 0) { + debug("%s: server sent no hostkeys", __func__); + goto out; + } + + if ((ctx->keys_seen = calloc(ctx->nkeys, + sizeof(*ctx->keys_seen))) == NULL) + fatal("%s: calloc failed", __func__); + + get_hostfile_hostname_ipaddr(host, + options.check_host_ip ? (struct sockaddr *)&hostaddr : NULL, + options.port, &ctx->host_str, + options.check_host_ip ? &ctx->ip_str : NULL); + + /* Find which keys we already know about. */ + if ((r = hostkeys_foreach(options.user_hostfiles[0], hostkeys_find, + ctx, ctx->host_str, ctx->ip_str, + HKF_WANT_PARSE_KEY|HKF_WANT_MATCH)) != 0) { + error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); + goto out; + } + + /* Figure out if we have any new keys to add */ + ctx->nnew = 0; + for (i = 0; i < ctx->nkeys; i++) { + if (!ctx->keys_seen[i]) + ctx->nnew++; + } + + debug3("%s: %zu keys from server: %zu new, %zu retained. %zu to remove", + __func__, ctx->nkeys, ctx->nnew, ctx->nkeys - ctx->nnew, ctx->nold); + + if (ctx->nnew == 0 && ctx->nold != 0) { + /* We have some keys to remove. Just do it. */ + update_known_hosts(ctx); + } else if (ctx->nnew != 0) { + /* + * We have received hitherto-unseen keys from the server. + * Ask the server to confirm ownership of the private halves. + */ + debug3("%s: asking server to prove ownership for %zu keys", + __func__, ctx->nnew); + if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || + (r = sshpkt_put_cstring(ssh, + "hostkeys-prove-00@openssh.com")) != 0 || + (r = sshpkt_put_u8(ssh, 1)) != 0) /* bool: want reply */ + fatal("%s: cannot prepare packet: %s", + __func__, ssh_err(r)); + if ((buf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new", __func__); + for (i = 0; i < ctx->nkeys; i++) { + if (ctx->keys_seen[i]) + continue; + sshbuf_reset(buf); + if ((r = sshkey_putb(ctx->keys[i], buf)) != 0) + fatal("%s: sshkey_putb: %s", + __func__, ssh_err(r)); + if ((r = sshpkt_put_stringb(ssh, buf)) != 0) + fatal("%s: sshpkt_put_string: %s", + __func__, ssh_err(r)); + } + if ((r = sshpkt_send(ssh)) != 0) + fatal("%s: sshpkt_send: %s", __func__, ssh_err(r)); + client_register_global_confirm( + client_global_hostkeys_private_confirm, ctx); + ctx = NULL; /* will be freed in callback */ + } + + /* Success */ + out: + hostkeys_update_ctx_free(ctx); + sshkey_free(key); + sshbuf_free(buf); + /* + * NB. Return success for all cases. The server doesn't need to know + * what the client does with its hosts file. + */ + return 1; +} + +static int client_input_global_request(int type, u_int32_t seq, void *ctxt) { char *rtype; int want_reply; int success = 0; - rtype = packet_get_string(NULL); + rtype = packet_get_cstring(NULL); want_reply = packet_get_char(); debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply); + if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) + success = client_input_hostkeys(); if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); @@ -2091,6 +2483,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) packet_write_wait(); } free(rtype); + return 0; } void diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c index 0f8388ec7ebc..86f126032930 100644 --- a/crypto/openssh/compat.c +++ b/crypto/openssh/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.85 2014/04/20 02:49:32 djm Exp $ */ +/* $OpenBSD: compat.c,v 1.87 2015/01/19 20:20:20 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -58,7 +58,7 @@ enable_compat13(void) compat13 = 1; } /* datafellows bug compatibility */ -void +u_int compat_datafellows(const char *version) { int i; @@ -175,13 +175,14 @@ compat_datafellows(const char *version) for (i = 0; check[i].pat; i++) { if (match_pattern_list(version, check[i].pat, strlen(check[i].pat), 0) == 1) { - datafellows = check[i].bugs; debug("match: %s pat %s compat 0x%08x", - version, check[i].pat, datafellows); - return; + version, check[i].pat, check[i].bugs); + datafellows = check[i].bugs; /* XXX for now */ + return check[i].bugs; } } debug("no match: %s", version); + return 0; } #define SEP "," @@ -193,7 +194,9 @@ proto_spec(const char *spec) if (spec == NULL) return ret; - q = s = xstrdup(spec); + q = s = strdup(spec); + if (s == NULL) + return ret; for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { switch (atoi(p)) { case 1: @@ -235,7 +238,7 @@ filter_proposal(char *proposal, const char *filter) debug2("Compat: skipping algorithm \"%s\"", cp); } buffer_append(&b, "\0", 1); - fix_prop = xstrdup(buffer_ptr(&b)); + fix_prop = xstrdup((char *)buffer_ptr(&b)); buffer_free(&b); free(orig_prop); diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h index bf6c24c658a0..b8d65c238e7a 100644 --- a/crypto/openssh/compat.h +++ b/crypto/openssh/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.45 2014/04/18 23:52:25 djm Exp $ */ +/* $OpenBSD: compat.h,v 1.46 2015/01/19 20:20:20 markus Exp $ */ /* $FreeBSD$ */ /* @@ -64,7 +64,7 @@ void enable_compat13(void); void enable_compat20(void); -void compat_datafellows(const char *); +u_int compat_datafellows(const char *); int proto_spec(const char *); char *compat_cipher_proposal(char *); char *compat_pkalg_proposal(char *); diff --git a/crypto/openssh/compress.c b/crypto/openssh/compress.c deleted file mode 100644 index 24778e524b4a..000000000000 --- a/crypto/openssh/compress.c +++ /dev/null @@ -1,167 +0,0 @@ -/* $OpenBSD: compress.c,v 1.26 2010/09/08 04:13:31 deraadt Exp $ */ -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * Interface to packet compression for ssh. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ - -#include "includes.h" - -#include - -#include - -#include "log.h" -#include "buffer.h" -#include "compress.h" - -#include - -z_stream incoming_stream; -z_stream outgoing_stream; -static int compress_init_send_called = 0; -static int compress_init_recv_called = 0; -static int inflate_failed = 0; -static int deflate_failed = 0; - -/* - * Initializes compression; level is compression level from 1 to 9 - * (as in gzip). - */ - -void -buffer_compress_init_send(int level) -{ - if (compress_init_send_called == 1) - deflateEnd(&outgoing_stream); - compress_init_send_called = 1; - debug("Enabling compression at level %d.", level); - if (level < 1 || level > 9) - fatal("Bad compression level %d.", level); - deflateInit(&outgoing_stream, level); -} -void -buffer_compress_init_recv(void) -{ - if (compress_init_recv_called == 1) - inflateEnd(&incoming_stream); - compress_init_recv_called = 1; - inflateInit(&incoming_stream); -} - -/* Frees any data structures allocated for compression. */ - -void -buffer_compress_uninit(void) -{ - debug("compress outgoing: raw data %llu, compressed %llu, factor %.2f", - (unsigned long long)outgoing_stream.total_in, - (unsigned long long)outgoing_stream.total_out, - outgoing_stream.total_in == 0 ? 0.0 : - (double) outgoing_stream.total_out / outgoing_stream.total_in); - debug("compress incoming: raw data %llu, compressed %llu, factor %.2f", - (unsigned long long)incoming_stream.total_out, - (unsigned long long)incoming_stream.total_in, - incoming_stream.total_out == 0 ? 0.0 : - (double) incoming_stream.total_in / incoming_stream.total_out); - if (compress_init_recv_called == 1 && inflate_failed == 0) - inflateEnd(&incoming_stream); - if (compress_init_send_called == 1 && deflate_failed == 0) - deflateEnd(&outgoing_stream); -} - -/* - * Compresses the contents of input_buffer into output_buffer. All packets - * compressed using this function will form a single compressed data stream; - * however, data will be flushed at the end of every call so that each - * output_buffer can be decompressed independently (but in the appropriate - * order since they together form a single compression stream) by the - * receiver. This appends the compressed data to the output buffer. - */ - -void -buffer_compress(Buffer * input_buffer, Buffer * output_buffer) -{ - u_char buf[4096]; - int status; - - /* This case is not handled below. */ - if (buffer_len(input_buffer) == 0) - return; - - /* Input is the contents of the input buffer. */ - outgoing_stream.next_in = buffer_ptr(input_buffer); - outgoing_stream.avail_in = buffer_len(input_buffer); - - /* Loop compressing until deflate() returns with avail_out != 0. */ - do { - /* Set up fixed-size output buffer. */ - outgoing_stream.next_out = buf; - outgoing_stream.avail_out = sizeof(buf); - - /* Compress as much data into the buffer as possible. */ - status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); - switch (status) { - case Z_OK: - /* Append compressed data to output_buffer. */ - buffer_append(output_buffer, buf, - sizeof(buf) - outgoing_stream.avail_out); - break; - default: - deflate_failed = 1; - fatal("buffer_compress: deflate returned %d", status); - /* NOTREACHED */ - } - } while (outgoing_stream.avail_out == 0); -} - -/* - * Uncompresses the contents of input_buffer into output_buffer. All packets - * uncompressed using this function will form a single compressed data - * stream; however, data will be flushed at the end of every call so that - * each output_buffer. This must be called for the same size units that the - * buffer_compress was called, and in the same order that buffers compressed - * with that. This appends the uncompressed data to the output buffer. - */ - -void -buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) -{ - u_char buf[4096]; - int status; - - incoming_stream.next_in = buffer_ptr(input_buffer); - incoming_stream.avail_in = buffer_len(input_buffer); - - for (;;) { - /* Set up fixed-size output buffer. */ - incoming_stream.next_out = buf; - incoming_stream.avail_out = sizeof(buf); - - status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); - switch (status) { - case Z_OK: - buffer_append(output_buffer, buf, - sizeof(buf) - incoming_stream.avail_out); - break; - case Z_BUF_ERROR: - /* - * Comments in zlib.h say that we should keep calling - * inflate() until we get an error. This appears to - * be the error that we get. - */ - return; - default: - inflate_failed = 1; - fatal("buffer_uncompress: inflate returned %d", status); - /* NOTREACHED */ - } - } -} diff --git a/crypto/openssh/compress.h b/crypto/openssh/compress.h deleted file mode 100644 index 418d6fd2ca90..000000000000 --- a/crypto/openssh/compress.h +++ /dev/null @@ -1,25 +0,0 @@ -/* $OpenBSD: compress.h,v 1.12 2006/03/25 22:22:43 djm Exp $ */ - -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * Interface to packet compression for ssh. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - */ - -#ifndef COMPRESS_H -#define COMPRESS_H - -void buffer_compress_init_send(int); -void buffer_compress_init_recv(void); -void buffer_compress_uninit(void); -void buffer_compress(Buffer *, Buffer *); -void buffer_uncompress(Buffer *, Buffer *); - -#endif /* COMPRESS_H */ diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index 57f1fd66cc7f..68c5fc1d3af9 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -292,6 +292,10 @@ /* Define if your libraries define daemon() */ #define HAVE_DAEMON 1 +/* Define to 1 if you have the declaration of `AI_NUMERICSERV', and to 0 if + you don't. */ +#define HAVE_DECL_AI_NUMERICSERV 1 + /* Define to 1 if you have the declaration of `authenticate', and to 0 if you don't. */ /* #undef HAVE_DECL_AUTHENTICATE */ @@ -875,6 +879,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_READPASSPHRASE_H 1 +/* Define to 1 if you have the `reallocarray' function. */ +#define HAVE_REALLOCARRAY 1 + /* Define to 1 if you have the `realpath' function. */ #define HAVE_REALPATH 1 @@ -1471,7 +1478,7 @@ /* libcrypto is missing AES 192 and 256 bit functions */ /* #undef OPENSSL_LOBOTOMISED_AES */ -/* Define if you want OpenSSL's internally seeded PRNG only */ +/* Define if you want the OpenSSL internally seeded PRNG only */ #define OPENSSL_PRNG_ONLY 1 /* Define to the address where bug reports for this package should be sent. */ diff --git a/crypto/openssh/config.h.in b/crypto/openssh/config.h.in index 44589fd82aa5..9f02954ccb09 100644 --- a/crypto/openssh/config.h.in +++ b/crypto/openssh/config.h.in @@ -291,6 +291,10 @@ /* Define if your libraries define daemon() */ #undef HAVE_DAEMON +/* Define to 1 if you have the declaration of `AI_NUMERICSERV', and to 0 if + you don't. */ +#undef HAVE_DECL_AI_NUMERICSERV + /* Define to 1 if you have the declaration of `authenticate', and to 0 if you don't. */ #undef HAVE_DECL_AUTHENTICATE @@ -874,6 +878,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_READPASSPHRASE_H +/* Define to 1 if you have the `reallocarray' function. */ +#undef HAVE_REALLOCARRAY + /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH @@ -1470,7 +1477,7 @@ /* libcrypto is missing AES 192 and 256 bit functions */ #undef OPENSSL_LOBOTOMISED_AES -/* Define if you want OpenSSL's internally seeded PRNG only */ +/* Define if you want the OpenSSL internally seeded PRNG only */ #undef OPENSSL_PRNG_ONLY /* Define to the address where bug reports for this package should be sent. */ diff --git a/crypto/openssh/configure b/crypto/openssh/configure index c4c393c0e7ac..b352055add81 100755 --- a/crypto/openssh/configure +++ b/crypto/openssh/configure @@ -731,6 +731,8 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_largefile +with_openssl +with_ssh1 with_stackprotect with_hardening with_rpath @@ -1421,6 +1423,8 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** + --without-ssh1 Disable support for SSH protocol 1 --without-stackprotect Don't use compiler's stack protection --without-hardening Don't use toolchain hardening flags --without-rpath Disable auto-added -R linker paths @@ -1439,7 +1443,7 @@ Optional Packages: --with-ldns[=PATH] Use ldns for DNSSEC support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp --with-audit=module Enable audit support (modules=debug,bsm,linux) - --with-pie Build Position Independent Executables if possible + --with-pie Build Position Independent Executables if possible --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support @@ -5619,6 +5623,62 @@ if test "x$ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" = xyes; then : fi +openssl=yes +ssh1=yes + +# Check whether --with-openssl was given. +if test "${with_openssl+set}" = set; then : + withval=$with_openssl; if test "x$withval" = "xno" ; then + openssl=no + ssh1=no + fi + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL will be used for cryptography" >&5 +$as_echo_n "checking whether OpenSSL will be used for cryptography... " >&6; } +if test "x$openssl" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<_ACEOF +#define WITH_OPENSSL 1 +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Check whether --with-ssh1 was given. +if test "${with_ssh1+set}" = set; then : + withval=$with_ssh1; + if test "x$withval" = "xno" ; then + ssh1=no + elif test "x$openssl" = "xno" ; then + as_fn_error $? "Cannot enable SSH protocol 1 with OpenSSL disabled" "$LINENO" 5 + fi + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SSH protocol 1 support is enabled" >&5 +$as_echo_n "checking whether SSH protocol 1 support is enabled... " >&6; } +if test "x$ssh1" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<_ACEOF +#define WITH_SSH1 1 +_ACEOF + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + use_stack_protector=1 use_toolchain_hardening=1 @@ -10444,6 +10504,7 @@ for ac_func in \ prctl \ pstat \ readpassphrase \ + reallocarray \ realpath \ recvmsg \ rresvport_af \ @@ -10527,8 +10588,10 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -# PKCS#11 support requires dlopen() and co -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +# PKCS11 depends on OpenSSL. +if test "x$openssl" = "xyes" ; then + # PKCS#11 support requires dlopen() and co + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 @@ -10587,6 +10650,7 @@ $as_echo "#define ENABLE_PKCS11 /**/" >>confdefs.h fi +fi # IRIX has a const char return value for gai_strerror() for ac_func in gai_strerror @@ -11731,6 +11795,23 @@ fi fi +if test "x$ac_cv_func_getaddrinfo" = "xyes"; then + ac_fn_c_check_decl "$LINENO" "AI_NUMERICSERV" "ac_cv_have_decl_AI_NUMERICSERV" "#include + #include + #include +" +if test "x$ac_cv_have_decl_AI_NUMERICSERV" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_AI_NUMERICSERV $ac_have_decl +_ACEOF + +fi + if test "x$check_for_conflicting_getspnam" = "x1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for conflicting getspnam in shadow.h" >&5 $as_echo_n "checking for conflicting getspnam in shadow.h... " >&6; } @@ -11804,6 +11885,9 @@ saved_LDFLAGS="$LDFLAGS" # Check whether --with-ssl-dir was given. if test "${with_ssl_dir+set}" = set; then : withval=$with_ssl_dir; + if test "x$openssl" = "xno" ; then + as_fn_error $? "cannot use --with-ssl-dir when OpenSSL disabled" "$LINENO" 5 + fi if test "x$withval" != "xno" ; then case "$withval" in # Relative paths @@ -11838,8 +11922,38 @@ if test "${with_ssl_dir+set}" = set; then : fi -LIBS="-lcrypto $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + +# Check whether --with-openssl-header-check was given. +if test "${with_openssl_header_check+set}" = set; then : + withval=$with_openssl_header_check; + if test "x$withval" = "xno" ; then + openssl_check_nonfatal=1 + fi + + +fi + + +openssl_engine=no + +# Check whether --with-ssl-engine was given. +if test "${with_ssl_engine+set}" = set; then : + withval=$with_ssl_engine; + if test "x$openssl" = "xno" ; then + as_fn_error $? "cannot use --with-ssl-engine when OpenSSL disabled" "$LINENO" 5 + fi + if test "x$withval" != "xno" ; then + openssl_engine=yes + fi + + +fi + + +if test "x$openssl" = "xyes" ; then + LIBS="-lcrypto $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -11863,13 +11977,13 @@ $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h else - if test -n "${need_dash_r}"; then - LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" - else - LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" - fi - CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" - ac_fn_c_check_header_mongrel "$LINENO" "openssl/opensslv.h" "ac_cv_header_openssl_opensslv_h" "$ac_includes_default" + if test -n "${need_dash_r}"; then + LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" + else + LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" + fi + CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" + ac_fn_c_check_header_mongrel "$LINENO" "openssl/opensslv.h" "ac_cv_header_openssl_opensslv_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_opensslv_h" = xyes; then : else @@ -11877,7 +11991,7 @@ else fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. @@ -11900,7 +12014,7 @@ if ac_fn_c_try_link "$LINENO"; then : else - as_fn_error $? "*** Can't find recent OpenSSL libcrypto (see config.log for details) ***" "$LINENO" 5 + as_fn_error $? "*** Can't find recent OpenSSL libcrypto (see config.log for details) ***" "$LINENO" 5 fi @@ -11912,12 +12026,12 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -# Determine OpenSSL header version -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL header version" >&5 + # Determine OpenSSL header version + { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL header version" >&5 $as_echo_n "checking OpenSSL header version... " >&6; } -if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} @@ -11925,26 +12039,26 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#define DATA "conftest.sslincver" + #include + #include + #include + #define DATA "conftest.sslincver" int main () { - FILE *fd; - int rc; + FILE *fd; + int rc; - fd = fopen(DATA,"w"); - if(fd == NULL) - exit(1); + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); - if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) - exit(1); + if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) + exit(1); - exit(0); + exit(0); ; return 0; @@ -11952,15 +12066,15 @@ main () _ACEOF if ac_fn_c_try_run "$LINENO"; then : - ssl_header_ver=`cat conftest.sslincver` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_header_ver" >&5 + ssl_header_ver=`cat conftest.sslincver` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_header_ver" >&5 $as_echo "$ssl_header_ver" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } - as_fn_error $? "OpenSSL version header not found." "$LINENO" 5 + as_fn_error $? "OpenSSL version header not found." "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -11968,12 +12082,12 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi -# Determine OpenSSL library version -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL library version" >&5 + # Determine OpenSSL library version + { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL library version" >&5 $as_echo_n "checking OpenSSL library version... " >&6; } -if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} @@ -11981,28 +12095,28 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include -#define DATA "conftest.ssllibver" + #include + #include + #include + #include + #define DATA "conftest.ssllibver" int main () { - FILE *fd; - int rc; + FILE *fd; + int rc; - fd = fopen(DATA,"w"); - if(fd == NULL) - exit(1); + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); - if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), - SSLeay_version(SSLEAY_VERSION))) <0) - exit(1); + if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), + SSLeay_version(SSLEAY_VERSION))) <0) + exit(1); - exit(0); + exit(0); ; return 0; @@ -12010,22 +12124,22 @@ main () _ACEOF if ac_fn_c_try_run "$LINENO"; then : - ssl_library_ver=`cat conftest.ssllibver` - # Check version is supported. - case "$ssl_library_ver" in - 0090[0-7]*|009080[0-5]*) - as_fn_error $? "OpenSSL >= 0.9.8f required" "$LINENO" 5 - ;; - *) ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5 + ssl_library_ver=`cat conftest.ssllibver` + # Check version is supported. + case "$ssl_library_ver" in + 0090[0-7]*|009080[0-5]*) + as_fn_error $? "OpenSSL >= 0.9.8f required (have \"$ssl_library_ver\")" "$LINENO" 5 + ;; + *) ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5 $as_echo "$ssl_library_ver" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } - as_fn_error $? "OpenSSL library not found." "$LINENO" 5 + as_fn_error $? "OpenSSL library not found." "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -12033,35 +12147,12 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi -# XXX make --without-openssl work - -cat >>confdefs.h <<_ACEOF -#define WITH_OPENSSL 1 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define WITH_SSH1 1 -_ACEOF - - - -# Check whether --with-openssl-header-check was given. -if test "${with_openssl_header_check+set}" = set; then : - withval=$with_openssl_header_check; if test "x$withval" = "xno" ; then - openssl_check_nonfatal=1 - fi - - -fi - - -# Sanity check OpenSSL headers -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL's headers match the library" >&5 + # Sanity check OpenSSL headers + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL's headers match the library" >&5 $as_echo_n "checking whether OpenSSL's headers match the library... " >&6; } -if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} @@ -12069,14 +12160,14 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include + #include + #include int main () { - exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); + exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); ; return 0; @@ -12084,28 +12175,28 @@ main () _ACEOF if ac_fn_c_try_run "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - if test "x$openssl_check_nonfatal" = "x"; then - as_fn_error $? "Your OpenSSL headers do not match your -library. Check config.log for details. -If you are sure your installation is consistent, you can disable the check -by running \"./configure --without-openssl-header-check\". -Also see contrib/findssl.sh for help identifying header/library mismatches. -" "$LINENO" 5 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your OpenSSL headers do not match your -library. Check config.log for details. -Also see contrib/findssl.sh for help identifying header/library mismatches." >&5 + if test "x$openssl_check_nonfatal" = "x"; then + as_fn_error $? "Your OpenSSL headers do not match your + library. Check config.log for details. + If you are sure your installation is consistent, you can disable the check + by running \"./configure --without-openssl-header-check\". + Also see contrib/findssl.sh for help identifying header/library mismatches. + " "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your OpenSSL headers do not match your + library. Check config.log for details. + Also see contrib/findssl.sh for help identifying header/library mismatches." >&5 $as_echo "$as_me: WARNING: Your OpenSSL headers do not match your -library. Check config.log for details. -Also see contrib/findssl.sh for help identifying header/library mismatches." >&2;} - fi + library. Check config.log for details. + Also see contrib/findssl.sh for help identifying header/library mismatches." >&2;} + fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -12113,9 +12204,9 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if programs using OpenSSL functions will link" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if programs using OpenSSL functions will link" >&5 $as_echo_n "checking if programs using OpenSSL functions will link... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -12128,18 +12219,18 @@ main () _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - saved_LIBS="$LIBS" - LIBS="$LIBS -ldl" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if programs using OpenSSL need -ldl" >&5 + saved_LIBS="$LIBS" + LIBS="$LIBS -ldl" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if programs using OpenSSL need -ldl" >&5 $as_echo_n "checking if programs using OpenSSL need -ldl... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -12152,14 +12243,14 @@ main () _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - LIBS="$saved_LIBS" + LIBS="$saved_LIBS" fi @@ -12171,17 +12262,17 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -for ac_func in \ - BN_is_prime_ex \ - DSA_generate_parameters_ex \ - EVP_DigestInit_ex \ - EVP_DigestFinal_ex \ - EVP_MD_CTX_init \ - EVP_MD_CTX_cleanup \ - EVP_MD_CTX_copy_ex \ - HMAC_CTX_init \ - RSA_generate_key_ex \ - RSA_get_default_method \ + for ac_func in \ + BN_is_prime_ex \ + DSA_generate_parameters_ex \ + EVP_DigestInit_ex \ + EVP_DigestFinal_ex \ + EVP_MD_CTX_init \ + EVP_MD_CTX_cleanup \ + EVP_MD_CTX_copy_ex \ + HMAC_CTX_init \ + RSA_generate_key_ex \ + RSA_get_default_method \ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -12195,23 +12286,20 @@ fi done - -# Check whether --with-ssl-engine was given. -if test "${with_ssl_engine+set}" = set; then : - withval=$with_ssl_engine; if test "x$withval" != "xno" ; then + if test "x$openssl_engine" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL ENGINE support" >&5 $as_echo_n "checking for OpenSSL ENGINE support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + #include int main () { - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); ; return 0; @@ -12229,25 +12317,22 @@ else fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi + fi -fi - - -# Check for OpenSSL without EVP_aes_{192,256}_cbc -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has crippled AES support" >&5 + # Check for OpenSSL without EVP_aes_{192,256}_cbc + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has crippled AES support" >&5 $as_echo_n "checking whether OpenSSL has crippled AES support... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include + #include + #include int main () { - exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); + exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); ; return 0; @@ -12255,12 +12340,12 @@ main () _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define OPENSSL_LOBOTOMISED_AES 1" >>confdefs.h @@ -12271,22 +12356,22 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -# Check for OpenSSL with EVP_aes_*ctr -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has AES CTR via EVP" >&5 + # Check for OpenSSL with EVP_aes_*ctr + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has AES CTR via EVP" >&5 $as_echo_n "checking whether OpenSSL has AES CTR via EVP... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include + #include + #include int main () { - exit(EVP_aes_128_ctr() == NULL || - EVP_aes_192_cbc() == NULL || - EVP_aes_256_cbc() == NULL); + exit(EVP_aes_128_ctr() == NULL || + EVP_aes_192_cbc() == NULL || + EVP_aes_256_cbc() == NULL); ; return 0; @@ -12294,7 +12379,7 @@ main () _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define OPENSSL_HAVE_EVPCTR 1" >>confdefs.h @@ -12302,7 +12387,7 @@ $as_echo "#define OPENSSL_HAVE_EVPCTR 1" >>confdefs.h else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -12310,26 +12395,26 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -# Check for OpenSSL with EVP_aes_*gcm -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has AES GCM via EVP" >&5 + # Check for OpenSSL with EVP_aes_*gcm + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has AES GCM via EVP" >&5 $as_echo_n "checking whether OpenSSL has AES GCM via EVP... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include + #include + #include int main () { - exit(EVP_aes_128_gcm() == NULL || - EVP_aes_256_gcm() == NULL || - EVP_CTRL_GCM_SET_IV_FIXED == 0 || - EVP_CTRL_GCM_IV_GEN == 0 || - EVP_CTRL_GCM_SET_TAG == 0 || - EVP_CTRL_GCM_GET_TAG == 0 || - EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); + exit(EVP_aes_128_gcm() == NULL || + EVP_aes_256_gcm() == NULL || + EVP_CTRL_GCM_SET_IV_FIXED == 0 || + EVP_CTRL_GCM_IV_GEN == 0 || + EVP_CTRL_GCM_SET_TAG == 0 || + EVP_CTRL_GCM_GET_TAG == 0 || + EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); ; return 0; @@ -12337,7 +12422,7 @@ main () _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define OPENSSL_HAVE_EVPGCM 1" >>confdefs.h @@ -12345,17 +12430,17 @@ $as_echo "#define OPENSSL_HAVE_EVPGCM 1" >>confdefs.h else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - unsupported_algorithms="$unsupported_cipers \ - aes128-gcm@openssh.com aes256-gcm@openssh.com" + unsupported_algorithms="$unsupported_cipers \ + aes128-gcm@openssh.com aes256-gcm@openssh.com" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_CIPHER_CTX_ctrl" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_CIPHER_CTX_ctrl" >&5 $as_echo_n "checking for library containing EVP_CIPHER_CTX_ctrl... " >&6; } if ${ac_cv_search_EVP_CIPHER_CTX_ctrl+:} false; then : $as_echo_n "(cached) " >&6 @@ -12414,20 +12499,20 @@ $as_echo "#define HAVE_EVP_CIPHER_CTX_CTRL 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if EVP_DigestUpdate returns an int" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if EVP_DigestUpdate returns an int" >&5 $as_echo_n "checking if EVP_DigestUpdate returns an int... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include + #include + #include int main () { - if(EVP_DigestUpdate(NULL, NULL,0)) - exit(0); + if(EVP_DigestUpdate(NULL, NULL,0)) + exit(0); ; return 0; @@ -12435,12 +12520,12 @@ main () _ACEOF if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define OPENSSL_EVP_DIGESTUPDATE_VOID 1" >>confdefs.h @@ -12451,10 +12536,10 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -# Some systems want crypt() from libcrypt, *not* the version in OpenSSL, -# because the system crypt() is more featureful. -if test "x$check_for_libcrypt_before" = "x1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 + # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, + # because the system crypt() is more featureful. + if test "x$check_for_libcrypt_before" = "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : $as_echo_n "(cached) " >&6 @@ -12499,11 +12584,304 @@ _ACEOF fi + fi + + # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the + # version in OpenSSL. + if test "x$check_for_libcrypt_later" = "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 +$as_echo_n "checking for crypt in -lcrypt... " >&6; } +if ${ac_cv_lib_crypt_crypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char crypt (); +int +main () +{ +return crypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypt_crypt=yes +else + ac_cv_lib_crypt_crypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 +$as_echo "$ac_cv_lib_crypt_crypt" >&6; } +if test "x$ac_cv_lib_crypt_crypt" = xyes; then : + LIBS="$LIBS -lcrypt" fi -# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the -# version in OpenSSL. -if test "x$check_for_libcrypt_later" = "x1"; then + fi + for ac_func in crypt DES_crypt +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + # Search for SHA256 support in libc and/or OpenSSL + for ac_func in SHA256_Update EVP_sha256 +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + unsupported_algorithms="$unsupported_algorithms \ + hmac-sha2-256 hmac-sha2-512 \ + diffie-hellman-group-exchange-sha256 \ + hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" + + +fi +done + + # Search for RIPE-MD support in OpenSSL + for ac_func in EVP_ripemd160 +do : + ac_fn_c_check_func "$LINENO" "EVP_ripemd160" "ac_cv_func_EVP_ripemd160" +if test "x$ac_cv_func_EVP_ripemd160" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_EVP_RIPEMD160 1 +_ACEOF + +else + unsupported_algorithms="$unsupported_algorithms \ + hmac-ripemd160 + hmac-ripemd160@openssh.com + hmac-ripemd160-etm@openssh.com" + + +fi +done + + + # Check complete ECC support in OpenSSL + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_X9_62_prime256v1" >&5 +$as_echo_n "checking whether OpenSSL has NID_X9_62_prime256v1... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + const EVP_MD *m = EVP_sha256(); /* We need this too */ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_nistp256=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp384r1" >&5 +$as_echo_n "checking whether OpenSSL has NID_secp384r1... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); + const EVP_MD *m = EVP_sha384(); /* We need this too */ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_nistp384=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp521r1" >&5 +$as_echo_n "checking whether OpenSSL has NID_secp521r1... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenSSL's NID_secp521r1 is functional" >&5 +$as_echo_n "checking if OpenSSL's NID_secp521r1 is functional... " >&6; } + if test "$cross_compiling" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross-compiling: assuming yes" >&5 +$as_echo "$as_me: WARNING: cross-compiling: assuming yes" >&2;} + enable_nistp521=1 + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include + #include + #include + +int +main () +{ + + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + exit(e == NULL || m == NULL); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + enable_nistp521=1 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + COMMENT_OUT_ECC="#no ecc#" + TEST_SSH_ECC=no + + if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ + test x$enable_nistp521 = x1; then + +$as_echo "#define OPENSSL_HAS_ECC 1" >>confdefs.h + + fi + if test x$enable_nistp256 = x1; then + +$as_echo "#define OPENSSL_HAS_NISTP256 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ + ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" + fi + if test x$enable_nistp384 = x1; then + +$as_echo "#define OPENSSL_HAS_NISTP384 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ + ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" + fi + if test x$enable_nistp521 = x1; then + +$as_echo "#define OPENSSL_HAS_NISTP521 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ + ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" + fi + + + +else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : @@ -12544,258 +12922,18 @@ if test "x$ac_cv_lib_crypt_crypt" = xyes; then : LIBS="$LIBS -lcrypt" fi -fi -for ac_func in crypt DES_crypt + for ac_func in crypt do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt" +if test "x$ac_cv_func_crypt" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define HAVE_CRYPT 1 _ACEOF fi done - -# Search for SHA256 support in libc and/or OpenSSL -for ac_func in SHA256_Update EVP_sha256 -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - unsupported_algorithms="$unsupported_algorithms \ - hmac-sha2-256 hmac-sha2-512 \ - diffie-hellman-group-exchange-sha256 \ - hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" - - fi -done - -# Search for RIPE-MD support in OpenSSL -for ac_func in EVP_ripemd160 -do : - ac_fn_c_check_func "$LINENO" "EVP_ripemd160" "ac_cv_func_EVP_ripemd160" -if test "x$ac_cv_func_EVP_ripemd160" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EVP_RIPEMD160 1 -_ACEOF - -else - unsupported_algorithms="$unsupported_algorithms \ - hmac-ripemd160 - hmac-ripemd160@openssh.com - hmac-ripemd160-etm@openssh.com" - - -fi -done - - -# Check complete ECC support in OpenSSL -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_X9_62_prime256v1" >&5 -$as_echo_n "checking whether OpenSSL has NID_X9_62_prime256v1... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - -int -main () -{ - - EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - const EVP_MD *m = EVP_sha256(); /* We need this too */ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - enable_nistp256=1 -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp384r1" >&5 -$as_echo_n "checking whether OpenSSL has NID_secp384r1... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - -int -main () -{ - - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); - const EVP_MD *m = EVP_sha384(); /* We need this too */ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - enable_nistp384=1 -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp521r1" >&5 -$as_echo_n "checking whether OpenSSL has NID_secp521r1... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - -int -main () -{ - - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); - const EVP_MD *m = EVP_sha512(); /* We need this too */ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenSSL's NID_secp521r1 is functional" >&5 -$as_echo_n "checking if OpenSSL's NID_secp521r1 is functional... " >&6; } - if test "$cross_compiling" = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross-compiling: assuming yes" >&5 -$as_echo "$as_me: WARNING: cross-compiling: assuming yes" >&2;} - enable_nistp521=1 - -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include -#include -#include - -int -main () -{ - - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); - const EVP_MD *m = EVP_sha512(); /* We need this too */ - exit(e == NULL || m == NULL); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - enable_nistp521=1 -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -COMMENT_OUT_ECC="#no ecc#" -TEST_SSH_ECC=no - -if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ - test x$enable_nistp521 = x1; then - -$as_echo "#define OPENSSL_HAS_ECC 1" >>confdefs.h - -fi -if test x$enable_nistp256 = x1; then - -$as_echo "#define OPENSSL_HAS_NISTP256 1" >>confdefs.h - - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ - ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" -fi -if test x$enable_nistp384 = x1; then - -$as_echo "#define OPENSSL_HAS_NISTP384 1" >>confdefs.h - - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ - ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" -fi -if test x$enable_nistp521 = x1; then - -$as_echo "#define OPENSSL_HAS_NISTP521 1" >>confdefs.h - - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ - ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" -fi - - - for ac_func in \ arc4random \ @@ -12878,29 +13016,30 @@ LIBS="$saved_LIBS" ### Configure cryptographic random number support # Check wheter OpenSSL seeds itself -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL's PRNG is internally seeded" >&5 +if test "x$openssl" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL's PRNG is internally seeded" >&5 $as_echo_n "checking whether OpenSSL's PRNG is internally seeded... " >&6; } -if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} - # This is safe, since we will fatal() at runtime if - # OpenSSL is not seeded correctly. - OPENSSL_SEEDS_ITSELF=yes + # This is safe, since we will fatal() at runtime if + # OpenSSL is not seeded correctly. + OPENSSL_SEEDS_ITSELF=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include + #include + #include int main () { - exit(RAND_status() == 1 ? 0 : 1); + exit(RAND_status() == 1 ? 0 : 1); ; return 0; @@ -12908,13 +13047,13 @@ main () _ACEOF if ac_fn_c_try_run "$LINENO"; then : - OPENSSL_SEEDS_ITSELF=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + OPENSSL_SEEDS_ITSELF=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi @@ -12922,6 +13061,7 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi +fi # PRNGD TCP socket @@ -13026,6 +13166,9 @@ elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then $as_echo "#define OPENSSL_PRNG_ONLY 1" >>confdefs.h RAND_MSG="OpenSSL internal ONLY" +elif test "x$openssl" = "xno" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible" >&5 +$as_echo "$as_me: WARNING: OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible" >&2;} else as_fn_error $? "OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options" "$LINENO" 5 fi diff --git a/crypto/openssh/configure.ac b/crypto/openssh/configure.ac index b7a89cf6d9d0..e1b800320720 100644 --- a/crypto/openssh/configure.ac +++ b/crypto/openssh/configure.ac @@ -121,6 +121,42 @@ AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [ #include ]) +openssl=yes +ssh1=yes +AC_ARG_WITH([openssl], + [ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ], + [ if test "x$withval" = "xno" ; then + openssl=no + ssh1=no + fi + ] +) +AC_MSG_CHECKING([whether OpenSSL will be used for cryptography]) +if test "x$openssl" = "xyes" ; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography]) +else + AC_MSG_RESULT([no]) +fi + +AC_ARG_WITH([ssh1], + [ --without-ssh1 Disable support for SSH protocol 1], + [ + if test "x$withval" = "xno" ; then + ssh1=no + elif test "x$openssl" = "xno" ; then + AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled]) + fi + ] +) +AC_MSG_CHECKING([whether SSH protocol 1 support is enabled]) +if test "x$ssh1" = "xyes" ; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED([WITH_SSH1], [1], [include SSH protocol version 1 support]) +else + AC_MSG_RESULT([no]) +fi + use_stack_protector=1 use_toolchain_hardening=1 AC_ARG_WITH([stackprotect], @@ -1302,7 +1338,7 @@ g.gl_statv = NULL; AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) - + ]) AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include ]) @@ -1585,7 +1621,7 @@ AC_ARG_WITH([audit], ) AC_ARG_WITH([pie], - [ --with-pie Build Position Independent Executables if possible], [ + [ --with-pie Build Position Independent Executables if possible], [ if test "x$withval" = "xno"; then use_pie=no fi @@ -1691,6 +1727,7 @@ AC_CHECK_FUNCS([ \ prctl \ pstat \ readpassphrase \ + reallocarray \ realpath \ recvmsg \ rresvport_af \ @@ -1750,10 +1787,13 @@ AC_LINK_IFELSE( [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) -# PKCS#11 support requires dlopen() and co -AC_SEARCH_LIBS([dlopen], [dl], - [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])] -) +# PKCS11 depends on OpenSSL. +if test "x$openssl" = "xyes" ; then + # PKCS#11 support requires dlopen() and co + AC_SEARCH_LIBS([dlopen], [dl], + [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])] + ) +fi # IRIX has a const char return value for gai_strerror() AC_CHECK_FUNCS([gai_strerror], [ @@ -2219,6 +2259,13 @@ if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ ) fi +if test "x$ac_cv_func_getaddrinfo" = "xyes"; then + AC_CHECK_DECLS(AI_NUMERICSERV, , , + [#include + #include + #include ]) +fi + if test "x$check_for_conflicting_getspnam" = "x1"; then AC_MSG_CHECKING([for conflicting getspnam in shadow.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], @@ -2242,6 +2289,9 @@ saved_LDFLAGS="$LDFLAGS" AC_ARG_WITH([ssl-dir], [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], [ + if test "x$openssl" = "xno" ; then + AC_MSG_ERROR([cannot use --with-ssl-dir when OpenSSL disabled]) + fi if test "x$withval" != "xno" ; then case "$withval" in # Relative paths @@ -2274,444 +2324,457 @@ AC_ARG_WITH([ssl-dir], fi ] ) -LIBS="-lcrypto $LIBS" -AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1], - [Define if your ssl headers are included - with #include ])], - [ - dnl Check default openssl install dir - if test -n "${need_dash_r}"; then - LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" - else - LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" - fi - CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" - AC_CHECK_HEADER([openssl/opensslv.h], , - [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])]) - AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])], - [ - AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***]) - ] - ) - ] -) - -# Determine OpenSSL header version -AC_MSG_CHECKING([OpenSSL header version]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#define DATA "conftest.sslincver" - ]], [[ - FILE *fd; - int rc; - - fd = fopen(DATA,"w"); - if(fd == NULL) - exit(1); - - if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) - exit(1); - - exit(0); - ]])], - [ - ssl_header_ver=`cat conftest.sslincver` - AC_MSG_RESULT([$ssl_header_ver]) - ], - [ - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([OpenSSL version header not found.]) - ], - [ - AC_MSG_WARN([cross compiling: not checking]) - ] -) - -# Determine OpenSSL library version -AC_MSG_CHECKING([OpenSSL library version]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#define DATA "conftest.ssllibver" - ]], [[ - FILE *fd; - int rc; - - fd = fopen(DATA,"w"); - if(fd == NULL) - exit(1); - - if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), - SSLeay_version(SSLEAY_VERSION))) <0) - exit(1); - - exit(0); - ]])], - [ - ssl_library_ver=`cat conftest.ssllibver` - # Check version is supported. - case "$ssl_library_ver" in - 0090[[0-7]]*|009080[[0-5]]*) - AC_MSG_ERROR([OpenSSL >= 0.9.8f required]) - ;; - *) ;; - esac - AC_MSG_RESULT([$ssl_library_ver]) - ], - [ - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([OpenSSL library not found.]) - ], - [ - AC_MSG_WARN([cross compiling: not checking]) - ] -) - -# XXX make --without-openssl work -AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography]) -AC_DEFINE_UNQUOTED([WITH_SSH1], [1], [include SSH protocol version 1 support]) AC_ARG_WITH([openssl-header-check], [ --without-openssl-header-check Disable OpenSSL version consistency check], - [ if test "x$withval" = "xno" ; then - openssl_check_nonfatal=1 - fi - ] -) - -# Sanity check OpenSSL headers -AC_MSG_CHECKING([whether OpenSSL's headers match the library]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); - ]])], [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - if test "x$openssl_check_nonfatal" = "x"; then - AC_MSG_ERROR([Your OpenSSL headers do not match your -library. Check config.log for details. -If you are sure your installation is consistent, you can disable the check -by running "./configure --without-openssl-header-check". -Also see contrib/findssl.sh for help identifying header/library mismatches. -]) - else - AC_MSG_WARN([Your OpenSSL headers do not match your -library. Check config.log for details. -Also see contrib/findssl.sh for help identifying header/library mismatches.]) + if test "x$withval" = "xno" ; then + openssl_check_nonfatal=1 fi - ], - [ - AC_MSG_WARN([cross compiling: not checking]) ] ) -AC_MSG_CHECKING([if programs using OpenSSL functions will link]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ #include ]], - [[ SSLeay_add_all_algorithms(); ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - saved_LIBS="$LIBS" - LIBS="$LIBS -ldl" - AC_MSG_CHECKING([if programs using OpenSSL need -ldl]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ #include ]], - [[ SSLeay_add_all_algorithms(); ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - LIBS="$saved_LIBS" - ] - ) - ] -) - -AC_CHECK_FUNCS([ \ - BN_is_prime_ex \ - DSA_generate_parameters_ex \ - EVP_DigestInit_ex \ - EVP_DigestFinal_ex \ - EVP_MD_CTX_init \ - EVP_MD_CTX_cleanup \ - EVP_MD_CTX_copy_ex \ - HMAC_CTX_init \ - RSA_generate_key_ex \ - RSA_get_default_method \ -]) - +openssl_engine=no AC_ARG_WITH([ssl-engine], [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], - [ if test "x$withval" != "xno" ; then + [ + if test "x$openssl" = "xno" ; then + AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled]) + fi + if test "x$withval" != "xno" ; then + openssl_engine=yes + fi + ] +) + +if test "x$openssl" = "xyes" ; then + LIBS="-lcrypto $LIBS" + AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1], + [Define if your ssl headers are included + with #include ])], + [ + dnl Check default openssl install dir + if test -n "${need_dash_r}"; then + LDFLAGS="-L/usr/local/ssl/lib -R/usr/local/ssl/lib ${saved_LDFLAGS}" + else + LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}" + fi + CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}" + AC_CHECK_HEADER([openssl/opensslv.h], , + [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])]) + AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL])], + [ + AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***]) + ] + ) + ] + ) + + # Determine OpenSSL header version + AC_MSG_CHECKING([OpenSSL header version]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #define DATA "conftest.sslincver" + ]], [[ + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) + exit(1); + + exit(0); + ]])], + [ + ssl_header_ver=`cat conftest.sslincver` + AC_MSG_RESULT([$ssl_header_ver]) + ], + [ + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([OpenSSL version header not found.]) + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) + + # Determine OpenSSL library version + AC_MSG_CHECKING([OpenSSL library version]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #define DATA "conftest.ssllibver" + ]], [[ + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%08x (%s)\n", SSLeay(), + SSLeay_version(SSLEAY_VERSION))) <0) + exit(1); + + exit(0); + ]])], + [ + ssl_library_ver=`cat conftest.ssllibver` + # Check version is supported. + case "$ssl_library_ver" in + 0090[[0-7]]*|009080[[0-5]]*) + AC_MSG_ERROR([OpenSSL >= 0.9.8f required (have "$ssl_library_ver")]) + ;; + *) ;; + esac + AC_MSG_RESULT([$ssl_library_ver]) + ], + [ + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([OpenSSL library not found.]) + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) + + # Sanity check OpenSSL headers + AC_MSG_CHECKING([whether OpenSSL's headers match the library]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); + ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + if test "x$openssl_check_nonfatal" = "x"; then + AC_MSG_ERROR([Your OpenSSL headers do not match your + library. Check config.log for details. + If you are sure your installation is consistent, you can disable the check + by running "./configure --without-openssl-header-check". + Also see contrib/findssl.sh for help identifying header/library mismatches. + ]) + else + AC_MSG_WARN([Your OpenSSL headers do not match your + library. Check config.log for details. + Also see contrib/findssl.sh for help identifying header/library mismatches.]) + fi + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) + + AC_MSG_CHECKING([if programs using OpenSSL functions will link]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #include ]], + [[ SSLeay_add_all_algorithms(); ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + saved_LIBS="$LIBS" + LIBS="$LIBS -ldl" + AC_MSG_CHECKING([if programs using OpenSSL need -ldl]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #include ]], + [[ SSLeay_add_all_algorithms(); ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + LIBS="$saved_LIBS" + ] + ) + ] + ) + + AC_CHECK_FUNCS([ \ + BN_is_prime_ex \ + DSA_generate_parameters_ex \ + EVP_DigestInit_ex \ + EVP_DigestFinal_ex \ + EVP_MD_CTX_init \ + EVP_MD_CTX_cleanup \ + EVP_MD_CTX_copy_ex \ + HMAC_CTX_init \ + RSA_generate_key_ex \ + RSA_get_default_method \ + ]) + + if test "x$openssl_engine" = "xyes" ; then AC_MSG_CHECKING([for OpenSSL ENGINE support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include + #include ]], [[ - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); ]])], [ AC_MSG_RESULT([yes]) AC_DEFINE([USE_OPENSSL_ENGINE], [1], [Enable OpenSSL engine support]) ], [ AC_MSG_ERROR([OpenSSL ENGINE support not found]) ]) - fi ] -) + fi -# Check for OpenSSL without EVP_aes_{192,256}_cbc -AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); - ]])], - [ - AC_MSG_RESULT([no]) - ], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1], - [libcrypto is missing AES 192 and 256 bit functions]) - ] -) - -# Check for OpenSSL with EVP_aes_*ctr -AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(EVP_aes_128_ctr() == NULL || - EVP_aes_192_cbc() == NULL || - EVP_aes_256_cbc() == NULL); - ]])], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1], - [libcrypto has EVP AES CTR]) - ], - [ - AC_MSG_RESULT([no]) - ] -) - -# Check for OpenSSL with EVP_aes_*gcm -AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(EVP_aes_128_gcm() == NULL || - EVP_aes_256_gcm() == NULL || - EVP_CTRL_GCM_SET_IV_FIXED == 0 || - EVP_CTRL_GCM_IV_GEN == 0 || - EVP_CTRL_GCM_SET_TAG == 0 || - EVP_CTRL_GCM_GET_TAG == 0 || - EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); - ]])], - [ - AC_MSG_RESULT([yes]) - AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1], - [libcrypto has EVP AES GCM]) - ], - [ - AC_MSG_RESULT([no]) - unsupported_algorithms="$unsupported_cipers \ - aes128-gcm@openssh.com aes256-gcm@openssh.com" - ] -) - -AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto], - [AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1], - [Define if libcrypto has EVP_CIPHER_CTX_ctrl])]) - -AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - if(EVP_DigestUpdate(NULL, NULL,0)) - exit(0); - ]])], - [ - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1], - [Define if EVP_DigestUpdate returns void]) - ] -) - -# Some systems want crypt() from libcrypt, *not* the version in OpenSSL, -# because the system crypt() is more featureful. -if test "x$check_for_libcrypt_before" = "x1"; then - AC_CHECK_LIB([crypt], [crypt]) -fi - -# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the -# version in OpenSSL. -if test "x$check_for_libcrypt_later" = "x1"; then - AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) -fi -AC_CHECK_FUNCS([crypt DES_crypt]) - -# Search for SHA256 support in libc and/or OpenSSL -AC_CHECK_FUNCS([SHA256_Update EVP_sha256], , - [unsupported_algorithms="$unsupported_algorithms \ - hmac-sha2-256 hmac-sha2-512 \ - diffie-hellman-group-exchange-sha256 \ - hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" - ] -) -# Search for RIPE-MD support in OpenSSL -AC_CHECK_FUNCS([EVP_ripemd160], , - [unsupported_algorithms="$unsupported_algorithms \ - hmac-ripemd160 - hmac-ripemd160@openssh.com - hmac-ripemd160-etm@openssh.com" - ] -) - -# Check complete ECC support in OpenSSL -AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - ]], [[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - const EVP_MD *m = EVP_sha256(); /* We need this too */ - ]])], - [ AC_MSG_RESULT([yes]) - enable_nistp256=1 ], - [ AC_MSG_RESULT([no]) ] -) - -AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - ]], [[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); - const EVP_MD *m = EVP_sha384(); /* We need this too */ - ]])], - [ AC_MSG_RESULT([yes]) - enable_nistp384=1 ], - [ AC_MSG_RESULT([no]) ] -) - -AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1]) -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include -#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ -# error "OpenSSL < 0.9.8g has unreliable ECC code" -#endif - ]], [[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); - const EVP_MD *m = EVP_sha512(); /* We need this too */ - ]])], - [ AC_MSG_RESULT([yes]) - AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional]) - AC_RUN_IFELSE( + # Check for OpenSSL without EVP_aes_{192,256}_cbc + AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) + AC_LINK_IFELSE( [AC_LANG_PROGRAM([[ -#include -#include -#include -#include -#include -#include - ]],[[ - EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); - const EVP_MD *m = EVP_sha512(); /* We need this too */ - exit(e == NULL || m == NULL); + #include + #include + ]], [[ + exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); + ]])], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1], + [libcrypto is missing AES 192 and 256 bit functions]) + ] + ) + + # Check for OpenSSL with EVP_aes_*ctr + AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(EVP_aes_128_ctr() == NULL || + EVP_aes_192_cbc() == NULL || + EVP_aes_256_cbc() == NULL); + ]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1], + [libcrypto has EVP AES CTR]) + ], + [ + AC_MSG_RESULT([no]) + ] + ) + + # Check for OpenSSL with EVP_aes_*gcm + AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(EVP_aes_128_gcm() == NULL || + EVP_aes_256_gcm() == NULL || + EVP_CTRL_GCM_SET_IV_FIXED == 0 || + EVP_CTRL_GCM_IV_GEN == 0 || + EVP_CTRL_GCM_SET_TAG == 0 || + EVP_CTRL_GCM_GET_TAG == 0 || + EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0); + ]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1], + [libcrypto has EVP AES GCM]) + ], + [ + AC_MSG_RESULT([no]) + unsupported_algorithms="$unsupported_cipers \ + aes128-gcm@openssh.com aes256-gcm@openssh.com" + ] + ) + + AC_SEARCH_LIBS([EVP_CIPHER_CTX_ctrl], [crypto], + [AC_DEFINE([HAVE_EVP_CIPHER_CTX_CTRL], [1], + [Define if libcrypto has EVP_CIPHER_CTX_ctrl])]) + + AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + if(EVP_DigestUpdate(NULL, NULL,0)) + exit(0); + ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1], + [Define if EVP_DigestUpdate returns void]) + ] + ) + + # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, + # because the system crypt() is more featureful. + if test "x$check_for_libcrypt_before" = "x1"; then + AC_CHECK_LIB([crypt], [crypt]) + fi + + # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the + # version in OpenSSL. + if test "x$check_for_libcrypt_later" = "x1"; then + AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) + fi + AC_CHECK_FUNCS([crypt DES_crypt]) + + # Search for SHA256 support in libc and/or OpenSSL + AC_CHECK_FUNCS([SHA256_Update EVP_sha256], , + [unsupported_algorithms="$unsupported_algorithms \ + hmac-sha2-256 hmac-sha2-512 \ + diffie-hellman-group-exchange-sha256 \ + hmac-sha2-256-etm@openssh.com hmac-sha2-512-etm@openssh.com" + ] + ) + # Search for RIPE-MD support in OpenSSL + AC_CHECK_FUNCS([EVP_ripemd160], , + [unsupported_algorithms="$unsupported_algorithms \ + hmac-ripemd160 + hmac-ripemd160@openssh.com + hmac-ripemd160-etm@openssh.com" + ] + ) + + # Check complete ECC support in OpenSSL + AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + const EVP_MD *m = EVP_sha256(); /* We need this too */ ]])], [ AC_MSG_RESULT([yes]) - enable_nistp521=1 ], - [ AC_MSG_RESULT([no]) ], - [ AC_MSG_WARN([cross-compiling: assuming yes]) - enable_nistp521=1 ] - )], - AC_MSG_RESULT([no]) -) + enable_nistp256=1 ], + [ AC_MSG_RESULT([no]) ] + ) -COMMENT_OUT_ECC="#no ecc#" -TEST_SSH_ECC=no + AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1); + const EVP_MD *m = EVP_sha384(); /* We need this too */ + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp384=1 ], + [ AC_MSG_RESULT([no]) ] + ) -if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ - test x$enable_nistp521 = x1; then - AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC]) -fi -if test x$enable_nistp256 = x1; then - AC_DEFINE([OPENSSL_HAS_NISTP256], [1], - [libcrypto has NID_X9_62_prime256v1]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ - ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" -fi -if test x$enable_nistp384 = x1; then - AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ - ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" -fi -if test x$enable_nistp521 = x1; then - AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1]) - TEST_SSH_ECC=yes - COMMENT_OUT_ECC="" -else - unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ - ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" -fi + AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1]) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ + # error "OpenSSL < 0.9.8g has unreliable ECC code" + #endif + ]], [[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + ]])], + [ AC_MSG_RESULT([yes]) + AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + #include + ]],[[ + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ + exit(e == NULL || m == NULL); + ]])], + [ AC_MSG_RESULT([yes]) + enable_nistp521=1 ], + [ AC_MSG_RESULT([no]) ], + [ AC_MSG_WARN([cross-compiling: assuming yes]) + enable_nistp521=1 ] + )], + AC_MSG_RESULT([no]) + ) -AC_SUBST([TEST_SSH_ECC]) -AC_SUBST([COMMENT_OUT_ECC]) + COMMENT_OUT_ECC="#no ecc#" + TEST_SSH_ECC=no + + if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \ + test x$enable_nistp521 = x1; then + AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC]) + fi + if test x$enable_nistp256 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP256], [1], + [libcrypto has NID_X9_62_prime256v1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp256 \ + ecdh-sha2-nistp256 ecdsa-sha2-nistp256-cert-v01@openssh.com" + fi + if test x$enable_nistp384 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdsa-sha2-nistp384 \ + ecdh-sha2-nistp384 ecdsa-sha2-nistp384-cert-v01@openssh.com" + fi + if test x$enable_nistp521 = x1; then + AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + else + unsupported_algorithms="$unsupported_algorithms ecdh-sha2-nistp521 \ + ecdsa-sha2-nistp521 ecdsa-sha2-nistp521-cert-v01@openssh.com" + fi + + AC_SUBST([TEST_SSH_ECC]) + AC_SUBST([COMMENT_OUT_ECC]) +else + AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"]) + AC_CHECK_FUNCS([crypt]) +fi AC_CHECK_FUNCS([ \ arc4random \ @@ -2733,28 +2796,30 @@ LIBS="$saved_LIBS" ### Configure cryptographic random number support # Check wheter OpenSSL seeds itself -AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ -#include -#include - ]], [[ - exit(RAND_status() == 1 ? 0 : 1); - ]])], - [ - OPENSSL_SEEDS_ITSELF=yes - AC_MSG_RESULT([yes]) - ], - [ - AC_MSG_RESULT([no]) - ], - [ - AC_MSG_WARN([cross compiling: assuming yes]) - # This is safe, since we will fatal() at runtime if - # OpenSSL is not seeded correctly. - OPENSSL_SEEDS_ITSELF=yes - ] -) +if test "x$openssl" = "xyes" ; then + AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + exit(RAND_status() == 1 ? 0 : 1); + ]])], + [ + OPENSSL_SEEDS_ITSELF=yes + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_MSG_WARN([cross compiling: assuming yes]) + # This is safe, since we will fatal() at runtime if + # OpenSSL is not seeded correctly. + OPENSSL_SEEDS_ITSELF=yes + ] + ) +fi # PRNGD TCP socket AC_ARG_WITH([prngd-port], @@ -2836,8 +2901,10 @@ elif test ! -z "$PRNGD_SOCKET" ; then RAND_MSG="PRNGd socket $PRNGD_SOCKET" elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then AC_DEFINE([OPENSSL_PRNG_ONLY], [1], - [Define if you want OpenSSL's internally seeded PRNG only]) + [Define if you want the OpenSSL internally seeded PRNG only]) RAND_MSG="OpenSSL internal ONLY" +elif test "x$openssl" = "xno" ; then + AC_MSG_WARN([OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible]) else AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options]) fi @@ -2899,7 +2966,7 @@ if test "x$PAM_MSG" = "xyes" ; then which takes only one argument to pam_strerror]) AC_MSG_RESULT([yes]) PAM_MSG="yes (old library)" - + ]) fi diff --git a/crypto/openssh/contrib/Makefile b/crypto/openssh/contrib/Makefile index c6c48e78aaaa..eaf7fe2fdfc9 100644 --- a/crypto/openssh/contrib/Makefile +++ b/crypto/openssh/contrib/Makefile @@ -4,12 +4,12 @@ all: @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" gnome-ssh-askpass1: gnome-ssh-askpass1.c - $(CC) `gnome-config --cflags gnome gnomeui` \ + $(CC) $(CFLAGS) `gnome-config --cflags gnome gnomeui` \ gnome-ssh-askpass1.c -o gnome-ssh-askpass1 \ `gnome-config --libs gnome gnomeui` gnome-ssh-askpass2: gnome-ssh-askpass2.c - $(CC) `$(PKG_CONFIG) --cflags gtk+-2.0` \ + $(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gtk+-2.0` \ gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ `$(PKG_CONFIG) --libs gtk+-2.0 x11` diff --git a/crypto/openssh/contrib/caldera/openssh.spec b/crypto/openssh/contrib/caldera/openssh.spec deleted file mode 100644 index 0011b4deaeb5..000000000000 --- a/crypto/openssh/contrib/caldera/openssh.spec +++ /dev/null @@ -1,365 +0,0 @@ - -# Some of this will need re-evaluation post-LSB. The SVIdir is there -# because the link appeared broken. The rest is for easy compilation, -# the tradeoff open to discussion. (LC957) - -%define SVIdir /etc/rc.d/init.d -%{!?_defaultdocdir:%define _defaultdocdir %{_prefix}/share/doc/packages} -%{!?SVIcdir:%define SVIcdir /etc/sysconfig/daemons} - -%define _mandir %{_prefix}/share/man/en -%define _sysconfdir /etc/ssh -%define _libexecdir %{_libdir}/ssh - -# Do we want to disable root_login? (1=yes 0=no) -%define no_root_login 0 - -#old cvs stuff. please update before use. may be deprecated. -%define use_stable 1 -%define version 6.7p1 -%if %{use_stable} - %define cvs %{nil} - %define release 1 -%else - %define cvs cvs20050315 - %define release 0r1 -%endif -%define xsa x11-ssh-askpass -%define askpass %{xsa}-1.2.4.1 - -# OpenSSH privilege separation requires a user & group ID -%define sshd_uid 67 -%define sshd_gid 67 - -Name : openssh -Version : %{version}%{cvs} -Release : %{release} -Group : System/Network - -Summary : OpenSSH free Secure Shell (SSH) implementation. -Summary(de) : OpenSSH - freie Implementation der Secure Shell (SSH). -Summary(es) : OpenSSH implementación libre de Secure Shell (SSH). -Summary(fr) : Implémentation libre du shell sécurisé OpenSSH (SSH). -Summary(it) : Implementazione gratuita OpenSSH della Secure Shell. -Summary(pt) : Implementação livre OpenSSH do protocolo 'Secure Shell' (SSH). -Summary(pt_BR) : Implementação livre OpenSSH do protocolo Secure Shell (SSH). - -Copyright : BSD -Packager : Raymund Will -URL : http://www.openssh.com/ - -Obsoletes : ssh, ssh-clients, openssh-clients - -BuildRoot : /tmp/%{name}-%{version} -BuildRequires : XFree86-imake - -# %{use_stable}==1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable -# %{use_stable}==0: :pserver:cvs@bass.directhit.com:/cvs/openssh_cvs -Source0: see-above:/.../openssh-%{version}.tar.gz -%if %{use_stable} -Source1: see-above:/.../openssh-%{version}.tar.gz.asc -%endif -Source2: http://www.jmknoble.net/software/%{xsa}/%{askpass}.tar.gz -Source3: http://www.openssh.com/faq.html - -%Package server -Group : System/Network -Requires : openssh = %{version} -Obsoletes : ssh-server - -Summary : OpenSSH Secure Shell protocol server (sshd). -Summary(de) : OpenSSH Secure Shell Protocol-Server (sshd). -Summary(es) : Servidor del protocolo OpenSSH Secure Shell (sshd). -Summary(fr) : Serveur de protocole du shell sécurisé OpenSSH (sshd). -Summary(it) : Server OpenSSH per il protocollo Secure Shell (sshd). -Summary(pt) : Servidor do protocolo 'Secure Shell' OpenSSH (sshd). -Summary(pt_BR) : Servidor do protocolo Secure Shell OpenSSH (sshd). - - -%Package askpass -Group : System/Network -Requires : openssh = %{version} -URL : http://www.jmknoble.net/software/x11-ssh-askpass/ -Obsoletes : ssh-extras - -Summary : OpenSSH X11 pass-phrase dialog. -Summary(de) : OpenSSH X11 Passwort-Dialog. -Summary(es) : Aplicación de petición de frase clave OpenSSH X11. -Summary(fr) : Dialogue pass-phrase X11 d'OpenSSH. -Summary(it) : Finestra di dialogo X11 per la frase segreta di OpenSSH. -Summary(pt) : Diálogo de pedido de senha para X11 do OpenSSH. -Summary(pt_BR) : Diálogo de pedido de senha para X11 do OpenSSH. - - -%Description -OpenSSH (Secure Shell) provides access to a remote system. It replaces -telnet, rlogin, rexec, and rsh, and provides secure encrypted -communications between two untrusted hosts over an insecure network. -X11 connections and arbitrary TCP/IP ports can also be forwarded over -the secure channel. - -%Description -l de -OpenSSH (Secure Shell) stellt den Zugang zu anderen Rechnern her. Es ersetzt -telnet, rlogin, rexec und rsh und stellt eine sichere, verschlüsselte -Verbindung zwischen zwei nicht vertrauenswürdigen Hosts über eine unsicheres -Netzwerk her. X11 Verbindungen und beliebige andere TCP/IP Ports können ebenso -über den sicheren Channel weitergeleitet werden. - -%Description -l es -OpenSSH (Secure Shell) proporciona acceso a sistemas remotos. Reemplaza a -telnet, rlogin, rexec, y rsh, y proporciona comunicaciones seguras encriptadas -entre dos equipos entre los que no se ha establecido confianza a través de una -red insegura. Las conexiones X11 y puertos TCP/IP arbitrarios también pueden -ser canalizadas sobre el canal seguro. - -%Description -l fr -OpenSSH (Secure Shell) fournit un accès à un système distant. Il remplace -telnet, rlogin, rexec et rsh, tout en assurant des communications cryptées -securisées entre deux hôtes non fiabilisés sur un réseau non sécurisé. Des -connexions X11 et des ports TCP/IP arbitraires peuvent également être -transmis sur le canal sécurisé. - -%Description -l it -OpenSSH (Secure Shell) fornisce l'accesso ad un sistema remoto. -Sostituisce telnet, rlogin, rexec, e rsh, e fornisce comunicazioni sicure -e crittate tra due host non fidati su una rete non sicura. Le connessioni -X11 ad una porta TCP/IP arbitraria possono essere inoltrate attraverso -un canale sicuro. - -%Description -l pt -OpenSSH (Secure Shell) fornece acesso a um sistema remoto. Substitui o -telnet, rlogin, rexec, e o rsh e fornece comunicações seguras e cifradas -entre duas máquinas sem confiança mútua sobre uma rede insegura. -Ligações X11 e portos TCP/IP arbitrários também poder ser reenviados -pelo canal seguro. - -%Description -l pt_BR -O OpenSSH (Secure Shell) fornece acesso a um sistema remoto. Substitui o -telnet, rlogin, rexec, e o rsh e fornece comunicações seguras e criptografadas -entre duas máquinas sem confiança mútua sobre uma rede insegura. -Ligações X11 e portas TCP/IP arbitrárias também podem ser reenviadas -pelo canal seguro. - -%Description server -This package installs the sshd, the server portion of OpenSSH. - -%Description -l de server -Dieses Paket installiert den sshd, den Server-Teil der OpenSSH. - -%Description -l es server -Este paquete instala sshd, la parte servidor de OpenSSH. - -%Description -l fr server -Ce paquetage installe le 'sshd', partie serveur de OpenSSH. - -%Description -l it server -Questo pacchetto installa sshd, il server di OpenSSH. - -%Description -l pt server -Este pacote intala o sshd, o servidor do OpenSSH. - -%Description -l pt_BR server -Este pacote intala o sshd, o servidor do OpenSSH. - -%Description askpass -This package contains an X11-based pass-phrase dialog used per -default by ssh-add(1). It is based on %{askpass} -by Jim Knoble . - - -%Prep -%setup %([ -z "%{cvs}" ] || echo "-n %{name}_cvs") -a2 -%if ! %{use_stable} - autoreconf -%endif - - -%Build -CFLAGS="$RPM_OPT_FLAGS" \ -%configure \ - --with-pam \ - --with-privsep-path=%{_var}/empty/sshd \ - #leave this line for easy edits. - -%__make - -cd %{askpass} -%configure \ - #leave this line for easy edits. - -xmkmf -%__make includes -%__make - - -%Install -[ %{buildroot} != "/" ] && rm -rf %{buildroot} - -make install DESTDIR=%{buildroot} -%makeinstall -C %{askpass} \ - BINDIR=%{_libexecdir} \ - MANPATH=%{_mandir} \ - DESTDIR=%{buildroot} - -# OpenLinux specific configuration -mkdir -p %{buildroot}{/etc/pam.d,%{SVIcdir},%{SVIdir}} -mkdir -p %{buildroot}%{_var}/empty/sshd - -# enabling X11 forwarding on the server is convenient and okay, -# on the client side it's a potential security risk! -%__perl -pi -e 's:#X11Forwarding no:X11Forwarding yes:g' \ - %{buildroot}%{_sysconfdir}/sshd_config - -%if %{no_root_login} -%__perl -pi -e 's:#PermitRootLogin yes:PermitRootLogin no:g' \ - %{buildroot}%{_sysconfdir}/sshd_config -%endif - -install -m644 contrib/caldera/sshd.pam %{buildroot}/etc/pam.d/sshd -# FIXME: disabled, find out why this doesn't work with nis -%__perl -pi -e 's:(.*pam_limits.*):#$1:' \ - %{buildroot}/etc/pam.d/sshd - -install -m 0755 contrib/caldera/sshd.init %{buildroot}%{SVIdir}/sshd - -# the last one is needless, but more future-proof -find %{buildroot}%{SVIdir} -type f -exec \ - %__perl -pi -e 's:\@SVIdir\@:%{SVIdir}:g;\ - s:\@sysconfdir\@:%{_sysconfdir}:g; \ - s:/usr/sbin:%{_sbindir}:g'\ - \{\} \; - -cat <<-EoD > %{buildroot}%{SVIcdir}/sshd - IDENT=sshd - DESCRIPTIVE="OpenSSH secure shell daemon" - # This service will be marked as 'skipped' on boot if there - # is no host key. Use ssh-host-keygen to generate one - ONBOOT="yes" - OPTIONS="" -EoD - -SKG=%{buildroot}%{_sbindir}/ssh-host-keygen -install -m 0755 contrib/caldera/ssh-host-keygen $SKG -# Fix up some path names in the keygen toy^Hol - %__perl -pi -e 's:\@sysconfdir\@:%{_sysconfdir}:g; \ - s:\@sshkeygen\@:%{_bindir}/ssh-keygen:g' \ - %{buildroot}%{_sbindir}/ssh-host-keygen - -# This looks terrible. Expect it to change. -# install remaining docs -DocD="%{buildroot}%{_defaultdocdir}/%{name}-%{version}" -mkdir -p $DocD/%{askpass} -cp -a CREDITS ChangeLog LICENCE OVERVIEW README* TODO PROTOCOL* $DocD -install -p -m 0444 %{SOURCE3} $DocD/faq.html -cp -a %{askpass}/{README,ChangeLog,TODO,SshAskpass*.ad} $DocD/%{askpass} -%if %{use_stable} - cp -p %{askpass}/%{xsa}.man $DocD/%{askpass}/%{xsa}.1 -%else - cp -p %{askpass}/%{xsa}.man %{buildroot}%{_mandir}man1/%{xsa}.1 - ln -s %{xsa}.1 %{buildroot}%{_mandir}man1/ssh-askpass.1 -%endif - -find %{buildroot}%{_mandir} -type f -not -name '*.gz' -print0 | xargs -0r %__gzip -9nf -rm %{buildroot}%{_mandir}/man1/slogin.1 && \ - ln -s %{_mandir}/man1/ssh.1.gz \ - %{buildroot}%{_mandir}/man1/slogin.1.gz - - -%Clean -#%{rmDESTDIR} -[ %{buildroot} != "/" ] && rm -rf %{buildroot} - -%Post -# Generate host key when none is present to get up and running, -# both client and server require this for host-based auth! -# ssh-host-keygen checks for existing keys. -/usr/sbin/ssh-host-keygen -: # to protect the rpm database - -%pre server -%{_sbindir}/groupadd -g %{sshd_gid} sshd 2>/dev/null || : -%{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \ - -c "SSH Daemon virtual user" -g sshd sshd 2>/dev/null || : -: # to protect the rpm database - -%Post server -if [ -x %{LSBinit}-install ]; then - %{LSBinit}-install sshd -else - lisa --SysV-init install sshd S55 2:3:4:5 K45 0:1:6 -fi - -! %{SVIdir}/sshd status || %{SVIdir}/sshd restart -: # to protect the rpm database - - -%PreUn server -[ "$1" = 0 ] || exit 0 -! %{SVIdir}/sshd status || %{SVIdir}/sshd stop -if [ -x %{LSBinit}-remove ]; then - %{LSBinit}-remove sshd -else - lisa --SysV-init remove sshd $1 -fi -: # to protect the rpm database - -%Files -%defattr(-,root,root) -%dir %{_sysconfdir} -%config %{_sysconfdir}/ssh_config -%{_bindir}/scp -%{_bindir}/sftp -%{_bindir}/ssh -%{_bindir}/slogin -%{_bindir}/ssh-add -%attr(2755,root,nobody) %{_bindir}/ssh-agent -%{_bindir}/ssh-keygen -%{_bindir}/ssh-keyscan -%dir %{_libexecdir} -%attr(4711,root,root) %{_libexecdir}/ssh-keysign -%{_libexecdir}/ssh-pkcs11-helper -%{_sbindir}/ssh-host-keygen -%dir %{_defaultdocdir}/%{name}-%{version} -%{_defaultdocdir}/%{name}-%{version}/CREDITS -%{_defaultdocdir}/%{name}-%{version}/ChangeLog -%{_defaultdocdir}/%{name}-%{version}/LICENCE -%{_defaultdocdir}/%{name}-%{version}/OVERVIEW -%{_defaultdocdir}/%{name}-%{version}/README* -%{_defaultdocdir}/%{name}-%{version}/TODO -%{_defaultdocdir}/%{name}-%{version}/faq.html -%{_mandir}/man1/* -%{_mandir}/man8/ssh-keysign.8.gz -%{_mandir}/man8/ssh-pkcs11-helper.8.gz -%{_mandir}/man5/ssh_config.5.gz - -%Files server -%defattr(-,root,root) -%dir %{_var}/empty/sshd -%config %{SVIdir}/sshd -%config /etc/pam.d/sshd -%config %{_sysconfdir}/moduli -%config %{_sysconfdir}/sshd_config -%config %{SVIcdir}/sshd -%{_libexecdir}/sftp-server -%{_sbindir}/sshd -%{_mandir}/man5/moduli.5.gz -%{_mandir}/man5/sshd_config.5.gz -%{_mandir}/man8/sftp-server.8.gz -%{_mandir}/man8/sshd.8.gz - -%Files askpass -%defattr(-,root,root) -%{_libexecdir}/ssh-askpass -%{_libexecdir}/x11-ssh-askpass -%{_defaultdocdir}/%{name}-%{version}/%{askpass} - - -%ChangeLog -* Tue Jan 18 2011 Tim Rice -- Use CFLAGS from Makefile instead of RPM so build completes. -- Signatures were changed to .asc since 4.1p1. - -* Mon Jan 01 1998 ... -Template Version: 1.31 - -$Id: openssh.spec,v 1.85 2014/08/19 01:36:08 djm Exp $ diff --git a/crypto/openssh/contrib/caldera/ssh-host-keygen b/crypto/openssh/contrib/caldera/ssh-host-keygen deleted file mode 100755 index 86382ddfb43f..000000000000 --- a/crypto/openssh/contrib/caldera/ssh-host-keygen +++ /dev/null @@ -1,36 +0,0 @@ -#! /bin/sh -# -# $Id: ssh-host-keygen,v 1.3 2008/11/03 09:16:01 djm Exp $ -# -# This script is normally run only *once* for a given host -# (in a given period of time) -- on updates/upgrades/recovery -# the ssh_host_key* files _should_ be retained! Otherwise false -# "man-in-the-middle-attack" alerts will frighten unsuspecting -# clients... - -keydir=@sysconfdir@ -keygen=@sshkeygen@ - -if [ -f $keydir/ssh_host_key -o \ - -f $keydir/ssh_host_key.pub ]; then - echo "You already have an SSH1 RSA host key in $keydir/ssh_host_key." -else - echo "Generating SSH1 RSA host key." - $keygen -t rsa1 -f $keydir/ssh_host_key -C '' -N '' -fi - -if [ -f $keydir/ssh_host_rsa_key -o \ - -f $keydir/ssh_host_rsa_key.pub ]; then - echo "You already have an SSH2 RSA host key in $keydir/ssh_host_rsa_key." -else - echo "Generating SSH2 RSA host key." - $keygen -t rsa -f $keydir/ssh_host_rsa_key -C '' -N '' -fi - -if [ -f $keydir/ssh_host_dsa_key -o \ - -f $keydir/ssh_host_dsa_key.pub ]; then - echo "You already have an SSH2 DSA host key in $keydir/ssh_host_dsa_key." -else - echo "Generating SSH2 DSA host key." - $keygen -t dsa -f $keydir/ssh_host_dsa_key -C '' -N '' -fi diff --git a/crypto/openssh/contrib/caldera/sshd.init b/crypto/openssh/contrib/caldera/sshd.init deleted file mode 100755 index 983146f4fe00..000000000000 --- a/crypto/openssh/contrib/caldera/sshd.init +++ /dev/null @@ -1,125 +0,0 @@ -#! /bin/bash -# -# $Id: sshd.init,v 1.4 2003/11/21 12:48:57 djm Exp $ -# -### BEGIN INIT INFO -# Provides: -# Required-Start: $network -# Required-Stop: -# Default-Start: 3 4 5 -# Default-Stop: 0 1 2 6 -# Description: sshd -# Bring up/down the OpenSSH secure shell daemon. -### END INIT INFO -# -# Written by Miquel van Smoorenburg . -# Modified for Debian GNU/Linux by Ian Murdock . -# Modified for OpenLinux by Raymund Will - -NAME=sshd -DAEMON=/usr/sbin/$NAME -# Hack-Alert(TM)! This is necessary to get around the 'reload'-problem -# created by recent OpenSSH daemon/ssd combinations. See Caldera internal -# PR [linux/8278] for details... -PIDF=/var/run/$NAME.pid -NAME=$DAEMON - -_status() { - [ -z "$1" ] || local pidf="$1" - local ret=-1 - local pid - if [ -n "$pidf" ] && [ -r "$pidf" ]; then - pid=$(head -1 $pidf) - else - pid=$(pidof $NAME) - fi - - if [ ! -e $SVIlock ]; then - # no lock-file => not started == stopped? - ret=3 - elif [ -n "$pidf" -a ! -f "$pidf" ] || [ -z "$pid" ]; then - # pid-file given but not present or no pid => died, but was not stopped - ret=2 - elif [ -r /proc/$pid/cmdline ] && - echo -ne $NAME'\000' | cmp -s - /proc/$pid/cmdline; then - # pid-file given and present or pid found => check process... - # but don't compare exe, as this will fail after an update! - # compares OK => all's well, that ends well... - ret=0 - else - # no such process or exe does not match => stale pid-file or process died - # just recently... - ret=1 - fi - return $ret -} - -# Source function library (and set vital variables). -. @SVIdir@/functions - -case "$1" in - start) - [ ! -e $SVIlock ] || exit 0 - [ -x $DAEMON ] || exit 5 - SVIemptyConfig @sysconfdir@/sshd_config && exit 6 - - if [ ! \( -f @sysconfdir@/ssh_host_key -a \ - -f @sysconfdir@/ssh_host_key.pub \) -a \ - ! \( -f @sysconfdir@/ssh_host_rsa_key -a \ - -f @sysconfdir@/ssh_host_rsa_key.pub \) -a \ - ! \( -f @sysconfdir@/ssh_host_dsa_key -a \ - -f @sysconfdir@/ssh_host_dsa_key.pub \) ]; then - - echo "$SVIsubsys: host key not initialized: skipped!" - echo "$SVIsubsys: use ssh-host-keygen to generate one!" - exit 6 - fi - - echo -n "Starting $SVIsubsys services: " - ssd -S -x $DAEMON -n $NAME -- $OPTIONS - ret=$? - - echo "." - touch $SVIlock - ;; - - stop) - [ -e $SVIlock ] || exit 0 - - echo -n "Stopping $SVIsubsys services: " - ssd -K -p $PIDF -n $NAME - ret=$? - - echo "." - rm -f $SVIlock - ;; - - force-reload|reload) - [ -e $SVIlock ] || exit 0 - - echo "Reloading $SVIsubsys configuration files: " - ssd -K --signal 1 -q -p $PIDF -n $NAME - ret=$? - echo "done." - ;; - - restart) - $0 stop - $0 start - ret=$? - ;; - - status) - _status $PIDF - ret=$? - ;; - - *) - echo "Usage: $SVIscript {[re]start|stop|[force-]reload|status}" - ret=2 - ;; - -esac - -exit $ret - diff --git a/crypto/openssh/contrib/caldera/sshd.pam b/crypto/openssh/contrib/caldera/sshd.pam deleted file mode 100644 index f050a9aee648..000000000000 --- a/crypto/openssh/contrib/caldera/sshd.pam +++ /dev/null @@ -1,8 +0,0 @@ -#%PAM-1.0 -auth required /lib/security/pam_pwdb.so shadow nodelay -account required /lib/security/pam_nologin.so -account required /lib/security/pam_pwdb.so -password required /lib/security/pam_cracklib.so -password required /lib/security/pam_pwdb.so shadow nullok use_authtok -session required /lib/security/pam_pwdb.so -session required /lib/security/pam_limits.so diff --git a/crypto/openssh/contrib/cygwin/ssh-host-config b/crypto/openssh/contrib/cygwin/ssh-host-config index a7ea3e0d2d3e..d934d09b5430 100644 --- a/crypto/openssh/contrib/cygwin/ssh-host-config +++ b/crypto/openssh/contrib/cygwin/ssh-host-config @@ -1,6 +1,6 @@ #!/bin/bash # -# ssh-host-config, Copyright 2000-2011 Red Hat Inc. +# ssh-host-config, Copyright 2000-2014 Red Hat Inc. # # This file is part of the Cygwin port of OpenSSH. # @@ -61,6 +61,7 @@ LOCALSTATEDIR=/var sshd_config_configured=no port_number=22 +service_name=sshd strictmodes=yes privsep_used=yes cygwin_value="" @@ -353,11 +354,9 @@ check_service_files_ownership() { fi if [ -z "${run_service_as}" ] then - csih_warning "Couldn't determine name of user running sshd service from /etc/passwd!" + csih_warning "Couldn't determine name of user running sshd service from account database!" csih_warning "As a result, this script cannot make sure that the files used" csih_warning "by the sshd service belong to the user running the service." - csih_warning "Please re-run the mkpasswd tool to make sure the /etc/passwd" - csih_warning "file is in a good shape." return 1 fi fi @@ -410,7 +409,7 @@ install_service() { local ret=0 echo - if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1 + if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1 then csih_inform "Sshd service is already installed." check_service_files_ownership "" || let ret+=$? @@ -466,7 +465,7 @@ install_service() { fi if [ -z "${password}" ] then - if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ + if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \ -a "-D" -y tcpip "${cygwin_env[@]}" then echo @@ -476,20 +475,20 @@ install_service() { csih_inform "will start automatically after the next reboot." fi else - if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ + if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \ -a "-D" -y tcpip "${cygwin_env[@]}" \ -u "${run_service_as}" -w "${password}" then /usr/bin/editrights -u "${run_service_as}" -a SeServiceLogonRight echo csih_inform "The sshd service has been installed under the '${run_service_as}'" - csih_inform "account. To start the service now, call \`net start sshd' or" - csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically" + csih_inform "account. To start the service now, call \`net start ${service_name}' or" + csih_inform "\`cygrunsrv -S ${service_name}'. Otherwise, it will start automatically" csih_inform "after the next reboot." fi fi - if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1 + if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1 then check_service_files_ownership "${run_service_as}" || let ret+=$? else @@ -563,6 +562,11 @@ do shift ;; + -N | --name ) + service_name=$1 + shift + ;; + -p | --port ) port_number=$1 shift @@ -592,6 +596,7 @@ do echo " --yes -y Answer all questions with \"yes\" automatically." echo " --no -n Answer all questions with \"no\" automatically." echo " --cygwin -c Use \"options\" as value for CYGWIN environment var." + echo " --name -N sshd windows service name." echo " --port -p sshd listens on port n." echo " --user -u privileged user for service, default 'cyg_server'." echo " --pwd -w Use \"pwd\" as password for privileged user." @@ -625,10 +630,7 @@ then csih_warning "However, it seems your account does not have these privileges." csih_warning "Here's the list of groups in your user token:" echo - for i in $(/usr/bin/id -G) - do - /usr/bin/awk -F: "/[^:]*:[^:]*:$i:/{ print \" \" \$1; }" /etc/group - done + /usr/bin/id -Gnz | xargs -0n1 echo " " echo csih_warning "This usually means you're running this script from a non-admin" csih_warning "desktop session, or in a non-elevated shell under UAC control." diff --git a/crypto/openssh/contrib/cygwin/ssh-user-config b/crypto/openssh/contrib/cygwin/ssh-user-config index 8708b7a58954..33dc0cbea45f 100644 --- a/crypto/openssh/contrib/cygwin/ssh-user-config +++ b/crypto/openssh/contrib/cygwin/ssh-user-config @@ -1,6 +1,6 @@ #!/bin/bash # -# ssh-user-config, Copyright 2000-2008 Red Hat Inc. +# ssh-user-config, Copyright 2000-2014 Red Hat Inc. # # This file is part of the Cygwin port of OpenSSH. # @@ -75,19 +75,18 @@ readonly -f create_identity # pwdhome # ====================================================================== check_user_homedir() { - local uid=$(id -u) - pwdhome=$(awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd) + pwdhome=$(getent passwd $UID | awk -F: '{ print $6; }') if [ "X${pwdhome}" = "X" ] then csih_error_multi \ - "There is no home directory set for you in ${SYSCONFDIR}/passwd." \ + "There is no home directory set for you in the account database." \ 'Setting $HOME is not sufficient!' fi if [ ! -d "${pwdhome}" ] then csih_error_multi \ - "${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory" \ + "${pwdhome} is set in the account database as your home directory" \ 'but it is not a valid directory. Cannot create user identity files.' fi @@ -96,7 +95,7 @@ check_user_homedir() { if [ "X${pwdhome}" = "X/" ] then # But first raise a warning! - csih_warning "Your home directory in ${SYSCONFDIR}/passwd is set to root (/). This is not recommended!" + csih_warning "Your home directory in the account database is set to root (/). This is not recommended!" if csih_request "Would you like to proceed anyway?" then pwdhome='' @@ -106,7 +105,7 @@ check_user_homedir() { fi fi - if [ -d "${pwdhome}" -a csih_is_nt -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ] + if [ -d "${pwdhome}" -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ] then echo csih_warning 'group and other have been revoked write permission to your home' @@ -149,9 +148,10 @@ readonly -f check_user_dot_ssh_dir # pwdhome -- check_user_homedir() # ====================================================================== fix_authorized_keys_perms() { - if [ csih_is_nt -a -e "${pwdhome}/.ssh/authorized_keys" ] + if [ -e "${pwdhome}/.ssh/authorized_keys" ] then - if ! setfacl -m "u::rw-,g::---,o::---" "${pwdhome}/.ssh/authorized_keys" + setfacl -b "${pwdhome}/.ssh/authorized_keys" 2>/dev/null || echo -n + if ! chmod u-x,g-wx,o-wx "${pwdhome}/.ssh/authorized_keys" then csih_warning "Setting correct permissions to ${pwdhome}/.ssh/authorized_keys" csih_warning "failed. Please care for the correct permissions. The minimum requirement" @@ -243,15 +243,6 @@ done # Action! # ====================================================================== -# Check passwd file -if [ ! -f ${SYSCONFDIR}/passwd ] -then - csih_error_multi \ - "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file" \ - 'first using mkpasswd. Check if it contains an entry for you and' \ - 'please care for the home directory in your entry as well.' -fi - check_user_homedir check_user_dot_ssh_dir create_identity id_rsa rsa "SSH2 RSA" diff --git a/crypto/openssh/contrib/redhat/openssh.spec b/crypto/openssh/contrib/redhat/openssh.spec index 9bdce1e3c225..7ac4ed0a546c 100644 --- a/crypto/openssh/contrib/redhat/openssh.spec +++ b/crypto/openssh/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 6.7p1 +%define ver 6.8p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID diff --git a/crypto/openssh/contrib/suse/openssh.spec b/crypto/openssh/contrib/suse/openssh.spec index f87674317682..0eb779c9b786 100644 --- a/crypto/openssh/contrib/suse/openssh.spec +++ b/crypto/openssh/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 6.7p1 +Version: 6.8p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/crypto/openssh/deattack.c b/crypto/openssh/deattack.c index 1b37e4dabe59..e76481a6d08e 100644 --- a/crypto/openssh/deattack.c +++ b/crypto/openssh/deattack.c @@ -1,4 +1,4 @@ -/* $OpenBSD: deattack.c,v 1.30 2006/09/16 19:53:37 djm Exp $ */ +/* $OpenBSD: deattack.c,v 1.32 2015/01/20 23:14:00 deraadt Exp $ */ /* * Cryptographic attack detector for ssh - source code * @@ -20,16 +20,13 @@ #include "includes.h" -#include - #include #include -#include +#include -#include "xmalloc.h" #include "deattack.h" -#include "log.h" #include "crc32.h" +#include "sshbuf.h" #include "misc.h" /* @@ -66,7 +63,7 @@ /* Hash function (Input keys are cipher results) */ -#define HASH(x) get_u32(x) +#define HASH(x) PEEK_U32(x) #define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE)) @@ -79,10 +76,10 @@ crc_update(u_int32_t *a, u_int32_t b) /* detect if a block is used in a particular pattern */ static int -check_crc(u_char *S, u_char *buf, u_int32_t len) +check_crc(const u_char *S, const u_char *buf, u_int32_t len) { u_int32_t crc; - u_char *c; + const u_char *c; crc = 0; for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { @@ -94,36 +91,44 @@ check_crc(u_char *S, u_char *buf, u_int32_t len) crc_update(&crc, 0); } } - return (crc == 0); + return crc == 0; } +void +deattack_init(struct deattack_ctx *dctx) +{ + bzero(dctx, sizeof(*dctx)); + dctx->n = HASH_MINSIZE / HASH_ENTRYSIZE; +} /* Detect a crc32 compensation attack on a packet */ int -detect_attack(u_char *buf, u_int32_t len) +detect_attack(struct deattack_ctx *dctx, const u_char *buf, u_int32_t len) { - static u_int16_t *h = (u_int16_t *) NULL; - static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; - u_int32_t i, j; - u_int32_t l, same; - u_char *c; - u_char *d; + u_int32_t i, j, l, same; + u_int16_t *tmp; + const u_char *c, *d; if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || - len % SSH_BLOCKSIZE != 0) { - fatal("detect_attack: bad length %d", len); - } - for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) + len % SSH_BLOCKSIZE != 0) + return DEATTACK_ERROR; + for (l = dctx->n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) ; - if (h == NULL) { - debug("Installing crc compensation attack detector."); - h = (u_int16_t *) xcalloc(l, HASH_ENTRYSIZE); - n = l; + if (dctx->h == NULL) { + if ((dctx->h = calloc(l, HASH_ENTRYSIZE)) == NULL) + return DEATTACK_ERROR; + dctx->n = l; } else { - if (l > n) { - h = (u_int16_t *)xrealloc(h, l, HASH_ENTRYSIZE); - n = l; + if (l > dctx->n) { + if ((tmp = reallocarray(dctx->h, l, HASH_ENTRYSIZE)) + == NULL) { + free(dctx->h); + dctx->h = NULL; + return DEATTACK_ERROR; + } + dctx->h = tmp; + dctx->n = l; } } @@ -132,29 +137,29 @@ detect_attack(u_char *buf, u_int32_t len) for (d = buf; d < c; d += SSH_BLOCKSIZE) { if (!CMP(c, d)) { if ((check_crc(c, buf, len))) - return (DEATTACK_DETECTED); + return DEATTACK_DETECTED; else break; } } } - return (DEATTACK_OK); + return DEATTACK_OK; } - memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); + memset(dctx->h, HASH_UNUSEDCHAR, dctx->n * HASH_ENTRYSIZE); for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { - for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; - i = (i + 1) & (n - 1)) { - if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { + for (i = HASH(c) & (dctx->n - 1); dctx->h[i] != HASH_UNUSED; + i = (i + 1) & (dctx->n - 1)) { + if (!CMP(c, buf + dctx->h[i] * SSH_BLOCKSIZE)) { if (++same > MAX_IDENTICAL) - return (DEATTACK_DOS_DETECTED); + return DEATTACK_DOS_DETECTED; if (check_crc(c, buf, len)) - return (DEATTACK_DETECTED); + return DEATTACK_DETECTED; else break; } } - h[i] = j; + dctx->h[i] = j; } - return (DEATTACK_OK); + return DEATTACK_OK; } diff --git a/crypto/openssh/deattack.h b/crypto/openssh/deattack.h index 0316fb28543b..ce67a30ffdd3 100644 --- a/crypto/openssh/deattack.h +++ b/crypto/openssh/deattack.h @@ -1,4 +1,4 @@ -/* $OpenBSD: deattack.h,v 1.10 2006/09/16 19:53:37 djm Exp $ */ +/* $OpenBSD: deattack.h,v 1.11 2015/01/19 19:52:16 markus Exp $ */ /* * Cryptographic attack detector for ssh - Header file @@ -26,6 +26,13 @@ #define DEATTACK_OK 0 #define DEATTACK_DETECTED 1 #define DEATTACK_DOS_DETECTED 2 +#define DEATTACK_ERROR 3 -int detect_attack(u_char *, u_int32_t); +struct deattack_ctx { + u_int16_t *h; + u_int32_t n; +}; + +void deattack_init(struct deattack_ctx *); +int detect_attack(struct deattack_ctx *, const u_char *, u_int32_t); #endif diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h index 3ac8be987539..fa0ccba7c018 100644 --- a/crypto/openssh/defines.h +++ b/crypto/openssh/defines.h @@ -105,6 +105,17 @@ enum # endif /* PATH_MAX */ #endif /* MAXPATHLEN */ +#ifndef HOST_NAME_MAX +# include "netdb.h" /* for MAXHOSTNAMELEN */ +# if defined(_POSIX_HOST_NAME_MAX) +# define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +# elif defined(MAXHOSTNAMELEN) +# define HOST_NAME_MAX MAXHOSTNAMELEN +# else +# define HOST_NAME_MAX 255 +# endif +#endif /* HOST_NAME_MAX */ + #if defined(HAVE_DECL_MAXSYMLINKS) && HAVE_DECL_MAXSYMLINKS == 0 # define MAXSYMLINKS 5 #endif @@ -586,6 +597,12 @@ struct winsize { # undef HAVE_GAI_STRERROR #endif +#if defined(HAVE_GETADDRINFO) +# if defined(HAVE_DECL_AI_NUMERICSERV) && HAVE_DECL_AI_NUMERICSERV == 0 +# define AI_NUMERICSERV 0 +# endif +#endif + #if defined(BROKEN_UPDWTMPX) && defined(HAVE_UPDWTMPX) # undef HAVE_UPDWTMPX #endif @@ -805,14 +822,6 @@ struct winsize { # define SSH_IOBUFSZ 8192 #endif -#ifndef _NSIG -# ifdef NSIG -# define _NSIG NSIG -# else -# define _NSIG 128 -# endif -#endif - /* * Platforms that have arc4random_uniform() and not arc4random_stir() * shouldn't need the latter. diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c index 3331cda6c71c..a260240fd6d2 100644 --- a/crypto/openssh/dh.c +++ b/crypto/openssh/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.53 2013/11/21 00:45:44 djm Exp $ */ +/* $OpenBSD: dh.c,v 1.55 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -25,7 +25,7 @@ #include "includes.h" -#include +#include /* MIN */ #include #include @@ -34,11 +34,13 @@ #include #include #include +#include #include "dh.h" #include "pathnames.h" #include "log.h" #include "misc.h" +#include "ssherr.h" static int parse_prime(int linenum, char *line, struct dhgroup *dhg) @@ -107,10 +109,11 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) goto fail; } - if ((dhg->g = BN_new()) == NULL) - fatal("parse_prime: BN_new failed"); - if ((dhg->p = BN_new()) == NULL) - fatal("parse_prime: BN_new failed"); + if ((dhg->g = BN_new()) == NULL || + (dhg->p = BN_new()) == NULL) { + error("parse_prime: BN_new failed"); + goto fail; + } if (BN_hex2bn(&dhg->g, gen) == 0) { error("moduli:%d: could not parse generator value", linenum); goto fail; @@ -128,7 +131,6 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) error("moduli:%d: generator is invalid", linenum); goto fail; } - return 1; fail: @@ -137,7 +139,6 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) if (dhg->p != NULL) BN_clear_free(dhg->p); dhg->g = dhg->p = NULL; - error("Bad prime description in line %d", linenum); return 0; } @@ -200,9 +201,11 @@ choose_dh(int min, int wantbits, int max) break; } fclose(f); - if (linenum != which+1) - fatal("WARNING: line %d disappeared in %s, giving up", + if (linenum != which+1) { + logit("WARNING: line %d disappeared in %s, giving up", which, _PATH_DH_PRIMES); + return (dh_new_group14()); + } return (dh_new_group(dhg.g, dhg.p)); } @@ -251,22 +254,22 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) return 0; } -void +int dh_gen_key(DH *dh, int need) { int pbits; - if (need <= 0) - fatal("%s: need <= 0", __func__); - if (dh->p == NULL) - fatal("%s: dh->p == NULL", __func__); - if ((pbits = BN_num_bits(dh->p)) <= 0) - fatal("%s: bits(p) <= 0", __func__); + if (need < 0 || dh->p == NULL || + (pbits = BN_num_bits(dh->p)) <= 0 || + need > INT_MAX / 2 || 2 * need >= pbits) + return SSH_ERR_INVALID_ARGUMENT; dh->length = MIN(need * 2, pbits - 1); - if (DH_generate_key(dh) == 0) - fatal("%s: key generation failed", __func__); - if (!dh_pub_is_valid(dh, dh->pub_key)) - fatal("%s: generated invalid key", __func__); + if (DH_generate_key(dh) == 0 || + !dh_pub_is_valid(dh, dh->pub_key)) { + BN_clear_free(dh->priv_key); + return SSH_ERR_LIBCRYPTO_ERROR; + } + return 0; } DH * @@ -275,13 +278,12 @@ dh_new_group_asc(const char *gen, const char *modulus) DH *dh; if ((dh = DH_new()) == NULL) - fatal("dh_new_group_asc: DH_new"); - - if (BN_hex2bn(&dh->p, modulus) == 0) - fatal("BN_hex2bn p"); - if (BN_hex2bn(&dh->g, gen) == 0) - fatal("BN_hex2bn g"); - + return NULL; + if (BN_hex2bn(&dh->p, modulus) == 0 || + BN_hex2bn(&dh->g, gen) == 0) { + DH_free(dh); + return NULL; + } return (dh); } @@ -296,7 +298,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus) DH *dh; if ((dh = DH_new()) == NULL) - fatal("dh_new_group: DH_new"); + return NULL; dh->p = modulus; dh->g = gen; @@ -344,7 +346,7 @@ dh_new_group14(void) * from RFC4419 section 3. */ -int +u_int dh_estimate(int bits) { if (bits <= 112) diff --git a/crypto/openssh/dh.h b/crypto/openssh/dh.h index 48f7b68eaf4b..63a1b14770cd 100644 --- a/crypto/openssh/dh.h +++ b/crypto/openssh/dh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.h,v 1.11 2013/10/08 11:42:13 dtucker Exp $ */ +/* $OpenBSD: dh.h,v 1.12 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. @@ -38,10 +38,10 @@ DH *dh_new_group(BIGNUM *, BIGNUM *); DH *dh_new_group1(void); DH *dh_new_group14(void); -void dh_gen_key(DH *, int); +int dh_gen_key(DH *, int); int dh_pub_is_valid(DH *, BIGNUM *); -int dh_estimate(int); +u_int dh_estimate(int); /* Min and max values from RFC4419. */ #define DH_GRP_MIN 1024 diff --git a/crypto/openssh/digest-libc.c b/crypto/openssh/digest-libc.c index 0bb1c73c7f57..2564ae781ba3 100644 --- a/crypto/openssh/digest-libc.c +++ b/crypto/openssh/digest-libc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-libc.c,v 1.3 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: digest-libc.c,v 1.4 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * Copyright (c) 2014 Markus Friedl. All rights reserved. @@ -18,15 +18,19 @@ #include "includes.h" +#ifndef WITH_OPENSSL + #include #include #include #include +#if 0 #include #include #include #include +#endif #include "ssherr.h" #include "sshbuf.h" @@ -89,30 +93,30 @@ const struct ssh_digest digests[SSH_DIGEST_MAX] = { "SHA256", SHA256_BLOCK_LENGTH, SHA256_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA256Init, - (md_update_fn *) SHA256Update, - (md_final_fn *) SHA256Final + sizeof(SHA256_CTX), + (md_init_fn *) SHA256_Init, + (md_update_fn *) SHA256_Update, + (md_final_fn *) SHA256_Final }, { SSH_DIGEST_SHA384, "SHA384", SHA384_BLOCK_LENGTH, SHA384_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA384Init, - (md_update_fn *) SHA384Update, - (md_final_fn *) SHA384Final + sizeof(SHA384_CTX), + (md_init_fn *) SHA384_Init, + (md_update_fn *) SHA384_Update, + (md_final_fn *) SHA384_Final }, { SSH_DIGEST_SHA512, "SHA512", SHA512_BLOCK_LENGTH, SHA512_DIGEST_LENGTH, - sizeof(SHA2_CTX), - (md_init_fn *) SHA512Init, - (md_update_fn *) SHA512Update, - (md_final_fn *) SHA512Final + sizeof(SHA512_CTX), + (md_init_fn *) SHA512_Init, + (md_update_fn *) SHA512_Update, + (md_final_fn *) SHA512_Final } }; @@ -126,6 +130,26 @@ ssh_digest_by_alg(int alg) return &(digests[alg]); } +int +ssh_digest_alg_by_name(const char *name) +{ + int alg; + + for (alg = 0; alg < SSH_DIGEST_MAX; alg++) { + if (strcasecmp(name, digests[alg].name) == 0) + return digests[alg].id; + } + return -1; +} + +const char * +ssh_digest_alg_name(int alg) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(alg); + + return digest == NULL ? NULL : digest->name; +} + size_t ssh_digest_bytes(int alg) { @@ -237,3 +261,4 @@ ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) { return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); } +#endif /* !WITH_OPENSSL */ diff --git a/crypto/openssh/digest-openssl.c b/crypto/openssh/digest-openssl.c index 02b1703412d2..13b63c2f006d 100644 --- a/crypto/openssh/digest-openssl.c +++ b/crypto/openssh/digest-openssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: digest-openssl.c,v 1.4 2014/07/03 03:26:43 djm Exp $ */ +/* $OpenBSD: digest-openssl.c,v 1.5 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * @@ -17,6 +17,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #include @@ -74,6 +76,26 @@ ssh_digest_by_alg(int alg) return &(digests[alg]); } +int +ssh_digest_alg_by_name(const char *name) +{ + int alg; + + for (alg = 0; digests[alg].id != -1; alg++) { + if (strcasecmp(name, digests[alg].name) == 0) + return digests[alg].id; + } + return -1; +} + +const char * +ssh_digest_alg_name(int alg) +{ + const struct ssh_digest *digest = ssh_digest_by_alg(alg); + + return digest == NULL ? NULL : digest->name; +} + size_t ssh_digest_bytes(int alg) { @@ -180,3 +202,4 @@ ssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) { return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/digest.h b/crypto/openssh/digest.h index 6afb197f0a28..3fe07346852b 100644 --- a/crypto/openssh/digest.h +++ b/crypto/openssh/digest.h @@ -1,4 +1,4 @@ -/* $OpenBSD: digest.h,v 1.6 2014/07/03 04:36:45 djm Exp $ */ +/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */ /* * Copyright (c) 2013 Damien Miller * @@ -33,6 +33,12 @@ struct sshbuf; struct ssh_digest_ctx; +/* Looks up a digest algorithm by name */ +int ssh_digest_alg_by_name(const char *name); + +/* Returns the algorithm name for a digest identifier */ +const char *ssh_digest_alg_name(int alg); + /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ size_t ssh_digest_bytes(int alg); diff --git a/crypto/openssh/dispatch.c b/crypto/openssh/dispatch.c index 64bb80947427..afe618221a6a 100644 --- a/crypto/openssh/dispatch.c +++ b/crypto/openssh/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.22 2008/10/31 15:05:34 stevesk Exp $ */ +/* $OpenBSD: dispatch.c,v 1.26 2015/02/12 20:34:19 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -36,69 +36,123 @@ #include "dispatch.h" #include "packet.h" #include "compat.h" +#include "ssherr.h" -#define DISPATCH_MAX 255 - -dispatch_fn *dispatch[DISPATCH_MAX]; - -void -dispatch_protocol_error(int type, u_int32_t seq, void *ctxt) +int +dispatch_protocol_error(int type, u_int32_t seq, void *ctx) { + struct ssh *ssh = active_state; /* XXX */ + int r; + logit("dispatch_protocol_error: type %d seq %u", type, seq); if (!compat20) fatal("protocol error"); - packet_start(SSH2_MSG_UNIMPLEMENTED); - packet_put_int(seq); - packet_send(); - packet_write_wait(); + if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || + (r = sshpkt_put_u32(ssh, seq)) != 0 || + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + sshpkt_fatal(ssh, __func__, r); + return 0; } -void -dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt) + +int +dispatch_protocol_ignore(int type, u_int32_t seq, void *ssh) { logit("dispatch_protocol_ignore: type %d seq %u", type, seq); + return 0; } + void -dispatch_init(dispatch_fn *dflt) +ssh_dispatch_init(struct ssh *ssh, dispatch_fn *dflt) { u_int i; for (i = 0; i < DISPATCH_MAX; i++) - dispatch[i] = dflt; + ssh->dispatch[i] = dflt; } + void -dispatch_range(u_int from, u_int to, dispatch_fn *fn) +ssh_dispatch_range(struct ssh *ssh, u_int from, u_int to, dispatch_fn *fn) { u_int i; for (i = from; i <= to; i++) { if (i >= DISPATCH_MAX) break; - dispatch[i] = fn; + ssh->dispatch[i] = fn; } } -void -dispatch_set(int type, dispatch_fn *fn) -{ - dispatch[type] = fn; -} -void -dispatch_run(int mode, volatile sig_atomic_t *done, void *ctxt) -{ - for (;;) { - int type; - u_int32_t seqnr; +void +ssh_dispatch_set(struct ssh *ssh, int type, dispatch_fn *fn) +{ + ssh->dispatch[type] = fn; +} + +int +ssh_dispatch_run(struct ssh *ssh, int mode, volatile sig_atomic_t *done, + void *ctxt) +{ + int r; + u_char type; + u_int32_t seqnr; + + for (;;) { if (mode == DISPATCH_BLOCK) { - type = packet_read_seqnr(&seqnr); + r = ssh_packet_read_seqnr(ssh, &type, &seqnr); + if (r != 0) + return r; } else { - type = packet_read_poll_seqnr(&seqnr); + r = ssh_packet_read_poll_seqnr(ssh, &type, &seqnr); + if (r != 0) + return r; if (type == SSH_MSG_NONE) - return; + return 0; + } + if (type > 0 && type < DISPATCH_MAX && + ssh->dispatch[type] != NULL) { + if (ssh->dispatch_skip_packets) { + debug2("skipped packet (type %u)", type); + ssh->dispatch_skip_packets--; + continue; + } + /* XXX 'ssh' will replace 'ctxt' later */ + r = (*ssh->dispatch[type])(type, seqnr, ctxt); + if (r != 0) + return r; + } else { + r = sshpkt_disconnect(ssh, + "protocol error: rcvd type %d", type); + if (r != 0) + return r; + return SSH_ERR_DISCONNECTED; } - if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) - (*dispatch[type])(type, seqnr, ctxt); - else - packet_disconnect("protocol error: rcvd type %d", type); if (done != NULL && *done) - return; + return 0; + } +} + +void +ssh_dispatch_run_fatal(struct ssh *ssh, int mode, volatile sig_atomic_t *done, + void *ctxt) +{ + int r; + + if ((r = ssh_dispatch_run(ssh, mode, done, ctxt)) != 0) { + switch (r) { + case SSH_ERR_CONN_CLOSED: + logit("Connection closed by %.200s", + ssh_remote_ipaddr(ssh)); + cleanup_exit(255); + case SSH_ERR_CONN_TIMEOUT: + logit("Connection to %.200s timed out while " + "waiting to read", ssh_remote_ipaddr(ssh)); + cleanup_exit(255); + case SSH_ERR_DISCONNECTED: + logit("Disconnected from %.200s", + ssh_remote_ipaddr(ssh)); + cleanup_exit(255); + default: + fatal("%s: %s", __func__, ssh_err(r)); + } } } diff --git a/crypto/openssh/dispatch.h b/crypto/openssh/dispatch.h index 3e3d1a1adf65..cd51dbc0b666 100644 --- a/crypto/openssh/dispatch.h +++ b/crypto/openssh/dispatch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.h,v 1.11 2006/04/20 09:27:09 djm Exp $ */ +/* $OpenBSD: dispatch.h,v 1.12 2015/01/19 20:07:45 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -24,18 +24,35 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#ifndef DISPATCH_H +#define DISPATCH_H + +#define DISPATCH_MAX 255 enum { DISPATCH_BLOCK, DISPATCH_NONBLOCK }; -typedef void dispatch_fn(int, u_int32_t, void *); +struct ssh; -void dispatch_init(dispatch_fn *); -void dispatch_set(int, dispatch_fn *); -void dispatch_range(u_int, u_int, dispatch_fn *); -void dispatch_run(int, volatile sig_atomic_t *, void *); -void dispatch_protocol_error(int, u_int32_t, void *); -void dispatch_protocol_ignore(int, u_int32_t, void *); +typedef int dispatch_fn(int, u_int32_t, void *); + +int dispatch_protocol_error(int, u_int32_t, void *); +int dispatch_protocol_ignore(int, u_int32_t, void *); +void ssh_dispatch_init(struct ssh *, dispatch_fn *); +void ssh_dispatch_set(struct ssh *, int, dispatch_fn *); +void ssh_dispatch_range(struct ssh *, u_int, u_int, dispatch_fn *); +int ssh_dispatch_run(struct ssh *, int, volatile sig_atomic_t *, void *); +void ssh_dispatch_run_fatal(struct ssh *, int, volatile sig_atomic_t *, void *); + +#define dispatch_init(dflt) \ + ssh_dispatch_init(active_state, (dflt)) +#define dispatch_range(from, to, fn) \ + ssh_dispatch_range(active_state, (from), (to), (fn)) +#define dispatch_set(type, fn) \ + ssh_dispatch_set(active_state, (type), (fn)) +#define dispatch_run(mode, done, ctxt) \ + ssh_dispatch_run_fatal(active_state, (mode), (done), (ctxt)) + +#endif diff --git a/crypto/openssh/dns.c b/crypto/openssh/dns.c index c4d073cf50fa..f201b602e5f8 100644 --- a/crypto/openssh/dns.c +++ b/crypto/openssh/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.31 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.34 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -38,9 +38,11 @@ #include #include "xmalloc.h" -#include "key.h" +#include "sshkey.h" +#include "ssherr.h" #include "dns.h" #include "log.h" +#include "digest.h" static const char *errset_text[] = { "success", /* 0 ERRSET_SUCCESS */ @@ -77,10 +79,10 @@ dns_result_totext(unsigned int res) */ static int dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, - u_char **digest, u_int *digest_len, Key *key) + u_char **digest, size_t *digest_len, struct sshkey *key) { - int success = 0; - enum fp_type fp_type = 0; + int r, success = 0; + int fp_alg = -1; switch (key->type) { case KEY_RSA: @@ -110,19 +112,20 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, switch (*digest_type) { case SSHFP_HASH_SHA1: - fp_type = SSH_FP_SHA1; + fp_alg = SSH_DIGEST_SHA1; break; case SSHFP_HASH_SHA256: - fp_type = SSH_FP_SHA256; + fp_alg = SSH_DIGEST_SHA256; break; default: *digest_type = SSHFP_HASH_RESERVED; /* 0 */ } if (*algorithm && *digest_type) { - *digest = key_fingerprint_raw(key, fp_type, digest_len); - if (*digest == NULL) - fatal("dns_read_key: null from key_fingerprint_raw()"); + if ((r = sshkey_fingerprint_raw(key, fp_alg, digest, + digest_len)) != 0) + fatal("%s: sshkey_fingerprint_raw: %s", __func__, + ssh_err(r)); success = 1; } else { *digest = NULL; @@ -138,7 +141,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, */ static int dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, - u_char **digest, u_int *digest_len, u_char *rdata, int rdata_len) + u_char **digest, size_t *digest_len, u_char *rdata, int rdata_len) { int success = 0; @@ -199,7 +202,7 @@ is_numeric_hostname(const char *hostname) */ int verify_host_key_dns(const char *hostname, struct sockaddr *address, - Key *hostkey, int *flags) + struct sshkey *hostkey, int *flags) { u_int counter; int result; @@ -208,12 +211,12 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, u_int8_t hostkey_algorithm; u_int8_t hostkey_digest_type = SSHFP_HASH_RESERVED; u_char *hostkey_digest; - u_int hostkey_digest_len; + size_t hostkey_digest_len; u_int8_t dnskey_algorithm; u_int8_t dnskey_digest_type; u_char *dnskey_digest; - u_int dnskey_digest_len; + size_t dnskey_digest_len; *flags = 0; @@ -291,7 +294,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, free(dnskey_digest); } - free(hostkey_digest); /* from key_fingerprint_raw() */ + free(hostkey_digest); /* from sshkey_fingerprint_raw() */ freerrset(fingerprints); if (*flags & DNS_VERIFY_FOUND) @@ -309,13 +312,13 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, * Export the fingerprint of a key as a DNS resource record */ int -export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) +export_dns_rr(const char *hostname, struct sshkey *key, FILE *f, int generic) { u_int8_t rdata_pubkey_algorithm = 0; u_int8_t rdata_digest_type = SSHFP_HASH_RESERVED; u_int8_t dtype; u_char *rdata_digest; - u_int i, rdata_digest_len; + size_t i, rdata_digest_len; int success = 0; for (dtype = SSHFP_HASH_SHA1; dtype < SSHFP_HASH_MAX; dtype++) { @@ -323,7 +326,7 @@ export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, &rdata_digest, &rdata_digest_len, key)) { if (generic) { - fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", + fprintf(f, "%s IN TYPE%d \\# %zu %02x %02x ", hostname, DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len, rdata_pubkey_algorithm, rdata_digest_type); @@ -334,7 +337,7 @@ export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) for (i = 0; i < rdata_digest_len; i++) fprintf(f, "%02x", rdata_digest[i]); fprintf(f, "\n"); - free(rdata_digest); /* from key_fingerprint_raw() */ + free(rdata_digest); /* from sshkey_fingerprint_raw() */ success = 1; } } diff --git a/crypto/openssh/dns.h b/crypto/openssh/dns.h index b9feae6bef64..815f073a1a18 100644 --- a/crypto/openssh/dns.h +++ b/crypto/openssh/dns.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.h,v 1.13 2014/04/20 09:24:26 logan Exp $ */ +/* $OpenBSD: dns.h,v 1.14 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -50,7 +50,8 @@ enum sshfp_hashes { #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 -int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); -int export_dns_rr(const char *, Key *, FILE *, int); +int verify_host_key_dns(const char *, struct sockaddr *, + struct sshkey *, int *); +int export_dns_rr(const char *, struct sshkey *, FILE *, int); #endif /* DNS_H */ diff --git a/crypto/openssh/entropy.c b/crypto/openssh/entropy.c index 1e9d52ac4605..9305f89aeada 100644 --- a/crypto/openssh/entropy.c +++ b/crypto/openssh/entropy.c @@ -24,6 +24,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #ifdef HAVE_SYS_UN_H @@ -230,3 +232,13 @@ seed_rng(void) if (RAND_status() != 1) fatal("PRNG is not seeded"); } + +#else /* WITH_OPENSSL */ + +/* Handled in arc4random() */ +void +seed_rng(void) +{ +} + +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/ge25519.h b/crypto/openssh/ge25519.h index 64f63c6f8f41..a09763760931 100644 --- a/crypto/openssh/ge25519.h +++ b/crypto/openssh/ge25519.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ge25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */ +/* $OpenBSD: ge25519.h,v 1.4 2015/02/16 18:26:26 miod Exp $ */ /* * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange, @@ -28,7 +28,7 @@ typedef struct fe25519 t; } ge25519; -const ge25519 ge25519_base; +extern const ge25519 ge25519_base; int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]); diff --git a/crypto/openssh/groupaccess.c b/crypto/openssh/groupaccess.c index 1eab10b19641..4fca04471b09 100644 --- a/crypto/openssh/groupaccess.c +++ b/crypto/openssh/groupaccess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.c,v 1.14 2013/05/17 00:13:13 djm Exp $ */ +/* $OpenBSD: groupaccess.c,v 1.15 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. * @@ -26,13 +26,13 @@ #include "includes.h" #include -#include #include #include #include #include #include +#include #include "xmalloc.h" #include "groupaccess.h" diff --git a/crypto/openssh/gss-genr.c b/crypto/openssh/gss-genr.c index b39281bc1e6c..60ac65f8d9b3 100644 --- a/crypto/openssh/gss-genr.c +++ b/crypto/openssh/gss-genr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-genr.c,v 1.22 2013/11/08 00:39:15 djm Exp $ */ +/* $OpenBSD: gss-genr.c,v 1.23 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. @@ -31,6 +31,7 @@ #include #include +#include #include #include #include diff --git a/crypto/openssh/gss-serv.c b/crypto/openssh/gss-serv.c index 5c599247bb21..e7b8c52235ce 100644 --- a/crypto/openssh/gss-serv.c +++ b/crypto/openssh/gss-serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv.c,v 1.27 2014/07/03 03:34:09 djm Exp $ */ +/* $OpenBSD: gss-serv.c,v 1.28 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -29,7 +29,6 @@ #ifdef GSSAPI #include -#include #include #include diff --git a/crypto/openssh/hmac.c b/crypto/openssh/hmac.c index 99317b0f9666..d1c12417e80f 100644 --- a/crypto/openssh/hmac.c +++ b/crypto/openssh/hmac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hmac.c,v 1.10 2014/01/31 16:39:19 tedu Exp $ */ +/* $OpenBSD: hmac.c,v 1.11 2015/01/15 21:37:14 markus Exp $ */ /* * Copyright (c) 2014 Markus Friedl. All rights reserved. * @@ -20,7 +20,7 @@ #include #include -#include "buffer.h" +#include "sshbuf.h" #include "digest.h" #include "hmac.h" @@ -96,7 +96,7 @@ ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) } int -ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b) +ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const struct sshbuf *b) { return ssh_digest_update_buffer(ctx->digest, b); } diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c index ee2daf45f020..b235795e6304 100644 --- a/crypto/openssh/hostfile.c +++ b/crypto/openssh/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.57 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.64 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -39,22 +39,26 @@ #include "includes.h" #include +#include #include +#include #include #include #include #include #include #include +#include #include "xmalloc.h" #include "match.h" -#include "key.h" +#include "sshkey.h" #include "hostfile.h" #include "log.h" #include "misc.h" +#include "ssherr.h" #include "digest.h" #include "hmac.h" @@ -63,6 +67,8 @@ struct hostkeys { u_int num_entries; }; +/* XXX hmac is too easy to dictionary attack; use bcrypt? */ + static int extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) { @@ -155,15 +161,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len) */ int -hostfile_read_key(char **cpp, int *bitsp, Key *ret) +hostfile_read_key(char **cpp, u_int *bitsp, struct sshkey *ret) { char *cp; + int r; /* Skip leading whitespace. */ for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) ; - if (key_read(ret, &cp) != 1) + if ((r = sshkey_read(ret, &cp)) != 0) return 0; /* Skip trailing whitespace. */ @@ -172,28 +179,8 @@ hostfile_read_key(char **cpp, int *bitsp, Key *ret) /* Return results. */ *cpp = cp; - if (bitsp != NULL) { - if ((*bitsp = key_size(ret)) <= 0) - return 0; - } - return 1; -} - -static int -hostfile_check_key(int bits, const Key *key, const char *host, - const char *filename, u_long linenum) -{ -#ifdef WITH_SSH1 - if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) - return 1; - if (bits != BN_num_bits(key->rsa->n)) { - logit("Warning: %s, line %lu: keysize mismatch for host %s: " - "actual %d vs. announced %d.", - filename, linenum, host, BN_num_bits(key->rsa->n), bits); - logit("Warning: replace %d with %d in %s, line %lu.", - bits, BN_num_bits(key->rsa->n), filename, linenum); - } -#endif + if (bitsp != NULL) + *bitsp = sshkey_size(ret); return 1; } @@ -241,95 +228,65 @@ init_hostkeys(void) return ret; } +struct load_callback_ctx { + const char *host; + u_long num_loaded; + struct hostkeys *hostkeys; +}; + +static int +record_hostkey(struct hostkey_foreach_line *l, void *_ctx) +{ + struct load_callback_ctx *ctx = (struct load_callback_ctx *)_ctx; + struct hostkeys *hostkeys = ctx->hostkeys; + struct hostkey_entry *tmp; + + if (l->status == HKF_STATUS_INVALID) { + error("%s:%ld: parse error in hostkeys file", + l->path, l->linenum); + return 0; + } + + debug3("%s: found %skey type %s in file %s:%lu", __func__, + l->marker == MRK_NONE ? "" : + (l->marker == MRK_CA ? "ca " : "revoked "), + sshkey_type(l->key), l->path, l->linenum); + if ((tmp = reallocarray(hostkeys->entries, + hostkeys->num_entries + 1, sizeof(*hostkeys->entries))) == NULL) + return SSH_ERR_ALLOC_FAIL; + hostkeys->entries = tmp; + hostkeys->entries[hostkeys->num_entries].host = xstrdup(ctx->host); + hostkeys->entries[hostkeys->num_entries].file = xstrdup(l->path); + hostkeys->entries[hostkeys->num_entries].line = l->linenum; + hostkeys->entries[hostkeys->num_entries].key = l->key; + l->key = NULL; /* steal it */ + hostkeys->entries[hostkeys->num_entries].marker = l->marker; + hostkeys->num_entries++; + ctx->num_loaded++; + + return 0; +} + void load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) { - FILE *f; - char line[8192]; - u_long linenum = 0, num_loaded = 0; - char *cp, *cp2, *hashed_host; - HostkeyMarker marker; - Key *key; - int kbits; + int r; + struct load_callback_ctx ctx; - if ((f = fopen(path, "r")) == NULL) - return; - debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", - __func__, host, path); - while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { - cp = line; + ctx.host = host; + ctx.num_loaded = 0; + ctx.hostkeys = hostkeys; - /* Skip any leading whitespace, comments and empty lines. */ - for (; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '#' || *cp == '\n') - continue; - - if ((marker = check_markers(&cp)) == MRK_ERROR) { - verbose("%s: invalid marker at %s:%lu", - __func__, path, linenum); - continue; - } - - /* Find the end of the host name portion. */ - for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) - ; - - /* Check if the host name matches. */ - if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { - if (*cp != HASH_DELIM) - continue; - hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); - if (hashed_host == NULL) { - debug("Invalid hashed host line %lu of %s", - linenum, path); - continue; - } - if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) - continue; - } - - /* Got a match. Skip host name. */ - cp = cp2; - - /* - * Extract the key from the line. This will skip any leading - * whitespace. Ignore badly formatted lines. - */ - key = key_new(KEY_UNSPEC); - if (!hostfile_read_key(&cp, &kbits, key)) { - key_free(key); -#ifdef WITH_SSH1 - key = key_new(KEY_RSA1); - if (!hostfile_read_key(&cp, &kbits, key)) { - key_free(key); - continue; - } -#else - continue; -#endif - } - if (!hostfile_check_key(kbits, key, host, path, linenum)) - continue; - - debug3("%s: found %skey type %s in file %s:%lu", __func__, - marker == MRK_NONE ? "" : - (marker == MRK_CA ? "ca " : "revoked "), - key_type(key), path, linenum); - hostkeys->entries = xrealloc(hostkeys->entries, - hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); - hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); - hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); - hostkeys->entries[hostkeys->num_entries].line = linenum; - hostkeys->entries[hostkeys->num_entries].key = key; - hostkeys->entries[hostkeys->num_entries].marker = marker; - hostkeys->num_entries++; - num_loaded++; + if ((r = hostkeys_foreach(path, record_hostkey, &ctx, host, NULL, + HKF_WANT_MATCH|HKF_WANT_PARSE_KEY)) != 0) { + if (r != SSH_ERR_SYSTEM_ERROR && errno != ENOENT) + debug("%s: hostkeys_foreach failed for %s: %s", + __func__, path, ssh_err(r)); } - debug3("%s: loaded %lu keys", __func__, num_loaded); - fclose(f); - return; -} + if (ctx.num_loaded != 0) + debug3("%s: loaded %lu keys from %s", __func__, + ctx.num_loaded, host); +} void free_hostkeys(struct hostkeys *hostkeys) @@ -339,7 +296,7 @@ free_hostkeys(struct hostkeys *hostkeys) for (i = 0; i < hostkeys->num_entries; i++) { free(hostkeys->entries[i].host); free(hostkeys->entries[i].file); - key_free(hostkeys->entries[i].key); + sshkey_free(hostkeys->entries[i].key); explicit_bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); } free(hostkeys->entries); @@ -348,18 +305,18 @@ free_hostkeys(struct hostkeys *hostkeys) } static int -check_key_not_revoked(struct hostkeys *hostkeys, Key *k) +check_key_not_revoked(struct hostkeys *hostkeys, struct sshkey *k) { - int is_cert = key_is_cert(k); + int is_cert = sshkey_is_cert(k); u_int i; for (i = 0; i < hostkeys->num_entries; i++) { if (hostkeys->entries[i].marker != MRK_REVOKE) continue; - if (key_equal_public(k, hostkeys->entries[i].key)) + if (sshkey_equal_public(k, hostkeys->entries[i].key)) return -1; if (is_cert && - key_equal_public(k->cert->signature_key, + sshkey_equal_public(k->cert->signature_key, hostkeys->entries[i].key)) return -1; } @@ -383,11 +340,11 @@ check_key_not_revoked(struct hostkeys *hostkeys, Key *k) */ static HostStatus check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, - Key *k, int keytype, const struct hostkey_entry **found) + struct sshkey *k, int keytype, const struct hostkey_entry **found) { u_int i; HostStatus end_return = HOST_NEW; - int want_cert = key_is_cert(k); + int want_cert = sshkey_is_cert(k); HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE; int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2; @@ -411,7 +368,7 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, break; } if (want_cert) { - if (key_equal_public(k->cert->signature_key, + if (sshkey_equal_public(k->cert->signature_key, hostkeys->entries[i].key)) { /* A matching CA exists */ end_return = HOST_OK; @@ -420,7 +377,7 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, break; } } else { - if (key_equal(k, hostkeys->entries[i].key)) { + if (sshkey_equal(k, hostkeys->entries[i].key)) { end_return = HOST_OK; if (found != NULL) *found = hostkeys->entries + i; @@ -439,9 +396,9 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, } return end_return; } - + HostStatus -check_key_in_hostkeys(struct hostkeys *hostkeys, Key *key, +check_key_in_hostkeys(struct hostkeys *hostkeys, struct sshkey *key, const struct hostkey_entry **found) { if (key == NULL) @@ -457,40 +414,438 @@ lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, found) == HOST_FOUND); } +static int +write_host_entry(FILE *f, const char *host, const char *ip, + const struct sshkey *key, int store_hash) +{ + int r, success = 0; + char *hashed_host = NULL; + + if (store_hash) { + if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { + error("%s: host_hash failed", __func__); + return 0; + } + fprintf(f, "%s ", hashed_host); + } else if (ip != NULL) + fprintf(f, "%s,%s ", host, ip); + else + fprintf(f, "%s ", host); + + if ((r = sshkey_write(key, f)) == 0) + success = 1; + else + error("%s: sshkey_write failed: %s", __func__, ssh_err(r)); + fputc('\n', f); + return success; +} + /* * Appends an entry to the host file. Returns false if the entry could not * be appended. */ - int -add_host_to_hostfile(const char *filename, const char *host, const Key *key, - int store_hash) +add_host_to_hostfile(const char *filename, const char *host, + const struct sshkey *key, int store_hash) { FILE *f; - int success = 0; - char *hashed_host = NULL; + int success; if (key == NULL) return 1; /* XXX ? */ f = fopen(filename, "a"); if (!f) return 0; - - if (store_hash) { - if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { - error("add_host_to_hostfile: host_hash failed"); - fclose(f); - return 0; - } - } - fprintf(f, "%s ", store_hash ? hashed_host : host); - - if (key_write(key, f)) { - success = 1; - } else { - error("add_host_to_hostfile: saving key in %s failed", filename); - } - fprintf(f, "\n"); + success = write_host_entry(f, host, NULL, key, store_hash); fclose(f); return success; } + +struct host_delete_ctx { + FILE *out; + int quiet; + const char *host; + int *skip_keys; /* XXX split for host/ip? might want to ensure both */ + struct sshkey * const *keys; + size_t nkeys; + int modified; +}; + +static int +host_delete(struct hostkey_foreach_line *l, void *_ctx) +{ + struct host_delete_ctx *ctx = (struct host_delete_ctx *)_ctx; + int loglevel = ctx->quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; + size_t i; + + if (l->status == HKF_STATUS_MATCHED) { + if (l->marker != MRK_NONE) { + /* Don't remove CA and revocation lines */ + fprintf(ctx->out, "%s\n", l->line); + return 0; + } + + /* XXX might need a knob for this later */ + /* Don't remove RSA1 keys */ + if (l->key->type == KEY_RSA1) { + fprintf(ctx->out, "%s\n", l->line); + return 0; + } + + /* + * If this line contains one of the keys that we will be + * adding later, then don't change it and mark the key for + * skipping. + */ + for (i = 0; i < ctx->nkeys; i++) { + if (sshkey_equal(ctx->keys[i], l->key)) { + ctx->skip_keys[i] = 1; + fprintf(ctx->out, "%s\n", l->line); + debug3("%s: %s key already at %s:%ld", __func__, + sshkey_type(l->key), l->path, l->linenum); + return 0; + } + } + + /* + * Hostname matches and has no CA/revoke marker, delete it + * by *not* writing the line to ctx->out. + */ + do_log2(loglevel, "%s%s%s:%ld: Removed %s key for host %s", + ctx->quiet ? __func__ : "", ctx->quiet ? ": " : "", + l->path, l->linenum, sshkey_type(l->key), ctx->host); + ctx->modified = 1; + return 0; + } + /* Retain non-matching hosts and invalid lines when deleting */ + if (l->status == HKF_STATUS_INVALID) { + do_log2(loglevel, "%s%s%s:%ld: invalid known_hosts entry", + ctx->quiet ? __func__ : "", ctx->quiet ? ": " : "", + l->path, l->linenum); + } + fprintf(ctx->out, "%s\n", l->line); + return 0; +} + +int +hostfile_replace_entries(const char *filename, const char *host, const char *ip, + struct sshkey **keys, size_t nkeys, int store_hash, int quiet, int hash_alg) +{ + int r, fd, oerrno = 0; + int loglevel = quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_VERBOSE; + struct host_delete_ctx ctx; + char *fp, *temp = NULL, *back = NULL; + mode_t omask; + size_t i; + + omask = umask(077); + + memset(&ctx, 0, sizeof(ctx)); + ctx.host = host; + ctx.quiet = quiet; + if ((ctx.skip_keys = calloc(nkeys, sizeof(*ctx.skip_keys))) == NULL) + return SSH_ERR_ALLOC_FAIL; + ctx.keys = keys; + ctx.nkeys = nkeys; + ctx.modified = 0; + + /* + * Prepare temporary file for in-place deletion. + */ + if ((r = asprintf(&temp, "%s.XXXXXXXXXXX", filename)) < 0 || + (r = asprintf(&back, "%s.old", filename)) < 0) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + + if ((fd = mkstemp(temp)) == -1) { + oerrno = errno; + error("%s: mkstemp: %s", __func__, strerror(oerrno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + if ((ctx.out = fdopen(fd, "w")) == NULL) { + oerrno = errno; + close(fd); + error("%s: fdopen: %s", __func__, strerror(oerrno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + + /* Remove all entries for the specified host from the file */ + if ((r = hostkeys_foreach(filename, host_delete, &ctx, host, ip, + HKF_WANT_PARSE_KEY)) != 0) { + error("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); + goto fail; + } + + /* Add the requested keys */ + for (i = 0; i < nkeys; i++) { + if (ctx.skip_keys[i]) + continue; + if ((fp = sshkey_fingerprint(keys[i], hash_alg, + SSH_FP_DEFAULT)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + do_log2(loglevel, "%s%sAdding new key for %s to %s: %s %s", + quiet ? __func__ : "", quiet ? ": " : "", host, filename, + sshkey_ssh_name(keys[i]), fp); + free(fp); + if (!write_host_entry(ctx.out, host, ip, keys[i], store_hash)) { + r = SSH_ERR_INTERNAL_ERROR; + goto fail; + } + ctx.modified = 1; + } + fclose(ctx.out); + ctx.out = NULL; + + if (ctx.modified) { + /* Backup the original file and replace it with the temporary */ + if (unlink(back) == -1 && errno != ENOENT) { + oerrno = errno; + error("%s: unlink %.100s: %s", __func__, + back, strerror(errno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + if (link(filename, back) == -1) { + oerrno = errno; + error("%s: link %.100s to %.100s: %s", __func__, + filename, back, strerror(errno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + if (rename(temp, filename) == -1) { + oerrno = errno; + error("%s: rename \"%s\" to \"%s\": %s", __func__, + temp, filename, strerror(errno)); + r = SSH_ERR_SYSTEM_ERROR; + goto fail; + } + } else { + /* No changes made; just delete the temporary file */ + if (unlink(temp) != 0) + error("%s: unlink \"%s\": %s", __func__, + temp, strerror(errno)); + } + + /* success */ + r = 0; + fail: + if (temp != NULL && r != 0) + unlink(temp); + free(temp); + free(back); + if (ctx.out != NULL) + fclose(ctx.out); + free(ctx.skip_keys); + umask(omask); + if (r == SSH_ERR_SYSTEM_ERROR) + errno = oerrno; + return r; +} + +static int +match_maybe_hashed(const char *host, const char *names, int *was_hashed) +{ + int hashed = *names == HASH_DELIM; + const char *hashed_host; + size_t nlen = strlen(names); + + if (was_hashed != NULL) + *was_hashed = hashed; + if (hashed) { + if ((hashed_host = host_hash(host, names, nlen)) == NULL) + return -1; + return nlen == strlen(hashed_host) && + strncmp(hashed_host, names, nlen) == 0; + } + return match_hostname(host, names, nlen) == 1; +} + +int +hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, + const char *host, const char *ip, u_int options) +{ + FILE *f; + char line[8192], oline[8192], ktype[128]; + u_long linenum = 0; + char *cp, *cp2; + u_int kbits; + int hashed; + int s, r = 0; + struct hostkey_foreach_line lineinfo; + size_t l; + + memset(&lineinfo, 0, sizeof(lineinfo)); + if (host == NULL && (options & HKF_WANT_MATCH) != 0) + return SSH_ERR_INVALID_ARGUMENT; + if ((f = fopen(path, "r")) == NULL) + return SSH_ERR_SYSTEM_ERROR; + + debug3("%s: reading file \"%s\"", __func__, path); + while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { + line[strcspn(line, "\n")] = '\0'; + strlcpy(oline, line, sizeof(oline)); + + sshkey_free(lineinfo.key); + memset(&lineinfo, 0, sizeof(lineinfo)); + lineinfo.path = path; + lineinfo.linenum = linenum; + lineinfo.line = oline; + lineinfo.marker = MRK_NONE; + lineinfo.status = HKF_STATUS_OK; + lineinfo.keytype = KEY_UNSPEC; + + /* Skip any leading whitespace, comments and empty lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') { + if ((options & HKF_WANT_MATCH) == 0) { + lineinfo.status = HKF_STATUS_COMMENT; + if ((r = callback(&lineinfo, ctx)) != 0) + break; + } + continue; + } + + if ((lineinfo.marker = check_markers(&cp)) == MRK_ERROR) { + verbose("%s: invalid marker at %s:%lu", + __func__, path, linenum); + if ((options & HKF_WANT_MATCH) == 0) + goto bad; + continue; + } + + /* Find the end of the host name portion. */ + for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) + ; + lineinfo.hosts = cp; + *cp2++ = '\0'; + + /* Check if the host name matches. */ + if (host != NULL) { + if ((s = match_maybe_hashed(host, lineinfo.hosts, + &hashed)) == -1) { + debug2("%s: %s:%ld: bad host hash \"%.32s\"", + __func__, path, linenum, lineinfo.hosts); + goto bad; + } + if (s == 1) { + lineinfo.status = HKF_STATUS_MATCHED; + lineinfo.match |= HKF_MATCH_HOST | + (hashed ? HKF_MATCH_HOST_HASHED : 0); + } + /* Try matching IP address if supplied */ + if (ip != NULL) { + if ((s = match_maybe_hashed(ip, lineinfo.hosts, + &hashed)) == -1) { + debug2("%s: %s:%ld: bad ip hash " + "\"%.32s\"", __func__, path, + linenum, lineinfo.hosts); + goto bad; + } + if (s == 1) { + lineinfo.status = HKF_STATUS_MATCHED; + lineinfo.match |= HKF_MATCH_IP | + (hashed ? HKF_MATCH_IP_HASHED : 0); + } + } + /* + * Skip this line if host matching requested and + * neither host nor address matched. + */ + if ((options & HKF_WANT_MATCH) != 0 && + lineinfo.status != HKF_STATUS_MATCHED) + continue; + } + + /* Got a match. Skip host name and any following whitespace */ + for (; *cp2 == ' ' || *cp2 == '\t'; cp2++) + ; + if (*cp2 == '\0' || *cp2 == '#') { + debug2("%s:%ld: truncated before key type", + path, linenum); + goto bad; + } + lineinfo.rawkey = cp = cp2; + + if ((options & HKF_WANT_PARSE_KEY) != 0) { + /* + * Extract the key from the line. This will skip + * any leading whitespace. Ignore badly formatted + * lines. + */ + if ((lineinfo.key = sshkey_new(KEY_UNSPEC)) == NULL) { + error("%s: sshkey_new failed", __func__); + r = SSH_ERR_ALLOC_FAIL; + break; + } + if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) { +#ifdef WITH_SSH1 + sshkey_free(lineinfo.key); + lineinfo.key = sshkey_new(KEY_RSA1); + if (lineinfo.key == NULL) { + error("%s: sshkey_new fail", __func__); + r = SSH_ERR_ALLOC_FAIL; + break; + } + if (!hostfile_read_key(&cp, &kbits, + lineinfo.key)) + goto bad; +#else + goto bad; +#endif + } + lineinfo.keytype = lineinfo.key->type; + lineinfo.comment = cp; + } else { + /* Extract and parse key type */ + l = strcspn(lineinfo.rawkey, " \t"); + if (l <= 1 || l >= sizeof(ktype) || + lineinfo.rawkey[l] == '\0') + goto bad; + memcpy(ktype, lineinfo.rawkey, l); + ktype[l] = '\0'; + lineinfo.keytype = sshkey_type_from_name(ktype); +#ifdef WITH_SSH1 + /* + * Assume RSA1 if the first component is a short + * decimal number. + */ + if (lineinfo.keytype == KEY_UNSPEC && l < 8 && + strspn(ktype, "0123456789") == l) + lineinfo.keytype = KEY_RSA1; +#endif + /* + * Check that something other than whitespace follows + * the key type. This won't catch all corruption, but + * it does catch trivial truncation. + */ + cp2 += l; /* Skip past key type */ + for (; *cp2 == ' ' || *cp2 == '\t'; cp2++) + ; + if (*cp2 == '\0' || *cp2 == '#') { + debug2("%s:%ld: truncated after key type", + path, linenum); + lineinfo.keytype = KEY_UNSPEC; + } + if (lineinfo.keytype == KEY_UNSPEC) { + bad: + sshkey_free(lineinfo.key); + lineinfo.key = NULL; + lineinfo.status = HKF_STATUS_INVALID; + if ((r = callback(&lineinfo, ctx)) != 0) + break; + continue; + } + } + if ((r = callback(&lineinfo, ctx)) != 0) + break; + } + sshkey_free(lineinfo.key); + fclose(f); + return r; +} diff --git a/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h index 679c034f3f6e..bd2104373f82 100644 --- a/crypto/openssh/hostfile.h +++ b/crypto/openssh/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.20 2013/07/12 00:19:58 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.24 2015/02/16 22:08:57 djm Exp $ */ /* * Author: Tatu Ylonen @@ -26,7 +26,7 @@ struct hostkey_entry { char *host; char *file; u_long line; - Key *key; + struct sshkey *key; HostkeyMarker marker; }; struct hostkeys; @@ -35,13 +35,18 @@ struct hostkeys *init_hostkeys(void); void load_hostkeys(struct hostkeys *, const char *, const char *); void free_hostkeys(struct hostkeys *); -HostStatus check_key_in_hostkeys(struct hostkeys *, Key *, +HostStatus check_key_in_hostkeys(struct hostkeys *, struct sshkey *, const struct hostkey_entry **); int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, const struct hostkey_entry **); -int hostfile_read_key(char **, int *, Key *); -int add_host_to_hostfile(const char *, const char *, const Key *, int); +int hostfile_read_key(char **, u_int *, struct sshkey *); +int add_host_to_hostfile(const char *, const char *, + const struct sshkey *, int); + +int hostfile_replace_entries(const char *filename, + const char *host, const char *ip, struct sshkey **keys, size_t nkeys, + int store_hash, int quiet, int hash_alg); #define HASH_MAGIC "|1|" #define HASH_DELIM '|' @@ -51,4 +56,53 @@ int add_host_to_hostfile(const char *, const char *, const Key *, int); char *host_hash(const char *, const char *, u_int); +/* + * Iterate through a hostkeys file, optionally parsing keys and matching + * hostnames. Allows access to the raw keyfile lines to allow + * streaming edits to the file to take place. + */ +#define HKF_WANT_MATCH (1) /* return only matching hosts/addrs */ +#define HKF_WANT_PARSE_KEY (1<<1) /* need key parsed */ + +#define HKF_STATUS_OK 0 /* Line parsed, didn't match host */ +#define HKF_STATUS_INVALID 1 /* line had parse error */ +#define HKF_STATUS_COMMENT 2 /* valid line contained no key */ +#define HKF_STATUS_MATCHED 3 /* hostname or IP matched */ + +#define HKF_MATCH_HOST (1) /* hostname matched */ +#define HKF_MATCH_IP (1<<1) /* address matched */ +#define HKF_MATCH_HOST_HASHED (1<<2) /* hostname was hashed */ +#define HKF_MATCH_IP_HASHED (1<<3) /* address was hashed */ +/* XXX HKF_MATCH_KEY_TYPE? */ + +/* + * The callback function receives this as an argument for each matching + * hostkey line. The callback may "steal" the 'key' field by setting it to NULL. + * If a parse error occurred, then "hosts" and subsequent options may be NULL. + */ +struct hostkey_foreach_line { + const char *path; /* Path of file */ + u_long linenum; /* Line number */ + u_int status; /* One of HKF_STATUS_* */ + u_int match; /* Zero or more of HKF_MATCH_* OR'd together */ + char *line; /* Entire key line; mutable by callback */ + int marker; /* CA/revocation markers; indicated by MRK_* value */ + const char *hosts; /* Raw hosts text, may be hashed or list multiple */ + const char *rawkey; /* Text of key and any comment following it */ + int keytype; /* Type of key; KEY_UNSPEC for invalid/comment lines */ + struct sshkey *key; /* Key, if parsed ok and HKF_WANT_MATCH_HOST set */ + const char *comment; /* Any comment following the key */ +}; + +/* + * Callback fires for each line (or matching line if a HKF_WANT_* option + * is set). The foreach loop will terminate if the callback returns a non- + * zero exit status. + */ +typedef int hostkeys_foreach_fn(struct hostkey_foreach_line *l, void *ctx); + +/* Iterate over a hostkeys file */ +int hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx, + const char *host, const char *ip, u_int options); + #endif diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h index 07bcd89f2c42..2893a54cdc6b 100644 --- a/crypto/openssh/includes.h +++ b/crypto/openssh/includes.h @@ -23,10 +23,11 @@ #endif #include +#include #include /* For CMSG_* */ #ifdef HAVE_LIMITS_H -# include /* For PATH_MAX */ +# include /* For PATH_MAX, _POSIX_HOST_NAME_MAX */ #endif #ifdef HAVE_BSTRING_H # include @@ -166,7 +167,9 @@ # endif #endif +#ifdef WITH_OPENSSL #include /* For OPENSSL_VERSION_NUMBER */ +#endif #include "defines.h" diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c index a173e70e381c..8c2b00179db9 100644 --- a/crypto/openssh/kex.c +++ b/crypto/openssh/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.99 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: kex.c,v 1.105 2015/01/30 00:22:25 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -25,7 +25,7 @@ #include "includes.h" -#include +#include /* MAX roundup */ #include #include @@ -37,20 +37,22 @@ #include #endif -#include "xmalloc.h" #include "ssh2.h" -#include "buffer.h" #include "packet.h" #include "compat.h" #include "cipher.h" -#include "key.h" +#include "sshkey.h" #include "kex.h" #include "log.h" #include "mac.h" #include "match.h" +#include "misc.h" #include "dispatch.h" #include "monitor.h" #include "roaming.h" + +#include "ssherr.h" +#include "sshbuf.h" #include "digest.h" #if OPENSSL_VERSION_NUMBER >= 0x00907000L @@ -62,12 +64,12 @@ extern const EVP_MD *evp_ssh_sha256(void); #endif /* prototype */ -static void kex_kexinit_finish(Kex *); -static void kex_choose_conf(Kex *); +static int kex_choose_conf(struct ssh *); +static int kex_input_newkeys(int, u_int32_t, void *); struct kexalg { char *name; - int type; + u_int type; int ec_nid; int hash_alg; }; @@ -89,18 +91,17 @@ static const struct kexalg kexalgs[] = { SSH_DIGEST_SHA512 }, # endif /* OPENSSL_HAS_NISTP521 */ #endif /* OPENSSL_HAS_ECC */ - { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, #endif /* WITH_OPENSSL */ -#ifdef HAVE_EVP_SHA256 +#if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL) { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, -#endif /* HAVE_EVP_SHA256 */ +#endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, -1, -1, -1}, }; char * kex_alg_list(char sep) { - char *ret = NULL; + char *ret = NULL, *tmp; size_t nlen, rlen = 0; const struct kexalg *k; @@ -108,7 +109,11 @@ kex_alg_list(char sep) if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); - ret = xrealloc(ret, 1, rlen + nlen + 2); + if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { + free(ret); + return NULL; + } + ret = tmp; memcpy(ret + rlen, k->name, nlen + 1); rlen += nlen; } @@ -135,7 +140,8 @@ kex_names_valid(const char *names) if (names == NULL || strcmp(names, "") == 0) return 0; - s = cp = xstrdup(names); + if ((s = cp = strdup(names)) == NULL) + return 0; for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { if (kex_alg_by_name(p) == NULL) { @@ -150,56 +156,75 @@ kex_names_valid(const char *names) } /* put algorithm proposal into buffer */ -static void -kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) +int +kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) { u_int i; + int r; + + sshbuf_reset(b); - buffer_clear(b); /* * add a dummy cookie, the cookie will be overwritten by * kex_send_kexinit(), each time a kexinit is set */ - for (i = 0; i < KEX_COOKIE_LEN; i++) - buffer_put_char(b, 0); - for (i = 0; i < PROPOSAL_MAX; i++) - buffer_put_cstring(b, proposal[i]); - buffer_put_char(b, 0); /* first_kex_packet_follows */ - buffer_put_int(b, 0); /* uint32 reserved */ + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if ((r = sshbuf_put_u8(b, 0)) != 0) + return r; + } + for (i = 0; i < PROPOSAL_MAX; i++) { + if ((r = sshbuf_put_cstring(b, proposal[i])) != 0) + return r; + } + if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */ + (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */ + return r; + return 0; } /* parse buffer and return algorithm proposal */ -static char ** -kex_buf2prop(Buffer *raw, int *first_kex_follows) +int +kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp) { - Buffer b; + struct sshbuf *b = NULL; + u_char v; u_int i; - char **proposal; + char **proposal = NULL; + int r; - proposal = xcalloc(PROPOSAL_MAX, sizeof(char *)); - - buffer_init(&b); - buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); - /* skip cookie */ - for (i = 0; i < KEX_COOKIE_LEN; i++) - buffer_get_char(&b); + *propp = NULL; + if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((b = sshbuf_fromb(raw)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */ + goto out; /* extract kex init proposal strings */ for (i = 0; i < PROPOSAL_MAX; i++) { - proposal[i] = buffer_get_cstring(&b,NULL); + if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) + goto out; debug2("kex_parse_kexinit: %s", proposal[i]); } /* first kex follows / reserved */ - i = buffer_get_char(&b); + if ((r = sshbuf_get_u8(b, &v)) != 0 || + (r = sshbuf_get_u32(b, &i)) != 0) + goto out; if (first_kex_follows != NULL) *first_kex_follows = i; - debug2("kex_parse_kexinit: first_kex_follows %d ", i); - i = buffer_get_int(&b); + debug2("kex_parse_kexinit: first_kex_follows %d ", v); debug2("kex_parse_kexinit: reserved %u ", i); - buffer_free(&b); - return proposal; + r = 0; + *propp = proposal; + out: + if (r != 0 && proposal != NULL) + kex_prop_free(proposal); + sshbuf_free(b); + return r; } -static void +void kex_prop_free(char **proposal) { u_int i; @@ -210,97 +235,111 @@ kex_prop_free(char **proposal) } /* ARGSUSED */ -static void +static int kex_protocol_error(int type, u_int32_t seq, void *ctxt) { error("Hm, kex protocol error: type %d seq %u", type, seq); + return 0; } static void -kex_reset_dispatch(void) +kex_reset_dispatch(struct ssh *ssh) { - dispatch_range(SSH2_MSG_TRANSPORT_MIN, + ssh_dispatch_range(ssh, SSH2_MSG_TRANSPORT_MIN, SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); - dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); + ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); } -void -kex_finish(Kex *kex) +int +kex_send_newkeys(struct ssh *ssh) { - kex_reset_dispatch(); + int r; - packet_start(SSH2_MSG_NEWKEYS); - packet_send(); - /* packet_write_wait(); */ + kex_reset_dispatch(ssh); + if ((r = sshpkt_start(ssh, SSH2_MSG_NEWKEYS)) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; debug("SSH2_MSG_NEWKEYS sent"); - debug("expecting SSH2_MSG_NEWKEYS"); - packet_read_expect(SSH2_MSG_NEWKEYS); - packet_check_eom(); - debug("SSH2_MSG_NEWKEYS received"); + ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); + return 0; +} +static int +kex_input_newkeys(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + int r; + + debug("SSH2_MSG_NEWKEYS received"); + ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); + if ((r = sshpkt_get_end(ssh)) != 0) + return r; kex->done = 1; - buffer_clear(&kex->peer); - /* buffer_clear(&kex->my); */ + sshbuf_reset(kex->peer); + /* sshbuf_reset(kex->my); */ kex->flags &= ~KEX_INIT_SENT; free(kex->name); kex->name = NULL; + return 0; } -void -kex_send_kexinit(Kex *kex) +int +kex_send_kexinit(struct ssh *ssh) { - u_int32_t rnd = 0; u_char *cookie; - u_int i; + struct kex *kex = ssh->kex; + int r; - if (kex == NULL) { - error("kex_send_kexinit: no kex, cannot rekey"); - return; - } - if (kex->flags & KEX_INIT_SENT) { - debug("KEX_INIT_SENT"); - return; - } + if (kex == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (kex->flags & KEX_INIT_SENT) + return 0; kex->done = 0; /* generate a random cookie */ - if (buffer_len(&kex->my) < KEX_COOKIE_LEN) - fatal("kex_send_kexinit: kex proposal too short"); - cookie = buffer_ptr(&kex->my); - for (i = 0; i < KEX_COOKIE_LEN; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cookie[i] = rnd; - rnd >>= 8; - } - packet_start(SSH2_MSG_KEXINIT); - packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); - packet_send(); + if (sshbuf_len(kex->my) < KEX_COOKIE_LEN) + return SSH_ERR_INVALID_FORMAT; + if ((cookie = sshbuf_mutable_ptr(kex->my)) == NULL) + return SSH_ERR_INTERNAL_ERROR; + arc4random_buf(cookie, KEX_COOKIE_LEN); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0 || + (r = sshpkt_putb(ssh, kex->my)) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; debug("SSH2_MSG_KEXINIT sent"); kex->flags |= KEX_INIT_SENT; + return 0; } /* ARGSUSED */ -void +int kex_input_kexinit(int type, u_int32_t seq, void *ctxt) { - char *ptr; - u_int i, dlen; - Kex *kex = (Kex *)ctxt; + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + const u_char *ptr; + u_int i; + size_t dlen; + int r; debug("SSH2_MSG_KEXINIT received"); if (kex == NULL) - fatal("kex_input_kexinit: no kex, cannot rekey"); + return SSH_ERR_INVALID_ARGUMENT; - ptr = packet_get_raw(&dlen); - buffer_append(&kex->peer, ptr, dlen); + ptr = sshpkt_ptr(ssh, &dlen); + if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0) + return r; /* discard packet */ for (i = 0; i < KEX_COOKIE_LEN; i++) - packet_get_char(); + if ((r = sshpkt_get_u8(ssh, NULL)) != 0) + return r; for (i = 0; i < PROPOSAL_MAX; i++) - free(packet_get_string(NULL)); + if ((r = sshpkt_get_string(ssh, NULL, NULL)) != 0) + return r; /* * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported * KEX method has the server move first, but a server might be using @@ -311,55 +350,129 @@ kex_input_kexinit(int type, u_int32_t seq, void *ctxt) * for cases where the server *doesn't* go first. I guess we should * ignore it when it is set for these cases, which is what we do now. */ - (void) packet_get_char(); /* first_kex_follows */ - (void) packet_get_int(); /* reserved */ - packet_check_eom(); + if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || /* first_kex_follows */ + (r = sshpkt_get_u32(ssh, NULL)) != 0 || /* reserved */ + (r = sshpkt_get_end(ssh)) != 0) + return r; - kex_kexinit_finish(kex); -} - -Kex * -kex_setup(char *proposal[PROPOSAL_MAX]) -{ - Kex *kex; - - kex = xcalloc(1, sizeof(*kex)); - buffer_init(&kex->peer); - buffer_init(&kex->my); - kex_prop2buf(&kex->my, proposal); - kex->done = 0; - - kex_send_kexinit(kex); /* we start */ - kex_reset_dispatch(); - - return kex; -} - -static void -kex_kexinit_finish(Kex *kex) -{ if (!(kex->flags & KEX_INIT_SENT)) - kex_send_kexinit(kex); + if ((r = kex_send_kexinit(ssh)) != 0) + return r; + if ((r = kex_choose_conf(ssh)) != 0) + return r; - kex_choose_conf(kex); + if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL) + return (kex->kex[kex->kex_type])(ssh); - if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && - kex->kex[kex->kex_type] != NULL) { - (kex->kex[kex->kex_type])(kex); - } else { - fatal("Unsupported key exchange %d", kex->kex_type); - } + return SSH_ERR_INTERNAL_ERROR; } -static void -choose_enc(Enc *enc, char *client, char *server) +int +kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], struct kex **kexp) +{ + struct kex *kex; + int r; + + *kexp = NULL; + if ((kex = calloc(1, sizeof(*kex))) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((kex->peer = sshbuf_new()) == NULL || + (kex->my = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = kex_prop2buf(kex->my, proposal)) != 0) + goto out; + kex->done = 0; + kex_reset_dispatch(ssh); + r = 0; + *kexp = kex; + out: + if (r != 0) + kex_free(kex); + return r; +} + +void +kex_free_newkeys(struct newkeys *newkeys) +{ + if (newkeys == NULL) + return; + if (newkeys->enc.key) { + explicit_bzero(newkeys->enc.key, newkeys->enc.key_len); + free(newkeys->enc.key); + newkeys->enc.key = NULL; + } + if (newkeys->enc.iv) { + explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size); + free(newkeys->enc.iv); + newkeys->enc.iv = NULL; + } + free(newkeys->enc.name); + explicit_bzero(&newkeys->enc, sizeof(newkeys->enc)); + free(newkeys->comp.name); + explicit_bzero(&newkeys->comp, sizeof(newkeys->comp)); + mac_clear(&newkeys->mac); + if (newkeys->mac.key) { + explicit_bzero(newkeys->mac.key, newkeys->mac.key_len); + free(newkeys->mac.key); + newkeys->mac.key = NULL; + } + free(newkeys->mac.name); + explicit_bzero(&newkeys->mac, sizeof(newkeys->mac)); + explicit_bzero(newkeys, sizeof(*newkeys)); + free(newkeys); +} + +void +kex_free(struct kex *kex) +{ + u_int mode; + +#ifdef WITH_OPENSSL + if (kex->dh) + DH_free(kex->dh); +#ifdef OPENSSL_HAS_ECC + if (kex->ec_client_key) + EC_KEY_free(kex->ec_client_key); +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + for (mode = 0; mode < MODE_MAX; mode++) { + kex_free_newkeys(kex->newkeys[mode]); + kex->newkeys[mode] = NULL; + } + sshbuf_free(kex->peer); + sshbuf_free(kex->my); + free(kex->session_id); + free(kex->client_version_string); + free(kex->server_version_string); + free(kex); +} + +int +kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) +{ + int r; + + if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) + return r; + if ((r = kex_send_kexinit(ssh)) != 0) { /* we start */ + kex_free(ssh->kex); + ssh->kex = NULL; + return r; + } + return 0; +} + +static int +choose_enc(struct sshenc *enc, char *client, char *server) { char *name = match_list(client, server, NULL); + if (name == NULL) - fatal("no matching cipher found: client %s server %s", - client, server); + return SSH_ERR_NO_CIPHER_ALG_MATCH; if ((enc->cipher = cipher_by_name(name)) == NULL) - fatal("matching cipher is not supported: %s", name); + return SSH_ERR_INTERNAL_ERROR; enc->name = name; enc->enabled = 0; enc->iv = NULL; @@ -367,31 +480,34 @@ choose_enc(Enc *enc, char *client, char *server) enc->key = NULL; enc->key_len = cipher_keylen(enc->cipher); enc->block_size = cipher_blocksize(enc->cipher); + return 0; } -static void -choose_mac(Mac *mac, char *client, char *server) +static int +choose_mac(struct ssh *ssh, struct sshmac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); + if (name == NULL) - fatal("no matching mac found: client %s server %s", - client, server); + return SSH_ERR_NO_MAC_ALG_MATCH; if (mac_setup(mac, name) < 0) - fatal("unsupported mac %s", name); + return SSH_ERR_INTERNAL_ERROR; /* truncate the key */ - if (datafellows & SSH_BUG_HMAC) + if (ssh->compat & SSH_BUG_HMAC) mac->key_len = 16; mac->name = name; mac->key = NULL; mac->enabled = 0; + return 0; } -static void -choose_comp(Comp *comp, char *client, char *server) +static int +choose_comp(struct sshcomp *comp, char *client, char *server) { char *name = match_list(client, server, NULL); + if (name == NULL) - fatal("no matching comp found: client %s server %s", client, server); + return SSH_ERR_NO_COMPRESS_ALG_MATCH; if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; } else if (strcmp(name, "zlib") == 0) { @@ -399,36 +515,42 @@ choose_comp(Comp *comp, char *client, char *server) } else if (strcmp(name, "none") == 0) { comp->type = COMP_NONE; } else { - fatal("unsupported comp %s", name); + return SSH_ERR_INTERNAL_ERROR; } comp->name = name; + return 0; } -static void -choose_kex(Kex *k, char *client, char *server) +static int +choose_kex(struct kex *k, char *client, char *server) { const struct kexalg *kexalg; k->name = match_list(client, server, NULL); + if (k->name == NULL) - fatal("Unable to negotiate a key exchange method"); + return SSH_ERR_NO_KEX_ALG_MATCH; if ((kexalg = kex_alg_by_name(k->name)) == NULL) - fatal("unsupported kex alg %s", k->name); + return SSH_ERR_INTERNAL_ERROR; k->kex_type = kexalg->type; k->hash_alg = kexalg->hash_alg; k->ec_nid = kexalg->ec_nid; + return 0; } -static void -choose_hostkeyalg(Kex *k, char *client, char *server) +static int +choose_hostkeyalg(struct kex *k, char *client, char *server) { char *hostkeyalg = match_list(client, server, NULL); + if (hostkeyalg == NULL) - fatal("no hostkey alg"); - k->hostkey_type = key_type_from_name(hostkeyalg); + return SSH_ERR_NO_HOSTKEY_ALG_MATCH; + k->hostkey_type = sshkey_type_from_name(hostkeyalg); if (k->hostkey_type == KEY_UNSPEC) - fatal("bad hostkey alg '%s'", hostkeyalg); + return SSH_ERR_INTERNAL_ERROR; + k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg); free(hostkeyalg); + return 0; } static int @@ -455,18 +577,20 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) return (1); } -static void -kex_choose_conf(Kex *kex) +static int +kex_choose_conf(struct ssh *ssh) { - Newkeys *newkeys; - char **my, **peer; + struct kex *kex = ssh->kex; + struct newkeys *newkeys; + char **my = NULL, **peer = NULL; char **cprop, **sprop; int nenc, nmac, ncomp; u_int mode, ctos, need, dh_need, authlen; - int first_kex_follows, type; + int r, first_kex_follows; - my = kex_buf2prop(&kex->my, NULL); - peer = kex_buf2prop(&kex->peer, &first_kex_follows); + if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 || + (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) + goto out; if (kex->server) { cprop=peer; @@ -478,8 +602,9 @@ kex_choose_conf(Kex *kex) /* Check whether server offers roaming */ if (!kex->server) { - char *roaming; - roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); + char *roaming = match_list(KEX_RESUME, + peer[PROPOSAL_KEX_ALGS], NULL); + if (roaming) { kex->roaming = 1; free(roaming); @@ -488,28 +613,39 @@ kex_choose_conf(Kex *kex) /* Algorithm Negotiation */ for (mode = 0; mode < MODE_MAX; mode++) { - newkeys = xcalloc(1, sizeof(*newkeys)); + if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } kex->newkeys[mode] = newkeys; ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; - choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]); - /* ignore mac for authenticated encryption */ + if ((r = choose_enc(&newkeys->enc, cprop[nenc], + sprop[nenc])) != 0) + goto out; authlen = cipher_authlen(newkeys->enc.cipher); - if (authlen == 0) - choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]); - choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); + /* ignore mac for authenticated encryption */ + if (authlen == 0 && + (r = choose_mac(ssh, &newkeys->mac, cprop[nmac], + sprop[nmac])) != 0) + goto out; + if ((r = choose_comp(&newkeys->comp, cprop[ncomp], + sprop[ncomp])) != 0) + goto out; debug("kex: %s %s %s %s", ctos ? "client->server" : "server->client", newkeys->enc.name, authlen == 0 ? newkeys->mac.name : "", newkeys->comp.name); } - choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); - choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], - sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], + sprop[PROPOSAL_KEX_ALGS])) != 0 || + (r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) + goto out; need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; @@ -528,45 +664,47 @@ kex_choose_conf(Kex *kex) /* ignore the next message if the proposals do not match */ if (first_kex_follows && !proposals_match(my, peer) && - !(datafellows & SSH_BUG_FIRSTKEX)) { - type = packet_read(); - debug2("skipping next packet (type %u)", type); - } - + !(ssh->compat & SSH_BUG_FIRSTKEX)) + ssh->dispatch_skip_packets = 1; + r = 0; + out: kex_prop_free(my); kex_prop_free(peer); + return r; } -static u_char * -derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, - const u_char *shared_secret, u_int slen) +static int +derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, + const struct sshbuf *shared_secret, u_char **keyp) { - Buffer b; - struct ssh_digest_ctx *hashctx; + struct kex *kex = ssh->kex; + struct ssh_digest_ctx *hashctx = NULL; char c = id; u_int have; size_t mdsz; u_char *digest; + int r; if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0) - fatal("bad kex md size %zu", mdsz); - digest = xmalloc(roundup(need, mdsz)); - - buffer_init(&b); - buffer_append(&b, shared_secret, slen); + return SSH_ERR_INVALID_ARGUMENT; + if ((digest = calloc(1, roundup(need, mdsz))) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } /* K1 = HASH(K || H || "A" || session_id) */ - if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) - fatal("%s: ssh_digest_start failed", __func__); - if (ssh_digest_update_buffer(hashctx, &b) != 0 || + if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || + ssh_digest_update_buffer(hashctx, shared_secret) != 0 || ssh_digest_update(hashctx, hash, hashlen) != 0 || ssh_digest_update(hashctx, &c, 1) != 0 || ssh_digest_update(hashctx, kex->session_id, - kex->session_id_len) != 0) - fatal("%s: ssh_digest_update failed", __func__); - if (ssh_digest_final(hashctx, digest, mdsz) != 0) - fatal("%s: ssh_digest_final failed", __func__); + kex->session_id_len) != 0 || + ssh_digest_final(hashctx, digest, mdsz) != 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ssh_digest_free(hashctx); + hashctx = NULL; /* * expand key: @@ -574,107 +712,115 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, * Key = K1 || K2 || ... || Kn */ for (have = mdsz; need > have; have += mdsz) { - if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL) - fatal("%s: ssh_digest_start failed", __func__); - if (ssh_digest_update_buffer(hashctx, &b) != 0 || + if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL || + ssh_digest_update_buffer(hashctx, shared_secret) != 0 || ssh_digest_update(hashctx, hash, hashlen) != 0 || - ssh_digest_update(hashctx, digest, have) != 0) - fatal("%s: ssh_digest_update failed", __func__); - if (ssh_digest_final(hashctx, digest + have, mdsz) != 0) - fatal("%s: ssh_digest_final failed", __func__); + ssh_digest_update(hashctx, digest, have) != 0 || + ssh_digest_final(hashctx, digest + have, mdsz) != 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } ssh_digest_free(hashctx); + hashctx = NULL; } - buffer_free(&b); #ifdef DEBUG_KEX fprintf(stderr, "key '%c'== ", c); dump_digest("key", digest, need); #endif - return digest; + *keyp = digest; + digest = NULL; + r = 0; + out: + if (digest) + free(digest); + ssh_digest_free(hashctx); + return r; } -Newkeys *current_keys[MODE_MAX]; - #define NKEYS 6 -void -kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, - const u_char *shared_secret, u_int slen) +int +kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen, + const struct sshbuf *shared_secret) { + struct kex *kex = ssh->kex; u_char *keys[NKEYS]; - u_int i, mode, ctos; + u_int i, j, mode, ctos; + int r; for (i = 0; i < NKEYS; i++) { - keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, - shared_secret, slen); + if ((r = derive_key(ssh, 'A'+i, kex->we_need, hash, hashlen, + shared_secret, &keys[i])) != 0) { + for (j = 0; j < i; j++) + free(keys[j]); + return r; + } } - - debug2("kex_derive_keys"); for (mode = 0; mode < MODE_MAX; mode++) { - current_keys[mode] = kex->newkeys[mode]; - kex->newkeys[mode] = NULL; ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); - current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; - current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; - current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; + kex->newkeys[mode]->enc.iv = keys[ctos ? 0 : 1]; + kex->newkeys[mode]->enc.key = keys[ctos ? 2 : 3]; + kex->newkeys[mode]->mac.key = keys[ctos ? 4 : 5]; } + return 0; } #ifdef WITH_OPENSSL -void -kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret) +int +kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen, + const BIGNUM *secret) { - Buffer shared_secret; + struct sshbuf *shared_secret; + int r; - buffer_init(&shared_secret); - buffer_put_bignum2(&shared_secret, secret); - kex_derive_keys(kex, hash, hashlen, - buffer_ptr(&shared_secret), buffer_len(&shared_secret)); - buffer_free(&shared_secret); + if ((shared_secret = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0) + r = kex_derive_keys(ssh, hash, hashlen, shared_secret); + sshbuf_free(shared_secret); + return r; } #endif -Newkeys * -kex_get_newkeys(int mode) -{ - Newkeys *ret; - - ret = current_keys[mode]; - current_keys[mode] = NULL; - return ret; -} - #ifdef WITH_SSH1 -void +int derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, u_int8_t cookie[8], u_int8_t id[16]) { - u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH]; - int len; - struct ssh_digest_ctx *hashctx; + u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH]; + struct ssh_digest_ctx *hashctx = NULL; + size_t hlen, slen; + int r; - if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) - fatal("%s: ssh_digest_start", __func__); - - len = BN_num_bytes(host_modulus); - if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) - fatal("%s: bad host modulus (len %d)", __func__, len); - BN_bn2bin(host_modulus, nbuf); - if (ssh_digest_update(hashctx, nbuf, len) != 0) - fatal("%s: ssh_digest_update failed", __func__); - - len = BN_num_bytes(server_modulus); - if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) - fatal("%s: bad server modulus (len %d)", __func__, len); - BN_bn2bin(server_modulus, nbuf); - if (ssh_digest_update(hashctx, nbuf, len) != 0 || - ssh_digest_update(hashctx, cookie, 8) != 0) - fatal("%s: ssh_digest_update failed", __func__); - if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) - fatal("%s: ssh_digest_final failed", __func__); + hlen = BN_num_bytes(host_modulus); + slen = BN_num_bytes(server_modulus); + if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) || + slen < (512 / 8) || (u_int)slen > sizeof(sbuf)) + return SSH_ERR_KEY_BITS_MISMATCH; + if (BN_bn2bin(host_modulus, hbuf) <= 0 || + BN_bn2bin(server_modulus, sbuf) <= 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (ssh_digest_update(hashctx, hbuf, hlen) != 0 || + ssh_digest_update(hashctx, sbuf, slen) != 0 || + ssh_digest_update(hashctx, cookie, 8) != 0 || + ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5)); - - explicit_bzero(nbuf, sizeof(nbuf)); + r = 0; + out: + ssh_digest_free(hashctx); + explicit_bzero(hbuf, sizeof(hbuf)); + explicit_bzero(sbuf, sizeof(sbuf)); explicit_bzero(obuf, sizeof(obuf)); + return r; } #endif @@ -682,16 +828,7 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, void dump_digest(char *msg, u_char *digest, int len) { - int i; - fprintf(stderr, "%s\n", msg); - for (i = 0; i < len; i++) { - fprintf(stderr, "%02x", digest[i]); - if (i%32 == 31) - fprintf(stderr, "\n"); - else if (i%8 == 7) - fprintf(stderr, " "); - } - fprintf(stderr, "\n"); + sshbuf_dump_data(digest, len, stderr); } #endif diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h index 4c40ec851859..f70b81fc143e 100644 --- a/crypto/openssh/kex.h +++ b/crypto/openssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.64 2014/05/02 03:27:54 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.71 2015/02/16 22:13:32 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -26,13 +26,28 @@ #ifndef KEX_H #define KEX_H -#include -#include -#include -#ifdef OPENSSL_HAS_ECC -#include +#include "mac.h" +#include "buffer.h" /* XXX for typedef */ +#include "key.h" /* XXX for typedef */ + +#ifdef WITH_LEAKMALLOC +#include "leakmalloc.h" #endif +#ifdef WITH_OPENSSL +# ifdef OPENSSL_HAS_ECC +# include +# else /* OPENSSL_HAS_ECC */ +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +# endif /* OPENSSL_HAS_ECC */ +#else /* WITH_OPENSSL */ +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +#endif /* WITH_OPENSSL */ + #define KEX_COOKIE_LEN 16 #define KEX_DH1 "diffie-hellman-group1-sha1" @@ -49,6 +64,8 @@ #define COMP_ZLIB 1 #define COMP_DELAYED 2 +#define CURVE25519_SIZE 32 + enum kex_init_proposals { PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, @@ -81,15 +98,9 @@ enum kex_exchange { #define KEX_INIT_SENT 0x0001 -typedef struct Kex Kex; -typedef struct Mac Mac; -typedef struct Comp Comp; -typedef struct Enc Enc; -typedef struct Newkeys Newkeys; - -struct Enc { +struct sshenc { char *name; - const Cipher *cipher; + const struct sshcipher *cipher; int enabled; u_int key_len; u_int iv_len; @@ -97,108 +108,120 @@ struct Enc { u_char *key; u_char *iv; }; -struct Mac { - char *name; - int enabled; - u_int mac_len; - u_char *key; - u_int key_len; - int type; - int etm; /* Encrypt-then-MAC */ - struct ssh_hmac_ctx *hmac_ctx; - struct umac_ctx *umac_ctx; -}; -struct Comp { - int type; +struct sshcomp { + u_int type; int enabled; char *name; }; -struct Newkeys { - Enc enc; - Mac mac; - Comp comp; +struct newkeys { + struct sshenc enc; + struct sshmac mac; + struct sshcomp comp; }; -struct Kex { + +struct ssh; + +struct kex { u_char *session_id; - u_int session_id_len; - Newkeys *newkeys[MODE_MAX]; + size_t session_id_len; + struct newkeys *newkeys[MODE_MAX]; u_int we_need; u_int dh_need; int server; char *name; int hostkey_type; - int kex_type; + int hostkey_nid; + u_int kex_type; int roaming; - Buffer my; - Buffer peer; + struct sshbuf *my; + struct sshbuf *peer; sig_atomic_t done; - int flags; + u_int flags; int hash_alg; int ec_nid; char *client_version_string; char *server_version_string; - int (*verify_host_key)(Key *); - Key *(*load_host_public_key)(int); - Key *(*load_host_private_key)(int); - int (*host_key_index)(Key *); - void (*sign)(Key *, Key *, u_char **, u_int *, u_char *, u_int); - void (*kex[KEX_MAX])(Kex *); + int (*verify_host_key)(struct sshkey *, struct ssh *); + struct sshkey *(*load_host_public_key)(int, int, struct ssh *); + struct sshkey *(*load_host_private_key)(int, int, struct ssh *); + int (*host_key_index)(struct sshkey *, int, struct ssh *); + int (*sign)(struct sshkey *, struct sshkey *, + u_char **, size_t *, const u_char *, size_t, u_int); + int (*kex[KEX_MAX])(struct ssh *); + /* kex specific state */ + DH *dh; /* DH */ + u_int min, max, nbits; /* GEX */ + EC_KEY *ec_client_key; /* ECDH */ + const EC_GROUP *ec_group; /* ECDH */ + u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 */ + u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ }; int kex_names_valid(const char *); char *kex_alg_list(char); -Kex *kex_setup(char *[PROPOSAL_MAX]); -void kex_finish(Kex *); +int kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **); +int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); +void kex_free_newkeys(struct newkeys *); +void kex_free(struct kex *); -void kex_send_kexinit(Kex *); -void kex_input_kexinit(int, u_int32_t, void *); -void kex_derive_keys(Kex *, u_char *, u_int, const u_char *, u_int); -void kex_derive_keys_bn(Kex *, u_char *, u_int, const BIGNUM *); +int kex_buf2prop(struct sshbuf *, int *, char ***); +int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); +void kex_prop_free(char **); -Newkeys *kex_get_newkeys(int); +int kex_send_kexinit(struct ssh *); +int kex_input_kexinit(int, u_int32_t, void *); +int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); +int kex_derive_keys_bn(struct ssh *, u_char *, u_int, const BIGNUM *); +int kex_send_newkeys(struct ssh *); -void kexdh_client(Kex *); -void kexdh_server(Kex *); -void kexgex_client(Kex *); -void kexgex_server(Kex *); -void kexecdh_client(Kex *); -void kexecdh_server(Kex *); -void kexc25519_client(Kex *); -void kexc25519_server(Kex *); +int kexdh_client(struct ssh *); +int kexdh_server(struct ssh *); +int kexgex_client(struct ssh *); +int kexgex_server(struct ssh *); +int kexecdh_client(struct ssh *); +int kexecdh_server(struct ssh *); +int kexc25519_client(struct ssh *); +int kexc25519_server(struct ssh *); -void -kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, - BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); -void -kexgex_hash(int, char *, char *, char *, int, char *, - int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, - BIGNUM *, BIGNUM *, u_char **, u_int *); -#ifdef OPENSSL_HAS_ECC -void -kex_ecdh_hash(int, const EC_GROUP *, char *, char *, char *, int, - char *, int, u_char *, int, const EC_POINT *, const EC_POINT *, - const BIGNUM *, u_char **, u_int *); -#endif -void -kex_c25519_hash(int, char *, char *, char *, int, - char *, int, u_char *, int, const u_char *, const u_char *, - const u_char *, u_int, u_char **, u_int *); +int kex_dh_hash(const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, + const BIGNUM *, const BIGNUM *, const BIGNUM *, u_char *, size_t *); -#define CURVE25519_SIZE 32 -void kexc25519_keygen(u_char[CURVE25519_SIZE], u_char[CURVE25519_SIZE]) +int kexgex_hash(int, const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, + int, int, int, + const BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, + u_char *, size_t *); + +int kex_ecdh_hash(int, const EC_GROUP *, const char *, const char *, + const u_char *, size_t, const u_char *, size_t, const u_char *, size_t, + const EC_POINT *, const EC_POINT *, const BIGNUM *, u_char *, size_t *); + +int kex_c25519_hash(int, const char *, const char *, const char *, size_t, + const char *, size_t, const u_char *, size_t, const u_char *, const u_char *, + const u_char *, size_t, u_char *, size_t *); + +void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -void kexc25519_shared_key(const u_char key[CURVE25519_SIZE], - const u_char pub[CURVE25519_SIZE], Buffer *out) +int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], + const u_char pub[CURVE25519_SIZE], struct sshbuf *out) __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); -void +int derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) void dump_digest(char *, u_char *, int); #endif +#if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) +# undef EC_KEY +# undef EC_GROUP +# undef EC_POINT +#endif + #endif diff --git a/crypto/openssh/kexc25519.c b/crypto/openssh/kexc25519.c index e3afa005512a..b6e6c4010824 100644 --- a/crypto/openssh/kexc25519.c +++ b/crypto/openssh/kexc25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexc25519.c,v 1.7 2014/05/02 03:27:54 djm Exp $ */ +/* $OpenBSD: kexc25519.c,v 1.8 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -35,13 +35,14 @@ #include #include -#include "buffer.h" +#include "sshbuf.h" #include "ssh2.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" #include "log.h" #include "digest.h" +#include "ssherr.h" extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) @@ -58,65 +59,70 @@ kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) crypto_scalarmult_curve25519(pub, key, basepoint); } -void +int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], - const u_char pub[CURVE25519_SIZE], Buffer *out) + const u_char pub[CURVE25519_SIZE], struct sshbuf *out) { u_char shared_key[CURVE25519_SIZE]; + int r; crypto_scalarmult_curve25519(shared_key, key, pub); #ifdef DEBUG_KEXECDH dump_digest("shared secret", shared_key, CURVE25519_SIZE); #endif - buffer_clear(out); - buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); + sshbuf_reset(out); + r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE); explicit_bzero(shared_key, CURVE25519_SIZE); + return r; } -void +int kex_c25519_hash( int hash_alg, - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, + const char *client_version_string, + const char *server_version_string, + const char *ckexinit, size_t ckexinitlen, + const char *skexinit, size_t skexinitlen, + const u_char *serverhostkeyblob, size_t sbloblen, const u_char client_dh_pub[CURVE25519_SIZE], const u_char server_dh_pub[CURVE25519_SIZE], - const u_char *shared_secret, u_int secretlen, - u_char **hash, u_int *hashlen) + const u_char *shared_secret, size_t secretlen, + u_char *hash, size_t *hashlen) { - Buffer b; - static u_char digest[SSH_DIGEST_MAX_LENGTH]; - - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - buffer_put_string(&b, client_dh_pub, CURVE25519_SIZE); - buffer_put_string(&b, server_dh_pub, CURVE25519_SIZE); - buffer_append(&b, shared_secret, secretlen); + struct sshbuf *b; + int r; + if (*hashlen < ssh_digest_bytes(hash_alg)) + return SSH_ERR_INVALID_ARGUMENT; + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 || + (r = sshbuf_put_cstring(b, server_version_string)) < 0 || + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || + (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 || + (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || + (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 || + (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 || + (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 || + (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 || + (r = sshbuf_put(b, shared_secret, secretlen)) < 0) { + sshbuf_free(b); + return r; + } #ifdef DEBUG_KEX - buffer_dump(&b); + sshbuf_dump(b, stderr); #endif - if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) - fatal("%s: digest_buffer failed", __func__); - - buffer_free(&b); - -#ifdef DEBUG_KEX - dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); -#endif - *hash = digest; + if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { + sshbuf_free(b); + return SSH_ERR_LIBCRYPTO_ERROR; + } + sshbuf_free(b); *hashlen = ssh_digest_bytes(hash_alg); +#ifdef DEBUG_KEX + dump_digest("hash", hash, *hashlen); +#endif + return 0; } diff --git a/crypto/openssh/kexc25519c.c b/crypto/openssh/kexc25519c.c index a80678af6c01..b7ef65dc31ae 100644 --- a/crypto/openssh/kexc25519c.c +++ b/crypto/openssh/kexc25519c.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexc25519c.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ +/* $OpenBSD: kexc25519c.c,v 1.7 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -33,97 +33,138 @@ #include #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" #include "log.h" #include "packet.h" #include "ssh2.h" +#include "sshbuf.h" +#include "digest.h" +#include "ssherr.h" -void -kexc25519_client(Kex *kex) +static int +input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt); + +int +kexc25519_client(struct ssh *ssh) { - Key *server_host_key; - u_char client_key[CURVE25519_SIZE]; - u_char client_pubkey[CURVE25519_SIZE]; - u_char *server_pubkey = NULL; - u_char *server_host_key_blob = NULL, *signature = NULL; - u_char *hash; - u_int slen, sbloblen, hashlen; - Buffer shared_secret; - - kexc25519_keygen(client_key, client_pubkey); - - packet_start(SSH2_MSG_KEX_ECDH_INIT); - packet_put_string(client_pubkey, sizeof(client_pubkey)); - packet_send(); - debug("sending SSH2_MSG_KEX_ECDH_INIT"); + struct kex *kex = ssh->kex; + int r; + kexc25519_keygen(kex->c25519_client_key, kex->c25519_client_pubkey); #ifdef DEBUG_KEXECDH - dump_digest("client private key:", client_key, sizeof(client_key)); + dump_digest("client private key:", kex->c25519_client_key, + sizeof(kex->c25519_client_key)); #endif + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 || + (r = sshpkt_put_string(ssh, kex->c25519_client_pubkey, + sizeof(kex->c25519_client_pubkey))) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); - packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_c25519_reply); + return 0; +} + +static int +input_kex_c25519_reply(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + struct sshkey *server_host_key = NULL; + struct sshbuf *shared_secret = NULL; + u_char *server_pubkey = NULL; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t slen, pklen, sbloblen, hashlen; + int r; + + if (kex->verify_host_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } /* hostkey */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); + if ((r = sshpkt_get_string(ssh, &server_host_key_blob, + &sbloblen)) != 0 || + (r = sshkey_from_blob(server_host_key_blob, sbloblen, + &server_host_key)) != 0) + goto out; + if (server_host_key->type != kex->hostkey_type || + (kex->hostkey_type == KEY_ECDSA && + server_host_key->ecdsa_nid != kex->hostkey_nid)) { + r = SSH_ERR_KEY_TYPE_MISMATCH; + goto out; + } + if (kex->verify_host_key(server_host_key, ssh) == -1) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } /* Q_S, server public key */ - server_pubkey = packet_get_string(&slen); - if (slen != CURVE25519_SIZE) - fatal("Incorrect size for server Curve25519 pubkey: %d", slen); + /* signed H */ + if ((r = sshpkt_get_string(ssh, &server_pubkey, &pklen)) != 0 || + (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; + if (pklen != CURVE25519_SIZE) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } #ifdef DEBUG_KEXECDH dump_digest("server public key:", server_pubkey, CURVE25519_SIZE); #endif - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - buffer_init(&shared_secret); - kexc25519_shared_key(client_key, server_pubkey, &shared_secret); + if ((shared_secret = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = kexc25519_shared_key(kex->c25519_client_key, server_pubkey, + shared_secret)) < 0) + goto out; /* calc and verify H */ - kex_c25519_hash( + hashlen = sizeof(hash); + if ((r = kex_c25519_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, - client_pubkey, + kex->c25519_client_pubkey, server_pubkey, - buffer_ptr(&shared_secret), buffer_len(&shared_secret), - &hash, &hashlen - ); - free(server_host_key_blob); - free(server_pubkey); - if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - free(signature); + sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), + hash, &hashlen)) < 0) + goto out; + + if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, + ssh->compat)) != 0) + goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys(kex, hash, hashlen, - buffer_ptr(&shared_secret), buffer_len(&shared_secret)); - buffer_free(&shared_secret); - kex_finish(kex); + + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); +out: + explicit_bzero(hash, sizeof(hash)); + explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); + free(server_host_key_blob); + free(server_pubkey); + free(signature); + sshkey_free(server_host_key); + sshbuf_free(shared_secret); + return r; } diff --git a/crypto/openssh/kexc25519s.c b/crypto/openssh/kexc25519s.c index 2b8e8efa175c..b2d2c858f84d 100644 --- a/crypto/openssh/kexc25519s.c +++ b/crypto/openssh/kexc25519s.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexc25519s.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ +/* $OpenBSD: kexc25519s.c,v 1.8 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -30,97 +30,129 @@ #include #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "ssh2.h" +#include "sshbuf.h" +#include "ssherr.h" -void -kexc25519_server(Kex *kex) +static int input_kex_c25519_init(int, u_int32_t, void *); + +int +kexc25519_server(struct ssh *ssh) { - Key *server_host_private, *server_host_public; + debug("expecting SSH2_MSG_KEX_ECDH_INIT"); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_c25519_init); + return 0; +} + +static int +input_kex_c25519_init(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + struct sshkey *server_host_private, *server_host_public; + struct sshbuf *shared_secret = NULL; u_char *server_host_key_blob = NULL, *signature = NULL; u_char server_key[CURVE25519_SIZE]; u_char *client_pubkey = NULL; u_char server_pubkey[CURVE25519_SIZE]; - u_char *hash; - u_int slen, sbloblen, hashlen; - Buffer shared_secret; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t slen, pklen, sbloblen, hashlen; + int r; /* generate private key */ kexc25519_keygen(server_key, server_pubkey); #ifdef DEBUG_KEXECDH dump_digest("server private key:", server_key, sizeof(server_key)); #endif - if (kex->load_host_public_key == NULL || - kex->load_host_private_key == NULL) - fatal("Cannot load hostkey"); - server_host_public = kex->load_host_public_key(kex->hostkey_type); - if (server_host_public == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - server_host_private = kex->load_host_private_key(kex->hostkey_type); - - debug("expecting SSH2_MSG_KEX_ECDH_INIT"); - packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); - client_pubkey = packet_get_string(&slen); - if (slen != CURVE25519_SIZE) - fatal("Incorrect size for server Curve25519 pubkey: %d", slen); - packet_check_eom(); + kex->load_host_private_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + server_host_public = kex->load_host_public_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + server_host_private = kex->load_host_private_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + if (server_host_public == NULL) { + r = SSH_ERR_NO_HOSTKEY_LOADED; + goto out; + } + if ((r = sshpkt_get_string(ssh, &client_pubkey, &pklen)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; + if (pklen != CURVE25519_SIZE) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } #ifdef DEBUG_KEXECDH dump_digest("client public key:", client_pubkey, CURVE25519_SIZE); #endif - buffer_init(&shared_secret); - kexc25519_shared_key(server_key, client_pubkey, &shared_secret); + if ((shared_secret = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = kexc25519_shared_key(server_key, client_pubkey, + shared_secret)) < 0) + goto out; /* calc H */ - key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); - kex_c25519_hash( + if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, + &sbloblen)) != 0) + goto out; + hashlen = sizeof(hash); + if ((r = kex_c25519_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, client_pubkey, server_pubkey, - buffer_ptr(&shared_secret), buffer_len(&shared_secret), - &hash, &hashlen - ); + sshbuf_ptr(shared_secret), sshbuf_len(shared_secret), + hash, &hashlen)) < 0) + goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ - kex->sign(server_host_private, server_host_public, &signature, &slen, - hash, hashlen); - - /* destroy_sensitive_data(); */ + if ((r = kex->sign(server_host_private, server_host_public, + &signature, &slen, hash, hashlen, ssh->compat)) < 0) + goto out; /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ - packet_start(SSH2_MSG_KEX_ECDH_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_string(server_pubkey, sizeof(server_pubkey)); - packet_put_string(signature, slen); - packet_send(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || + (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || + (r = sshpkt_put_string(ssh, server_pubkey, sizeof(server_pubkey))) != 0 || + (r = sshpkt_put_string(ssh, signature, slen)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; - free(signature); + if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); +out: + explicit_bzero(hash, sizeof(hash)); + explicit_bzero(server_key, sizeof(server_key)); free(server_host_key_blob); - /* have keys, free server key */ + free(signature); free(client_pubkey); - - kex_derive_keys(kex, hash, hashlen, - buffer_ptr(&shared_secret), buffer_len(&shared_secret)); - buffer_free(&shared_secret); - kex_finish(kex); + sshbuf_free(shared_secret); + return r; } diff --git a/crypto/openssh/kexdh.c b/crypto/openssh/kexdh.c index e7cdadc90046..feea6697d5d6 100644 --- a/crypto/openssh/kexdh.c +++ b/crypto/openssh/kexdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdh.c,v 1.24 2014/01/09 23:20:00 djm Exp $ */ +/* $OpenBSD: kexdh.c,v 1.25 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -25,63 +25,69 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #include -#include "buffer.h" #include "ssh2.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" +#include "ssherr.h" +#include "sshbuf.h" #include "digest.h" -#include "log.h" -void +int kex_dh_hash( - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, - BIGNUM *client_dh_pub, - BIGNUM *server_dh_pub, - BIGNUM *shared_secret, - u_char **hash, u_int *hashlen) + const char *client_version_string, + const char *server_version_string, + const u_char *ckexinit, size_t ckexinitlen, + const u_char *skexinit, size_t skexinitlen, + const u_char *serverhostkeyblob, size_t sbloblen, + const BIGNUM *client_dh_pub, + const BIGNUM *server_dh_pub, + const BIGNUM *shared_secret, + u_char *hash, size_t *hashlen) { - Buffer b; - static u_char digest[SSH_DIGEST_MAX_LENGTH]; - - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - buffer_put_bignum2(&b, client_dh_pub); - buffer_put_bignum2(&b, server_dh_pub); - buffer_put_bignum2(&b, shared_secret); + struct sshbuf *b; + int r; + if (*hashlen < ssh_digest_bytes(SSH_DIGEST_SHA1)) + return SSH_ERR_INVALID_ARGUMENT; + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || + (r = sshbuf_put_cstring(b, server_version_string)) != 0 || + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || + (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || + (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || + (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || + (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || + (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || + (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || + (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { + sshbuf_free(b); + return r; + } #ifdef DEBUG_KEX - buffer_dump(&b); + sshbuf_dump(b, stderr); #endif - if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0) - fatal("%s: ssh_digest_buffer failed", __func__); - - buffer_free(&b); - -#ifdef DEBUG_KEX - dump_digest("hash", digest, ssh_digest_bytes(SSH_DIGEST_SHA1)); -#endif - *hash = digest; + if (ssh_digest_buffer(SSH_DIGEST_SHA1, b, hash, *hashlen) != 0) { + sshbuf_free(b); + return SSH_ERR_LIBCRYPTO_ERROR; + } + sshbuf_free(b); *hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1); +#ifdef DEBUG_KEX + dump_digest("hash", hash, *hashlen); +#endif + return 0; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/kexdhc.c b/crypto/openssh/kexdhc.c index f7a19fc1344a..af259f16a459 100644 --- a/crypto/openssh/kexdhc.c +++ b/crypto/openssh/kexdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhc.c,v 1.15 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: kexdhc.c,v 1.18 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -34,128 +36,177 @@ #include #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" +#include "dispatch.h" +#include "compat.h" +#include "ssherr.h" +#include "sshbuf.h" -void -kexdh_client(Kex *kex) +static int input_kex_dh(int, u_int32_t, void *); + +int +kexdh_client(struct ssh *ssh) { - BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; - DH *dh; - Key *server_host_key; - u_char *server_host_key_blob = NULL, *signature = NULL; - u_char *kbuf, *hash; - u_int klen, slen, sbloblen, hashlen; - int kout; + struct kex *kex = ssh->kex; + int r; /* generate and send 'e', client DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: - dh = dh_new_group1(); + kex->dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: - dh = dh_new_group14(); + kex->dh = dh_new_group14(); break; default: - fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + if (kex->dh == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; } - dh_gen_key(dh, kex->we_need * 8); - packet_start(SSH2_MSG_KEXDH_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - debug("sending SSH2_MSG_KEXDH_INIT"); + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || + (r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || + (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif - debug("expecting SSH2_MSG_KEXDH_REPLY"); - packet_read_expect(SSH2_MSG_KEXDH_REPLY); + ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); + r = 0; + out: + return r; +} +static int +input_kex_dh(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + struct sshkey *server_host_key = NULL; + u_char *kbuf = NULL, *server_host_key_blob = NULL, *signature = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t klen = 0, slen, sbloblen, hashlen; + int kout, r; + + if (kex->verify_host_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); - + if ((r = sshpkt_get_string(ssh, &server_host_key_blob, + &sbloblen)) != 0 || + (r = sshkey_from_blob(server_host_key_blob, sbloblen, + &server_host_key)) != 0) + goto out; + if (server_host_key->type != kex->hostkey_type || + (kex->hostkey_type == KEY_ECDSA && + server_host_key->ecdsa_nid != kex->hostkey_nid)) { + r = SSH_ERR_KEY_TYPE_MISMATCH; + goto out; + } + if (kex->verify_host_key(server_host_key, ssh) == -1) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } /* DH parameter f, server public DH key */ - if ((dh_server_pub = BN_new()) == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub); - + if ((dh_server_pub = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* signed H */ + if ((r = sshpkt_get_bignum2(ssh, dh_server_pub)) != 0 || + (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif + if (!dh_pub_is_valid(kex->dh, dh_server_pub)) { + sshpkt_disconnect(ssh, "bad server public DH value"); + r = SSH_ERR_MESSAGE_INCOMPLETE; + goto out; + } - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) - fatal("DH_compute_key: failed"); + klen = DH_size(kex->dh); + if ((kbuf = malloc(klen)) == NULL || + (shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 || + BN_bin2bn(kbuf, kout, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexdh_client: BN_new failed"); - if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) - fatal("kexdh_client: BN_bin2bn failed"); - explicit_bzero(kbuf, klen); - free(kbuf); /* calc and verify H */ - kex_dh_hash( + hashlen = sizeof(hash); + if ((r = kex_dh_hash( kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, - dh->pub_key, + kex->dh->pub_key, dh_server_pub, shared_secret, - &hash, &hashlen - ); - free(server_host_key_blob); - BN_clear_free(dh_server_pub); - DH_free(dh); + hash, &hashlen)) != 0) + goto out; - if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - free(signature); + if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen, + ssh->compat)) != 0) + goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); + if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + out: + explicit_bzero(hash, sizeof(hash)); + DH_free(kex->dh); + kex->dh = NULL; + if (dh_server_pub) + BN_clear_free(dh_server_pub); + if (kbuf) { + explicit_bzero(kbuf, klen); + free(kbuf); + } + if (shared_secret) + BN_clear_free(shared_secret); + sshkey_free(server_host_key); + free(server_host_key_blob); + free(signature); + return r; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/kexdhs.c b/crypto/openssh/kexdhs.c index c3011f741dc7..de7c05b17249 100644 --- a/crypto/openssh/kexdhs.c +++ b/crypto/openssh/kexdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhs.c,v 1.18 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: kexdhs.c,v 1.22 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -33,55 +35,89 @@ #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" -void -kexdh_server(Kex *kex) +#include "dispatch.h" +#include "compat.h" +#include "ssherr.h" +#include "sshbuf.h" + +static int input_kex_dh_init(int, u_int32_t, void *); + +int +kexdh_server(struct ssh *ssh) { - BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - DH *dh; - Key *server_host_public, *server_host_private; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, hashlen, slen; - int kout; + struct kex *kex = ssh->kex; + int r; /* generate server DH public key */ switch (kex->kex_type) { case KEX_DH_GRP1_SHA1: - dh = dh_new_group1(); + kex->dh = dh_new_group1(); break; case KEX_DH_GRP14_SHA1: - dh = dh_new_group14(); + kex->dh = dh_new_group14(); break; default: - fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; } - dh_gen_key(dh, kex->we_need * 8); + if (kex->dh == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) + goto out; debug("expecting SSH2_MSG_KEXDH_INIT"); - packet_read_expect(SSH2_MSG_KEXDH_INIT); + ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); + r = 0; + out: + return r; +} + +int +input_kex_dh_init(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + struct sshkey *server_host_public, *server_host_private; + u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t sbloblen, slen; + size_t klen = 0, hashlen; + int kout, r; if (kex->load_host_public_key == NULL || - kex->load_host_private_key == NULL) - fatal("Cannot load hostkey"); - server_host_public = kex->load_host_public_key(kex->hostkey_type); - if (server_host_public == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - server_host_private = kex->load_host_private_key(kex->hostkey_type); + kex->load_host_private_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + server_host_public = kex->load_host_public_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + server_host_private = kex->load_host_private_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + if (server_host_public == NULL) { + r = SSH_ERR_NO_HOSTKEY_LOADED; + goto out; + } /* key, cert */ - if ((dh_client_pub = BN_new()) == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - packet_check_eom(); + if ((dh_client_pub = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_client_pub= "); @@ -91,70 +127,90 @@ kexdh_server(Kex *kex) #endif #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); + if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { + sshpkt_disconnect(ssh, "bad client public DH value"); + r = SSH_ERR_MESSAGE_INCOMPLETE; + goto out; + } - klen = DH_size(dh); - kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) - fatal("DH_compute_key: failed"); + klen = DH_size(kex->dh); + if ((kbuf = malloc(klen)) == NULL || + (shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 || + BN_bin2bn(kbuf, kout, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexdh_server: BN_new failed"); - if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) - fatal("kexdh_server: BN_bin2bn failed"); - explicit_bzero(kbuf, klen); - free(kbuf); - - key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); - + if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, + &sbloblen)) != 0) + goto out; /* calc H */ - kex_dh_hash( + hashlen = sizeof(hash); + if ((r = kex_dh_hash( kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, dh_client_pub, - dh->pub_key, + kex->dh->pub_key, shared_secret, - &hash, &hashlen - ); - BN_clear_free(dh_client_pub); + hash, &hashlen)) != 0) + goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ - kex->sign(server_host_private, server_host_public, &signature, &slen, - hash, hashlen); + if ((r = kex->sign(server_host_private, server_host_public, + &signature, &slen, hash, hashlen, ssh->compat)) < 0) + goto out; /* destroy_sensitive_data(); */ /* send server hostkey, DH pubkey 'f' and singed H */ - packet_start(SSH2_MSG_KEXDH_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string(signature, slen); - packet_send(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || + (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || + (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ + (r = sshpkt_put_string(ssh, signature, slen)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; - free(signature); + if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + out: + explicit_bzero(hash, sizeof(hash)); + DH_free(kex->dh); + kex->dh = NULL; + if (dh_client_pub) + BN_clear_free(dh_client_pub); + if (kbuf) { + explicit_bzero(kbuf, klen); + free(kbuf); + } + if (shared_secret) + BN_clear_free(shared_secret); free(server_host_key_blob); - /* have keys, free DH */ - DH_free(dh); - - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); + free(signature); + return r; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/kexecdh.c b/crypto/openssh/kexecdh.c index c52c5e234743..2a4fec6b124c 100644 --- a/crypto/openssh/kexecdh.c +++ b/crypto/openssh/kexecdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdh.c,v 1.5 2014/01/09 23:20:00 djm Exp $ */ +/* $OpenBSD: kexecdh.c,v 1.6 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -26,7 +26,7 @@ #include "includes.h" -#ifdef OPENSSL_HAS_ECC +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include @@ -38,60 +38,63 @@ #include #include -#include "buffer.h" #include "ssh2.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" -#include "log.h" +#include "sshbuf.h" #include "digest.h" +#include "ssherr.h" -void +int kex_ecdh_hash( int hash_alg, const EC_GROUP *ec_group, - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, + const char *client_version_string, + const char *server_version_string, + const u_char *ckexinit, size_t ckexinitlen, + const u_char *skexinit, size_t skexinitlen, + const u_char *serverhostkeyblob, size_t sbloblen, const EC_POINT *client_dh_pub, const EC_POINT *server_dh_pub, const BIGNUM *shared_secret, - u_char **hash, u_int *hashlen) + u_char *hash, size_t *hashlen) { - Buffer b; - static u_char digest[SSH_DIGEST_MAX_LENGTH]; - - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - buffer_put_ecpoint(&b, ec_group, client_dh_pub); - buffer_put_ecpoint(&b, ec_group, server_dh_pub); - buffer_put_bignum2(&b, shared_secret); + struct sshbuf *b; + int r; + if (*hashlen < ssh_digest_bytes(hash_alg)) + return SSH_ERR_INVALID_ARGUMENT; + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || + (r = sshbuf_put_cstring(b, server_version_string)) != 0 || + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || + (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || + (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || + (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || + (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || + (r = sshbuf_put_ec(b, client_dh_pub, ec_group)) != 0 || + (r = sshbuf_put_ec(b, server_dh_pub, ec_group)) != 0 || + (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { + sshbuf_free(b); + return r; + } #ifdef DEBUG_KEX - buffer_dump(&b); + sshbuf_dump(b, stderr); #endif - if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) - fatal("%s: ssh_digest_buffer failed", __func__); - - buffer_free(&b); - -#ifdef DEBUG_KEX - dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); -#endif - *hash = digest; + if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { + sshbuf_free(b); + return SSH_ERR_LIBCRYPTO_ERROR; + } + sshbuf_free(b); *hashlen = ssh_digest_bytes(hash_alg); +#ifdef DEBUG_KEX + dump_digest("hash", hash, *hashlen); +#endif + return 0; } -#endif /* OPENSSL_HAS_ECC */ +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ diff --git a/crypto/openssh/kexecdhc.c b/crypto/openssh/kexecdhc.c index 2f7629cca3da..90220ce8205d 100644 --- a/crypto/openssh/kexecdhc.c +++ b/crypto/openssh/kexecdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdhc.c,v 1.7 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: kexecdhc.c,v 1.10 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -26,140 +26,203 @@ #include "includes.h" +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) + #include #include #include #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include + +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" +#include "dispatch.h" +#include "compat.h" +#include "ssherr.h" +#include "sshbuf.h" -#ifdef OPENSSL_HAS_ECC +static int input_kex_ecdh_reply(int, u_int32_t, void *); -#include - -void -kexecdh_client(Kex *kex) +int +kexecdh_client(struct ssh *ssh) { - EC_KEY *client_key; - EC_POINT *server_public; + struct kex *kex = ssh->kex; + EC_KEY *client_key = NULL; const EC_GROUP *group; - BIGNUM *shared_secret; - Key *server_host_key; - u_char *server_host_key_blob = NULL, *signature = NULL; - u_char *kbuf, *hash; - u_int klen, slen, sbloblen, hashlen; + const EC_POINT *public_key; + int r; - if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) - fatal("%s: EC_KEY_new_by_curve_name failed", __func__); - if (EC_KEY_generate_key(client_key) != 1) - fatal("%s: EC_KEY_generate_key failed", __func__); + if ((client_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EC_KEY_generate_key(client_key) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } group = EC_KEY_get0_group(client_key); + public_key = EC_KEY_get0_public_key(client_key); - packet_start(SSH2_MSG_KEX_ECDH_INIT); - packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key)); - packet_send(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 || + (r = sshpkt_put_ec(ssh, public_key, group)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; debug("sending SSH2_MSG_KEX_ECDH_INIT"); #ifdef DEBUG_KEXECDH fputs("client private key:\n", stderr); - key_dump_ec_key(client_key); + sshkey_dump_ec_key(client_key); #endif + kex->ec_client_key = client_key; + kex->ec_group = group; + client_key = NULL; /* owned by the kex */ debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); - packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_ecdh_reply); + r = 0; + out: + if (client_key) + EC_KEY_free(client_key); + return r; +} + +static int +input_kex_ecdh_reply(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + const EC_GROUP *group; + EC_POINT *server_public = NULL; + EC_KEY *client_key; + BIGNUM *shared_secret = NULL; + struct sshkey *server_host_key = NULL; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t slen, sbloblen; + size_t klen = 0, hashlen; + int r; + + if (kex->verify_host_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + group = kex->ec_group; + client_key = kex->ec_client_key; /* hostkey */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); + if ((r = sshpkt_get_string(ssh, &server_host_key_blob, + &sbloblen)) != 0 || + (r = sshkey_from_blob(server_host_key_blob, sbloblen, + &server_host_key)) != 0) + goto out; + if (server_host_key->type != kex->hostkey_type || + (kex->hostkey_type == KEY_ECDSA && + server_host_key->ecdsa_nid != kex->hostkey_nid)) { + r = SSH_ERR_KEY_TYPE_MISMATCH; + goto out; + } + if (kex->verify_host_key(server_host_key, ssh) == -1) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } /* Q_S, server public key */ - if ((server_public = EC_POINT_new(group)) == NULL) - fatal("%s: EC_POINT_new failed", __func__); - packet_get_ecpoint(group, server_public); - - if (key_ec_validate_public(group, server_public) != 0) - fatal("%s: invalid server public key", __func__); + /* signed H */ + if ((server_public = EC_POINT_new(group)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshpkt_get_ec(ssh, server_public, group)) != 0 || + (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; #ifdef DEBUG_KEXECDH fputs("server public key:\n", stderr); - key_dump_ec_point(group, server_public); + sshkey_dump_ec_point(group, server_public); #endif - - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); + if (sshkey_ec_validate_public(group, server_public) != 0) { + sshpkt_disconnect(ssh, "invalid server public key"); + r = SSH_ERR_MESSAGE_INCOMPLETE; + goto out; + } klen = (EC_GROUP_get_degree(group) + 7) / 8; - kbuf = xmalloc(klen); + if ((kbuf = malloc(klen)) == NULL || + (shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } if (ECDH_compute_key(kbuf, klen, server_public, - client_key, NULL) != (int)klen) - fatal("%s: ECDH_compute_key failed", __func__); + client_key, NULL) != (int)klen || + BN_bin2bn(kbuf, klen, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif - if ((shared_secret = BN_new()) == NULL) - fatal("%s: BN_new failed", __func__); - if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) - fatal("%s: BN_bin2bn failed", __func__); - explicit_bzero(kbuf, klen); - free(kbuf); - /* calc and verify H */ - kex_ecdh_hash( + hashlen = sizeof(hash); + if ((r = kex_ecdh_hash( kex->hash_alg, group, kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, EC_KEY_get0_public_key(client_key), server_public, shared_secret, - &hash, &hashlen - ); - free(server_host_key_blob); - EC_POINT_clear_free(server_public); - EC_KEY_free(client_key); + hash, &hashlen)) != 0) + goto out; - if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - free(signature); + if ((r = sshkey_verify(server_host_key, signature, slen, hash, + hashlen, ssh->compat)) != 0) + goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); + if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + out: + explicit_bzero(hash, sizeof(hash)); + if (kex->ec_client_key) { + EC_KEY_free(kex->ec_client_key); + kex->ec_client_key = NULL; + } + if (server_public) + EC_POINT_clear_free(server_public); + if (kbuf) { + explicit_bzero(kbuf, klen); + free(kbuf); + } + if (shared_secret) + BN_clear_free(shared_secret); + sshkey_free(server_host_key); + free(server_host_key_blob); + free(signature); + return r; } -#else /* OPENSSL_HAS_ECC */ -void -kexecdh_client(Kex *kex) -{ - fatal("ECC support is not enabled"); -} -#endif /* OPENSSL_HAS_ECC */ +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ + diff --git a/crypto/openssh/kexecdhs.c b/crypto/openssh/kexecdhs.c index 2700b7219a6f..0adb80e6addf 100644 --- a/crypto/openssh/kexecdhs.c +++ b/crypto/openssh/kexecdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdhs.c,v 1.10 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: kexecdhs.c,v 1.14 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -26,136 +26,183 @@ #include "includes.h" +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) + #include #include #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include + +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "ssh2.h" -#ifdef OPENSSL_HAS_ECC +#include "dispatch.h" +#include "compat.h" +#include "ssherr.h" +#include "sshbuf.h" -#include +static int input_kex_ecdh_init(int, u_int32_t, void *); -void -kexecdh_server(Kex *kex) +int +kexecdh_server(struct ssh *ssh) { - EC_POINT *client_public; - EC_KEY *server_key; - const EC_GROUP *group; - BIGNUM *shared_secret; - Key *server_host_private, *server_host_public; - u_char *server_host_key_blob = NULL, *signature = NULL; - u_char *kbuf, *hash; - u_int klen, slen, sbloblen, hashlen; + debug("expecting SSH2_MSG_KEX_ECDH_INIT"); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_ecdh_init); + return 0; +} - if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) - fatal("%s: EC_KEY_new_by_curve_name failed", __func__); - if (EC_KEY_generate_key(server_key) != 1) - fatal("%s: EC_KEY_generate_key failed", __func__); +static int +input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + EC_POINT *client_public; + EC_KEY *server_key = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + BIGNUM *shared_secret = NULL; + struct sshkey *server_host_private, *server_host_public; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t slen, sbloblen; + size_t klen = 0, hashlen; + int r; + + if ((server_key = EC_KEY_new_by_curve_name(kex->ec_nid)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EC_KEY_generate_key(server_key) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } group = EC_KEY_get0_group(server_key); #ifdef DEBUG_KEXECDH fputs("server private key:\n", stderr); - key_dump_ec_key(server_key); + sshkey_dump_ec_key(server_key); #endif if (kex->load_host_public_key == NULL || - kex->load_host_private_key == NULL) - fatal("Cannot load hostkey"); - server_host_public = kex->load_host_public_key(kex->hostkey_type); - if (server_host_public == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - server_host_private = kex->load_host_private_key(kex->hostkey_type); - - debug("expecting SSH2_MSG_KEX_ECDH_INIT"); - packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); - if ((client_public = EC_POINT_new(group)) == NULL) - fatal("%s: EC_POINT_new failed", __func__); - packet_get_ecpoint(group, client_public); - packet_check_eom(); - - if (key_ec_validate_public(group, client_public) != 0) - fatal("%s: invalid client public key", __func__); + kex->load_host_private_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + server_host_public = kex->load_host_public_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + server_host_private = kex->load_host_private_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + if (server_host_public == NULL) { + r = SSH_ERR_NO_HOSTKEY_LOADED; + goto out; + } + if ((client_public = EC_POINT_new(group)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshpkt_get_ec(ssh, client_public, group)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; #ifdef DEBUG_KEXECDH fputs("client public key:\n", stderr); - key_dump_ec_point(group, client_public); + sshkey_dump_ec_point(group, client_public); #endif + if (sshkey_ec_validate_public(group, client_public) != 0) { + sshpkt_disconnect(ssh, "invalid client public key"); + r = SSH_ERR_MESSAGE_INCOMPLETE; + goto out; + } /* Calculate shared_secret */ klen = (EC_GROUP_get_degree(group) + 7) / 8; - kbuf = xmalloc(klen); + if ((kbuf = malloc(klen)) == NULL || + (shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } if (ECDH_compute_key(kbuf, klen, client_public, - server_key, NULL) != (int)klen) - fatal("%s: ECDH_compute_key failed", __func__); + server_key, NULL) != (int)klen || + BN_bin2bn(kbuf, klen, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } -#ifdef DEBUG_KEXDH +#ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif - if ((shared_secret = BN_new()) == NULL) - fatal("%s: BN_new failed", __func__); - if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) - fatal("%s: BN_bin2bn failed", __func__); - explicit_bzero(kbuf, klen); - free(kbuf); - /* calc H */ - key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); - kex_ecdh_hash( + if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, + &sbloblen)) != 0) + goto out; + hashlen = sizeof(hash); + if ((r = kex_ecdh_hash( kex->hash_alg, group, kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, client_public, EC_KEY_get0_public_key(server_key), shared_secret, - &hash, &hashlen - ); - EC_POINT_clear_free(client_public); + hash, &hashlen)) != 0) + goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ - kex->sign(server_host_private, server_host_public, &signature, &slen, - hash, hashlen); + if ((r = kex->sign(server_host_private, server_host_public, + &signature, &slen, hash, hashlen, ssh->compat)) < 0) + goto out; /* destroy_sensitive_data(); */ + public_key = EC_KEY_get0_public_key(server_key); /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ - packet_start(SSH2_MSG_KEX_ECDH_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key)); - packet_put_string(signature, slen); - packet_send(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 || + (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || + (r = sshpkt_put_ec(ssh, public_key, group)) != 0 || + (r = sshpkt_put_string(ssh, signature, slen)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; - free(signature); + if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + out: + explicit_bzero(hash, sizeof(hash)); + if (kex->ec_client_key) { + EC_KEY_free(kex->ec_client_key); + kex->ec_client_key = NULL; + } + if (server_key) + EC_KEY_free(server_key); + if (kbuf) { + explicit_bzero(kbuf, klen); + free(kbuf); + } + if (shared_secret) + BN_clear_free(shared_secret); free(server_host_key_blob); - /* have keys, free server key */ - EC_KEY_free(server_key); + free(signature); + return r; +} +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} -#else /* OPENSSL_HAS_ECC */ -void -kexecdh_server(Kex *kex) -{ - fatal("ECC support is not enabled"); -} -#endif /* OPENSSL_HAS_ECC */ diff --git a/crypto/openssh/kexgex.c b/crypto/openssh/kexgex.c index c2e6bc16d567..8b0d83332cd5 100644 --- a/crypto/openssh/kexgex.c +++ b/crypto/openssh/kexgex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgex.c,v 1.28 2014/01/09 23:20:00 djm Exp $ */ +/* $OpenBSD: kexgex.c,v 1.29 2015/01/19 20:16:15 markus Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -26,73 +26,77 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #include -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" #include "ssh2.h" +#include "ssherr.h" +#include "sshbuf.h" #include "digest.h" -#include "log.h" -void +int kexgex_hash( int hash_alg, - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, - int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, - BIGNUM *client_dh_pub, - BIGNUM *server_dh_pub, - BIGNUM *shared_secret, - u_char **hash, u_int *hashlen) + const char *client_version_string, + const char *server_version_string, + const u_char *ckexinit, size_t ckexinitlen, + const u_char *skexinit, size_t skexinitlen, + const u_char *serverhostkeyblob, size_t sbloblen, + int min, int wantbits, int max, + const BIGNUM *prime, + const BIGNUM *gen, + const BIGNUM *client_dh_pub, + const BIGNUM *server_dh_pub, + const BIGNUM *shared_secret, + u_char *hash, size_t *hashlen) { - Buffer b; - static u_char digest[SSH_DIGEST_MAX_LENGTH]; + struct sshbuf *b; + int r; - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - if (min == -1 || max == -1) - buffer_put_int(&b, wantbits); - else { - buffer_put_int(&b, min); - buffer_put_int(&b, wantbits); - buffer_put_int(&b, max); + if (*hashlen < ssh_digest_bytes(SSH_DIGEST_SHA1)) + return SSH_ERR_INVALID_ARGUMENT; + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 || + (r = sshbuf_put_cstring(b, server_version_string)) != 0 || + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || + (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 || + (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 || + (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 || + (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || + (min != -1 && (r = sshbuf_put_u32(b, min)) != 0) || + (r = sshbuf_put_u32(b, wantbits)) != 0 || + (max != -1 && (r = sshbuf_put_u32(b, max)) != 0) || + (r = sshbuf_put_bignum2(b, prime)) != 0 || + (r = sshbuf_put_bignum2(b, gen)) != 0 || + (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || + (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || + (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { + sshbuf_free(b); + return r; } - buffer_put_bignum2(&b, prime); - buffer_put_bignum2(&b, gen); - buffer_put_bignum2(&b, client_dh_pub); - buffer_put_bignum2(&b, server_dh_pub); - buffer_put_bignum2(&b, shared_secret); - #ifdef DEBUG_KEXDH - buffer_dump(&b); + sshbuf_dump(b, stderr); #endif - if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) - fatal("%s: ssh_digest_buffer failed", __func__); - - buffer_free(&b); - -#ifdef DEBUG_KEX - dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); -#endif - *hash = digest; + if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { + sshbuf_free(b); + return SSH_ERR_LIBCRYPTO_ERROR; + } + sshbuf_free(b); *hashlen = ssh_digest_bytes(hash_alg); +#ifdef DEBUG_KEXDH + dump_digest("hash", hash, *hashlen); +#endif + return 0; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/kexgexc.c b/crypto/openssh/kexgexc.c index 355b7ba311b5..e8e059a885aa 100644 --- a/crypto/openssh/kexgexc.c +++ b/crypto/openssh/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.17 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.20 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -26,6 +26,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -35,173 +37,243 @@ #include #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" #include "dh.h" #include "ssh2.h" #include "compat.h" +#include "dispatch.h" +#include "ssherr.h" +#include "sshbuf.h" -void -kexgex_client(Kex *kex) +static int input_kex_dh_gex_group(int, u_int32_t, void *); +static int input_kex_dh_gex_reply(int, u_int32_t, void *); + +int +kexgex_client(struct ssh *ssh) { - BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; - BIGNUM *p = NULL, *g = NULL; - Key *server_host_key; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int klen, slen, sbloblen, hashlen; - int kout; - int min, max, nbits; - DH *dh; + struct kex *kex = ssh->kex; + int r; + u_int nbits; nbits = dh_estimate(kex->dh_need * 8); - if (datafellows & SSH_OLD_DHGEX) { + kex->min = DH_GRP_MIN; + kex->max = DH_GRP_MAX; + kex->nbits = nbits; + if (ssh->compat & SSH_OLD_DHGEX) { /* Old GEX request */ - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); - packet_put_int(nbits); - min = DH_GRP_MIN; - max = DH_GRP_MAX; - - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD)) + != 0 || + (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", kex->nbits); } else { /* New GEX request */ - min = DH_GRP_MIN; - max = DH_GRP_MAX; - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); - packet_put_int(min); - packet_put_int(nbits); - packet_put_int(max); - + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST)) != 0 || + (r = sshpkt_put_u32(ssh, kex->min)) != 0 || + (r = sshpkt_put_u32(ssh, kex->nbits)) != 0 || + (r = sshpkt_put_u32(ssh, kex->max)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent", - min, nbits, max); + kex->min, kex->nbits, kex->max); } #ifdef DEBUG_KEXDH fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", - min, nbits, max); + kex->min, kex->nbits, kex->max); #endif - packet_send(); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, + &input_kex_dh_gex_group); + r = 0; + out: + return r; +} - debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); +static int +input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + BIGNUM *p = NULL, *g = NULL; + int r, bits; - if ((p = BN_new()) == NULL) - fatal("BN_new"); - packet_get_bignum2(p); - if ((g = BN_new()) == NULL) - fatal("BN_new"); - packet_get_bignum2(g); - packet_check_eom(); + debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); - if (BN_num_bits(p) < min || BN_num_bits(p) > max) - fatal("DH_GEX group out of range: %d !< %d !< %d", - min, BN_num_bits(p), max); - - dh = dh_new_group(g, p); - dh_gen_key(dh, kex->we_need * 8); + if ((p = BN_new()) == NULL || + (g = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshpkt_get_bignum2(ssh, p)) != 0 || + (r = sshpkt_get_bignum2(ssh, g)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; + if ((bits = BN_num_bits(p)) < 0 || + (u_int)bits < kex->min || (u_int)bits > kex->max) { + r = SSH_ERR_DH_GEX_OUT_OF_RANGE; + goto out; + } + if ((kex->dh = dh_new_group(g, p)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + p = g = NULL; /* belong to kex->dh now */ + /* generate and send 'e', client DH public key */ + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || + (r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || + (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; + debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply); + r = 0; +out: + if (p) + BN_clear_free(p); + if (g) + BN_clear_free(g); + return r; +} - debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); - /* generate and send 'e', client DH public key */ - packet_start(SSH2_MSG_KEX_DH_GEX_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - - debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); +static int +input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + struct sshkey *server_host_key = NULL; + u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t klen = 0, slen, sbloblen, hashlen; + int kout, r; + debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); + if (kex->verify_host_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); - + if ((r = sshpkt_get_string(ssh, &server_host_key_blob, + &sbloblen)) != 0 || + (r = sshkey_from_blob(server_host_key_blob, sbloblen, + &server_host_key)) != 0) + goto out; + if (server_host_key->type != kex->hostkey_type) { + r = SSH_ERR_KEY_TYPE_MISMATCH; + goto out; + } + if (server_host_key->type != kex->hostkey_type || + (kex->hostkey_type == KEY_ECDSA && + server_host_key->ecdsa_nid != kex->hostkey_nid)) { + r = SSH_ERR_KEY_TYPE_MISMATCH; + goto out; + } + if (kex->verify_host_key(server_host_key, ssh) == -1) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } /* DH parameter f, server public DH key */ - if ((dh_server_pub = BN_new()) == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub); - + if ((dh_server_pub = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* signed H */ + if ((r = sshpkt_get_bignum2(ssh, dh_server_pub)) != 0 || + (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_server_pub= "); BN_print_fp(stderr, dh_server_pub); fprintf(stderr, "\n"); debug("bits %d", BN_num_bits(dh_server_pub)); #endif + if (!dh_pub_is_valid(kex->dh, dh_server_pub)) { + sshpkt_disconnect(ssh, "bad server public DH value"); + r = SSH_ERR_MESSAGE_INCOMPLETE; + goto out; + } - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) - fatal("DH_compute_key: failed"); + klen = DH_size(kex->dh); + if ((kbuf = malloc(klen)) == NULL || + (shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((kout = DH_compute_key(kbuf, dh_server_pub, kex->dh)) < 0 || + BN_bin2bn(kbuf, kout, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexgex_client: BN_new failed"); - if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) - fatal("kexgex_client: BN_bin2bn failed"); - explicit_bzero(kbuf, klen); - free(kbuf); - - if (datafellows & SSH_OLD_DHGEX) - min = max = -1; + if (ssh->compat & SSH_OLD_DHGEX) + kex->min = kex->max = -1; /* calc and verify H */ - kexgex_hash( + hashlen = sizeof(hash); + if ((r = kexgex_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), server_host_key_blob, sbloblen, - min, nbits, max, - dh->p, dh->g, - dh->pub_key, + kex->min, kex->nbits, kex->max, + kex->dh->p, kex->dh->g, + kex->dh->pub_key, dh_server_pub, shared_secret, - &hash, &hashlen - ); + hash, &hashlen)) != 0) + goto out; - /* have keys, free DH */ - DH_free(dh); - free(server_host_key_blob); - BN_clear_free(dh_server_pub); - - if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - free(signature); + if ((r = sshkey_verify(server_host_key, signature, slen, hash, + hashlen, ssh->compat)) != 0) + goto out; /* save session id */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); + if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + out: + explicit_bzero(hash, sizeof(hash)); + DH_free(kex->dh); + kex->dh = NULL; + if (dh_server_pub) + BN_clear_free(dh_server_pub); + if (kbuf) { + explicit_bzero(kbuf, klen); + free(kbuf); + } + if (shared_secret) + BN_clear_free(shared_secret); + sshkey_free(server_host_key); + free(server_host_key_blob); + free(signature); + return r; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/kexgexs.c b/crypto/openssh/kexgexs.c index 770ad28a8d1c..9c281d28853c 100644 --- a/crypto/openssh/kexgexs.c +++ b/crypto/openssh/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.19 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.24 2015/01/26 06:10:03 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -26,7 +26,9 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL + +#include /* MIN MAX */ #include #include @@ -35,10 +37,9 @@ #include -#include "xmalloc.h" -#include "buffer.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" +#include "digest.h" #include "kex.h" #include "log.h" #include "packet.h" @@ -49,33 +50,43 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" +#include "dispatch.h" +#include "ssherr.h" +#include "sshbuf.h" -void -kexgex_server(Kex *kex) +static int input_kex_dh_gex_request(int, u_int32_t, void *); +static int input_kex_dh_gex_init(int, u_int32_t, void *); + +int +kexgex_server(struct ssh *ssh) { - BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - Key *server_host_public, *server_host_private; - DH *dh; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, slen, hashlen; - int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1; - int type, kout; + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST_OLD, + &input_kex_dh_gex_request); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REQUEST, + &input_kex_dh_gex_request); + debug("expecting SSH2_MSG_KEX_DH_GEX_REQUEST"); + return 0; +} - if (kex->load_host_public_key == NULL || - kex->load_host_private_key == NULL) - fatal("Cannot load hostkey"); - server_host_public = kex->load_host_public_key(kex->hostkey_type); - if (server_host_public == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - server_host_private = kex->load_host_private_key(kex->hostkey_type); +static int +input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + int r; + u_int min = 0, max = 0, nbits = 0; - type = packet_read(); switch (type) { case SSH2_MSG_KEX_DH_GEX_REQUEST: debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - omin = min = packet_get_int(); - onbits = nbits = packet_get_int(); - omax = max = packet_get_int(); + if ((r = sshpkt_get_u32(ssh, &min)) != 0 || + (r = sshpkt_get_u32(ssh, &nbits)) != 0 || + (r = sshpkt_get_u32(ssh, &max)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; + kex->nbits = nbits; + kex->min = min; + kex->max = max; min = MAX(DH_GRP_MIN, min); max = MIN(DH_GRP_MAX, max); nbits = MAX(DH_GRP_MIN, nbits); @@ -83,45 +94,89 @@ kexgex_server(Kex *kex) break; case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - onbits = nbits = packet_get_int(); + if ((r = sshpkt_get_u32(ssh, &nbits)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; + kex->nbits = nbits; /* unused for old GEX */ - omin = min = DH_GRP_MIN; - omax = max = DH_GRP_MAX; + kex->min = min = DH_GRP_MIN; + kex->max = max = DH_GRP_MAX; break; default: - fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; } - packet_check_eom(); - if (omax < omin || onbits < omin || omax < onbits) - fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", - omin, onbits, omax); + if (kex->max < kex->min || kex->nbits < kex->min || + kex->max < kex->nbits) { + r = SSH_ERR_DH_GEX_OUT_OF_RANGE; + goto out; + } /* Contact privileged parent */ - dh = PRIVSEP(choose_dh(min, nbits, max)); - if (dh == NULL) - packet_disconnect("Protocol error: no matching DH grp found"); - + kex->dh = PRIVSEP(choose_dh(min, nbits, max)); + if (kex->dh == NULL) { + sshpkt_disconnect(ssh, "no matching DH grp found"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); - packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); - packet_put_bignum2(dh->p); - packet_put_bignum2(dh->g); - packet_send(); - - /* flush */ - packet_write_wait(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 || + (r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 || + (r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; /* Compute our exchange value in parallel with the client */ - dh_gen_key(dh, kex->we_need * 8); + if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0) + goto out; + + /* old KEX does not use min/max in kexgex_hash() */ + if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) + kex->min = kex->max = -1; debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); + ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init); + r = 0; + out: + return r; +} + +static int +input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + struct sshkey *server_host_public, *server_host_private; + u_char *kbuf = NULL, *signature = NULL, *server_host_key_blob = NULL; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t sbloblen, slen; + size_t klen = 0, hashlen; + int kout, r; + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + server_host_public = kex->load_host_public_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + server_host_private = kex->load_host_private_key(kex->hostkey_type, + kex->hostkey_nid, ssh); + if (server_host_public == NULL) { + r = SSH_ERR_NO_HOSTKEY_LOADED; + goto out; + } /* key, cert */ - if ((dh_client_pub = BN_new()) == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - packet_check_eom(); + if ((dh_client_pub = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshpkt_get_bignum2(ssh, dh_client_pub)) != 0 || + (r = sshpkt_get_end(ssh)) != 0) + goto out; #ifdef DEBUG_KEXDH fprintf(stderr, "dh_client_pub= "); @@ -131,78 +186,92 @@ kexgex_server(Kex *kex) #endif #ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); + DHparams_print_fp(stderr, kex->dh); fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); + BN_print_fp(stderr, kex->dh->pub_key); fprintf(stderr, "\n"); #endif - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); + if (!dh_pub_is_valid(kex->dh, dh_client_pub)) { + sshpkt_disconnect(ssh, "bad client public DH value"); + r = SSH_ERR_MESSAGE_INCOMPLETE; + goto out; + } - klen = DH_size(dh); - kbuf = xmalloc(klen); - if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) - fatal("DH_compute_key: failed"); + klen = DH_size(kex->dh); + if ((kbuf = malloc(klen)) == NULL || + (shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((kout = DH_compute_key(kbuf, dh_client_pub, kex->dh)) < 0 || + BN_bin2bn(kbuf, kout, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } #ifdef DEBUG_KEXDH dump_digest("shared secret", kbuf, kout); #endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexgex_server: BN_new failed"); - if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) - fatal("kexgex_server: BN_bin2bn failed"); - explicit_bzero(kbuf, klen); - free(kbuf); - - key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); - - if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) - omin = min = omax = max = -1; - + if ((r = sshkey_to_blob(server_host_public, &server_host_key_blob, + &sbloblen)) != 0) + goto out; /* calc H */ - kexgex_hash( + hashlen = sizeof(hash); + if ((r = kexgex_hash( kex->hash_alg, kex->client_version_string, kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), + sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), + sshbuf_ptr(kex->my), sshbuf_len(kex->my), server_host_key_blob, sbloblen, - omin, onbits, omax, - dh->p, dh->g, + kex->min, kex->nbits, kex->max, + kex->dh->p, kex->dh->g, dh_client_pub, - dh->pub_key, + kex->dh->pub_key, shared_secret, - &hash, &hashlen - ); - BN_clear_free(dh_client_pub); + hash, &hashlen)) != 0) + goto out; /* save session id := H */ if (kex->session_id == NULL) { kex->session_id_len = hashlen; - kex->session_id = xmalloc(kex->session_id_len); + kex->session_id = malloc(kex->session_id_len); + if (kex->session_id == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ - kex->sign(server_host_private, server_host_public, &signature, &slen, - hash, hashlen); + if ((r = kex->sign(server_host_private, server_host_public, + &signature, &slen, hash, hashlen, ssh->compat)) < 0) + goto out; /* destroy_sensitive_data(); */ /* send server hostkey, DH pubkey 'f' and singed H */ - debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); - packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string(signature, slen); - packet_send(); + if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || + (r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 || + (r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */ + (r = sshpkt_put_string(ssh, signature, slen)) != 0 || + (r = sshpkt_send(ssh)) != 0) + goto out; - free(signature); + if ((r = kex_derive_keys_bn(ssh, hash, hashlen, shared_secret)) == 0) + r = kex_send_newkeys(ssh); + out: + DH_free(kex->dh); + kex->dh = NULL; + if (dh_client_pub) + BN_clear_free(dh_client_pub); + if (kbuf) { + explicit_bzero(kbuf, klen); + free(kbuf); + } + if (shared_secret) + BN_clear_free(shared_secret); free(server_host_key_blob); - /* have keys, free DH */ - DH_free(dh); - - kex_derive_keys_bn(kex, hash, hashlen, shared_secret); - BN_clear_free(shared_secret); - - kex_finish(kex); + free(signature); + return r; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c index 206076159a9c..bbe027b66855 100644 --- a/crypto/openssh/key.c +++ b/crypto/openssh/key.c @@ -1,15 +1,15 @@ -/* $OpenBSD: key.c,v 1.122 2014/07/22 01:18:50 dtucker Exp $ */ +/* $OpenBSD: key.c,v 1.127 2015/01/28 22:36:00 djm Exp $ */ /* * placed in the public domain */ #include "includes.h" -#include #include #include #include #include +#include #define SSH_KEY_NO_DEFINE #include "key.h" @@ -39,24 +39,6 @@ key_new_private(int type) return ret; } -u_char* -key_fingerprint_raw(const Key *k, enum fp_type dgst_type, - u_int *dgst_raw_length) -{ - u_char *ret = NULL; - size_t dlen; - int r; - - if (dgst_raw_length != NULL) - *dgst_raw_length = 0; - if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0) - fatal("%s: %s", __func__, ssh_err(r)); - if (dlen > INT_MAX) - fatal("%s: giant len %zu", __func__, dlen); - *dgst_raw_length = dlen; - return ret; -} - int key_read(Key *ret, char **cpp) { @@ -329,7 +311,7 @@ key_load_file(int fd, const char *filename, struct sshbuf *blob) { int r; - if ((r = sshkey_load_file(fd, filename, blob)) != 0) { + if ((r = sshkey_load_file(fd, blob)) != 0) { fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); error("%s: %s", __func__, ssh_err(r)); return 0; @@ -436,44 +418,9 @@ key_load_private_type(int type, const char *filename, const char *passphrase, return ret; } -#ifdef WITH_OPENSSL -Key * -key_load_private_pem(int fd, int type, const char *passphrase, - char **commentp) -{ - int r; - Key *ret = NULL; - - if ((r = sshkey_load_private_pem(fd, type, passphrase, - &ret, commentp)) != 0) { - fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); - if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) - debug("%s: %s", __func__, ssh_err(r)); - else - error("%s: %s", __func__, ssh_err(r)); - return NULL; - } - return ret; -} -#endif /* WITH_OPENSSL */ - int key_perm_ok(int fd, const char *filename) { return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0; } -int -key_in_file(Key *key, const char *filename, int strict_type) -{ - int r; - - if ((r = sshkey_in_file(key, filename, strict_type)) != 0) { - fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR); - if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT) - return 0; - error("%s: %s", __func__, ssh_err(r)); - return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1; - } - return 1; -} diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h index c6401a576fc4..89fd5cfdf54a 100644 --- a/crypto/openssh/key.h +++ b/crypto/openssh/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.42 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: key.h,v 1.47 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -39,7 +39,6 @@ typedef struct sshkey Key; #define key_free sshkey_free #define key_equal_public sshkey_equal_public #define key_equal sshkey_equal -#define key_fingerprint sshkey_fingerprint #define key_type sshkey_type #define key_cert_type sshkey_cert_type #define key_ssh_name sshkey_ssh_name @@ -50,7 +49,6 @@ typedef struct sshkey Key; #define key_size sshkey_size #define key_ecdsa_bits_to_nid sshkey_ecdsa_bits_to_nid #define key_ecdsa_key_to_nid sshkey_ecdsa_key_to_nid -#define key_names_valid2 sshkey_names_valid2 #define key_is_cert sshkey_is_cert #define key_type_plain sshkey_type_plain #define key_cert_is_legacy sshkey_cert_is_legacy @@ -60,14 +58,12 @@ typedef struct sshkey Key; #define key_ec_nid_to_hash_alg sshkey_ec_nid_to_hash_alg #define key_dump_ec_point sshkey_dump_ec_point #define key_dump_ec_key sshkey_dump_ec_key -#define key_fingerprint sshkey_fingerprint #endif void key_add_private(Key *); Key *key_new_private(int); void key_free(Key *); Key *key_demote(const Key *); -u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *); int key_write(const Key *, FILE *); int key_read(Key *, char **); @@ -104,8 +100,6 @@ Key *key_load_public(const char *, char **); Key *key_load_private(const char *, const char *, char **); Key *key_load_private_cert(int, const char *, const char *, int *); Key *key_load_private_type(int, const char *, const char *, char **, int *); -Key *key_load_private_pem(int, int, const char *, char **); int key_perm_ok(int, const char *); -int key_in_file(Key *, const char *, int); #endif diff --git a/crypto/openssh/krl.c b/crypto/openssh/krl.c index eb31df90fdc1..4bbaa208073e 100644 --- a/crypto/openssh/krl.c +++ b/crypto/openssh/krl.c @@ -14,12 +14,12 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.c,v 1.17 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: krl.c,v 1.31 2015/01/30 01:10:33 djm Exp $ */ #include "includes.h" +#include /* MIN */ #include -#include #include #include @@ -30,12 +30,14 @@ #include #include -#include "buffer.h" -#include "key.h" +#include "sshbuf.h" +#include "ssherr.h" +#include "sshkey.h" #include "authfile.h" #include "misc.h" #include "log.h" -#include "xmalloc.h" +#include "digest.h" +#include "bitmap.h" #include "krl.h" @@ -72,7 +74,7 @@ RB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp); /* Tree of blobs (used for keys and fingerprints) */ struct revoked_blob { u_char *blob; - u_int len; + size_t len; RB_ENTRY(revoked_blob) tree_entry; }; static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b); @@ -81,7 +83,7 @@ RB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp); /* Tracks revoked certs for a single CA */ struct revoked_certs { - Key *ca_key; + struct sshkey *ca_key; struct revoked_serial_tree revoked_serials; struct revoked_key_id_tree revoked_key_ids; TAILQ_ENTRY(revoked_certs) entry; @@ -154,8 +156,7 @@ revoked_certs_free(struct revoked_certs *rc) free(rki->key_id); free(rki); } - if (rc->ca_key != NULL) - key_free(rc->ca_key); + sshkey_free(rc->ca_key); } void @@ -190,12 +191,13 @@ ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version) krl->krl_version = version; } -void +int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment) { free(krl->comment); if ((krl->comment = strdup(comment)) == NULL) - fatal("%s: strdup", __func__); + return SSH_ERR_ALLOC_FAIL; + return 0; } /* @@ -203,14 +205,16 @@ ssh_krl_set_comment(struct ssh_krl *krl, const char *comment) * create a new one in the tree if one did not exist already. */ static int -revoked_certs_for_ca_key(struct ssh_krl *krl, const Key *ca_key, +revoked_certs_for_ca_key(struct ssh_krl *krl, const struct sshkey *ca_key, struct revoked_certs **rcp, int allow_create) { struct revoked_certs *rc; + int r; *rcp = NULL; TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { - if (key_equal(rc->ca_key, ca_key)) { + if ((ca_key == NULL && rc->ca_key == NULL) || + sshkey_equal(rc->ca_key, ca_key)) { *rcp = rc; return 0; } @@ -219,15 +223,18 @@ revoked_certs_for_ca_key(struct ssh_krl *krl, const Key *ca_key, return 0; /* If this CA doesn't exist in the list then add it now */ if ((rc = calloc(1, sizeof(*rc))) == NULL) - return -1; - if ((rc->ca_key = key_from_private(ca_key)) == NULL) { + return SSH_ERR_ALLOC_FAIL; + if (ca_key == NULL) + rc->ca_key = NULL; + else if ((r = sshkey_from_private(ca_key, &rc->ca_key)) != 0) { free(rc); - return -1; + return r; } RB_INIT(&rc->revoked_serials); RB_INIT(&rc->revoked_key_ids); TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry); - debug3("%s: new CA %s", __func__, key_type(ca_key)); + KRL_DBG(("%s: new CA %s", __func__, + ca_key == NULL ? "*" : sshkey_type(ca_key))); *rcp = rc; return 0; } @@ -245,14 +252,14 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) if (ers == NULL || serial_cmp(ers, &rs) != 0) { /* No entry matches. Just insert */ if ((irs = malloc(sizeof(rs))) == NULL) - return -1; + return SSH_ERR_ALLOC_FAIL; memcpy(irs, &rs, sizeof(*irs)); ers = RB_INSERT(revoked_serial_tree, rt, irs); if (ers != NULL) { KRL_DBG(("%s: bad: ers != NULL", __func__)); /* Shouldn't happen */ free(irs); - return -1; + return SSH_ERR_INTERNAL_ERROR; } ers = irs; } else { @@ -267,6 +274,7 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) if (ers->hi < hi) ers->hi = hi; } + /* * The inserted or revised range might overlap or abut adjacent ones; * coalesce as necessary. @@ -305,40 +313,42 @@ insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) } int -ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key, +ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const struct sshkey *ca_key, u_int64_t serial) { return ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, serial); } int -ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const Key *ca_key, - u_int64_t lo, u_int64_t hi) +ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, + const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi) { struct revoked_certs *rc; + int r; if (lo > hi || lo == 0) - return -1; - if (revoked_certs_for_ca_key(krl, ca_key, &rc, 1) != 0) - return -1; + return SSH_ERR_INVALID_ARGUMENT; + if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0) + return r; return insert_serial_range(&rc->revoked_serials, lo, hi); } int -ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key, +ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const struct sshkey *ca_key, const char *key_id) { struct revoked_key_id *rki, *erki; struct revoked_certs *rc; + int r; - if (revoked_certs_for_ca_key(krl, ca_key, &rc, 1) != 0) - return -1; + if ((r = revoked_certs_for_ca_key(krl, ca_key, &rc, 1)) != 0) + return r; - debug3("%s: revoke %s", __func__, key_id); + KRL_DBG(("%s: revoke %s", __func__, key_id)); if ((rki = calloc(1, sizeof(*rki))) == NULL || (rki->key_id = strdup(key_id)) == NULL) { free(rki); - fatal("%s: strdup", __func__); + return SSH_ERR_ALLOC_FAIL; } erki = RB_INSERT(revoked_key_id_tree, &rc->revoked_key_ids, rki); if (erki != NULL) { @@ -350,33 +360,32 @@ ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key, /* Convert "key" to a public key blob without any certificate information */ static int -plain_key_blob(const Key *key, u_char **blob, u_int *blen) +plain_key_blob(const struct sshkey *key, u_char **blob, size_t *blen) { - Key *kcopy; + struct sshkey *kcopy; int r; - if ((kcopy = key_from_private(key)) == NULL) - return -1; - if (key_is_cert(kcopy)) { - if (key_drop_cert(kcopy) != 0) { - error("%s: key_drop_cert", __func__); - key_free(kcopy); - return -1; + if ((r = sshkey_from_private(key, &kcopy)) != 0) + return r; + if (sshkey_is_cert(kcopy)) { + if ((r = sshkey_drop_cert(kcopy)) != 0) { + sshkey_free(kcopy); + return r; } } - r = key_to_blob(kcopy, blob, blen); - free(kcopy); + r = sshkey_to_blob(kcopy, blob, blen); + sshkey_free(kcopy); return r; } /* Revoke a key blob. Ownership of blob is transferred to the tree */ static int -revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, u_int len) +revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, size_t len) { struct revoked_blob *rb, *erb; if ((rb = calloc(1, sizeof(*rb))) == NULL) - return -1; + return SSH_ERR_ALLOC_FAIL; rb->blob = blob; rb->len = len; erb = RB_INSERT(revoked_blob_tree, rbt, rb); @@ -388,36 +397,39 @@ revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, u_int len) } int -ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key) +ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key) { u_char *blob; - u_int len; + size_t len; + int r; - debug3("%s: revoke type %s", __func__, key_type(key)); - if (plain_key_blob(key, &blob, &len) < 0) - return -1; + debug3("%s: revoke type %s", __func__, sshkey_type(key)); + if ((r = plain_key_blob(key, &blob, &len)) != 0) + return r; return revoke_blob(&krl->revoked_keys, blob, len); } int -ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key) +ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key) { u_char *blob; - u_int len; + size_t len; + int r; - debug3("%s: revoke type %s by sha1", __func__, key_type(key)); - if ((blob = key_fingerprint_raw(key, SSH_FP_SHA1, &len)) == NULL) - return -1; + debug3("%s: revoke type %s by sha1", __func__, sshkey_type(key)); + if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, + &blob, &len)) != 0) + return r; return revoke_blob(&krl->revoked_sha1s, blob, len); } int -ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key) +ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key) { - if (!key_is_cert(key)) + if (!sshkey_is_cert(key)) return ssh_krl_revoke_key_sha1(krl, key); - if (key_cert_is_legacy(key) || key->cert->serial == 0) { + if (sshkey_cert_is_legacy(key) || key->cert->serial == 0) { return ssh_krl_revoke_cert_by_key_id(krl, key->cert->signature_key, key->cert->key_id); @@ -429,8 +441,8 @@ ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key) } /* - * Select a copact next section type to emit in a KRL based on the - * current section type, the run length of contiguous revoked serial + * Select the most compact section type to emit next in a KRL based on + * the current section type, the run length of contiguous revoked serial * numbers and the gaps from the last and to the next revoked serial. * Applies a mostly-accurate bit cost model to select the section type * that will minimise the size of the resultant KRL. @@ -500,50 +512,69 @@ choose_next_state(int current_state, u_int64_t contig, int final, *force_new_section = 1; cost = cost_bitmap_restart; } - debug3("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:" + KRL_DBG(("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:" "list %llu range %llu bitmap %llu new bitmap %llu, " "selected 0x%02x%s", __func__, (long long unsigned)contig, (long long unsigned)last_gap, (long long unsigned)next_gap, final, (long long unsigned)cost_list, (long long unsigned)cost_range, (long long unsigned)cost_bitmap, (long long unsigned)cost_bitmap_restart, new_state, - *force_new_section ? " restart" : ""); + *force_new_section ? " restart" : "")); return new_state; } +static int +put_bitmap(struct sshbuf *buf, struct bitmap *bitmap) +{ + size_t len; + u_char *blob; + int r; + + len = bitmap_nbytes(bitmap); + if ((blob = malloc(len)) == NULL) + return SSH_ERR_ALLOC_FAIL; + if (bitmap_to_string(bitmap, blob, len) != 0) { + free(blob); + return SSH_ERR_INTERNAL_ERROR; + } + r = sshbuf_put_bignum2_bytes(buf, blob, len); + free(blob); + return r; +} + /* Generate a KRL_SECTION_CERTIFICATES KRL section */ static int -revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) +revoked_certs_generate(struct revoked_certs *rc, struct sshbuf *buf) { - int final, force_new_sect, r = -1; + int final, force_new_sect, r = SSH_ERR_INTERNAL_ERROR; u_int64_t i, contig, gap, last = 0, bitmap_start = 0; struct revoked_serial *rs, *nrs; struct revoked_key_id *rki; int next_state, state = 0; - Buffer sect; - u_char *kblob = NULL; - u_int klen; - BIGNUM *bitmap = NULL; + struct sshbuf *sect; + struct bitmap *bitmap = NULL; - /* Prepare CA scope key blob if we have one supplied */ - if (key_to_blob(rc->ca_key, &kblob, &klen) == 0) - return -1; + if ((sect = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; - buffer_init(§); - - /* Store the header */ - buffer_put_string(buf, kblob, klen); - buffer_put_string(buf, NULL, 0); /* Reserved */ - - free(kblob); + /* Store the header: optional CA scope key, reserved */ + if (rc->ca_key == NULL) { + if ((r = sshbuf_put_string(buf, NULL, 0)) != 0) + goto out; + } else { + if ((r = sshkey_puts(rc->ca_key, buf)) != 0) + goto out; + } + if ((r = sshbuf_put_string(buf, NULL, 0)) != 0) + goto out; /* Store the revoked serials. */ for (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials); rs != NULL; rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) { - debug3("%s: serial %llu:%llu state 0x%02x", __func__, + KRL_DBG(("%s: serial %llu:%llu state 0x%02x", __func__, (long long unsigned)rs->lo, (long long unsigned)rs->hi, - state); + state)); /* Check contiguous length and gap to next section (if any) */ nrs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs); @@ -561,37 +592,43 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) */ if (state != 0 && (force_new_sect || next_state != state || state == KRL_SECTION_CERT_SERIAL_RANGE)) { - debug3("%s: finish state 0x%02x", __func__, state); + KRL_DBG(("%s: finish state 0x%02x", __func__, state)); switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: case KRL_SECTION_CERT_SERIAL_RANGE: break; case KRL_SECTION_CERT_SERIAL_BITMAP: - buffer_put_bignum2(§, bitmap); - BN_free(bitmap); + if ((r = put_bitmap(sect, bitmap)) != 0) + goto out; + bitmap_free(bitmap); bitmap = NULL; break; } - buffer_put_char(buf, state); - buffer_put_string(buf, - buffer_ptr(§), buffer_len(§)); - buffer_clear(§); + if ((r = sshbuf_put_u8(buf, state)) != 0 || + (r = sshbuf_put_stringb(buf, sect)) != 0) + goto out; + sshbuf_reset(sect); } /* If we are starting a new section then prepare it now */ if (next_state != state || force_new_sect) { - debug3("%s: start state 0x%02x", __func__, next_state); + KRL_DBG(("%s: start state 0x%02x", __func__, + next_state)); state = next_state; - buffer_clear(§); + sshbuf_reset(sect); switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: case KRL_SECTION_CERT_SERIAL_RANGE: break; case KRL_SECTION_CERT_SERIAL_BITMAP: - if ((bitmap = BN_new()) == NULL) + if ((bitmap = bitmap_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; goto out; + } bitmap_start = rs->lo; - buffer_put_int64(§, bitmap_start); + if ((r = sshbuf_put_u64(sect, + bitmap_start)) != 0) + goto out; break; } } @@ -599,12 +636,15 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) /* Perform section-specific processing */ switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: - for (i = 0; i < contig; i++) - buffer_put_int64(§, rs->lo + i); + for (i = 0; i < contig; i++) { + if ((r = sshbuf_put_u64(sect, rs->lo + i)) != 0) + goto out; + } break; case KRL_SECTION_CERT_SERIAL_RANGE: - buffer_put_int64(§, rs->lo); - buffer_put_int64(§, rs->hi); + if ((r = sshbuf_put_u64(sect, rs->lo)) != 0 || + (r = sshbuf_put_u64(sect, rs->hi)) != 0) + goto out; break; case KRL_SECTION_CERT_SERIAL_BITMAP: if (rs->lo - bitmap_start > INT_MAX) { @@ -612,9 +652,11 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) goto out; } for (i = 0; i < contig; i++) { - if (BN_set_bit(bitmap, - rs->lo + i - bitmap_start) != 1) + if (bitmap_set_bit(bitmap, + rs->lo + i - bitmap_start) != 0) { + r = SSH_ERR_ALLOC_FAIL; goto out; + } } break; } @@ -622,119 +664,125 @@ revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) } /* Flush the remaining section, if any */ if (state != 0) { - debug3("%s: serial final flush for state 0x%02x", - __func__, state); + KRL_DBG(("%s: serial final flush for state 0x%02x", + __func__, state)); switch (state) { case KRL_SECTION_CERT_SERIAL_LIST: case KRL_SECTION_CERT_SERIAL_RANGE: break; case KRL_SECTION_CERT_SERIAL_BITMAP: - buffer_put_bignum2(§, bitmap); - BN_free(bitmap); + if ((r = put_bitmap(sect, bitmap)) != 0) + goto out; + bitmap_free(bitmap); bitmap = NULL; break; } - buffer_put_char(buf, state); - buffer_put_string(buf, - buffer_ptr(§), buffer_len(§)); + if ((r = sshbuf_put_u8(buf, state)) != 0 || + (r = sshbuf_put_stringb(buf, sect)) != 0) + goto out; } - debug3("%s: serial done ", __func__); + KRL_DBG(("%s: serial done ", __func__)); /* Now output a section for any revocations by key ID */ - buffer_clear(§); + sshbuf_reset(sect); RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) { - debug3("%s: key ID %s", __func__, rki->key_id); - buffer_put_cstring(§, rki->key_id); + KRL_DBG(("%s: key ID %s", __func__, rki->key_id)); + if ((r = sshbuf_put_cstring(sect, rki->key_id)) != 0) + goto out; } - if (buffer_len(§) != 0) { - buffer_put_char(buf, KRL_SECTION_CERT_KEY_ID); - buffer_put_string(buf, buffer_ptr(§), - buffer_len(§)); + if (sshbuf_len(sect) != 0) { + if ((r = sshbuf_put_u8(buf, KRL_SECTION_CERT_KEY_ID)) != 0 || + (r = sshbuf_put_stringb(buf, sect)) != 0) + goto out; } r = 0; out: - if (bitmap != NULL) - BN_free(bitmap); - buffer_free(§); + bitmap_free(bitmap); + sshbuf_free(sect); return r; } int -ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys, - u_int nsign_keys) +ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, + const struct sshkey **sign_keys, u_int nsign_keys) { - int r = -1; + int r = SSH_ERR_INTERNAL_ERROR; struct revoked_certs *rc; struct revoked_blob *rb; - Buffer sect; - u_char *kblob = NULL, *sblob = NULL; - u_int klen, slen, i; + struct sshbuf *sect; + u_char *sblob = NULL; + size_t slen, i; if (krl->generated_date == 0) krl->generated_date = time(NULL); - buffer_init(§); + if ((sect = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; /* Store the header */ - buffer_append(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1); - buffer_put_int(buf, KRL_FORMAT_VERSION); - buffer_put_int64(buf, krl->krl_version); - buffer_put_int64(buf, krl->generated_date); - buffer_put_int64(buf, krl->flags); - buffer_put_string(buf, NULL, 0); - buffer_put_cstring(buf, krl->comment ? krl->comment : ""); + if ((r = sshbuf_put(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1)) != 0 || + (r = sshbuf_put_u32(buf, KRL_FORMAT_VERSION)) != 0 || + (r = sshbuf_put_u64(buf, krl->krl_version)) != 0 || + (r = sshbuf_put_u64(buf, krl->generated_date) != 0) || + (r = sshbuf_put_u64(buf, krl->flags)) != 0 || + (r = sshbuf_put_string(buf, NULL, 0)) != 0 || + (r = sshbuf_put_cstring(buf, krl->comment)) != 0) + goto out; /* Store sections for revoked certificates */ TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { - if (revoked_certs_generate(rc, §) != 0) + sshbuf_reset(sect); + if ((r = revoked_certs_generate(rc, sect)) != 0) + goto out; + if ((r = sshbuf_put_u8(buf, KRL_SECTION_CERTIFICATES)) != 0 || + (r = sshbuf_put_stringb(buf, sect)) != 0) goto out; - buffer_put_char(buf, KRL_SECTION_CERTIFICATES); - buffer_put_string(buf, buffer_ptr(§), - buffer_len(§)); } /* Finally, output sections for revocations by public key/hash */ - buffer_clear(§); + sshbuf_reset(sect); RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) { - debug3("%s: key len %u ", __func__, rb->len); - buffer_put_string(§, rb->blob, rb->len); + KRL_DBG(("%s: key len %zu ", __func__, rb->len)); + if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0) + goto out; } - if (buffer_len(§) != 0) { - buffer_put_char(buf, KRL_SECTION_EXPLICIT_KEY); - buffer_put_string(buf, buffer_ptr(§), - buffer_len(§)); + if (sshbuf_len(sect) != 0) { + if ((r = sshbuf_put_u8(buf, KRL_SECTION_EXPLICIT_KEY)) != 0 || + (r = sshbuf_put_stringb(buf, sect)) != 0) + goto out; } - buffer_clear(§); + sshbuf_reset(sect); RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) { - debug3("%s: hash len %u ", __func__, rb->len); - buffer_put_string(§, rb->blob, rb->len); + KRL_DBG(("%s: hash len %zu ", __func__, rb->len)); + if ((r = sshbuf_put_string(sect, rb->blob, rb->len)) != 0) + goto out; } - if (buffer_len(§) != 0) { - buffer_put_char(buf, KRL_SECTION_FINGERPRINT_SHA1); - buffer_put_string(buf, buffer_ptr(§), - buffer_len(§)); + if (sshbuf_len(sect) != 0) { + if ((r = sshbuf_put_u8(buf, + KRL_SECTION_FINGERPRINT_SHA1)) != 0 || + (r = sshbuf_put_stringb(buf, sect)) != 0) + goto out; } for (i = 0; i < nsign_keys; i++) { - if (key_to_blob(sign_keys[i], &kblob, &klen) == 0) + KRL_DBG(("%s: signature key %s", __func__, + sshkey_ssh_name(sign_keys[i]))); + if ((r = sshbuf_put_u8(buf, KRL_SECTION_SIGNATURE)) != 0 || + (r = sshkey_puts(sign_keys[i], buf)) != 0) goto out; - debug3("%s: signature key len %u", __func__, klen); - buffer_put_char(buf, KRL_SECTION_SIGNATURE); - buffer_put_string(buf, kblob, klen); - - if (key_sign(sign_keys[i], &sblob, &slen, - buffer_ptr(buf), buffer_len(buf)) == -1) + if ((r = sshkey_sign(sign_keys[i], &sblob, &slen, + sshbuf_ptr(buf), sshbuf_len(buf), 0)) == -1) + goto out; + KRL_DBG(("%s: signature sig len %zu", __func__, slen)); + if ((r = sshbuf_put_string(buf, sblob, slen)) != 0) goto out; - debug3("%s: signature sig len %u", __func__, slen); - buffer_put_string(buf, sblob, slen); } r = 0; out: - free(kblob); free(sblob); - buffer_free(§); + sshbuf_free(sect); return r; } @@ -746,194 +794,178 @@ format_timestamp(u_int64_t timestamp, char *ts, size_t nts) t = timestamp; tm = localtime(&t); - *ts = '\0'; - strftime(ts, nts, "%Y%m%dT%H%M%S", tm); + if (tm == NULL) + strlcpy(ts, "", nts); + else { + *ts = '\0'; + strftime(ts, nts, "%Y%m%dT%H%M%S", tm); + } } static int -parse_revoked_certs(Buffer *buf, struct ssh_krl *krl) +parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl) { - int ret = -1, nbits; + int r = SSH_ERR_INTERNAL_ERROR; u_char type; const u_char *blob; - u_int blen; - Buffer subsect; + size_t blen, nbits; + struct sshbuf *subsect = NULL; u_int64_t serial, serial_lo, serial_hi; - BIGNUM *bitmap = NULL; + struct bitmap *bitmap = NULL; char *key_id = NULL; - Key *ca_key = NULL; + struct sshkey *ca_key = NULL; - buffer_init(&subsect); + if ((subsect = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; - if ((blob = buffer_get_string_ptr_ret(buf, &blen)) == NULL || - buffer_get_string_ptr_ret(buf, NULL) == NULL) { /* reserved */ - error("%s: buffer error", __func__); + /* Header: key, reserved */ + if ((r = sshbuf_get_string_direct(buf, &blob, &blen)) != 0 || + (r = sshbuf_skip_string(buf)) != 0) goto out; - } - if ((ca_key = key_from_blob(blob, blen)) == NULL) + if (blen != 0 && (r = sshkey_from_blob(blob, blen, &ca_key)) != 0) goto out; - while (buffer_len(buf) > 0) { - if (buffer_get_char_ret(&type, buf) != 0 || - (blob = buffer_get_string_ptr_ret(buf, &blen)) == NULL) { - error("%s: buffer error", __func__); - goto out; + while (sshbuf_len(buf) > 0) { + if (subsect != NULL) { + sshbuf_free(subsect); + subsect = NULL; } - buffer_clear(&subsect); - buffer_append(&subsect, blob, blen); - debug3("%s: subsection type 0x%02x", __func__, type); - /* buffer_dump(&subsect); */ + if ((r = sshbuf_get_u8(buf, &type)) != 0 || + (r = sshbuf_froms(buf, &subsect)) != 0) + goto out; + KRL_DBG(("%s: subsection type 0x%02x", __func__, type)); + /* sshbuf_dump(subsect, stderr); */ switch (type) { case KRL_SECTION_CERT_SERIAL_LIST: - while (buffer_len(&subsect) > 0) { - if (buffer_get_int64_ret(&serial, - &subsect) != 0) { - error("%s: buffer error", __func__); + while (sshbuf_len(subsect) > 0) { + if ((r = sshbuf_get_u64(subsect, &serial)) != 0) goto out; - } - if (ssh_krl_revoke_cert_by_serial(krl, ca_key, - serial) != 0) { - error("%s: update failed", __func__); + if ((r = ssh_krl_revoke_cert_by_serial(krl, + ca_key, serial)) != 0) goto out; - } } break; case KRL_SECTION_CERT_SERIAL_RANGE: - if (buffer_get_int64_ret(&serial_lo, &subsect) != 0 || - buffer_get_int64_ret(&serial_hi, &subsect) != 0) { - error("%s: buffer error", __func__); + if ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 || + (r = sshbuf_get_u64(subsect, &serial_hi)) != 0) goto out; - } - if (ssh_krl_revoke_cert_by_serial_range(krl, ca_key, - serial_lo, serial_hi) != 0) { - error("%s: update failed", __func__); + if ((r = ssh_krl_revoke_cert_by_serial_range(krl, + ca_key, serial_lo, serial_hi)) != 0) goto out; - } break; case KRL_SECTION_CERT_SERIAL_BITMAP: - if ((bitmap = BN_new()) == NULL) { - error("%s: BN_new", __func__); + if ((bitmap = bitmap_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; goto out; } - if (buffer_get_int64_ret(&serial_lo, &subsect) != 0 || - buffer_get_bignum2_ret(&subsect, bitmap) != 0) { - error("%s: buffer error", __func__); + if ((r = sshbuf_get_u64(subsect, &serial_lo)) != 0 || + (r = sshbuf_get_bignum2_bytes_direct(subsect, + &blob, &blen)) != 0) + goto out; + if (bitmap_from_string(bitmap, blob, blen) != 0) { + r = SSH_ERR_INVALID_FORMAT; goto out; } - if ((nbits = BN_num_bits(bitmap)) < 0) { - error("%s: bitmap bits < 0", __func__); - goto out; - } - for (serial = 0; serial < (u_int)nbits; serial++) { + nbits = bitmap_nbits(bitmap); + for (serial = 0; serial < (u_int64_t)nbits; serial++) { if (serial > 0 && serial_lo + serial == 0) { error("%s: bitmap wraps u64", __func__); + r = SSH_ERR_INVALID_FORMAT; goto out; } - if (!BN_is_bit_set(bitmap, serial)) + if (!bitmap_test_bit(bitmap, serial)) continue; - if (ssh_krl_revoke_cert_by_serial(krl, ca_key, - serial_lo + serial) != 0) { - error("%s: update failed", __func__); + if ((r = ssh_krl_revoke_cert_by_serial(krl, + ca_key, serial_lo + serial)) != 0) goto out; - } } - BN_free(bitmap); + bitmap_free(bitmap); bitmap = NULL; break; case KRL_SECTION_CERT_KEY_ID: - while (buffer_len(&subsect) > 0) { - if ((key_id = buffer_get_cstring_ret(&subsect, - NULL)) == NULL) { - error("%s: buffer error", __func__); + while (sshbuf_len(subsect) > 0) { + if ((r = sshbuf_get_cstring(subsect, + &key_id, NULL)) != 0) goto out; - } - if (ssh_krl_revoke_cert_by_key_id(krl, ca_key, - key_id) != 0) { - error("%s: update failed", __func__); + if ((r = ssh_krl_revoke_cert_by_key_id(krl, + ca_key, key_id)) != 0) goto out; - } free(key_id); key_id = NULL; } break; default: error("Unsupported KRL certificate section %u", type); + r = SSH_ERR_INVALID_FORMAT; goto out; } - if (buffer_len(&subsect) > 0) { + if (sshbuf_len(subsect) > 0) { error("KRL certificate section contains unparsed data"); + r = SSH_ERR_INVALID_FORMAT; goto out; } } - ret = 0; + r = 0; out: - if (ca_key != NULL) - key_free(ca_key); if (bitmap != NULL) - BN_free(bitmap); + bitmap_free(bitmap); free(key_id); - buffer_free(&subsect); - return ret; + sshkey_free(ca_key); + sshbuf_free(subsect); + return r; } /* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */ int -ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, - const Key **sign_ca_keys, u_int nsign_ca_keys) +ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, + const struct sshkey **sign_ca_keys, size_t nsign_ca_keys) { - Buffer copy, sect; - struct ssh_krl *krl; + struct sshbuf *copy = NULL, *sect = NULL; + struct ssh_krl *krl = NULL; char timestamp[64]; - int ret = -1, r, sig_seen; - Key *key = NULL, **ca_used = NULL; + int r = SSH_ERR_INTERNAL_ERROR, sig_seen; + struct sshkey *key = NULL, **ca_used = NULL, **tmp_ca_used; u_char type, *rdata = NULL; const u_char *blob; - u_int i, j, sig_off, sects_off, rlen, blen, format_version, nca_used; + size_t i, j, sig_off, sects_off, rlen, blen, nca_used; + u_int format_version; nca_used = 0; *krlp = NULL; - if (buffer_len(buf) < sizeof(KRL_MAGIC) - 1 || - memcmp(buffer_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) { + if (sshbuf_len(buf) < sizeof(KRL_MAGIC) - 1 || + memcmp(sshbuf_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) { debug3("%s: not a KRL", __func__); - /* - * Return success but a NULL *krlp here to signal that the - * file might be a simple list of keys. - */ - return 0; + return SSH_ERR_KRL_BAD_MAGIC; } /* Take a copy of the KRL buffer so we can verify its signature later */ - buffer_init(©); - buffer_append(©, buffer_ptr(buf), buffer_len(buf)); - - buffer_init(§); - buffer_consume(©, sizeof(KRL_MAGIC) - 1); + if ((copy = sshbuf_fromb(buf)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_consume(copy, sizeof(KRL_MAGIC) - 1)) != 0) + goto out; if ((krl = ssh_krl_init()) == NULL) { error("%s: alloc failed", __func__); goto out; } - if (buffer_get_int_ret(&format_version, ©) != 0) { - error("%s: KRL truncated", __func__); + if ((r = sshbuf_get_u32(copy, &format_version)) != 0) goto out; - } if (format_version != KRL_FORMAT_VERSION) { - error("%s: KRL unsupported format version %u", - __func__, format_version); + r = SSH_ERR_INVALID_FORMAT; goto out; } - if (buffer_get_int64_ret(&krl->krl_version, ©) != 0 || - buffer_get_int64_ret(&krl->generated_date, ©) != 0 || - buffer_get_int64_ret(&krl->flags, ©) != 0 || - buffer_get_string_ptr_ret(©, NULL) == NULL || /* reserved */ - (krl->comment = buffer_get_cstring_ret(©, NULL)) == NULL) { - error("%s: buffer error", __func__); + if ((r = sshbuf_get_u64(copy, &krl->krl_version)) != 0 || + (r = sshbuf_get_u64(copy, &krl->generated_date)) != 0 || + (r = sshbuf_get_u64(copy, &krl->flags)) != 0 || + (r = sshbuf_skip_string(copy)) != 0 || + (r = sshbuf_get_cstring(copy, &krl->comment, NULL)) != 0) goto out; - } format_timestamp(krl->generated_date, timestamp, sizeof(timestamp)); debug("KRL version %llu generated at %s%s%s", @@ -945,18 +977,22 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, * detailed parsing of data whose provenance is unverified. */ sig_seen = 0; - sects_off = buffer_len(buf) - buffer_len(©); - while (buffer_len(©) > 0) { - if (buffer_get_char_ret(&type, ©) != 0 || - (blob = buffer_get_string_ptr_ret(©, &blen)) == NULL) { - error("%s: buffer error", __func__); + if (sshbuf_len(buf) < sshbuf_len(copy)) { + /* Shouldn't happen */ + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } + sects_off = sshbuf_len(buf) - sshbuf_len(copy); + while (sshbuf_len(copy) > 0) { + if ((r = sshbuf_get_u8(copy, &type)) != 0 || + (r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0) goto out; - } - debug3("%s: first pass, section 0x%02x", __func__, type); + KRL_DBG(("%s: first pass, section 0x%02x", __func__, type)); if (type != KRL_SECTION_SIGNATURE) { if (sig_seen) { error("KRL contains non-signature section " "after signature"); + r = SSH_ERR_INVALID_FORMAT; goto out; } /* Not interested for now. */ @@ -964,94 +1000,114 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, } sig_seen = 1; /* First string component is the signing key */ - if ((key = key_from_blob(blob, blen)) == NULL) { - error("%s: invalid signature key", __func__); + if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { + r = SSH_ERR_INVALID_FORMAT; goto out; } - sig_off = buffer_len(buf) - buffer_len(©); + if (sshbuf_len(buf) < sshbuf_len(copy)) { + /* Shouldn't happen */ + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } + sig_off = sshbuf_len(buf) - sshbuf_len(copy); /* Second string component is the signature itself */ - if ((blob = buffer_get_string_ptr_ret(©, &blen)) == NULL) { - error("%s: buffer error", __func__); + if ((r = sshbuf_get_string_direct(copy, &blob, &blen)) != 0) { + r = SSH_ERR_INVALID_FORMAT; goto out; } /* Check signature over entire KRL up to this point */ - if (key_verify(key, blob, blen, - buffer_ptr(buf), buffer_len(buf) - sig_off) != 1) { - error("bad signaure on KRL"); + if ((r = sshkey_verify(key, blob, blen, + sshbuf_ptr(buf), sshbuf_len(buf) - sig_off, 0)) != 0) goto out; - } /* Check if this key has already signed this KRL */ for (i = 0; i < nca_used; i++) { - if (key_equal(ca_used[i], key)) { + if (sshkey_equal(ca_used[i], key)) { error("KRL signed more than once with " "the same key"); + r = SSH_ERR_INVALID_FORMAT; goto out; } } /* Record keys used to sign the KRL */ - ca_used = xrealloc(ca_used, nca_used + 1, sizeof(*ca_used)); + tmp_ca_used = reallocarray(ca_used, nca_used + 1, + sizeof(*ca_used)); + if (tmp_ca_used == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + ca_used = tmp_ca_used; ca_used[nca_used++] = key; key = NULL; break; } + if (sshbuf_len(copy) != 0) { + /* Shouldn't happen */ + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } + /* * 2nd pass: parse and load the KRL, skipping the header to the point * where the section start. */ - buffer_append(©, (u_char*)buffer_ptr(buf) + sects_off, - buffer_len(buf) - sects_off); - while (buffer_len(©) > 0) { - if (buffer_get_char_ret(&type, ©) != 0 || - (blob = buffer_get_string_ptr_ret(©, &blen)) == NULL) { - error("%s: buffer error", __func__); - goto out; + sshbuf_free(copy); + if ((copy = sshbuf_fromb(buf)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_consume(copy, sects_off)) != 0) + goto out; + while (sshbuf_len(copy) > 0) { + if (sect != NULL) { + sshbuf_free(sect); + sect = NULL; } - debug3("%s: second pass, section 0x%02x", __func__, type); - buffer_clear(§); - buffer_append(§, blob, blen); + if ((r = sshbuf_get_u8(copy, &type)) != 0 || + (r = sshbuf_froms(copy, §)) != 0) + goto out; + KRL_DBG(("%s: second pass, section 0x%02x", __func__, type)); switch (type) { case KRL_SECTION_CERTIFICATES: - if ((r = parse_revoked_certs(§, krl)) != 0) + if ((r = parse_revoked_certs(sect, krl)) != 0) goto out; break; case KRL_SECTION_EXPLICIT_KEY: case KRL_SECTION_FINGERPRINT_SHA1: - while (buffer_len(§) > 0) { - if ((rdata = buffer_get_string_ret(§, - &rlen)) == NULL) { - error("%s: buffer error", __func__); + while (sshbuf_len(sect) > 0) { + if ((r = sshbuf_get_string(sect, + &rdata, &rlen)) != 0) goto out; - } if (type == KRL_SECTION_FINGERPRINT_SHA1 && rlen != 20) { error("%s: bad SHA1 length", __func__); + r = SSH_ERR_INVALID_FORMAT; goto out; } - if (revoke_blob( + if ((r = revoke_blob( type == KRL_SECTION_EXPLICIT_KEY ? &krl->revoked_keys : &krl->revoked_sha1s, - rdata, rlen) != 0) + rdata, rlen)) != 0) goto out; - rdata = NULL; /* revoke_blob frees blob */ + rdata = NULL; /* revoke_blob frees rdata */ } break; case KRL_SECTION_SIGNATURE: /* Handled above, but still need to stay in synch */ - buffer_clear(§); - if ((blob = buffer_get_string_ptr_ret(©, - &blen)) == NULL) { - error("%s: buffer error", __func__); + sshbuf_reset(sect); + sect = NULL; + if ((r = sshbuf_skip_string(copy)) != 0) goto out; - } break; default: error("Unsupported KRL section %u", type); + r = SSH_ERR_INVALID_FORMAT; goto out; } - if (buffer_len(§) > 0) { + if (sshbuf_len(sect) > 0) { error("KRL section contains unparsed data"); + r = SSH_ERR_INVALID_FORMAT; goto out; } } @@ -1062,12 +1118,13 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, if (ssh_krl_check_key(krl, ca_used[i]) == 0) sig_seen = 1; else { - key_free(ca_used[i]); + sshkey_free(ca_used[i]); ca_used[i] = NULL; } } if (nca_used && !sig_seen) { error("All keys used to sign KRL were revoked"); + r = SSH_ERR_KEY_REVOKED; goto out; } @@ -1078,163 +1135,169 @@ ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, for (j = 0; j < nca_used; j++) { if (ca_used[j] == NULL) continue; - if (key_equal(ca_used[j], sign_ca_keys[i])) { + if (sshkey_equal(ca_used[j], sign_ca_keys[i])) { sig_seen = 1; break; } } } if (!sig_seen) { + r = SSH_ERR_SIGNATURE_INVALID; error("KRL not signed with any trusted key"); goto out; } } *krlp = krl; - ret = 0; + r = 0; out: - if (ret != 0) + if (r != 0) ssh_krl_free(krl); - for (i = 0; i < nca_used; i++) { - if (ca_used[i] != NULL) - key_free(ca_used[i]); - } + for (i = 0; i < nca_used; i++) + sshkey_free(ca_used[i]); free(ca_used); free(rdata); - if (key != NULL) - key_free(key); - buffer_free(©); - buffer_free(§); - return ret; + sshkey_free(key); + sshbuf_free(copy); + sshbuf_free(sect); + return r; } -/* Checks whether a given key/cert is revoked. Does not check its CA */ +/* Checks certificate serial number and key ID revocation */ static int -is_key_revoked(struct ssh_krl *krl, const Key *key) +is_cert_revoked(const struct sshkey *key, struct revoked_certs *rc) { - struct revoked_blob rb, *erb; struct revoked_serial rs, *ers; struct revoked_key_id rki, *erki; - struct revoked_certs *rc; - - /* Check explicitly revoked hashes first */ - memset(&rb, 0, sizeof(rb)); - if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL) - return -1; - erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); - free(rb.blob); - if (erb != NULL) { - debug("%s: revoked by key SHA1", __func__); - return -1; - } - - /* Next, explicit keys */ - memset(&rb, 0, sizeof(rb)); - if (plain_key_blob(key, &rb.blob, &rb.len) < 0) - return -1; - erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); - free(rb.blob); - if (erb != NULL) { - debug("%s: revoked by explicit key", __func__); - return -1; - } - - if (!key_is_cert(key)) - return 0; - - /* Check cert revocation */ - if (revoked_certs_for_ca_key(krl, key->cert->signature_key, - &rc, 0) != 0) - return -1; - if (rc == NULL) - return 0; /* No entry for this CA */ /* Check revocation by cert key ID */ memset(&rki, 0, sizeof(rki)); rki.key_id = key->cert->key_id; erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); if (erki != NULL) { - debug("%s: revoked by key ID", __func__); - return -1; + KRL_DBG(("%s: revoked by key ID", __func__)); + return SSH_ERR_KEY_REVOKED; } /* * Legacy cert formats lack serial numbers. Zero serials numbers * are ignored (it's the default when the CA doesn't specify one). */ - if (key_cert_is_legacy(key) || key->cert->serial == 0) + if (sshkey_cert_is_legacy(key) || key->cert->serial == 0) return 0; memset(&rs, 0, sizeof(rs)); rs.lo = rs.hi = key->cert->serial; ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); if (ers != NULL) { - KRL_DBG(("%s: %llu matched %llu:%llu", __func__, + KRL_DBG(("%s: revoked serial %llu matched %llu:%llu", __func__, key->cert->serial, ers->lo, ers->hi)); - debug("%s: revoked by serial", __func__); - return -1; + return SSH_ERR_KEY_REVOKED; } - KRL_DBG(("%s: %llu no match", __func__, key->cert->serial)); + return 0; +} +/* Checks whether a given key/cert is revoked. Does not check its CA */ +static int +is_key_revoked(struct ssh_krl *krl, const struct sshkey *key) +{ + struct revoked_blob rb, *erb; + struct revoked_certs *rc; + int r; + + /* Check explicitly revoked hashes first */ + memset(&rb, 0, sizeof(rb)); + if ((r = sshkey_fingerprint_raw(key, SSH_DIGEST_SHA1, + &rb.blob, &rb.len)) != 0) + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); + free(rb.blob); + if (erb != NULL) { + KRL_DBG(("%s: revoked by key SHA1", __func__)); + return SSH_ERR_KEY_REVOKED; + } + + /* Next, explicit keys */ + memset(&rb, 0, sizeof(rb)); + if ((r = plain_key_blob(key, &rb.blob, &rb.len)) != 0) + return r; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); + free(rb.blob); + if (erb != NULL) { + KRL_DBG(("%s: revoked by explicit key", __func__)); + return SSH_ERR_KEY_REVOKED; + } + + if (!sshkey_is_cert(key)) + return 0; + + /* Check cert revocation for the specified CA */ + if ((r = revoked_certs_for_ca_key(krl, key->cert->signature_key, + &rc, 0)) != 0) + return r; + if (rc != NULL) { + if ((r = is_cert_revoked(key, rc)) != 0) + return r; + } + /* Check cert revocation for the wildcard CA */ + if ((r = revoked_certs_for_ca_key(krl, NULL, &rc, 0)) != 0) + return r; + if (rc != NULL) { + if ((r = is_cert_revoked(key, rc)) != 0) + return r; + } + + KRL_DBG(("%s: %llu no match", __func__, key->cert->serial)); return 0; } int -ssh_krl_check_key(struct ssh_krl *krl, const Key *key) +ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key) { int r; - debug2("%s: checking key", __func__); + KRL_DBG(("%s: checking key", __func__)); if ((r = is_key_revoked(krl, key)) != 0) return r; - if (key_is_cert(key)) { + if (sshkey_is_cert(key)) { debug2("%s: checking CA key", __func__); if ((r = is_key_revoked(krl, key->cert->signature_key)) != 0) return r; } - debug3("%s: key okay", __func__); + KRL_DBG(("%s: key okay", __func__)); return 0; } -/* Returns 0 on success, -1 on error or key revoked, -2 if path is not a KRL */ int -ssh_krl_file_contains_key(const char *path, const Key *key) +ssh_krl_file_contains_key(const char *path, const struct sshkey *key) { - Buffer krlbuf; - struct ssh_krl *krl; - int revoked, fd; + struct sshbuf *krlbuf = NULL; + struct ssh_krl *krl = NULL; + int oerrno = 0, r, fd; if (path == NULL) return 0; + if ((krlbuf = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; if ((fd = open(path, O_RDONLY)) == -1) { - error("open %s: %s", path, strerror(errno)); - error("Revoked keys file not accessible - refusing public key " - "authentication"); - return -1; + r = SSH_ERR_SYSTEM_ERROR; + oerrno = errno; + goto out; } - buffer_init(&krlbuf); - if (!key_load_file(fd, path, &krlbuf)) { - close(fd); - buffer_free(&krlbuf); - error("Revoked keys file not readable - refusing public key " - "authentication"); - return -1; - } - close(fd); - if (ssh_krl_from_blob(&krlbuf, &krl, NULL, 0) != 0) { - buffer_free(&krlbuf); - error("Invalid KRL, refusing public key " - "authentication"); - return -1; - } - buffer_free(&krlbuf); - if (krl == NULL) { - debug3("%s: %s is not a KRL file", __func__, path); - return -2; + if ((r = sshkey_load_file(fd, krlbuf)) != 0) { + oerrno = errno; + goto out; } + if ((r = ssh_krl_from_blob(krlbuf, &krl, NULL, 0)) != 0) + goto out; debug2("%s: checking KRL %s", __func__, path); - revoked = ssh_krl_check_key(krl, key) != 0; + r = ssh_krl_check_key(krl, key); + out: + close(fd); + sshbuf_free(krlbuf); ssh_krl_free(krl); - return revoked ? -1 : 0; + if (r != 0) + errno = oerrno; + return r; } diff --git a/crypto/openssh/krl.h b/crypto/openssh/krl.h index 2c43f5bb252f..4e12befc3c13 100644 --- a/crypto/openssh/krl.h +++ b/crypto/openssh/krl.h @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.h,v 1.2 2013/01/18 00:24:58 djm Exp $ */ +/* $OpenBSD: krl.h,v 1.4 2015/01/13 19:06:49 djm Exp $ */ #ifndef _KRL_H #define _KRL_H @@ -36,28 +36,30 @@ #define KRL_SECTION_CERT_SERIAL_BITMAP 0x22 #define KRL_SECTION_CERT_KEY_ID 0x23 +struct sshkey; +struct sshbuf; struct ssh_krl; struct ssh_krl *ssh_krl_init(void); void ssh_krl_free(struct ssh_krl *krl); void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version); -void ssh_krl_set_sign_key(struct ssh_krl *krl, const Key *sign_key); -void ssh_krl_set_comment(struct ssh_krl *krl, const char *comment); -int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key, - u_int64_t serial); -int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const Key *ca_key, - u_int64_t lo, u_int64_t hi); -int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key, - const char *key_id); -int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key); -int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key); -int ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key); -int ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys, - u_int nsign_keys); -int ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, - const Key **sign_ca_keys, u_int nsign_ca_keys); -int ssh_krl_check_key(struct ssh_krl *krl, const Key *key); -int ssh_krl_file_contains_key(const char *path, const Key *key); +void ssh_krl_set_sign_key(struct ssh_krl *krl, const struct sshkey *sign_key); +int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment); +int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, + const struct sshkey *ca_key, u_int64_t serial); +int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, + const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi); +int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, + const struct sshkey *ca_key, const char *key_id); +int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key); +int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key); +int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key); +int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, + const struct sshkey **sign_keys, u_int nsign_keys); +int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, + const struct sshkey **sign_ca_keys, size_t nsign_ca_keys); +int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key); +int ssh_krl_file_contains_key(const char *path, const struct sshkey *key); #endif /* _KRL_H */ diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c index 4219b9aef3de..94ae81dc6088 100644 --- a/crypto/openssh/loginrec.c +++ b/crypto/openssh/loginrec.c @@ -787,12 +787,12 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) /* this is just a 128-bit IPv6 address */ if (li->hostaddr.sa.sa_family == AF_INET6) { sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); - memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); + memcpy(utx->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { - ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; - ut->ut_addr_v6[1] = 0; - ut->ut_addr_v6[2] = 0; - ut->ut_addr_v6[3] = 0; + utx->ut_addr_v6[0] = utx->ut_addr_v6[3]; + utx->ut_addr_v6[1] = 0; + utx->ut_addr_v6[2] = 0; + utx->ut_addr_v6[3] = 0; } } # endif diff --git a/crypto/openssh/mac.c b/crypto/openssh/mac.c index 402dc984ce69..f63fbff09edc 100644 --- a/crypto/openssh/mac.c +++ b/crypto/openssh/mac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.c,v 1.30 2014/04/30 19:07:48 naddy Exp $ */ +/* $OpenBSD: mac.c,v 1.32 2015/01/15 18:32:54 naddy Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -27,22 +27,16 @@ #include -#include #include -#include - -#include "xmalloc.h" -#include "log.h" -#include "cipher.h" -#include "buffer.h" -#include "key.h" -#include "kex.h" -#include "mac.h" -#include "misc.h" +#include #include "digest.h" #include "hmac.h" #include "umac.h" +#include "mac.h" +#include "misc.h" +#include "ssherr.h" +#include "sshbuf.h" #include "openbsd-compat/openssl-compat.h" @@ -95,7 +89,7 @@ static const struct macalg macs[] = { char * mac_alg_list(char sep) { - char *ret = NULL; + char *ret = NULL, *tmp; size_t nlen, rlen = 0; const struct macalg *m; @@ -103,20 +97,24 @@ mac_alg_list(char sep) if (ret != NULL) ret[rlen++] = sep; nlen = strlen(m->name); - ret = xrealloc(ret, 1, rlen + nlen + 2); + if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { + free(ret); + return NULL; + } + ret = tmp; memcpy(ret + rlen, m->name, nlen + 1); rlen += nlen; } return ret; } -static void -mac_setup_by_alg(Mac *mac, const struct macalg *macalg) +static int +mac_setup_by_alg(struct sshmac *mac, const struct macalg *macalg) { mac->type = macalg->type; if (mac->type == SSH_DIGEST) { if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL) - fatal("ssh_hmac_start(alg=%d) failed", macalg->alg); + return SSH_ERR_ALLOC_FAIL; mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg); } else { mac->mac_len = macalg->len / 8; @@ -126,61 +124,61 @@ mac_setup_by_alg(Mac *mac, const struct macalg *macalg) if (macalg->truncatebits != 0) mac->mac_len = macalg->truncatebits / 8; mac->etm = macalg->etm; + return 0; } int -mac_setup(Mac *mac, char *name) +mac_setup(struct sshmac *mac, char *name) { const struct macalg *m; for (m = macs; m->name != NULL; m++) { if (strcmp(name, m->name) != 0) continue; - if (mac != NULL) { - mac_setup_by_alg(mac, m); - debug2("mac_setup: setup %s", name); - } - return (0); + if (mac != NULL) + return mac_setup_by_alg(mac, m); + return 0; } - debug2("mac_setup: unknown %s", name); - return (-1); + return SSH_ERR_INVALID_ARGUMENT; } int -mac_init(Mac *mac) +mac_init(struct sshmac *mac) { if (mac->key == NULL) - fatal("%s: no key", __func__); + return SSH_ERR_INVALID_ARGUMENT; switch (mac->type) { case SSH_DIGEST: if (mac->hmac_ctx == NULL || ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0) - return -1; + return SSH_ERR_INVALID_ARGUMENT; return 0; case SSH_UMAC: - mac->umac_ctx = umac_new(mac->key); + if ((mac->umac_ctx = umac_new(mac->key)) == NULL) + return SSH_ERR_ALLOC_FAIL; return 0; case SSH_UMAC128: - mac->umac_ctx = umac128_new(mac->key); + if ((mac->umac_ctx = umac128_new(mac->key)) == NULL) + return SSH_ERR_ALLOC_FAIL; return 0; default: - return -1; + return SSH_ERR_INVALID_ARGUMENT; } } -u_char * -mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) +int +mac_compute(struct sshmac *mac, u_int32_t seqno, const u_char *data, int datalen, + u_char *digest, size_t dlen) { static union { - u_char m[EVP_MAX_MD_SIZE]; + u_char m[SSH_DIGEST_MAX_LENGTH]; u_int64_t for_align; } u; u_char b[4]; u_char nonce[8]; if (mac->mac_len > sizeof(u)) - fatal("mac_compute: mac too long %u %zu", - mac->mac_len, sizeof(u)); + return SSH_ERR_INTERNAL_ERROR; switch (mac->type) { case SSH_DIGEST: @@ -190,10 +188,10 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 || ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 || ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) - fatal("ssh_hmac failed"); + return SSH_ERR_LIBCRYPTO_ERROR; break; case SSH_UMAC: - put_u64(nonce, seqno); + POKE_U64(nonce, seqno); umac_update(mac->umac_ctx, data, datalen); umac_final(mac->umac_ctx, u.m, nonce); break; @@ -203,13 +201,18 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) umac128_final(mac->umac_ctx, u.m, nonce); break; default: - fatal("mac_compute: unknown MAC type"); + return SSH_ERR_INVALID_ARGUMENT; } - return (u.m); + if (digest != NULL) { + if (dlen > mac->mac_len) + dlen = mac->mac_len; + memcpy(digest, u.m, dlen); + } + return 0; } void -mac_clear(Mac *mac) +mac_clear(struct sshmac *mac) { if (mac->type == SSH_UMAC) { if (mac->umac_ctx != NULL) @@ -231,17 +234,16 @@ mac_valid(const char *names) char *maclist, *cp, *p; if (names == NULL || strcmp(names, "") == 0) - return (0); - maclist = cp = xstrdup(names); + return 0; + if ((maclist = cp = strdup(names)) == NULL) + return 0; for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; (p = strsep(&cp, MAC_SEP))) { if (mac_setup(NULL, p) < 0) { - debug("bad mac %s [%s]", p, names); free(maclist); - return (0); + return 0; } } - debug3("macs ok: [%s]", names); free(maclist); - return (1); + return 1; } diff --git a/crypto/openssh/mac.h b/crypto/openssh/mac.h index fbe18c463bbc..e5f6b84d9ed6 100644 --- a/crypto/openssh/mac.h +++ b/crypto/openssh/mac.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.h,v 1.8 2013/11/07 11:58:27 dtucker Exp $ */ +/* $OpenBSD: mac.h,v 1.9 2015/01/13 19:31:40 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -23,9 +23,29 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef SSHMAC_H +#define SSHMAC_H + +#include + +struct sshmac { + char *name; + int enabled; + u_int mac_len; + u_char *key; + u_int key_len; + int type; + int etm; /* Encrypt-then-MAC */ + struct ssh_hmac_ctx *hmac_ctx; + struct umac_ctx *umac_ctx; +}; + int mac_valid(const char *); char *mac_alg_list(char); -int mac_setup(Mac *, char *); -int mac_init(Mac *); -u_char *mac_compute(Mac *, u_int32_t, u_char *, int); -void mac_clear(Mac *); +int mac_setup(struct sshmac *, char *); +int mac_init(struct sshmac *); +int mac_compute(struct sshmac *, u_int32_t, const u_char *, int, + u_char *, size_t); +void mac_clear(struct sshmac *); + +#endif /* SSHMAC_H */ diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c index f7595abfbb8d..e6903815f418 100644 --- a/crypto/openssh/misc.c +++ b/crypto/openssh/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.94 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: misc.c,v 1.96 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -31,8 +31,8 @@ __RCSID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -552,7 +552,7 @@ tilde_expand_filename(const char *filename, uid_t uid) if (path != NULL) filename = path + 1; - if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= MAXPATHLEN) + if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX) fatal("tilde_expand_filename: Path too long"); return (ret); diff --git a/crypto/openssh/moduli.0 b/crypto/openssh/moduli.0 index d9aaadba9855..1c580d46c5d7 100644 --- a/crypto/openssh/moduli.0 +++ b/crypto/openssh/moduli.0 @@ -1,7 +1,7 @@ MODULI(5) File Formats Manual MODULI(5) NAME - moduli - Diffie-Hellman moduli + moduli M-bM-^@M-^S Diffie-Hellman moduli DESCRIPTION The /etc/moduli file contains prime numbers and generators for use by @@ -38,7 +38,7 @@ DESCRIPTION bitmask of the following values: 0x00 Not tested. - 0x01 Composite number - not prime. + 0x01 Composite number M-bM-^@M-^S not prime. 0x02 Sieve of Eratosthenes. 0x04 Probabilistic Miller-Rabin primality tests. @@ -71,4 +71,4 @@ STANDARDS the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, 2006. -OpenBSD 5.6 September 26, 2012 OpenBSD 5.6 +OpenBSD 5.7 September 26, 2012 OpenBSD 5.7 diff --git a/crypto/openssh/moduli.c b/crypto/openssh/moduli.c index bb4dd7beb49d..ed1bdc9467cf 100644 --- a/crypto/openssh/moduli.c +++ b/crypto/openssh/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.28 2013/10/24 00:49:49 dtucker Exp $ */ +/* $OpenBSD: moduli.c,v 1.30 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -39,7 +39,9 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL + +#include /* MAX */ #include #include @@ -52,6 +54,7 @@ #include #include #include +#include #include "xmalloc.h" #include "dh.h" @@ -447,11 +450,11 @@ static void write_checkpoint(char *cpfile, u_int32_t lineno) { FILE *fp; - char tmp[MAXPATHLEN]; + char tmp[PATH_MAX]; int r; r = snprintf(tmp, sizeof(tmp), "%s.XXXXXXXXXX", cpfile); - if (r == -1 || r >= MAXPATHLEN) { + if (r == -1 || r >= PATH_MAX) { logit("write_checkpoint: temp pathname too long"); return; } @@ -461,6 +464,7 @@ write_checkpoint(char *cpfile, u_int32_t lineno) } if ((fp = fdopen(r, "w")) == NULL) { logit("write_checkpoint: fdopen: %s", strerror(errno)); + unlink(tmp); close(r); return; } @@ -801,3 +805,5 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted, return (res); } + +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c index 16d82a7a32b9..7af19b12a179 100644 --- a/crypto/openssh/monitor.c +++ b/crypto/openssh/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.135 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: monitor.c,v 1.145 2015/02/20 22:17:21 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -28,7 +28,6 @@ #include "includes.h" #include -#include #include #include "openbsd-compat/sys-tree.h" #include @@ -40,6 +39,9 @@ #endif #include #include +#ifdef HAVE_STDINT_H +#include +#endif #include #include #include @@ -100,6 +102,8 @@ #include "ssh2.h" #include "roaming.h" #include "authfd.h" +#include "match.h" +#include "ssherr.h" #ifdef GSSAPI static Gssctxt *gsscontext = NULL; @@ -108,38 +112,13 @@ static Gssctxt *gsscontext = NULL; /* Imports */ extern ServerOptions options; extern u_int utmp_len; -extern Newkeys *current_keys[]; -extern z_stream incoming_stream; -extern z_stream outgoing_stream; extern u_char session_id[]; extern Buffer auth_debug; extern int auth_debug_init; extern Buffer loginmsg; /* State exported from the child */ - -struct { - z_stream incoming; - z_stream outgoing; - u_char *keyin; - u_int keyinlen; - u_char *keyout; - u_int keyoutlen; - u_char *ivin; - u_int ivinlen; - u_char *ivout; - u_int ivoutlen; - u_char *ssh1key; - u_int ssh1keylen; - int ssh1cipher; - int ssh1protoflags; - u_char *input; - u_int ilen; - u_char *output; - u_int olen; - u_int64_t sent_bytes; - u_int64_t recv_bytes; -} child_state; +static struct sshbuf *child_state; /* Functions on the monitor that answer unprivileged requests */ @@ -504,6 +483,27 @@ monitor_sync(struct monitor *pmonitor) } } +/* Allocation functions for zlib */ +static void * +mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) +{ + size_t len = (size_t) size * ncount; + void *address; + + if (len == 0 || ncount > SIZE_MAX / size) + fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); + + address = mm_malloc(mm, len); + + return (address); +} + +static void +mm_zfree(struct mm_master *mm, void *address) +{ + mm_free(mm, address); +} + static int monitor_read_log(struct monitor *pmonitor) { @@ -684,28 +684,60 @@ mm_answer_moduli(int sock, Buffer *m) } #endif -extern AuthenticationConnection *auth_conn; - int mm_answer_sign(int sock, Buffer *m) { - Key *key; + struct ssh *ssh = active_state; /* XXX */ + extern int auth_sock; /* XXX move to state struct? */ + struct sshkey *key; + struct sshbuf *sigbuf; u_char *p; u_char *signature; - u_int siglen, datlen; - int keyid; + size_t datlen, siglen; + int r, keyid, is_proof = 0; + const char proof_req[] = "hostkeys-prove-00@openssh.com"; debug3("%s", __func__); - keyid = buffer_get_int(m); - p = buffer_get_string(m, &datlen); + if ((r = sshbuf_get_u32(m, &keyid)) != 0 || + (r = sshbuf_get_string(m, &p, &datlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), * SHA384 (48 bytes) and SHA512 (64 bytes). + * + * Otherwise, verify the signature request is for a hostkey + * proof. + * + * XXX perform similar check for KEX signature requests too? + * it's not trivial, since what is signed is the hash, rather + * than the full kex structure... */ - if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) - fatal("%s: data length incorrect: %u", __func__, datlen); + if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) { + /* + * Construct expected hostkey proof and compare it to what + * the client sent us. + */ + if (session_id2_len == 0) /* hostkeys is never first */ + fatal("%s: bad data length: %zu", __func__, datlen); + if ((key = get_hostkey_public_by_index(keyid, ssh)) == NULL) + fatal("%s: no hostkey for index %d", __func__, keyid); + if ((sigbuf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new", __func__); + if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 || + (r = sshbuf_put_string(sigbuf, session_id2, + session_id2_len) != 0) || + (r = sshkey_puts(key, sigbuf)) != 0) + fatal("%s: couldn't prepare private key " + "proof buffer: %s", __func__, ssh_err(r)); + if (datlen != sshbuf_len(sigbuf) || + memcmp(p, sshbuf_ptr(sigbuf), sshbuf_len(sigbuf)) != 0) + fatal("%s: bad data length: %zu, hostkey proof len %zu", + __func__, datlen, sshbuf_len(sigbuf)); + sshbuf_free(sigbuf); + is_proof = 1; + } /* save session id, it will be passed on the first call */ if (session_id2_len == 0) { @@ -715,20 +747,26 @@ mm_answer_sign(int sock, Buffer *m) } if ((key = get_hostkey_by_index(keyid)) != NULL) { - if (key_sign(key, &signature, &siglen, p, datlen) < 0) - fatal("%s: key_sign failed", __func__); - } else if ((key = get_hostkey_public_by_index(keyid)) != NULL && - auth_conn != NULL) { - if (ssh_agent_sign(auth_conn, key, &signature, &siglen, p, - datlen) < 0) - fatal("%s: ssh_agent_sign failed", __func__); + if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, + datafellows)) != 0) + fatal("%s: sshkey_sign failed: %s", + __func__, ssh_err(r)); + } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && + auth_sock > 0) { + if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, + p, datlen, datafellows)) != 0) { + fatal("%s: ssh_agent_sign failed: %s", + __func__, ssh_err(r)); + } } else fatal("%s: no hostkey from index %d", __func__, keyid); - debug3("%s: signature %p(%u)", __func__, signature, siglen); + debug3("%s: %s signature %p(%zu)", __func__, + is_proof ? "KEX" : "hostkey proof", signature, siglen); - buffer_clear(m); - buffer_put_string(m, signature, siglen); + sshbuf_reset(m); + if ((r = sshbuf_put_string(m, signature, siglen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); free(p); free(signature); @@ -1167,9 +1205,18 @@ mm_answer_keyallowed(int sock, Buffer *m) debug3("%s: key_from_blob: %p", __func__, key); if (key != NULL && authctxt->valid) { + /* These should not make it past the privsep child */ + if (key_type_plain(key->type) == KEY_RSA && + (datafellows & SSH_BUG_RSASIGMD5) != 0) + fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__); + switch (type) { case MM_USERKEY: allowed = options.pubkey_authentication && + !auth2_userkey_already_used(authctxt, key) && + match_pattern_list(sshkey_ssh_name(key), + options.pubkey_key_types, + strlen(options.pubkey_key_types), 0) == 1 && user_key_allowed(authctxt->pw, key); pubkey_auth_info(authctxt, key, NULL); auth_method = "publickey"; @@ -1178,6 +1225,9 @@ mm_answer_keyallowed(int sock, Buffer *m) break; case MM_HOSTKEY: allowed = options.hostbased_authentication && + match_pattern_list(sshkey_ssh_name(key), + options.hostbased_key_types, + strlen(options.hostbased_key_types), 0) == 1 && hostbased_key_allowed(authctxt->pw, cuser, chost, key); pubkey_auth_info(authctxt, key, @@ -1397,7 +1447,12 @@ mm_answer_keyverify(int sock, Buffer *m) debug3("%s: key %p signature %s", __func__, key, (verified == 1) ? "verified" : "unverified"); - key_free(key); + /* If auth was successful then record key to ensure it isn't reused */ + if (verified == 1) + auth2_record_userkey(authctxt, key); + else + key_free(key); + free(blob); free(signature); free(data); @@ -1783,105 +1838,40 @@ mm_answer_audit_command(int socket, Buffer *m) void monitor_apply_keystate(struct monitor *pmonitor) { - if (compat20) { - set_newkeys(MODE_IN); - set_newkeys(MODE_OUT); - } else { - packet_set_protocol_flags(child_state.ssh1protoflags); - packet_set_encryption_key(child_state.ssh1key, - child_state.ssh1keylen, child_state.ssh1cipher); - free(child_state.ssh1key); + struct ssh *ssh = active_state; /* XXX */ + struct kex *kex; + int r; + + debug3("%s: packet_set_state", __func__); + if ((r = ssh_packet_set_state(ssh, child_state)) != 0) + fatal("%s: packet_set_state: %s", __func__, ssh_err(r)); + sshbuf_free(child_state); + child_state = NULL; + + if ((kex = ssh->kex) != 0) { + /* XXX set callbacks */ +#ifdef WITH_OPENSSL + kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +# ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kexecdh_server; +# endif +#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kexc25519_server; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; + kex->sign = sshd_hostkey_sign; } - /* for rc4 and other stateful ciphers */ - packet_set_keycontext(MODE_OUT, child_state.keyout); - free(child_state.keyout); - packet_set_keycontext(MODE_IN, child_state.keyin); - free(child_state.keyin); - - if (!compat20) { - packet_set_iv(MODE_OUT, child_state.ivout); - free(child_state.ivout); - packet_set_iv(MODE_IN, child_state.ivin); - free(child_state.ivin); - } - - memcpy(&incoming_stream, &child_state.incoming, - sizeof(incoming_stream)); - memcpy(&outgoing_stream, &child_state.outgoing, - sizeof(outgoing_stream)); - /* Update with new address */ - if (options.compression) - mm_init_compression(pmonitor->m_zlib); - - packet_set_postauth(); - - if (options.rekey_limit || options.rekey_interval) - packet_set_rekey_limits((u_int32_t)options.rekey_limit, - (time_t)options.rekey_interval); - - /* Network I/O buffers */ - /* XXX inefficient for large buffers, need: buffer_init_from_string */ - buffer_clear(packet_get_input()); - buffer_append(packet_get_input(), child_state.input, child_state.ilen); - explicit_bzero(child_state.input, child_state.ilen); - free(child_state.input); - - buffer_clear(packet_get_output()); - buffer_append(packet_get_output(), child_state.output, - child_state.olen); - explicit_bzero(child_state.output, child_state.olen); - free(child_state.output); - - /* Roaming */ - if (compat20) - roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes); -} - -static Kex * -mm_get_kex(Buffer *m) -{ - Kex *kex; - void *blob; - u_int bloblen; - - kex = xcalloc(1, sizeof(*kex)); - kex->session_id = buffer_get_string(m, &kex->session_id_len); - if (session_id2 == NULL || - kex->session_id_len != session_id2_len || - timingsafe_bcmp(kex->session_id, session_id2, session_id2_len) != 0) - fatal("mm_get_get: internal error: bad session id"); - kex->we_need = buffer_get_int(m); -#ifdef WITH_OPENSSL - kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; - kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - kex->kex[KEX_ECDH_SHA2] = kexecdh_server; -#endif - kex->kex[KEX_C25519_SHA256] = kexc25519_server; - kex->server = 1; - kex->hostkey_type = buffer_get_int(m); - kex->kex_type = buffer_get_int(m); - blob = buffer_get_string(m, &bloblen); - buffer_init(&kex->my); - buffer_append(&kex->my, blob, bloblen); - free(blob); - blob = buffer_get_string(m, &bloblen); - buffer_init(&kex->peer); - buffer_append(&kex->peer, blob, bloblen); - free(blob); - kex->done = 1; - kex->flags = buffer_get_int(m); - kex->client_version_string = buffer_get_string(m, NULL); - kex->server_version_string = buffer_get_string(m, NULL); - kex->load_host_public_key=&get_hostkey_public_by_type; - kex->load_host_private_key=&get_hostkey_private_by_type; - kex->host_key_index=&get_hostkey_index; - kex->sign = sshd_hostkey_sign; - - return (kex); + if (options.compression) { + ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib, + (ssh_packet_comp_alloc_func *)mm_zalloc, + (ssh_packet_comp_free_func *)mm_zfree); + } } /* This function requries careful sanity checking */ @@ -1889,118 +1879,16 @@ mm_get_kex(Buffer *m) void mm_get_keystate(struct monitor *pmonitor) { - Buffer m; - u_char *blob, *p; - u_int bloblen, plen; - u_int32_t seqnr, packets; - u_int64_t blocks, bytes; - debug3("%s: Waiting for new keys", __func__); - buffer_init(&m); - mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); - if (!compat20) { - child_state.ssh1protoflags = buffer_get_int(&m); - child_state.ssh1cipher = buffer_get_int(&m); - child_state.ssh1key = buffer_get_string(&m, - &child_state.ssh1keylen); - child_state.ivout = buffer_get_string(&m, - &child_state.ivoutlen); - child_state.ivin = buffer_get_string(&m, &child_state.ivinlen); - goto skip; - } else { - /* Get the Kex for rekeying */ - *pmonitor->m_pkex = mm_get_kex(&m); - } - - blob = buffer_get_string(&m, &bloblen); - current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); - free(blob); - - debug3("%s: Waiting for second key", __func__); - blob = buffer_get_string(&m, &bloblen); - current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen); - free(blob); - - /* Now get sequence numbers for the packets */ - seqnr = buffer_get_int(&m); - blocks = buffer_get_int64(&m); - packets = buffer_get_int(&m); - bytes = buffer_get_int64(&m); - packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes); - seqnr = buffer_get_int(&m); - blocks = buffer_get_int64(&m); - packets = buffer_get_int(&m); - bytes = buffer_get_int64(&m); - packet_set_state(MODE_IN, seqnr, blocks, packets, bytes); - - skip: - /* Get the key context */ - child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen); - child_state.keyin = buffer_get_string(&m, &child_state.keyinlen); - - debug3("%s: Getting compression state", __func__); - /* Get compression state */ - p = buffer_get_string(&m, &plen); - if (plen != sizeof(child_state.outgoing)) - fatal("%s: bad request size", __func__); - memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing)); - free(p); - - p = buffer_get_string(&m, &plen); - if (plen != sizeof(child_state.incoming)) - fatal("%s: bad request size", __func__); - memcpy(&child_state.incoming, p, sizeof(child_state.incoming)); - free(p); - - /* Network I/O buffers */ - debug3("%s: Getting Network I/O buffers", __func__); - child_state.input = buffer_get_string(&m, &child_state.ilen); - child_state.output = buffer_get_string(&m, &child_state.olen); - - /* Roaming */ - if (compat20) { - child_state.sent_bytes = buffer_get_int64(&m); - child_state.recv_bytes = buffer_get_int64(&m); - } - - buffer_free(&m); + if ((child_state = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, + child_state); + debug3("%s: GOT new keys", __func__); } -/* Allocation functions for zlib */ -void * -mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) -{ - size_t len = (size_t) size * ncount; - void *address; - - if (len == 0 || ncount > SIZE_T_MAX / size) - fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); - - address = mm_malloc(mm, len); - - return (address); -} - -void -mm_zfree(struct mm_master *mm, void *address) -{ - mm_free(mm, address); -} - -void -mm_init_compression(struct mm_master *mm) -{ - outgoing_stream.zalloc = (alloc_func)mm_zalloc; - outgoing_stream.zfree = (free_func)mm_zfree; - outgoing_stream.opaque = mm; - - incoming_stream.zalloc = (alloc_func)mm_zalloc; - incoming_stream.zfree = (free_func)mm_zfree; - incoming_stream.opaque = mm; -} - /* XXX */ #define FD_CLOSEONEXEC(x) do { \ @@ -2036,6 +1924,7 @@ monitor_openfds(struct monitor *mon, int do_logfds) struct monitor * monitor_init(void) { + struct ssh *ssh = active_state; /* XXX */ struct monitor *mon; mon = xcalloc(1, sizeof(*mon)); @@ -2048,7 +1937,9 @@ monitor_init(void) mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); /* Compression needs to share state across borders */ - mm_init_compression(mon->m_zlib); + ssh_packet_set_compress_hooks(ssh, mon->m_zlib, + (ssh_packet_comp_alloc_func *)mm_zalloc, + (ssh_packet_comp_free_func *)mm_zfree); } return mon; diff --git a/crypto/openssh/monitor.h b/crypto/openssh/monitor.h index 5bc41b513a3a..93b8b66dddba 100644 --- a/crypto/openssh/monitor.h +++ b/crypto/openssh/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.18 2014/01/29 06:18:35 djm Exp $ */ +/* $OpenBSD: monitor.h,v 1.19 2015/01/19 19:52:16 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -75,7 +75,7 @@ struct monitor { int m_log_sendfd; struct mm_master *m_zback; struct mm_master *m_zlib; - struct Kex **m_pkex; + struct kex **m_pkex; pid_t m_pid; }; diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c index 100fa5660972..2ddd80732f3a 100644 --- a/crypto/openssh/monitor_fdpass.c +++ b/crypto/openssh/monitor_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.20 2015/02/25 23:05:47 djm Exp $ */ /* * Copyright 2001 Niels Provos * All rights reserved. @@ -70,6 +70,7 @@ mm_send_fd(int sock, int fd) msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); #else + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); msg.msg_control = (caddr_t)&cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); cmsg = CMSG_FIRSTHDR(&msg); @@ -136,6 +137,7 @@ mm_receive_fd(int sock) msg.msg_accrights = (caddr_t)&fd; msg.msg_accrightslen = sizeof(fd); #else + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); msg.msg_control = &cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); #endif diff --git a/crypto/openssh/monitor_mm.c b/crypto/openssh/monitor_mm.c index 0ba0658a14a5..aa47b2ed520d 100644 --- a/crypto/openssh/monitor_mm.c +++ b/crypto/openssh/monitor_mm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_mm.c,v 1.19 2014/01/04 17:50:55 tedu Exp $ */ +/* $OpenBSD: monitor_mm.c,v 1.21 2015/02/06 23:21:59 millert Exp $ */ /* * Copyright 2002 Niels Provos * All rights reserved. @@ -30,12 +30,14 @@ #ifdef HAVE_SYS_MMAN_H #include #endif -#include #include "openbsd-compat/sys-tree.h" #include #include #include +#ifdef HAVE_STDINT_H +#include +#endif #include #include @@ -176,7 +178,7 @@ mm_malloc(struct mm_master *mm, size_t size) if (size == 0) fatal("mm_malloc: try to allocate 0 space"); - if (size > SIZE_T_MAX - MM_MINSIZE + 1) + if (size > SIZE_MAX - MM_MINSIZE + 1) fatal("mm_malloc: size too big"); size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE; diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c index 6509a1816888..6ad27f7ec483 100644 --- a/crypto/openssh/monitor_wrap.c +++ b/crypto/openssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.80 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.84 2015/02/16 22:13:32 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -82,6 +82,8 @@ #include "servconf.h" #include "roaming.h" +#include "ssherr.h" + /* Imports */ extern int compat20; extern z_stream incoming_stream; @@ -151,8 +153,10 @@ mm_request_receive(int sock, Buffer *m) debug3("%s entering", __func__); if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { - if (errno == EPIPE) + if (errno == EPIPE) { + error("%s: socket closed", __func__); cleanup_exit(255); + } fatal("%s: read: %s", __func__, strerror(errno)); } msg_len = get_u32(buf); @@ -215,15 +219,16 @@ mm_choose_dh(int min, int nbits, int max) #endif int -mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) +mm_key_sign(Key *key, u_char **sigp, u_int *lenp, + const u_char *data, u_int datalen) { - Kex *kex = *pmonitor->m_pkex; + struct kex *kex = *pmonitor->m_pkex; Buffer m; debug3("%s entering", __func__); buffer_init(&m); - buffer_put_int(&m, kex->host_key_index(key)); + buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); buffer_put_string(&m, data, datalen); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); @@ -468,239 +473,21 @@ mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) return (verified); } -/* Export key state after authentication */ -Newkeys * -mm_newkeys_from_blob(u_char *blob, int blen) -{ - Buffer b; - u_int len; - Newkeys *newkey = NULL; - Enc *enc; - Mac *mac; - Comp *comp; - - debug3("%s: %p(%d)", __func__, blob, blen); -#ifdef DEBUG_PK - dump_base64(stderr, blob, blen); -#endif - buffer_init(&b); - buffer_append(&b, blob, blen); - - newkey = xcalloc(1, sizeof(*newkey)); - enc = &newkey->enc; - mac = &newkey->mac; - comp = &newkey->comp; - - /* Enc structure */ - enc->name = buffer_get_string(&b, NULL); - buffer_get(&b, &enc->cipher, sizeof(enc->cipher)); - enc->enabled = buffer_get_int(&b); - enc->block_size = buffer_get_int(&b); - enc->key = buffer_get_string(&b, &enc->key_len); - enc->iv = buffer_get_string(&b, &enc->iv_len); - - if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) - fatal("%s: bad cipher name %s or pointer %p", __func__, - enc->name, enc->cipher); - - /* Mac structure */ - if (cipher_authlen(enc->cipher) == 0) { - mac->name = buffer_get_string(&b, NULL); - if (mac->name == NULL || mac_setup(mac, mac->name) == -1) - fatal("%s: can not setup mac %s", __func__, mac->name); - mac->enabled = buffer_get_int(&b); - mac->key = buffer_get_string(&b, &len); - if (len > mac->key_len) - fatal("%s: bad mac key length: %u > %d", __func__, len, - mac->key_len); - mac->key_len = len; - } - - /* Comp structure */ - comp->type = buffer_get_int(&b); - comp->enabled = buffer_get_int(&b); - comp->name = buffer_get_string(&b, NULL); - - len = buffer_len(&b); - if (len != 0) - error("newkeys_from_blob: remaining bytes in blob %u", len); - buffer_free(&b); - return (newkey); -} - -int -mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) -{ - Buffer b; - int len; - Enc *enc; - Mac *mac; - Comp *comp; - Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode); - - debug3("%s: converting %p", __func__, newkey); - - if (newkey == NULL) { - error("%s: newkey == NULL", __func__); - return 0; - } - enc = &newkey->enc; - mac = &newkey->mac; - comp = &newkey->comp; - - buffer_init(&b); - /* Enc structure */ - buffer_put_cstring(&b, enc->name); - /* The cipher struct is constant and shared, you export pointer */ - buffer_append(&b, &enc->cipher, sizeof(enc->cipher)); - buffer_put_int(&b, enc->enabled); - buffer_put_int(&b, enc->block_size); - buffer_put_string(&b, enc->key, enc->key_len); - packet_get_keyiv(mode, enc->iv, enc->iv_len); - buffer_put_string(&b, enc->iv, enc->iv_len); - - /* Mac structure */ - if (cipher_authlen(enc->cipher) == 0) { - buffer_put_cstring(&b, mac->name); - buffer_put_int(&b, mac->enabled); - buffer_put_string(&b, mac->key, mac->key_len); - } - - /* Comp structure */ - buffer_put_int(&b, comp->type); - buffer_put_int(&b, comp->enabled); - buffer_put_cstring(&b, comp->name); - - len = buffer_len(&b); - if (lenp != NULL) - *lenp = len; - if (blobp != NULL) { - *blobp = xmalloc(len); - memcpy(*blobp, buffer_ptr(&b), len); - } - explicit_bzero(buffer_ptr(&b), len); - buffer_free(&b); - return len; -} - -static void -mm_send_kex(Buffer *m, Kex *kex) -{ - buffer_put_string(m, kex->session_id, kex->session_id_len); - buffer_put_int(m, kex->we_need); - buffer_put_int(m, kex->hostkey_type); - buffer_put_int(m, kex->kex_type); - buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my)); - buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer)); - buffer_put_int(m, kex->flags); - buffer_put_cstring(m, kex->client_version_string); - buffer_put_cstring(m, kex->server_version_string); -} - void mm_send_keystate(struct monitor *monitor) { - Buffer m, *input, *output; - u_char *blob, *p; - u_int bloblen, plen; - u_int32_t seqnr, packets; - u_int64_t blocks, bytes; + struct ssh *ssh = active_state; /* XXX */ + struct sshbuf *m; + int r; - buffer_init(&m); - - if (!compat20) { - u_char iv[24]; - u_char *key; - u_int ivlen, keylen; - - buffer_put_int(&m, packet_get_protocol_flags()); - - buffer_put_int(&m, packet_get_ssh1_cipher()); - - debug3("%s: Sending ssh1 KEY+IV", __func__); - keylen = packet_get_encryption_key(NULL); - key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ - keylen = packet_get_encryption_key(key); - buffer_put_string(&m, key, keylen); - explicit_bzero(key, keylen); - free(key); - - ivlen = packet_get_keyiv_len(MODE_OUT); - packet_get_keyiv(MODE_OUT, iv, ivlen); - buffer_put_string(&m, iv, ivlen); - ivlen = packet_get_keyiv_len(MODE_IN); - packet_get_keyiv(MODE_IN, iv, ivlen); - buffer_put_string(&m, iv, ivlen); - goto skip; - } else { - /* Kex for rekeying */ - mm_send_kex(&m, *monitor->m_pkex); - } - - debug3("%s: Sending new keys: %p %p", - __func__, packet_get_newkeys(MODE_OUT), - packet_get_newkeys(MODE_IN)); - - /* Keys from Kex */ - if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen)) - fatal("%s: conversion of newkeys failed", __func__); - - buffer_put_string(&m, blob, bloblen); - free(blob); - - if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) - fatal("%s: conversion of newkeys failed", __func__); - - buffer_put_string(&m, blob, bloblen); - free(blob); - - packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); - buffer_put_int(&m, seqnr); - buffer_put_int64(&m, blocks); - buffer_put_int(&m, packets); - buffer_put_int64(&m, bytes); - packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes); - buffer_put_int(&m, seqnr); - buffer_put_int64(&m, blocks); - buffer_put_int(&m, packets); - buffer_put_int64(&m, bytes); - - debug3("%s: New keys have been sent", __func__); - skip: - /* More key context */ - plen = packet_get_keycontext(MODE_OUT, NULL); - p = xmalloc(plen+1); - packet_get_keycontext(MODE_OUT, p); - buffer_put_string(&m, p, plen); - free(p); - - plen = packet_get_keycontext(MODE_IN, NULL); - p = xmalloc(plen+1); - packet_get_keycontext(MODE_IN, p); - buffer_put_string(&m, p, plen); - free(p); - - /* Compression state */ - debug3("%s: Sending compression state", __func__); - buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream)); - buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream)); - - /* Network I/O buffers */ - input = (Buffer *)packet_get_input(); - output = (Buffer *)packet_get_output(); - buffer_put_string(&m, buffer_ptr(input), buffer_len(input)); - buffer_put_string(&m, buffer_ptr(output), buffer_len(output)); - - /* Roaming */ - if (compat20) { - buffer_put_int64(&m, get_sent_bytes()); - buffer_put_int64(&m, get_recv_bytes()); - } - - mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = ssh_packet_get_state(ssh, m)) != 0) + fatal("%s: get_state failed: %s", + __func__, ssh_err(r)); + mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m); debug3("%s: Finished sending state", __func__); - - buffer_free(&m); + sshbuf_free(m); } int diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h index 18c25010d9a1..e18784ac411f 100644 --- a/crypto/openssh/monitor_wrap.h +++ b/crypto/openssh/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.24 2014/01/29 06:18:35 djm Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.26 2015/02/16 22:13:32 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -40,7 +40,7 @@ struct Authctxt; void mm_log_handler(LogLevel, const char *, void *); int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); -int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int); +int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int); void mm_inform_authserv(char *, char *); struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); @@ -87,7 +87,7 @@ void mm_ssh1_session_id(u_char *); int mm_ssh1_session_key(BIGNUM *); /* Key export functions */ -struct Newkeys *mm_newkeys_from_blob(u_char *, int); +struct newkeys *mm_newkeys_from_blob(u_char *, int); int mm_newkeys_to_blob(int, u_char **, u_int *); void monitor_apply_keystate(struct monitor *); @@ -103,9 +103,6 @@ int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); /* zlib allocation hooks */ - -void *mm_zalloc(struct mm_master *, u_int, u_int); -void mm_zfree(struct mm_master *, void *); void mm_init_compression(struct mm_master *); #endif /* _MM_WRAP_H_ */ diff --git a/crypto/openssh/msg.c b/crypto/openssh/msg.c index cd5f98c4f6ce..5a7b8ca91291 100644 --- a/crypto/openssh/msg.c +++ b/crypto/openssh/msg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: msg.c,v 1.16 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -34,17 +34,18 @@ #include #include -#include "buffer.h" +#include "sshbuf.h" +#include "ssherr.h" #include "log.h" #include "atomicio.h" #include "msg.h" #include "misc.h" int -ssh_msg_send(int fd, u_char type, Buffer *m) +ssh_msg_send(int fd, u_char type, struct sshbuf *m) { u_char buf[5]; - u_int mlen = buffer_len(m); + u_int mlen = sshbuf_len(m); debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff); @@ -54,7 +55,7 @@ ssh_msg_send(int fd, u_char type, Buffer *m) error("ssh_msg_send: write"); return (-1); } - if (atomicio(vwrite, fd, buffer_ptr(m), mlen) != mlen) { + if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(m), mlen) != mlen) { error("ssh_msg_send: write"); return (-1); } @@ -62,10 +63,11 @@ ssh_msg_send(int fd, u_char type, Buffer *m) } int -ssh_msg_recv(int fd, Buffer *m) +ssh_msg_recv(int fd, struct sshbuf *m) { - u_char buf[4]; + u_char buf[4], *p; u_int msg_len; + int r; debug3("ssh_msg_recv entering"); @@ -79,9 +81,12 @@ ssh_msg_recv(int fd, Buffer *m) error("ssh_msg_recv: read: bad msg_len %u", msg_len); return (-1); } - buffer_clear(m); - buffer_append_space(m, msg_len); - if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { + sshbuf_reset(m); + if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + return -1; + } + if (atomicio(read, fd, p, msg_len) != msg_len) { error("ssh_msg_recv: read: %s", strerror(errno)); return (-1); } diff --git a/crypto/openssh/msg.h b/crypto/openssh/msg.h index b0cb9b52bc2c..dfb34247c6e9 100644 --- a/crypto/openssh/msg.h +++ b/crypto/openssh/msg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.h,v 1.4 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: msg.h,v 1.5 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -25,7 +25,8 @@ #ifndef SSH_MSG_H #define SSH_MSG_H -int ssh_msg_send(int, u_char, Buffer *); -int ssh_msg_recv(int, Buffer *); +struct sshbuf; +int ssh_msg_send(int, u_char, struct sshbuf *); +int ssh_msg_recv(int, struct sshbuf *); #endif diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c index 576913887db4..52641cb3bfb9 100644 --- a/crypto/openssh/mux.c +++ b/crypto/openssh/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.48 2014/07/17 07:22:19 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.50 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -34,7 +34,6 @@ __RCSID("$FreeBSD$"); #include -#include #include #include #include @@ -1690,7 +1689,8 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd) buffer_put_cstring(&m, fwd->listen_path); } else { buffer_put_cstring(&m, - fwd->listen_host == NULL ? "" : fwd->listen_host); + fwd->listen_host == NULL ? "" : + (*fwd->listen_host == '\0' ? "*" : fwd->listen_host)); } buffer_put_int(&m, fwd->listen_port); if (fwd->connect_path != NULL) { diff --git a/crypto/openssh/opacket.c b/crypto/openssh/opacket.c new file mode 100644 index 000000000000..b9160d59def8 --- /dev/null +++ b/crypto/openssh/opacket.c @@ -0,0 +1,349 @@ +/* Written by Markus Friedl. Placed in the public domain. */ + +#include "includes.h" + +#include "ssherr.h" +#include "packet.h" +#include "log.h" + +struct ssh *active_state, *backup_state; + +/* Map old to new API */ + +void +ssh_packet_start(struct ssh *ssh, u_char type) +{ + int r; + + if ((r = sshpkt_start(ssh, type)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +void +ssh_packet_put_char(struct ssh *ssh, int value) +{ + u_char ch = value; + int r; + + if ((r = sshpkt_put_u8(ssh, ch)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +void +ssh_packet_put_int(struct ssh *ssh, u_int value) +{ + int r; + + if ((r = sshpkt_put_u32(ssh, value)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +void +ssh_packet_put_int64(struct ssh *ssh, u_int64_t value) +{ + int r; + + if ((r = sshpkt_put_u64(ssh, value)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +void +ssh_packet_put_string(struct ssh *ssh, const void *buf, u_int len) +{ + int r; + + if ((r = sshpkt_put_string(ssh, buf, len)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +void +ssh_packet_put_cstring(struct ssh *ssh, const char *str) +{ + int r; + + if ((r = sshpkt_put_cstring(ssh, str)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +void +ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len) +{ + int r; + + if ((r = sshpkt_put(ssh, buf, len)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +#ifdef WITH_SSH1 +void +ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value) +{ + int r; + + if ((r = sshpkt_put_bignum1(ssh, value)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} +#endif + +#ifdef WITH_OPENSSL +void +ssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value) +{ + int r; + + if ((r = sshpkt_put_bignum2(ssh, value)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +# ifdef OPENSSL_HAS_ECC +void +ssh_packet_put_ecpoint(struct ssh *ssh, const EC_GROUP *curve, + const EC_POINT *point) +{ + int r; + + if ((r = sshpkt_put_ec(ssh, point, curve)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} +# endif +#endif /* WITH_OPENSSL */ + +void +ssh_packet_send(struct ssh *ssh) +{ + int r; + + if ((r = sshpkt_send(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +u_int +ssh_packet_get_char(struct ssh *ssh) +{ + u_char ch; + int r; + + if ((r = sshpkt_get_u8(ssh, &ch)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + return ch; +} + +u_int +ssh_packet_get_int(struct ssh *ssh) +{ + u_int val; + int r; + + if ((r = sshpkt_get_u32(ssh, &val)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + return val; +} + +u_int64_t +ssh_packet_get_int64(struct ssh *ssh) +{ + u_int64_t val; + int r; + + if ((r = sshpkt_get_u64(ssh, &val)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + return val; +} + +#ifdef WITH_SSH1 +void +ssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value) +{ + int r; + + if ((r = sshpkt_get_bignum1(ssh, value)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} +#endif + +#ifdef WITH_OPENSSL +void +ssh_packet_get_bignum2(struct ssh *ssh, BIGNUM * value) +{ + int r; + + if ((r = sshpkt_get_bignum2(ssh, value)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +# ifdef OPENSSL_HAS_ECC +void +ssh_packet_get_ecpoint(struct ssh *ssh, const EC_GROUP *curve, EC_POINT *point) +{ + int r; + + if ((r = sshpkt_get_ec(ssh, point, curve)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} +# endif +#endif /* WITH_OPENSSL */ + +void * +ssh_packet_get_string(struct ssh *ssh, u_int *length_ptr) +{ + int r; + size_t len; + u_char *val; + + if ((r = sshpkt_get_string(ssh, &val, &len)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + if (length_ptr != NULL) + *length_ptr = (u_int)len; + return val; +} + +const void * +ssh_packet_get_string_ptr(struct ssh *ssh, u_int *length_ptr) +{ + int r; + size_t len; + const u_char *val; + + if ((r = sshpkt_get_string_direct(ssh, &val, &len)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + if (length_ptr != NULL) + *length_ptr = (u_int)len; + return val; +} + +char * +ssh_packet_get_cstring(struct ssh *ssh, u_int *length_ptr) +{ + int r; + size_t len; + char *val; + + if ((r = sshpkt_get_cstring(ssh, &val, &len)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + if (length_ptr != NULL) + *length_ptr = (u_int)len; + return val; +} + +/* Old API, that had to be reimplemented */ + +void +packet_set_connection(int fd_in, int fd_out) +{ + active_state = ssh_packet_set_connection(active_state, fd_in, fd_out); + if (active_state == NULL) + fatal("%s: ssh_packet_set_connection failed", __func__); +} + +void +packet_backup_state(void) +{ + ssh_packet_backup_state(active_state, backup_state); +} + +void +packet_restore_state(void) +{ + ssh_packet_restore_state(active_state, backup_state); +} + +u_int +packet_get_char(void) +{ + return (ssh_packet_get_char(active_state)); +} + +u_int +packet_get_int(void) +{ + return (ssh_packet_get_int(active_state)); +} + +int +packet_read_seqnr(u_int32_t *seqnr) +{ + u_char type; + int r; + + if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0) + sshpkt_fatal(active_state, __func__, r); + return type; +} + +int +packet_read_poll_seqnr(u_int32_t *seqnr) +{ + u_char type; + int r; + + if ((r = ssh_packet_read_poll_seqnr(active_state, &type, seqnr))) + sshpkt_fatal(active_state, __func__, r); + return type; +} + +void +packet_close(void) +{ + ssh_packet_close(active_state); + active_state = NULL; +} + +void +packet_process_incoming(const char *buf, u_int len) +{ + int r; + + if ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0) + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_write_wait(void) +{ + int r; + + if ((r = ssh_packet_write_wait(active_state)) != 0) + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_write_poll(void) +{ + int r; + + if ((r = ssh_packet_write_poll(active_state)) != 0) + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_read_expect(int expected_type) +{ + int r; + + if ((r = ssh_packet_read_expect(active_state, expected_type)) != 0) + sshpkt_fatal(active_state, __func__, r); +} + +void +packet_disconnect(const char *fmt, ...) +{ + char buf[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + ssh_packet_disconnect(active_state, "%s", buf); +} + +void +packet_send_debug(const char *fmt, ...) +{ + char buf[1024]; + va_list args; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + ssh_packet_send_debug(active_state, "%s", buf); +} diff --git a/crypto/openssh/opacket.h b/crypto/openssh/opacket.h new file mode 100644 index 000000000000..a0a60e5507e1 --- /dev/null +++ b/crypto/openssh/opacket.h @@ -0,0 +1,168 @@ +#ifndef _OPACKET_H +/* Written by Markus Friedl. Placed in the public domain. */ + +/* Map old to new API */ +void ssh_packet_start(struct ssh *, u_char); +void ssh_packet_put_char(struct ssh *, int ch); +void ssh_packet_put_int(struct ssh *, u_int value); +void ssh_packet_put_int64(struct ssh *, u_int64_t value); +void ssh_packet_put_bignum(struct ssh *, BIGNUM * value); +void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value); +void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *); +void ssh_packet_put_string(struct ssh *, const void *buf, u_int len); +void ssh_packet_put_cstring(struct ssh *, const char *str); +void ssh_packet_put_raw(struct ssh *, const void *buf, u_int len); +void ssh_packet_send(struct ssh *); + +u_int ssh_packet_get_char(struct ssh *); +u_int ssh_packet_get_int(struct ssh *); +u_int64_t ssh_packet_get_int64(struct ssh *); +void ssh_packet_get_bignum(struct ssh *, BIGNUM * value); +void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value); +void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *); +void *ssh_packet_get_string(struct ssh *, u_int *length_ptr); +char *ssh_packet_get_cstring(struct ssh *, u_int *length_ptr); + +/* don't allow remaining bytes after the end of the message */ +#define ssh_packet_check_eom(ssh) \ +do { \ + int _len = ssh_packet_remaining(ssh); \ + if (_len > 0) { \ + logit("Packet integrity error (%d bytes remaining) at %s:%d", \ + _len ,__FILE__, __LINE__); \ + ssh_packet_disconnect(ssh, \ + "Packet integrity error."); \ + } \ +} while (0) + +/* old API */ +void packet_close(void); +u_int packet_get_char(void); +u_int packet_get_int(void); +void packet_backup_state(void); +void packet_restore_state(void); +void packet_set_connection(int, int); +int packet_read_seqnr(u_int32_t *); +int packet_read_poll_seqnr(u_int32_t *); +void packet_process_incoming(const char *buf, u_int len); +void packet_write_wait(void); +void packet_write_poll(void); +void packet_read_expect(int expected_type); +#define packet_set_timeout(timeout, count) \ + ssh_packet_set_timeout(active_state, (timeout), (count)) +#define packet_connection_is_on_socket() \ + ssh_packet_connection_is_on_socket(active_state) +#define packet_set_nonblocking() \ + ssh_packet_set_nonblocking(active_state) +#define packet_get_connection_in() \ + ssh_packet_get_connection_in(active_state) +#define packet_get_connection_out() \ + ssh_packet_get_connection_out(active_state) +#define packet_set_protocol_flags(protocol_flags) \ + ssh_packet_set_protocol_flags(active_state, (protocol_flags)) +#define packet_get_protocol_flags() \ + ssh_packet_get_protocol_flags(active_state) +#define packet_start_compression(level) \ + ssh_packet_start_compression(active_state, (level)) +#define packet_set_encryption_key(key, keylen, number) \ + ssh_packet_set_encryption_key(active_state, (key), (keylen), (number)) +#define packet_start(type) \ + ssh_packet_start(active_state, (type)) +#define packet_put_char(value) \ + ssh_packet_put_char(active_state, (value)) +#define packet_put_int(value) \ + ssh_packet_put_int(active_state, (value)) +#define packet_put_int64(value) \ + ssh_packet_put_int64(active_state, (value)) +#define packet_put_string( buf, len) \ + ssh_packet_put_string(active_state, (buf), (len)) +#define packet_put_cstring(str) \ + ssh_packet_put_cstring(active_state, (str)) +#define packet_put_raw(buf, len) \ + ssh_packet_put_raw(active_state, (buf), (len)) +#define packet_put_bignum(value) \ + ssh_packet_put_bignum(active_state, (value)) +#define packet_put_bignum2(value) \ + ssh_packet_put_bignum2(active_state, (value)) +#define packet_send() \ + ssh_packet_send(active_state) +#define packet_read() \ + ssh_packet_read(active_state) +#define packet_get_int64() \ + ssh_packet_get_int64(active_state) +#define packet_get_bignum(value) \ + ssh_packet_get_bignum(active_state, (value)) +#define packet_get_bignum2(value) \ + ssh_packet_get_bignum2(active_state, (value)) +#define packet_remaining() \ + ssh_packet_remaining(active_state) +#define packet_get_string(length_ptr) \ + ssh_packet_get_string(active_state, (length_ptr)) +#define packet_get_string_ptr(length_ptr) \ + ssh_packet_get_string_ptr(active_state, (length_ptr)) +#define packet_get_cstring(length_ptr) \ + ssh_packet_get_cstring(active_state, (length_ptr)) +void packet_send_debug(const char *, ...) + __attribute__((format(printf, 1, 2))); +void packet_disconnect(const char *, ...) + __attribute__((format(printf, 1, 2))) + __attribute__((noreturn)); +#define packet_have_data_to_write() \ + ssh_packet_have_data_to_write(active_state) +#define packet_not_very_much_data_to_write() \ + ssh_packet_not_very_much_data_to_write(active_state) +#define packet_set_interactive(interactive, qos_interactive, qos_bulk) \ + ssh_packet_set_interactive(active_state, (interactive), (qos_interactive), (qos_bulk)) +#define packet_is_interactive() \ + ssh_packet_is_interactive(active_state) +#define packet_set_maxsize(s) \ + ssh_packet_set_maxsize(active_state, (s)) +#define packet_inc_alive_timeouts() \ + ssh_packet_inc_alive_timeouts(active_state) +#define packet_set_alive_timeouts(ka) \ + ssh_packet_set_alive_timeouts(active_state, (ka)) +#define packet_get_maxsize() \ + ssh_packet_get_maxsize(active_state) +#define packet_add_padding(pad) \ + sshpkt_add_padding(active_state, (pad)) +#define packet_send_ignore(nbytes) \ + ssh_packet_send_ignore(active_state, (nbytes)) +#define packet_need_rekeying() \ + ssh_packet_need_rekeying(active_state) +#define packet_set_server() \ + ssh_packet_set_server(active_state) +#define packet_set_authenticated() \ + ssh_packet_set_authenticated(active_state) +#define packet_get_input() \ + ssh_packet_get_input(active_state) +#define packet_get_output() \ + ssh_packet_get_output(active_state) +#define packet_set_compress_hooks(ctx, allocfunc, freefunc) \ + ssh_packet_set_compress_hooks(active_state, ctx, \ + allocfunc, freefunc); +#define packet_check_eom() \ + ssh_packet_check_eom(active_state) +#define set_newkeys(mode) \ + ssh_set_newkeys(active_state, (mode)) +#define packet_get_state(m) \ + ssh_packet_get_state(active_state, m) +#define packet_set_state(m) \ + ssh_packet_set_state(active_state, m) +#if 0 +#define get_remote_ipaddr() \ + ssh_remote_ipaddr(active_state) +#endif +#define packet_get_raw(lenp) \ + sshpkt_ptr(active_state, lenp) +#define packet_get_ecpoint(c,p) \ + ssh_packet_get_ecpoint(active_state, c, p) +#define packet_put_ecpoint(c,p) \ + ssh_packet_put_ecpoint(active_state, c, p) +#define packet_get_rekey_timeout() \ + ssh_packet_get_rekey_timeout(active_state) +#define packet_set_rekey_limits(x,y) \ + ssh_packet_set_rekey_limits(active_state, x, y) +#define packet_get_bytes(x,y) \ + ssh_packet_get_bytes(active_state, x, y) + +#endif /* _OPACKET_H */ diff --git a/crypto/openssh/openbsd-compat/.cvsignore b/crypto/openssh/openbsd-compat/.cvsignore new file mode 100644 index 000000000000..f3c7a7c5da68 --- /dev/null +++ b/crypto/openssh/openbsd-compat/.cvsignore @@ -0,0 +1 @@ +Makefile diff --git a/crypto/openssh/openbsd-compat/Makefile.in b/crypto/openssh/openbsd-compat/Makefile.in index ab1a3e315db2..3c5e3b7f7da8 100644 --- a/crypto/openssh/openbsd-compat/Makefile.in +++ b/crypto/openssh/openbsd-compat/Makefile.in @@ -16,7 +16,7 @@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ -OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o +OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o kludge-fd_set.o diff --git a/crypto/openssh/openbsd-compat/arc4random.c b/crypto/openssh/openbsd-compat/arc4random.c index 09dbfda16492..046f57e6113c 100644 --- a/crypto/openssh/openbsd-compat/arc4random.c +++ b/crypto/openssh/openbsd-compat/arc4random.c @@ -26,15 +26,19 @@ #include "includes.h" +#include + +#include #include #include #include -#include #ifndef HAVE_ARC4RANDOM +#ifdef WITH_OPENSSL #include #include +#endif #include "log.h" @@ -73,14 +77,44 @@ _rs_init(u_char *buf, size_t n) chacha_ivsetup(&rs, buf + KEYSZ); } +#ifndef WITH_OPENSSL +#define SSH_RANDOM_DEV "/dev/urandom" +/* XXX use getrandom() if supported on Linux */ +static void +getrnd(u_char *s, size_t len) +{ + int fd; + ssize_t r; + size_t o = 0; + + if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) + fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, strerror(errno)); + while (o < len) { + r = read(fd, s + o, len - o); + if (r < 0) { + if (errno == EAGAIN || errno == EINTR || + errno == EWOULDBLOCK) + continue; + fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno)); + } + o += r; + } + close(fd); +} +#endif + static void _rs_stir(void) { u_char rnd[KEYSZ + IVSZ]; +#ifdef WITH_OPENSSL if (RAND_bytes(rnd, sizeof(rnd)) <= 0) fatal("Couldn't obtain random bytes (error %ld)", ERR_get_error()); +#else + getrnd(rnd, sizeof(rnd)); +#endif if (!rs_initialized) { rs_initialized = 1; diff --git a/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c b/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c index 91b6ba07be59..16912575afe8 100644 --- a/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c +++ b/crypto/openssh/openbsd-compat/bcrypt_pbkdf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.9 2014/07/13 21:21:25 tedu Exp $ */ /* * Copyright (c) 2013 Ted Unangst * @@ -32,6 +32,9 @@ #endif #include "crypto_api.h" +#ifdef SHA512_DIGEST_LENGTH +# undef SHA512_DIGEST_LENGTH +#endif #define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES /* @@ -51,8 +54,8 @@ * * One modification from official pbkdf2. Instead of outputting key material * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to - * generate (i.e.) 512 bits of key material for use as two 256 bit keys, an - * attacker can merely run once through the outer loop below, but the user + * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an + * attacker can merely run once through the outer loop, but the user * always runs it twice. Shuffling output bytes requires computing the * entirety of the key material to assemble any subkey. This is something a * wise caller could do; we just do it for you. @@ -97,9 +100,9 @@ bcrypt_hash(u_int8_t *sha2pass, u_int8_t *sha2salt, u_int8_t *out) } /* zap */ - memset(ciphertext, 0, sizeof(ciphertext)); - memset(cdata, 0, sizeof(cdata)); - memset(&state, 0, sizeof(state)); + explicit_bzero(ciphertext, sizeof(ciphertext)); + explicit_bzero(cdata, sizeof(cdata)); + explicit_bzero(&state, sizeof(state)); } int @@ -113,6 +116,7 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t salt u_int8_t *countsalt; size_t i, j, amt, stride; uint32_t count; + size_t origkeylen = keylen; /* nothing crazy */ if (rounds < 1) @@ -155,14 +159,17 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const u_int8_t *salt, size_t salt * pbkdf2 deviation: ouput the key material non-linearly. */ amt = MIN(amt, keylen); - for (i = 0; i < amt; i++) - key[i * stride + (count - 1)] = out[i]; - keylen -= amt; + for (i = 0; i < amt; i++) { + size_t dest = i * stride + (count - 1); + if (dest >= origkeylen) + break; + key[dest] = out[i]; + } + keylen -= i; } /* zap */ - memset(out, 0, sizeof(out)); - memset(countsalt, 0, saltlen + 4); + explicit_bzero(out, sizeof(out)); free(countsalt); return 0; diff --git a/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c index 65e800397cd6..f7be415ec226 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.c +++ b/crypto/openssh/openbsd-compat/bsd-misc.c @@ -31,8 +31,6 @@ #include #include -#include "xmalloc.h" - #ifndef HAVE___PROGNAME char *__progname; #endif @@ -43,13 +41,12 @@ char *__progname; */ char *ssh_get_progname(char *argv0) { + char *p, *q; #ifdef HAVE___PROGNAME extern char *__progname; - return xstrdup(__progname); + p = __progname; #else - char *p; - if (argv0 == NULL) return ("unknown"); /* XXX */ p = strrchr(argv0, '/'); @@ -57,9 +54,12 @@ char *ssh_get_progname(char *argv0) p = argv0; else p++; - - return (xstrdup(p)); #endif + if ((q = strdup(p)) == NULL) { + perror("strdup"); + exit(1); + } + return q; } #ifndef HAVE_SETLOGIN diff --git a/crypto/openssh/openbsd-compat/fake-rfc2553.h b/crypto/openssh/openbsd-compat/fake-rfc2553.h index 3e9090fc8c16..6426f7bf6441 100644 --- a/crypto/openssh/openbsd-compat/fake-rfc2553.h +++ b/crypto/openssh/openbsd-compat/fake-rfc2553.h @@ -109,6 +109,9 @@ struct sockaddr_in6 { #ifndef AI_NUMERICHOST # define AI_NUMERICHOST (1<<2) #endif +#ifndef AI_NUMERICSERV +# define AI_NUMERICSERV (1<<3) +#endif #ifndef NI_MAXSERV # define NI_MAXSERV 32 diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c b/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c index 343720f1091c..4647b623b862 100644 --- a/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c +++ b/crypto/openssh/openbsd-compat/getrrsetbyname-ldns.c @@ -69,7 +69,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, struct rrsetinfo *rrset = NULL; struct rdatainfo *rdata; size_t len; - ldns_resolver *ldns_res; + ldns_resolver *ldns_res = NULL; ldns_rdf *domain = NULL; ldns_pkt *pkt = NULL; ldns_rr_list *rrsigs = NULL, *rrdata = NULL; diff --git a/crypto/openssh/openbsd-compat/md5.c b/crypto/openssh/openbsd-compat/md5.c new file mode 100644 index 000000000000..195ab515d1ba --- /dev/null +++ b/crypto/openssh/openbsd-compat/md5.c @@ -0,0 +1,251 @@ +/* $OpenBSD: md5.c,v 1.9 2014/01/08 06:14:57 tedu Exp $ */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +#include "includes.h" + +#ifndef WITH_OPENSSL + +#include +#include +#include "md5.h" + +#define PUT_64BIT_LE(cp, value) do { \ + (cp)[7] = (value) >> 56; \ + (cp)[6] = (value) >> 48; \ + (cp)[5] = (value) >> 40; \ + (cp)[4] = (value) >> 32; \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do { \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void +MD5Init(MD5_CTX *ctx) +{ + ctx->count = 0; + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xefcdab89; + ctx->state[2] = 0x98badcfe; + ctx->state[3] = 0x10325476; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void +MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) +{ + size_t have, need; + + /* Check how many bytes we already have and how many more we need. */ + have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); + need = MD5_BLOCK_LENGTH - have; + + /* Update bitcount */ + ctx->count += (u_int64_t)len << 3; + + if (len >= need) { + if (have != 0) { + memcpy(ctx->buffer + have, input, need); + MD5Transform(ctx->state, ctx->buffer); + input += need; + len -= need; + have = 0; + } + + /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ + while (len >= MD5_BLOCK_LENGTH) { + MD5Transform(ctx->state, input); + input += MD5_BLOCK_LENGTH; + len -= MD5_BLOCK_LENGTH; + } + } + + /* Handle any remaining bytes of data. */ + if (len != 0) + memcpy(ctx->buffer + have, input, len); +} + +/* + * Pad pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void +MD5Pad(MD5_CTX *ctx) +{ + u_int8_t count[8]; + size_t padlen; + + /* Convert count to 8 bytes in little endian order. */ + PUT_64BIT_LE(count, ctx->count); + + /* Pad out to 56 mod 64. */ + padlen = MD5_BLOCK_LENGTH - + ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); + if (padlen < 1 + 8) + padlen += MD5_BLOCK_LENGTH; + MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ + MD5Update(ctx, count, 8); +} + +/* + * Final wrapup--call MD5Pad, fill in digest and zero out ctx. + */ +void +MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) +{ + int i; + + MD5Pad(ctx); + for (i = 0; i < 4; i++) + PUT_32BIT_LE(digest + i * 4, ctx->state[i]); + memset(ctx, 0, sizeof(*ctx)); +} + + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void +MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; + +#if BYTE_ORDER == LITTLE_ENDIAN + memcpy(in, block, sizeof(in)); +#else + for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { + in[a] = (u_int32_t)( + (u_int32_t)(block[a * 4 + 0]) | + (u_int32_t)(block[a * 4 + 1]) << 8 | + (u_int32_t)(block[a * 4 + 2]) << 16 | + (u_int32_t)(block[a * 4 + 3]) << 24); + } +#endif + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + + MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; +} +#endif /* !WITH_OPENSSL */ diff --git a/crypto/openssh/openbsd-compat/md5.h b/crypto/openssh/openbsd-compat/md5.h new file mode 100644 index 000000000000..c83c19dcac60 --- /dev/null +++ b/crypto/openssh/openbsd-compat/md5.h @@ -0,0 +1,51 @@ +/* $OpenBSD: md5.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $ */ + +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + */ + +#ifndef _MD5_H_ +#define _MD5_H_ + +#ifndef WITH_OPENSSL + +#define MD5_BLOCK_LENGTH 64 +#define MD5_DIGEST_LENGTH 16 +#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) + +typedef struct MD5Context { + u_int32_t state[4]; /* state */ + u_int64_t count; /* number of bits, mod 2^64 */ + u_int8_t buffer[MD5_BLOCK_LENGTH]; /* input buffer */ +} MD5_CTX; + +void MD5Init(MD5_CTX *); +void MD5Update(MD5_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void MD5Pad(MD5_CTX *); +void MD5Final(u_int8_t [MD5_DIGEST_LENGTH], MD5_CTX *) + __attribute__((__bounded__(__minbytes__,1,MD5_DIGEST_LENGTH))); +void MD5Transform(u_int32_t [4], const u_int8_t [MD5_BLOCK_LENGTH]) + __attribute__((__bounded__(__minbytes__,1,4))) + __attribute__((__bounded__(__minbytes__,2,MD5_BLOCK_LENGTH))); +char *MD5End(MD5_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); +char *MD5File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); +char *MD5FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,MD5_DIGEST_STRING_LENGTH))); +char *MD5Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,MD5_DIGEST_STRING_LENGTH))); + +#endif /* !WITH_OPENSSL */ + +#endif /* _MD5_H_ */ diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h index ce6abae8237c..1cffefe06502 100644 --- a/crypto/openssh/openbsd-compat/openbsd-compat.h +++ b/crypto/openssh/openbsd-compat/openbsd-compat.h @@ -43,7 +43,10 @@ #include "readpassphrase.h" #include "vis.h" #include "getrrsetbyname.h" +#include "sha1.h" #include "sha2.h" +#include "rmd160.h" +#include "md5.h" #include "blf.h" #ifndef HAVE_BASENAME @@ -62,6 +65,10 @@ void closefrom(int); char *getcwd(char *pt, size_t size); #endif +#ifndef HAVE_REALLOCARRAY +void *reallocarray(void *, size_t, size_t); +#endif + #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) char *realpath(const char *path, char *resolved); #endif diff --git a/crypto/openssh/openbsd-compat/openssl-compat.c b/crypto/openssh/openbsd-compat/openssl-compat.c index 36570e4ade44..63a660c7a42a 100644 --- a/crypto/openssh/openbsd-compat/openssl-compat.c +++ b/crypto/openssh/openbsd-compat/openssl-compat.c @@ -19,6 +19,8 @@ #define SSH_DONT_OVERLOAD_OPENSSL_FUNCS #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -78,3 +80,5 @@ ssh_OpenSSL_add_all_algorithms(void) OPENSSL_config(NULL); } #endif + +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/openbsd-compat/openssl-compat.h b/crypto/openssh/openbsd-compat/openssl-compat.h index 3695d412b0c2..8917551d314e 100644 --- a/crypto/openssh/openbsd-compat/openssl-compat.h +++ b/crypto/openssh/openbsd-compat/openssl-compat.h @@ -20,6 +20,8 @@ #define _OPENSSL_COMPAT_H #include "includes.h" +#ifdef WITH_OPENSSL + #include #include #include @@ -90,4 +92,5 @@ void ssh_OpenSSL_add_all_algorithms(void); #endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ +#endif /* WITH_OPENSSL */ #endif /* _OPENSSL_COMPAT_H */ diff --git a/crypto/openssh/openbsd-compat/port-tun.c b/crypto/openssh/openbsd-compat/port-tun.c index 0d756f74f806..49e7b4d99d1a 100644 --- a/crypto/openssh/openbsd-compat/port-tun.c +++ b/crypto/openssh/openbsd-compat/port-tun.c @@ -32,8 +32,9 @@ #include "openbsd-compat/sys-queue.h" #include "log.h" #include "misc.h" -#include "buffer.h" +#include "sshbuf.h" #include "channels.h" +#include "ssherr.h" /* * This is the portable version of the SSH tunnel forwarding, it @@ -210,6 +211,7 @@ sys_tun_infilter(struct Channel *c, char *buf, int len) #endif u_int32_t *af; char *ptr = buf; + int r; #if defined(SSH_TUN_PREPEND_AF) if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) @@ -242,7 +244,8 @@ sys_tun_infilter(struct Channel *c, char *buf, int len) *af = htonl(OPENBSD_AF_INET); #endif - buffer_put_string(&c->input, ptr, len); + if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); return (0); } @@ -251,8 +254,14 @@ sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) { u_char *buf; u_int32_t *af; + int r; + size_t xxx_dlen; - *data = buffer_get_string(&c->output, dlen); + /* XXX new API is incompatible with this signature. */ + if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (dlen != NULL) + *dlen = xxx_dlen; if (*dlen < sizeof(*af)) return (NULL); buf = *data; diff --git a/crypto/openssh/openbsd-compat/readpassphrase.c b/crypto/openssh/openbsd-compat/readpassphrase.c index 62b6d0d84380..d63cdf2f0e33 100644 --- a/crypto/openssh/openbsd-compat/readpassphrase.c +++ b/crypto/openssh/openbsd-compat/readpassphrase.c @@ -46,6 +46,14 @@ # define _POSIX_VDISABLE VDISABLE #endif +#ifndef _NSIG +# ifdef NSIG +# define _NSIG NSIG +# else +# define _NSIG 128 +# endif +#endif + static volatile sig_atomic_t signo[_NSIG]; static void handler(int); diff --git a/crypto/openssh/openbsd-compat/reallocarray.c b/crypto/openssh/openbsd-compat/reallocarray.c new file mode 100644 index 000000000000..1a52acc623fe --- /dev/null +++ b/crypto/openssh/openbsd-compat/reallocarray.c @@ -0,0 +1,46 @@ +/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ +/* + * Copyright (c) 2008 Otto Moerbeek + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/stdlib/reallocarray.c */ + +#include "includes.h" +#ifndef HAVE_REALLOCARRAY + +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include + +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) + +void * +reallocarray(void *optr, size_t nmemb, size_t size) +{ + if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && + nmemb > 0 && SIZE_MAX / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return realloc(optr, size * nmemb); +} +#endif /* HAVE_REALLOCARRAY */ diff --git a/crypto/openssh/openbsd-compat/regress/.cvsignore b/crypto/openssh/openbsd-compat/regress/.cvsignore new file mode 100644 index 000000000000..33074f4a373d --- /dev/null +++ b/crypto/openssh/openbsd-compat/regress/.cvsignore @@ -0,0 +1,6 @@ +Makefile +snprintftest +strduptest +strtonumtest +closefromtest +opensslvertest diff --git a/crypto/openssh/openbsd-compat/rmd160.c b/crypto/openssh/openbsd-compat/rmd160.c new file mode 100644 index 000000000000..2a14dd7b021f --- /dev/null +++ b/crypto/openssh/openbsd-compat/rmd160.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160", + * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997, + * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf + */ + +#include "includes.h" + +#ifndef WITH_OPENSSL + +#include +#include +#include +#include + +#define PUT_64BIT_LE(cp, value) do { \ + (cp)[7] = (value) >> 56; \ + (cp)[6] = (value) >> 48; \ + (cp)[5] = (value) >> 40; \ + (cp)[4] = (value) >> 32; \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define PUT_32BIT_LE(cp, value) do { \ + (cp)[3] = (value) >> 24; \ + (cp)[2] = (value) >> 16; \ + (cp)[1] = (value) >> 8; \ + (cp)[0] = (value); } while (0) + +#define H0 0x67452301U +#define H1 0xEFCDAB89U +#define H2 0x98BADCFEU +#define H3 0x10325476U +#define H4 0xC3D2E1F0U + +#define K0 0x00000000U +#define K1 0x5A827999U +#define K2 0x6ED9EBA1U +#define K3 0x8F1BBCDCU +#define K4 0xA953FD4EU + +#define KK0 0x50A28BE6U +#define KK1 0x5C4DD124U +#define KK2 0x6D703EF3U +#define KK3 0x7A6D76E9U +#define KK4 0x00000000U + +/* rotate x left n bits. */ +#define ROL(n, x) (((x) << (n)) | ((x) >> (32-(n)))) + +#define F0(x, y, z) ((x) ^ (y) ^ (z)) +#define F1(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define F2(x, y, z) (((x) | (~y)) ^ (z)) +#define F3(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define F4(x, y, z) ((x) ^ ((y) | (~z))) + +#define R(a, b, c, d, e, Fj, Kj, sj, rj) \ + do { \ + a = ROL(sj, a + Fj(b,c,d) + X(rj) + Kj) + e; \ + c = ROL(10, c); \ + } while(0) + +#define X(i) x[i] + +static u_int8_t PADDING[RMD160_BLOCK_LENGTH] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void +RMD160Init(RMD160_CTX *ctx) +{ + ctx->count = 0; + ctx->state[0] = H0; + ctx->state[1] = H1; + ctx->state[2] = H2; + ctx->state[3] = H3; + ctx->state[4] = H4; +} + +void +RMD160Update(RMD160_CTX *ctx, const u_int8_t *input, size_t len) +{ + size_t have, off, need; + + have = (ctx->count / 8) % RMD160_BLOCK_LENGTH; + need = RMD160_BLOCK_LENGTH - have; + ctx->count += 8 * len; + off = 0; + + if (len >= need) { + if (have) { + memcpy(ctx->buffer + have, input, need); + RMD160Transform(ctx->state, ctx->buffer); + off = need; + have = 0; + } + /* now the buffer is empty */ + while (off + RMD160_BLOCK_LENGTH <= len) { + RMD160Transform(ctx->state, input+off); + off += RMD160_BLOCK_LENGTH; + } + } + if (off < len) + memcpy(ctx->buffer + have, input+off, len-off); +} + +void +RMD160Pad(RMD160_CTX *ctx) +{ + u_int8_t size[8]; + size_t padlen; + + PUT_64BIT_LE(size, ctx->count); + + /* + * pad to RMD160_BLOCK_LENGTH byte blocks, at least one byte from + * PADDING plus 8 bytes for the size + */ + padlen = RMD160_BLOCK_LENGTH - ((ctx->count / 8) % RMD160_BLOCK_LENGTH); + if (padlen < 1 + 8) + padlen += RMD160_BLOCK_LENGTH; + RMD160Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ + RMD160Update(ctx, size, 8); +} + +void +RMD160Final(u_int8_t digest[RMD160_DIGEST_LENGTH], RMD160_CTX *ctx) +{ + int i; + + RMD160Pad(ctx); + for (i = 0; i < 5; i++) + PUT_32BIT_LE(digest + i*4, ctx->state[i]); + memset(ctx, 0, sizeof (*ctx)); +} + +void +RMD160Transform(u_int32_t state[5], const u_int8_t block[RMD160_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16]; + +#if BYTE_ORDER == LITTLE_ENDIAN + memcpy(x, block, RMD160_BLOCK_LENGTH); +#else + int i; + + for (i = 0; i < 16; i++) + x[i] = (u_int32_t)( + (u_int32_t)(block[i*4 + 0]) | + (u_int32_t)(block[i*4 + 1]) << 8 | + (u_int32_t)(block[i*4 + 2]) << 16 | + (u_int32_t)(block[i*4 + 3]) << 24); +#endif + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* Round 1 */ + R(a, b, c, d, e, F0, K0, 11, 0); + R(e, a, b, c, d, F0, K0, 14, 1); + R(d, e, a, b, c, F0, K0, 15, 2); + R(c, d, e, a, b, F0, K0, 12, 3); + R(b, c, d, e, a, F0, K0, 5, 4); + R(a, b, c, d, e, F0, K0, 8, 5); + R(e, a, b, c, d, F0, K0, 7, 6); + R(d, e, a, b, c, F0, K0, 9, 7); + R(c, d, e, a, b, F0, K0, 11, 8); + R(b, c, d, e, a, F0, K0, 13, 9); + R(a, b, c, d, e, F0, K0, 14, 10); + R(e, a, b, c, d, F0, K0, 15, 11); + R(d, e, a, b, c, F0, K0, 6, 12); + R(c, d, e, a, b, F0, K0, 7, 13); + R(b, c, d, e, a, F0, K0, 9, 14); + R(a, b, c, d, e, F0, K0, 8, 15); /* #15 */ + /* Round 2 */ + R(e, a, b, c, d, F1, K1, 7, 7); + R(d, e, a, b, c, F1, K1, 6, 4); + R(c, d, e, a, b, F1, K1, 8, 13); + R(b, c, d, e, a, F1, K1, 13, 1); + R(a, b, c, d, e, F1, K1, 11, 10); + R(e, a, b, c, d, F1, K1, 9, 6); + R(d, e, a, b, c, F1, K1, 7, 15); + R(c, d, e, a, b, F1, K1, 15, 3); + R(b, c, d, e, a, F1, K1, 7, 12); + R(a, b, c, d, e, F1, K1, 12, 0); + R(e, a, b, c, d, F1, K1, 15, 9); + R(d, e, a, b, c, F1, K1, 9, 5); + R(c, d, e, a, b, F1, K1, 11, 2); + R(b, c, d, e, a, F1, K1, 7, 14); + R(a, b, c, d, e, F1, K1, 13, 11); + R(e, a, b, c, d, F1, K1, 12, 8); /* #31 */ + /* Round 3 */ + R(d, e, a, b, c, F2, K2, 11, 3); + R(c, d, e, a, b, F2, K2, 13, 10); + R(b, c, d, e, a, F2, K2, 6, 14); + R(a, b, c, d, e, F2, K2, 7, 4); + R(e, a, b, c, d, F2, K2, 14, 9); + R(d, e, a, b, c, F2, K2, 9, 15); + R(c, d, e, a, b, F2, K2, 13, 8); + R(b, c, d, e, a, F2, K2, 15, 1); + R(a, b, c, d, e, F2, K2, 14, 2); + R(e, a, b, c, d, F2, K2, 8, 7); + R(d, e, a, b, c, F2, K2, 13, 0); + R(c, d, e, a, b, F2, K2, 6, 6); + R(b, c, d, e, a, F2, K2, 5, 13); + R(a, b, c, d, e, F2, K2, 12, 11); + R(e, a, b, c, d, F2, K2, 7, 5); + R(d, e, a, b, c, F2, K2, 5, 12); /* #47 */ + /* Round 4 */ + R(c, d, e, a, b, F3, K3, 11, 1); + R(b, c, d, e, a, F3, K3, 12, 9); + R(a, b, c, d, e, F3, K3, 14, 11); + R(e, a, b, c, d, F3, K3, 15, 10); + R(d, e, a, b, c, F3, K3, 14, 0); + R(c, d, e, a, b, F3, K3, 15, 8); + R(b, c, d, e, a, F3, K3, 9, 12); + R(a, b, c, d, e, F3, K3, 8, 4); + R(e, a, b, c, d, F3, K3, 9, 13); + R(d, e, a, b, c, F3, K3, 14, 3); + R(c, d, e, a, b, F3, K3, 5, 7); + R(b, c, d, e, a, F3, K3, 6, 15); + R(a, b, c, d, e, F3, K3, 8, 14); + R(e, a, b, c, d, F3, K3, 6, 5); + R(d, e, a, b, c, F3, K3, 5, 6); + R(c, d, e, a, b, F3, K3, 12, 2); /* #63 */ + /* Round 5 */ + R(b, c, d, e, a, F4, K4, 9, 4); + R(a, b, c, d, e, F4, K4, 15, 0); + R(e, a, b, c, d, F4, K4, 5, 5); + R(d, e, a, b, c, F4, K4, 11, 9); + R(c, d, e, a, b, F4, K4, 6, 7); + R(b, c, d, e, a, F4, K4, 8, 12); + R(a, b, c, d, e, F4, K4, 13, 2); + R(e, a, b, c, d, F4, K4, 12, 10); + R(d, e, a, b, c, F4, K4, 5, 14); + R(c, d, e, a, b, F4, K4, 12, 1); + R(b, c, d, e, a, F4, K4, 13, 3); + R(a, b, c, d, e, F4, K4, 14, 8); + R(e, a, b, c, d, F4, K4, 11, 11); + R(d, e, a, b, c, F4, K4, 8, 6); + R(c, d, e, a, b, F4, K4, 5, 15); + R(b, c, d, e, a, F4, K4, 6, 13); /* #79 */ + + aa = a ; bb = b; cc = c; dd = d; ee = e; + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* Parallel round 1 */ + R(a, b, c, d, e, F4, KK0, 8, 5); + R(e, a, b, c, d, F4, KK0, 9, 14); + R(d, e, a, b, c, F4, KK0, 9, 7); + R(c, d, e, a, b, F4, KK0, 11, 0); + R(b, c, d, e, a, F4, KK0, 13, 9); + R(a, b, c, d, e, F4, KK0, 15, 2); + R(e, a, b, c, d, F4, KK0, 15, 11); + R(d, e, a, b, c, F4, KK0, 5, 4); + R(c, d, e, a, b, F4, KK0, 7, 13); + R(b, c, d, e, a, F4, KK0, 7, 6); + R(a, b, c, d, e, F4, KK0, 8, 15); + R(e, a, b, c, d, F4, KK0, 11, 8); + R(d, e, a, b, c, F4, KK0, 14, 1); + R(c, d, e, a, b, F4, KK0, 14, 10); + R(b, c, d, e, a, F4, KK0, 12, 3); + R(a, b, c, d, e, F4, KK0, 6, 12); /* #15 */ + /* Parallel round 2 */ + R(e, a, b, c, d, F3, KK1, 9, 6); + R(d, e, a, b, c, F3, KK1, 13, 11); + R(c, d, e, a, b, F3, KK1, 15, 3); + R(b, c, d, e, a, F3, KK1, 7, 7); + R(a, b, c, d, e, F3, KK1, 12, 0); + R(e, a, b, c, d, F3, KK1, 8, 13); + R(d, e, a, b, c, F3, KK1, 9, 5); + R(c, d, e, a, b, F3, KK1, 11, 10); + R(b, c, d, e, a, F3, KK1, 7, 14); + R(a, b, c, d, e, F3, KK1, 7, 15); + R(e, a, b, c, d, F3, KK1, 12, 8); + R(d, e, a, b, c, F3, KK1, 7, 12); + R(c, d, e, a, b, F3, KK1, 6, 4); + R(b, c, d, e, a, F3, KK1, 15, 9); + R(a, b, c, d, e, F3, KK1, 13, 1); + R(e, a, b, c, d, F3, KK1, 11, 2); /* #31 */ + /* Parallel round 3 */ + R(d, e, a, b, c, F2, KK2, 9, 15); + R(c, d, e, a, b, F2, KK2, 7, 5); + R(b, c, d, e, a, F2, KK2, 15, 1); + R(a, b, c, d, e, F2, KK2, 11, 3); + R(e, a, b, c, d, F2, KK2, 8, 7); + R(d, e, a, b, c, F2, KK2, 6, 14); + R(c, d, e, a, b, F2, KK2, 6, 6); + R(b, c, d, e, a, F2, KK2, 14, 9); + R(a, b, c, d, e, F2, KK2, 12, 11); + R(e, a, b, c, d, F2, KK2, 13, 8); + R(d, e, a, b, c, F2, KK2, 5, 12); + R(c, d, e, a, b, F2, KK2, 14, 2); + R(b, c, d, e, a, F2, KK2, 13, 10); + R(a, b, c, d, e, F2, KK2, 13, 0); + R(e, a, b, c, d, F2, KK2, 7, 4); + R(d, e, a, b, c, F2, KK2, 5, 13); /* #47 */ + /* Parallel round 4 */ + R(c, d, e, a, b, F1, KK3, 15, 8); + R(b, c, d, e, a, F1, KK3, 5, 6); + R(a, b, c, d, e, F1, KK3, 8, 4); + R(e, a, b, c, d, F1, KK3, 11, 1); + R(d, e, a, b, c, F1, KK3, 14, 3); + R(c, d, e, a, b, F1, KK3, 14, 11); + R(b, c, d, e, a, F1, KK3, 6, 15); + R(a, b, c, d, e, F1, KK3, 14, 0); + R(e, a, b, c, d, F1, KK3, 6, 5); + R(d, e, a, b, c, F1, KK3, 9, 12); + R(c, d, e, a, b, F1, KK3, 12, 2); + R(b, c, d, e, a, F1, KK3, 9, 13); + R(a, b, c, d, e, F1, KK3, 12, 9); + R(e, a, b, c, d, F1, KK3, 5, 7); + R(d, e, a, b, c, F1, KK3, 15, 10); + R(c, d, e, a, b, F1, KK3, 8, 14); /* #63 */ + /* Parallel round 5 */ + R(b, c, d, e, a, F0, KK4, 8, 12); + R(a, b, c, d, e, F0, KK4, 5, 15); + R(e, a, b, c, d, F0, KK4, 12, 10); + R(d, e, a, b, c, F0, KK4, 9, 4); + R(c, d, e, a, b, F0, KK4, 12, 1); + R(b, c, d, e, a, F0, KK4, 5, 5); + R(a, b, c, d, e, F0, KK4, 14, 8); + R(e, a, b, c, d, F0, KK4, 6, 7); + R(d, e, a, b, c, F0, KK4, 8, 6); + R(c, d, e, a, b, F0, KK4, 13, 2); + R(b, c, d, e, a, F0, KK4, 6, 13); + R(a, b, c, d, e, F0, KK4, 5, 14); + R(e, a, b, c, d, F0, KK4, 15, 0); + R(d, e, a, b, c, F0, KK4, 13, 3); + R(c, d, e, a, b, F0, KK4, 11, 9); + R(b, c, d, e, a, F0, KK4, 11, 11); /* #79 */ + + t = state[1] + cc + d; + state[1] = state[2] + dd + e; + state[2] = state[3] + ee + a; + state[3] = state[4] + aa + b; + state[4] = state[0] + bb + c; + state[0] = t; +} + +#endif /* !WITH_OPENSSL */ diff --git a/crypto/openssh/openbsd-compat/rmd160.h b/crypto/openssh/openbsd-compat/rmd160.h new file mode 100644 index 000000000000..99c1dcdc060a --- /dev/null +++ b/crypto/openssh/openbsd-compat/rmd160.h @@ -0,0 +1,61 @@ +/* $OpenBSD: rmd160.h,v 1.17 2012/12/05 23:19:57 deraadt Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _RMD160_H +#define _RMD160_H + +#ifndef WITH_OPENSSL + +#define RMD160_BLOCK_LENGTH 64 +#define RMD160_DIGEST_LENGTH 20 +#define RMD160_DIGEST_STRING_LENGTH (RMD160_DIGEST_LENGTH * 2 + 1) + +/* RMD160 context. */ +typedef struct RMD160Context { + u_int32_t state[5]; /* state */ + u_int64_t count; /* number of bits, mod 2^64 */ + u_int8_t buffer[RMD160_BLOCK_LENGTH]; /* input buffer */ +} RMD160_CTX; + +void RMD160Init(RMD160_CTX *); +void RMD160Transform(u_int32_t [5], const u_int8_t [RMD160_BLOCK_LENGTH]) + __attribute__((__bounded__(__minbytes__,1,5))) + __attribute__((__bounded__(__minbytes__,2,RMD160_BLOCK_LENGTH))); +void RMD160Update(RMD160_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void RMD160Pad(RMD160_CTX *); +void RMD160Final(u_int8_t [RMD160_DIGEST_LENGTH], RMD160_CTX *) + __attribute__((__bounded__(__minbytes__,1,RMD160_DIGEST_LENGTH))); +char *RMD160End(RMD160_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); +char *RMD160File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); +char *RMD160FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,RMD160_DIGEST_STRING_LENGTH))); +char *RMD160Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,RMD160_DIGEST_STRING_LENGTH))); + +#endif /* !WITH_OPENSSL */ +#endif /* _RMD160_H */ diff --git a/crypto/openssh/openbsd-compat/sha1.c b/crypto/openssh/openbsd-compat/sha1.c new file mode 100644 index 000000000000..4b5381f87582 --- /dev/null +++ b/crypto/openssh/openbsd-compat/sha1.c @@ -0,0 +1,177 @@ +/* $OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 tedu Exp $ */ + +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + * + * Test Vectors (from FIPS PUB 180-1) + * "abc" + * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + * A million repetitions of "a" + * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + */ + +#include "includes.h" + +#ifndef WITH_OPENSSL + +#include +#include + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + */ +#if BYTE_ORDER == LITTLE_ENDIAN +# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +# define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + +typedef union { + u_int8_t c[64]; + u_int32_t l[16]; +} CHAR64LONG16; + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +void +SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH]) +{ + u_int32_t a, b, c, d, e; + u_int8_t workspace[SHA1_BLOCK_LENGTH]; + CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; + + (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* + * SHA1Init - Initialize new context + */ +void +SHA1Init(SHA1_CTX *context) +{ + + /* SHA1 initialization constants */ + context->count = 0; + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; +} + + +/* + * Run your data through this. + */ +void +SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) +{ + size_t i, j; + + j = (size_t)((context->count >> 3) & 63); + context->count += (len << 3); + if ((j + len) > 63) { + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1Transform(context->state, (u_int8_t *)&data[i]); + j = 0; + } else { + i = 0; + } + (void)memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* + * Add padding and return the message digest. + */ +void +SHA1Pad(SHA1_CTX *context) +{ + u_int8_t finalcount[8]; + u_int i; + + for (i = 0; i < 8; i++) { + finalcount[i] = (u_int8_t)((context->count >> + ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ + } + SHA1Update(context, (u_int8_t *)"\200", 1); + while ((context->count & 504) != 448) + SHA1Update(context, (u_int8_t *)"\0", 1); + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ +} + +void +SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) +{ + u_int i; + + SHA1Pad(context); + for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { + digest[i] = (u_int8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + memset(context, 0, sizeof(*context)); +} +#endif /* !WITH_OPENSSL */ diff --git a/crypto/openssh/openbsd-compat/sha1.h b/crypto/openssh/openbsd-compat/sha1.h new file mode 100644 index 000000000000..327d94cd5a87 --- /dev/null +++ b/crypto/openssh/openbsd-compat/sha1.h @@ -0,0 +1,58 @@ +/* $OpenBSD: sha1.h,v 1.24 2012/12/05 23:19:57 deraadt Exp $ */ + +/* + * SHA-1 in C + * By Steve Reid + * 100% Public Domain + */ + +#ifndef _SHA1_H +#define _SHA1_H + +#ifndef WITH_OPENSSL + +#define SHA1_BLOCK_LENGTH 64 +#define SHA1_DIGEST_LENGTH 20 +#define SHA1_DIGEST_STRING_LENGTH (SHA1_DIGEST_LENGTH * 2 + 1) + +typedef struct { + u_int32_t state[5]; + u_int64_t count; + u_int8_t buffer[SHA1_BLOCK_LENGTH]; +} SHA1_CTX; + +void SHA1Init(SHA1_CTX *); +void SHA1Pad(SHA1_CTX *); +void SHA1Transform(u_int32_t [5], const u_int8_t [SHA1_BLOCK_LENGTH]) + __attribute__((__bounded__(__minbytes__,1,5))) + __attribute__((__bounded__(__minbytes__,2,SHA1_BLOCK_LENGTH))); +void SHA1Update(SHA1_CTX *, const u_int8_t *, size_t) + __attribute__((__bounded__(__string__,2,3))); +void SHA1Final(u_int8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *) + __attribute__((__bounded__(__minbytes__,1,SHA1_DIGEST_LENGTH))); +char *SHA1End(SHA1_CTX *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); +char *SHA1File(const char *, char *) + __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); +char *SHA1FileChunk(const char *, char *, off_t, off_t) + __attribute__((__bounded__(__minbytes__,2,SHA1_DIGEST_STRING_LENGTH))); +char *SHA1Data(const u_int8_t *, size_t, char *) + __attribute__((__bounded__(__string__,1,2))) + __attribute__((__bounded__(__minbytes__,3,SHA1_DIGEST_STRING_LENGTH))); + +#define HTONDIGEST(x) do { \ + x[0] = htonl(x[0]); \ + x[1] = htonl(x[1]); \ + x[2] = htonl(x[2]); \ + x[3] = htonl(x[3]); \ + x[4] = htonl(x[4]); } while (0) + +#define NTOHDIGEST(x) do { \ + x[0] = ntohl(x[0]); \ + x[1] = ntohl(x[1]); \ + x[2] = ntohl(x[2]); \ + x[3] = ntohl(x[3]); \ + x[4] = ntohl(x[4]); } while (0) + +#endif /* !WITH_OPENSSL */ +#endif /* _SHA1_H */ diff --git a/crypto/openssh/openbsd-compat/sha2.c b/crypto/openssh/openbsd-compat/sha2.c index f5bf74d1fb5c..737935d46383 100644 --- a/crypto/openssh/openbsd-compat/sha2.c +++ b/crypto/openssh/openbsd-compat/sha2.c @@ -38,13 +38,18 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL +# include +# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# define _NEED_SHA2 1 +# endif +#else +# define _NEED_SHA2 1 +#endif + +#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) -#if !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) -#include #include -#include "sha2.h" /* * UNROLLED TRANSFORM LOOP NOTE: @@ -838,7 +843,6 @@ SHA512_Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA512_CTX *context) } -#if 0 /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX *context) @@ -851,9 +855,29 @@ SHA384_Init(SHA384_CTX *context) context->bitcount[0] = context->bitcount[1] = 0; } +#if 0 __weak_alias(SHA384_Transform, SHA512_Transform); __weak_alias(SHA384_Update, SHA512_Update); __weak_alias(SHA384_Pad, SHA512_Pad); +#endif + +void +SHA384_Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH]) +{ + return SHA512_Transform(state, data); +} + +void +SHA384_Update(SHA512_CTX *context, const u_int8_t *data, size_t len) +{ + SHA512_Update(context, data, len); +} + +void +SHA384_Pad(SHA512_CTX *context) +{ + SHA512_Pad(context); +} void SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) @@ -876,7 +900,5 @@ SHA384_Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA384_CTX *context) /* Zero out state data */ memset(context, 0, sizeof(*context)); } -#endif -#endif /* !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) */ +#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ diff --git a/crypto/openssh/openbsd-compat/sha2.h b/crypto/openssh/openbsd-compat/sha2.h index 73e94f150330..c8bfc3cd13f0 100644 --- a/crypto/openssh/openbsd-compat/sha2.h +++ b/crypto/openssh/openbsd-compat/sha2.h @@ -41,10 +41,16 @@ #include "includes.h" -#include +#ifdef WITH_OPENSSL +# include +# if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# define _NEED_SHA2 1 +# endif +#else +# define _NEED_SHA2 1 +#endif -#if !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) +#if defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 @@ -70,9 +76,7 @@ typedef struct _SHA512_CTX { u_int8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; -#if 0 typedef SHA512_CTX SHA384_CTX; -#endif void SHA256_Init(SHA256_CTX *); void SHA256_Transform(u_int32_t state[8], const u_int8_t [SHA256_BLOCK_LENGTH]); @@ -91,7 +95,6 @@ char *SHA256_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA256_DIGEST_STRING_LENGTH))); -#if 0 void SHA384_Init(SHA384_CTX *); void SHA384_Transform(u_int64_t state[8], const u_int8_t [SHA384_BLOCK_LENGTH]); void SHA384_Update(SHA384_CTX *, const u_int8_t *, size_t) @@ -108,7 +111,6 @@ char *SHA384_FileChunk(const char *, char *, off_t, off_t) char *SHA384_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA384_DIGEST_STRING_LENGTH))); -#endif /* 0 */ void SHA512_Init(SHA512_CTX *); void SHA512_Transform(u_int64_t state[8], const u_int8_t [SHA512_BLOCK_LENGTH]); @@ -127,7 +129,6 @@ char *SHA512_Data(const u_int8_t *, size_t, char *) __attribute__((__bounded__(__string__,1,2))) __attribute__((__bounded__(__minbytes__,3,SHA512_DIGEST_STRING_LENGTH))); -#endif /* !defined(HAVE_EVP_SHA256) && !defined(HAVE_SHA256_UPDATE) && \ - (OPENSSL_VERSION_NUMBER >= 0x00907000L) */ +#endif /* defined(_NEED_SHA2) && !defined(HAVE_SHA256_UPDATE) */ #endif /* _SSHSHA2_H */ diff --git a/crypto/openssh/openbsd-compat/xcrypt.c b/crypto/openssh/openbsd-compat/xcrypt.c index c8aea461d1ab..8577cbd8a632 100644 --- a/crypto/openssh/openbsd-compat/xcrypt.c +++ b/crypto/openssh/openbsd-compat/xcrypt.c @@ -57,7 +57,7 @@ # include "md5crypt.h" # endif -# if !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT) +# if defined(WITH_OPENSSL) && !defined(HAVE_CRYPT) && defined(HAVE_DES_CRYPT) # include # define crypt DES_crypt # endif diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index f76eedb876fc..7884eeb531be 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.198 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: packet.c,v 1.208 2015/02/13 18:57:00 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -40,9 +40,9 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* MIN roundup */ #include #include "openbsd-compat/sys-queue.h" -#include #include #ifdef HAVE_SYS_TIME_H # include @@ -58,29 +58,35 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include #include +#include + +#include "buffer.h" /* typedefs XXX */ +#include "key.h" /* typedefs XXX */ + #include "xmalloc.h" -#include "buffer.h" -#include "packet.h" #include "crc32.h" -#include "compress.h" #include "deattack.h" #include "compat.h" #include "ssh1.h" #include "ssh2.h" #include "cipher.h" -#include "key.h" +#include "sshkey.h" #include "kex.h" +#include "digest.h" #include "mac.h" #include "log.h" #include "canohost.h" #include "misc.h" #include "channels.h" #include "ssh.h" -#include "ssherr.h" +#include "packet.h" #include "roaming.h" +#include "ssherr.h" +#include "sshbuf.h" #ifdef PACKET_DEBUG #define DBG(x) x @@ -100,7 +106,7 @@ struct packet_state { struct packet { TAILQ_ENTRY(packet) next; u_char type; - Buffer payload; + struct sshbuf *payload; }; struct session_state { @@ -117,26 +123,33 @@ struct session_state { u_int remote_protocol_flags; /* Encryption context for receiving data. Only used for decryption. */ - CipherContext receive_context; + struct sshcipher_ctx receive_context; /* Encryption context for sending data. Only used for encryption. */ - CipherContext send_context; + struct sshcipher_ctx send_context; /* Buffer for raw input data from the socket. */ - Buffer input; + struct sshbuf *input; /* Buffer for raw output data going to the socket. */ - Buffer output; + struct sshbuf *output; /* Buffer for the partial outgoing packet being constructed. */ - Buffer outgoing_packet; + struct sshbuf *outgoing_packet; /* Buffer for the incoming packet currently being processed. */ - Buffer incoming_packet; + struct sshbuf *incoming_packet; /* Scratch buffer for packet compression/decompression. */ - Buffer compression_buffer; - int compression_buffer_ready; + struct sshbuf *compression_buffer; + + /* Incoming/outgoing compression dictionaries */ + z_stream compression_in_stream; + z_stream compression_out_stream; + int compression_in_started; + int compression_out_started; + int compression_in_failures; + int compression_out_failures; /* * Flag indicating whether packet compression/decompression is @@ -165,7 +178,7 @@ struct session_state { int packet_timeout_ms; /* Session key information for Encryption and MAC */ - Newkeys *newkeys[MODE_MAX]; + struct newkeys *newkeys[MODE_MAX]; struct packet_state p_read, p_send; /* Volume-based rekeying */ @@ -173,7 +186,7 @@ struct session_state { u_int32_t rekey_limit; /* Time-based rekeying */ - time_t rekey_interval; /* how often in seconds */ + u_int32_t rekey_interval; /* how often in seconds */ time_t rekey_time; /* time of last rekeying */ /* Session key for protocol v1 */ @@ -185,7 +198,7 @@ struct session_state { /* XXX discard incoming data after MAC error */ u_int packet_discard; - Mac *packet_discard_mac; + struct sshmac *packet_discard_mac; /* Used in packet_read_poll2() */ u_int packlen; @@ -199,121 +212,177 @@ struct session_state { /* Used in packet_set_maxsize */ int set_maxsize_called; + /* One-off warning about weak ciphers */ + int cipher_warning_done; + + /* SSH1 CRC compensation attack detector */ + struct deattack_ctx deattack; + TAILQ_HEAD(, packet) outgoing; }; -static struct session_state *active_state, *backup_state; - -static struct session_state * -alloc_session_state(void) +struct ssh * +ssh_alloc_session_state(void) { - struct session_state *s = xcalloc(1, sizeof(*s)); + struct ssh *ssh = NULL; + struct session_state *state = NULL; - s->connection_in = -1; - s->connection_out = -1; - s->max_packet_size = 32768; - s->packet_timeout_ms = -1; - return s; + if ((ssh = calloc(1, sizeof(*ssh))) == NULL || + (state = calloc(1, sizeof(*state))) == NULL || + (state->input = sshbuf_new()) == NULL || + (state->output = sshbuf_new()) == NULL || + (state->outgoing_packet = sshbuf_new()) == NULL || + (state->incoming_packet = sshbuf_new()) == NULL) + goto fail; + TAILQ_INIT(&state->outgoing); + TAILQ_INIT(&ssh->private_keys); + TAILQ_INIT(&ssh->public_keys); + state->connection_in = -1; + state->connection_out = -1; + state->max_packet_size = 32768; + state->packet_timeout_ms = -1; + state->p_send.packets = state->p_read.packets = 0; + state->initialized = 1; + /* + * ssh_packet_send2() needs to queue packets until + * we've done the initial key exchange. + */ + state->rekeying = 1; + ssh->state = state; + return ssh; + fail: + if (state) { + sshbuf_free(state->input); + sshbuf_free(state->output); + sshbuf_free(state->incoming_packet); + sshbuf_free(state->outgoing_packet); + free(state); + } + free(ssh); + return NULL; } /* * Sets the descriptors used for communication. Disables encryption until * packet_set_encryption_key is called. */ -void -packet_set_connection(int fd_in, int fd_out) +struct ssh * +ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) { - const Cipher *none = cipher_by_name("none"); + struct session_state *state; + const struct sshcipher *none = cipher_by_name("none"); int r; - if (none == NULL) - fatal("packet_set_connection: cannot load cipher 'none'"); - if (active_state == NULL) - active_state = alloc_session_state(); - active_state->connection_in = fd_in; - active_state->connection_out = fd_out; - if ((r = cipher_init(&active_state->send_context, none, - (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || - (r = cipher_init(&active_state->receive_context, none, - (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) - fatal("%s: cipher_init: %s", __func__, ssh_err(r)); - active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL; - if (!active_state->initialized) { - active_state->initialized = 1; - buffer_init(&active_state->input); - buffer_init(&active_state->output); - buffer_init(&active_state->outgoing_packet); - buffer_init(&active_state->incoming_packet); - TAILQ_INIT(&active_state->outgoing); - active_state->p_send.packets = active_state->p_read.packets = 0; + if (none == NULL) { + error("%s: cannot load cipher 'none'", __func__); + return NULL; } + if (ssh == NULL) + ssh = ssh_alloc_session_state(); + if (ssh == NULL) { + error("%s: cound not allocate state", __func__); + return NULL; + } + state = ssh->state; + state->connection_in = fd_in; + state->connection_out = fd_out; + if ((r = cipher_init(&state->send_context, none, + (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || + (r = cipher_init(&state->receive_context, none, + (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { + error("%s: cipher_init failed: %s", __func__, ssh_err(r)); + return NULL; + } + state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; + deattack_init(&state->deattack); + /* + * Cache the IP address of the remote connection for use in error + * messages that might be generated after the connection has closed. + */ + (void)ssh_remote_ipaddr(ssh); + return ssh; } void -packet_set_timeout(int timeout, int count) +ssh_packet_set_timeout(struct ssh *ssh, int timeout, int count) { + struct session_state *state = ssh->state; + if (timeout <= 0 || count <= 0) { - active_state->packet_timeout_ms = -1; + state->packet_timeout_ms = -1; return; } if ((INT_MAX / 1000) / count < timeout) - active_state->packet_timeout_ms = INT_MAX; + state->packet_timeout_ms = INT_MAX; else - active_state->packet_timeout_ms = timeout * count * 1000; + state->packet_timeout_ms = timeout * count * 1000; } -static void -packet_stop_discard(void) +int +ssh_packet_stop_discard(struct ssh *ssh) { - if (active_state->packet_discard_mac) { + struct session_state *state = ssh->state; + int r; + + if (state->packet_discard_mac) { char buf[1024]; - + memset(buf, 'a', sizeof(buf)); - while (buffer_len(&active_state->incoming_packet) < + while (sshbuf_len(state->incoming_packet) < PACKET_MAX_SIZE) - buffer_append(&active_state->incoming_packet, buf, - sizeof(buf)); - (void) mac_compute(active_state->packet_discard_mac, - active_state->p_read.seqnr, - buffer_ptr(&active_state->incoming_packet), - PACKET_MAX_SIZE); + if ((r = sshbuf_put(state->incoming_packet, buf, + sizeof(buf))) != 0) + return r; + (void) mac_compute(state->packet_discard_mac, + state->p_read.seqnr, + sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE, + NULL, 0); } - logit("Finished discarding for %.200s", get_remote_ipaddr()); - cleanup_exit(255); + logit("Finished discarding for %.200s", ssh_remote_ipaddr(ssh)); + return SSH_ERR_MAC_INVALID; } -static void -packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) +static int +ssh_packet_start_discard(struct ssh *ssh, struct sshenc *enc, + struct sshmac *mac, u_int packet_length, u_int discard) { - if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm)) - packet_disconnect("Packet corrupt"); + struct session_state *state = ssh->state; + int r; + + if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm)) { + if ((r = sshpkt_disconnect(ssh, "Packet corrupt")) != 0) + return r; + return SSH_ERR_MAC_INVALID; + } if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) - active_state->packet_discard_mac = mac; - if (buffer_len(&active_state->input) >= discard) - packet_stop_discard(); - active_state->packet_discard = discard - - buffer_len(&active_state->input); + state->packet_discard_mac = mac; + if (sshbuf_len(state->input) >= discard && + (r = ssh_packet_stop_discard(ssh)) != 0) + return r; + state->packet_discard = discard - sshbuf_len(state->input); + return 0; } /* Returns 1 if remote host is connected via socket, 0 if not. */ int -packet_connection_is_on_socket(void) +ssh_packet_connection_is_on_socket(struct ssh *ssh) { + struct session_state *state = ssh->state; struct sockaddr_storage from, to; socklen_t fromlen, tolen; /* filedescriptors in and out are the same, so it's a socket */ - if (active_state->connection_in == active_state->connection_out) + if (state->connection_in == state->connection_out) return 1; fromlen = sizeof(from); memset(&from, 0, sizeof(from)); - if (getpeername(active_state->connection_in, (struct sockaddr *)&from, + if (getpeername(state->connection_in, (struct sockaddr *)&from, &fromlen) < 0) return 0; tolen = sizeof(to); memset(&to, 0, sizeof(to)); - if (getpeername(active_state->connection_out, (struct sockaddr *)&to, + if (getpeername(state->connection_out, (struct sockaddr *)&to, &tolen) < 0) return 0; if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) @@ -323,127 +392,23 @@ packet_connection_is_on_socket(void) return 1; } -/* - * Exports an IV from the CipherContext required to export the key - * state back from the unprivileged child to the privileged parent - * process. - */ - void -packet_get_keyiv(int mode, u_char *iv, u_int len) +ssh_packet_get_bytes(struct ssh *ssh, u_int64_t *ibytes, u_int64_t *obytes) { - CipherContext *cc; - int r; - - if (mode == MODE_OUT) - cc = &active_state->send_context; - else - cc = &active_state->receive_context; - - if ((r = cipher_get_keyiv(cc, iv, len)) != 0) - fatal("%s: cipher_get_keyiv: %s", __func__, ssh_err(r)); + if (ibytes) + *ibytes = ssh->state->p_read.bytes; + if (obytes) + *obytes = ssh->state->p_send.bytes; } int -packet_get_keycontext(int mode, u_char *dat) -{ - CipherContext *cc; - - if (mode == MODE_OUT) - cc = &active_state->send_context; - else - cc = &active_state->receive_context; - - return (cipher_get_keycontext(cc, dat)); -} - -void -packet_set_keycontext(int mode, u_char *dat) -{ - CipherContext *cc; - - if (mode == MODE_OUT) - cc = &active_state->send_context; - else - cc = &active_state->receive_context; - - cipher_set_keycontext(cc, dat); -} - -int -packet_get_keyiv_len(int mode) -{ - CipherContext *cc; - - if (mode == MODE_OUT) - cc = &active_state->send_context; - else - cc = &active_state->receive_context; - - return (cipher_get_keyiv_len(cc)); -} - -void -packet_set_iv(int mode, u_char *dat) -{ - CipherContext *cc; - int r; - - if (mode == MODE_OUT) - cc = &active_state->send_context; - else - cc = &active_state->receive_context; - - if ((r = cipher_set_keyiv(cc, dat)) != 0) - fatal("%s: cipher_set_keyiv: %s", __func__, ssh_err(r)); -} - -int -packet_get_ssh1_cipher(void) -{ - return (cipher_get_number(active_state->receive_context.cipher)); -} - -void -packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, - u_int32_t *packets, u_int64_t *bytes) -{ - struct packet_state *state; - - state = (mode == MODE_IN) ? - &active_state->p_read : &active_state->p_send; - if (seqnr) - *seqnr = state->seqnr; - if (blocks) - *blocks = state->blocks; - if (packets) - *packets = state->packets; - if (bytes) - *bytes = state->bytes; -} - -void -packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets, - u_int64_t bytes) -{ - struct packet_state *state; - - state = (mode == MODE_IN) ? - &active_state->p_read : &active_state->p_send; - state->seqnr = seqnr; - state->blocks = blocks; - state->packets = packets; - state->bytes = bytes; -} - -static int -packet_connection_af(void) +ssh_packet_connection_af(struct ssh *ssh) { struct sockaddr_storage to; socklen_t tolen = sizeof(to); memset(&to, 0, sizeof(to)); - if (getsockname(active_state->connection_out, (struct sockaddr *)&to, + if (getsockname(ssh->state->connection_out, (struct sockaddr *)&to, &tolen) < 0) return 0; #ifdef IPV4_IN_IPV6 @@ -457,72 +422,125 @@ packet_connection_af(void) /* Sets the connection into non-blocking mode. */ void -packet_set_nonblocking(void) +ssh_packet_set_nonblocking(struct ssh *ssh) { /* Set the socket into non-blocking mode. */ - set_nonblock(active_state->connection_in); + set_nonblock(ssh->state->connection_in); - if (active_state->connection_out != active_state->connection_in) - set_nonblock(active_state->connection_out); + if (ssh->state->connection_out != ssh->state->connection_in) + set_nonblock(ssh->state->connection_out); } /* Returns the socket used for reading. */ int -packet_get_connection_in(void) +ssh_packet_get_connection_in(struct ssh *ssh) { - return active_state->connection_in; + return ssh->state->connection_in; } /* Returns the descriptor used for writing. */ int -packet_get_connection_out(void) +ssh_packet_get_connection_out(struct ssh *ssh) { - return active_state->connection_out; + return ssh->state->connection_out; +} + +/* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. + */ + +const char * +ssh_remote_ipaddr(struct ssh *ssh) +{ + /* Check whether we have cached the ipaddr. */ + if (ssh->remote_ipaddr == NULL) + ssh->remote_ipaddr = ssh_packet_connection_is_on_socket(ssh) ? + get_peer_ipaddr(ssh->state->connection_in) : + strdup("UNKNOWN"); + if (ssh->remote_ipaddr == NULL) + return "UNKNOWN"; + return ssh->remote_ipaddr; } /* Closes the connection and clears and frees internal data structures. */ void -packet_close(void) +ssh_packet_close(struct ssh *ssh) { - if (!active_state->initialized) + struct session_state *state = ssh->state; + int r; + u_int mode; + + if (!state->initialized) return; - active_state->initialized = 0; - if (active_state->connection_in == active_state->connection_out) { - shutdown(active_state->connection_out, SHUT_RDWR); - close(active_state->connection_out); + state->initialized = 0; + if (state->connection_in == state->connection_out) { + shutdown(state->connection_out, SHUT_RDWR); + close(state->connection_out); } else { - close(active_state->connection_in); - close(active_state->connection_out); + close(state->connection_in); + close(state->connection_out); } - buffer_free(&active_state->input); - buffer_free(&active_state->output); - buffer_free(&active_state->outgoing_packet); - buffer_free(&active_state->incoming_packet); - if (active_state->compression_buffer_ready) { - buffer_free(&active_state->compression_buffer); - buffer_compress_uninit(); + sshbuf_free(state->input); + sshbuf_free(state->output); + sshbuf_free(state->outgoing_packet); + sshbuf_free(state->incoming_packet); + for (mode = 0; mode < MODE_MAX; mode++) + kex_free_newkeys(state->newkeys[mode]); + if (state->compression_buffer) { + sshbuf_free(state->compression_buffer); + if (state->compression_out_started) { + z_streamp stream = &state->compression_out_stream; + debug("compress outgoing: " + "raw data %llu, compressed %llu, factor %.2f", + (unsigned long long)stream->total_in, + (unsigned long long)stream->total_out, + stream->total_in == 0 ? 0.0 : + (double) stream->total_out / stream->total_in); + if (state->compression_out_failures == 0) + deflateEnd(stream); + } + if (state->compression_in_started) { + z_streamp stream = &state->compression_out_stream; + debug("compress incoming: " + "raw data %llu, compressed %llu, factor %.2f", + (unsigned long long)stream->total_out, + (unsigned long long)stream->total_in, + stream->total_out == 0 ? 0.0 : + (double) stream->total_in / stream->total_out); + if (state->compression_in_failures == 0) + inflateEnd(stream); + } } - cipher_cleanup(&active_state->send_context); - cipher_cleanup(&active_state->receive_context); + if ((r = cipher_cleanup(&state->send_context)) != 0) + error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); + if ((r = cipher_cleanup(&state->receive_context)) != 0) + error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); + if (ssh->remote_ipaddr) { + free(ssh->remote_ipaddr); + ssh->remote_ipaddr = NULL; + } + free(ssh->state); + ssh->state = NULL; } /* Sets remote side protocol flags. */ void -packet_set_protocol_flags(u_int protocol_flags) +ssh_packet_set_protocol_flags(struct ssh *ssh, u_int protocol_flags) { - active_state->remote_protocol_flags = protocol_flags; + ssh->state->remote_protocol_flags = protocol_flags; } /* Returns the remote protocol flags set earlier by the above function. */ u_int -packet_get_protocol_flags(void) +ssh_packet_get_protocol_flags(struct ssh *ssh) { - return active_state->remote_protocol_flags; + return ssh->state->remote_protocol_flags; } /* @@ -530,24 +548,239 @@ packet_get_protocol_flags(void) * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */ -static void -packet_init_compression(void) +static int +ssh_packet_init_compression(struct ssh *ssh) { - if (active_state->compression_buffer_ready == 1) - return; - active_state->compression_buffer_ready = 1; - buffer_init(&active_state->compression_buffer); + if (!ssh->state->compression_buffer && + ((ssh->state->compression_buffer = sshbuf_new()) == NULL)) + return SSH_ERR_ALLOC_FAIL; + return 0; +} + +static int +start_compression_out(struct ssh *ssh, int level) +{ + if (level < 1 || level > 9) + return SSH_ERR_INVALID_ARGUMENT; + debug("Enabling compression at level %d.", level); + if (ssh->state->compression_out_started == 1) + deflateEnd(&ssh->state->compression_out_stream); + switch (deflateInit(&ssh->state->compression_out_stream, level)) { + case Z_OK: + ssh->state->compression_out_started = 1; + break; + case Z_MEM_ERROR: + return SSH_ERR_ALLOC_FAIL; + default: + return SSH_ERR_INTERNAL_ERROR; + } + return 0; +} + +static int +start_compression_in(struct ssh *ssh) +{ + if (ssh->state->compression_in_started == 1) + inflateEnd(&ssh->state->compression_in_stream); + switch (inflateInit(&ssh->state->compression_in_stream)) { + case Z_OK: + ssh->state->compression_in_started = 1; + break; + case Z_MEM_ERROR: + return SSH_ERR_ALLOC_FAIL; + default: + return SSH_ERR_INTERNAL_ERROR; + } + return 0; +} + +int +ssh_packet_start_compression(struct ssh *ssh, int level) +{ + int r; + + if (ssh->state->packet_compression && !compat20) + return SSH_ERR_INTERNAL_ERROR; + ssh->state->packet_compression = 1; + if ((r = ssh_packet_init_compression(ssh)) != 0 || + (r = start_compression_in(ssh)) != 0 || + (r = start_compression_out(ssh, level)) != 0) + return r; + return 0; +} + +/* XXX remove need for separate compression buffer */ +static int +compress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) +{ + u_char buf[4096]; + int r, status; + + if (ssh->state->compression_out_started != 1) + return SSH_ERR_INTERNAL_ERROR; + + /* This case is not handled below. */ + if (sshbuf_len(in) == 0) + return 0; + + /* Input is the contents of the input buffer. */ + if ((ssh->state->compression_out_stream.next_in = + sshbuf_mutable_ptr(in)) == NULL) + return SSH_ERR_INTERNAL_ERROR; + ssh->state->compression_out_stream.avail_in = sshbuf_len(in); + + /* Loop compressing until deflate() returns with avail_out != 0. */ + do { + /* Set up fixed-size output buffer. */ + ssh->state->compression_out_stream.next_out = buf; + ssh->state->compression_out_stream.avail_out = sizeof(buf); + + /* Compress as much data into the buffer as possible. */ + status = deflate(&ssh->state->compression_out_stream, + Z_PARTIAL_FLUSH); + switch (status) { + case Z_MEM_ERROR: + return SSH_ERR_ALLOC_FAIL; + case Z_OK: + /* Append compressed data to output_buffer. */ + if ((r = sshbuf_put(out, buf, sizeof(buf) - + ssh->state->compression_out_stream.avail_out)) != 0) + return r; + break; + case Z_STREAM_ERROR: + default: + ssh->state->compression_out_failures++; + return SSH_ERR_INVALID_FORMAT; + } + } while (ssh->state->compression_out_stream.avail_out == 0); + return 0; +} + +static int +uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) +{ + u_char buf[4096]; + int r, status; + + if (ssh->state->compression_in_started != 1) + return SSH_ERR_INTERNAL_ERROR; + + if ((ssh->state->compression_in_stream.next_in = + sshbuf_mutable_ptr(in)) == NULL) + return SSH_ERR_INTERNAL_ERROR; + ssh->state->compression_in_stream.avail_in = sshbuf_len(in); + + for (;;) { + /* Set up fixed-size output buffer. */ + ssh->state->compression_in_stream.next_out = buf; + ssh->state->compression_in_stream.avail_out = sizeof(buf); + + status = inflate(&ssh->state->compression_in_stream, + Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + if ((r = sshbuf_put(out, buf, sizeof(buf) - + ssh->state->compression_in_stream.avail_out)) != 0) + return r; + break; + case Z_BUF_ERROR: + /* + * Comments in zlib.h say that we should keep calling + * inflate() until we get an error. This appears to + * be the error that we get. + */ + return 0; + case Z_DATA_ERROR: + return SSH_ERR_INVALID_FORMAT; + case Z_MEM_ERROR: + return SSH_ERR_ALLOC_FAIL; + case Z_STREAM_ERROR: + default: + ssh->state->compression_in_failures++; + return SSH_ERR_INTERNAL_ERROR; + } + } + /* NOTREACHED */ +} + +/* Serialise compression state into a blob for privsep */ +static int +ssh_packet_get_compress_state(struct sshbuf *m, struct ssh *ssh) +{ + struct session_state *state = ssh->state; + struct sshbuf *b; + int r; + + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if (state->compression_in_started) { + if ((r = sshbuf_put_string(b, &state->compression_in_stream, + sizeof(state->compression_in_stream))) != 0) + goto out; + } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) + goto out; + if (state->compression_out_started) { + if ((r = sshbuf_put_string(b, &state->compression_out_stream, + sizeof(state->compression_out_stream))) != 0) + goto out; + } else if ((r = sshbuf_put_string(b, NULL, 0)) != 0) + goto out; + r = sshbuf_put_stringb(m, b); + out: + sshbuf_free(b); + return r; +} + +/* Deserialise compression state from a blob for privsep */ +static int +ssh_packet_set_compress_state(struct ssh *ssh, struct sshbuf *m) +{ + struct session_state *state = ssh->state; + struct sshbuf *b = NULL; + int r; + const u_char *inblob, *outblob; + size_t inl, outl; + + if ((r = sshbuf_froms(m, &b)) != 0) + goto out; + if ((r = sshbuf_get_string_direct(b, &inblob, &inl)) != 0 || + (r = sshbuf_get_string_direct(b, &outblob, &outl)) != 0) + goto out; + if (inl == 0) + state->compression_in_started = 0; + else if (inl != sizeof(state->compression_in_stream)) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } else { + state->compression_in_started = 1; + memcpy(&state->compression_in_stream, inblob, inl); + } + if (outl == 0) + state->compression_out_started = 0; + else if (outl != sizeof(state->compression_out_stream)) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } else { + state->compression_out_started = 1; + memcpy(&state->compression_out_stream, outblob, outl); + } + r = 0; + out: + sshbuf_free(b); + return r; } void -packet_start_compression(int level) +ssh_packet_set_compress_hooks(struct ssh *ssh, void *ctx, + void *(*allocfunc)(void *, u_int, u_int), + void (*freefunc)(void *, void *)) { - if (active_state->packet_compression && !compat20) - fatal("Compression already enabled."); - active_state->packet_compression = 1; - packet_init_compression(); - buffer_compress_init_send(level); - buffer_compress_init_recv(); + ssh->state->compression_out_stream.zalloc = (alloc_func)allocfunc; + ssh->state->compression_out_stream.zfree = (free_func)freefunc; + ssh->state->compression_out_stream.opaque = ctx; + ssh->state->compression_in_stream.zalloc = (alloc_func)allocfunc; + ssh->state->compression_in_stream.zfree = (free_func)freefunc; + ssh->state->compression_in_stream.opaque = ctx; } /* @@ -557,224 +790,161 @@ packet_start_compression(int level) */ void -packet_set_encryption_key(const u_char *key, u_int keylen, int number) +ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) { - const Cipher *cipher = cipher_by_number(number); +#ifdef WITH_SSH1 + struct session_state *state = ssh->state; + const struct sshcipher *cipher = cipher_by_number(number); int r; + const char *wmsg; if (cipher == NULL) - fatal("packet_set_encryption_key: unknown cipher number %d", number); + fatal("%s: unknown cipher number %d", __func__, number); if (keylen < 20) - fatal("packet_set_encryption_key: keylen too small: %d", keylen); + fatal("%s: keylen too small: %d", __func__, keylen); if (keylen > SSH_SESSION_KEY_LENGTH) - fatal("packet_set_encryption_key: keylen too big: %d", keylen); - memcpy(active_state->ssh1_key, key, keylen); - active_state->ssh1_keylen = keylen; - if ((r = cipher_init(&active_state->send_context, cipher, - key, keylen, NULL, 0, CIPHER_ENCRYPT)) != 0 || - (r = cipher_init(&active_state->receive_context, cipher, - key, keylen, NULL, 0, CIPHER_DECRYPT)) != 0) - fatal("%s: cipher_init: %s", __func__, ssh_err(r)); + fatal("%s: keylen too big: %d", __func__, keylen); + memcpy(state->ssh1_key, key, keylen); + state->ssh1_keylen = keylen; + if ((r = cipher_init(&state->send_context, cipher, key, keylen, + NULL, 0, CIPHER_ENCRYPT)) != 0 || + (r = cipher_init(&state->receive_context, cipher, key, keylen, + NULL, 0, CIPHER_DECRYPT) != 0)) + fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); + if (!state->cipher_warning_done && + ((wmsg = cipher_warning_message(&state->send_context)) != NULL || + (wmsg = cipher_warning_message(&state->send_context)) != NULL)) { + error("Warning: %s", wmsg); + state->cipher_warning_done = 1; + } +#endif /* WITH_SSH1 */ } -u_int -packet_get_encryption_key(u_char *key) -{ - if (key == NULL) - return (active_state->ssh1_keylen); - memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen); - return (active_state->ssh1_keylen); -} - -/* Start constructing a packet to send. */ -void -packet_start(u_char type) -{ - u_char buf[9]; - int len; - - DBG(debug("packet_start[%d]", type)); - len = compat20 ? 6 : 9; - memset(buf, 0, len - 1); - buf[len - 1] = type; - buffer_clear(&active_state->outgoing_packet); - buffer_append(&active_state->outgoing_packet, buf, len); -} - -/* Append payload. */ -void -packet_put_char(int value) -{ - char ch = value; - - buffer_append(&active_state->outgoing_packet, &ch, 1); -} - -void -packet_put_int(u_int value) -{ - buffer_put_int(&active_state->outgoing_packet, value); -} - -void -packet_put_int64(u_int64_t value) -{ - buffer_put_int64(&active_state->outgoing_packet, value); -} - -void -packet_put_string(const void *buf, u_int len) -{ - buffer_put_string(&active_state->outgoing_packet, buf, len); -} - -void -packet_put_cstring(const char *str) -{ - buffer_put_cstring(&active_state->outgoing_packet, str); -} - -void -packet_put_raw(const void *buf, u_int len) -{ - buffer_append(&active_state->outgoing_packet, buf, len); -} - -#ifdef WITH_OPENSSL -void -packet_put_bignum(BIGNUM * value) -{ - buffer_put_bignum(&active_state->outgoing_packet, value); -} - -void -packet_put_bignum2(BIGNUM * value) -{ - buffer_put_bignum2(&active_state->outgoing_packet, value); -} -#endif - -#ifdef OPENSSL_HAS_ECC -void -packet_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point) -{ - buffer_put_ecpoint(&active_state->outgoing_packet, curve, point); -} -#endif - /* * Finalizes and sends the packet. If the encryption key has been set, * encrypts the packet before sending. */ -static void -packet_send1(void) +int +ssh_packet_send1(struct ssh *ssh) { + struct session_state *state = ssh->state; u_char buf[8], *cp; - int i, padding, len; + int r, padding, len; u_int checksum; - u_int32_t rnd = 0; /* * If using packet compression, compress the payload of the outgoing * packet. */ - if (active_state->packet_compression) { - buffer_clear(&active_state->compression_buffer); + if (state->packet_compression) { + sshbuf_reset(state->compression_buffer); /* Skip padding. */ - buffer_consume(&active_state->outgoing_packet, 8); + if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0) + goto out; /* padding */ - buffer_append(&active_state->compression_buffer, - "\0\0\0\0\0\0\0\0", 8); - buffer_compress(&active_state->outgoing_packet, - &active_state->compression_buffer); - buffer_clear(&active_state->outgoing_packet); - buffer_append(&active_state->outgoing_packet, - buffer_ptr(&active_state->compression_buffer), - buffer_len(&active_state->compression_buffer)); + if ((r = sshbuf_put(state->compression_buffer, + "\0\0\0\0\0\0\0\0", 8)) != 0) + goto out; + if ((r = compress_buffer(ssh, state->outgoing_packet, + state->compression_buffer)) != 0) + goto out; + sshbuf_reset(state->outgoing_packet); + if ((r = sshbuf_putb(state->outgoing_packet, + state->compression_buffer)) != 0) + goto out; } /* Compute packet length without padding (add checksum, remove padding). */ - len = buffer_len(&active_state->outgoing_packet) + 4 - 8; + len = sshbuf_len(state->outgoing_packet) + 4 - 8; /* Insert padding. Initialized to zero in packet_start1() */ padding = 8 - len % 8; - if (!active_state->send_context.plaintext) { - cp = buffer_ptr(&active_state->outgoing_packet); - for (i = 0; i < padding; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cp[7 - i] = rnd & 0xff; - rnd >>= 8; + if (!state->send_context.plaintext) { + cp = sshbuf_mutable_ptr(state->outgoing_packet); + if (cp == NULL) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; } + arc4random_buf(cp + 8 - padding, padding); } - buffer_consume(&active_state->outgoing_packet, 8 - padding); + if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0) + goto out; /* Add check bytes. */ - checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet), - buffer_len(&active_state->outgoing_packet)); - put_u32(buf, checksum); - buffer_append(&active_state->outgoing_packet, buf, 4); + checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet), + sshbuf_len(state->outgoing_packet)); + POKE_U32(buf, checksum); + if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0) + goto out; #ifdef PACKET_DEBUG fprintf(stderr, "packet_send plain: "); - buffer_dump(&active_state->outgoing_packet); + sshbuf_dump(state->outgoing_packet, stderr); #endif /* Append to output. */ - put_u32(buf, len); - buffer_append(&active_state->output, buf, 4); - cp = buffer_append_space(&active_state->output, - buffer_len(&active_state->outgoing_packet)); - if (cipher_crypt(&active_state->send_context, 0, cp, - buffer_ptr(&active_state->outgoing_packet), - buffer_len(&active_state->outgoing_packet), 0, 0) != 0) - fatal("%s: cipher_crypt failed", __func__); + POKE_U32(buf, len); + if ((r = sshbuf_put(state->output, buf, 4)) != 0) + goto out; + if ((r = sshbuf_reserve(state->output, + sshbuf_len(state->outgoing_packet), &cp)) != 0) + goto out; + if ((r = cipher_crypt(&state->send_context, 0, cp, + sshbuf_ptr(state->outgoing_packet), + sshbuf_len(state->outgoing_packet), 0, 0)) != 0) + goto out; #ifdef PACKET_DEBUG fprintf(stderr, "encrypted: "); - buffer_dump(&active_state->output); + sshbuf_dump(state->output, stderr); #endif - active_state->p_send.packets++; - active_state->p_send.bytes += len + - buffer_len(&active_state->outgoing_packet); - buffer_clear(&active_state->outgoing_packet); + state->p_send.packets++; + state->p_send.bytes += len + + sshbuf_len(state->outgoing_packet); + sshbuf_reset(state->outgoing_packet); /* * Note that the packet is now only buffered in output. It won't be - * actually sent until packet_write_wait or packet_write_poll is - * called. + * actually sent until ssh_packet_write_wait or ssh_packet_write_poll + * is called. */ + r = 0; + out: + return r; } -void -set_newkeys(int mode) +int +ssh_set_newkeys(struct ssh *ssh, int mode) { - Enc *enc; - Mac *mac; - Comp *comp; - CipherContext *cc; + struct session_state *state = ssh->state; + struct sshenc *enc; + struct sshmac *mac; + struct sshcomp *comp; + struct sshcipher_ctx *cc; u_int64_t *max_blocks; + const char *wmsg; int r, crypt_type; debug2("set_newkeys: mode %d", mode); if (mode == MODE_OUT) { - cc = &active_state->send_context; + cc = &state->send_context; crypt_type = CIPHER_ENCRYPT; - active_state->p_send.packets = active_state->p_send.blocks = 0; - max_blocks = &active_state->max_blocks_out; + state->p_send.packets = state->p_send.blocks = 0; + max_blocks = &state->max_blocks_out; } else { - cc = &active_state->receive_context; + cc = &state->receive_context; crypt_type = CIPHER_DECRYPT; - active_state->p_read.packets = active_state->p_read.blocks = 0; - max_blocks = &active_state->max_blocks_in; + state->p_read.packets = state->p_read.blocks = 0; + max_blocks = &state->max_blocks_in; } - if (active_state->newkeys[mode] != NULL) { + if (state->newkeys[mode] != NULL) { debug("set_newkeys: rekeying"); - cipher_cleanup(cc); - enc = &active_state->newkeys[mode]->enc; - mac = &active_state->newkeys[mode]->mac; - comp = &active_state->newkeys[mode]->comp; + if ((r = cipher_cleanup(cc)) != 0) + return r; + enc = &state->newkeys[mode]->enc; + mac = &state->newkeys[mode]->mac; + comp = &state->newkeys[mode]->comp; mac_clear(mac); explicit_bzero(enc->iv, enc->iv_len); explicit_bzero(enc->key, enc->key_len); @@ -785,32 +955,45 @@ set_newkeys(int mode) free(mac->name); free(mac->key); free(comp->name); - free(active_state->newkeys[mode]); + free(state->newkeys[mode]); } - active_state->newkeys[mode] = kex_get_newkeys(mode); - if (active_state->newkeys[mode] == NULL) - fatal("newkeys: no keys for mode %d", mode); - enc = &active_state->newkeys[mode]->enc; - mac = &active_state->newkeys[mode]->mac; - comp = &active_state->newkeys[mode]->comp; - if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0) - mac->enabled = 1; + /* move newkeys from kex to state */ + if ((state->newkeys[mode] = ssh->kex->newkeys[mode]) == NULL) + return SSH_ERR_INTERNAL_ERROR; + ssh->kex->newkeys[mode] = NULL; + enc = &state->newkeys[mode]->enc; + mac = &state->newkeys[mode]->mac; + comp = &state->newkeys[mode]->comp; + if (cipher_authlen(enc->cipher) == 0) { + if ((r = mac_init(mac)) != 0) + return r; + } + mac->enabled = 1; DBG(debug("cipher_init_context: %d", mode)); if ((r = cipher_init(cc, enc->cipher, enc->key, enc->key_len, enc->iv, enc->iv_len, crypt_type)) != 0) - fatal("%s: cipher_init: %s", __func__, ssh_err(r)); + return r; + if (!state->cipher_warning_done && + (wmsg = cipher_warning_message(cc)) != NULL) { + error("Warning: %s", wmsg); + state->cipher_warning_done = 1; + } /* Deleting the keys does not gain extra security */ /* explicit_bzero(enc->iv, enc->block_size); explicit_bzero(enc->key, enc->key_len); explicit_bzero(mac->key, mac->key_len); */ if ((comp->type == COMP_ZLIB || (comp->type == COMP_DELAYED && - active_state->after_authentication)) && comp->enabled == 0) { - packet_init_compression(); - if (mode == MODE_OUT) - buffer_compress_init_send(6); - else - buffer_compress_init_recv(); + state->after_authentication)) && comp->enabled == 0) { + if ((r = ssh_packet_init_compression(ssh)) < 0) + return r; + if (mode == MODE_OUT) { + if ((r = start_compression_out(ssh, 6)) != 0) + return r; + } else { + if ((r = start_compression_in(ssh)) != 0) + return r; + } comp->enabled = 1; } /* @@ -821,9 +1004,10 @@ set_newkeys(int mode) *max_blocks = (u_int64_t)1 << (enc->block_size*2); else *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; - if (active_state->rekey_limit) + if (state->rekey_limit) *max_blocks = MIN(*max_blocks, - active_state->rekey_limit / enc->block_size); + state->rekey_limit / enc->block_size); + return 0; } /* @@ -831,52 +1015,59 @@ set_newkeys(int mode) * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. */ -static void -packet_enable_delayed_compress(void) +static int +ssh_packet_enable_delayed_compress(struct ssh *ssh) { - Comp *comp = NULL; - int mode; + struct session_state *state = ssh->state; + struct sshcomp *comp = NULL; + int r, mode; /* * Remember that we are past the authentication step, so rekeying * with COMP_DELAYED will turn on compression immediately. */ - active_state->after_authentication = 1; + state->after_authentication = 1; for (mode = 0; mode < MODE_MAX; mode++) { /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ - if (active_state->newkeys[mode] == NULL) + if (state->newkeys[mode] == NULL) continue; - comp = &active_state->newkeys[mode]->comp; + comp = &state->newkeys[mode]->comp; if (comp && !comp->enabled && comp->type == COMP_DELAYED) { - packet_init_compression(); - if (mode == MODE_OUT) - buffer_compress_init_send(6); - else - buffer_compress_init_recv(); + if ((r = ssh_packet_init_compression(ssh)) != 0) + return r; + if (mode == MODE_OUT) { + if ((r = start_compression_out(ssh, 6)) != 0) + return r; + } else { + if ((r = start_compression_in(ssh)) != 0) + return r; + } comp->enabled = 1; } } + return 0; } /* * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) */ -static void -packet_send2_wrapped(void) +int +ssh_packet_send2_wrapped(struct ssh *ssh) { - u_char type, *cp, *macbuf = NULL; + struct session_state *state = ssh->state; + u_char type, *cp, macbuf[SSH_DIGEST_MAX_LENGTH]; u_char padlen, pad = 0; - u_int i, len, authlen = 0, aadlen = 0; - u_int32_t rnd = 0; - Enc *enc = NULL; - Mac *mac = NULL; - Comp *comp = NULL; - int block_size; + u_int authlen = 0, aadlen = 0; + u_int len; + struct sshenc *enc = NULL; + struct sshmac *mac = NULL; + struct sshcomp *comp = NULL; + int r, block_size; - if (active_state->newkeys[MODE_OUT] != NULL) { - enc = &active_state->newkeys[MODE_OUT]->enc; - mac = &active_state->newkeys[MODE_OUT]->mac; - comp = &active_state->newkeys[MODE_OUT]->comp; + if (state->newkeys[MODE_OUT] != NULL) { + enc = &state->newkeys[MODE_OUT]->enc; + mac = &state->newkeys[MODE_OUT]->mac; + comp = &state->newkeys[MODE_OUT]->comp; /* disable mac for authenticated encryption */ if ((authlen = cipher_authlen(enc->cipher)) != 0) mac = NULL; @@ -884,32 +1075,34 @@ packet_send2_wrapped(void) block_size = enc ? enc->block_size : 8; aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; - cp = buffer_ptr(&active_state->outgoing_packet); - type = cp[5]; + type = (sshbuf_ptr(state->outgoing_packet))[5]; #ifdef PACKET_DEBUG fprintf(stderr, "plain: "); - buffer_dump(&active_state->outgoing_packet); + sshbuf_dump(state->outgoing_packet, stderr); #endif if (comp && comp->enabled) { - len = buffer_len(&active_state->outgoing_packet); + len = sshbuf_len(state->outgoing_packet); /* skip header, compress only payload */ - buffer_consume(&active_state->outgoing_packet, 5); - buffer_clear(&active_state->compression_buffer); - buffer_compress(&active_state->outgoing_packet, - &active_state->compression_buffer); - buffer_clear(&active_state->outgoing_packet); - buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5); - buffer_append(&active_state->outgoing_packet, - buffer_ptr(&active_state->compression_buffer), - buffer_len(&active_state->compression_buffer)); - DBG(debug("compression: raw %d compressed %d", len, - buffer_len(&active_state->outgoing_packet))); + if ((r = sshbuf_consume(state->outgoing_packet, 5)) != 0) + goto out; + sshbuf_reset(state->compression_buffer); + if ((r = compress_buffer(ssh, state->outgoing_packet, + state->compression_buffer)) != 0) + goto out; + sshbuf_reset(state->outgoing_packet); + if ((r = sshbuf_put(state->outgoing_packet, + "\0\0\0\0\0", 5)) != 0 || + (r = sshbuf_putb(state->outgoing_packet, + state->compression_buffer)) != 0) + goto out; + DBG(debug("compression: raw %d compressed %zd", len, + sshbuf_len(state->outgoing_packet))); } /* sizeof (packet_len + pad_len + payload) */ - len = buffer_len(&active_state->outgoing_packet); + len = sshbuf_len(state->outgoing_packet); /* * calc size of padding, alloc space, get random data, @@ -919,139 +1112,145 @@ packet_send2_wrapped(void) padlen = block_size - (len % block_size); if (padlen < 4) padlen += block_size; - if (active_state->extra_pad) { + if (state->extra_pad) { /* will wrap if extra_pad+padlen > 255 */ - active_state->extra_pad = - roundup(active_state->extra_pad, block_size); - pad = active_state->extra_pad - - ((len + padlen) % active_state->extra_pad); + state->extra_pad = + roundup(state->extra_pad, block_size); + pad = state->extra_pad - + ((len + padlen) % state->extra_pad); DBG(debug3("%s: adding %d (len %d padlen %d extra_pad %d)", - __func__, pad, len, padlen, active_state->extra_pad)); + __func__, pad, len, padlen, state->extra_pad)); padlen += pad; - active_state->extra_pad = 0; + state->extra_pad = 0; } - cp = buffer_append_space(&active_state->outgoing_packet, padlen); - if (enc && !active_state->send_context.plaintext) { + if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0) + goto out; + if (enc && !state->send_context.plaintext) { /* random padding */ - for (i = 0; i < padlen; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cp[i] = rnd & 0xff; - rnd >>= 8; - } + arc4random_buf(cp, padlen); } else { /* clear padding */ explicit_bzero(cp, padlen); } /* sizeof (packet_len + pad_len + payload + padding) */ - len = buffer_len(&active_state->outgoing_packet); - cp = buffer_ptr(&active_state->outgoing_packet); + len = sshbuf_len(state->outgoing_packet); + cp = sshbuf_mutable_ptr(state->outgoing_packet); + if (cp == NULL) { + r = SSH_ERR_INTERNAL_ERROR; + goto out; + } /* packet_length includes payload, padding and padding length field */ - put_u32(cp, len - 4); + POKE_U32(cp, len - 4); cp[4] = padlen; DBG(debug("send: len %d (includes padlen %d, aadlen %d)", len, padlen, aadlen)); /* compute MAC over seqnr and packet(length fields, payload, padding) */ if (mac && mac->enabled && !mac->etm) { - macbuf = mac_compute(mac, active_state->p_send.seqnr, - buffer_ptr(&active_state->outgoing_packet), len); - DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); + if ((r = mac_compute(mac, state->p_send.seqnr, + sshbuf_ptr(state->outgoing_packet), len, + macbuf, sizeof(macbuf))) != 0) + goto out; + DBG(debug("done calc MAC out #%d", state->p_send.seqnr)); } /* encrypt packet and append to output buffer. */ - cp = buffer_append_space(&active_state->output, len + authlen); - if (cipher_crypt(&active_state->send_context, active_state->p_send.seqnr, - cp, buffer_ptr(&active_state->outgoing_packet), - len - aadlen, aadlen, authlen) != 0) - fatal("%s: cipher_crypt failed", __func__); + if ((r = sshbuf_reserve(state->output, + sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) + goto out; + if ((r = cipher_crypt(&state->send_context, state->p_send.seqnr, cp, + sshbuf_ptr(state->outgoing_packet), + len - aadlen, aadlen, authlen)) != 0) + goto out; /* append unencrypted MAC */ if (mac && mac->enabled) { if (mac->etm) { /* EtM: compute mac over aadlen + cipher text */ - macbuf = mac_compute(mac, - active_state->p_send.seqnr, cp, len); + if ((r = mac_compute(mac, state->p_send.seqnr, + cp, len, macbuf, sizeof(macbuf))) != 0) + goto out; DBG(debug("done calc MAC(EtM) out #%d", - active_state->p_send.seqnr)); + state->p_send.seqnr)); } - buffer_append(&active_state->output, macbuf, mac->mac_len); + if ((r = sshbuf_put(state->output, macbuf, mac->mac_len)) != 0) + goto out; } #ifdef PACKET_DEBUG fprintf(stderr, "encrypted: "); - buffer_dump(&active_state->output); + sshbuf_dump(state->output, stderr); #endif /* increment sequence number for outgoing packets */ - if (++active_state->p_send.seqnr == 0) + if (++state->p_send.seqnr == 0) logit("outgoing seqnr wraps around"); - if (++active_state->p_send.packets == 0) - if (!(datafellows & SSH_BUG_NOREKEY)) - fatal("XXX too many packets with same key"); - active_state->p_send.blocks += len / block_size; - active_state->p_send.bytes += len; - buffer_clear(&active_state->outgoing_packet); + if (++state->p_send.packets == 0) + if (!(ssh->compat & SSH_BUG_NOREKEY)) + return SSH_ERR_NEED_REKEY; + state->p_send.blocks += len / block_size; + state->p_send.bytes += len; + sshbuf_reset(state->outgoing_packet); if (type == SSH2_MSG_NEWKEYS) - set_newkeys(MODE_OUT); - else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side) - packet_enable_delayed_compress(); + r = ssh_set_newkeys(ssh, MODE_OUT); + else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side) + r = ssh_packet_enable_delayed_compress(ssh); + else + r = 0; + out: + return r; } -static void -packet_send2(void) +int +ssh_packet_send2(struct ssh *ssh) { + struct session_state *state = ssh->state; struct packet *p; - u_char type, *cp; + u_char type; + int r; - cp = buffer_ptr(&active_state->outgoing_packet); - type = cp[5]; + type = sshbuf_ptr(state->outgoing_packet)[5]; /* during rekeying we can only send key exchange messages */ - if (active_state->rekeying) { + if (state->rekeying) { if ((type < SSH2_MSG_TRANSPORT_MIN) || (type > SSH2_MSG_TRANSPORT_MAX) || (type == SSH2_MSG_SERVICE_REQUEST) || (type == SSH2_MSG_SERVICE_ACCEPT)) { debug("enqueue packet: %u", type); - p = xcalloc(1, sizeof(*p)); + p = calloc(1, sizeof(*p)); + if (p == NULL) + return SSH_ERR_ALLOC_FAIL; p->type = type; - memcpy(&p->payload, &active_state->outgoing_packet, - sizeof(Buffer)); - buffer_init(&active_state->outgoing_packet); - TAILQ_INSERT_TAIL(&active_state->outgoing, p, next); - return; + p->payload = state->outgoing_packet; + TAILQ_INSERT_TAIL(&state->outgoing, p, next); + state->outgoing_packet = sshbuf_new(); + if (state->outgoing_packet == NULL) + return SSH_ERR_ALLOC_FAIL; + return 0; } } /* rekeying starts with sending KEXINIT */ if (type == SSH2_MSG_KEXINIT) - active_state->rekeying = 1; + state->rekeying = 1; - packet_send2_wrapped(); + if ((r = ssh_packet_send2_wrapped(ssh)) != 0) + return r; /* after a NEWKEYS message we can send the complete queue */ if (type == SSH2_MSG_NEWKEYS) { - active_state->rekeying = 0; - active_state->rekey_time = monotime(); - while ((p = TAILQ_FIRST(&active_state->outgoing))) { + state->rekeying = 0; + state->rekey_time = monotime(); + while ((p = TAILQ_FIRST(&state->outgoing))) { type = p->type; debug("dequeue packet: %u", type); - buffer_free(&active_state->outgoing_packet); - memcpy(&active_state->outgoing_packet, &p->payload, - sizeof(Buffer)); - TAILQ_REMOVE(&active_state->outgoing, p, next); + sshbuf_free(state->outgoing_packet); + state->outgoing_packet = p->payload; + TAILQ_REMOVE(&state->outgoing, p, next); free(p); - packet_send2_wrapped(); + if ((r = ssh_packet_send2_wrapped(ssh)) != 0) + return r; } } -} - -void -packet_send(void) -{ - if (compat20) - packet_send2(); - else - packet_send1(); - DBG(debug("packet_send done")); + return 0; } /* @@ -1061,95 +1260,106 @@ packet_send(void) */ int -packet_read_seqnr(u_int32_t *seqnr_p) +ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { - int type, len, ret, cont, ms_remain = 0; + struct session_state *state = ssh->state; + int len, r, ms_remain, cont; fd_set *setp; char buf[8192]; struct timeval timeout, start, *timeoutp = NULL; DBG(debug("packet_read()")); - setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1, + setp = (fd_set *)calloc(howmany(state->connection_in + 1, NFDBITS), sizeof(fd_mask)); + if (setp == NULL) + return SSH_ERR_ALLOC_FAIL; - /* Since we are blocking, ensure that all written packets have been sent. */ - packet_write_wait(); + /* + * Since we are blocking, ensure that all written packets have + * been sent. + */ + if ((r = ssh_packet_write_wait(ssh)) != 0) + return r; /* Stay in the loop until we have received a complete packet. */ for (;;) { /* Try to read a packet from the buffer. */ - type = packet_read_poll_seqnr(seqnr_p); + r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); + if (r != 0) + break; if (!compat20 && ( - type == SSH_SMSG_SUCCESS - || type == SSH_SMSG_FAILURE - || type == SSH_CMSG_EOF - || type == SSH_CMSG_EXIT_CONFIRMATION)) - packet_check_eom(); + *typep == SSH_SMSG_SUCCESS + || *typep == SSH_SMSG_FAILURE + || *typep == SSH_CMSG_EOF + || *typep == SSH_CMSG_EXIT_CONFIRMATION)) + if ((r = sshpkt_get_end(ssh)) != 0) + break; /* If we got a packet, return it. */ - if (type != SSH_MSG_NONE) { - free(setp); - return type; - } + if (*typep != SSH_MSG_NONE) + break; /* * Otherwise, wait for some data to arrive, add it to the * buffer, and try again. */ - memset(setp, 0, howmany(active_state->connection_in + 1, + memset(setp, 0, howmany(state->connection_in + 1, NFDBITS) * sizeof(fd_mask)); - FD_SET(active_state->connection_in, setp); + FD_SET(state->connection_in, setp); - if (active_state->packet_timeout_ms > 0) { - ms_remain = active_state->packet_timeout_ms; + if (state->packet_timeout_ms > 0) { + ms_remain = state->packet_timeout_ms; timeoutp = &timeout; } /* Wait for some data to arrive. */ for (;;) { - if (active_state->packet_timeout_ms != -1) { + if (state->packet_timeout_ms != -1) { ms_to_timeval(&timeout, ms_remain); gettimeofday(&start, NULL); } - if ((ret = select(active_state->connection_in + 1, setp, + if ((r = select(state->connection_in + 1, setp, NULL, NULL, timeoutp)) >= 0) break; if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) break; - if (active_state->packet_timeout_ms == -1) + if (state->packet_timeout_ms == -1) continue; ms_subtract_diff(&start, &ms_remain); if (ms_remain <= 0) { - ret = 0; + r = 0; break; } } - if (ret == 0) { - logit("Connection to %.200s timed out while " - "waiting to read", get_remote_ipaddr()); - cleanup_exit(255); - } + if (r == 0) + return SSH_ERR_CONN_TIMEOUT; /* Read data from the socket. */ do { cont = 0; - len = roaming_read(active_state->connection_in, buf, + len = roaming_read(state->connection_in, buf, sizeof(buf), &cont); } while (len == 0 && cont); - if (len == 0) { - logit("Connection closed by %.200s", get_remote_ipaddr()); - cleanup_exit(255); - } + if (len == 0) + return SSH_ERR_CONN_CLOSED; if (len < 0) - fatal("Read from socket failed: %.100s", strerror(errno)); + return SSH_ERR_SYSTEM_ERROR; + /* Append it to the buffer. */ - packet_process_incoming(buf, len); + if ((r = ssh_packet_process_incoming(ssh, buf, len)) != 0) + return r; } - /* NOTREACHED */ + free(setp); + return r; } int -packet_read(void) +ssh_packet_read(struct ssh *ssh) { - return packet_read_seqnr(NULL); + u_char type; + int r; + + if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + return type; } /* @@ -1157,15 +1367,22 @@ packet_read(void) * that given, and gives a fatal error and exits if there is a mismatch. */ -void -packet_read_expect(int expected_type) +int +ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) { - int type; + int r; + u_char type; - type = packet_read(); - if (type != expected_type) - packet_disconnect("Protocol error: expected packet type %d, got %d", - expected_type, type); + if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) + return r; + if (type != expected_type) { + if ((r = sshpkt_disconnect(ssh, + "Protocol error: expected packet type %d, got %d", + expected_type, type)) != 0) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } + return 0; } /* Checks if a full packet is available in the data received so far via @@ -1177,115 +1394,165 @@ packet_read_expect(int expected_type) * to higher levels. */ -static int -packet_read_poll1(void) +int +ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) { + struct session_state *state = ssh->state; u_int len, padded_len; - u_char *cp, type; + const char *emsg; + const u_char *cp; + u_char *p; u_int checksum, stored_checksum; + int r; + + *typep = SSH_MSG_NONE; /* Check if input size is less than minimum packet size. */ - if (buffer_len(&active_state->input) < 4 + 8) - return SSH_MSG_NONE; + if (sshbuf_len(state->input) < 4 + 8) + return 0; /* Get length of incoming packet. */ - cp = buffer_ptr(&active_state->input); - len = get_u32(cp); - if (len < 1 + 2 + 2 || len > 256 * 1024) - packet_disconnect("Bad packet length %u.", len); + len = PEEK_U32(sshbuf_ptr(state->input)); + if (len < 1 + 2 + 2 || len > 256 * 1024) { + if ((r = sshpkt_disconnect(ssh, "Bad packet length %u", + len)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } padded_len = (len + 8) & ~7; /* Check if the packet has been entirely received. */ - if (buffer_len(&active_state->input) < 4 + padded_len) - return SSH_MSG_NONE; + if (sshbuf_len(state->input) < 4 + padded_len) + return 0; /* The entire packet is in buffer. */ /* Consume packet length. */ - buffer_consume(&active_state->input, 4); + if ((r = sshbuf_consume(state->input, 4)) != 0) + goto out; /* * Cryptographic attack detector for ssh * (C)1998 CORE-SDI, Buenos Aires Argentina * Ariel Futoransky(futo@core-sdi.com) */ - if (!active_state->receive_context.plaintext) { - switch (detect_attack(buffer_ptr(&active_state->input), - padded_len)) { + if (!state->receive_context.plaintext) { + emsg = NULL; + switch (detect_attack(&state->deattack, + sshbuf_ptr(state->input), padded_len)) { + case DEATTACK_OK: + break; case DEATTACK_DETECTED: - packet_disconnect("crc32 compensation attack: " - "network attack detected"); + emsg = "crc32 compensation attack detected"; + break; case DEATTACK_DOS_DETECTED: - packet_disconnect("deattack denial of " - "service detected"); + emsg = "deattack denial of service detected"; + break; + default: + emsg = "deattack error"; + break; + } + if (emsg != NULL) { + error("%s", emsg); + if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; } } /* Decrypt data to incoming_packet. */ - buffer_clear(&active_state->incoming_packet); - cp = buffer_append_space(&active_state->incoming_packet, padded_len); - if (cipher_crypt(&active_state->receive_context, 0, cp, - buffer_ptr(&active_state->input), padded_len, 0, 0) != 0) - fatal("%s: cipher_crypt failed", __func__); + sshbuf_reset(state->incoming_packet); + if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0) + goto out; + if ((r = cipher_crypt(&state->receive_context, 0, p, + sshbuf_ptr(state->input), padded_len, 0, 0)) != 0) + goto out; - buffer_consume(&active_state->input, padded_len); + if ((r = sshbuf_consume(state->input, padded_len)) != 0) + goto out; #ifdef PACKET_DEBUG fprintf(stderr, "read_poll plain: "); - buffer_dump(&active_state->incoming_packet); + sshbuf_dump(state->incoming_packet, stderr); #endif /* Compute packet checksum. */ - checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet), - buffer_len(&active_state->incoming_packet) - 4); + checksum = ssh_crc32(sshbuf_ptr(state->incoming_packet), + sshbuf_len(state->incoming_packet) - 4); /* Skip padding. */ - buffer_consume(&active_state->incoming_packet, 8 - len % 8); + if ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0) + goto out; /* Test check bytes. */ - if (len != buffer_len(&active_state->incoming_packet)) - packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", - len, buffer_len(&active_state->incoming_packet)); - - cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4; - stored_checksum = get_u32(cp); - if (checksum != stored_checksum) - packet_disconnect("Corrupted check bytes on input."); - buffer_consume_end(&active_state->incoming_packet, 4); - - if (active_state->packet_compression) { - buffer_clear(&active_state->compression_buffer); - buffer_uncompress(&active_state->incoming_packet, - &active_state->compression_buffer); - buffer_clear(&active_state->incoming_packet); - buffer_append(&active_state->incoming_packet, - buffer_ptr(&active_state->compression_buffer), - buffer_len(&active_state->compression_buffer)); + if (len != sshbuf_len(state->incoming_packet)) { + error("%s: len %d != sshbuf_len %zd", __func__, + len, sshbuf_len(state->incoming_packet)); + if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; } - active_state->p_read.packets++; - active_state->p_read.bytes += padded_len + 4; - type = buffer_get_char(&active_state->incoming_packet); - if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) - packet_disconnect("Invalid ssh1 packet type: %d", type); - return type; + + cp = sshbuf_ptr(state->incoming_packet) + len - 4; + stored_checksum = PEEK_U32(cp); + if (checksum != stored_checksum) { + error("Corrupted check bytes on input"); + if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } + if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0) + goto out; + + if (state->packet_compression) { + sshbuf_reset(state->compression_buffer); + if ((r = uncompress_buffer(ssh, state->incoming_packet, + state->compression_buffer)) != 0) + goto out; + sshbuf_reset(state->incoming_packet); + if ((r = sshbuf_putb(state->incoming_packet, + state->compression_buffer)) != 0) + goto out; + } + state->p_read.packets++; + state->p_read.bytes += padded_len + 4; + if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) + goto out; + if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) { + error("Invalid ssh1 packet type: %d", *typep); + if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } + r = 0; + out: + return r; } -static int -packet_read_poll2(u_int32_t *seqnr_p) +int +ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { + struct session_state *state = ssh->state; u_int padlen, need; - u_char *macbuf = NULL, *cp, type; - u_int maclen, authlen = 0, aadlen = 0, block_size; - Enc *enc = NULL; - Mac *mac = NULL; - Comp *comp = NULL; + u_char *cp, macbuf[SSH_DIGEST_MAX_LENGTH]; + u_int maclen, aadlen = 0, authlen = 0, block_size; + struct sshenc *enc = NULL; + struct sshmac *mac = NULL; + struct sshcomp *comp = NULL; + int r; - if (active_state->packet_discard) - return SSH_MSG_NONE; + *typep = SSH_MSG_NONE; - if (active_state->newkeys[MODE_IN] != NULL) { - enc = &active_state->newkeys[MODE_IN]->enc; - mac = &active_state->newkeys[MODE_IN]->mac; - comp = &active_state->newkeys[MODE_IN]->comp; + if (state->packet_discard) + return 0; + + if (state->newkeys[MODE_IN] != NULL) { + enc = &state->newkeys[MODE_IN]->enc; + mac = &state->newkeys[MODE_IN]->mac; + comp = &state->newkeys[MODE_IN]->comp; /* disable mac for authenticated encryption */ if ((authlen = cipher_authlen(enc->cipher)) != 0) mac = NULL; @@ -1294,69 +1561,71 @@ packet_read_poll2(u_int32_t *seqnr_p) block_size = enc ? enc->block_size : 8; aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; - if (aadlen && active_state->packlen == 0) { - if (cipher_get_length(&active_state->receive_context, - &active_state->packlen, - active_state->p_read.seqnr, - buffer_ptr(&active_state->input), - buffer_len(&active_state->input)) != 0) - return SSH_MSG_NONE; - if (active_state->packlen < 1 + 4 || - active_state->packlen > PACKET_MAX_SIZE) { + if (aadlen && state->packlen == 0) { + if (cipher_get_length(&state->receive_context, + &state->packlen, state->p_read.seqnr, + sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) + return 0; + if (state->packlen < 1 + 4 || + state->packlen > PACKET_MAX_SIZE) { #ifdef PACKET_DEBUG - buffer_dump(&active_state->input); + sshbuf_dump(state->input, stderr); #endif - logit("Bad packet length %u.", active_state->packlen); - packet_disconnect("Packet corrupt"); + logit("Bad packet length %u.", state->packlen); + if ((r = sshpkt_disconnect(ssh, "Packet corrupt")) != 0) + return r; } - buffer_clear(&active_state->incoming_packet); - } else if (active_state->packlen == 0) { + sshbuf_reset(state->incoming_packet); + } else if (state->packlen == 0) { /* * check if input size is less than the cipher block size, * decrypt first block and extract length of incoming packet */ - if (buffer_len(&active_state->input) < block_size) - return SSH_MSG_NONE; - buffer_clear(&active_state->incoming_packet); - cp = buffer_append_space(&active_state->incoming_packet, - block_size); - if (cipher_crypt(&active_state->receive_context, - active_state->p_read.seqnr, cp, - buffer_ptr(&active_state->input), block_size, 0, 0) != 0) - fatal("Decryption integrity check failed"); - cp = buffer_ptr(&active_state->incoming_packet); - active_state->packlen = get_u32(cp); - if (active_state->packlen < 1 + 4 || - active_state->packlen > PACKET_MAX_SIZE) { + if (sshbuf_len(state->input) < block_size) + return 0; + sshbuf_reset(state->incoming_packet); + if ((r = sshbuf_reserve(state->incoming_packet, block_size, + &cp)) != 0) + goto out; + if ((r = cipher_crypt(&state->receive_context, + state->p_send.seqnr, cp, sshbuf_ptr(state->input), + block_size, 0, 0)) != 0) + goto out; + state->packlen = PEEK_U32(sshbuf_ptr(state->incoming_packet)); + if (state->packlen < 1 + 4 || + state->packlen > PACKET_MAX_SIZE) { #ifdef PACKET_DEBUG - buffer_dump(&active_state->incoming_packet); + fprintf(stderr, "input: \n"); + sshbuf_dump(state->input, stderr); + fprintf(stderr, "incoming_packet: \n"); + sshbuf_dump(state->incoming_packet, stderr); #endif - logit("Bad packet length %u.", active_state->packlen); - packet_start_discard(enc, mac, active_state->packlen, - PACKET_MAX_SIZE); - return SSH_MSG_NONE; + logit("Bad packet length %u.", state->packlen); + return ssh_packet_start_discard(ssh, enc, mac, + state->packlen, PACKET_MAX_SIZE); } - buffer_consume(&active_state->input, block_size); + if ((r = sshbuf_consume(state->input, block_size)) != 0) + goto out; } - DBG(debug("input: packet len %u", active_state->packlen+4)); + DBG(debug("input: packet len %u", state->packlen+4)); + if (aadlen) { /* only the payload is encrypted */ - need = active_state->packlen; + need = state->packlen; } else { /* * the payload size and the payload are encrypted, but we * have a partial packet of block_size bytes */ - need = 4 + active_state->packlen - block_size; + need = 4 + state->packlen - block_size; } DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d," " aadlen %d", block_size, need, maclen, authlen, aadlen)); if (need % block_size != 0) { logit("padding error: need %d block %d mod %d", need, block_size, need % block_size); - packet_start_discard(enc, mac, active_state->packlen, - PACKET_MAX_SIZE - block_size); - return SSH_MSG_NONE; + return ssh_packet_start_discard(ssh, enc, mac, + state->packlen, PACKET_MAX_SIZE - block_size); } /* * check if the entire packet has been received and @@ -1366,167 +1635,197 @@ packet_read_poll2(u_int32_t *seqnr_p) * 'authlen' bytes of authentication tag or * 'maclen' bytes of message authentication code. */ - if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen) - return SSH_MSG_NONE; + if (sshbuf_len(state->input) < aadlen + need + authlen + maclen) + return 0; #ifdef PACKET_DEBUG fprintf(stderr, "read_poll enc/full: "); - buffer_dump(&active_state->input); + sshbuf_dump(state->input, stderr); #endif /* EtM: compute mac over encrypted input */ - if (mac && mac->enabled && mac->etm) - macbuf = mac_compute(mac, active_state->p_read.seqnr, - buffer_ptr(&active_state->input), aadlen + need); - cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); - if (cipher_crypt(&active_state->receive_context, - active_state->p_read.seqnr, cp, - buffer_ptr(&active_state->input), need, aadlen, authlen) != 0) - fatal("Decryption integrity check failed"); - buffer_consume(&active_state->input, aadlen + need + authlen); + if (mac && mac->enabled && mac->etm) { + if ((r = mac_compute(mac, state->p_read.seqnr, + sshbuf_ptr(state->input), aadlen + need, + macbuf, sizeof(macbuf))) != 0) + goto out; + } + if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, + &cp)) != 0) + goto out; + if ((r = cipher_crypt(&state->receive_context, state->p_read.seqnr, cp, + sshbuf_ptr(state->input), need, aadlen, authlen)) != 0) + goto out; + if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) + goto out; /* * compute MAC over seqnr and packet, * increment sequence number for incoming packet */ if (mac && mac->enabled) { if (!mac->etm) - macbuf = mac_compute(mac, active_state->p_read.seqnr, - buffer_ptr(&active_state->incoming_packet), - buffer_len(&active_state->incoming_packet)); - if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), + if ((r = mac_compute(mac, state->p_read.seqnr, + sshbuf_ptr(state->incoming_packet), + sshbuf_len(state->incoming_packet), + macbuf, sizeof(macbuf))) != 0) + goto out; + if (timingsafe_bcmp(macbuf, sshbuf_ptr(state->input), mac->mac_len) != 0) { logit("Corrupted MAC on input."); if (need > PACKET_MAX_SIZE) - fatal("internal error need %d", need); - packet_start_discard(enc, mac, active_state->packlen, - PACKET_MAX_SIZE - need); - return SSH_MSG_NONE; + return SSH_ERR_INTERNAL_ERROR; + return ssh_packet_start_discard(ssh, enc, mac, + state->packlen, PACKET_MAX_SIZE - need); } - - DBG(debug("MAC #%d ok", active_state->p_read.seqnr)); - buffer_consume(&active_state->input, mac->mac_len); + + DBG(debug("MAC #%d ok", state->p_read.seqnr)); + if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) + goto out; } - /* XXX now it's safe to use fatal/packet_disconnect */ if (seqnr_p != NULL) - *seqnr_p = active_state->p_read.seqnr; - if (++active_state->p_read.seqnr == 0) + *seqnr_p = state->p_read.seqnr; + if (++state->p_read.seqnr == 0) logit("incoming seqnr wraps around"); - if (++active_state->p_read.packets == 0) - if (!(datafellows & SSH_BUG_NOREKEY)) - fatal("XXX too many packets with same key"); - active_state->p_read.blocks += (active_state->packlen + 4) / block_size; - active_state->p_read.bytes += active_state->packlen + 4; + if (++state->p_read.packets == 0) + if (!(ssh->compat & SSH_BUG_NOREKEY)) + return SSH_ERR_NEED_REKEY; + state->p_read.blocks += (state->packlen + 4) / block_size; + state->p_read.bytes += state->packlen + 4; /* get padlen */ - cp = buffer_ptr(&active_state->incoming_packet); - padlen = cp[4]; + padlen = sshbuf_ptr(state->incoming_packet)[4]; DBG(debug("input: padlen %d", padlen)); - if (padlen < 4) - packet_disconnect("Corrupted padlen %d on input.", padlen); + if (padlen < 4) { + if ((r = sshpkt_disconnect(ssh, + "Corrupted padlen %d on input.", padlen)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_CONN_CORRUPT; + } /* skip packet size + padlen, discard padding */ - buffer_consume(&active_state->incoming_packet, 4 + 1); - buffer_consume_end(&active_state->incoming_packet, padlen); + if ((r = sshbuf_consume(state->incoming_packet, 4 + 1)) != 0 || + ((r = sshbuf_consume_end(state->incoming_packet, padlen)) != 0)) + goto out; - DBG(debug("input: len before de-compress %d", - buffer_len(&active_state->incoming_packet))); + DBG(debug("input: len before de-compress %zd", + sshbuf_len(state->incoming_packet))); if (comp && comp->enabled) { - buffer_clear(&active_state->compression_buffer); - buffer_uncompress(&active_state->incoming_packet, - &active_state->compression_buffer); - buffer_clear(&active_state->incoming_packet); - buffer_append(&active_state->incoming_packet, - buffer_ptr(&active_state->compression_buffer), - buffer_len(&active_state->compression_buffer)); - DBG(debug("input: len after de-compress %d", - buffer_len(&active_state->incoming_packet))); + sshbuf_reset(state->compression_buffer); + if ((r = uncompress_buffer(ssh, state->incoming_packet, + state->compression_buffer)) != 0) + goto out; + sshbuf_reset(state->incoming_packet); + if ((r = sshbuf_putb(state->incoming_packet, + state->compression_buffer)) != 0) + goto out; + DBG(debug("input: len after de-compress %zd", + sshbuf_len(state->incoming_packet))); } /* * get packet type, implies consume. * return length of payload (without type field) */ - type = buffer_get_char(&active_state->incoming_packet); - if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN) - packet_disconnect("Invalid ssh2 packet type: %d", type); - if (type == SSH2_MSG_NEWKEYS) - set_newkeys(MODE_IN); - else if (type == SSH2_MSG_USERAUTH_SUCCESS && - !active_state->server_side) - packet_enable_delayed_compress(); + if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) + goto out; + if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { + if ((r = sshpkt_disconnect(ssh, + "Invalid ssh2 packet type: %d", *typep)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + return r; + return SSH_ERR_PROTOCOL_ERROR; + } + if (*typep == SSH2_MSG_NEWKEYS) + r = ssh_set_newkeys(ssh, MODE_IN); + else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) + r = ssh_packet_enable_delayed_compress(ssh); + else + r = 0; #ifdef PACKET_DEBUG - fprintf(stderr, "read/plain[%d]:\r\n", type); - buffer_dump(&active_state->incoming_packet); + fprintf(stderr, "read/plain[%d]:\r\n", *typep); + sshbuf_dump(state->incoming_packet, stderr); #endif /* reset for next packet */ - active_state->packlen = 0; - return type; + state->packlen = 0; + out: + return r; } int -packet_read_poll_seqnr(u_int32_t *seqnr_p) +ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { + struct session_state *state = ssh->state; u_int reason, seqnr; - u_char type; - char *msg; + int r; + u_char *msg; for (;;) { + msg = NULL; if (compat20) { - type = packet_read_poll2(seqnr_p); - if (type) { - active_state->keep_alive_timeouts = 0; - DBG(debug("received packet type %d", type)); + r = ssh_packet_read_poll2(ssh, typep, seqnr_p); + if (r != 0) + return r; + if (*typep) { + state->keep_alive_timeouts = 0; + DBG(debug("received packet type %d", *typep)); } - switch (type) { + switch (*typep) { case SSH2_MSG_IGNORE: debug3("Received SSH2_MSG_IGNORE"); break; case SSH2_MSG_DEBUG: - packet_get_char(); - msg = packet_get_string(NULL); + if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || + (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || + (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { + if (msg) + free(msg); + return r; + } debug("Remote: %.900s", msg); free(msg); - msg = packet_get_string(NULL); - free(msg); break; case SSH2_MSG_DISCONNECT: - reason = packet_get_int(); - msg = packet_get_string(NULL); + if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || + (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) + return r; /* Ignore normal client exit notifications */ - do_log2(active_state->server_side && + do_log2(ssh->state->server_side && reason == SSH2_DISCONNECT_BY_APPLICATION ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, "Received disconnect from %s: %u: %.400s", - get_remote_ipaddr(), reason, msg); + ssh_remote_ipaddr(ssh), reason, msg); free(msg); - cleanup_exit(255); - break; + return SSH_ERR_DISCONNECTED; case SSH2_MSG_UNIMPLEMENTED: - seqnr = packet_get_int(); + if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0) + return r; debug("Received SSH2_MSG_UNIMPLEMENTED for %u", seqnr); break; default: - return type; + return 0; } } else { - type = packet_read_poll1(); - switch (type) { + r = ssh_packet_read_poll1(ssh, typep); + switch (*typep) { case SSH_MSG_NONE: return SSH_MSG_NONE; case SSH_MSG_IGNORE: break; case SSH_MSG_DEBUG: - msg = packet_get_string(NULL); + if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) + return r; debug("Remote: %.900s", msg); free(msg); break; case SSH_MSG_DISCONNECT: - msg = packet_get_string(NULL); + if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) + return r; logit("Received disconnect from %s: %.400s", - get_remote_ipaddr(), msg); - cleanup_exit(255); - break; + ssh_remote_ipaddr(ssh), msg); + free(msg); + return SSH_ERR_DISCONNECTED; default: - DBG(debug("received packet type %d", type)); - return type; + DBG(debug("received packet type %d", *typep)); + return 0; } } } @@ -1537,113 +1836,31 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) * together with packet_read_poll. */ -void -packet_process_incoming(const char *buf, u_int len) +int +ssh_packet_process_incoming(struct ssh *ssh, const char *buf, u_int len) { - if (active_state->packet_discard) { - active_state->keep_alive_timeouts = 0; /* ?? */ - if (len >= active_state->packet_discard) - packet_stop_discard(); - active_state->packet_discard -= len; - return; + struct session_state *state = ssh->state; + int r; + + if (state->packet_discard) { + state->keep_alive_timeouts = 0; /* ?? */ + if (len >= state->packet_discard) { + if ((r = ssh_packet_stop_discard(ssh)) != 0) + return r; + } + state->packet_discard -= len; + return 0; } - buffer_append(&active_state->input, buf, len); + if ((r = sshbuf_put(ssh->state->input, buf, len)) != 0) + return r; + + return 0; } -/* Returns a character from the packet. */ - -u_int -packet_get_char(void) -{ - char ch; - - buffer_get(&active_state->incoming_packet, &ch, 1); - return (u_char) ch; -} - -/* Returns an integer from the packet data. */ - -u_int -packet_get_int(void) -{ - return buffer_get_int(&active_state->incoming_packet); -} - -/* Returns an 64 bit integer from the packet data. */ - -u_int64_t -packet_get_int64(void) -{ - return buffer_get_int64(&active_state->incoming_packet); -} - -/* - * Returns an arbitrary precision integer from the packet data. The integer - * must have been initialized before this call. - */ - -#ifdef WITH_OPENSSL -void -packet_get_bignum(BIGNUM * value) -{ - buffer_get_bignum(&active_state->incoming_packet, value); -} - -void -packet_get_bignum2(BIGNUM * value) -{ - buffer_get_bignum2(&active_state->incoming_packet, value); -} - -#ifdef OPENSSL_HAS_ECC -void -packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point) -{ - buffer_get_ecpoint(&active_state->incoming_packet, curve, point); -} -#endif - -void * -packet_get_raw(u_int *length_ptr) -{ - u_int bytes = buffer_len(&active_state->incoming_packet); - - if (length_ptr != NULL) - *length_ptr = bytes; - return buffer_ptr(&active_state->incoming_packet); -} -#endif - int -packet_remaining(void) +ssh_packet_remaining(struct ssh *ssh) { - return buffer_len(&active_state->incoming_packet); -} - -/* - * Returns a string from the packet data. The string is allocated using - * xmalloc; it is the responsibility of the calling program to free it when - * no longer needed. The length_ptr argument may be NULL, or point to an - * integer into which the length of the string is stored. - */ - -void * -packet_get_string(u_int *length_ptr) -{ - return buffer_get_string(&active_state->incoming_packet, length_ptr); -} - -const void * -packet_get_string_ptr(u_int *length_ptr) -{ - return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr); -} - -/* Ensures the returned string has no embedded \0 characters in it. */ -char * -packet_get_cstring(u_int *length_ptr) -{ - return buffer_get_cstring(&active_state->incoming_packet, length_ptr); + return sshbuf_len(ssh->state->incoming_packet); } /* @@ -1652,16 +1869,16 @@ packet_get_cstring(u_int *length_ptr) * message is printed immediately, but only if the client is being executed * in verbose mode. These messages are primarily intended to ease debugging * authentication problems. The length of the formatted message must not - * exceed 1024 bytes. This will automatically call packet_write_wait. + * exceed 1024 bytes. This will automatically call ssh_packet_write_wait. */ - void -packet_send_debug(const char *fmt,...) +ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) { char buf[1024]; va_list args; + int r; - if (compat20 && (datafellows & SSH_BUG_DEBUG)) + if (compat20 && (ssh->compat & SSH_BUG_DEBUG)) return; va_start(args, fmt); @@ -1669,16 +1886,41 @@ packet_send_debug(const char *fmt,...) va_end(args); if (compat20) { - packet_start(SSH2_MSG_DEBUG); - packet_put_char(0); /* bool: always display */ - packet_put_cstring(buf); - packet_put_cstring(""); + if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 || + (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */ + (r = sshpkt_put_cstring(ssh, buf)) != 0 || + (r = sshpkt_put_cstring(ssh, "")) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); } else { - packet_start(SSH_MSG_DEBUG); - packet_put_cstring(buf); + if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 || + (r = sshpkt_put_cstring(ssh, buf)) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + } + if ((r = ssh_packet_write_wait(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); +} + +/* + * Pretty-print connection-terminating errors and exit. + */ +void +sshpkt_fatal(struct ssh *ssh, const char *tag, int r) +{ + switch (r) { + case SSH_ERR_CONN_CLOSED: + logit("Connection closed by %.200s", ssh_remote_ipaddr(ssh)); + cleanup_exit(255); + case SSH_ERR_CONN_TIMEOUT: + logit("Connection to %.200s timed out while " + "waiting to write", ssh_remote_ipaddr(ssh)); + cleanup_exit(255); + default: + fatal("%s%sConnection to %.200s: %s", + tag != NULL ? tag : "", tag != NULL ? ": " : "", + ssh_remote_ipaddr(ssh), ssh_err(r)); } - packet_send(); - packet_write_wait(); } /* @@ -1687,13 +1929,13 @@ packet_send_debug(const char *fmt,...) * should not contain a newline. The length of the formatted message must * not exceed 1024 bytes. */ - void -packet_disconnect(const char *fmt,...) +ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) { char buf[1024]; va_list args; static int disconnecting = 0; + int r; if (disconnecting) /* Guard against recursive invocations. */ fatal("packet_disconnect called recursively."); @@ -1710,87 +1952,88 @@ packet_disconnect(const char *fmt,...) /* Display the error locally */ logit("Disconnecting: %.100s", buf); - /* Send the disconnect message to the other side, and wait for it to get sent. */ - if (compat20) { - packet_start(SSH2_MSG_DISCONNECT); - packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); - packet_put_cstring(buf); - packet_put_cstring(""); - } else { - packet_start(SSH_MSG_DISCONNECT); - packet_put_cstring(buf); - } - packet_send(); - packet_write_wait(); + /* + * Send the disconnect message to the other side, and wait + * for it to get sent. + */ + if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0) + sshpkt_fatal(ssh, __func__, r); - /* Stop listening for connections. */ - channel_close_all(); + if ((r = ssh_packet_write_wait(ssh)) != 0) + sshpkt_fatal(ssh, __func__, r); /* Close the connection. */ - packet_close(); + ssh_packet_close(ssh); cleanup_exit(255); } -/* Checks if there is any buffered output, and tries to write some of the output. */ - -void -packet_write_poll(void) +/* + * Checks if there is any buffered output, and tries to write some of + * the output. + */ +int +ssh_packet_write_poll(struct ssh *ssh) { - int len = buffer_len(&active_state->output); - int cont; + struct session_state *state = ssh->state; + int len = sshbuf_len(state->output); + int cont, r; if (len > 0) { cont = 0; - len = roaming_write(active_state->connection_out, - buffer_ptr(&active_state->output), len, &cont); + len = roaming_write(state->connection_out, + sshbuf_ptr(state->output), len, &cont); if (len == -1) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) - return; - fatal("Write failed: %.100s", strerror(errno)); + return 0; + return SSH_ERR_SYSTEM_ERROR; } if (len == 0 && !cont) - fatal("Write connection closed"); - buffer_consume(&active_state->output, len); + return SSH_ERR_CONN_CLOSED; + if ((r = sshbuf_consume(state->output, len)) != 0) + return r; } + return 0; } /* * Calls packet_write_poll repeatedly until all pending output data has been * written. */ - -void -packet_write_wait(void) +int +ssh_packet_write_wait(struct ssh *ssh) { fd_set *setp; - int ret, ms_remain = 0; + int ret, r, ms_remain = 0; struct timeval start, timeout, *timeoutp = NULL; + struct session_state *state = ssh->state; - setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, + setp = (fd_set *)calloc(howmany(state->connection_out + 1, NFDBITS), sizeof(fd_mask)); - packet_write_poll(); - while (packet_have_data_to_write()) { - memset(setp, 0, howmany(active_state->connection_out + 1, + if (setp == NULL) + return SSH_ERR_ALLOC_FAIL; + ssh_packet_write_poll(ssh); + while (ssh_packet_have_data_to_write(ssh)) { + memset(setp, 0, howmany(state->connection_out + 1, NFDBITS) * sizeof(fd_mask)); - FD_SET(active_state->connection_out, setp); + FD_SET(state->connection_out, setp); - if (active_state->packet_timeout_ms > 0) { - ms_remain = active_state->packet_timeout_ms; + if (state->packet_timeout_ms > 0) { + ms_remain = state->packet_timeout_ms; timeoutp = &timeout; } for (;;) { - if (active_state->packet_timeout_ms != -1) { + if (state->packet_timeout_ms != -1) { ms_to_timeval(&timeout, ms_remain); gettimeofday(&start, NULL); } - if ((ret = select(active_state->connection_out + 1, + if ((ret = select(state->connection_out + 1, NULL, setp, NULL, timeoutp)) >= 0) break; if (errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) break; - if (active_state->packet_timeout_ms == -1) + if (state->packet_timeout_ms == -1) continue; ms_subtract_diff(&start, &ms_remain); if (ms_remain <= 0) { @@ -1799,45 +2042,48 @@ packet_write_wait(void) } } if (ret == 0) { - logit("Connection to %.200s timed out while " - "waiting to write", get_remote_ipaddr()); - cleanup_exit(255); + free(setp); + return SSH_ERR_CONN_TIMEOUT; + } + if ((r = ssh_packet_write_poll(ssh)) != 0) { + free(setp); + return r; } - packet_write_poll(); } free(setp); + return 0; } /* Returns true if there is buffered data to write to the connection. */ int -packet_have_data_to_write(void) +ssh_packet_have_data_to_write(struct ssh *ssh) { - return buffer_len(&active_state->output) != 0; + return sshbuf_len(ssh->state->output) != 0; } /* Returns true if there is not too much data to write to the connection. */ int -packet_not_very_much_data_to_write(void) +ssh_packet_not_very_much_data_to_write(struct ssh *ssh) { - if (active_state->interactive_mode) - return buffer_len(&active_state->output) < 16384; + if (ssh->state->interactive_mode) + return sshbuf_len(ssh->state->output) < 16384; else - return buffer_len(&active_state->output) < 128 * 1024; + return sshbuf_len(ssh->state->output) < 128 * 1024; } -static void -packet_set_tos(int tos) +void +ssh_packet_set_tos(struct ssh *ssh, int tos) { #ifndef IP_TOS_IS_BROKEN - if (!packet_connection_is_on_socket()) + if (!ssh_packet_connection_is_on_socket(ssh)) return; - switch (packet_connection_af()) { + switch (ssh_packet_connection_af(ssh)) { # ifdef IP_TOS case AF_INET: debug3("%s: set IP_TOS 0x%02x", __func__, tos); - if (setsockopt(active_state->connection_in, + if (setsockopt(ssh->state->connection_in, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) error("setsockopt IP_TOS %d: %.100s:", tos, strerror(errno)); @@ -1846,7 +2092,7 @@ packet_set_tos(int tos) # ifdef IPV6_TCLASS case AF_INET6: debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos); - if (setsockopt(active_state->connection_in, + if (setsockopt(ssh->state->connection_in, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0) error("setsockopt IPV6_TCLASS %d: %.100s:", tos, strerror(errno)); @@ -1859,71 +2105,69 @@ packet_set_tos(int tos) /* Informs that the current session is interactive. Sets IP flags for that. */ void -packet_set_interactive(int interactive, int qos_interactive, int qos_bulk) +ssh_packet_set_interactive(struct ssh *ssh, int interactive, int qos_interactive, int qos_bulk) { - if (active_state->set_interactive_called) + struct session_state *state = ssh->state; + + if (state->set_interactive_called) return; - active_state->set_interactive_called = 1; + state->set_interactive_called = 1; /* Record that we are in interactive mode. */ - active_state->interactive_mode = interactive; + state->interactive_mode = interactive; /* Only set socket options if using a socket. */ - if (!packet_connection_is_on_socket()) + if (!ssh_packet_connection_is_on_socket(ssh)) return; - set_nodelay(active_state->connection_in); - packet_set_tos(interactive ? qos_interactive : qos_bulk); + set_nodelay(state->connection_in); + ssh_packet_set_tos(ssh, interactive ? qos_interactive : + qos_bulk); } /* Returns true if the current connection is interactive. */ int -packet_is_interactive(void) +ssh_packet_is_interactive(struct ssh *ssh) { - return active_state->interactive_mode; + return ssh->state->interactive_mode; } int -packet_set_maxsize(u_int s) +ssh_packet_set_maxsize(struct ssh *ssh, u_int s) { - if (active_state->set_maxsize_called) { + struct session_state *state = ssh->state; + + if (state->set_maxsize_called) { logit("packet_set_maxsize: called twice: old %d new %d", - active_state->max_packet_size, s); + state->max_packet_size, s); return -1; } if (s < 4 * 1024 || s > 1024 * 1024) { logit("packet_set_maxsize: bad size %d", s); return -1; } - active_state->set_maxsize_called = 1; + state->set_maxsize_called = 1; debug("packet_set_maxsize: setting to %d", s); - active_state->max_packet_size = s; + state->max_packet_size = s; return s; } int -packet_inc_alive_timeouts(void) +ssh_packet_inc_alive_timeouts(struct ssh *ssh) { - return ++active_state->keep_alive_timeouts; + return ++ssh->state->keep_alive_timeouts; } void -packet_set_alive_timeouts(int ka) +ssh_packet_set_alive_timeouts(struct ssh *ssh, int ka) { - active_state->keep_alive_timeouts = ka; + ssh->state->keep_alive_timeouts = ka; } u_int -packet_get_maxsize(void) +ssh_packet_get_maxsize(struct ssh *ssh) { - return active_state->max_packet_size; -} - -/* roundup current message to pad bytes */ -void -packet_add_padding(u_char pad) -{ - active_state->extra_pad = pad; + return ssh->state->max_packet_size; } /* @@ -1938,155 +2182,718 @@ packet_add_padding(u_char pad) * protection measure against advanced traffic analysis techniques. */ void -packet_send_ignore(int nbytes) +ssh_packet_send_ignore(struct ssh *ssh, int nbytes) { u_int32_t rnd = 0; - int i; + int r, i; - packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); - packet_put_int(nbytes); + if ((r = sshpkt_start(ssh, compat20 ? + SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 || + (r = sshpkt_put_u32(ssh, nbytes)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); for (i = 0; i < nbytes; i++) { if (i % 4 == 0) rnd = arc4random(); - packet_put_char((u_char)rnd & 0xff); + if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); rnd >>= 8; } } #define MAX_PACKETS (1U<<31) int -packet_need_rekeying(void) +ssh_packet_need_rekeying(struct ssh *ssh) { - if (datafellows & SSH_BUG_NOREKEY) + struct session_state *state = ssh->state; + + if (ssh->compat & SSH_BUG_NOREKEY) return 0; return - (active_state->p_send.packets > MAX_PACKETS) || - (active_state->p_read.packets > MAX_PACKETS) || - (active_state->max_blocks_out && - (active_state->p_send.blocks > active_state->max_blocks_out)) || - (active_state->max_blocks_in && - (active_state->p_read.blocks > active_state->max_blocks_in)) || - (active_state->rekey_interval != 0 && active_state->rekey_time + - active_state->rekey_interval <= monotime()); + (state->p_send.packets > MAX_PACKETS) || + (state->p_read.packets > MAX_PACKETS) || + (state->max_blocks_out && + (state->p_send.blocks > state->max_blocks_out)) || + (state->max_blocks_in && + (state->p_read.blocks > state->max_blocks_in)) || + (state->rekey_interval != 0 && state->rekey_time + + state->rekey_interval <= monotime()); } void -packet_set_rekey_limits(u_int32_t bytes, time_t seconds) +ssh_packet_set_rekey_limits(struct ssh *ssh, u_int32_t bytes, time_t seconds) { debug3("rekey after %lld bytes, %d seconds", (long long)bytes, (int)seconds); - active_state->rekey_limit = bytes; - active_state->rekey_interval = seconds; - /* - * We set the time here so that in post-auth privsep slave we count - * from the completion of the authentication. - */ - active_state->rekey_time = monotime(); + ssh->state->rekey_limit = bytes; + ssh->state->rekey_interval = seconds; } time_t -packet_get_rekey_timeout(void) +ssh_packet_get_rekey_timeout(struct ssh *ssh) { time_t seconds; - seconds = active_state->rekey_time + active_state->rekey_interval - + seconds = ssh->state->rekey_time + ssh->state->rekey_interval - monotime(); return (seconds <= 0 ? 1 : seconds); } void -packet_set_server(void) +ssh_packet_set_server(struct ssh *ssh) { - active_state->server_side = 1; + ssh->state->server_side = 1; } void -packet_set_authenticated(void) +ssh_packet_set_authenticated(struct ssh *ssh) { - active_state->after_authentication = 1; + ssh->state->after_authentication = 1; } void * -packet_get_input(void) +ssh_packet_get_input(struct ssh *ssh) { - return (void *)&active_state->input; + return (void *)ssh->state->input; } void * -packet_get_output(void) +ssh_packet_get_output(struct ssh *ssh) { - return (void *)&active_state->output; -} - -void * -packet_get_newkeys(int mode) -{ - return (void *)active_state->newkeys[mode]; + return (void *)ssh->state->output; } +/* XXX TODO update roaming to new API (does not work anyway) */ /* * Save the state for the real connection, and use a separate state when * resuming a suspended connection. */ void -packet_backup_state(void) +ssh_packet_backup_state(struct ssh *ssh, + struct ssh *backup_state) { - struct session_state *tmp; + struct ssh *tmp; - close(active_state->connection_in); - active_state->connection_in = -1; - close(active_state->connection_out); - active_state->connection_out = -1; + close(ssh->state->connection_in); + ssh->state->connection_in = -1; + close(ssh->state->connection_out); + ssh->state->connection_out = -1; if (backup_state) tmp = backup_state; else - tmp = alloc_session_state(); - backup_state = active_state; - active_state = tmp; + tmp = ssh_alloc_session_state(); + backup_state = ssh; + ssh = tmp; } +/* XXX FIXME FIXME FIXME */ /* * Swap in the old state when resuming a connecion. */ void -packet_restore_state(void) +ssh_packet_restore_state(struct ssh *ssh, + struct ssh *backup_state) { - struct session_state *tmp; - void *buf; + struct ssh *tmp; u_int len; + int r; tmp = backup_state; - backup_state = active_state; - active_state = tmp; - active_state->connection_in = backup_state->connection_in; - backup_state->connection_in = -1; - active_state->connection_out = backup_state->connection_out; - backup_state->connection_out = -1; - len = buffer_len(&backup_state->input); + backup_state = ssh; + ssh = tmp; + ssh->state->connection_in = backup_state->state->connection_in; + backup_state->state->connection_in = -1; + ssh->state->connection_out = backup_state->state->connection_out; + backup_state->state->connection_out = -1; + len = sshbuf_len(backup_state->state->input); if (len > 0) { - buf = buffer_ptr(&backup_state->input); - buffer_append(&active_state->input, buf, len); - buffer_clear(&backup_state->input); + if ((r = sshbuf_putb(ssh->state->input, + backup_state->state->input)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); + sshbuf_reset(backup_state->state->input); add_recv_bytes(len); } } /* Reset after_authentication and reset compression in post-auth privsep */ -void -packet_set_postauth(void) +static int +ssh_packet_set_postauth(struct ssh *ssh) { - Comp *comp; - int mode; + struct sshcomp *comp; + int r, mode; debug("%s: called", __func__); /* This was set in net child, but is not visible in user child */ - active_state->after_authentication = 1; - active_state->rekeying = 0; + ssh->state->after_authentication = 1; + ssh->state->rekeying = 0; for (mode = 0; mode < MODE_MAX; mode++) { - if (active_state->newkeys[mode] == NULL) + if (ssh->state->newkeys[mode] == NULL) continue; - comp = &active_state->newkeys[mode]->comp; - if (comp && comp->enabled) - packet_init_compression(); + comp = &ssh->state->newkeys[mode]->comp; + if (comp && comp->enabled && + (r = ssh_packet_init_compression(ssh)) != 0) + return r; } + return 0; +} + +/* Packet state (de-)serialization for privsep */ + +/* turn kex into a blob for packet state serialization */ +static int +kex_to_blob(struct sshbuf *m, struct kex *kex) +{ + int r; + + if ((r = sshbuf_put_string(m, kex->session_id, + kex->session_id_len)) != 0 || + (r = sshbuf_put_u32(m, kex->we_need)) != 0 || + (r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 || + (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || + (r = sshbuf_put_stringb(m, kex->my)) != 0 || + (r = sshbuf_put_stringb(m, kex->peer)) != 0 || + (r = sshbuf_put_u32(m, kex->flags)) != 0 || + (r = sshbuf_put_cstring(m, kex->client_version_string)) != 0 || + (r = sshbuf_put_cstring(m, kex->server_version_string)) != 0) + return r; + return 0; +} + +/* turn key exchange results into a blob for packet state serialization */ +static int +newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) +{ + struct sshbuf *b; + struct sshcipher_ctx *cc; + struct sshcomp *comp; + struct sshenc *enc; + struct sshmac *mac; + struct newkeys *newkey; + int r; + + if ((newkey = ssh->state->newkeys[mode]) == NULL) + return SSH_ERR_INTERNAL_ERROR; + enc = &newkey->enc; + mac = &newkey->mac; + comp = &newkey->comp; + cc = (mode == MODE_OUT) ? &ssh->state->send_context : + &ssh->state->receive_context; + if ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0) + return r; + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + /* The cipher struct is constant and shared, you export pointer */ + if ((r = sshbuf_put_cstring(b, enc->name)) != 0 || + (r = sshbuf_put(b, &enc->cipher, sizeof(enc->cipher))) != 0 || + (r = sshbuf_put_u32(b, enc->enabled)) != 0 || + (r = sshbuf_put_u32(b, enc->block_size)) != 0 || + (r = sshbuf_put_string(b, enc->key, enc->key_len)) != 0 || + (r = sshbuf_put_string(b, enc->iv, enc->iv_len)) != 0) + goto out; + if (cipher_authlen(enc->cipher) == 0) { + if ((r = sshbuf_put_cstring(b, mac->name)) != 0 || + (r = sshbuf_put_u32(b, mac->enabled)) != 0 || + (r = sshbuf_put_string(b, mac->key, mac->key_len)) != 0) + goto out; + } + if ((r = sshbuf_put_u32(b, comp->type)) != 0 || + (r = sshbuf_put_u32(b, comp->enabled)) != 0 || + (r = sshbuf_put_cstring(b, comp->name)) != 0) + goto out; + r = sshbuf_put_stringb(m, b); + out: + if (b != NULL) + sshbuf_free(b); + return r; +} + +/* serialize packet state into a blob */ +int +ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) +{ + struct session_state *state = ssh->state; + u_char *p; + size_t slen, rlen; + int r, ssh1cipher; + + if (!compat20) { + ssh1cipher = cipher_get_number(state->receive_context.cipher); + slen = cipher_get_keyiv_len(&state->send_context); + rlen = cipher_get_keyiv_len(&state->receive_context); + if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || + (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || + (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || + (r = sshbuf_put_u32(m, slen)) != 0 || + (r = sshbuf_reserve(m, slen, &p)) != 0 || + (r = cipher_get_keyiv(&state->send_context, p, slen)) != 0 || + (r = sshbuf_put_u32(m, rlen)) != 0 || + (r = sshbuf_reserve(m, rlen, &p)) != 0 || + (r = cipher_get_keyiv(&state->receive_context, p, rlen)) != 0) + return r; + } else { + if ((r = kex_to_blob(m, ssh->kex)) != 0 || + (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || + (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || + (r = sshbuf_put_u32(m, state->rekey_limit)) != 0 || + (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 || + (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 || + (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 || + (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 || + (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 || + (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 || + (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 || + (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || + (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0) + return r; + } + + slen = cipher_get_keycontext(&state->send_context, NULL); + rlen = cipher_get_keycontext(&state->receive_context, NULL); + if ((r = sshbuf_put_u32(m, slen)) != 0 || + (r = sshbuf_reserve(m, slen, &p)) != 0) + return r; + if (cipher_get_keycontext(&state->send_context, p) != (int)slen) + return SSH_ERR_INTERNAL_ERROR; + if ((r = sshbuf_put_u32(m, rlen)) != 0 || + (r = sshbuf_reserve(m, rlen, &p)) != 0) + return r; + if (cipher_get_keycontext(&state->receive_context, p) != (int)rlen) + return SSH_ERR_INTERNAL_ERROR; + + if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || + (r = sshbuf_put_stringb(m, state->input)) != 0 || + (r = sshbuf_put_stringb(m, state->output)) != 0) + return r; + + if (compat20) { + if ((r = sshbuf_put_u64(m, get_sent_bytes())) != 0 || + (r = sshbuf_put_u64(m, get_recv_bytes())) != 0) + return r; + } + return 0; +} + +/* restore key exchange results from blob for packet state de-serialization */ +static int +newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode) +{ + struct sshbuf *b = NULL; + struct sshcomp *comp; + struct sshenc *enc; + struct sshmac *mac; + struct newkeys *newkey = NULL; + size_t keylen, ivlen, maclen; + int r; + + if ((newkey = calloc(1, sizeof(*newkey))) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_froms(m, &b)) != 0) + goto out; +#ifdef DEBUG_PK + sshbuf_dump(b, stderr); +#endif + enc = &newkey->enc; + mac = &newkey->mac; + comp = &newkey->comp; + + if ((r = sshbuf_get_cstring(b, &enc->name, NULL)) != 0 || + (r = sshbuf_get(b, &enc->cipher, sizeof(enc->cipher))) != 0 || + (r = sshbuf_get_u32(b, (u_int *)&enc->enabled)) != 0 || + (r = sshbuf_get_u32(b, &enc->block_size)) != 0 || + (r = sshbuf_get_string(b, &enc->key, &keylen)) != 0 || + (r = sshbuf_get_string(b, &enc->iv, &ivlen)) != 0) + goto out; + if (cipher_authlen(enc->cipher) == 0) { + if ((r = sshbuf_get_cstring(b, &mac->name, NULL)) != 0) + goto out; + if ((r = mac_setup(mac, mac->name)) != 0) + goto out; + if ((r = sshbuf_get_u32(b, (u_int *)&mac->enabled)) != 0 || + (r = sshbuf_get_string(b, &mac->key, &maclen)) != 0) + goto out; + if (maclen > mac->key_len) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + mac->key_len = maclen; + } + if ((r = sshbuf_get_u32(b, &comp->type)) != 0 || + (r = sshbuf_get_u32(b, (u_int *)&comp->enabled)) != 0 || + (r = sshbuf_get_cstring(b, &comp->name, NULL)) != 0) + goto out; + if (enc->name == NULL || + cipher_by_name(enc->name) != enc->cipher) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if (sshbuf_len(b) != 0) { + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + enc->key_len = keylen; + enc->iv_len = ivlen; + ssh->kex->newkeys[mode] = newkey; + newkey = NULL; + r = 0; + out: + if (newkey != NULL) + free(newkey); + if (b != NULL) + sshbuf_free(b); + return r; +} + +/* restore kex from blob for packet state de-serialization */ +static int +kex_from_blob(struct sshbuf *m, struct kex **kexp) +{ + struct kex *kex; + int r; + + if ((kex = calloc(1, sizeof(struct kex))) == NULL || + (kex->my = sshbuf_new()) == NULL || + (kex->peer = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 || + (r = sshbuf_get_u32(m, &kex->we_need)) != 0 || + (r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 || + (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || + (r = sshbuf_get_stringb(m, kex->my)) != 0 || + (r = sshbuf_get_stringb(m, kex->peer)) != 0 || + (r = sshbuf_get_u32(m, &kex->flags)) != 0 || + (r = sshbuf_get_cstring(m, &kex->client_version_string, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &kex->server_version_string, NULL)) != 0) + goto out; + kex->server = 1; + kex->done = 1; + r = 0; + out: + if (r != 0 || kexp == NULL) { + if (kex != NULL) { + if (kex->my != NULL) + sshbuf_free(kex->my); + if (kex->peer != NULL) + sshbuf_free(kex->peer); + free(kex); + } + if (kexp != NULL) + *kexp = NULL; + } else { + *kexp = kex; + } + return r; +} + +/* + * Restore packet state from content of blob 'm' (de-serialization). + * Note that 'm' will be partially consumed on parsing or any other errors. + */ +int +ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) +{ + struct session_state *state = ssh->state; + const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output; + size_t ssh1keylen, rlen, slen, ilen, olen; + int r; + u_int ssh1cipher = 0; + u_int64_t sent_bytes = 0, recv_bytes = 0; + + if (!compat20) { + if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || + (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 || + (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 || + (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 || + (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0) + return r; + if (ssh1cipher > INT_MAX) + return SSH_ERR_KEY_UNKNOWN_CIPHER; + ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, + (int)ssh1cipher); + if (cipher_get_keyiv_len(&state->send_context) != (int)slen || + cipher_get_keyiv_len(&state->receive_context) != (int)rlen) + return SSH_ERR_INVALID_FORMAT; + if ((r = cipher_set_keyiv(&state->send_context, ivout)) != 0 || + (r = cipher_set_keyiv(&state->receive_context, ivin)) != 0) + return r; + } else { + if ((r = kex_from_blob(m, &ssh->kex)) != 0 || + (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || + (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || + (r = sshbuf_get_u32(m, &state->rekey_limit)) != 0 || + (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || + (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 || + (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 || + (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 || + (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 || + (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 || + (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 || + (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 || + (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0) + return r; + /* + * We set the time here so that in post-auth privsep slave we + * count from the completion of the authentication. + */ + state->rekey_time = monotime(); + /* XXX ssh_set_newkeys overrides p_read.packets? XXX */ + if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 || + (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0) + return r; + } + if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || + (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) + return r; + if (cipher_get_keycontext(&state->send_context, NULL) != (int)slen || + cipher_get_keycontext(&state->receive_context, NULL) != (int)rlen) + return SSH_ERR_INVALID_FORMAT; + cipher_set_keycontext(&state->send_context, keyout); + cipher_set_keycontext(&state->receive_context, keyin); + + if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || + (r = ssh_packet_set_postauth(ssh)) != 0) + return r; + + sshbuf_reset(state->input); + sshbuf_reset(state->output); + if ((r = sshbuf_get_string_direct(m, &input, &ilen)) != 0 || + (r = sshbuf_get_string_direct(m, &output, &olen)) != 0 || + (r = sshbuf_put(state->input, input, ilen)) != 0 || + (r = sshbuf_put(state->output, output, olen)) != 0) + return r; + + if (compat20) { + if ((r = sshbuf_get_u64(m, &sent_bytes)) != 0 || + (r = sshbuf_get_u64(m, &recv_bytes)) != 0) + return r; + roam_set_bytes(sent_bytes, recv_bytes); + } + if (sshbuf_len(m)) + return SSH_ERR_INVALID_FORMAT; + debug3("%s: done", __func__); + return 0; +} + +/* NEW API */ + +/* put data to the outgoing packet */ + +int +sshpkt_put(struct ssh *ssh, const void *v, size_t len) +{ + return sshbuf_put(ssh->state->outgoing_packet, v, len); +} + +int +sshpkt_putb(struct ssh *ssh, const struct sshbuf *b) +{ + return sshbuf_putb(ssh->state->outgoing_packet, b); +} + +int +sshpkt_put_u8(struct ssh *ssh, u_char val) +{ + return sshbuf_put_u8(ssh->state->outgoing_packet, val); +} + +int +sshpkt_put_u32(struct ssh *ssh, u_int32_t val) +{ + return sshbuf_put_u32(ssh->state->outgoing_packet, val); +} + +int +sshpkt_put_u64(struct ssh *ssh, u_int64_t val) +{ + return sshbuf_put_u64(ssh->state->outgoing_packet, val); +} + +int +sshpkt_put_string(struct ssh *ssh, const void *v, size_t len) +{ + return sshbuf_put_string(ssh->state->outgoing_packet, v, len); +} + +int +sshpkt_put_cstring(struct ssh *ssh, const void *v) +{ + return sshbuf_put_cstring(ssh->state->outgoing_packet, v); +} + +int +sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v) +{ + return sshbuf_put_stringb(ssh->state->outgoing_packet, v); +} + +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) +int +sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g) +{ + return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); +} +#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ + +#ifdef WITH_SSH1 +int +sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v) +{ + return sshbuf_put_bignum1(ssh->state->outgoing_packet, v); +} +#endif /* WITH_SSH1 */ + +#ifdef WITH_OPENSSL +int +sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) +{ + return sshbuf_put_bignum2(ssh->state->outgoing_packet, v); +} +#endif /* WITH_OPENSSL */ + +/* fetch data from the incoming packet */ + +int +sshpkt_get(struct ssh *ssh, void *valp, size_t len) +{ + return sshbuf_get(ssh->state->incoming_packet, valp, len); +} + +int +sshpkt_get_u8(struct ssh *ssh, u_char *valp) +{ + return sshbuf_get_u8(ssh->state->incoming_packet, valp); +} + +int +sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp) +{ + return sshbuf_get_u32(ssh->state->incoming_packet, valp); +} + +int +sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp) +{ + return sshbuf_get_u64(ssh->state->incoming_packet, valp); +} + +int +sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp) +{ + return sshbuf_get_string(ssh->state->incoming_packet, valp, lenp); +} + +int +sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp) +{ + return sshbuf_get_string_direct(ssh->state->incoming_packet, valp, lenp); +} + +int +sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) +{ + return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); +} + +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) +int +sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g) +{ + return sshbuf_get_ec(ssh->state->incoming_packet, v, g); +} +#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ + +#ifdef WITH_SSH1 +int +sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v) +{ + return sshbuf_get_bignum1(ssh->state->incoming_packet, v); +} +#endif /* WITH_SSH1 */ + +#ifdef WITH_OPENSSL +int +sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) +{ + return sshbuf_get_bignum2(ssh->state->incoming_packet, v); +} +#endif /* WITH_OPENSSL */ + +int +sshpkt_get_end(struct ssh *ssh) +{ + if (sshbuf_len(ssh->state->incoming_packet) > 0) + return SSH_ERR_UNEXPECTED_TRAILING_DATA; + return 0; +} + +const u_char * +sshpkt_ptr(struct ssh *ssh, size_t *lenp) +{ + if (lenp != NULL) + *lenp = sshbuf_len(ssh->state->incoming_packet); + return sshbuf_ptr(ssh->state->incoming_packet); +} + +/* start a new packet */ + +int +sshpkt_start(struct ssh *ssh, u_char type) +{ + u_char buf[9]; + int len; + + DBG(debug("packet_start[%d]", type)); + len = compat20 ? 6 : 9; + memset(buf, 0, len - 1); + buf[len - 1] = type; + sshbuf_reset(ssh->state->outgoing_packet); + return sshbuf_put(ssh->state->outgoing_packet, buf, len); +} + +/* send it */ + +int +sshpkt_send(struct ssh *ssh) +{ + if (compat20) + return ssh_packet_send2(ssh); + else + return ssh_packet_send1(ssh); +} + +int +sshpkt_disconnect(struct ssh *ssh, const char *fmt,...) +{ + char buf[1024]; + va_list args; + int r; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + if (compat20) { + if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || + (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || + (r = sshpkt_put_cstring(ssh, buf)) != 0 || + (r = sshpkt_put_cstring(ssh, "")) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; + } else { + if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 || + (r = sshpkt_put_cstring(ssh, buf)) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; + } + return 0; +} + +/* roundup current message to pad bytes */ +int +sshpkt_add_padding(struct ssh *ssh, u_char pad) +{ + ssh->state->extra_pad = pad; + return 0; } diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h index e7b5fcba9fb0..7b06544e8370 100644 --- a/crypto/openssh/packet.h +++ b/crypto/openssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.61 2014/05/03 17:20:34 markus Exp $ */ +/* $OpenBSD: packet.h,v 1.66 2015/01/30 01:13:33 djm Exp $ */ /* * Author: Tatu Ylonen @@ -18,111 +18,189 @@ #include -#include -#ifdef OPENSSL_HAS_ECC -#include -#endif +#ifdef WITH_OPENSSL +# include +# ifdef OPENSSL_HAS_ECC +# include +# else /* OPENSSL_HAS_ECC */ +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +# endif /* OPENSSL_HAS_ECC */ +#else /* WITH_OPENSSL */ +# define BIGNUM void +# define EC_KEY void +# define EC_GROUP void +# define EC_POINT void +#endif /* WITH_OPENSSL */ -void packet_set_connection(int, int); -void packet_set_timeout(int, int); -void packet_set_nonblocking(void); -int packet_get_connection_in(void); -int packet_get_connection_out(void); -void packet_close(void); -void packet_set_encryption_key(const u_char *, u_int, int); -u_int packet_get_encryption_key(u_char *); -void packet_set_protocol_flags(u_int); -u_int packet_get_protocol_flags(void); -void packet_start_compression(int); -void packet_set_interactive(int, int, int); -int packet_is_interactive(void); -void packet_set_server(void); -void packet_set_authenticated(void); +#include +#include "openbsd-compat/sys-queue.h" -void packet_start(u_char); -void packet_put_char(int ch); -void packet_put_int(u_int value); -void packet_put_int64(u_int64_t value); -void packet_put_bignum(BIGNUM * value); -void packet_put_bignum2(BIGNUM * value); -#ifdef OPENSSL_HAS_ECC -void packet_put_ecpoint(const EC_GROUP *, const EC_POINT *); -#endif -void packet_put_string(const void *buf, u_int len); -void packet_put_cstring(const char *str); -void packet_put_raw(const void *buf, u_int len); -void packet_send(void); +struct kex; +struct sshkey; +struct sshbuf; +struct session_state; /* private session data */ -int packet_read(void); -void packet_read_expect(int type); -void packet_process_incoming(const char *buf, u_int len); -int packet_read_seqnr(u_int32_t *seqnr_p); -int packet_read_poll_seqnr(u_int32_t *seqnr_p); +#include "dispatch.h" /* typedef, DISPATCH_MAX */ -u_int packet_get_char(void); -u_int packet_get_int(void); -u_int64_t packet_get_int64(void); -void packet_get_bignum(BIGNUM * value); -void packet_get_bignum2(BIGNUM * value); -#ifdef OPENSSL_HAS_ECC -void packet_get_ecpoint(const EC_GROUP *, EC_POINT *); -#endif -void *packet_get_raw(u_int *length_ptr); -void *packet_get_string(u_int *length_ptr); -char *packet_get_cstring(u_int *length_ptr); -const void *packet_get_string_ptr(u_int *length_ptr); -void packet_disconnect(const char *fmt,...) __attribute__((noreturn)) __attribute__((format(printf, 1, 2))); -void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); +struct key_entry { + TAILQ_ENTRY(key_entry) next; + struct sshkey *key; +}; -void set_newkeys(int mode); -int packet_get_keyiv_len(int); -void packet_get_keyiv(int, u_char *, u_int); -int packet_get_keycontext(int, u_char *); -void packet_set_keycontext(int, u_char *); -void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *, u_int64_t *); -void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t); -int packet_get_ssh1_cipher(void); -void packet_set_iv(int, u_char *); -void *packet_get_newkeys(int); +struct ssh { + /* Session state */ + struct session_state *state; -void packet_write_poll(void); -void packet_write_wait(void); -int packet_have_data_to_write(void); -int packet_not_very_much_data_to_write(void); + /* Key exchange */ + struct kex *kex; -int packet_connection_is_on_socket(void); -int packet_remaining(void); -void packet_send_ignore(int); -void packet_add_padding(u_char); + /* cached remote ip address and port*/ + char *remote_ipaddr; + int remote_port; + + /* Dispatcher table */ + dispatch_fn *dispatch[DISPATCH_MAX]; + /* number of packets to ignore in the dispatcher */ + int dispatch_skip_packets; + + /* datafellows */ + int compat; + + /* Lists for private and public keys */ + TAILQ_HEAD(, key_entry) private_keys; + TAILQ_HEAD(, key_entry) public_keys; + + /* APP data */ + void *app_data; +}; + +struct ssh *ssh_alloc_session_state(void); +struct ssh *ssh_packet_set_connection(struct ssh *, int, int); +void ssh_packet_set_timeout(struct ssh *, int, int); +int ssh_packet_stop_discard(struct ssh *); +int ssh_packet_connection_af(struct ssh *); +void ssh_packet_set_nonblocking(struct ssh *); +int ssh_packet_get_connection_in(struct ssh *); +int ssh_packet_get_connection_out(struct ssh *); +void ssh_packet_close(struct ssh *); +void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int); +void ssh_packet_set_protocol_flags(struct ssh *, u_int); +u_int ssh_packet_get_protocol_flags(struct ssh *); +int ssh_packet_start_compression(struct ssh *, int); +void ssh_packet_set_tos(struct ssh *, int); +void ssh_packet_set_interactive(struct ssh *, int, int, int); +int ssh_packet_is_interactive(struct ssh *); +void ssh_packet_set_server(struct ssh *); +void ssh_packet_set_authenticated(struct ssh *); + +int ssh_packet_send1(struct ssh *); +int ssh_packet_send2_wrapped(struct ssh *); +int ssh_packet_send2(struct ssh *); + +int ssh_packet_read(struct ssh *); +int ssh_packet_read_expect(struct ssh *, u_int type); +int ssh_packet_read_poll(struct ssh *); +int ssh_packet_read_poll1(struct ssh *, u_char *); +int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); +int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); +int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); +int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); + +const void *ssh_packet_get_string_ptr(struct ssh *, u_int *length_ptr); +void ssh_packet_disconnect(struct ssh *, const char *fmt, ...) + __attribute__((format(printf, 2, 3))) + __attribute__((noreturn)); +void ssh_packet_send_debug(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))); + +int ssh_set_newkeys(struct ssh *, int mode); +void ssh_packet_get_bytes(struct ssh *, u_int64_t *, u_int64_t *); + +typedef void *(ssh_packet_comp_alloc_func)(void *, u_int, u_int); +typedef void (ssh_packet_comp_free_func)(void *, void *); +void ssh_packet_set_compress_hooks(struct ssh *, void *, + ssh_packet_comp_alloc_func *, ssh_packet_comp_free_func *); + +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_connection_is_on_socket(struct ssh *); +int ssh_packet_remaining(struct ssh *); +void ssh_packet_send_ignore(struct ssh *, int); void tty_make_modes(int, struct termios *); void tty_parse_modes(int, int *); -void packet_set_alive_timeouts(int); -int packet_inc_alive_timeouts(void); -int packet_set_maxsize(u_int); -u_int packet_get_maxsize(void); +void ssh_packet_set_alive_timeouts(struct ssh *, int); +int ssh_packet_inc_alive_timeouts(struct ssh *); +int ssh_packet_set_maxsize(struct ssh *, u_int); +u_int ssh_packet_get_maxsize(struct ssh *); -/* don't allow remaining bytes after the end of the message */ -#define packet_check_eom() \ -do { \ - int _len = packet_remaining(); \ - if (_len > 0) { \ - logit("Packet integrity error (%d bytes remaining) at %s:%d", \ - _len ,__FILE__, __LINE__); \ - packet_disconnect("Packet integrity error."); \ - } \ -} while (0) +int ssh_packet_get_state(struct ssh *, struct sshbuf *); +int ssh_packet_set_state(struct ssh *, struct sshbuf *); -int packet_need_rekeying(void); -void packet_set_rekey_limits(u_int32_t, time_t); -time_t packet_get_rekey_timeout(void); +const char *ssh_remote_ipaddr(struct ssh *); -void packet_backup_state(void); -void packet_restore_state(void); -void packet_set_postauth(void); +int ssh_packet_need_rekeying(struct ssh *); +void ssh_packet_set_rekey_limits(struct ssh *, u_int32_t, time_t); +time_t ssh_packet_get_rekey_timeout(struct ssh *); -void *packet_get_input(void); -void *packet_get_output(void); +/* XXX FIXME */ +void ssh_packet_backup_state(struct ssh *, struct ssh *); +void ssh_packet_restore_state(struct ssh *, struct ssh *); + +void *ssh_packet_get_input(struct ssh *); +void *ssh_packet_get_output(struct ssh *); + +/* new API */ +int sshpkt_start(struct ssh *ssh, u_char type); +int sshpkt_send(struct ssh *ssh); +int sshpkt_disconnect(struct ssh *, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +int sshpkt_add_padding(struct ssh *, u_char); +void sshpkt_fatal(struct ssh *ssh, const char *tag, int r); + +int sshpkt_put(struct ssh *ssh, const void *v, size_t len); +int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b); +int sshpkt_put_u8(struct ssh *ssh, u_char val); +int sshpkt_put_u32(struct ssh *ssh, u_int32_t val); +int sshpkt_put_u64(struct ssh *ssh, u_int64_t val); +int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len); +int sshpkt_put_cstring(struct ssh *ssh, const void *v); +int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); +int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); +int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v); +int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); + +int sshpkt_get(struct ssh *ssh, void *valp, size_t len); +int sshpkt_get_u8(struct ssh *ssh, u_char *valp); +int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp); +int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp); +int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp); +int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp); +int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp); +int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g); +int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v); +int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v); +int sshpkt_get_end(struct ssh *ssh); +const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); + +/* OLD API */ +extern struct ssh *active_state; +#include "opacket.h" + +#if !defined(WITH_OPENSSL) +# undef BIGNUM +# undef EC_KEY +# undef EC_GROUP +# undef EC_POINT +#elif !defined(OPENSSL_HAS_ECC) +# undef EC_KEY +# undef EC_GROUP +# undef EC_POINT +#endif #endif /* PACKET_H */ diff --git a/crypto/openssh/progressmeter.c b/crypto/openssh/progressmeter.c index bbbc7066bcb7..319b7470acd1 100644 --- a/crypto/openssh/progressmeter.c +++ b/crypto/openssh/progressmeter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.c,v 1.40 2013/09/19 00:24:52 djm Exp $ */ +/* $OpenBSD: progressmeter.c,v 1.41 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * @@ -65,7 +65,7 @@ static void update_progress_meter(int); static time_t start; /* start progress */ static time_t last_update; /* last progress update */ -static char *file; /* name of the file being transferred */ +static const char *file; /* name of the file being transferred */ static off_t start_pos; /* initial position of transfer */ static off_t end_pos; /* ending position of transfer */ static off_t cur_pos; /* transfer position as of last refresh */ @@ -248,7 +248,7 @@ update_progress_meter(int ignore) } void -start_progress_meter(char *f, off_t filesize, off_t *ctr) +start_progress_meter(const char *f, off_t filesize, off_t *ctr) { start = last_update = monotime(); file = f; diff --git a/crypto/openssh/progressmeter.h b/crypto/openssh/progressmeter.h index 10bab99ba4c7..bf179dca6518 100644 --- a/crypto/openssh/progressmeter.h +++ b/crypto/openssh/progressmeter.h @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.h,v 1.2 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: progressmeter.h,v 1.3 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2002 Nils Nordman. All rights reserved. * @@ -23,5 +23,5 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -void start_progress_meter(char *, off_t, off_t *); +void start_progress_meter(const char *, off_t, off_t *); void stop_progress_meter(void); diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c index 04d351710687..9a14c699a985 100644 --- a/crypto/openssh/readconf.c +++ b/crypto/openssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.220 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: readconf.c,v 1.232 2015/02/16 22:13:32 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -30,6 +30,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include #ifdef HAVE_PATHS_H # include @@ -43,6 +44,9 @@ __RCSID("$FreeBSD$"); #ifdef HAVE_UTIL_H #include #endif +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) +# include +#endif #include "xmalloc.h" #include "ssh.h" @@ -50,14 +54,15 @@ __RCSID("$FreeBSD$"); #include "cipher.h" #include "pathnames.h" #include "log.h" -#include "key.h" +#include "sshkey.h" #include "misc.h" #include "readconf.h" #include "match.h" -#include "buffer.h" #include "kex.h" #include "mac.h" #include "uidswap.h" +#include "myproposal.h" +#include "digest.h" #include "version.h" /* Format of the configuration file: @@ -138,7 +143,7 @@ typedef enum { oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts, oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, - oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, + oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oHostKeyAlgorithms, oBindAddress, oPKCS11Provider, @@ -153,7 +158,8 @@ typedef enum { oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, - oStreamLocalBindMask, oStreamLocalBindUnlink, + oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, + oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes, oVersionAddendum, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -216,7 +222,7 @@ static struct { { "globalknownhostsfile", oGlobalKnownHostsFile }, { "globalknownhostsfile2", oDeprecated }, { "userknownhostsfile", oUserKnownHostsFile }, - { "userknownhostsfile2", oDeprecated }, + { "userknownhostsfile2", oDeprecated }, { "connectionattempts", oConnectionAttempts }, { "batchmode", oBatchMode }, { "checkhostip", oCheckHostIP }, @@ -269,6 +275,10 @@ static struct { { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, { "streamlocalbindmask", oStreamLocalBindMask }, { "streamlocalbindunlink", oStreamLocalBindUnlink }, + { "revokedhostkeys", oRevokedHostKeys }, + { "fingerprinthash", oFingerprintHash }, + { "updatehostkeys", oUpdateHostkeys }, + { "hostbasedkeytypes", oHostbasedKeyTypes }, { "ignoreunknown", oIgnoreUnknown }, { "versionaddendum", oVersionAddendum }, @@ -484,7 +494,7 @@ execute_in_shell(const char *cmd) if (!WIFEXITED(status)) { error("command '%.100s' exited abnormally", cmd); return -1; - } + } debug3("command returned status %d", WEXITSTATUS(status)); return WEXITSTATUS(status); } @@ -494,11 +504,12 @@ execute_in_shell(const char *cmd) */ static int match_cfg_line(Options *options, char **condition, struct passwd *pw, - const char *host_arg, const char *filename, int linenum) + const char *host_arg, const char *original_host, int post_canon, + const char *filename, int linenum) { - char *arg, *attrib, *cmd, *cp = *condition, *host; + char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; const char *ruser; - int r, port, result = 1, attributes = 0; + int r, port, this_result, result = 1, attributes = 0, negate; size_t len; char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; @@ -515,21 +526,38 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, } else host = xstrdup(host_arg); - debug3("checking match for '%s' host %s", cp, host); - while ((attrib = strdelim(&cp)) && *attrib != '\0') { - attributes++; + debug2("checking match for '%s' host %s originally %s", + cp, host, original_host); + while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { + criteria = NULL; + this_result = 1; + if ((negate = attrib[0] == '!')) + attrib++; + /* criteria "all" and "canonical" have no argument */ if (strcasecmp(attrib, "all") == 0) { - if (attributes != 1 || + if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && *arg != '\0')) { - error("'all' cannot be combined with other " - "Match attributes"); + error("%.200s line %d: '%s' cannot be combined " + "with other Match attributes", + filename, linenum, oattrib); result = -1; goto out; } - *condition = cp; - result = 1; + if (result) + result = negate ? 0 : 1; goto out; } + attributes++; + if (strcasecmp(attrib, "canonical") == 0) { + r = !!post_canon; /* force bitmask member to boolean */ + if (r == (negate ? 1 : 0)) + this_result = result = 0; + debug3("%.200s line %d: %smatched '%s'", + filename, linenum, + this_result ? "" : "not ", oattrib); + continue; + } + /* All other criteria require an argument */ if ((arg = strdelim(&cp)) == NULL || *arg == '\0') { error("Missing Match criteria for %s", attrib); result = -1; @@ -537,31 +565,25 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, } len = strlen(arg); if (strcasecmp(attrib, "host") == 0) { - if (match_hostname(host, arg, len) != 1) - result = 0; - else - debug("%.200s line %d: matched 'Host %.100s' ", - filename, linenum, host); + criteria = xstrdup(host); + r = match_hostname(host, arg, len) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "originalhost") == 0) { - if (match_hostname(host_arg, arg, len) != 1) - result = 0; - else - debug("%.200s line %d: matched " - "'OriginalHost %.100s' ", - filename, linenum, host_arg); + criteria = xstrdup(original_host); + r = match_hostname(original_host, arg, len) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "user") == 0) { - if (match_pattern_list(ruser, arg, len, 0) != 1) - result = 0; - else - debug("%.200s line %d: matched 'User %.100s' ", - filename, linenum, ruser); + criteria = xstrdup(ruser); + r = match_pattern_list(ruser, arg, len, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "localuser") == 0) { - if (match_pattern_list(pw->pw_name, arg, len, 0) != 1) - result = 0; - else - debug("%.200s line %d: matched " - "'LocalUser %.100s' ", - filename, linenum, pw->pw_name); + criteria = xstrdup(pw->pw_name); + r = match_pattern_list(pw->pw_name, arg, len, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "exec") == 0) { if (gethostname(thishost, sizeof(thishost)) == -1) fatal("gethostname: %s", strerror(errno)); @@ -574,47 +596,49 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, "d", pw->pw_dir, "h", host, "l", thishost, - "n", host_arg, + "n", original_host, "p", portstr, "r", ruser, "u", pw->pw_name, (char *)NULL); if (result != 1) { /* skip execution if prior predicate failed */ - debug("%.200s line %d: skipped exec \"%.100s\"", - filename, linenum, cmd); - } else { - r = execute_in_shell(cmd); - if (r == -1) { - fatal("%.200s line %d: match exec " - "'%.100s' error", filename, - linenum, cmd); - } else if (r == 0) { - debug("%.200s line %d: matched " - "'exec \"%.100s\"'", filename, - linenum, cmd); - } else { - debug("%.200s line %d: no match " - "'exec \"%.100s\"'", filename, - linenum, cmd); - result = 0; - } + debug3("%.200s line %d: skipped exec " + "\"%.100s\"", filename, linenum, cmd); + free(cmd); + continue; } + r = execute_in_shell(cmd); + if (r == -1) { + fatal("%.200s line %d: match exec " + "'%.100s' error", filename, + linenum, cmd); + } + criteria = xstrdup(cmd); free(cmd); + /* Force exit status to boolean */ + r = r == 0; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else { error("Unsupported Match attribute %s", attrib); result = -1; goto out; } + debug3("%.200s line %d: %smatched '%s \"%.100s\"' ", + filename, linenum, this_result ? "": "not ", + oattrib, criteria); + free(criteria); } if (attributes == 0) { error("One or more attributes required for Match"); result = -1; goto out; } - debug3("match %sfound", result ? "" : "not "); - *condition = cp; out: + if (result != -1) + debug2("match %sfound", result ? "" : "not "); + *condition = cp; free(host); return result; } @@ -737,7 +761,8 @@ static const struct multistate multistate_canonicalizehostname[] = { #define WHITESPACE " \t\r\n" int process_config_line(Options *options, struct passwd *pw, const char *host, - char *line, const char *filename, int linenum, int *activep, int userconfig) + const char *original_host, char *line, const char *filename, + int linenum, int *activep, int flags) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; char **cpptr, fwdarg[256]; @@ -793,7 +818,9 @@ process_config_line(Options *options, struct passwd *pw, const char *host, if (!arg || *arg == '\0') fatal("%s line %d: missing time value.", filename, linenum); - if ((value = convtime(arg)) == -1) + if (strcmp(arg, "none") == 0) + value = -1; + else if ((value = convtime(arg)) == -1) fatal("%s line %d: invalid time value.", filename, linenum); if (*activep && *intptr == -1) @@ -830,7 +857,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host, case oForwardX11Trusted: intptr = &options->forward_x11_trusted; goto parse_flag; - + case oForwardX11Timeout: intptr = &options->forward_x11_timeout; goto parse_time; @@ -965,7 +992,8 @@ process_config_line(Options *options, struct passwd *pw, const char *host, if (*intptr >= SSH_MAX_IDENTITY_FILES) fatal("%.200s line %d: Too many identity files specified (max %d).", filename, linenum, SSH_MAX_IDENTITY_FILES); - add_identity_file(options, NULL, arg, userconfig); + add_identity_file(options, NULL, + arg, flags & SSHCONF_USERCONF); } break; @@ -1108,7 +1136,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host, arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); - if (!key_names_valid2(arg)) + if (!sshkey_names_valid2(arg, 1)) fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.", filename, linenum, arg ? arg : ""); if (*activep && options->hostkeyalgorithms == NULL) @@ -1213,8 +1241,8 @@ process_config_line(Options *options, struct passwd *pw, const char *host, if (cmdline) fatal("Host directive not supported as a command-line " "option"); - value = match_cfg_line(options, &s, pw, host, - filename, linenum); + value = match_cfg_line(options, &s, pw, host, original_host, + flags & SSHCONF_POSTCANON, filename, linenum); if (value < 0) fatal("%.200s line %d: Bad Match condition", filename, linenum); @@ -1467,6 +1495,41 @@ process_config_line(Options *options, struct passwd *pw, const char *host, intptr = &options->fwd_opts.streamlocal_bind_unlink; goto parse_flag; + case oRevokedHostKeys: + charptr = &options->revoked_host_keys; + goto parse_string; + + case oFingerprintHash: + intptr = &options->fingerprint_hash; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if ((value = ssh_digest_alg_by_name(arg)) == -1) + fatal("%.200s line %d: Invalid hash algorithm \"%s\".", + filename, linenum, arg); + if (*activep && *intptr == -1) + *intptr = value; + break; + + case oUpdateHostkeys: + intptr = &options->update_hostkeys; + multistate_ptr = multistate_yesnoask; + goto parse_multistate; + + case oHostbasedKeyTypes: + charptr = &options->hostbased_key_types; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if (!sshkey_names_valid2(arg, 1)) + fatal("%s line %d: Bad key types '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1478,7 +1541,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host, return 0; default: - fatal("process_config_line: Unimplemented opcode %d", opcode); + fatal("%s: Unimplemented opcode %d", __func__, opcode); } /* Check that there is no garbage at end of line. */ @@ -1498,7 +1561,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host, int read_config_file(const char *filename, struct passwd *pw, const char *host, - Options *options, int flags) + const char *original_host, Options *options, int flags) { FILE *f; char line[1024]; @@ -1529,8 +1592,8 @@ read_config_file(const char *filename, struct passwd *pw, const char *host, while (fgets(line, sizeof(line), f)) { /* Update line number counter. */ linenum++; - if (process_config_line(options, pw, host, line, filename, - linenum, &active, flags & SSHCONF_USERCONF) != 0) + if (process_config_line(options, pw, host, original_host, + line, filename, linenum, &active, flags) != 0) bad_options++; } fclose(f); @@ -1643,6 +1706,10 @@ initialize_options(Options * options) options->canonicalize_max_dots = -1; options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; + options->revoked_host_keys = NULL; + options->fingerprint_hash = -1; + options->update_hostkeys = -1; + options->hostbased_key_types = NULL; options->version_addendum = NULL; } @@ -1826,6 +1893,13 @@ fill_default_options(Options * options) options->canonicalize_fallback_local = 1; if (options->canonicalize_hostname == -1) options->canonicalize_hostname = SSH_CANONICALISE_NO; + if (options->fingerprint_hash == -1) + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; + if (options->update_hostkeys == -1) + options->update_hostkeys = 0; + if (options->hostbased_key_types == NULL) + options->hostbased_key_types = xstrdup("*"); + #define CLEAR_ON_NONE(v) \ do { \ if (option_clear_or_none(v)) { \ @@ -1836,6 +1910,7 @@ fill_default_options(Options * options) CLEAR_ON_NONE(options->local_command); CLEAR_ON_NONE(options->proxy_command); CLEAR_ON_NONE(options->control_path); + CLEAR_ON_NONE(options->revoked_host_keys); /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ /* options->host_key_alias should not be set by default */ @@ -2051,3 +2126,303 @@ parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remo fwd->listen_path = NULL; return (0); } + +/* XXX the following is a near-vebatim copy from servconf.c; refactor */ +static const char * +fmt_multistate_int(int val, const struct multistate *m) +{ + u_int i; + + for (i = 0; m[i].key != NULL; i++) { + if (m[i].value == val) + return m[i].key; + } + return "UNKNOWN"; +} + +static const char * +fmt_intarg(OpCodes code, int val) +{ + if (val == -1) + return "unset"; + switch (code) { + case oAddressFamily: + return fmt_multistate_int(val, multistate_addressfamily); + case oVerifyHostKeyDNS: + case oStrictHostKeyChecking: + case oUpdateHostkeys: + return fmt_multistate_int(val, multistate_yesnoask); + case oControlMaster: + return fmt_multistate_int(val, multistate_controlmaster); + case oTunnel: + return fmt_multistate_int(val, multistate_tunnel); + case oRequestTTY: + return fmt_multistate_int(val, multistate_requesttty); + case oCanonicalizeHostname: + return fmt_multistate_int(val, multistate_canonicalizehostname); + case oFingerprintHash: + return ssh_digest_alg_name(val); + case oProtocol: + switch (val) { + case SSH_PROTO_1: + return "1"; + case SSH_PROTO_2: + return "2"; + case (SSH_PROTO_1|SSH_PROTO_2): + return "2,1"; + default: + return "UNKNOWN"; + } + default: + switch (val) { + case 0: + return "no"; + case 1: + return "yes"; + default: + return "UNKNOWN"; + } + } +} + +static const char * +lookup_opcode_name(OpCodes code) +{ + u_int i; + + for (i = 0; keywords[i].name != NULL; i++) + if (keywords[i].opcode == code) + return(keywords[i].name); + return "UNKNOWN"; +} + +static void +dump_cfg_int(OpCodes code, int val) +{ + printf("%s %d\n", lookup_opcode_name(code), val); +} + +static void +dump_cfg_fmtint(OpCodes code, int val) +{ + printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); +} + +static void +dump_cfg_string(OpCodes code, const char *val) +{ + if (val == NULL) + return; + printf("%s %s\n", lookup_opcode_name(code), val); +} + +static void +dump_cfg_strarray(OpCodes code, u_int count, char **vals) +{ + u_int i; + + for (i = 0; i < count; i++) + printf("%s %s\n", lookup_opcode_name(code), vals[i]); +} + +static void +dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals) +{ + u_int i; + + printf("%s", lookup_opcode_name(code)); + for (i = 0; i < count; i++) + printf(" %s", vals[i]); + printf("\n"); +} + +static void +dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds) +{ + const struct Forward *fwd; + u_int i; + + /* oDynamicForward */ + for (i = 0; i < count; i++) { + fwd = &fwds[i]; + if (code == oDynamicForward && + strcmp(fwd->connect_host, "socks") != 0) + continue; + if (code == oLocalForward && + strcmp(fwd->connect_host, "socks") == 0) + continue; + printf("%s", lookup_opcode_name(code)); + if (fwd->listen_port == PORT_STREAMLOCAL) + printf(" %s", fwd->listen_path); + else if (fwd->listen_host == NULL) + printf(" %d", fwd->listen_port); + else { + printf(" [%s]:%d", + fwd->listen_host, fwd->listen_port); + } + if (code != oDynamicForward) { + if (fwd->connect_port == PORT_STREAMLOCAL) + printf(" %s", fwd->connect_path); + else if (fwd->connect_host == NULL) + printf(" %d", fwd->connect_port); + else { + printf(" [%s]:%d", + fwd->connect_host, fwd->connect_port); + } + } + printf("\n"); + } +} + +void +dump_client_config(Options *o, const char *host) +{ + int i; + char vbuf[5]; + + /* Most interesting options first: user, host, port */ + dump_cfg_string(oUser, o->user); + dump_cfg_string(oHostName, host); + dump_cfg_int(oPort, o->port); + + /* Flag options */ + dump_cfg_fmtint(oAddressFamily, o->address_family); + dump_cfg_fmtint(oBatchMode, o->batch_mode); + dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local); + dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname); + dump_cfg_fmtint(oChallengeResponseAuthentication, o->challenge_response_authentication); + dump_cfg_fmtint(oCheckHostIP, o->check_host_ip); + dump_cfg_fmtint(oCompression, o->compression); + dump_cfg_fmtint(oControlMaster, o->control_master); + dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign); + dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure); + dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash); + dump_cfg_fmtint(oForwardAgent, o->forward_agent); + dump_cfg_fmtint(oForwardX11, o->forward_x11); + dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted); + dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); +#ifdef GSSAPI + dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); + dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); +#endif /* GSSAPI */ + dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); + dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); + dump_cfg_fmtint(oIdentitiesOnly, o->identities_only); + dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication); + dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost); + dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication); + dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command); + dump_cfg_fmtint(oProtocol, o->protocol); + dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass); + dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication); + dump_cfg_fmtint(oRequestTTY, o->request_tty); + dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); + dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); + dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); + dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking); + dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive); + dump_cfg_fmtint(oTunnel, o->tun_open); + dump_cfg_fmtint(oUsePrivilegedPort, o->use_privileged_port); + dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns); + dump_cfg_fmtint(oVisualHostKey, o->visual_host_key); + dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys); + + /* Integer options */ + dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); + dump_cfg_int(oCompressionLevel, o->compression_level); + dump_cfg_int(oConnectionAttempts, o->connection_attempts); + dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); + dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); + dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max); + dump_cfg_int(oServerAliveInterval, o->server_alive_interval); + + /* String options */ + dump_cfg_string(oBindAddress, o->bind_address); + dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); + dump_cfg_string(oControlPath, o->control_path); + dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); + dump_cfg_string(oHostKeyAlias, o->host_key_alias); + dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); + dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); + dump_cfg_string(oKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : KEX_CLIENT_KEX); + dump_cfg_string(oLocalCommand, o->local_command); + dump_cfg_string(oLogLevel, log_level_name(o->log_level)); + dump_cfg_string(oMacs, o->macs ? o->macs : KEX_CLIENT_MAC); + dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); + dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); + dump_cfg_string(oProxyCommand, o->proxy_command); + dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); + dump_cfg_string(oXAuthLocation, o->xauth_location); + + /* Forwards */ + dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); + dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); + dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); + + /* String array options */ + dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); + dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); + dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles); + dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles); + dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env); + + /* Special cases */ + + /* oConnectTimeout */ + if (o->connection_timeout == -1) + printf("connecttimeout none\n"); + else + dump_cfg_int(oConnectTimeout, o->connection_timeout); + + /* oTunnelDevice */ + printf("tunneldevice"); + if (o->tun_local == SSH_TUNID_ANY) + printf(" any"); + else + printf(" %d", o->tun_local); + if (o->tun_remote == SSH_TUNID_ANY) + printf(":any"); + else + printf(":%d", o->tun_remote); + printf("\n"); + + /* oCanonicalizePermittedCNAMEs */ + if ( o->num_permitted_cnames > 0) { + printf("canonicalizePermittedcnames"); + for (i = 0; i < o->num_permitted_cnames; i++) { + printf(" %s:%s", o->permitted_cnames[i].source_list, + o->permitted_cnames[i].target_list); + } + printf("\n"); + } + + /* oCipher */ + if (o->cipher != SSH_CIPHER_NOT_SET) + printf("Cipher %s\n", cipher_name(o->cipher)); + + /* oControlPersist */ + if (o->control_persist == 0 || o->control_persist_timeout == 0) + dump_cfg_fmtint(oControlPersist, o->control_persist); + else + dump_cfg_int(oControlPersist, o->control_persist_timeout); + + /* oEscapeChar */ + if (o->escape_char == SSH_ESCAPECHAR_NONE) + printf("escapechar none\n"); + else { + vis(vbuf, o->escape_char, VIS_WHITE, 0); + printf("escapechar %s\n", vbuf); + } + + /* oIPQoS */ + printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); + printf("%s\n", iptos2str(o->ip_qos_bulk)); + + /* oRekeyLimit */ + printf("rekeylimit %lld %d\n", + (long long)o->rekey_limit, o->rekey_interval); + + /* oStreamLocalBindMask */ + printf("streamlocalbindmask 0%o\n", + o->fwd_opts.streamlocal_bind_mask); +} diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h index 744475203303..a34aa7df49fa 100644 --- a/crypto/openssh/readconf.h +++ b/crypto/openssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.102 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: readconf.h,v 1.109 2015/02/16 22:13:32 djm Exp $ */ /* * Author: Tatu Ylonen @@ -93,7 +93,7 @@ typedef struct { int num_identity_files; /* Number of files for RSA/DSA identities. */ char *identity_files[SSH_MAX_IDENTITY_FILES]; int identity_file_userprovided[SSH_MAX_IDENTITY_FILES]; - Key *identity_keys[SSH_MAX_IDENTITY_FILES]; + struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; /* Local TCP/IP forward requests. */ int num_local_forwards; @@ -144,7 +144,15 @@ typedef struct { int num_permitted_cnames; struct allowed_cname permitted_cnames[MAX_CANON_DOMAINS]; - char *version_addendum; /* Appended to SSH banner */ + char *revoked_host_keys; + + int fingerprint_hash; + + int update_hostkeys; /* one of SSH_UPDATE_HOSTKEYS_* */ + + char *hostbased_key_types; + + char *version_addendum; /* Appended to SSH banner */ char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; @@ -166,17 +174,23 @@ typedef struct { #define SSHCONF_CHECKPERM 1 /* check permissions on config file */ #define SSHCONF_USERCONF 2 /* user provided config file not system */ +#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ + +#define SSH_UPDATE_HOSTKEYS_NO 0 +#define SSH_UPDATE_HOSTKEYS_YES 1 +#define SSH_UPDATE_HOSTKEYS_ASK 2 void initialize_options(Options *); void fill_default_options(Options *); void fill_default_options_for_canonicalization(Options *); -int process_config_line(Options *, struct passwd *, const char *, char *, - const char *, int, int *, int); +int process_config_line(Options *, struct passwd *, const char *, + const char *, char *, const char *, int, int *, int); int read_config_file(const char *, struct passwd *, const char *, - Options *, int); + const char *, Options *, int); int parse_forward(struct Forward *, const char *, int, int); int default_ssh_port(void); int option_clear_or_none(const char *); +void dump_client_config(Options *o, const char *host); void add_local_forward(Options *, const struct Forward *); void add_remote_forward(Options *, const struct Forward *); diff --git a/crypto/openssh/regress/.cvsignore b/crypto/openssh/regress/.cvsignore new file mode 100644 index 000000000000..3fd25b02e774 --- /dev/null +++ b/crypto/openssh/regress/.cvsignore @@ -0,0 +1,31 @@ +*-agent +*.copy +*.log +*.prv +*.pub +actual +authorized_keys_* +batch +copy.dd* +data +expect +host.rsa* +key.* +known_hosts +krl-* +modpipe +remote_pid +revoked-* +revoked-ca +revoked-keyid +revoked-serials +rsa +rsa1 +sftp-server.sh +ssh-log-wrapper.sh +ssh_config +ssh_proxy* +sshd_config +sshd_proxy* +t*.out +t*.out[0-9] diff --git a/crypto/openssh/regress/Makefile b/crypto/openssh/regress/Makefile index 3feb7a997b6d..99a7d60f5d98 100644 --- a/crypto/openssh/regress/Makefile +++ b/crypto/openssh/regress/Makefile @@ -1,11 +1,14 @@ -# $OpenBSD: Makefile,v 1.70 2014/06/24 01:14:17 djm Exp $ +# $OpenBSD: Makefile,v 1.78 2015/01/26 06:12:18 djm Exp $ -REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t-exec -tests: $(REGRESS_TARGETS) +REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec +tests: prep $(REGRESS_TARGETS) # Interop tests are not run by default interop interop-tests: t-exec-interop +prep: + test "x${USE_VALGRIND}" = "x" || mkdir -p $(OBJ)/valgrind-out + clean: for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN} @@ -64,7 +67,14 @@ LTESTS= connect \ keys-command \ forward-control \ integrity \ - krl + krl \ + multipubkey \ + limit-keytype \ + hostkey-agent \ + keygen-knownhosts \ + hostkey-rotate + + # dhgex \ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers @@ -75,6 +85,7 @@ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers USER!= id -un CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ t8.out t8.out.pub t9.out t9.out.pub t10.out t10.out.pub \ + t12.out t12.out.pub \ authorized_keys_${USER} known_hosts pidfile testdata \ ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ @@ -91,7 +102,8 @@ CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ regress.log failed-regress.log ssh-log-wrapper.sh \ sftp-server.sh sftp-server.log sftp.log setuid-allowed \ data ed25519-agent ed25519-agent.pub key.ed25519-512 \ - key.ed25519-512.pub + key.ed25519-512.pub netcat host_krl_* host_revoked_* \ + kh.* user_*key* agent-key.* known_hosts.* hkr.* SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} @@ -119,7 +131,7 @@ t3: ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub t4: - ${TEST_SSH_SSHKEYGEN} -lf ${.CURDIR}/rsa_openssh.pub |\ + ${TEST_SSH_SSHKEYGEN} -E md5 -lf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t4.ok t5: @@ -164,6 +176,16 @@ t10: $(OBJ)/t10.out ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t10.out > /dev/null ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t10.out > /dev/null +t11: + ${TEST_SSH_SSHKEYGEN} -E sha256 -lf ${.CURDIR}/rsa_openssh.pub |\ + awk '{print $$2}' | diff - ${.CURDIR}/t11.ok + +t12.out: + ${TEST_SSH_SSHKEYGEN} -q -t ed25519 -N '' -C 'test-comment-1234' -f $(OBJ)/$@ + +t12: t12.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t12.out.pub | grep test-comment-1234 >/dev/null + t-exec: ${LTESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ @@ -184,7 +206,14 @@ interop: ${INTEROP_TARGETS} # Unit tests, built by top-level Makefile unit: set -e ; if test -z "${SKIP_UNIT}" ; then \ - ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ - ${.OBJDIR}/unittests/sshkey/test_sshkey \ - -d ${.CURDIR}//unittests/sshkey/testdata ; \ + V="" ; \ + test "x${USE_VALGRIND}" = "x" || \ + V=${.CURDIR}/valgrind-unit.sh ; \ + $$V ${.OBJDIR}/unittests/sshbuf/test_sshbuf ; \ + $$V ${.OBJDIR}/unittests/sshkey/test_sshkey \ + -d ${.CURDIR}/unittests/sshkey/testdata ; \ + $$V ${.OBJDIR}/unittests/bitmap/test_bitmap ; \ + $$V ${.OBJDIR}/unittests/kex/test_kex ; \ + $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ + -d ${.CURDIR}/unittests/hostkeys/testdata ; \ fi diff --git a/crypto/openssh/regress/agent-pkcs11.sh b/crypto/openssh/regress/agent-pkcs11.sh index db33ab37eb60..3aa20c8b1ee0 100755 --- a/crypto/openssh/regress/agent-pkcs11.sh +++ b/crypto/openssh/regress/agent-pkcs11.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent-pkcs11.sh,v 1.1 2010/02/08 10:52:47 markus Exp $ +# $OpenBSD: agent-pkcs11.sh,v 1.2 2015/01/12 11:46:32 djm Exp $ # Placed in the Public Domain. tid="pkcs11 agent test" @@ -6,6 +6,8 @@ tid="pkcs11 agent test" TEST_SSH_PIN="" TEST_SSH_PKCS11=/usr/local/lib/soft-pkcs11.so.0.0 +test -f "$TEST_SSH_PKCS11" || fatal "$TEST_SSH_PKCS11 does not exist" + # setup environment for soft-pkcs11 token SOFTPKCS11RC=$OBJ/pkcs11.info export SOFTPKCS11RC diff --git a/crypto/openssh/regress/agent-timeout.sh b/crypto/openssh/regress/agent-timeout.sh index 68826594e470..9598c2032d26 100644 --- a/crypto/openssh/regress/agent-timeout.sh +++ b/crypto/openssh/regress/agent-timeout.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent-timeout.sh,v 1.2 2013/05/17 01:16:09 dtucker Exp $ +# $OpenBSD: agent-timeout.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="agent timeout test" @@ -12,7 +12,7 @@ if [ $r -ne 0 ]; then fail "could not start ssh-agent: exit code $r" else trace "add keys with timeout" - for t in rsa rsa1; do + for t in ${SSH_KEYTYPES}; do ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh-add did succeed exit code 0" diff --git a/crypto/openssh/regress/agent.sh b/crypto/openssh/regress/agent.sh index caad3c88e4c3..c5e2794b763c 100644 --- a/crypto/openssh/regress/agent.sh +++ b/crypto/openssh/regress/agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent.sh,v 1.10 2014/02/27 21:21:25 djm Exp $ +# $OpenBSD: agent.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="simple agent test" @@ -20,7 +20,7 @@ else fi trace "overwrite authorized keys" printf '' > $OBJ/authorized_keys_$USER - for t in ed25519 rsa rsa1; do + for t in ${SSH_KEYTYPES}; do # generate user key for agent rm -f $OBJ/$t-agent ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ @@ -46,7 +46,7 @@ else fi trace "simple connect via agent" - for p in 1 2; do + for p in ${SSH_PROTOCOLS}; do ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p r=$? if [ $r -ne 5$p ]; then @@ -55,7 +55,7 @@ else done trace "agent forwarding" - for p in 1 2; do + for p in ${SSH_PROTOCOLS}; do ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then diff --git a/crypto/openssh/regress/broken-pipe.sh b/crypto/openssh/regress/broken-pipe.sh index c08c849a7581..a416f7a3b52c 100644 --- a/crypto/openssh/regress/broken-pipe.sh +++ b/crypto/openssh/regress/broken-pipe.sh @@ -1,9 +1,9 @@ -# $OpenBSD: broken-pipe.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# $OpenBSD: broken-pipe.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="broken pipe test" -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "protocol $p" for i in 1 2 3 4; do ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true diff --git a/crypto/openssh/regress/cert-hostkey.sh b/crypto/openssh/regress/cert-hostkey.sh index 1d9e0ed8e346..51685dc2b54b 100755 --- a/crypto/openssh/regress/cert-hostkey.sh +++ b/crypto/openssh/regress/cert-hostkey.sh @@ -1,21 +1,29 @@ -# $OpenBSD: cert-hostkey.sh,v 1.9 2014/01/26 10:22:10 djm Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.11 2015/01/19 06:01:32 djm Exp $ # Placed in the Public Domain. tid="certified host keys" -rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* +rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/host_revoked_* +rm -f $OBJ/cert_host_key* $OBJ/host_krl_* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak HOSTS='localhost-with-alias,127.0.0.1,::1' -# Create a CA key and add it to known hosts -${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ +# Create a CA key and add it to known hosts. Ed25519 chosed for speed. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/host_ca_key ||\ fail "ssh-keygen of host_ca_key failed" ( printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub -) > $OBJ/known_hosts-cert +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + +# Plain text revocation files +touch $OBJ/host_revoked_empty +touch $OBJ/host_revoked_plain +touch $OBJ/host_revoked_cert +cp $OBJ/host_ca_key.pub $OBJ/host_revoked_ca PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` @@ -26,17 +34,33 @@ type_has_legacy() { return 0 } +# Prepare certificate, plain key and CA KRLs +${SSHKEYGEN} -kf $OBJ/host_krl_empty || fatal "KRL init failed" +${SSHKEYGEN} -kf $OBJ/host_krl_plain || fatal "KRL init failed" +${SSHKEYGEN} -kf $OBJ/host_krl_cert || fatal "KRL init failed" +${SSHKEYGEN} -kf $OBJ/host_krl_ca $OBJ/host_ca_key.pub \ + || fatal "KRL init failed" + # Generate and sign host keys +serial=1 for ktype in $PLAIN_TYPES ; do verbose "$tid: sign host ${ktype} cert" # Generate and sign a host key ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_host_key_${ktype} || \ - fail "ssh-keygen of cert_host_key_${ktype} failed" - ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key \ + fatal "ssh-keygen of cert_host_key_${ktype} failed" + ${SSHKEYGEN} -ukf $OBJ/host_krl_plain \ + $OBJ/cert_host_key_${ktype}.pub || fatal "KRL update failed" + cat $OBJ/cert_host_key_${ktype}.pub >> $OBJ/host_revoked_plain + ${SSHKEYGEN} -h -q -s $OBJ/host_ca_key -z $serial \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype} || - fail "couldn't sign cert_host_key_${ktype}" + fatal "couldn't sign cert_host_key_${ktype}" + ${SSHKEYGEN} -ukf $OBJ/host_krl_cert \ + $OBJ/cert_host_key_${ktype}-cert.pub || \ + fatal "KRL update failed" + cat $OBJ/cert_host_key_${ktype}-cert.pub >> $OBJ/host_revoked_cert + serial=`expr $serial + 1` type_has_legacy $ktype || continue cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00 cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub @@ -44,10 +68,35 @@ for ktype in $PLAIN_TYPES ; do ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype}_v00 || - fail "couldn't sign cert_host_key_${ktype}_v00" + fatal "couldn't sign cert_host_key_${ktype}_v00" + ${SSHKEYGEN} -ukf $OBJ/host_krl_cert \ + $OBJ/cert_host_key_${ktype}_v00-cert.pub || \ + fatal "KRL update failed" + cat $OBJ/cert_host_key_${ktype}_v00-cert.pub >> $OBJ/host_revoked_cert done -# Basic connect tests +attempt_connect() { + _ident="$1" + _expect_success="$2" + shift; shift + verbose "$tid: $_ident expect success $_expect_success" + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert + ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ + -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ + "$@" -F $OBJ/ssh_proxy somehost true + _r=$? + if [ "x$_expect_success" = "xyes" ] ; then + if [ $_r -ne 0 ]; then + fail "ssh cert connect $_ident failed" + fi + else + if [ $_r -eq 0 ]; then + fail "ssh cert connect $_ident succeeded unexpectedly" + fi + fi +} + +# Basic connect and revocation tests. for privsep in yes no ; do for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do verbose "$tid: host ${ktype} cert connect privsep $privsep" @@ -58,12 +107,24 @@ for privsep in yes no ; do echo UsePrivilegeSeparation $privsep ) > $OBJ/sshd_proxy - ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ - -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ - -F $OBJ/ssh_proxy somehost true - if [ $? -ne 0 ]; then - fail "ssh cert connect failed" - fi + # test name expect success + attempt_connect "$ktype basic connect" "yes" + attempt_connect "$ktype empty KRL" "yes" \ + -oRevokedHostKeys=$OBJ/host_krl_empty + attempt_connect "$ktype KRL w/ plain key revoked" "no" \ + -oRevokedHostKeys=$OBJ/host_krl_plain + attempt_connect "$ktype KRL w/ cert revoked" "no" \ + -oRevokedHostKeys=$OBJ/host_krl_cert + attempt_connect "$ktype KRL w/ CA revoked" "no" \ + -oRevokedHostKeys=$OBJ/host_krl_ca + attempt_connect "$ktype empty plaintext revocation" "yes" \ + -oRevokedHostKeys=$OBJ/host_revoked_empty + attempt_connect "$ktype plain key plaintext revocation" "no" \ + -oRevokedHostKeys=$OBJ/host_revoked_plain + attempt_connect "$ktype cert plaintext revocation" "no" \ + -oRevokedHostKeys=$OBJ/host_revoked_cert + attempt_connect "$ktype CA plaintext revocation" "no" \ + -oRevokedHostKeys=$OBJ/host_revoked_ca done done @@ -76,7 +137,8 @@ done test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" printf "@revoked * `cat $OBJ/cert_host_key_${ktype}.pub`\n" done -) > $OBJ/known_hosts-cert +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for privsep in yes no ; do for ktype in $PLAIN_TYPES rsa_v00 dsa_v00; do verbose "$tid: host ${ktype} revoked cert privsep $privsep" @@ -87,6 +149,7 @@ for privsep in yes no ; do echo UsePrivilegeSeparation $privsep ) > $OBJ/sshd_proxy + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 @@ -104,7 +167,8 @@ done printf '@revoked ' printf "* " cat $OBJ/host_ca_key.pub -) > $OBJ/known_hosts-cert +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do verbose "$tid: host ${ktype} revoked cert" ( @@ -112,6 +176,7 @@ for ktype in $PLAIN_TYPES rsa_v00 dsa_v00 ; do echo HostKey $OBJ/cert_host_key_${ktype} echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub ) > $OBJ/sshd_proxy + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 @@ -125,7 +190,8 @@ done printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub -) > $OBJ/known_hosts-cert +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert test_one() { ident=$1 @@ -150,6 +216,7 @@ test_one() { echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub ) > $OBJ/sshd_proxy + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 @@ -212,7 +279,8 @@ done printf '@cert-authority ' printf "$HOSTS " cat $OBJ/host_ca_key.pub -) > $OBJ/known_hosts-cert +) > $OBJ/known_hosts-cert.orig +cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for v in v01 v00 ; do for kt in $PLAIN_TYPES ; do type_has_legacy $kt || continue @@ -232,6 +300,7 @@ for v in v01 v00 ; do echo HostCertificate $OBJ/cert_host_key_${kt}-cert.pub ) > $OBJ/sshd_proxy + cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert ${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \ -oGlobalKnownHostsFile=$OBJ/known_hosts-cert \ -F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1 @@ -241,4 +310,4 @@ for v in v01 v00 ; do done done -rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* +rm -f $OBJ/known_hosts-cert* $OBJ/host_ca_key* $OBJ/cert_host_key* diff --git a/crypto/openssh/regress/cfgmatch.sh b/crypto/openssh/regress/cfgmatch.sh index 80cf22930ce3..056296398657 100644 --- a/crypto/openssh/regress/cfgmatch.sh +++ b/crypto/openssh/regress/cfgmatch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfgmatch.sh,v 1.8 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: cfgmatch.sh,v 1.9 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="sshd_config match" @@ -56,7 +56,7 @@ start_sshd #set -x # Test Match + PermitOpen in sshd_config. This should be permitted -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "match permitopen localhost proto $p" start_client -F $OBJ/ssh_config ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ @@ -65,7 +65,7 @@ for p in 1 2; do done # Same but from different source. This should not be permitted -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "match permitopen proxy proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ @@ -74,11 +74,12 @@ for p in 1 2; do done # Retry previous with key option, should also be denied. -printf 'permitopen="127.0.0.1:'$PORT'" ' >$OBJ/authorized_keys_$USER -cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER -printf 'permitopen="127.0.0.1:'$PORT'" ' >>$OBJ/authorized_keys_$USER -cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER -for p in 1 2; do +cp /dev/null $OBJ/authorized_keys_$USER +for t in ${SSH_KEYTYPES}; do + printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER +done +for p in ${SSH_PROTOCOLS}; do trace "match permitopen proxy w/key opts proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ @@ -88,7 +89,7 @@ done # Test both sshd_config and key options permitting the same dst/port pair. # Should be permitted. -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "match permitopen localhost proto $p" start_client -F $OBJ/ssh_config ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ @@ -102,7 +103,7 @@ echo "Match User $USER" >>$OBJ/sshd_proxy echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy # Test that a Match overrides a PermitOpen in the global section -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "match permitopen proxy w/key opts proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \ @@ -117,7 +118,7 @@ echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy # Test that a rule that doesn't match doesn't override, plus test a # PermitOpen entry that's not at the start of the list -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "nomatch permitopen proxy w/key opts proto $p" start_client -F $OBJ/ssh_proxy ${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \ diff --git a/crypto/openssh/regress/cipher-speed.sh b/crypto/openssh/regress/cipher-speed.sh index a6d53a78d11f..ad2f9b90bc07 100644 --- a/crypto/openssh/regress/cipher-speed.sh +++ b/crypto/openssh/regress/cipher-speed.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cipher-speed.sh,v 1.11 2013/11/21 03:18:51 djm Exp $ +# $OpenBSD: cipher-speed.sh,v 1.12 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="cipher speed" @@ -31,7 +31,11 @@ for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do n=`expr $n + 1` done; done -ciphers="3des blowfish" +if ssh_version 1; then + ciphers="3des blowfish" +else + ciphers="" +fi for c in $ciphers; do trace "proto 1 cipher $c" for x in $tries; do diff --git a/crypto/openssh/regress/connect-privsep.sh b/crypto/openssh/regress/connect-privsep.sh index 41cb7af69641..9a51f569054c 100644 --- a/crypto/openssh/regress/connect-privsep.sh +++ b/crypto/openssh/regress/connect-privsep.sh @@ -1,4 +1,4 @@ -# $OpenBSD: connect-privsep.sh,v 1.5 2014/05/04 10:40:59 logan Exp $ +# $OpenBSD: connect-privsep.sh,v 1.6 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="proxy connect with privsep" @@ -6,7 +6,7 @@ tid="proxy connect with privsep" cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then fail "ssh privsep+proxyconnect protocol $p failed" @@ -16,7 +16,7 @@ done cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then # XXX replace this with fail once sandbox has stabilised @@ -27,7 +27,7 @@ done # Because sandbox is sensitive to changes in libc, especially malloc, retest # with every malloc.conf option (and none). for m in '' A F G H J P R S X '<' '>'; do - for p in 1 2; do + for p in ${SSH_PROTOCOLS}; do env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true if [ $? -ne 0 ]; then fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed" diff --git a/crypto/openssh/regress/connect.sh b/crypto/openssh/regress/connect.sh index 2186fa6e7eb9..f0d55d343d8a 100644 --- a/crypto/openssh/regress/connect.sh +++ b/crypto/openssh/regress/connect.sh @@ -1,11 +1,11 @@ -# $OpenBSD: connect.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# $OpenBSD: connect.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="simple connect" start_sshd -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect with protocol $p failed" diff --git a/crypto/openssh/regress/dynamic-forward.sh b/crypto/openssh/regress/dynamic-forward.sh index 42fa8acdcc19..dd67c9639eaf 100644 --- a/crypto/openssh/regress/dynamic-forward.sh +++ b/crypto/openssh/regress/dynamic-forward.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dynamic-forward.sh,v 1.10 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: dynamic-forward.sh,v 1.11 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="dynamic forwarding" @@ -17,7 +17,7 @@ trace "will use ProxyCommand $proxycmd" start_sshd -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do n=0 error="1" trace "start dynamic forwarding, fork to background" diff --git a/crypto/openssh/regress/exit-status.sh b/crypto/openssh/regress/exit-status.sh index 56b78a622b7a..397d8d732fed 100644 --- a/crypto/openssh/regress/exit-status.sh +++ b/crypto/openssh/regress/exit-status.sh @@ -1,9 +1,9 @@ -# $OpenBSD: exit-status.sh,v 1.6 2002/03/15 13:08:56 markus Exp $ +# $OpenBSD: exit-status.sh,v 1.7 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="remote exit status" -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do for s in 0 1 4 5 44; do trace "proto $p status $s" verbose "test $tid: proto $p status $s" diff --git a/crypto/openssh/regress/forcecommand.sh b/crypto/openssh/regress/forcecommand.sh index 44d2b7ffdaba..8a9b090ea5d8 100644 --- a/crypto/openssh/regress/forcecommand.sh +++ b/crypto/openssh/regress/forcecommand.sh @@ -1,30 +1,32 @@ -# $OpenBSD: forcecommand.sh,v 1.2 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: forcecommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="forced command" cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak -printf 'command="true" ' >$OBJ/authorized_keys_$USER -cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER -printf 'command="true" ' >>$OBJ/authorized_keys_$USER -cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER +cp /dev/null $OBJ/authorized_keys_$USER +for t in ${SSH_KEYTYPES}; do + printf 'command="true" ' >>$OBJ/authorized_keys_$USER + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER +done -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "forced command in key option proto $p" ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || fail "forced command in key proto $p" done -printf 'command="false" ' >$OBJ/authorized_keys_$USER -cat $OBJ/rsa.pub >> $OBJ/authorized_keys_$USER -printf 'command="false" ' >>$OBJ/authorized_keys_$USER -cat $OBJ/rsa1.pub >> $OBJ/authorized_keys_$USER +cp /dev/null $OBJ/authorized_keys_$USER +for t in ${SSH_KEYTYPES}; do + printf 'command="false" ' >> $OBJ/authorized_keys_$USER + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER +done cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "ForceCommand true" >> $OBJ/sshd_proxy -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "forced command in sshd_config overrides key option proto $p" ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || fail "forced command in key proto $p" @@ -35,7 +37,7 @@ echo "ForceCommand false" >> $OBJ/sshd_proxy echo "Match User $USER" >> $OBJ/sshd_proxy echo " ForceCommand true" >> $OBJ/sshd_proxy -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "forced command with match proto $p" ${SSH} -$p -F $OBJ/ssh_proxy somehost false \ || fail "forced command in key proto $p" diff --git a/crypto/openssh/regress/forward-control.sh b/crypto/openssh/regress/forward-control.sh index 7f7d105e85a6..91957098f7db 100755 --- a/crypto/openssh/regress/forward-control.sh +++ b/crypto/openssh/regress/forward-control.sh @@ -1,4 +1,4 @@ -# $OpenBSD: forward-control.sh,v 1.2 2013/11/18 05:09:32 naddy Exp $ +# $OpenBSD: forward-control.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="sshd control of local and remote forwarding" @@ -99,7 +99,7 @@ cp ${OBJ}/sshd_proxy ${OBJ}/sshd_proxy.bak cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak # Sanity check: ensure the default config allows forwarding -for p in 1 2 ; do +for p in ${SSH_PROTOCOLS} ; do check_lfwd $p Y "proto $p, default configuration" check_rfwd $p Y "proto $p, default configuration" done @@ -115,7 +115,7 @@ all_tests() { _permit_rfwd=$7 _badfwd=127.0.0.1:22 _goodfwd=127.0.0.1:${PORT} - for _proto in 1 2 ; do + for _proto in ${SSH_PROTOCOLS} ; do cp ${OBJ}/authorized_keys_${USER}.bak \ ${OBJ}/authorized_keys_${USER} _prefix="proto $_proto, AllowTcpForwarding=$_tcpfwd" diff --git a/crypto/openssh/regress/forwarding.sh b/crypto/openssh/regress/forwarding.sh index f799d49514ab..fb4f35aff61e 100644 --- a/crypto/openssh/regress/forwarding.sh +++ b/crypto/openssh/regress/forwarding.sh @@ -1,4 +1,4 @@ -# $OpenBSD: forwarding.sh,v 1.12 2014/07/15 15:54:15 millert Exp $ +# $OpenBSD: forwarding.sh,v 1.15 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="local and remote forwarding" @@ -10,6 +10,9 @@ start_sshd base=33 last=$PORT fwd="" +CTL=$OBJ/ctl-sock +rm -f $CTL + for j in 0 1 2; do for i in 0 1 2; do a=$base$j$i @@ -20,8 +23,11 @@ for j in 0 1 2; do last=$a done done -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do q=`expr 3 - $p` + if ! ssh_version $q; then + q=$p + fi trace "start forwarding, fork to background" ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10 @@ -34,7 +40,7 @@ for p in 1 2; do sleep 10 done -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do for d in L R; do trace "exit on -$d forward failure, proto $p" @@ -64,7 +70,7 @@ for d in L R; do done done -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "simple clear forwarding proto $p" ${SSH} -$p -F $OBJ/ssh_config -oClearAllForwardings=yes somehost true @@ -107,9 +113,9 @@ done echo "LocalForward ${base}01 127.0.0.1:$PORT" >> $OBJ/ssh_config echo "RemoteForward ${base}02 127.0.0.1:${base}01" >> $OBJ/ssh_config -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do trace "config file: start forwarding, fork to background" - ${SSH} -$p -F $OBJ/ssh_config -f somehost sleep 10 + ${SSH} -S $CTL -M -$p -F $OBJ/ssh_config -f somehost sleep 10 trace "config file: transfer over forwarded channels and check result" ${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \ @@ -117,7 +123,7 @@ for p in 1 2; do test -s ${COPY} || fail "failed copy of ${DATA}" cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}" - wait + ${SSH} -S $CTL -O exit somehost done for p in 2; do diff --git a/crypto/openssh/regress/host-expand.sh b/crypto/openssh/regress/host-expand.sh index 6cc0e6055eae..2a95bfe1b37b 100755 --- a/crypto/openssh/regress/host-expand.sh +++ b/crypto/openssh/regress/host-expand.sh @@ -1,4 +1,4 @@ -# $OpenBSD: host-expand.sh,v 1.3 2014/02/27 23:17:41 djm Exp $ +# $OpenBSD: host-expand.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="expand %h and %n" @@ -11,7 +11,7 @@ somehost 127.0.0.1 EOE -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "test $tid: proto $p" ${SSH} -F $OBJ/ssh_proxy -$p somehost true >$OBJ/actual diff $OBJ/expect $OBJ/actual || fail "$tid proto $p" diff --git a/crypto/openssh/regress/hostkey-agent.sh b/crypto/openssh/regress/hostkey-agent.sh new file mode 100755 index 000000000000..a011ec83107f --- /dev/null +++ b/crypto/openssh/regress/hostkey-agent.sh @@ -0,0 +1,52 @@ +# $OpenBSD: hostkey-agent.sh,v 1.5 2015/02/21 20:51:02 djm Exp $ +# Placed in the Public Domain. + +tid="hostkey agent" + +rm -f $OBJ/agent-key.* $OBJ/ssh_proxy.orig $OBJ/known_hosts.orig + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +[ $r -ne 0 ] && fatal "could not start ssh-agent: exit code $r" + +grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig +echo "HostKeyAgent $SSH_AUTH_SOCK" >> $OBJ/sshd_proxy.orig + +trace "load hostkeys" +for k in `${SSH} -Q key-plain` ; do + ${SSHKEYGEN} -qt $k -f $OBJ/agent-key.$k -N '' || fatal "ssh-keygen $k" + ( + printf 'localhost-with-alias,127.0.0.1,::1 ' + cat $OBJ/agent-key.$k.pub + ) >> $OBJ/known_hosts.orig + ${SSHADD} $OBJ/agent-key.$k >/dev/null 2>&1 || \ + fatal "couldn't load key $OBJ/agent-key.$k" + echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy.orig + # Remove private key so the server can't use it. + rm $OBJ/agent-key.$k || fatal "couldn't rm $OBJ/agent-key.$k" +done +cp $OBJ/known_hosts.orig $OBJ/known_hosts + +unset SSH_AUTH_SOCK + +for ps in no yes; do + cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy + for k in `${SSH} -Q key-plain` ; do + verbose "key type $k privsep=$ps" + opts="-oHostKeyAlgorithms=$k -F $OBJ/ssh_proxy" + cp $OBJ/known_hosts.orig $OBJ/known_hosts + SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` + if [ $? -ne 0 ]; then + fail "protocol $p privsep=$ps failed" + fi + if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION key type $k privsep=$ps" + fi + done +done + +trace "kill agent" +${SSHAGENT} -k > /dev/null + diff --git a/crypto/openssh/regress/hostkey-rotate.sh b/crypto/openssh/regress/hostkey-rotate.sh new file mode 100755 index 000000000000..b5d542d1208e --- /dev/null +++ b/crypto/openssh/regress/hostkey-rotate.sh @@ -0,0 +1,128 @@ +# $OpenBSD: hostkey-rotate.sh,v 1.2 2015/03/03 17:53:40 djm Exp $ +# Placed in the Public Domain. + +tid="hostkey rotate" + +# Need full names here since they are used in HostKeyAlgorithms +HOSTKEY_TYPES="ecdsa-sha2-nistp256 ssh-ed25519 ssh-rsa ssh-dss" + +rm -f $OBJ/hkr.* $OBJ/ssh_proxy.orig + +grep -vi 'hostkey' $OBJ/sshd_proxy > $OBJ/sshd_proxy.orig +echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy +rm $OBJ/known_hosts + +trace "prepare hostkeys" +nkeys=0 +all_algs="" +for k in `ssh -Q key-plain` ; do + ${SSHKEYGEN} -qt $k -f $OBJ/hkr.$k -N '' || fatal "ssh-keygen $k" + echo "Hostkey $OBJ/hkr.${k}" >> $OBJ/sshd_proxy.orig + nkeys=`expr $nkeys + 1` + test "x$all_algs" = "x" || all_algs="${all_algs}," + all_algs="${all_algs}$k" +done + +dossh() { + # All ssh should succeed in this test + ${SSH} -F $OBJ/ssh_proxy "$@" x true || fail "ssh $@ failed" +} + +expect_nkeys() { + _expected=$1 + _message=$2 + _n=`wc -l $OBJ/known_hosts | awk '{ print $1 }'` || fatal "wc failed" + [ "x$_n" = "x$_expected" ] || fail "$_message (got $_n wanted $_expected)" +} + +check_key_present() { + _type=$1 + _kfile=$2 + test "x$_kfile" = "x" && _kfile="$OBJ/hkr.${_type}.pub" + _kpub=`awk "/$_type /"' { print $2 }' < $_kfile` || \ + fatal "awk failed" + fgrep "$_kpub" $OBJ/known_hosts > /dev/null +} + +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy + +# Connect to sshd with StrictHostkeyChecking=no +verbose "learn hostkey with StrictHostKeyChecking=no" +>$OBJ/known_hosts +dossh -oHostKeyAlgorithms=ssh-ed25519 -oStrictHostKeyChecking=no +# Verify no additional keys learned +expect_nkeys 1 "unstrict connect keys" +check_key_present ssh-ed25519 || fail "unstrict didn't learn key" + +# Connect to sshd as usual +verbose "learn additional hostkeys" +dossh -oStrictHostKeyChecking=yes +# Check that other keys learned +expect_nkeys $nkeys "learn hostkeys" +check_key_present ssh-rsa || fail "didn't learn keys" + +# Check each key type +for k in `ssh -Q key-plain` ; do + verbose "learn additional hostkeys, type=$k" + dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=$k,$all_algs + expect_nkeys $nkeys "learn hostkeys $k" + check_key_present $k || fail "didn't learn $k" +done + +# Change one hostkey (non primary) and relearn +verbose "learn changed non-primary hostkey" +mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old +rm -f $OBJ/hkr.ssh-rsa +${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa -N '' || fatal "ssh-keygen $k" +dossh -oStrictHostKeyChecking=yes +# Check that the key was replaced +expect_nkeys $nkeys "learn hostkeys" +check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" +check_key_present ssh-rsa || fail "didn't learn changed key" + +# Add new hostkey (primary type) to sshd and connect +verbose "learn new primary hostkey" +${SSHKEYGEN} -qt ssh-rsa -f $OBJ/hkr.ssh-rsa-new -N '' || fatal "ssh-keygen $k" +( cat $OBJ/sshd_proxy.orig ; echo HostKey $OBJ/hkr.ssh-rsa-new ) \ + > $OBJ/sshd_proxy +# Check new hostkey added +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs +expect_nkeys `expr $nkeys + 1` "learn hostkeys" +check_key_present ssh-rsa || fail "current key missing" +check_key_present ssh-rsa $OBJ/hkr.ssh-rsa-new.pub || fail "new key missing" + +# Remove old hostkey (primary type) from sshd +verbose "rotate primary hostkey" +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy +mv $OBJ/hkr.ssh-rsa.pub $OBJ/hkr.ssh-rsa.pub.old +mv $OBJ/hkr.ssh-rsa-new.pub $OBJ/hkr.ssh-rsa.pub +mv $OBJ/hkr.ssh-rsa-new $OBJ/hkr.ssh-rsa +# Check old hostkey removed +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa,$all_algs +expect_nkeys $nkeys "learn hostkeys" +check_key_present ssh-rsa $OBJ/hkr.ssh-rsa.pub.old && fail "old key present" +check_key_present ssh-rsa || fail "didn't learn changed key" + +# Connect again, forcing rotated key +verbose "check rotate primary hostkey" +dossh -oStrictHostKeyChecking=yes -oHostKeyAlgorithms=ssh-rsa +expect_nkeys 1 "learn hostkeys" +check_key_present ssh-rsa || fail "didn't learn changed key" + +# $OpenBSD: hostkey-rotate.sh,v 1.2 2015/03/03 17:53:40 djm Exp $ +# Placed in the Public Domain. + +tid="hostkey rotate" + +# Prepare hostkeys file with one key + +# Connect to sshd + +# Check that other keys learned + +# Change one hostkey (non primary) + +# Connect to sshd + +# Check that the key was replaced + diff --git a/crypto/openssh/regress/integrity.sh b/crypto/openssh/regress/integrity.sh index d3a489ff78a0..2ff8b3f17d1c 100755 --- a/crypto/openssh/regress/integrity.sh +++ b/crypto/openssh/regress/integrity.sh @@ -1,4 +1,4 @@ -# $OpenBSD: integrity.sh,v 1.14 2014/05/21 07:04:21 djm Exp $ +# $OpenBSD: integrity.sh,v 1.15 2015/01/19 20:42:31 markus Exp $ # Placed in the Public Domain. tid="integrity" @@ -20,7 +20,7 @@ echo "KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1" \ >> $OBJ/ssh_proxy # sshd-command for proxy (see test-exec.sh) -cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy" +cmd="$SUDO sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" for m in $macs; do trace "test $tid: mac $m" @@ -58,7 +58,7 @@ for m in $macs; do tr -s '\r\n' '.') case "$out" in Bad?packet*) elen=`expr $elen + 1`; skip=3;; - Corrupted?MAC* | Decryption?integrity?check?failed*) + Corrupted?MAC* | *message?authentication?code?incorrect*) emac=`expr $emac + 1`; skip=0;; padding*) epad=`expr $epad + 1`; skip=0;; *) fail "unexpected error mac $m at $off: $out";; diff --git a/crypto/openssh/regress/key-options.sh b/crypto/openssh/regress/key-options.sh index f98d78b30774..7a68ad358b76 100755 --- a/crypto/openssh/regress/key-options.sh +++ b/crypto/openssh/regress/key-options.sh @@ -1,4 +1,4 @@ -# $OpenBSD: key-options.sh,v 1.2 2008/06/30 08:07:34 djm Exp $ +# $OpenBSD: key-options.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="key options" @@ -8,7 +8,7 @@ authkeys="$OBJ/authorized_keys_${USER}" cp $authkeys $origkeys # Test command= forced command -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do for c in 'command="echo bar"' 'no-pty,command="echo bar"'; do sed "s/.*/$c &/" $origkeys >$authkeys verbose "key option proto $p $c" @@ -24,7 +24,7 @@ done # Test no-pty sed 's/.*/no-pty &/' $origkeys >$authkeys -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "key option proto $p no-pty" r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost tty` if [ -f "$r" ]; then @@ -35,7 +35,7 @@ done # Test environment= echo 'PermitUserEnvironment yes' >> $OBJ/sshd_proxy sed 's/.*/environment="FOO=bar" &/' $origkeys >$authkeys -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "key option proto $p environment" r=`${SSH} -$p -q -F $OBJ/ssh_proxy somehost 'echo $FOO'` if [ "$r" != "bar" ]; then @@ -45,7 +45,7 @@ done # Test from= restriction start_sshd -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do for f in 127.0.0.1 '127.0.0.0\/8'; do cat $origkeys >$authkeys ${SSH} -$p -q -F $OBJ/ssh_proxy somehost true diff --git a/crypto/openssh/regress/keygen-change.sh b/crypto/openssh/regress/keygen-change.sh index 08d35902301b..e56185050ddf 100644 --- a/crypto/openssh/regress/keygen-change.sh +++ b/crypto/openssh/regress/keygen-change.sh @@ -1,4 +1,4 @@ -# $OpenBSD: keygen-change.sh,v 1.2 2002/07/16 09:15:55 markus Exp $ +# $OpenBSD: keygen-change.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="change passphrase for key" @@ -6,7 +6,12 @@ tid="change passphrase for key" S1="secret1" S2="2secret" -for t in rsa dsa rsa1; do +KEYTYPES=`${SSH} -Q key-plain` +if ssh_version 1; then + KEYTYPES="${KEYTYPES} rsa1" +fi + +for t in $KEYTYPES; do # generate user key for agent trace "generating $t key" rm -f $OBJ/$t-key diff --git a/crypto/openssh/regress/keygen-knownhosts.sh b/crypto/openssh/regress/keygen-knownhosts.sh new file mode 100755 index 000000000000..085aac650fab --- /dev/null +++ b/crypto/openssh/regress/keygen-knownhosts.sh @@ -0,0 +1,197 @@ +# $OpenBSD: keygen-knownhosts.sh,v 1.2 2015/01/27 12:01:36 djm Exp $ +# Placed in the Public Domain. + +tid="ssh-keygen known_hosts" + +rm -f $OBJ/kh.* + +# Generate some keys for testing (just ed25519 for speed) and make a hosts file. +for x in host-a host-b host-c host-d host-e host-f host-a2 host-b2; do + ${SSHKEYGEN} -qt ed25519 -f $OBJ/kh.$x -C "$x" -N "" || \ + fatal "ssh-keygen failed" + # Add a comment that we expect should be preserved. + echo "# $x" >> $OBJ/kh.hosts + ( + case "$x" in + host-a|host-b) printf "$x " ;; + host-c) printf "@cert-authority $x " ;; + host-d) printf "@revoked $x " ;; + host-e) printf "host-e* " ;; + host-f) printf "host-f,host-g,host-h " ;; + host-a2) printf "host-a " ;; + host-b2) printf "host-b " ;; + esac + cat $OBJ/kh.${x}.pub + # Blank line should be preserved. + echo "" >> $OBJ/kh.hosts + ) >> $OBJ/kh.hosts +done + +# Generate a variant with an invalid line. We'll use this for most tests, +# because keygen should be able to cope and it should be preserved in any +# output file. +cat $OBJ/kh.hosts >> $OBJ/kh.invalid +echo "host-i " >> $OBJ/kh.invalid + +cp $OBJ/kh.invalid $OBJ/kh.invalid.orig +cp $OBJ/kh.hosts $OBJ/kh.hosts.orig + +expect_key() { + _host=$1 + _hosts=$2 + _key=$3 + _line=$4 + _mark=$5 + _marker="" + test "x$_mark" = "xCA" && _marker="@cert-authority " + test "x$_mark" = "xREVOKED" && _marker="@revoked " + test "x$_line" != "x" && + echo "# Host $_host found: line $_line $_mark" >> $OBJ/kh.expect + printf "${_marker}$_hosts " >> $OBJ/kh.expect + cat $OBJ/kh.${_key}.pub >> $OBJ/kh.expect || + fatal "${_key}.pub missing" +} + +check_find() { + _host=$1 + _name=$2 + _keygenopt=$3 + ${SSHKEYGEN} $_keygenopt -f $OBJ/kh.invalid -F $_host > $OBJ/kh.result + if ! diff -uw $OBJ/kh.expect $OBJ/kh.result ; then + fail "didn't find $_name" + fi +} + +# Find key +rm -f $OBJ/kh.expect +expect_key host-a host-a host-a 2 +expect_key host-a host-a host-a2 20 +check_find host-a "simple find" + +# find CA key +rm -f $OBJ/kh.expect +expect_key host-c host-c host-c 8 CA +check_find host-c "find CA key" + +# find revoked key +rm -f $OBJ/kh.expect +expect_key host-d host-d host-d 11 REVOKED +check_find host-d "find revoked key" + +# find key with wildcard +rm -f $OBJ/kh.expect +expect_key host-e.somedomain "host-e*" host-e 14 +check_find host-e.somedomain "find wildcard key" + +# find key among multiple hosts +rm -f $OBJ/kh.expect +expect_key host-h "host-f,host-g,host-h " host-f 17 +check_find host-h "find multiple hosts" + +check_hashed_find() { + _host=$1 + _name=$2 + _file=$3 + test "x$_file" = "x" && _file=$OBJ/kh.invalid + ${SSHKEYGEN} -f $_file -HF $_host | grep '|1|' | \ + sed "s/^[^ ]*/$_host/" > $OBJ/kh.result + if ! diff -uw $OBJ/kh.expect $OBJ/kh.result ; then + fail "didn't find $_name" + fi +} + +# Find key and hash +rm -f $OBJ/kh.expect +expect_key host-a host-a host-a +expect_key host-a host-a host-a2 +check_hashed_find host-a "find simple and hash" + +# Find CA key and hash +rm -f $OBJ/kh.expect +expect_key host-c host-c host-c "" CA +# CA key output is not hashed. +check_find host-c "find simple and hash" -H + +# Find revoked key and hash +rm -f $OBJ/kh.expect +expect_key host-d host-d host-d "" REVOKED +# Revoked key output is not hashed. +check_find host-d "find simple and hash" -H + +# find key with wildcard and hash +rm -f $OBJ/kh.expect +expect_key host-e "host-e*" host-e "" +# Key with wildcard hostname should not be hashed. +check_find host-e "find wildcard key" -H + +# find key among multiple hosts +rm -f $OBJ/kh.expect +# Comma-separated hostnames should be expanded and hashed. +expect_key host-f "host-h " host-f +expect_key host-g "host-h " host-f +expect_key host-h "host-h " host-f +check_hashed_find host-h "find multiple hosts" + +# Attempt remove key on invalid file. +cp $OBJ/kh.invalid.orig $OBJ/kh.invalid +${SSHKEYGEN} -qf $OBJ/kh.invalid -R host-a 2>/dev/null +diff -u $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "remove on invalid succeeded" + +# Remove key +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-a 2>/dev/null +grep -v "^host-a " $OBJ/kh.hosts.orig > $OBJ/kh.expect +diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove simple" + +# Remove CA key +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-c 2>/dev/null +# CA key should not be removed. +diff -u $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove CA" + +# Remove revoked key +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-d 2>/dev/null +# revoked key should not be removed. +diff -u $OBJ/kh.hosts $OBJ/kh.hosts.orig || fail "remove revoked" + +# Remove wildcard +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-e.blahblah 2>/dev/null +grep -v "^host-e[*] " $OBJ/kh.hosts.orig > $OBJ/kh.expect +diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" + +# Remove multiple +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -R host-h 2>/dev/null +grep -v "^host-f," $OBJ/kh.hosts.orig > $OBJ/kh.expect +diff -u $OBJ/kh.hosts $OBJ/kh.expect || fail "remove wildcard" + +# Attempt hash on invalid file +cp $OBJ/kh.invalid.orig $OBJ/kh.invalid +${SSHKEYGEN} -qf $OBJ/kh.invalid -H 2>/dev/null && fail "hash invalid succeeded" +diff -u $OBJ/kh.invalid $OBJ/kh.invalid.orig || fail "invalid file modified" + +# Hash valid file +cp $OBJ/kh.hosts.orig $OBJ/kh.hosts +${SSHKEYGEN} -qf $OBJ/kh.hosts -H 2>/dev/null || fail "hash failed" +diff -u $OBJ/kh.hosts.old $OBJ/kh.hosts.orig || fail "backup differs" +grep "^host-[abfgh]" $OBJ/kh.hosts && fail "original hostnames persist" + +cp $OBJ/kh.hosts $OBJ/kh.hashed.orig + +# Test lookup +rm -f $OBJ/kh.expect +expect_key host-a host-a host-a +expect_key host-a host-a host-a2 +check_hashed_find host-a "find simple in hashed" $OBJ/kh.hosts + +# Test multiple expanded +rm -f $OBJ/kh.expect +expect_key host-h host-h host-f +check_hashed_find host-h "find simple in hashed" $OBJ/kh.hosts + +# Test remove +cp $OBJ/kh.hashed.orig $OBJ/kh.hashed +${SSHKEYGEN} -qf $OBJ/kh.hashed -R host-a 2>/dev/null +${SSHKEYGEN} -qf $OBJ/kh.hashed -F host-a && fail "found key after hashed remove" diff --git a/crypto/openssh/regress/keyscan.sh b/crypto/openssh/regress/keyscan.sh index 33f14f0fcc9d..886f3295ae7c 100644 --- a/crypto/openssh/regress/keyscan.sh +++ b/crypto/openssh/regress/keyscan.sh @@ -1,4 +1,4 @@ -# $OpenBSD: keyscan.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ +# $OpenBSD: keyscan.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="keyscan" @@ -8,7 +8,12 @@ rm -f ${OBJ}/host.dsa start_sshd -for t in rsa1 rsa dsa; do +KEYTYPES="rsa dsa" +if ssh_version 1; then + KEYTYPES="${KEYTYPES} rsa1" +fi + +for t in $KEYTYPES; do trace "keyscan type $t" ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ > /dev/null 2>&1 diff --git a/crypto/openssh/regress/krl.sh b/crypto/openssh/regress/krl.sh index 287384b4af2b..1077358ff9f0 100755 --- a/crypto/openssh/regress/krl.sh +++ b/crypto/openssh/regress/krl.sh @@ -1,4 +1,4 @@ -# $OpenBSD: krl.sh,v 1.3 2014/06/24 01:04:43 djm Exp $ +# $OpenBSD: krl.sh,v 1.6 2015/01/30 01:11:39 djm Exp $ # Placed in the Public Domain. tid="key revocation lists" @@ -17,6 +17,8 @@ rm -f $OBJ/revoked-* $OBJ/krl-* # Generate a CA key $SSHKEYGEN -t $ECDSA -f $OBJ/revoked-ca -C "" -N "" > /dev/null || fatal "$SSHKEYGEN CA failed" +$SSHKEYGEN -t ed25519 -f $OBJ/revoked-ca2 -C "" -N "" > /dev/null || + fatal "$SSHKEYGEN CA2 failed" # A specification that revokes some certificates by serial numbers # The serial pattern is chosen to ensure the KRL includes list, range and @@ -45,6 +47,7 @@ EOF # A specification that revokes some certificated by key ID. touch $OBJ/revoked-keyid for n in 1 2 3 4 10 15 30 50 `jot 500 300` 999 1000 1001 1002; do + test "x$n" = "x499" && continue # Fill in by-ID revocation spec. echo "id: revoked $n" >> $OBJ/revoked-keyid done @@ -56,7 +59,7 @@ keygen() { keytype=$ECDSA case $N in 2 | 10 | 510 | 1001) keytype=rsa;; - 4 | 30 | 520 | 1002) keytype=dsa;; + 4 | 30 | 520 | 1002) keytype=ed25519;; esac $SSHKEYGEN -t $keytype -f $f -C "" -N "" > /dev/null \ || fatal "$SSHKEYGEN failed" @@ -71,37 +74,48 @@ verbose "$tid: generating test keys" REVOKED_SERIALS="1 4 10 50 500 510 520 799 999" for n in $REVOKED_SERIALS ; do f=`keygen $n` - REVOKED_KEYS="$REVOKED_KEYS ${f}.pub" - REVOKED_CERTS="$REVOKED_CERTS ${f}-cert.pub" + RKEYS="$RKEYS ${f}.pub" + RCERTS="$RCERTS ${f}-cert.pub" done -NOTREVOKED_SERIALS="5 9 14 16 29 30 49 51 499 800 1000 1001" -NOTREVOKED="" -for n in $NOTREVOKED_SERIALS ; do - NOTREVOKED_KEYS="$NOTREVOKED_KEYS ${f}.pub" - NOTREVOKED_CERTS="$NOTREVOKED_CERTS ${f}-cert.pub" +UNREVOKED_SERIALS="5 9 14 16 29 49 51 499 800 1010 1011" +UNREVOKED="" +for n in $UNREVOKED_SERIALS ; do + f=`keygen $n` + UKEYS="$UKEYS ${f}.pub" + UCERTS="$UCERTS ${f}-cert.pub" done genkrls() { OPTS=$1 $SSHKEYGEN $OPTS -kf $OBJ/krl-empty - /dev/null || fatal "$SSHKEYGEN KRL failed" -$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $REVOKED_KEYS \ +$SSHKEYGEN $OPTS -kf $OBJ/krl-keys $RKEYS \ >/dev/null || fatal "$SSHKEYGEN KRL failed" -$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $REVOKED_CERTS \ +$SSHKEYGEN $OPTS -kf $OBJ/krl-cert $RCERTS \ >/dev/null || fatal "$SSHKEYGEN KRL failed" -$SSHKEYGEN $OPTS -kf $OBJ/krl-all $REVOKED_KEYS $REVOKED_CERTS \ +$SSHKEYGEN $OPTS -kf $OBJ/krl-all $RKEYS $RCERTS \ >/dev/null || fatal "$SSHKEYGEN KRL failed" $SSHKEYGEN $OPTS -kf $OBJ/krl-ca $OBJ/revoked-ca.pub \ >/dev/null || fatal "$SSHKEYGEN KRL failed" -# KRLs from serial/key-id spec need the CA specified. +# This should fail as KRLs from serial/key-id spec need the CA specified. $SSHKEYGEN $OPTS -kf $OBJ/krl-serial $OBJ/revoked-serials \ >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" $SSHKEYGEN $OPTS -kf $OBJ/krl-keyid $OBJ/revoked-keyid \ >/dev/null 2>&1 && fatal "$SSHKEYGEN KRL succeeded unexpectedly" -$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca $OBJ/revoked-serials \ +# These should succeed; they specify an explicit CA key. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -s $OBJ/revoked-ca \ + $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" +$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub \ + $OBJ/revoked-keyid >/dev/null || fatal "$SSHKEYGEN KRL failed" +# These should succeed; they specify an wildcard CA key. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial-wild -s NONE $OBJ/revoked-serials \ >/dev/null || fatal "$SSHKEYGEN KRL failed" -$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid -s $OBJ/revoked-ca.pub $OBJ/revoked-keyid \ +$SSHKEYGEN $OPTS -kf $OBJ/krl-keyid-wild -s NONE $OBJ/revoked-keyid \ >/dev/null || fatal "$SSHKEYGEN KRL failed" +# Revoke the same serials with the second CA key to ensure a multi-CA +# KRL is generated. +$SSHKEYGEN $OPTS -kf $OBJ/krl-serial -u -s $OBJ/revoked-ca2 \ + $OBJ/revoked-serials >/dev/null || fatal "$SSHKEYGEN KRL failed" } ## XXX dump with trace and grep for set cert serials @@ -123,7 +137,7 @@ check_krl() { fatal "key $KEY unexpectedly revoked by KRL $KRL: $TAG" fi } -test_all() { +test_rev() { FILES=$1 TAG=$2 KEYS_RESULT=$3 @@ -132,32 +146,40 @@ test_all() { KEYID_RESULT=$6 CERTS_RESULT=$7 CA_RESULT=$8 + SERIAL_WRESULT=$9 + KEYID_WRESULT=$10 verbose "$tid: checking revocations for $TAG" for f in $FILES ; do - check_krl $f $OBJ/krl-empty no "$TAG" - check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" - check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" - check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" - check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" - check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" - check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" + check_krl $f $OBJ/krl-empty no "$TAG" + check_krl $f $OBJ/krl-keys $KEYS_RESULT "$TAG" + check_krl $f $OBJ/krl-all $ALL_RESULT "$TAG" + check_krl $f $OBJ/krl-serial $SERIAL_RESULT "$TAG" + check_krl $f $OBJ/krl-keyid $KEYID_RESULT "$TAG" + check_krl $f $OBJ/krl-cert $CERTS_RESULT "$TAG" + check_krl $f $OBJ/krl-ca $CA_RESULT "$TAG" + check_krl $f $OBJ/krl-serial-wild $SERIAL_WRESULT "$TAG" + check_krl $f $OBJ/krl-keyid-wild $KEYID_WRESULT "$TAG" done } -# keys all serial keyid certs CA -test_all "$REVOKED_KEYS" "revoked keys" yes yes no no no no -test_all "$UNREVOKED_KEYS" "unrevoked keys" no no no no no no -test_all "$REVOKED_CERTS" "revoked certs" yes yes yes yes yes yes -test_all "$UNREVOKED_CERTS" "unrevoked certs" no no no no no yes + +test_all() { + # wildcard + # keys all sr# k.ID cert CA sr.# k.ID + test_rev "$RKEYS" "revoked keys" yes yes no no no no no no + test_rev "$UKEYS" "unrevoked keys" no no no no no no no no + test_rev "$RCERTS" "revoked certs" yes yes yes yes yes yes yes yes + test_rev "$UCERTS" "unrevoked certs" no no no no no yes no no +} + +test_all # Check update. Results should be identical. verbose "$tid: testing KRL update" for f in $OBJ/krl-keys $OBJ/krl-cert $OBJ/krl-all \ - $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid ; do + $OBJ/krl-ca $OBJ/krl-serial $OBJ/krl-keyid \ + $OBJ/krl-serial-wild $OBJ/krl-keyid-wild; do cp -f $OBJ/krl-empty $f genkrls -u done -# keys all serial keyid certs CA -test_all "$REVOKED_KEYS" "revoked keys" yes yes no no no no -test_all "$UNREVOKED_KEYS" "unrevoked keys" no no no no no no -test_all "$REVOKED_CERTS" "revoked certs" yes yes yes yes yes yes -test_all "$UNREVOKED_CERTS" "unrevoked certs" no no no no no yes + +test_all diff --git a/crypto/openssh/regress/limit-keytype.sh b/crypto/openssh/regress/limit-keytype.sh new file mode 100755 index 000000000000..2de037bd1edb --- /dev/null +++ b/crypto/openssh/regress/limit-keytype.sh @@ -0,0 +1,80 @@ +# $OpenBSD: limit-keytype.sh,v 1.1 2015/01/13 07:49:49 djm Exp $ +# Placed in the Public Domain. + +tid="restrict pubkey type" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* +rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* + +mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig +mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig + +# Create a CA key +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ + fatal "ssh-keygen failed" + +# Make some keys and a certificate. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key2 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_key3 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key3 || + fatal "couldn't sign user_key1" +# Copy the private key alongside the cert to allow better control of when +# it is offered. +mv $OBJ/user_key3-cert.pub $OBJ/cert_user_key3.pub +cp -p $OBJ/user_key3 $OBJ/cert_user_key3 + +grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy + +opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" +fullopts="$opts -i $OBJ/cert_user_key3 -i $OBJ/user_key1 -i $OBJ/user_key2" + +echo mekmitasdigoat > $OBJ/authorized_principals_$USER +cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER +cat $OBJ/user_key2.pub >> $OBJ/authorized_keys_$USER + +prepare_config() { + ( + grep -v "Protocol" $OBJ/sshd_proxy.orig + echo "Protocol 2" + echo "AuthenticationMethods publickey" + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" + echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + for x in "$@" ; do + echo "$x" + done + ) > $OBJ/sshd_proxy +} + +prepare_config + +# Check we can log in with all key types. +${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" + +# Allow plain Ed25519 and RSA. The certificate should fail. +verbose "privsep=$privsep allow rsa,ed25519" +prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519" +${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" + +# Allow Ed25519 only. +verbose "privsep=$privsep allow ed25519" +prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519" +${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" + +# Allow all certs. Plain keys should fail. +verbose "privsep=$privsep allow cert only" +prepare_config "PubkeyAcceptedKeyTypes ssh-*-cert-v01@openssh.com" +${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" +${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" +${SSH} $opts -i $OBJ/user_key2 proxy true && fatal "key2 succeeded" + diff --git a/crypto/openssh/regress/localcommand.sh b/crypto/openssh/regress/localcommand.sh index 8a9b569717d5..220f19a4d48b 100755 --- a/crypto/openssh/regress/localcommand.sh +++ b/crypto/openssh/regress/localcommand.sh @@ -1,4 +1,4 @@ -# $OpenBSD: localcommand.sh,v 1.2 2013/05/17 10:24:48 dtucker Exp $ +# $OpenBSD: localcommand.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="localcommand" @@ -6,7 +6,7 @@ tid="localcommand" echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy echo 'LocalCommand echo foo' >> $OBJ/ssh_proxy -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "test $tid: proto $p localcommand" a=`${SSH} -F $OBJ/ssh_proxy -$p somehost true` if [ "$a" != "foo" ] ; then diff --git a/crypto/openssh/regress/multiplex.sh b/crypto/openssh/regress/multiplex.sh index 8ee140be6dd9..acb9234d9a94 100644 --- a/crypto/openssh/regress/multiplex.sh +++ b/crypto/openssh/regress/multiplex.sh @@ -1,24 +1,11 @@ -# $OpenBSD: multiplex.sh,v 1.25 2014/07/22 01:32:12 djm Exp $ +# $OpenBSD: multiplex.sh,v 1.27 2014/12/22 06:14:29 djm Exp $ # Placed in the Public Domain. CTL=/tmp/openssh.regress.ctl-sock.$$ tid="connection multiplexing" -if have_prog nc ; then - if nc -h 2>&1 | grep -- -N >/dev/null; then - NC="nc -N"; - elif nc -h 2>&1 | grep -- "-U.*Use UNIX" >/dev/null ; then - NC="nc" - else - echo "nc is incompatible" - fi -fi - -if test -z "$NC" ; then - echo "skipped (no compatible nc found)" - exit 0 -fi +NC=$OBJ/netcat trace "will use ProxyCommand $proxycmd" if config_defined DISABLE_FD_PASSING ; then @@ -90,20 +77,20 @@ cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" rm -f ${COPY} verbose "test $tid: forward" trace "forward over TCP/IP and check result" -$NC -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} & +$NC -N -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} > /dev/null & netcat_pid=$! ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1 -$NC -d 127.0.0.1 $((${PORT} + 2)) > ${COPY} < /dev/null +$NC 127.0.0.1 $((${PORT} + 2)) < /dev/null > ${COPY} cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" kill $netcat_pid 2>/dev/null rm -f ${COPY} $OBJ/unix-[123].fwd trace "forward over UNIX and check result" -$NC -Ul $OBJ/unix-1.fwd < ${DATA} & +$NC -N -Ul $OBJ/unix-1.fwd < ${DATA} > /dev/null & netcat_pid=$! ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 ${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 -$NC -d -U $OBJ/unix-3.fwd > ${COPY} ${COPY} 2>/dev/null cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" kill $netcat_pid 2>/dev/null rm -f ${COPY} $OBJ/unix-[123].fwd diff --git a/crypto/openssh/regress/multipubkey.sh b/crypto/openssh/regress/multipubkey.sh new file mode 100755 index 000000000000..e9d15306ff2f --- /dev/null +++ b/crypto/openssh/regress/multipubkey.sh @@ -0,0 +1,66 @@ +# $OpenBSD: multipubkey.sh,v 1.1 2014/12/22 08:06:03 djm Exp $ +# Placed in the Public Domain. + +tid="multiple pubkey" + +rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/user_key* +rm -f $OBJ/authorized_principals_$USER $OBJ/cert_user_key* + +mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig +mv $OBJ/ssh_proxy $OBJ/ssh_proxy.orig + +# Create a CA key +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key ||\ + fatal "ssh-keygen failed" + +# Make some keys and a certificate. +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key1 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key2 || \ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "regress user key for $USER" \ + -z $$ -n ${USER},mekmitasdigoat $OBJ/user_key1 || + fail "couldn't sign user_key1" +# Copy the private key alongside the cert to allow better control of when +# it is offered. +mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1.pub +cp -p $OBJ/user_key1 $OBJ/cert_user_key1 + +grep -v IdentityFile $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy + +opts="-oProtocol=2 -F $OBJ/ssh_proxy -oIdentitiesOnly=yes" +opts="$opts -i $OBJ/cert_user_key1 -i $OBJ/user_key1 -i $OBJ/user_key2" + +for privsep in no yes; do + ( + grep -v "Protocol" $OBJ/sshd_proxy.orig + echo "Protocol 2" + echo "UsePrivilegeSeparation $privsep" + echo "AuthenticationMethods publickey,publickey" + echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" + echo "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + ) > $OBJ/sshd_proxy + + # Single key should fail. + rm -f $OBJ/authorized_principals_$USER + cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true && fail "ssh succeeded with key" + + # Single key with same-public cert should fail. + echo mekmitasdigoat > $OBJ/authorized_principals_$USER + cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true && fail "ssh succeeded with key+cert" + + # Multiple plain keys should succeed. + rm -f $OBJ/authorized_principals_$USER + cat $OBJ/user_key1.pub $OBJ/user_key2.pub > \ + $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true || fail "ssh failed with multiple keys" + # Cert and different key should succeed + + # Key and different-public cert should succeed. + echo mekmitasdigoat > $OBJ/authorized_principals_$USER + cat $OBJ/user_key2.pub > $OBJ/authorized_keys_$USER + ${SSH} $opts proxy true || fail "ssh failed with key/cert" +done + diff --git a/crypto/openssh/regress/netcat.c b/crypto/openssh/regress/netcat.c new file mode 100644 index 000000000000..1a9fc8730012 --- /dev/null +++ b/crypto/openssh/regress/netcat.c @@ -0,0 +1,1690 @@ +/* $OpenBSD: netcat.c,v 1.126 2014/10/30 16:08:31 tedu Exp $ */ +/* + * Copyright (c) 2001 Eric Jackson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Re-written nc(1) for OpenBSD. Original implementation by + * *Hobbit* . + */ + +#include "includes.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "atomicio.h" + +#ifdef HAVE_POLL_H +#include +#else +# ifdef HAVE_SYS_POLL_H +# include +# endif +#endif + +#ifndef SUN_LEN +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif + +#define PORT_MAX 65535 +#define PORT_MAX_LEN 6 +#define UNIX_DG_TMP_SOCKET_SIZE 19 + +#define POLL_STDIN 0 +#define POLL_NETOUT 1 +#define POLL_NETIN 2 +#define POLL_STDOUT 3 +#define BUFSIZE 16384 + +/* Command Line Options */ +int dflag; /* detached, no stdin */ +int Fflag; /* fdpass sock to stdout */ +unsigned int iflag; /* Interval Flag */ +int kflag; /* More than one connect */ +int lflag; /* Bind to local port */ +int Nflag; /* shutdown() network socket */ +int nflag; /* Don't do name look up */ +char *Pflag; /* Proxy username */ +char *pflag; /* Localport flag */ +int rflag; /* Random ports flag */ +char *sflag; /* Source Address */ +int tflag; /* Telnet Emulation */ +int uflag; /* UDP - Default to TCP */ +int vflag; /* Verbosity */ +int xflag; /* Socks proxy */ +int zflag; /* Port Scan Flag */ +int Dflag; /* sodebug */ +int Iflag; /* TCP receive buffer size */ +int Oflag; /* TCP send buffer size */ +int Sflag; /* TCP MD5 signature option */ +int Tflag = -1; /* IP Type of Service */ +int rtableid = -1; + +int timeout = -1; +int family = AF_UNSPEC; +char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; + +void atelnet(int, unsigned char *, unsigned int); +void build_ports(char *); +void help(void); +int local_listen(char *, char *, struct addrinfo); +void readwrite(int); +void fdpass(int nfd) __attribute__((noreturn)); +int remote_connect(const char *, const char *, struct addrinfo); +int timeout_connect(int, const struct sockaddr *, socklen_t); +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, const char *); +int udptest(int); +int unix_bind(char *); +int unix_connect(char *); +int unix_listen(char *); +void set_common_sockopts(int); +int map_tos(char *, int *); +void report_connect(const struct sockaddr *, socklen_t); +void usage(int); +ssize_t drainbuf(int, unsigned char *, size_t *); +ssize_t fillbuf(int, unsigned char *, size_t *); + +static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); +static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); +static void warn(const char *, ...) __attribute__((format(printf, 1, 2))); + +static void +err(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} + +static void +errx(int r, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(r); +} + +static void +warn(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "%s: ", strerror(errno)); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); +} + +int +main(int argc, char *argv[]) +{ + int ch, s, ret, socksv; + char *host, *uport; + struct addrinfo hints; + struct servent *sv; + socklen_t len; + struct sockaddr_storage cliaddr; + char *proxy = NULL; + const char *errstr, *proxyhost = "", *proxyport = NULL; + struct addrinfo proxyhints; + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; + + ret = 1; + s = 0; + socksv = 5; + host = NULL; + uport = NULL; + sv = NULL; + + while ((ch = getopt(argc, argv, + "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { + switch (ch) { + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + case 'U': + family = AF_UNIX; + break; + case 'X': + if (strcasecmp(optarg, "connect") == 0) + socksv = -1; /* HTTP proxy CONNECT */ + else if (strcmp(optarg, "4") == 0) + socksv = 4; /* SOCKS v.4 */ + else if (strcmp(optarg, "5") == 0) + socksv = 5; /* SOCKS v.5 */ + else + errx(1, "unsupported proxy protocol"); + break; + case 'd': + dflag = 1; + break; + case 'F': + Fflag = 1; + break; + case 'h': + help(); + break; + case 'i': + iflag = strtonum(optarg, 0, UINT_MAX, &errstr); + if (errstr) + errx(1, "interval %s: %s", errstr, optarg); + break; + case 'k': + kflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'N': + Nflag = 1; + break; + case 'n': + nflag = 1; + break; + case 'P': + Pflag = optarg; + break; + case 'p': + pflag = optarg; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = optarg; + break; + case 't': + tflag = 1; + break; + case 'u': + uflag = 1; + break; +#ifdef SO_RTABLE + case 'V': + rtableid = (int)strtonum(optarg, 0, + RT_TABLEID_MAX, &errstr); + if (errstr) + errx(1, "rtable %s: %s", errstr, optarg); + break; +#endif + case 'v': + vflag = 1; + break; + case 'w': + timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); + if (errstr) + errx(1, "timeout %s: %s", errstr, optarg); + timeout *= 1000; + break; + case 'x': + xflag = 1; + if ((proxy = strdup(optarg)) == NULL) + errx(1, "strdup"); + break; + case 'z': + zflag = 1; + break; + case 'D': + Dflag = 1; + break; + case 'I': + Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP receive window %s: %s", + errstr, optarg); + break; + case 'O': + Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP send window %s: %s", + errstr, optarg); + break; + case 'S': + Sflag = 1; + break; + case 'T': + errstr = NULL; + errno = 0; + if (map_tos(optarg, &Tflag)) + break; + if (strlen(optarg) > 1 && optarg[0] == '0' && + optarg[1] == 'x') + Tflag = (int)strtol(optarg, NULL, 16); + else + Tflag = (int)strtonum(optarg, 0, 255, + &errstr); + if (Tflag < 0 || Tflag > 255 || errstr || errno) + errx(1, "illegal tos value %s", optarg); + break; + default: + usage(1); + } + } + argc -= optind; + argv += optind; + + /* Cruft to make sure options are clean, and used properly. */ + if (argv[0] && !argv[1] && family == AF_UNIX) { + host = argv[0]; + uport = NULL; + } else if (argv[0] && !argv[1]) { + if (!lflag) + usage(1); + uport = argv[0]; + host = NULL; + } else if (argv[0] && argv[1]) { + host = argv[0]; + uport = argv[1]; + } else + usage(1); + + if (lflag && sflag) + errx(1, "cannot use -s and -l"); + if (lflag && pflag) + errx(1, "cannot use -p and -l"); + if (lflag && zflag) + errx(1, "cannot use -z and -l"); + if (!lflag && kflag) + errx(1, "must use -l with -k"); + + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) && uflag && !lflag) { + if (sflag) { + unix_dg_tmp_socket = sflag; + } else { + strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", + UNIX_DG_TMP_SOCKET_SIZE); + if (mktemp(unix_dg_tmp_socket_buf) == NULL) + err(1, "mktemp"); + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; + } + } + + /* Initialize addrinfo structure. */ + if (family != AF_UNIX) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + if (nflag) + hints.ai_flags |= AI_NUMERICHOST; + } + + if (xflag) { + if (uflag) + errx(1, "no proxy support for UDP mode"); + + if (lflag) + errx(1, "no proxy support for listen"); + + if (family == AF_UNIX) + errx(1, "no proxy support for unix sockets"); + + /* XXX IPv6 transport to proxy would probably work */ + if (family == AF_INET6) + errx(1, "no proxy support for IPv6"); + + if (sflag) + errx(1, "no proxy support for local source address"); + + proxyhost = strsep(&proxy, ":"); + proxyport = proxy; + + memset(&proxyhints, 0, sizeof(struct addrinfo)); + proxyhints.ai_family = family; + proxyhints.ai_socktype = SOCK_STREAM; + proxyhints.ai_protocol = IPPROTO_TCP; + if (nflag) + proxyhints.ai_flags |= AI_NUMERICHOST; + } + + if (lflag) { + int connfd; + ret = 0; + + if (family == AF_UNIX) { + if (uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } + + /* Allow only one connection at a time, but stay alive. */ + for (;;) { + if (family != AF_UNIX) + s = local_listen(host, uport, hints); + if (s < 0) + err(1, "local_listen"); + /* + * For UDP and -k, don't connect the socket, let it + * receive datagrams from multiple socket pairs. + */ + if (uflag && kflag) + readwrite(s); + /* + * For UDP and not -k, we will use recvfrom() initially + * to wait for a caller, then use the regular functions + * to talk to the caller. + */ + else if (uflag && !kflag) { + int rv, plen; + char buf[16384]; + struct sockaddr_storage z; + + len = sizeof(z); + plen = 2048; + rv = recvfrom(s, buf, plen, MSG_PEEK, + (struct sockaddr *)&z, &len); + if (rv < 0) + err(1, "recvfrom"); + + rv = connect(s, (struct sockaddr *)&z, len); + if (rv < 0) + err(1, "connect"); + + if (vflag) + report_connect((struct sockaddr *)&z, len); + + readwrite(s); + } else { + len = sizeof(cliaddr); + connfd = accept(s, (struct sockaddr *)&cliaddr, + &len); + if (connfd == -1) { + /* For now, all errnos are fatal */ + err(1, "accept"); + } + if (vflag) + report_connect((struct sockaddr *)&cliaddr, len); + + readwrite(connfd); + close(connfd); + } + + if (family != AF_UNIX) + close(s); + else if (uflag) { + if (connect(s, NULL, 0) < 0) + err(1, "connect"); + } + + if (!kflag) + break; + } + } else if (family == AF_UNIX) { + ret = 0; + + if ((s = unix_connect(host)) > 0 && !zflag) { + readwrite(s); + close(s); + } else + ret = 1; + + if (uflag) + unlink(unix_dg_tmp_socket); + exit(ret); + + } else { + int i = 0; + + /* Construct the portlist[] array. */ + build_ports(uport); + + /* Cycle through portlist, connecting to each port. */ + for (i = 0; portlist[i] != NULL; i++) { + if (s) + close(s); + + if (xflag) + s = socks_connect(host, portlist[i], hints, + proxyhost, proxyport, proxyhints, socksv, + Pflag); + else + s = remote_connect(host, portlist[i], hints); + + if (s < 0) + continue; + + ret = 0; + if (vflag || zflag) { + /* For UDP, make sure we are connected. */ + if (uflag) { + if (udptest(s) == -1) { + ret = 1; + continue; + } + } + + /* Don't look up port if -n. */ + if (nflag) + sv = NULL; + else { + sv = getservbyport( + ntohs(atoi(portlist[i])), + uflag ? "udp" : "tcp"); + } + + fprintf(stderr, + "Connection to %s %s port [%s/%s] " + "succeeded!\n", host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*"); + } + if (Fflag) + fdpass(s); + else if (!zflag) + readwrite(s); + } + } + + if (s) + close(s); + + exit(ret); +} + +/* + * unix_bind() + * Returns a unix socket bound to the given path + */ +int +unix_bind(char *path) +{ + struct sockaddr_un sun_sa; + int s; + + /* Create unix domain socket. */ + if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, + 0)) < 0) + return (-1); + + memset(&sun_sa, 0, sizeof(struct sockaddr_un)); + sun_sa.sun_family = AF_UNIX; + + if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= + sizeof(sun_sa.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + + if (bind(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* + * unix_connect() + * Returns a socket connected to a local unix socket. Returns -1 on failure. + */ +int +unix_connect(char *path) +{ + struct sockaddr_un sun_sa; + int s; + + if (uflag) { + if ((s = unix_bind(unix_dg_tmp_socket)) < 0) + return (-1); + } else { + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return (-1); + } + (void)fcntl(s, F_SETFD, FD_CLOEXEC); + + memset(&sun_sa, 0, sizeof(struct sockaddr_un)); + sun_sa.sun_family = AF_UNIX; + + if (strlcpy(sun_sa.sun_path, path, sizeof(sun_sa.sun_path)) >= + sizeof(sun_sa.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + if (connect(s, (struct sockaddr *)&sun_sa, SUN_LEN(&sun_sa)) < 0) { + close(s); + return (-1); + } + return (s); + +} + +/* + * unix_listen() + * Create a unix domain socket, and listen on it. + */ +int +unix_listen(char *path) +{ + int s; + if ((s = unix_bind(path)) < 0) + return (-1); + + if (listen(s, 5) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* + * remote_connect() + * Returns a socket connected to a remote host. Properly binds to a local + * port or source address if needed. Returns -1 on failure. + */ +int +remote_connect(const char *host, const char *port, struct addrinfo hints) +{ + struct addrinfo *res, *res0; + int s, error; +#if defined(SO_RTABLE) || defined(SO_BINDANY) + int on = 1; +#endif + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifdef SO_RTABLE + if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, + &rtableid, sizeof(rtableid)) == -1)) + err(1, "setsockopt SO_RTABLE"); +#endif + /* Bind to a local port or source address if specified. */ + if (sflag || pflag) { + struct addrinfo ahints, *ares; + +#ifdef SO_BINDANY + /* try SO_BINDANY, but don't insist */ + setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); +#endif + memset(&ahints, 0, sizeof(struct addrinfo)); + ahints.ai_family = res0->ai_family; + ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + ahints.ai_flags = AI_PASSIVE; + if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + if (bind(s, (struct sockaddr *)ares->ai_addr, + ares->ai_addrlen) < 0) + err(1, "bind failed"); + freeaddrinfo(ares); + } + + set_common_sockopts(s); + + if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) + break; + else if (vflag) + warn("connect to %s port %s (%s) failed", host, port, + uflag ? "udp" : "tcp"); + + close(s); + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + freeaddrinfo(res); + + return (s); +} + +int +timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct pollfd pfd; + socklen_t optlen; + int flags = 0, optval; + int ret; + + if (timeout != -1) { + flags = fcntl(s, F_GETFL, 0); + if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) + err(1, "set non-blocking mode"); + } + + if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { + pfd.fd = s; + pfd.events = POLLOUT; + if ((ret = poll(&pfd, 1, timeout)) == 1) { + optlen = sizeof(optval); + if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, + &optval, &optlen)) == 0) { + errno = optval; + ret = optval == 0 ? 0 : -1; + } + } else if (ret == 0) { + errno = ETIMEDOUT; + ret = -1; + } else + err(1, "poll failed"); + } + + if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) + err(1, "restoring flags"); + + return (ret); +} + +/* + * local_listen() + * Returns a socket listening on a local port, binds to specified source + * address. Returns -1 on failure. + */ +int +local_listen(char *host, char *port, struct addrinfo hints) +{ + struct addrinfo *res, *res0; + int s, ret, x = 1; + int error; + + /* Allow nodename to be null. */ + hints.ai_flags |= AI_PASSIVE; + + /* + * In the case of binding to a wildcard address + * default to binding to an ipv4 address. + */ + if (host == NULL && hints.ai_family == AF_UNSPEC) + hints.ai_family = AF_INET; + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifdef SO_RTABLE + if (rtableid >= 0 && (setsockopt(s, SOL_SOCKET, SO_RTABLE, + &rtableid, sizeof(rtableid)) == -1)) + err(1, "setsockopt SO_RTABLE"); +#endif +#ifdef SO_REUSEPORT + ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); + if (ret == -1) + err(1, "setsockopt"); +#endif + set_common_sockopts(s); + + if (bind(s, (struct sockaddr *)res0->ai_addr, + res0->ai_addrlen) == 0) + break; + + close(s); + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + if (!uflag && s != -1) { + if (listen(s, 1) < 0) + err(1, "listen"); + } + + freeaddrinfo(res); + + return (s); +} + +/* + * readwrite() + * Loop that polls on the network file descriptor and stdin. + */ +void +readwrite(int net_fd) +{ + struct pollfd pfd[4]; + int stdin_fd = STDIN_FILENO; + int stdout_fd = STDOUT_FILENO; + unsigned char netinbuf[BUFSIZE]; + size_t netinbufpos = 0; + unsigned char stdinbuf[BUFSIZE]; + size_t stdinbufpos = 0; + int n, num_fds; + ssize_t ret; + + /* don't read from stdin if requested */ + if (dflag) + stdin_fd = -1; + + /* stdin */ + pfd[POLL_STDIN].fd = stdin_fd; + pfd[POLL_STDIN].events = POLLIN; + + /* network out */ + pfd[POLL_NETOUT].fd = net_fd; + pfd[POLL_NETOUT].events = 0; + + /* network in */ + pfd[POLL_NETIN].fd = net_fd; + pfd[POLL_NETIN].events = POLLIN; + + /* stdout */ + pfd[POLL_STDOUT].fd = stdout_fd; + pfd[POLL_STDOUT].events = 0; + + while (1) { + /* both inputs are gone, buffers are empty, we are done */ + if (pfd[POLL_STDIN].fd == -1 && pfd[POLL_NETIN].fd == -1 + && stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + /* both outputs are gone, we can't continue */ + if (pfd[POLL_NETOUT].fd == -1 && pfd[POLL_STDOUT].fd == -1) { + close(net_fd); + return; + } + /* listen and net in gone, queues empty, done */ + if (lflag && pfd[POLL_NETIN].fd == -1 + && stdinbufpos == 0 && netinbufpos == 0) { + close(net_fd); + return; + } + + /* help says -i is for "wait between lines sent". We read and + * write arbitrary amounts of data, and we don't want to start + * scanning for newlines, so this is as good as it gets */ + if (iflag) + sleep(iflag); + + /* poll */ + num_fds = poll(pfd, 4, timeout); + + /* treat poll errors */ + if (num_fds == -1) { + close(net_fd); + err(1, "polling error"); + } + + /* timeout happened */ + if (num_fds == 0) + return; + + /* treat socket error conditions */ + for (n = 0; n < 4; n++) { + if (pfd[n].revents & (POLLERR|POLLNVAL)) { + pfd[n].fd = -1; + } + } + /* reading is possible after HUP */ + if (pfd[POLL_STDIN].events & POLLIN && + pfd[POLL_STDIN].revents & POLLHUP && + ! (pfd[POLL_STDIN].revents & POLLIN)) + pfd[POLL_STDIN].fd = -1; + + if (pfd[POLL_NETIN].events & POLLIN && + pfd[POLL_NETIN].revents & POLLHUP && + ! (pfd[POLL_NETIN].revents & POLLIN)) + pfd[POLL_NETIN].fd = -1; + + if (pfd[POLL_NETOUT].revents & POLLHUP) { + if (Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* if HUP, stop watching stdout */ + if (pfd[POLL_STDOUT].revents & POLLHUP) + pfd[POLL_STDOUT].fd = -1; + /* if no net out, stop watching stdin */ + if (pfd[POLL_NETOUT].fd == -1) + pfd[POLL_STDIN].fd = -1; + /* if no stdout, stop watching net in */ + if (pfd[POLL_STDOUT].fd == -1) { + if (pfd[POLL_NETIN].fd != -1) + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } + + /* try to read from stdin */ + if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, + &stdinbufpos); + /* error or eof on stdin - remove from pfd */ + if (ret == 0 || ret == -1) + pfd[POLL_STDIN].fd = -1; + /* read something - poll net out */ + if (stdinbufpos > 0) + pfd[POLL_NETOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (stdinbufpos == BUFSIZE) + pfd[POLL_STDIN].events = 0; + } + /* try to write to network */ + if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { + ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, + &stdinbufpos); + if (ret == -1) + pfd[POLL_NETOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (stdinbufpos == 0) + pfd[POLL_NETOUT].events = 0; + /* buffer no longer full - poll stdin again */ + if (stdinbufpos < BUFSIZE) + pfd[POLL_STDIN].events = POLLIN; + } + /* try to read from network */ + if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { + ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, + &netinbufpos); + if (ret == -1) + pfd[POLL_NETIN].fd = -1; + /* eof on net in - remove from pfd */ + if (ret == 0) { + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + } + /* read something - poll stdout */ + if (netinbufpos > 0) + pfd[POLL_STDOUT].events = POLLOUT; + /* filled buffer - remove self from polling */ + if (netinbufpos == BUFSIZE) + pfd[POLL_NETIN].events = 0; + /* handle telnet */ + if (tflag) + atelnet(pfd[POLL_NETIN].fd, netinbuf, + netinbufpos); + } + /* try to write to stdout */ + if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { + ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, + &netinbufpos); + if (ret == -1) + pfd[POLL_STDOUT].fd = -1; + /* buffer empty - remove self from polling */ + if (netinbufpos == 0) + pfd[POLL_STDOUT].events = 0; + /* buffer no longer full - poll net in again */ + if (netinbufpos < BUFSIZE) + pfd[POLL_NETIN].events = POLLIN; + } + + /* stdin gone and queue empty? */ + if (pfd[POLL_STDIN].fd == -1 && stdinbufpos == 0) { + if (pfd[POLL_NETOUT].fd != -1 && Nflag) + shutdown(pfd[POLL_NETOUT].fd, SHUT_WR); + pfd[POLL_NETOUT].fd = -1; + } + /* net in gone and queue empty? */ + if (pfd[POLL_NETIN].fd == -1 && netinbufpos == 0) { + pfd[POLL_STDOUT].fd = -1; + } + } +} + +ssize_t +drainbuf(int fd, unsigned char *buf, size_t *bufpos) +{ + ssize_t n; + ssize_t adjust; + + n = write(fd, buf, *bufpos); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = -2; + if (n <= 0) + return n; + /* adjust buffer */ + adjust = *bufpos - n; + if (adjust > 0) + memmove(buf, buf + n, adjust); + *bufpos -= n; + return n; +} + + +ssize_t +fillbuf(int fd, unsigned char *buf, size_t *bufpos) +{ + size_t num = BUFSIZE - *bufpos; + ssize_t n; + + n = read(fd, buf + *bufpos, num); + /* don't treat EAGAIN, EINTR as error */ + if (n == -1 && (errno == EAGAIN || errno == EINTR)) + n = -2; + if (n <= 0) + return n; + *bufpos += n; + return n; +} + +/* + * fdpass() + * Pass the connected file descriptor to stdout and exit. + */ +void +fdpass(int nfd) +{ +#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) + struct msghdr msg; +#ifndef HAVE_ACCRIGHTS_IN_MSGHDR + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + struct cmsghdr *cmsg; +#endif + struct iovec vec; + char ch = '\0'; + struct pollfd pfd; + ssize_t r; + + memset(&msg, 0, sizeof(msg)); +#ifdef HAVE_ACCRIGHTS_IN_MSGHDR + msg.msg_accrights = (caddr_t)&nfd; + msg.msg_accrightslen = sizeof(nfd); +#else + memset(&cmsgbuf, 0, sizeof(cmsgbuf)); + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = nfd; +#endif + + vec.iov_base = &ch; + vec.iov_len = 1; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + + bzero(&pfd, sizeof(pfd)); + pfd.fd = STDOUT_FILENO; + for (;;) { + r = sendmsg(STDOUT_FILENO, &msg, 0); + if (r == -1) { + if (errno == EAGAIN || errno == EINTR) { + pfd.events = POLLOUT; + if (poll(&pfd, 1, -1) == -1) + err(1, "poll"); + continue; + } + err(1, "sendmsg"); + } else if (r == -1) + errx(1, "sendmsg: unexpected return value %zd", r); + else + break; + } + exit(0); +#else + errx(1, "%s: file descriptor passing not supported", __func__); +#endif +} + +/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ +void +atelnet(int nfd, unsigned char *buf, unsigned int size) +{ + unsigned char *p, *end; + unsigned char obuf[4]; + + if (size < 3) + return; + end = buf + size - 2; + + for (p = buf; p < end; p++) { + if (*p != IAC) + continue; + + obuf[0] = IAC; + p++; + if ((*p == WILL) || (*p == WONT)) + obuf[1] = DONT; + else if ((*p == DO) || (*p == DONT)) + obuf[1] = WONT; + else + continue; + + p++; + obuf[2] = *p; + if (atomicio(vwrite, nfd, obuf, 3) != 3) + warn("Write Error!"); + } +} + +/* + * build_ports() + * Build an array of ports in portlist[], listing each port + * that we should try to connect to. + */ +void +build_ports(char *p) +{ + const char *errstr; + char *n; + int hi, lo, cp; + int x = 0; + + if ((n = strchr(p, '-')) != NULL) { + *n = '\0'; + n++; + + /* Make sure the ports are in order: lowest->highest. */ + hi = strtonum(n, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, n); + lo = strtonum(p, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, p); + + if (lo > hi) { + cp = hi; + hi = lo; + lo = cp; + } + + /* Load ports sequentially. */ + for (cp = lo; cp <= hi; cp++) { + portlist[x] = calloc(1, PORT_MAX_LEN); + if (portlist[x] == NULL) + errx(1, "calloc"); + snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); + x++; + } + + /* Randomly swap ports. */ + if (rflag) { + int y; + char *c; + + for (x = 0; x <= (hi - lo); x++) { + y = (arc4random() & 0xFFFF) % (hi - lo); + c = portlist[x]; + portlist[x] = portlist[y]; + portlist[y] = c; + } + } + } else { + hi = strtonum(p, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, p); + portlist[0] = strdup(p); + if (portlist[0] == NULL) + errx(1, "strdup"); + } +} + +/* + * udptest() + * Do a few writes to see if the UDP port is there. + * Fails once PF state table is full. + */ +int +udptest(int s) +{ + int i, ret; + + for (i = 0; i <= 3; i++) { + if (write(s, "X", 1) == 1) + ret = 1; + else + ret = -1; + } + return (ret); +} + +void +set_common_sockopts(int s) +{ + int x = 1; + +#ifdef TCP_MD5SIG + if (Sflag) { + if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, + &x, sizeof(x)) == -1) + err(1, "setsockopt"); + } +#endif + if (Dflag) { + if (setsockopt(s, SOL_SOCKET, SO_DEBUG, + &x, sizeof(x)) == -1) + err(1, "setsockopt"); + } + if (Tflag != -1) { + if (setsockopt(s, IPPROTO_IP, IP_TOS, + &Tflag, sizeof(Tflag)) == -1) + err(1, "set IP ToS"); + } + if (Iflag) { + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &Iflag, sizeof(Iflag)) == -1) + err(1, "set TCP receive buffer size"); + } + if (Oflag) { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &Oflag, sizeof(Oflag)) == -1) + err(1, "set TCP send buffer size"); + } +} + +int +map_tos(char *s, int *val) +{ + /* DiffServ Codepoints and other TOS mappings */ + const struct toskeywords { + const char *keyword; + int val; + } *t, toskeywords[] = { + { "af11", IPTOS_DSCP_AF11 }, + { "af12", IPTOS_DSCP_AF12 }, + { "af13", IPTOS_DSCP_AF13 }, + { "af21", IPTOS_DSCP_AF21 }, + { "af22", IPTOS_DSCP_AF22 }, + { "af23", IPTOS_DSCP_AF23 }, + { "af31", IPTOS_DSCP_AF31 }, + { "af32", IPTOS_DSCP_AF32 }, + { "af33", IPTOS_DSCP_AF33 }, + { "af41", IPTOS_DSCP_AF41 }, + { "af42", IPTOS_DSCP_AF42 }, + { "af43", IPTOS_DSCP_AF43 }, + { "critical", IPTOS_PREC_CRITIC_ECP }, + { "cs0", IPTOS_DSCP_CS0 }, + { "cs1", IPTOS_DSCP_CS1 }, + { "cs2", IPTOS_DSCP_CS2 }, + { "cs3", IPTOS_DSCP_CS3 }, + { "cs4", IPTOS_DSCP_CS4 }, + { "cs5", IPTOS_DSCP_CS5 }, + { "cs6", IPTOS_DSCP_CS6 }, + { "cs7", IPTOS_DSCP_CS7 }, + { "ef", IPTOS_DSCP_EF }, + { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, + { "lowdelay", IPTOS_LOWDELAY }, + { "netcontrol", IPTOS_PREC_NETCONTROL }, + { "reliability", IPTOS_RELIABILITY }, + { "throughput", IPTOS_THROUGHPUT }, + { NULL, -1 }, + }; + + for (t = toskeywords; t->keyword != NULL; t++) { + if (strcmp(s, t->keyword) == 0) { + *val = t->val; + return (1); + } + } + + return (0); +} + +void +report_connect(const struct sockaddr *sa, socklen_t salen) +{ + char remote_host[NI_MAXHOST]; + char remote_port[NI_MAXSERV]; + int herr; + int flags = NI_NUMERICSERV; + + if (nflag) + flags |= NI_NUMERICHOST; + + if ((herr = getnameinfo(sa, salen, + remote_host, sizeof(remote_host), + remote_port, sizeof(remote_port), + flags)) != 0) { + if (herr == EAI_SYSTEM) + err(1, "getnameinfo"); + else + errx(1, "getnameinfo: %s", gai_strerror(herr)); + } + + fprintf(stderr, + "Connection from %s %s " + "received!\n", remote_host, remote_port); +} + +void +help(void) +{ + usage(0); + fprintf(stderr, "\tCommand Summary:\n\ + \t-4 Use IPv4\n\ + \t-6 Use IPv6\n\ + \t-D Enable the debug socket option\n\ + \t-d Detach from stdin\n\ + \t-F Pass socket fd\n\ + \t-h This help text\n\ + \t-I length TCP receive buffer length\n\ + \t-i secs\t Delay interval for lines sent, ports scanned\n\ + \t-k Keep inbound sockets open for multiple connects\n\ + \t-l Listen mode, for inbound connects\n\ + \t-N Shutdown the network socket after EOF on stdin\n\ + \t-n Suppress name/port resolutions\n\ + \t-O length TCP send buffer length\n\ + \t-P proxyuser\tUsername for proxy authentication\n\ + \t-p port\t Specify local port for remote connects\n\ + \t-r Randomize remote ports\n\ + \t-S Enable the TCP MD5 signature option\n\ + \t-s addr\t Local source address\n\ + \t-T toskeyword\tSet IP Type of Service\n\ + \t-t Answer TELNET negotiation\n\ + \t-U Use UNIX domain socket\n\ + \t-u UDP mode\n\ + \t-V rtable Specify alternate routing table\n\ + \t-v Verbose\n\ + \t-w secs\t Timeout for connects and final net reads\n\ + \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ + \t-x addr[:port]\tSpecify proxy address and port\n\ + \t-z Zero-I/O mode [used for scanning]\n\ + Port numbers can be individual or ranges: lo-hi [inclusive]\n"); + exit(1); +} + +void +usage(int ret) +{ + fprintf(stderr, + "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n" + "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" + "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" + "\t [-x proxy_address[:port]] [destination] [port]\n"); + if (ret) + exit(1); +} + +/* *** src/usr.bin/nc/socks.c *** */ + + +/* $OpenBSD: socks.c,v 1.20 2012/03/08 09:56:28 espie Exp $ */ + +/* + * Copyright (c) 1999 Niklas Hallqvist. All rights reserved. + * Copyright (c) 2004, 2005 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SOCKS_PORT "1080" +#define HTTP_PROXY_PORT "3128" +#define HTTP_MAXHDRS 64 +#define SOCKS_V5 5 +#define SOCKS_V4 4 +#define SOCKS_NOAUTH 0 +#define SOCKS_NOMETHOD 0xff +#define SOCKS_CONNECT 1 +#define SOCKS_IPV4 1 +#define SOCKS_DOMAIN 3 +#define SOCKS_IPV6 4 + +int remote_connect(const char *, const char *, struct addrinfo); +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, + const char *); + +static int +decode_addrport(const char *h, const char *p, struct sockaddr *addr, + socklen_t addrlen, int v4only, int numeric) +{ + int r; + struct addrinfo hints, *res; + + bzero(&hints, sizeof(hints)); + hints.ai_family = v4only ? PF_INET : PF_UNSPEC; + hints.ai_flags = numeric ? AI_NUMERICHOST : 0; + hints.ai_socktype = SOCK_STREAM; + r = getaddrinfo(h, p, &hints, &res); + /* Don't fatal when attempting to convert a numeric address */ + if (r != 0) { + if (!numeric) { + errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p, + gai_strerror(r)); + } + return (-1); + } + if (addrlen < res->ai_addrlen) { + freeaddrinfo(res); + errx(1, "internal error: addrlen < res->ai_addrlen"); + } + memcpy(addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + return (0); +} + +static int +proxy_read_line(int fd, char *buf, size_t bufsz) +{ + size_t off; + + for(off = 0;;) { + if (off >= bufsz) + errx(1, "proxy read too long"); + if (atomicio(read, fd, buf + off, 1) != 1) + err(1, "proxy read"); + /* Skip CR */ + if (buf[off] == '\r') + continue; + if (buf[off] == '\n') { + buf[off] = '\0'; + break; + } + off++; + } + return (off); +} + +static const char * +getproxypass(const char *proxyuser, const char *proxyhost) +{ + char prompt[512]; + static char pw[256]; + + snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ", + proxyuser, proxyhost); + if (readpassphrase(prompt, pw, sizeof(pw), RPP_REQUIRE_TTY) == NULL) + errx(1, "Unable to read proxy passphrase"); + return (pw); +} + +int +socks_connect(const char *host, const char *port, + struct addrinfo hints __attribute__ ((__unused__)), + const char *proxyhost, const char *proxyport, struct addrinfo proxyhints, + int socksv, const char *proxyuser) +{ + int proxyfd, r, authretry = 0; + size_t hlen, wlen = 0; + unsigned char buf[1024]; + size_t cnt; + struct sockaddr_storage addr; + struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr; + in_port_t serverport; + const char *proxypass = NULL; + + if (proxyport == NULL) + proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT; + + /* Abuse API to lookup port */ + if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr, + sizeof(addr), 1, 1) == -1) + errx(1, "unknown port \"%.64s\"", port); + serverport = in4->sin_port; + + again: + if (authretry++ > 3) + errx(1, "Too many authentication failures"); + + proxyfd = remote_connect(proxyhost, proxyport, proxyhints); + + if (proxyfd < 0) + return (-1); + + if (socksv == 5) { + if (decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 0, 1) == -1) + addr.ss_family = 0; /* used in switch below */ + + /* Version 5, one method: no authentication */ + buf[0] = SOCKS_V5; + buf[1] = 1; + buf[2] = SOCKS_NOAUTH; + cnt = atomicio(vwrite, proxyfd, buf, 3); + if (cnt != 3) + err(1, "write failed (%zu/3)", cnt); + + cnt = atomicio(read, proxyfd, buf, 2); + if (cnt != 2) + err(1, "read failed (%zu/3)", cnt); + + if (buf[1] == SOCKS_NOMETHOD) + errx(1, "authentication method negotiation failed"); + + switch (addr.ss_family) { + case 0: + /* Version 5, connect: domain name */ + + /* Max domain name length is 255 bytes */ + hlen = strlen(host); + if (hlen > 255) + errx(1, "host name too long for SOCKS5"); + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_DOMAIN; + buf[4] = hlen; + memcpy(buf + 5, host, hlen); + memcpy(buf + 5 + hlen, &serverport, sizeof serverport); + wlen = 7 + hlen; + break; + case AF_INET: + /* Version 5, connect: IPv4 address */ + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_IPV4; + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port); + wlen = 10; + break; + case AF_INET6: + /* Version 5, connect: IPv6 address */ + buf[0] = SOCKS_V5; + buf[1] = SOCKS_CONNECT; + buf[2] = 0; + buf[3] = SOCKS_IPV6; + memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr); + memcpy(buf + 20, &in6->sin6_port, + sizeof in6->sin6_port); + wlen = 22; + break; + default: + errx(1, "internal error: silly AF"); + } + + cnt = atomicio(vwrite, proxyfd, buf, wlen); + if (cnt != wlen) + err(1, "write failed (%zu/%zu)", cnt, wlen); + + cnt = atomicio(read, proxyfd, buf, 4); + if (cnt != 4) + err(1, "read failed (%zu/4)", cnt); + if (buf[1] != 0) + errx(1, "connection failed, SOCKS error %d", buf[1]); + switch (buf[3]) { + case SOCKS_IPV4: + cnt = atomicio(read, proxyfd, buf + 4, 6); + if (cnt != 6) + err(1, "read failed (%zu/6)", cnt); + break; + case SOCKS_IPV6: + cnt = atomicio(read, proxyfd, buf + 4, 18); + if (cnt != 18) + err(1, "read failed (%zu/18)", cnt); + break; + default: + errx(1, "connection failed, unsupported address type"); + } + } else if (socksv == 4) { + /* This will exit on lookup failure */ + decode_addrport(host, port, (struct sockaddr *)&addr, + sizeof(addr), 1, 0); + + /* Version 4 */ + buf[0] = SOCKS_V4; + buf[1] = SOCKS_CONNECT; /* connect */ + memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port); + memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr); + buf[8] = 0; /* empty username */ + wlen = 9; + + cnt = atomicio(vwrite, proxyfd, buf, wlen); + if (cnt != wlen) + err(1, "write failed (%zu/%zu)", cnt, wlen); + + cnt = atomicio(read, proxyfd, buf, 8); + if (cnt != 8) + err(1, "read failed (%zu/8)", cnt); + if (buf[1] != 90) + errx(1, "connection failed, SOCKS error %d", buf[1]); + } else if (socksv == -1) { + /* HTTP proxy CONNECT */ + + /* Disallow bad chars in hostname */ + if (strcspn(host, "\r\n\t []:") != strlen(host)) + errx(1, "Invalid hostname"); + + /* Try to be sane about numeric IPv6 addresses */ + if (strchr(host, ':') != NULL) { + r = snprintf(buf, sizeof(buf), + "CONNECT [%s]:%d HTTP/1.0\r\n", + host, ntohs(serverport)); + } else { + r = snprintf(buf, sizeof(buf), + "CONNECT %s:%d HTTP/1.0\r\n", + host, ntohs(serverport)); + } + if (r == -1 || (size_t)r >= sizeof(buf)) + errx(1, "hostname too long"); + r = strlen(buf); + + cnt = atomicio(vwrite, proxyfd, buf, r); + if (cnt != (size_t)r) + err(1, "write failed (%zu/%d)", cnt, r); + + if (authretry > 1) { + char resp[1024]; + + proxypass = getproxypass(proxyuser, proxyhost); + r = snprintf(buf, sizeof(buf), "%s:%s", + proxyuser, proxypass); + if (r == -1 || (size_t)r >= sizeof(buf) || + b64_ntop(buf, strlen(buf), resp, + sizeof(resp)) == -1) + errx(1, "Proxy username/password too long"); + r = snprintf(buf, sizeof(buf), "Proxy-Authorization: " + "Basic %s\r\n", resp); + if (r == -1 || (size_t)r >= sizeof(buf)) + errx(1, "Proxy auth response too long"); + r = strlen(buf); + if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != (size_t)r) + err(1, "write failed (%zu/%d)", cnt, r); + } + + /* Terminate headers */ + if ((r = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2) + err(1, "write failed (2/%d)", r); + + /* Read status reply */ + proxy_read_line(proxyfd, buf, sizeof(buf)); + if (proxyuser != NULL && + strncmp(buf, "HTTP/1.0 407 ", 12) == 0) { + if (authretry > 1) { + fprintf(stderr, "Proxy authentication " + "failed\n"); + } + close(proxyfd); + goto again; + } else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 && + strncmp(buf, "HTTP/1.1 200 ", 12) != 0) + errx(1, "Proxy error: \"%s\"", buf); + + /* Headers continue until we hit an empty line */ + for (r = 0; r < HTTP_MAXHDRS; r++) { + proxy_read_line(proxyfd, buf, sizeof(buf)); + if (*buf == '\0') + break; + } + if (*buf != '\0') + errx(1, "Too many proxy headers received"); + } else + errx(1, "Unknown proxy protocol %d", socksv); + + return (proxyfd); +} + diff --git a/crypto/openssh/regress/proto-mismatch.sh b/crypto/openssh/regress/proto-mismatch.sh index fb521f214fd1..9e8024beb0f9 100644 --- a/crypto/openssh/regress/proto-mismatch.sh +++ b/crypto/openssh/regress/proto-mismatch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: proto-mismatch.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ +# $OpenBSD: proto-mismatch.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="protocol version mismatch" @@ -16,4 +16,6 @@ mismatch () } mismatch 2 SSH-1.5-HALLO -mismatch 1 SSH-2.0-HALLO +if ssh_version 1; then + mismatch 1 SSH-2.0-HALLO +fi diff --git a/crypto/openssh/regress/proto-version.sh b/crypto/openssh/regress/proto-version.sh index b876dd7ec2b4..cf4946115488 100644 --- a/crypto/openssh/regress/proto-version.sh +++ b/crypto/openssh/regress/proto-version.sh @@ -1,4 +1,4 @@ -# $OpenBSD: proto-version.sh,v 1.4 2013/05/17 00:37:40 dtucker Exp $ +# $OpenBSD: proto-version.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="sshd version with different protocol combinations" @@ -28,7 +28,9 @@ check_version () fi } -check_version 2,1 199 -check_version 1,2 199 check_version 2 20 -check_version 1 15 +if ssh_version 1; then + check_version 2,1 199 + check_version 1,2 199 + check_version 1 15 +fi diff --git a/crypto/openssh/regress/proxy-connect.sh b/crypto/openssh/regress/proxy-connect.sh index 023ba73678dd..f816962b592a 100644 --- a/crypto/openssh/regress/proxy-connect.sh +++ b/crypto/openssh/regress/proxy-connect.sh @@ -1,4 +1,4 @@ -# $OpenBSD: proxy-connect.sh,v 1.7 2014/05/03 18:46:14 dtucker Exp $ +# $OpenBSD: proxy-connect.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="proxy connect" @@ -9,7 +9,7 @@ for ps in no yes; do cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy echo "UsePrivilegeSeparation $ps" >> $OBJ/sshd_proxy - for p in 1 2; do + for p in ${SSH_PROTOCOLS}; do for c in no yes; do verbose "plain username protocol $p privsep=$ps comp=$c" opts="-$p -oCompression=$c -F $OBJ/ssh_proxy" @@ -24,7 +24,7 @@ for ps in no yes; do done done -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "username with style protocol $p" ${SSH} -$p -F $OBJ/ssh_proxy ${USER}:style@999.999.999.999 true || \ fail "ssh proxyconnect protocol $p failed" diff --git a/crypto/openssh/regress/reconfigure.sh b/crypto/openssh/regress/reconfigure.sh index 9fd2895314e4..eecddd3c7302 100644 --- a/crypto/openssh/regress/reconfigure.sh +++ b/crypto/openssh/regress/reconfigure.sh @@ -1,20 +1,30 @@ -# $OpenBSD: reconfigure.sh,v 1.2 2003/06/21 09:14:05 markus Exp $ +# $OpenBSD: reconfigure.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="simple connect after reconfigure" # we need the full path to sshd for -HUP -case $SSHD in -/*) - # full path is OK - ;; -*) - # otherwise make fully qualified - SSHD=$OBJ/$SSHD -esac +if test "x$USE_VALGRIND" = "x" ; then + case $SSHD in + /*) + # full path is OK + ;; + *) + # otherwise make fully qualified + SSHD=$OBJ/$SSHD + esac +fi start_sshd +trace "connect before restart" +for p in ${SSH_PROTOCOLS} ; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed before reconfigure" + fi +done + PID=`$SUDO cat $PIDFILE` rm -f $PIDFILE $SUDO kill -HUP $PID @@ -28,7 +38,8 @@ done test -f $PIDFILE || fatal "sshd did not restart" -for p in 1 2; do +trace "connect after restart" +for p in ${SSH_PROTOCOLS} ; do ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true if [ $? -ne 0 ]; then fail "ssh connect with protocol $p failed after reconfigure" diff --git a/crypto/openssh/regress/reexec.sh b/crypto/openssh/regress/reexec.sh index 433573f06424..5c0a7b46f068 100644 --- a/crypto/openssh/regress/reexec.sh +++ b/crypto/openssh/regress/reexec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: reexec.sh,v 1.7 2013/05/17 10:23:52 dtucker Exp $ +# $OpenBSD: reexec.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="reexec tests" @@ -19,7 +19,7 @@ start_sshd_copy () copy_tests () { rm -f ${COPY} - for p in 1 2; do + for p in ${SSH_PROTOCOLS} ; do verbose "$tid: proto $p" ${SSH} -nqo "Protocol=$p" -F $OBJ/ssh_config somehost \ cat ${DATA} > ${COPY} diff --git a/crypto/openssh/regress/rekey.sh b/crypto/openssh/regress/rekey.sh index fd452b034518..0d4444d03fed 100644 --- a/crypto/openssh/regress/rekey.sh +++ b/crypto/openssh/regress/rekey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: rekey.sh,v 1.15 2014/04/21 22:15:37 djm Exp $ +# $OpenBSD: rekey.sh,v 1.16 2015/02/14 12:43:16 markus Exp $ # Placed in the Public Domain. tid="rekey" @@ -100,9 +100,29 @@ for s in 5 10; do fi done -echo "rekeylimit default 5" >>$OBJ/sshd_proxy +for s in 16 1k 128k 256k; do + verbose "server rekeylimit ${s}" + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "rekeylimit ${s}" >>$OBJ/sshd_proxy + rm -f ${COPY} ${LOG} + ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "cat ${DATA}" \ + > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done + for s in 5 10; do verbose "server rekeylimit default ${s} no data" + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy + echo "rekeylimit default ${s}" >>$OBJ/sshd_proxy rm -f ${COPY} ${LOG} ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 3" if [ $? -ne 0 ]; then diff --git a/crypto/openssh/regress/sshd-log-wrapper.sh b/crypto/openssh/regress/sshd-log-wrapper.sh index a9386be4d1cf..c00934c780ba 100644 --- a/crypto/openssh/regress/sshd-log-wrapper.sh +++ b/crypto/openssh/regress/sshd-log-wrapper.sh @@ -3,11 +3,9 @@ # Placed in the Public Domain. # # simple wrapper for sshd proxy mode to catch stderr output -# sh sshd-log-wrapper.sh /path/to/sshd /path/to/logfile +# sh sshd-log-wrapper.sh /path/to/logfile /path/to/sshd [args...] -sshd=$1 -log=$2 -shift +log=$1 shift -exec $sshd -E$log $@ +exec "$@" -E$log diff --git a/crypto/openssh/regress/stderr-data.sh b/crypto/openssh/regress/stderr-data.sh index b0bd2355cc96..8c8149a732b7 100644 --- a/crypto/openssh/regress/stderr-data.sh +++ b/crypto/openssh/regress/stderr-data.sh @@ -1,10 +1,10 @@ -# $OpenBSD: stderr-data.sh,v 1.3 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: stderr-data.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="stderr data transfer" for n in '' -n; do -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "test $tid: proto $p ($n)" ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ diff --git a/crypto/openssh/regress/t11.ok b/crypto/openssh/regress/t11.ok new file mode 100644 index 000000000000..1925bb470fc0 --- /dev/null +++ b/crypto/openssh/regress/t11.ok @@ -0,0 +1 @@ +SHA256:4w1rnrek3klTJOTVhwuCIFd5k+pq9Bfo5KTxxb8BqbY diff --git a/crypto/openssh/regress/t4.ok b/crypto/openssh/regress/t4.ok index 8c4942bf177b..4631ea8c7094 100644 --- a/crypto/openssh/regress/t4.ok +++ b/crypto/openssh/regress/t4.ok @@ -1 +1 @@ -3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 +MD5:3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 diff --git a/crypto/openssh/regress/test-exec.sh b/crypto/openssh/regress/test-exec.sh index a1bab832f81c..0f766620d694 100644 --- a/crypto/openssh/regress/test-exec.sh +++ b/crypto/openssh/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.48 2014/07/06 07:42:03 djm Exp $ +# $OpenBSD: test-exec.sh,v 1.51 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -130,6 +130,11 @@ if [ "x$TEST_SSH_CONCH" != "x" ]; then esac fi +SSH_PROTOCOLS=`$SSH -Q protocol-version` +if [ "x$TEST_SSH_PROTOCOLS" != "x" ]; then + SSH_PROTOCOLS="${TEST_SSH_PROTOCOLS}" +fi + # Path to sshd must be absolute for rexec case "$SSHD" in /*) ;; @@ -141,6 +146,55 @@ case "$SSHAGENT" in *) SSHAGENT=`which $SSHAGENT` ;; esac +# Record the actual binaries used. +SSH_BIN=${SSH} +SSHD_BIN=${SSHD} +SSHAGENT_BIN=${SSHAGENT} +SSHADD_BIN=${SSHADD} +SSHKEYGEN_BIN=${SSHKEYGEN} +SSHKEYSCAN_BIN=${SSHKEYSCAN} +SFTP_BIN=${SFTP} +SFTPSERVER_BIN=${SFTPSERVER} +SCP_BIN=${SCP} + +if [ "x$USE_VALGRIND" != "x" ]; then + mkdir -p $OBJ/valgrind-out + VG_TEST=`basename $SCRIPT .sh` + + # Some tests are difficult to fix. + case "$VG_TEST" in + connect-privsep|reexec) + VG_SKIP=1 ;; + esac + + if [ x"$VG_SKIP" = "x" ]; then + VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*" + VG_LOG="$OBJ/valgrind-out/${VG_TEST}." + VG_OPTS="--track-origins=yes --leak-check=full" + VG_OPTS="$VG_OPTS --trace-children=yes" + VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}" + VG_PATH="valgrind" + if [ "x$VALGRIND_PATH" != "x" ]; then + VG_PATH="$VALGRIND_PATH" + fi + VG="$VG_PATH $VG_OPTS" + SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH" + SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD" + SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT" + SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD" + SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN" + SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN" + SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}" + SCP="$VG --log-file=${VG_LOG}scp.%p $SCP" + cat > $OBJ/valgrind-sftp-server.sh << EOF +#!/bin/sh +exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@" +EOF + chmod a+rx $OBJ/valgrind-sftp-server.sh + SFTPSERVER="$OBJ/valgrind-sftp-server.sh" + fi +fi + # Logfiles. # SSH_LOGFILE should be the debug output of ssh(1) only # SSHD_LOGFILE should be the debug output of sshd(8) only @@ -175,7 +229,7 @@ SSH="$SSHLOGWRAP" # [kbytes] to ensure the file is at least that large. DATANAME=data DATA=$OBJ/${DATANAME} -cat ${SSHAGENT} >${DATA} +cat ${SSHAGENT_BIN} >${DATA} chmod u+w ${DATA} COPY=$OBJ/copy rm -f ${COPY} @@ -183,7 +237,7 @@ rm -f ${COPY} increase_datafile_size() { while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do - cat ${SSHAGENT} >>${DATA} + cat ${SSHAGENT_BIN} >>${DATA} done } @@ -325,16 +379,27 @@ fatal () exit $RESULT } +ssh_version () +{ + echo ${SSH_PROTOCOLS} | grep "$1" >/dev/null +} + RESULT=0 PIDFILE=$OBJ/pidfile trap fatal 3 2 +if ssh_version 1; then + PROTO="2,1" +else + PROTO="2" +fi + # create server config cat << EOF > $OBJ/sshd_config StrictModes no Port $PORT - Protocol 2,1 + Protocol $PROTO AddressFamily inet ListenAddress 127.0.0.1 #ListenAddress ::1 @@ -360,7 +425,7 @@ echo 'StrictModes no' >> $OBJ/sshd_proxy # create client config cat << EOF > $OBJ/ssh_config Host * - Protocol 2,1 + Protocol $PROTO Hostname 127.0.0.1 HostKeyAlias localhost-with-alias Port $PORT @@ -385,10 +450,15 @@ fi rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER +if ssh_version 1; then + SSH_KEYTYPES="rsa rsa1" +else + SSH_KEYTYPES="rsa ed25519" +fi trace "generate keys" -for t in rsa rsa1; do +for t in ${SSH_KEYTYPES}; do # generate user key - if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN} -nt $OBJ/$t ]; then + if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then rm -f $OBJ/$t ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ fail "ssh-keygen for $t failed" @@ -451,7 +521,7 @@ if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then echo "Hostname=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy - echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy + echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy REGRESS_INTEROP_PUTTY=yes fi @@ -459,7 +529,7 @@ fi # create a proxy version of the client config ( cat $OBJ/ssh_config - echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${SSHD} ${TEST_SSHD_LOGFILE} -i -f $OBJ/sshd_proxy + echo proxycommand ${SUDO} sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy ) > $OBJ/ssh_proxy # check proxy config diff --git a/crypto/openssh/regress/transfer.sh b/crypto/openssh/regress/transfer.sh index 1ae3ef5bf506..36c14634ab9e 100644 --- a/crypto/openssh/regress/transfer.sh +++ b/crypto/openssh/regress/transfer.sh @@ -1,9 +1,9 @@ -# $OpenBSD: transfer.sh,v 1.2 2013/05/17 04:29:14 dtucker Exp $ +# $OpenBSD: transfer.sh,v 1.3 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="transfer data" -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do verbose "$tid: proto $p" rm -f ${COPY} ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} diff --git a/crypto/openssh/regress/try-ciphers.sh b/crypto/openssh/regress/try-ciphers.sh index 2881ce16c13b..4165c7b887be 100644 --- a/crypto/openssh/regress/try-ciphers.sh +++ b/crypto/openssh/regress/try-ciphers.sh @@ -1,4 +1,4 @@ -# $OpenBSD: try-ciphers.sh,v 1.23 2014/04/21 22:15:37 djm Exp $ +# $OpenBSD: try-ciphers.sh,v 1.24 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="try ciphers" @@ -26,7 +26,11 @@ for c in `${SSH} -Q cipher`; do done done -ciphers="3des blowfish" +if ssh_version 1; then + ciphers="3des blowfish" +else + ciphers="" +fi for c in $ciphers; do trace "proto 1 cipher $c" verbose "test $tid: proto 1 cipher $c" diff --git a/crypto/openssh/regress/unittests/Makefile b/crypto/openssh/regress/unittests/Makefile index bdb4574e2f55..d3d90823f907 100644 --- a/crypto/openssh/regress/unittests/Makefile +++ b/crypto/openssh/regress/unittests/Makefile @@ -1,5 +1,5 @@ -# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ - -SUBDIR= test_helper sshbuf sshkey +# $OpenBSD: Makefile,v 1.5 2015/02/16 22:21:03 djm Exp $ +REGRESS_FAIL_EARLY= yes +SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys .include diff --git a/crypto/openssh/regress/unittests/Makefile.inc b/crypto/openssh/regress/unittests/Makefile.inc index 4c33637495c0..c55d00c61ca5 100644 --- a/crypto/openssh/regress/unittests/Makefile.inc +++ b/crypto/openssh/regress/unittests/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.1 2014/04/30 05:32:00 djm Exp $ +# $OpenBSD: Makefile.inc,v 1.3 2015/01/23 21:21:23 miod Exp $ .include .include @@ -21,7 +21,6 @@ CDIAGFLAGS+= -Wmissing-declarations CDIAGFLAGS+= -Wmissing-prototypes CDIAGFLAGS+= -Wparentheses CDIAGFLAGS+= -Wpointer-arith -CDIAGFLAGS+= -Wpointer-sign CDIAGFLAGS+= -Wreturn-type CDIAGFLAGS+= -Wshadow CDIAGFLAGS+= -Wsign-compare @@ -32,6 +31,7 @@ CDIAGFLAGS+= -Wtrigraphs CDIAGFLAGS+= -Wuninitialized CDIAGFLAGS+= -Wunused .if ${COMPILER_VERSION} == "gcc4" +CDIAGFLAGS+= -Wpointer-sign CDIAGFLAGS+= -Wold-style-definition .endif diff --git a/crypto/openssh/regress/unittests/bitmap/Makefile b/crypto/openssh/regress/unittests/bitmap/Makefile new file mode 100644 index 000000000000..b704d22d6d78 --- /dev/null +++ b/crypto/openssh/regress/unittests/bitmap/Makefile @@ -0,0 +1,12 @@ +# $OpenBSD: Makefile,v 1.1 2015/01/15 07:36:28 djm Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_bitmap +SRCS=tests.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} + +.include diff --git a/crypto/openssh/regress/unittests/bitmap/tests.c b/crypto/openssh/regress/unittests/bitmap/tests.c new file mode 100644 index 000000000000..23025f90af82 --- /dev/null +++ b/crypto/openssh/regress/unittests/bitmap/tests.c @@ -0,0 +1,135 @@ +/* $OpenBSD: tests.c,v 1.1 2015/01/15 07:36:28 djm Exp $ */ +/* + * Regress test for bitmap.h bitmap API + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include + +#include "../test_helper/test_helper.h" + +#include "bitmap.h" + +#define NTESTS 131 + +void +tests(void) +{ + struct bitmap *b; + BIGNUM *bn; + size_t len; + int i, j, k, n; + u_char bbuf[1024], bnbuf[1024]; + int r; + + TEST_START("bitmap_new"); + b = bitmap_new(); + ASSERT_PTR_NE(b, NULL); + bn = BN_new(); + ASSERT_PTR_NE(bn, NULL); + TEST_DONE(); + + TEST_START("bitmap_set_bit / bitmap_test_bit"); + for (i = -1; i < NTESTS; i++) { + for (j = -1; j < NTESTS; j++) { + for (k = -1; k < NTESTS; k++) { + bitmap_zero(b); + BN_clear(bn); + + test_subtest_info("set %d/%d/%d", i, j, k); + /* Set bits */ + if (i >= 0) { + ASSERT_INT_EQ(bitmap_set_bit(b, i), 0); + ASSERT_INT_EQ(BN_set_bit(bn, i), 1); + } + if (j >= 0) { + ASSERT_INT_EQ(bitmap_set_bit(b, j), 0); + ASSERT_INT_EQ(BN_set_bit(bn, j), 1); + } + if (k >= 0) { + ASSERT_INT_EQ(bitmap_set_bit(b, k), 0); + ASSERT_INT_EQ(BN_set_bit(bn, k), 1); + } + + /* Check perfect match between bitmap and bn */ + test_subtest_info("match %d/%d/%d", i, j, k); + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(BN_is_bit_set(bn, n), + bitmap_test_bit(b, n)); + } + + /* Test length calculations */ + test_subtest_info("length %d/%d/%d", i, j, k); + ASSERT_INT_EQ(BN_num_bits(bn), + (int)bitmap_nbits(b)); + ASSERT_INT_EQ(BN_num_bytes(bn), + (int)bitmap_nbytes(b)); + + /* Test serialisation */ + test_subtest_info("serialise %d/%d/%d", + i, j, k); + len = bitmap_nbytes(b); + memset(bbuf, 0xfc, sizeof(bbuf)); + ASSERT_INT_EQ(bitmap_to_string(b, bbuf, + sizeof(bbuf)), 0); + for (n = len; n < (int)sizeof(bbuf); n++) + ASSERT_U8_EQ(bbuf[n], 0xfc); + r = BN_bn2bin(bn, bnbuf); + ASSERT_INT_GE(r, 0); + ASSERT_INT_EQ(r, (int)len); + ASSERT_MEM_EQ(bbuf, bnbuf, len); + + /* Test deserialisation */ + test_subtest_info("deserialise %d/%d/%d", + i, j, k); + bitmap_zero(b); + ASSERT_INT_EQ(bitmap_from_string(b, bnbuf, + len), 0); + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(BN_is_bit_set(bn, n), + bitmap_test_bit(b, n)); + } + + /* Test clearing bits */ + test_subtest_info("clear %d/%d/%d", + i, j, k); + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(bitmap_set_bit(b, n), 0); + ASSERT_INT_EQ(BN_set_bit(bn, n), 1); + } + if (i >= 0) { + bitmap_clear_bit(b, i); + BN_clear_bit(bn, i); + } + if (j >= 0) { + bitmap_clear_bit(b, j); + BN_clear_bit(bn, j); + } + if (k >= 0) { + bitmap_clear_bit(b, k); + BN_clear_bit(bn, k); + } + for (n = 0; n < NTESTS; n++) { + ASSERT_INT_EQ(BN_is_bit_set(bn, n), + bitmap_test_bit(b, n)); + } + } + } + } + bitmap_free(b); + BN_free(bn); + TEST_DONE(); +} + diff --git a/crypto/openssh/regress/unittests/hostkeys/Makefile b/crypto/openssh/regress/unittests/hostkeys/Makefile new file mode 100644 index 000000000000..f52a85fb1503 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/Makefile @@ -0,0 +1,12 @@ +# $OpenBSD: Makefile,v 1.1 2015/02/16 22:18:34 djm Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_hostkeys +SRCS=tests.c test_iterate.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} -d ${.CURDIR}/testdata + +.include diff --git a/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh b/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh new file mode 100755 index 000000000000..36890ba11a76 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/mktestdata.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# $OpenBSD: mktestdata.sh,v 1.1 2015/02/16 22:18:34 djm Exp $ + +set -ex + +cd testdata + +rm -f rsa1* rsa* dsa* ecdsa* ed25519* +rm -f known_hosts* + +gen_all() { + _n=$1 + _ecdsa_bits=256 + test "x$_n" = "x1" && _ecdsa_bits=384 + test "x$_n" = "x2" && _ecdsa_bits=521 + ssh-keygen -qt rsa1 -b 1024 -C "RSA1 #$_n" -N "" -f rsa1_$_n + ssh-keygen -qt rsa -b 1024 -C "RSA #$_n" -N "" -f rsa_$_n + ssh-keygen -qt dsa -b 1024 -C "DSA #$_n" -N "" -f dsa_$_n + ssh-keygen -qt ecdsa -b $_ecdsa_bits -C "ECDSA #$_n" -N "" -f ecdsa_$_n + ssh-keygen -qt ed25519 -C "ED25519 #$_n" -N "" -f ed25519_$_n + # Don't need private keys + rm -f rsa1_$_n rsa_$_n dsa_$_n ecdsa_$_n ed25519_$_n +} + +hentries() { + _preamble=$1 + _kspec=$2 + for k in `ls -1 $_kspec | sort` ; do + printf "$_preamble " + cat $k + done + echo +} + +gen_all 1 +gen_all 2 +gen_all 3 +gen_all 4 +gen_all 5 +gen_all 6 + +# A section of known_hosts with hashed hostnames. +( + hentries "sisyphus.example.com" "*_5.pub" + hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_6.pub" +) > known_hosts_hash_frag +ssh-keygen -Hf known_hosts_hash_frag +rm -f known_hosts_hash_frag.old + +# Populated known_hosts, including comments, hashed names and invalid lines +( + echo "# Plain host keys, plain host names" + hentries "sisyphus.example.com" "*_1.pub" + + echo "# Plain host keys, hostnames + addresses" + hentries "prometheus.example.com,192.0.2.1,2001:db8::1" "*_2.pub" + + echo "# Some hosts with wildcard names / IPs" + hentries "*.example.com,192.0.2.*,2001:*" "*_3.pub" + + echo "# Hashed hostname and address entries" + cat known_hosts_hash_frag + rm -f known_hosts_hash_frag + echo + + echo "# Revoked and CA keys" + printf "@revoked sisyphus.example.com " ; cat rsa1_4.pub + printf "@revoked sisyphus.example.com " ; cat ed25519_4.pub + printf "@cert-authority prometheus.example.com " ; cat ecdsa_4.pub + printf "@cert-authority *.example.com " ; cat dsa_4.pub + + printf "\n" + echo "# Some invalid lines" + # Invalid marker + printf "@what sisyphus.example.com " ; cat rsa1_1.pub + # Key missing + echo "sisyphus.example.com " + # Key blob missing + echo "prometheus.example.com ssh-ed25519 " + # Key blob truncated + echo "sisyphus.example.com ssh-dsa AAAATgAAAAdz" + # RSA1 key truncated after key bits + echo "prometheus.example.com 1024 " + # RSA1 key truncated after exponent + echo "sisyphus.example.com 1024 65535 " + # RSA1 key incorrect key bits + printf "prometheus.example.com 1025 " ; cut -d' ' -f2- < rsa1_1.pub + # Invalid type + echo "sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" + # Type mismatch with blob + echo "prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg==" +) > known_hosts + +echo OK diff --git a/crypto/openssh/regress/unittests/hostkeys/test_iterate.c b/crypto/openssh/regress/unittests/hostkeys/test_iterate.c new file mode 100644 index 000000000000..d81291b68b03 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/test_iterate.c @@ -0,0 +1,1171 @@ +/* $OpenBSD: test_iterate.c,v 1.3 2015/03/07 04:41:48 djm Exp $ */ +/* + * Regress test for hostfile.h hostkeys_foreach() + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "sshkey.h" +#include "authfile.h" +#include "hostfile.h" + +struct expected { + const char *key_file; /* Path for key, NULL for none */ + int no_parse_status; /* Expected status w/o key parsing */ + int no_parse_keytype; /* Expected keytype w/o key parsing */ + int match_host_p; /* Match 'prometheus.example.com' */ + int match_host_s; /* Match 'sisyphus.example.com' */ + int match_ipv4; /* Match '192.0.2.1' */ + int match_ipv6; /* Match '2001:db8::1' */ + int match_flags; /* Expected flags from match */ + struct hostkey_foreach_line l; /* Expected line contents */ +}; + +struct cbctx { + const struct expected *expected; + size_t nexpected; + size_t i; + int flags; + int match_host_p; + int match_host_s; + int match_ipv4; + int match_ipv6; +}; + +/* + * hostkeys_foreach() iterator callback that verifies the line passed + * against an array of expected entries. + */ +static int +check(struct hostkey_foreach_line *l, void *_ctx) +{ + struct cbctx *ctx = (struct cbctx *)_ctx; + const struct expected *expected; + int parse_key = (ctx->flags & HKF_WANT_PARSE_KEY) != 0; + const int matching = (ctx->flags & HKF_WANT_MATCH) != 0; + u_int expected_status, expected_match; + int expected_keytype; + + test_subtest_info("entry %zu/%zu, file line %ld", + ctx->i + 1, ctx->nexpected, l->linenum); + + for (;;) { + ASSERT_SIZE_T_LT(ctx->i, ctx->nexpected); + expected = ctx->expected + ctx->i++; + /* If we are matching host/IP then skip entries that don't */ + if (!matching) + break; + if (ctx->match_host_p && expected->match_host_p) + break; + if (ctx->match_host_s && expected->match_host_s) + break; + if (ctx->match_ipv4 && expected->match_ipv4) + break; + if (ctx->match_ipv6 && expected->match_ipv6) + break; + } + expected_status = (parse_key || expected->no_parse_status < 0) ? + expected->l.status : (u_int)expected->no_parse_status; + expected_match = expected->l.match; +#define UPDATE_MATCH_STATUS(x) do { \ + if (ctx->x && expected->x) { \ + expected_match |= expected->x; \ + if (expected_status == HKF_STATUS_OK) \ + expected_status = HKF_STATUS_MATCHED; \ + } \ + } while (0) + expected_keytype = (parse_key || expected->no_parse_keytype < 0) ? + expected->l.keytype : expected->no_parse_keytype; + +#ifndef WITH_SSH1 + if (expected->l.keytype == KEY_RSA1 || + expected->no_parse_keytype == KEY_RSA1) { + expected_status = HKF_STATUS_INVALID; + expected_keytype = KEY_UNSPEC; + parse_key = 0; + } +#endif +#ifndef OPENSSL_HAS_ECC + if (expected->l.keytype == KEY_ECDSA || + expected->no_parse_keytype == KEY_ECDSA) { + expected_status = HKF_STATUS_INVALID; + expected_keytype = KEY_UNSPEC; + parse_key = 0; + } +#endif + + UPDATE_MATCH_STATUS(match_host_p); + UPDATE_MATCH_STATUS(match_host_s); + UPDATE_MATCH_STATUS(match_ipv4); + UPDATE_MATCH_STATUS(match_ipv6); + + ASSERT_PTR_NE(l->path, NULL); /* Don't care about path */ + ASSERT_LONG_LONG_EQ(l->linenum, expected->l.linenum); + ASSERT_U_INT_EQ(l->status, expected_status); + ASSERT_U_INT_EQ(l->match, expected_match); + /* Not all test entries contain fulltext */ + if (expected->l.line != NULL) + ASSERT_STRING_EQ(l->line, expected->l.line); + ASSERT_INT_EQ(l->marker, expected->l.marker); + /* XXX we skip hashed hostnames for now; implement checking */ + if (expected->l.hosts != NULL) + ASSERT_STRING_EQ(l->hosts, expected->l.hosts); + /* Not all test entries contain raw keys */ + if (expected->l.rawkey != NULL) + ASSERT_STRING_EQ(l->rawkey, expected->l.rawkey); + /* XXX synthesise raw key for cases lacking and compare */ + ASSERT_INT_EQ(l->keytype, expected_keytype); + if (parse_key) { + if (expected->l.key == NULL) + ASSERT_PTR_EQ(l->key, NULL); + if (expected->l.key != NULL) { + ASSERT_PTR_NE(l->key, NULL); + ASSERT_INT_EQ(sshkey_equal(l->key, expected->l.key), 1); + } + } + if (parse_key && !(l->comment == NULL && expected->l.comment == NULL)) + ASSERT_STRING_EQ(l->comment, expected->l.comment); + return 0; +} + +/* Loads public keys for a set of expected results */ +static void +prepare_expected(struct expected *expected, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + if (expected[i].key_file == NULL) + continue; +#ifndef WITH_SSH1 + if (expected[i].l.keytype == KEY_RSA1) + continue; +#endif +#ifndef OPENSSL_HAS_ECC + if (expected[i].l.keytype == KEY_ECDSA) + continue; +#endif + ASSERT_INT_EQ(sshkey_load_public( + test_data_file(expected[i].key_file), &expected[i].l.key, + NULL), 0); + } +} + +struct expected expected_full[] = { + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, /* path, don't care */ + 1, /* line number */ + HKF_STATUS_COMMENT, /* status */ + 0, /* match flags */ + "# Plain host keys, plain host names", /* full line, optional */ + MRK_NONE, /* marker (CA / revoked) */ + NULL, /* hosts text */ + NULL, /* raw key, optional */ + KEY_UNSPEC, /* key type */ + NULL, /* deserialised key */ + NULL, /* comment */ + } }, + { "dsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 2, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #1", + } }, + { "ecdsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 3, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #1", + } }, + { "ed25519_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 4, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #1", + } }, + { "rsa1_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 5, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #1", + } }, + { "rsa_1.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 6, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #1", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 7, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 8, + HKF_STATUS_COMMENT, + 0, + "# Plain host keys, hostnames + addresses", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "dsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 9, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #2", + } }, + { "ecdsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 10, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #2", + } }, + { "ed25519_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 11, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #2", + } }, + { "rsa1_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 12, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #2", + } }, + { "rsa_2.pub" , -1, -1, HKF_MATCH_HOST, 0, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 13, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "prometheus.example.com,192.0.2.1,2001:db8::1", + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #2", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 14, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 15, + HKF_STATUS_COMMENT, + 0, + "# Some hosts with wildcard names / IPs", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "dsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 16, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #3", + } }, + { "ecdsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 17, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #3", + } }, + { "ed25519_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 18, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #3", + } }, + { "rsa1_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 19, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #3", + } }, + { "rsa_3.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, HKF_MATCH_IP, HKF_MATCH_IP, -1, { + NULL, + 20, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + "*.example.com,192.0.2.*,2001:*", + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #3", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 21, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 22, + HKF_STATUS_COMMENT, + 0, + "# Hashed hostname and address entries", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "dsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 23, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #5", + } }, + { "ecdsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 24, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #5", + } }, + { "ed25519_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 25, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #5", + } }, + { "rsa1_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 26, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #5", + } }, + { "rsa_5.pub" , -1, -1, 0, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, -1, { + NULL, + 27, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #5", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 28, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + /* + * The next series have each key listed multiple times, as the + * hostname and addresses in the pre-hashed known_hosts are split + * to separate lines. + */ + { "dsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 29, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #6", + } }, + { "dsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 30, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #6", + } }, + { "dsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 31, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #6", + } }, + { "ecdsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 32, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #6", + } }, + { "ecdsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 33, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #6", + } }, + { "ecdsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 34, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #6", + } }, + { "ed25519_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 35, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #6", + } }, + { "ed25519_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 36, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #6", + } }, + { "ed25519_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 37, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #6", + } }, + { "rsa1_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 38, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #6", + } }, + { "rsa1_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 39, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #6", + } }, + { "rsa1_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 40, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #6", + } }, + { "rsa_6.pub" , -1, -1, HKF_MATCH_HOST|HKF_MATCH_HOST_HASHED, 0, 0, 0, -1, { + NULL, + 41, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #6", + } }, + { "rsa_6.pub" , -1, -1, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, 0, -1, { + NULL, + 42, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #6", + } }, + { "rsa_6.pub" , -1, -1, 0, 0, 0, HKF_MATCH_IP|HKF_MATCH_IP_HASHED, -1, { + NULL, + 43, + HKF_STATUS_OK, + 0, + NULL, + MRK_NONE, + NULL, + NULL, + KEY_RSA, + NULL, /* filled at runtime */ + "RSA #6", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 44, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 45, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 46, + HKF_STATUS_COMMENT, + 0, + "# Revoked and CA keys", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { "rsa1_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 47, + HKF_STATUS_OK, + 0, + NULL, + MRK_REVOKE, + "sisyphus.example.com", + NULL, + KEY_RSA1, + NULL, /* filled at runtime */ + "RSA1 #4", + } }, + { "ed25519_4.pub" , -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 48, + HKF_STATUS_OK, + 0, + NULL, + MRK_REVOKE, + "sisyphus.example.com", + NULL, + KEY_ED25519, + NULL, /* filled at runtime */ + "ED25519 #4", + } }, + { "ecdsa_4.pub" , -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 49, + HKF_STATUS_OK, + 0, + NULL, + MRK_CA, + "prometheus.example.com", + NULL, + KEY_ECDSA, + NULL, /* filled at runtime */ + "ECDSA #4", + } }, + { "dsa_4.pub" , -1, -1, HKF_MATCH_HOST, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 50, + HKF_STATUS_OK, + 0, + NULL, + MRK_CA, + "*.example.com", + NULL, + KEY_DSA, + NULL, /* filled at runtime */ + "DSA #4", + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 51, + HKF_STATUS_COMMENT, + 0, + "", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 52, + HKF_STATUS_COMMENT, + 0, + "# Some invalid lines", + MRK_NONE, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, 0, 0, 0, -1, { + NULL, + 53, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_ERROR, + NULL, + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 54, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 55, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 56, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, -1, -1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 57, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, HKF_STATUS_OK, KEY_RSA1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 58, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, + NULL, + } }, + { NULL, HKF_STATUS_OK, KEY_RSA1, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 59, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, /* filled at runtime */ + NULL, + } }, + { NULL, -1, -1, 0, HKF_MATCH_HOST, 0, 0, -1, { + NULL, + 60, + HKF_STATUS_INVALID, + 0, + NULL, + MRK_NONE, + "sisyphus.example.com", + NULL, + KEY_UNSPEC, + NULL, /* filled at runtime */ + NULL, + } }, + { NULL, HKF_STATUS_OK, KEY_RSA, HKF_MATCH_HOST, 0, 0, 0, -1, { + NULL, + 61, + HKF_STATUS_INVALID, /* Would be ok if key not parsed */ + 0, + NULL, + MRK_NONE, + "prometheus.example.com", + NULL, + KEY_UNSPEC, + NULL, /* filled at runtime */ + NULL, + } }, +}; + +void test_iterate(void); + +void +test_iterate(void) +{ + struct cbctx ctx; + + TEST_START("hostkeys_iterate all with key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_PARSE_KEY; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, NULL, NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate all without key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, NULL, NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 1"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_host_p = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 2"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_host_s = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 1"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_host_p = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 2"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_host_s = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "actaeon.example.org", NULL, ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify IPv4"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify IPv6"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match IPv4"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match IPv6"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify addr missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "192.168.0.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match addr missing"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "tiresias.example.org", "::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 2 and IPv4"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = 0; + ctx.match_host_s = 1; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 1 and IPv6"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH; + ctx.match_host_p = 1; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate specify host 2 and IPv4 w/ key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_PARSE_KEY; + ctx.match_host_s = 1; + ctx.match_ipv4 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "sisyphus.example.com", "192.0.2.1", ctx.flags), 0); + TEST_DONE(); + + TEST_START("hostkeys_iterate match host 1 and IPv6 w/ key parse"); + memset(&ctx, 0, sizeof(ctx)); + ctx.expected = expected_full; + ctx.nexpected = sizeof(expected_full)/sizeof(*expected_full); + ctx.flags = HKF_WANT_MATCH|HKF_WANT_PARSE_KEY; + ctx.match_host_p = 1; + ctx.match_ipv6 = 1; + prepare_expected(expected_full, ctx.nexpected); + ASSERT_INT_EQ(hostkeys_foreach(test_data_file("known_hosts"), + check, &ctx, "prometheus.example.com", "2001:db8::1", ctx.flags), 0); + TEST_DONE(); +} + diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub new file mode 100644 index 000000000000..56e1e3714625 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_1.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub new file mode 100644 index 000000000000..394e0bf00255 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_2.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub new file mode 100644 index 000000000000..e506ea42253a --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_3.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub new file mode 100644 index 000000000000..8552c3819287 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_4.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub new file mode 100644 index 000000000000..149e1efd166b --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_5.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub new file mode 100644 index 000000000000..edbb97643d26 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/dsa_6.pub @@ -0,0 +1 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub new file mode 100644 index 000000000000..16a535bccb0a --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_1.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub new file mode 100644 index 000000000000..d2bad11e2379 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_2.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub new file mode 100644 index 000000000000..e3ea9254ec1a --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_3.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub new file mode 100644 index 000000000000..2d616f5c6de6 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_4.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub new file mode 100644 index 000000000000..a3df9b3f40aa --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_5.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub new file mode 100644 index 000000000000..139f5a7bf8a4 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ecdsa_6.pub @@ -0,0 +1 @@ +ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub new file mode 100644 index 000000000000..0b12efedbfdc --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_1.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub new file mode 100644 index 000000000000..78e262bcc195 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_2.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub new file mode 100644 index 000000000000..64e5f12a6209 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_3.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub new file mode 100644 index 000000000000..47b6724ec89e --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_4.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub new file mode 100644 index 000000000000..72ccae6fed2e --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_5.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub new file mode 100644 index 000000000000..0f719731db29 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/ed25519_6.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts b/crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts new file mode 100644 index 000000000000..3740f674b48b --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/known_hosts @@ -0,0 +1,61 @@ +# Plain host keys, plain host names +sisyphus.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 +sisyphus.example.com ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 +sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 +sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 +sisyphus.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 + +# Plain host keys, hostnames + addresses +prometheus.example.com,192.0.2.1,2001:db8::1 ssh-dss AAAAB3NzaC1kc3MAAACBAI38Hy/61/O5Bp6yUG8J5XQCeNjRS0xvjlCdzKLyXCueMa+L+X2L/u9PWUsy5SVbTjGgpB8sF6UkCNsV+va7S8zCCHas2MZ7GPlxP6GZBkRPTIFR0N/Pu7wfBzDQz0t0iL4VmxBfTBQv/SxkGWZg+yHihIQP9fwdSAwD/7aVh6ItAAAAFQDSyihIUlINlswM0PJ8wXSti3yIMwAAAIB+oqzaB6ozqs8YxpN5oQOBa/9HEBQEsp8RSIlQmVubXRNgktp42n+Ii1waU9UUk8DX5ahhIeR6B7ojWkqmDAji4SKpoHf4kmr6HvYo85ZSTSx0W4YK/gJHSpDJwhlT52tAfb1JCbWSObjl09B4STv7KedCHcR5oXQvvrV+XoKOSAAAAIAue/EXrs2INw1RfaKNHC0oqOMxmRitv0BFMuNVPo1VDj39CE5kA7AHjwvS1TNeaHtK5Hhgeb6vsmLmNPTOc8xCob0ilyQbt9O0GbONeF2Ge7D2UJyULA/hxql+tCYFIC6yUrmo35fF9XiNisXLoaflk9fjp7ROWWVwnki/jstaQw== DSA #2 +prometheus.example.com,192.0.2.1,2001:db8::1 ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 +prometheus.example.com,192.0.2.1,2001:db8::1 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 +prometheus.example.com,192.0.2.1,2001:db8::1 1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 +prometheus.example.com,192.0.2.1,2001:db8::1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 + +# Some hosts with wildcard names / IPs +*.example.com,192.0.2.*,2001:* ssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 +*.example.com,192.0.2.*,2001:* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 +*.example.com,192.0.2.*,2001:* ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 +*.example.com,192.0.2.*,2001:* 1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 +*.example.com,192.0.2.*,2001:* ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 + +# Hashed hostname and address entries +|1|6FWxoqTCAfm8sZ7T/q73OmxCFGM=|S4eQmusok4cbyDzzGEFGIAthDbw= ssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 +|1|hTrfD0CuuB9ZbOa1CHFYvIk/gKE=|tPmW50t7flncm1UyM+DR97ubDNU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 +|1|fOGqe75X5ZpTz4c7DitP4E8/y30=|Lmcch2fh54bUYoV//S2VqDFVeiY= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 +|1|0RVzLjY3lwE3MRweguaAXaCCWk8=|DbcIgJQcRZJMYI6NYDOM6oJycPk= 1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 +|1|4q79XnHpKBNQhyMLAqbPPDN+JKo=|k1Wvjjb52zDdrXWM801+wX5oH8U= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 + +|1|0M6PIx6THA3ipIOvTl3fcgn2z+A=|bwEJAOwJz+Sm7orFdgj170mD/zY= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 +|1|a6WGHcL+9gX3e96tMlgDSDJwtSg=|5Dqlb/yqNEf7jgfllrp/ygLmRV8= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 +|1|OeCpi7Pn5Q6c8la4fPf9G8YctT8=|sC6D7lDXTafIpokZJ1+1xWg2R6Q= ssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 +|1|BHESVyiJ7G2NN0lxrw7vT109jmk=|TKof+015J77bXqibsh0N1Lp0MKk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 +|1|wY53mZNASDJ5/P3JYCJ4FUNa6WQ=|v8p0MfV5lqlZB2J0yLxl/gsWVQo= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 +|1|horeoyFPwfKhyFN+zJZ5LCfOo/I=|2ofvp0tNwCbKsV8FuiFA4gQG2Z8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 +|1|Aw4fXumZfx6jEIJuDGIyeEMd81A=|5FdLtdm2JeKNsS8IQeQlGYIadOE= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 +|1|+dGUNpv6GblrDd5fgHLlOWpSbEo=|He/pQ1yJjtiCyTNWpGwjBD4sZFI= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 +|1|E/PACGl8m1T7QnPedOoooozstP0=|w6DQAFT8yZgj0Hlkz5R1TppYHCA= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 +|1|SaoyMStgxpYfwedSXBAghi8Zo0s=|Gz78k69GaE6iViV3OOvbStKqyTA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 +|1|8qfGeiT5WTCzWYbXPQ+lsLg7km4=|1sIBwiSUr8IGkvrUGm3/9QYurmA= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 +|1|87M1OtyHg1BZiDY3rT6lYsZFnAU=|eddAQVcMNbn2OB87XWXFQnYo6R4= 1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 +|1|60w3wFfC0XWI+rRmRlxIRhh8lwE=|yMhsGrzBJKiesAdSQ/PVgkCrDKk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 +|1|5gdEMmLUJC7grqWhRJPy2OTaSyE=|/XTfmLMa/B8npcVCGFRdaHl+d/0= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 +|1|6FGCWUr42GHdMB/eifnHNCuwgdk=|ONJvYZ/ANmi59R5HrOhLPmvYENM= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 + + +# Revoked and CA keys +@revoked sisyphus.example.com 1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 +@revoked sisyphus.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 +@cert-authority prometheus.example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 +@cert-authority *.example.com ssh-dss AAAAB3NzaC1kc3MAAACBAKvjnFHm0VvMr5h2Zu3nURsxQKGoxm+DCzYDxRYcilK07Cm5c4XTrFbA2X86+9sGs++W7QRMcTJUYIg0a+UtIMtAjwORd6ZPXM2K5dBW+gh1oHyvKi767tWX7I2c+1ZPJDY95mUUfZQUEfdy9eGDSBmw/pSsveQ1ur6XNUh/MtP/AAAAFQDHnXk/9jBJAdce1pHtLWnbdPSGdQAAAIEAm2OLy8tZBfiEO3c3X1yyB/GTcDwrQCqRMDkhnsmrliec3dWkOfNTzu+MrdvF8ymTWLEqPpbMheYtvNyZ3TF0HO5W7aVBpdGZbOdOAIfB+6skqGbI8A5Up1d7dak/bSsqL2r5NjwbDOdq+1hBzzvbl/qjh+sQarV2zHrpKoQaV28AAACANtkBVedBbqIAdphCrN/LbUi9WlyuF9UZz+tlpVLYrj8GJVwnplV2tvOmUw6yP5/pzCimTsao8dpL5PWxm7fKxLWVxA+lEsA4WeC885CiZn8xhdaJOCN+NyJ2bqkz+4VPI7oDGBm0aFwUqJn+M1PiSgvI50XdF2dBsFRTRNY0wzA= DSA #4 + +# Some invalid lines +@what sisyphus.example.com 1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 +sisyphus.example.com +prometheus.example.com ssh-ed25519 +sisyphus.example.com ssh-dsa AAAATgAAAAdz +prometheus.example.com 1024 +sisyphus.example.com 1024 65535 +prometheus.example.com 1025 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 +sisyphus.example.com ssh-XXX AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== +prometheus.example.com ssh-rsa AAAATgAAAAdzc2gtWFhYAAAAP0ZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRkZVQ0tPRkZGVUNLT0ZGRlVDS09GRg== diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub new file mode 100644 index 000000000000..772ce9c05bbb --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_1.pub @@ -0,0 +1 @@ +1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub new file mode 100644 index 000000000000..78794b94153b --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_2.pub @@ -0,0 +1 @@ +1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub new file mode 100644 index 000000000000..0c035fe0ac0f --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_3.pub @@ -0,0 +1 @@ +1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub new file mode 100644 index 000000000000..00064423e7f9 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_4.pub @@ -0,0 +1 @@ +1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub new file mode 100644 index 000000000000..bb53c2642dbe --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_5.pub @@ -0,0 +1 @@ +1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub new file mode 100644 index 000000000000..85d6576b57ac --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa1_6.pub @@ -0,0 +1 @@ +1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub new file mode 100644 index 000000000000..2b87885a19dd --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_1.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub new file mode 100644 index 000000000000..33f1fd93b58b --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_2.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub new file mode 100644 index 000000000000..c2f6b208ce71 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_3.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub new file mode 100644 index 000000000000..35545a713aaa --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_4.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDI8AdjBAozcdRnIikVlt69iyDHKyrtxmpdkbRy9bWaL86OH+PTmLUk5e+T/ufiakpeE2pm0hkE3e4Sh/FsY+rsQdRoraWVNFfchcMeVlKvuy5RZN0ElvmaQebOJUeNeBn2LLw8aL8bJ4CP/bQRKrmrSSqjz3+4H9YNVyyk1OGBPQ== RSA #4 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub new file mode 100644 index 000000000000..befbaa7d93de --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_5.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 diff --git a/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub new file mode 100644 index 000000000000..393e1167200f --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/testdata/rsa_6.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 diff --git a/crypto/openssh/regress/unittests/hostkeys/tests.c b/crypto/openssh/regress/unittests/hostkeys/tests.c new file mode 100644 index 000000000000..92c7646ad164 --- /dev/null +++ b/crypto/openssh/regress/unittests/hostkeys/tests.c @@ -0,0 +1,16 @@ +/* $OpenBSD: tests.c,v 1.1 2015/02/16 22:18:34 djm Exp $ */ +/* + * Regress test for known_hosts-related API. + * + * Placed in the public domain + */ + +void tests(void); +void test_iterate(void); /* test_iterate.c */ + +void +tests(void) +{ + test_iterate(); +} + diff --git a/crypto/openssh/regress/unittests/kex/Makefile b/crypto/openssh/regress/unittests/kex/Makefile new file mode 100644 index 000000000000..6532cb00a6a0 --- /dev/null +++ b/crypto/openssh/regress/unittests/kex/Makefile @@ -0,0 +1,14 @@ +# $OpenBSD: Makefile,v 1.2 2015/01/24 10:39:21 miod Exp $ + +TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" + +PROG=test_kex +SRCS=tests.c test_kex.c +REGRESS_TARGETS=run-regress-${PROG} + +run-regress-${PROG}: ${PROG} + env ${TEST_ENV} ./${PROG} + +.include + +LDADD+=-lz diff --git a/crypto/openssh/regress/unittests/kex/test_kex.c b/crypto/openssh/regress/unittests/kex/test_kex.c new file mode 100644 index 000000000000..c61e2bdbb270 --- /dev/null +++ b/crypto/openssh/regress/unittests/kex/test_kex.c @@ -0,0 +1,197 @@ +/* $OpenBSD: test_kex.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */ +/* + * Regress test KEX + * + * Placed in the public domain + */ + +#include "includes.h" + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include + +#include "../test_helper/test_helper.h" + +#include "ssherr.h" +#include "ssh_api.h" +#include "sshbuf.h" +#include "packet.h" +#include "myproposal.h" + +struct ssh *active_state = NULL; /* XXX - needed for linking */ + +void kex_tests(void); +static int do_debug = 0; + +static int +do_send_and_receive(struct ssh *from, struct ssh *to) +{ + u_char type; + size_t len; + const u_char *buf; + int r; + + for (;;) { + if ((r = ssh_packet_next(from, &type)) != 0) { + fprintf(stderr, "ssh_packet_next: %s\n", ssh_err(r)); + return r; + } + if (type != 0) + return 0; + buf = ssh_output_ptr(from, &len); + if (do_debug) + printf("%zu", len); + if (len == 0) + return 0; + if ((r = ssh_output_consume(from, len)) != 0 || + (r = ssh_input_append(to, buf, len)) != 0) + return r; + } +} + +static void +run_kex(struct ssh *client, struct ssh *server) +{ + int r = 0; + + while (!server->kex->done || !client->kex->done) { + if (do_debug) + printf(" S:"); + if ((r = do_send_and_receive(server, client))) + break; + if (do_debug) + printf(" C:"); + if ((r = do_send_and_receive(client, server))) + break; + } + if (do_debug) + printf("done: %s\n", ssh_err(r)); + ASSERT_INT_EQ(r, 0); + ASSERT_INT_EQ(server->kex->done, 1); + ASSERT_INT_EQ(client->kex->done, 1); +} + +static void +do_kex_with_key(char *kex, int keytype, int bits) +{ + struct ssh *client = NULL, *server = NULL, *server2 = NULL; + struct sshkey *private, *public; + struct sshbuf *state; + struct kex_params kex_params; + char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; + + TEST_START("sshkey_generate"); + ASSERT_INT_EQ(sshkey_generate(keytype, bits, &private), 0); + TEST_DONE(); + + TEST_START("sshkey_from_private"); + ASSERT_INT_EQ(sshkey_from_private(private, &public), 0); + TEST_DONE(); + + TEST_START("ssh_init"); + memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); + if (kex != NULL) + kex_params.proposal[PROPOSAL_KEX_ALGS] = kex; + ASSERT_INT_EQ(ssh_init(&client, 0, &kex_params), 0); + ASSERT_INT_EQ(ssh_init(&server, 1, &kex_params), 0); + ASSERT_PTR_NE(client, NULL); + ASSERT_PTR_NE(server, NULL); + TEST_DONE(); + + TEST_START("ssh_add_hostkey"); + ASSERT_INT_EQ(ssh_add_hostkey(server, private), 0); + ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0); + TEST_DONE(); + + TEST_START("kex"); + run_kex(client, server); + TEST_DONE(); + + TEST_START("rekeying client"); + ASSERT_INT_EQ(kex_send_kexinit(client), 0); + run_kex(client, server); + TEST_DONE(); + + TEST_START("rekeying server"); + ASSERT_INT_EQ(kex_send_kexinit(server), 0); + run_kex(client, server); + TEST_DONE(); + + TEST_START("ssh_packet_get_state"); + state = sshbuf_new(); + ASSERT_PTR_NE(state, NULL); + ASSERT_INT_EQ(ssh_packet_get_state(server, state), 0); + ASSERT_INT_GE(sshbuf_len(state), 1); + TEST_DONE(); + + TEST_START("ssh_packet_set_state"); + server2 = NULL; + ASSERT_INT_EQ(ssh_init(&server2, 1, NULL), 0); + ASSERT_PTR_NE(server2, NULL); + ASSERT_INT_EQ(ssh_add_hostkey(server2, private), 0); + kex_free(server2->kex); /* XXX or should ssh_packet_set_state()? */ + ASSERT_INT_EQ(ssh_packet_set_state(server2, state), 0); + ASSERT_INT_EQ(sshbuf_len(state), 0); + sshbuf_free(state); + ASSERT_PTR_NE(server2->kex, NULL); + /* XXX we need to set the callbacks */ + server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; + server2->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + server2->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +#ifdef OPENSSL_HAS_ECC + server2->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; +#endif + server2->kex->kex[KEX_C25519_SHA256] = kexc25519_server; + server2->kex->load_host_public_key = server->kex->load_host_public_key; + server2->kex->load_host_private_key = server->kex->load_host_private_key; + server2->kex->sign = server->kex->sign; + TEST_DONE(); + + TEST_START("rekeying server2"); + ASSERT_INT_EQ(kex_send_kexinit(server2), 0); + run_kex(client, server2); + ASSERT_INT_EQ(kex_send_kexinit(client), 0); + run_kex(client, server2); + TEST_DONE(); + + TEST_START("cleanup"); + sshkey_free(private); + sshkey_free(public); + ssh_free(client); + ssh_free(server); + ssh_free(server2); + TEST_DONE(); +} + +static void +do_kex(char *kex) +{ + do_kex_with_key(kex, KEY_RSA, 2048); + do_kex_with_key(kex, KEY_DSA, 1024); +#ifdef OPENSSL_HAS_ECC + do_kex_with_key(kex, KEY_ECDSA, 256); +#endif + do_kex_with_key(kex, KEY_ED25519, 256); +} + +void +kex_tests(void) +{ + do_kex("curve25519-sha256@libssh.org"); +#ifdef OPENSSL_HAS_ECC + do_kex("ecdh-sha2-nistp256"); + do_kex("ecdh-sha2-nistp384"); + do_kex("ecdh-sha2-nistp521"); +#endif + do_kex("diffie-hellman-group-exchange-sha256"); + do_kex("diffie-hellman-group-exchange-sha1"); + do_kex("diffie-hellman-group14-sha1"); + do_kex("diffie-hellman-group1-sha1"); +} diff --git a/crypto/openssh/regress/unittests/kex/tests.c b/crypto/openssh/regress/unittests/kex/tests.c new file mode 100644 index 000000000000..e7036ec17f7b --- /dev/null +++ b/crypto/openssh/regress/unittests/kex/tests.c @@ -0,0 +1,14 @@ +/* $OpenBSD: tests.c,v 1.1 2015/01/15 23:41:29 markus Exp $ */ +/* + * Placed in the public domain + */ + +#include "../test_helper/test_helper.h" + +void kex_tests(void); + +void +tests(void) +{ + kex_tests(); +} diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c index 0c4c71ecdc02..a68e1329e40b 100644 --- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c @@ -32,8 +32,6 @@ void sshbuf_getput_crypto_tests(void) { struct sshbuf *p1; - const u_char *d; - size_t s; BIGNUM *bn, *bn2; /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; @@ -48,7 +46,9 @@ sshbuf_getput_crypto_tests(void) 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 0x7f, 0xff, 0x11 }; -#ifdef OPENSSL_HAS_NISTP256 +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) + const u_char *d; + size_t s; BIGNUM *bn_x, *bn_y; int ec256_nid = NID_X9_62_prime256v1; char *ec256_x = "0C828004839D0106AA59575216191357" @@ -352,7 +352,7 @@ sshbuf_getput_crypto_tests(void) sshbuf_free(p1); TEST_DONE(); -#ifdef OPENSSL_HAS_NISTP256 +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) TEST_START("sshbuf_put_ec"); eck = EC_KEY_new_by_curve_name(ec256_nid); ASSERT_PTR_NE(eck, NULL); diff --git a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c index 8c3269b138d0..c6b5c29d176b 100644 --- a/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c +++ b/crypto/openssh/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c @@ -33,7 +33,7 @@ attempt_parse_blob(u_char *blob, size_t len) { struct sshbuf *p1; BIGNUM *bn; -#ifdef OPENSSL_HAS_NISTP256 +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) EC_KEY *eck; #endif u_char *s; @@ -60,7 +60,7 @@ attempt_parse_blob(u_char *blob, size_t len) bn = BN_new(); sshbuf_get_bignum2(p1, bn); BN_clear_free(bn); -#ifdef OPENSSL_HAS_NISTP256 +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ASSERT_PTR_NE(eck, NULL); sshbuf_get_eckey(p1, eck); diff --git a/crypto/openssh/regress/unittests/sshkey/common.c b/crypto/openssh/regress/unittests/sshkey/common.c index 0a4b3a90ce7e..b598f05cb967 100644 --- a/crypto/openssh/regress/unittests/sshkey/common.c +++ b/crypto/openssh/regress/unittests/sshkey/common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: common.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* $OpenBSD: common.c,v 1.2 2015/01/08 13:10:58 djm Exp $ */ /* * Helpers for key API tests * @@ -44,7 +44,7 @@ load_file(const char *name) ASSERT_PTR_NE(ret = sshbuf_new(), NULL); ASSERT_INT_NE(fd = open(test_data_file(name), O_RDONLY), -1); - ASSERT_INT_EQ(sshkey_load_file(fd, name, ret), 0); + ASSERT_INT_EQ(sshkey_load_file(fd, ret), 0); close(fd); return ret; } diff --git a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh index ee1fe3962084..09165af02fd4 100755 --- a/crypto/openssh/regress/unittests/sshkey/mktestdata.sh +++ b/crypto/openssh/regress/unittests/sshkey/mktestdata.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: mktestdata.sh,v 1.3 2014/07/22 23:57:40 dtucker Exp $ +# $OpenBSD: mktestdata.sh,v 1.4 2015/01/18 19:54:46 djm Exp $ PW=mekmitasdigoat @@ -187,4 +187,6 @@ ssh-keygen -Bf dsa_2 | awk '{print $2}' > dsa_2.fp.bb ssh-keygen -Bf ecdsa_2 | awk '{print $2}' > ecdsa_2.fp.bb ssh-keygen -Bf ed25519_2 | awk '{print $2}' > ed25519_2.fp.bb +# XXX Extend ssh-keygen to do detached signatures (better to test/fuzz against) + echo "$PW" > pw diff --git a/crypto/openssh/regress/unittests/sshkey/test_file.c b/crypto/openssh/regress/unittests/sshkey/test_file.c index 764f7fb769ea..fa95212bfcb1 100644 --- a/crypto/openssh/regress/unittests/sshkey/test_file.c +++ b/crypto/openssh/regress/unittests/sshkey/test_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_file.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* $OpenBSD: test_file.c,v 1.3 2015/03/04 23:22:35 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -33,6 +33,7 @@ #include "authfile.h" #include "sshkey.h" #include "sshbuf.h" +#include "digest.h" #include "common.h" @@ -50,6 +51,7 @@ sshkey_file_tests(void) pw = load_text_file("pw"); TEST_DONE(); +#ifdef WITH_SSH1 TEST_START("parse RSA1 from private"); buf = load_file("rsa1_1"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1", @@ -81,7 +83,7 @@ sshkey_file_tests(void) TEST_START("RSA1 key hex fingerprint"); buf = load_text_file("rsa1_1.fp"); - cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -90,7 +92,7 @@ sshkey_file_tests(void) TEST_START("RSA1 key bubblebabble fingerprint"); buf = load_text_file("rsa1_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -98,6 +100,7 @@ sshkey_file_tests(void) TEST_DONE(); sshkey_free(k1); +#endif TEST_START("parse RSA from private"); buf = load_file("rsa_1"); @@ -164,7 +167,7 @@ sshkey_file_tests(void) TEST_START("RSA key hex fingerprint"); buf = load_text_file("rsa_1.fp"); - cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -173,7 +176,7 @@ sshkey_file_tests(void) TEST_START("RSA cert hex fingerprint"); buf = load_text_file("rsa_1-cert.fp"); - cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -183,7 +186,7 @@ sshkey_file_tests(void) TEST_START("RSA key bubblebabble fingerprint"); buf = load_text_file("rsa_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -257,7 +260,7 @@ sshkey_file_tests(void) TEST_START("DSA key hex fingerprint"); buf = load_text_file("dsa_1.fp"); - cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -266,7 +269,7 @@ sshkey_file_tests(void) TEST_START("DSA cert hex fingerprint"); buf = load_text_file("dsa_1-cert.fp"); - cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -276,7 +279,7 @@ sshkey_file_tests(void) TEST_START("DSA key bubblebabble fingerprint"); buf = load_text_file("dsa_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -357,7 +360,7 @@ sshkey_file_tests(void) TEST_START("ECDSA key hex fingerprint"); buf = load_text_file("ecdsa_1.fp"); - cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -366,7 +369,7 @@ sshkey_file_tests(void) TEST_START("ECDSA cert hex fingerprint"); buf = load_text_file("ecdsa_1-cert.fp"); - cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -376,7 +379,7 @@ sshkey_file_tests(void) TEST_START("ECDSA key bubblebabble fingerprint"); buf = load_text_file("ecdsa_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -424,7 +427,7 @@ sshkey_file_tests(void) TEST_START("Ed25519 key hex fingerprint"); buf = load_text_file("ed25519_1.fp"); - cp = sshkey_fingerprint(k1, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k1, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -433,7 +436,7 @@ sshkey_file_tests(void) TEST_START("Ed25519 cert hex fingerprint"); buf = load_text_file("ed25519_1-cert.fp"); - cp = sshkey_fingerprint(k2, SSH_FP_MD5, SSH_FP_HEX); + cp = sshkey_fingerprint(k2, SSH_DIGEST_MD5, SSH_FP_HEX); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); @@ -443,7 +446,7 @@ sshkey_file_tests(void) TEST_START("Ed25519 key bubblebabble fingerprint"); buf = load_text_file("ed25519_1.fp.bb"); - cp = sshkey_fingerprint(k1, SSH_FP_SHA1, SSH_FP_BUBBLEBABBLE); + cp = sshkey_fingerprint(k1, SSH_DIGEST_SHA1, SSH_FP_BUBBLEBABBLE); ASSERT_PTR_NE(cp, NULL); ASSERT_STRING_EQ(cp, (const char *)sshbuf_ptr(buf)); sshbuf_free(buf); diff --git a/crypto/openssh/regress/unittests/sshkey/test_fuzz.c b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c index a3f61a6dfba6..1f08a2e432bb 100644 --- a/crypto/openssh/regress/unittests/sshkey/test_fuzz.c +++ b/crypto/openssh/regress/unittests/sshkey/test_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_fuzz.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */ /* * Fuzz tests for key parsing * @@ -53,7 +53,7 @@ public_fuzz(struct sshkey *k) struct fuzz *fuzz; ASSERT_PTR_NE(buf = sshbuf_new(), NULL); - ASSERT_INT_EQ(sshkey_to_blob_buf(k, buf), 0); + ASSERT_INT_EQ(sshkey_putb(k, buf), 0); /* XXX need a way to run the tests in "slow, but complete" mode */ fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* XXX too slow FUZZ_2_BIT_FLIP | */ FUZZ_1_BYTE_FLIP | /* XXX too slow FUZZ_2_BYTE_FLIP | */ @@ -87,8 +87,11 @@ sig_fuzz(struct sshkey *k) free(sig); TEST_ONERROR(onerror, fuzz); for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { - sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), - c, sizeof(c), 0); + /* Ensure 1-bit difference at least */ + if (fuzz_matches_original(fuzz)) + continue; + ASSERT_INT_NE(sshkey_verify(k, fuzz_ptr(fuzz), fuzz_len(fuzz), + c, sizeof(c), 0), 0); } fuzz_cleanup(fuzz); } @@ -101,6 +104,7 @@ sshkey_fuzz_tests(void) struct fuzz *fuzz; int r; +#ifdef WITH_SSH1 TEST_START("fuzz RSA1 private"); buf = load_file("rsa1_1"); fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | @@ -144,6 +148,7 @@ sshkey_fuzz_tests(void) sshbuf_free(fuzzed); fuzz_cleanup(fuzz); TEST_DONE(); +#endif TEST_START("fuzz RSA private"); buf = load_file("rsa_1"); diff --git a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c index ef0c67956ebe..ad10c9be2b5f 100644 --- a/crypto/openssh/regress/unittests/sshkey/test_sshkey.c +++ b/crypto/openssh/regress/unittests/sshkey/test_sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshkey.c,v 1.1 2014/06/24 01:14:18 djm Exp $ */ +/* $OpenBSD: test_sshkey.c,v 1.3 2015/01/26 06:11:28 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -19,7 +19,7 @@ #include #include #include -#ifdef OPENSSL_HAS_NISTP256 +#if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) # include #endif @@ -36,6 +36,20 @@ void sshkey_tests(void); +static void +put_opt(struct sshbuf *b, const char *name, const char *value) +{ + struct sshbuf *sect; + + sect = sshbuf_new(); + ASSERT_PTR_NE(sect, NULL); + ASSERT_INT_EQ(sshbuf_put_cstring(b, name), 0); + if (value != NULL) + ASSERT_INT_EQ(sshbuf_put_cstring(sect, value), 0); + ASSERT_INT_EQ(sshbuf_put_stringb(b, sect), 0); + sshbuf_free(sect); +} + static void build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, const struct sshkey *sign_key, const struct sshkey *ca_key) @@ -45,25 +59,31 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, size_t siglen; ca_buf = sshbuf_new(); - ASSERT_INT_EQ(sshkey_to_blob_buf(ca_key, ca_buf), 0); + ASSERT_PTR_NE(ca_buf, NULL); + ASSERT_INT_EQ(sshkey_putb(ca_key, ca_buf), 0); /* * Get the public key serialisation by rendering the key and skipping * the type string. This is a bit of a hack :/ */ pk = sshbuf_new(); - ASSERT_INT_EQ(sshkey_plain_to_blob_buf(k, pk), 0); + ASSERT_PTR_NE(pk, NULL); + ASSERT_INT_EQ(sshkey_putb_plain(k, pk), 0); ASSERT_INT_EQ(sshbuf_skip_string(pk), 0); principals = sshbuf_new(); + ASSERT_PTR_NE(principals, NULL); ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gsamsa"), 0); ASSERT_INT_EQ(sshbuf_put_cstring(principals, "gregor"), 0); critopts = sshbuf_new(); - /* XXX fill this in */ + ASSERT_PTR_NE(critopts, NULL); + put_opt(critopts, "force-command", "/usr/local/bin/nethack"); + put_opt(critopts, "source-address", "192.168.0.0/24,127.0.0.1,::1"); exts = sshbuf_new(); - /* XXX fill this in */ + ASSERT_PTR_NE(exts, NULL); + put_opt(critopts, "permit-X11-forwarding", NULL); ASSERT_INT_EQ(sshbuf_put_cstring(b, type), 0); ASSERT_INT_EQ(sshbuf_put_cstring(b, "noncenoncenonce!"), 0); /* nonce */ @@ -90,10 +110,74 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, sshbuf_free(pk); } +static void +signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l) +{ + size_t len; + u_char *sig; + + ASSERT_INT_EQ(sshkey_sign(k, &sig, &len, d, l, 0), 0); + ASSERT_SIZE_T_GT(len, 8); + ASSERT_PTR_NE(sig, NULL); + ASSERT_INT_EQ(sshkey_verify(k, sig, len, d, l, 0), 0); + ASSERT_INT_NE(sshkey_verify(bad, sig, len, d, l, 0), 0); + /* Fuzz test is more comprehensive, this is just a smoke test */ + sig[len - 5] ^= 0x10; + ASSERT_INT_NE(sshkey_verify(k, sig, len, d, l, 0), 0); + free(sig); +} + +static void +banana(u_char *s, size_t l) +{ + size_t o; + const u_char the_banana[] = { 'b', 'a', 'n', 'a', 'n', 'a' }; + + for (o = 0; o < l; o += sizeof(the_banana)) { + if (l - o < sizeof(the_banana)) { + memcpy(s + o, "nanananana", l - o); + break; + } + memcpy(s + o, banana, sizeof(the_banana)); + } +} + +static void +signature_tests(struct sshkey *k, struct sshkey *bad) +{ + u_char i, buf[2049]; + size_t lens[] = { + 1, 2, 7, 8, 9, 15, 16, 17, 31, 32, 33, 127, 128, 129, + 255, 256, 257, 1023, 1024, 1025, 2047, 2048, 2049 + }; + + for (i = 0; i < (sizeof(lens)/sizeof(lens[0])); i++) { + test_subtest_info("%s key, banana length %zu", + sshkey_type(k), lens[i]); + banana(buf, lens[i]); + signature_test(k, bad, buf, lens[i]); + } +} + +static struct sshkey * +get_private(const char *n) +{ + struct sshbuf *b; + struct sshkey *ret; + + b = load_file(n); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0); + sshbuf_free(b); + return ret; +} + void sshkey_tests(void) { - struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *ke, *kf; + struct sshkey *k1, *k2, *k3, *k4, *kr, *kd, *kf; +#ifdef OPENSSL_HAS_ECC + struct sshkey *ke; +#endif struct sshbuf *b; TEST_START("new invalid"); @@ -136,12 +220,14 @@ sshkey_tests(void) sshkey_free(k1); TEST_DONE(); +#ifdef OPENSSL_HAS_ECC TEST_START("new/free KEY_ECDSA"); k1 = sshkey_new(KEY_ECDSA); ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ sshkey_free(k1); TEST_DONE(); +#endif TEST_START("new/free KEY_ED25519"); k1 = sshkey_new(KEY_ED25519); @@ -192,12 +278,14 @@ sshkey_tests(void) sshkey_free(k1); TEST_DONE(); +#ifdef OPENSSL_HAS_ECC TEST_START("generate KEY_ECDSA wrong bits"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 42, &k1), SSH_ERR_INVALID_ARGUMENT); ASSERT_PTR_EQ(k1, NULL); sshkey_free(k1); TEST_DONE(); +#endif TEST_START("generate KEY_RSA"); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 768, &kr), 0); @@ -332,26 +420,100 @@ sshkey_tests(void) #endif sshkey_free(kf); -/* XXX certify test */ -/* XXX sign test */ -/* XXX verify test */ + TEST_START("certify key"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_1.pub"), + &k1, NULL), 0); + k2 = get_private("ed25519_2"); + ASSERT_INT_EQ(sshkey_to_certified(k1, 0), 0); + ASSERT_PTR_NE(k1->cert, NULL); + k1->cert->type = SSH2_CERT_TYPE_USER; + k1->cert->serial = 1234; + k1->cert->key_id = strdup("estragon"); + ASSERT_PTR_NE(k1->cert->key_id, NULL); + k1->cert->principals = calloc(4, sizeof(*k1->cert->principals)); + ASSERT_PTR_NE(k1->cert->principals, NULL); + k1->cert->principals[0] = strdup("estragon"); + k1->cert->principals[1] = strdup("vladimir"); + k1->cert->principals[2] = strdup("pozzo"); + k1->cert->principals[3] = strdup("lucky"); + ASSERT_PTR_NE(k1->cert->principals[0], NULL); + ASSERT_PTR_NE(k1->cert->principals[1], NULL); + ASSERT_PTR_NE(k1->cert->principals[2], NULL); + ASSERT_PTR_NE(k1->cert->principals[3], NULL); + k1->cert->valid_after = 0; + k1->cert->valid_before = (u_int64_t)-1; + k1->cert->critical = sshbuf_new(); + ASSERT_PTR_NE(k1->cert->critical, NULL); + k1->cert->extensions = sshbuf_new(); + ASSERT_PTR_NE(k1->cert->extensions, NULL); + put_opt(k1->cert->critical, "force-command", "/usr/bin/true"); + put_opt(k1->cert->critical, "source-address", "127.0.0.1"); + put_opt(k1->cert->extensions, "permit-X11-forwarding", NULL); + put_opt(k1->cert->extensions, "permit-agent-forwarding", NULL); + ASSERT_INT_EQ(sshkey_from_private(k2, &k1->cert->signature_key), 0); + ASSERT_INT_EQ(sshkey_certify(k1, k2), 0); + b = sshbuf_new(); + ASSERT_PTR_NE(b, NULL); + ASSERT_INT_EQ(sshkey_putb(k1, b), 0); + ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k3), 0); + + sshkey_free(k1); + sshkey_free(k2); + sshkey_free(k3); + sshbuf_reset(b); + TEST_DONE(); + + TEST_START("sign and verify RSA"); + k1 = get_private("rsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("sign and verify DSA"); + k1 = get_private("dsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + +#ifdef OPENSSL_HAS_ECC + TEST_START("sign and verify ECDSA"); + k1 = get_private("ecdsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); +#endif + + TEST_START("sign and verify ED25519"); + k1 = get_private("ed25519_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); TEST_START("nested certificate"); ASSERT_INT_EQ(sshkey_load_cert(test_data_file("rsa_1"), &k1), 0); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); - b = load_file("rsa_2"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", "rsa_1", - &k3, NULL), 0); - sshbuf_reset(b); + k3 = get_private("ed25519_2"); build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); ASSERT_INT_EQ(sshkey_from_blob(sshbuf_ptr(b), sshbuf_len(b), &k4), SSH_ERR_KEY_CERT_INVALID_SIGN_KEY); ASSERT_PTR_EQ(k4, NULL); - sshbuf_free(b); sshkey_free(k1); sshkey_free(k2); sshkey_free(k3); + sshbuf_free(b); TEST_DONE(); } diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp index 56ee1f89b9e8..b26145b24d5c 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1-cert.fp @@ -1 +1 @@ -5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 +MD5:5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp index 56ee1f89b9e8..b26145b24d5c 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_1.fp @@ -1 +1 @@ -5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 +MD5:5a:4a:41:8c:4e:fa:4c:52:19:f9:39:49:31:fb:fd:74 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp index ba9de82a8a81..8226574039dc 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/dsa_2.fp @@ -1 +1 @@ -72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a +MD5:72:5f:50:6b:e5:64:c5:62:21:92:3f:8b:10:9b:9f:1a diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp index a56dbc8d0118..c3d747affb66 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp @@ -1 +1 @@ -f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 +MD5:f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp index a56dbc8d0118..c3d747affb66 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_1.fp @@ -1 +1 @@ -f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 +MD5:f7:be:4c:02:65:ed:4c:11:af:ab:a8:dd:0a:92:e7:44 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp index eb4bbdf0304e..fe7526b9290d 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/ecdsa_2.fp @@ -1 +1 @@ -51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70 +MD5:51:bd:ff:2b:6d:26:9b:90:f9:e1:4a:ca:a0:29:8e:70 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp index e6d23d0b84ca..fbde87af041b 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1-cert.fp @@ -1 +1 @@ -19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f +MD5:19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp index e6d23d0b84ca..fbde87af041b 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_1.fp @@ -1 +1 @@ -19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f +MD5:19:08:8e:7e:4d:e5:de:86:2a:09:47:65:eb:0a:51:2f diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp index 02c684f36af3..ec1cdbb94d9a 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/ed25519_2.fp @@ -1 +1 @@ -5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9 +MD5:5c:c9:ae:a3:0c:aa:28:29:b8:fc:7c:64:ba:6e:e9:c9 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp index 782ece0dbec7..2e1068c649ee 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_1.fp @@ -1 +1 @@ -a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80 +MD5:a8:82:9b:98:c5:e6:19:d6:83:39:9f:4d:3a:8f:7c:80 diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp index c3325371d56f..cd0039306f85 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa1_2.fp @@ -1 +1 @@ -c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c +MD5:c0:83:1c:97:5f:32:77:7e:e4:e3:e9:29:b9:eb:76:9c diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp index bf9c2e3626fc..1cf780dd952e 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1-cert.fp @@ -1 +1 @@ -be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b +MD5:be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp index bf9c2e3626fc..1cf780dd952e 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_1.fp @@ -1 +1 @@ -be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b +MD5:be:27:4c:16:27:f5:04:03:62:a8:b7:91:df:a5:b1:3b diff --git a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp index 53939f413db1..8d43676105d4 100644 --- a/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp +++ b/crypto/openssh/regress/unittests/sshkey/testdata/rsa_2.fp @@ -1 +1 @@ -fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0 +MD5:fb:8f:7b:26:3d:42:40:ef:ed:f1:ed:ee:66:9e:ba:b0 diff --git a/crypto/openssh/regress/unittests/test_helper/Makefile b/crypto/openssh/regress/unittests/test_helper/Makefile index 3e90903ef161..5b3894cbfb56 100644 --- a/crypto/openssh/regress/unittests/test_helper/Makefile +++ b/crypto/openssh/regress/unittests/test_helper/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.1 2014/04/30 05:32:00 djm Exp $ +# $OpenBSD: Makefile,v 1.2 2015/01/20 22:58:57 djm Exp $ LIB= test_helper SRCS= test_helper.c fuzz.c @@ -7,6 +7,9 @@ DEBUGLIBS= no NOPROFILE= yes NOPIC= yes +# Hack to allow building with SUBDIR in ../../Makefile +regress: all + install: @echo -n diff --git a/crypto/openssh/regress/unittests/test_helper/fuzz.c b/crypto/openssh/regress/unittests/test_helper/fuzz.c index 77c6e7cad3aa..99f1d036c46e 100644 --- a/crypto/openssh/regress/unittests/test_helper/fuzz.c +++ b/crypto/openssh/regress/unittests/test_helper/fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuzz.c,v 1.3 2014/05/02 09:41:32 andre Exp $ */ +/* $OpenBSD: fuzz.c,v 1.8 2015/03/03 20:42:49 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -20,6 +20,7 @@ #include "includes.h" #include +#include #include #include @@ -29,9 +30,11 @@ #endif #include #include -#include +#include +#include #include "test_helper.h" +#include "atomicio.h" /* #define FUZZ_DEBUG */ @@ -96,60 +99,66 @@ fuzz_ntop(u_int n) } } -void -fuzz_dump(struct fuzz *fuzz) +static int +fuzz_fmt(struct fuzz *fuzz, char *s, size_t n) { - u_char *p = fuzz_ptr(fuzz); - size_t i, j, len = fuzz_len(fuzz); + if (fuzz == NULL) + return -1; switch (fuzz->strategy) { case FUZZ_1_BIT_FLIP: - fprintf(stderr, "%s case %zu of %zu (bit: %zu)\n", + snprintf(s, n, "%s case %zu of %zu (bit: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen * 8, fuzz->o1); - break; + return 0; case FUZZ_2_BIT_FLIP: - fprintf(stderr, "%s case %llu of %llu (bits: %zu, %zu)\n", + snprintf(s, n, "%s case %llu of %llu (bits: %zu, %zu)\n", fuzz_ntop(fuzz->strategy), (((fuzz_ullong)fuzz->o2) * fuzz->slen * 8) + fuzz->o1, ((fuzz_ullong)fuzz->slen * 8) * fuzz->slen * 8, fuzz->o1, fuzz->o2); - break; + return 0; case FUZZ_1_BYTE_FLIP: - fprintf(stderr, "%s case %zu of %zu (byte: %zu)\n", + snprintf(s, n, "%s case %zu of %zu (byte: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); - break; + return 0; case FUZZ_2_BYTE_FLIP: - fprintf(stderr, "%s case %llu of %llu (bytes: %zu, %zu)\n", + snprintf(s, n, "%s case %llu of %llu (bytes: %zu, %zu)\n", fuzz_ntop(fuzz->strategy), (((fuzz_ullong)fuzz->o2) * fuzz->slen) + fuzz->o1, ((fuzz_ullong)fuzz->slen) * fuzz->slen, fuzz->o1, fuzz->o2); - break; + return 0; case FUZZ_TRUNCATE_START: - fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", + snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); - break; + return 0; case FUZZ_TRUNCATE_END: - fprintf(stderr, "%s case %zu of %zu (offset: %zu)\n", + snprintf(s, n, "%s case %zu of %zu (offset: %zu)\n", fuzz_ntop(fuzz->strategy), fuzz->o1, fuzz->slen, fuzz->o1); - break; + return 0; case FUZZ_BASE64: assert(fuzz->o2 < sizeof(fuzz_b64chars) - 1); - fprintf(stderr, "%s case %llu of %llu (offset: %zu char: %c)\n", + snprintf(s, n, "%s case %llu of %llu (offset: %zu char: %c)\n", fuzz_ntop(fuzz->strategy), (fuzz->o1 * (fuzz_ullong)64) + fuzz->o2, fuzz->slen * (fuzz_ullong)64, fuzz->o1, fuzz_b64chars[fuzz->o2]); - break; + return 0; default: + return -1; abort(); } +} + +static void +dump(u_char *p, size_t len) +{ + size_t i, j; - fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, len); for (i = 0; i < len; i += 16) { fprintf(stderr, "%.4zd: ", i); for (j = i; j < i + 16; j++) { @@ -171,6 +180,39 @@ fuzz_dump(struct fuzz *fuzz) } } +void +fuzz_dump(struct fuzz *fuzz) +{ + char buf[256]; + + if (fuzz_fmt(fuzz, buf, sizeof(buf)) != 0) { + fprintf(stderr, "%s: fuzz invalid\n", __func__); + abort(); + } + fputs(buf, stderr); + fprintf(stderr, "fuzz original %p len = %zu\n", fuzz->seed, fuzz->slen); + dump(fuzz->seed, fuzz->slen); + fprintf(stderr, "fuzz context %p len = %zu\n", fuzz, fuzz_len(fuzz)); + dump(fuzz_ptr(fuzz), fuzz_len(fuzz)); +} + +#ifdef SIGINFO +static struct fuzz *last_fuzz; + +static void +siginfo(int unused __attribute__((__unused__))) +{ + char buf[256]; + + test_info(buf, sizeof(buf)); + atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); + if (last_fuzz != NULL) { + fuzz_fmt(last_fuzz, buf, sizeof(buf)); + atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); + } +} +#endif + struct fuzz * fuzz_begin(u_int strategies, const void *p, size_t l) { @@ -190,6 +232,12 @@ fuzz_begin(u_int strategies, const void *p, size_t l) FUZZ_DBG(("begin, ret = %p", ret)); fuzz_next(ret); + +#ifdef SIGINFO + last_fuzz = ret; + signal(SIGINFO, siginfo); +#endif + return ret; } @@ -197,6 +245,10 @@ void fuzz_cleanup(struct fuzz *fuzz) { FUZZ_DBG(("cleanup, fuzz = %p", fuzz)); +#ifdef SIGINFO + last_fuzz = NULL; + signal(SIGINFO, SIG_DFL); +#endif assert(fuzz != NULL); assert(fuzz->seed != NULL); assert(fuzz->fuzzed != NULL); @@ -325,6 +377,14 @@ fuzz_next(struct fuzz *fuzz) (u_long)fuzz->strategies, fuzz->o1, fuzz->o2, fuzz->slen)); } +int +fuzz_matches_original(struct fuzz *fuzz) +{ + if (fuzz_len(fuzz) != fuzz->slen) + return 0; + return memcmp(fuzz_ptr(fuzz), fuzz->seed, fuzz->slen) == 0; +} + int fuzz_done(struct fuzz *fuzz) { diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.c b/crypto/openssh/regress/unittests/test_helper/test_helper.c index d0bc67833cd2..26ca26b5e3b7 100644 --- a/crypto/openssh/regress/unittests/test_helper/test_helper.c +++ b/crypto/openssh/regress/unittests/test_helper/test_helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_helper.c,v 1.2 2014/05/02 09:41:32 andre Exp $ */ +/* $OpenBSD: test_helper.c,v 1.6 2015/03/03 20:42:49 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -31,6 +32,7 @@ #include #include #include +#include #include @@ -39,6 +41,7 @@ #endif #include "test_helper.h" +#include "atomicio.h" #define TEST_CHECK_INT(r, pred) do { \ switch (pred) { \ @@ -111,6 +114,7 @@ static u_int test_number = 0; static test_onerror_func_t *test_onerror = NULL; static void *onerror_ctx = NULL; static const char *data_dir = NULL; +static char subtest_info[512]; int main(int argc, char **argv) @@ -179,14 +183,37 @@ test_data_file(const char *name) return ret; } +void +test_info(char *s, size_t len) +{ + snprintf(s, len, "In test %u: \"%s\"%s%s\n", test_number, + active_test_name == NULL ? "" : active_test_name, + *subtest_info != '\0' ? " - " : "", subtest_info); +} + +#ifdef SIGINFO +static void +siginfo(int unused __attribute__((__unused__))) +{ + char buf[256]; + + test_info(buf, sizeof(buf)); + atomicio(vwrite, STDERR_FILENO, buf, strlen(buf)); +} +#endif + void test_start(const char *n) { assert(active_test_name == NULL); assert((active_test_name = strdup(n)) != NULL); + *subtest_info = '\0'; if (verbose_mode) printf("test %u - \"%s\": ", test_number, active_test_name); test_number++; +#ifdef SIGINFO + signal(SIGINFO, siginfo); +#endif } void @@ -199,6 +226,7 @@ set_onerror_func(test_onerror_func_t *f, void *ctx) void test_done(void) { + *subtest_info = '\0'; assert(active_test_name != NULL); free(active_test_name); active_test_name = NULL; @@ -210,6 +238,16 @@ test_done(void) } } +void +test_subtest_info(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsnprintf(subtest_info, sizeof(subtest_info), fmt, ap); + va_end(ap); +} + void ssl_err_check(const char *file, int line) { @@ -256,8 +294,9 @@ static void test_header(const char *file, int line, const char *a1, const char *a2, const char *name, enum test_predicate pred) { - fprintf(stderr, "\n%s:%d test #%u \"%s\"\n", - file, line, test_number, active_test_name); + fprintf(stderr, "\n%s:%d test #%u \"%s\"%s%s\n", + file, line, test_number, active_test_name, + *subtest_info != '\0' ? " - " : "", subtest_info); fprintf(stderr, "ASSERT_%s_%s(%s%s%s) failed:\n", name, pred_name(pred), a1, a2 != NULL ? ", " : "", a2 != NULL ? a2 : ""); @@ -280,8 +319,13 @@ void assert_string(const char *file, int line, const char *a1, const char *a2, const char *aa1, const char *aa2, enum test_predicate pred) { - int r = strcmp(aa1, aa2); + int r; + /* Verify pointers are not NULL */ + assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); + assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); + + r = strcmp(aa1, aa2); TEST_CHECK_INT(r, pred); test_header(file, line, a1, a2, "STRING", pred); fprintf(stderr, "%12s = %s (len %zu)\n", a1, aa1, strlen(aa1)); @@ -310,8 +354,15 @@ void assert_mem(const char *file, int line, const char *a1, const char *a2, const void *aa1, const void *aa2, size_t l, enum test_predicate pred) { - int r = memcmp(aa1, aa2, l); + int r; + if (l == 0) + return; + /* If length is >0, then verify pointers are not NULL */ + assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); + assert_ptr(file, line, a2, "NULL", aa2, NULL, TEST_NE); + + r = memcmp(aa1, aa2, l); TEST_CHECK_INT(r, pred); test_header(file, line, a1, a2, "STRING", pred); fprintf(stderr, "%12s = %s (len %zu)\n", a1, tohex(aa1, MIN(l, 256)), l); @@ -338,11 +389,15 @@ assert_mem_filled(const char *file, int line, const char *a1, const void *aa1, u_char v, size_t l, enum test_predicate pred) { size_t where = -1; - int r = memvalcmp(aa1, v, l, &where); + int r; char tmp[64]; if (l == 0) return; + /* If length is >0, then verify the pointer is not NULL */ + assert_ptr(file, line, a1, "NULL", aa1, NULL, TEST_NE); + + r = memvalcmp(aa1, v, l, &where); TEST_CHECK_INT(r, pred); test_header(file, line, a1, NULL, "MEM_ZERO", pred); fprintf(stderr, "%20s = %s%s (len %zu)\n", a1, diff --git a/crypto/openssh/regress/unittests/test_helper/test_helper.h b/crypto/openssh/regress/unittests/test_helper/test_helper.h index a398c615f851..1d9c66986d5d 100644 --- a/crypto/openssh/regress/unittests/test_helper/test_helper.h +++ b/crypto/openssh/regress/unittests/test_helper/test_helper.h @@ -1,4 +1,4 @@ -/* $OpenBSD: test_helper.h,v 1.3 2014/05/02 09:41:32 andre Exp $ */ +/* $OpenBSD: test_helper.h,v 1.6 2015/01/18 19:52:44 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -40,8 +40,11 @@ void tests(void); const char *test_data_file(const char *name); void test_start(const char *n); +void test_info(char *s, size_t len); void set_onerror_func(test_onerror_func_t *f, void *ctx); void test_done(void); +void test_subtest_info(const char *fmt, ...) + __attribute__((format(printf, 1, 2))); void ssl_err_check(const char *file, int line); void assert_bignum(const char *file, int line, const char *a1, const char *a2, @@ -280,6 +283,13 @@ void fuzz_cleanup(struct fuzz *fuzz); /* Prepare the next fuzz case in the series */ void fuzz_next(struct fuzz *fuzz); +/* + * Check whether this fuzz case is identical to the original + * This is slow, but useful if the caller needs to ensure that all tests + * generated change the input (e.g. when fuzzing signatures). + */ +int fuzz_matches_original(struct fuzz *fuzz); + /* Determine whether the current fuzz sequence is exhausted (nonzero = yes) */ int fuzz_done(struct fuzz *fuzz); @@ -289,4 +299,5 @@ u_char *fuzz_ptr(struct fuzz *fuzz); /* Dump the current fuzz case to stderr */ void fuzz_dump(struct fuzz *fuzz); + #endif /* _TEST_HELPER_H */ diff --git a/crypto/openssh/regress/valgrind-unit.sh b/crypto/openssh/regress/valgrind-unit.sh new file mode 100755 index 000000000000..433cb069a75a --- /dev/null +++ b/crypto/openssh/regress/valgrind-unit.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +UNIT_BINARY="$1" +shift +UNIT_ARGS="$@" + +test "x$OBJ" = "x" && OBJ=$PWD + +# This mostly replicates the logic in test-exec.sh for running the +# regress tests under valgrind. +VG_TEST=`basename $UNIT_BINARY` +VG_LOG="$OBJ/valgrind-out/${VG_TEST}.%p" +VG_OPTS="--track-origins=yes --leak-check=full --log-file=${VG_LOG}" +VG_OPTS="$VG_OPTS --trace-children=yes" +VG_PATH="valgrind" +if [ "x$VALGRIND_PATH" != "x" ]; then + VG_PATH="$VALGRIND_PATH" +fi + +exec $VG_PATH $VG_OPTS $UNIT_BINARY $UNIT_ARGS diff --git a/crypto/openssh/regress/yes-head.sh b/crypto/openssh/regress/yes-head.sh index a8e6bc80019b..1fc754211feb 100644 --- a/crypto/openssh/regress/yes-head.sh +++ b/crypto/openssh/regress/yes-head.sh @@ -1,9 +1,9 @@ -# $OpenBSD: yes-head.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# $OpenBSD: yes-head.sh,v 1.5 2015/03/03 22:35:19 markus Exp $ # Placed in the Public Domain. tid="yes pipe head" -for p in 1 2; do +for p in ${SSH_PROTOCOLS}; do lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | _POSIX2_VERSION=199209 head -2000"' | (sleep 3 ; wc -l)` if [ $? -ne 0 ]; then fail "yes|head test failed" diff --git a/crypto/openssh/rijndael.c b/crypto/openssh/rijndael.c index cde90789e59b..b352a11e5294 100644 --- a/crypto/openssh/rijndael.c +++ b/crypto/openssh/rijndael.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rijndael.c,v 1.18 2014/04/29 15:42:07 markus Exp $ */ +/* $OpenBSD: rijndael.c,v 1.19 2014/11/18 22:38:48 mikeb Exp $ */ /** * rijndael-alg-fst.c @@ -40,13 +40,12 @@ Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; Te2[x] = S [x].[01, 03, 02, 01]; Te3[x] = S [x].[01, 01, 03, 02]; -Te4[x] = S [x].[01, 01, 01, 01]; Td0[x] = Si[x].[0e, 09, 0d, 0b]; Td1[x] = Si[x].[0b, 0e, 09, 0d]; Td2[x] = Si[x].[0d, 0b, 0e, 09]; Td3[x] = Si[x].[09, 0d, 0b, 0e]; -Td4[x] = Si[x].[01, 01, 01, 01]; +Td4[x] = Si[x].[01]; */ static const u32 Te0[256] = { @@ -313,72 +312,7 @@ static const u32 Te3[256] = { 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, }; -static const u32 Te4[256] = { - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; +#if 0 static const u32 Td0[256] = { 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, @@ -643,72 +577,41 @@ static const u32 Td3[256] = { 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, }; -static const u32 Td4[256] = { - 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U, - 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U, - 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU, - 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU, - 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U, - 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U, - 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U, - 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU, - 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U, - 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU, - 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU, - 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU, - 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U, - 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U, - 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U, - 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U, - 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U, - 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U, - 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU, - 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U, - 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U, - 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU, - 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U, - 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U, - 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U, - 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU, - 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U, - 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U, - 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU, - 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U, - 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U, - 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU, - 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U, - 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU, - 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU, - 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U, - 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U, - 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U, - 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U, - 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU, - 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U, - 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U, - 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU, - 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU, - 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU, - 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U, - 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU, - 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U, - 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U, - 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U, - 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U, - 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU, - 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U, - 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU, - 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU, - 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU, - 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU, - 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U, - 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU, - 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U, - 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU, - 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U, - 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U, - 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, +static const u8 Td4[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, }; +#endif static const u32 rcon[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, @@ -737,10 +640,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) for (;;) { temp = rk[3]; rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; @@ -757,10 +660,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) for (;;) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; @@ -779,10 +682,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) for (;;) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; @@ -792,10 +695,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) } temp = rk[11]; rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff); + (Te2[(temp >> 24) ] & 0xff000000) ^ + (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(temp ) & 0xff] & 0x000000ff); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; @@ -805,25 +708,20 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) return 0; } +#if 0 /** * Expand the cipher key into the decryption key schedule. * * @return the number of rounds for the given cipher key size. */ int -rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits, - int have_encrypt) +rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) { int Nr, i, j; u32 temp; /* expand the cipher key: */ - if (have_encrypt > 0) { - /* Already done */ - Nr = have_encrypt; - } else { - Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); - } + Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits); /* invert the order of the round keys: */ for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { @@ -836,28 +734,29 @@ rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits, for (i = 1; i < Nr; i++) { rk += 4; rk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; + Td0[Te1[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[0] ) & 0xff] & 0xff]; rk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; + Td0[Te1[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[1] ) & 0xff] & 0xff]; rk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; + Td0[Te1[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[2] ) & 0xff] & 0xff]; rk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; + Td0[Te1[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[3] ) & 0xff] & 0xff]; } return Nr; } +#endif void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], @@ -1014,35 +913,36 @@ rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], * map cipher state to byte array block: */ s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ + (Te2[(t0 >> 24) ] & 0xff000000) ^ + (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t3 ) & 0xff] & 0x000000ff) ^ rk[0]; PUTU32(ct , s0); s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ + (Te2[(t1 >> 24) ] & 0xff000000) ^ + (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t0 ) & 0xff] & 0x000000ff) ^ rk[1]; PUTU32(ct + 4, s1); s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ + (Te2[(t2 >> 24) ] & 0xff000000) ^ + (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t1 ) & 0xff] & 0x000000ff) ^ rk[2]; PUTU32(ct + 8, s2); s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ + (Te2[(t3 >> 24) ] & 0xff000000) ^ + (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t2 ) & 0xff] & 0x000000ff) ^ rk[3]; PUTU32(ct + 12, s3); } +#if 0 static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) @@ -1198,57 +1098,32 @@ rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], * map cipher state to byte array block: */ s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + (Td4[(t0 >> 24) ] << 24) ^ + (Td4[(t3 >> 16) & 0xff] << 16) ^ + (Td4[(t2 >> 8) & 0xff] << 8) ^ + (Td4[(t1 ) & 0xff]) ^ rk[0]; PUTU32(pt , s0); s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + (Td4[(t1 >> 24) ] << 24) ^ + (Td4[(t0 >> 16) & 0xff] << 16) ^ + (Td4[(t3 >> 8) & 0xff] << 8) ^ + (Td4[(t2 ) & 0xff]) ^ rk[1]; PUTU32(pt + 4, s1); s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + (Td4[(t2 >> 24) ] << 24) ^ + (Td4[(t1 >> 16) & 0xff] << 16) ^ + (Td4[(t0 >> 8) & 0xff] << 8) ^ + (Td4[(t3 ) & 0xff]) ^ rk[2]; PUTU32(pt + 8, s2); s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + (Td4[(t3 >> 24) ] << 24) ^ + (Td4[(t2 >> 16) & 0xff] << 16) ^ + (Td4[(t1 >> 8) & 0xff] << 8) ^ + (Td4[(t0 ) & 0xff]) ^ rk[3]; PUTU32(pt + 12, s3); } - -void -rijndael_set_key(rijndael_ctx *ctx, u_char *key, int bits, int do_encrypt) -{ - ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits); - if (do_encrypt) { - ctx->decrypt = 0; - memset(ctx->dk, 0, sizeof(ctx->dk)); - } else { - ctx->decrypt = 1; - memcpy(ctx->dk, ctx->ek, sizeof(ctx->dk)); - rijndaelKeySetupDec(ctx->dk, key, bits, ctx->Nr); - } -} - -void -rijndael_decrypt(rijndael_ctx *ctx, u_char *src, u_char *dst) -{ - rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst); -} - -void -rijndael_encrypt(rijndael_ctx *ctx, u_char *src, u_char *dst) -{ - rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst); -} +#endif diff --git a/crypto/openssh/roaming_client.c b/crypto/openssh/roaming_client.c index 5e5c28b2b296..cb1328574140 100644 --- a/crypto/openssh/roaming_client.c +++ b/crypto/openssh/roaming_client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_client.c,v 1.8 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: roaming_client.c,v 1.9 2015/01/27 12:54:06 okan Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -21,9 +21,6 @@ #include #include -#ifdef HAVE_INTTYPES_H -#include -#endif #include #include #include diff --git a/crypto/openssh/roaming_common.c b/crypto/openssh/roaming_common.c index 787bef04a6ff..ea064605cec4 100644 --- a/crypto/openssh/roaming_common.c +++ b/crypto/openssh/roaming_common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_common.c,v 1.12 2014/01/09 23:20:00 djm Exp $ */ +/* $OpenBSD: roaming_common.c,v 1.13 2015/01/27 12:54:06 okan Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -22,9 +22,6 @@ #include #include -#ifdef HAVE_INTTYPES_H -#include -#endif #include #include #include diff --git a/crypto/openssh/roaming_dummy.c b/crypto/openssh/roaming_dummy.c index 45c4008e7f9b..837de695ddf1 100644 --- a/crypto/openssh/roaming_dummy.c +++ b/crypto/openssh/roaming_dummy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roaming_dummy.c,v 1.3 2009/06/21 09:04:03 dtucker Exp $ */ +/* $OpenBSD: roaming_dummy.c,v 1.4 2015/01/19 19:52:16 markus Exp $ */ /* * Copyright (c) 2004-2009 AppGate Network Security AB * @@ -35,6 +35,17 @@ get_recv_bytes(void) return 0; } +u_int64_t +get_sent_bytes(void) +{ + return 0; +} + +void +roam_set_bytes(u_int64_t sent, u_int64_t recvd) +{ +} + ssize_t roaming_write(int fd, const void *buf, size_t count, int *cont) { diff --git a/crypto/openssh/sandbox-systrace.c b/crypto/openssh/sandbox-systrace.c index aaa3d8f0a62f..f30e70575105 100644 --- a/crypto/openssh/sandbox-systrace.c +++ b/crypto/openssh/sandbox-systrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sandbox-systrace.c,v 1.13 2014/07/17 00:10:56 djm Exp $ */ +/* $OpenBSD: sandbox-systrace.c,v 1.14 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -20,7 +20,6 @@ #ifdef SANDBOX_SYSTRACE #include -#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include "atomicio.h" #include "log.h" diff --git a/crypto/openssh/scard/.cvsignore b/crypto/openssh/scard/.cvsignore new file mode 100644 index 000000000000..5349d34aeabd --- /dev/null +++ b/crypto/openssh/scard/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Ssh.bin diff --git a/crypto/openssh/scp.0 b/crypto/openssh/scp.0 index 0495f2555d99..3f309fe0329c 100644 --- a/crypto/openssh/scp.0 +++ b/crypto/openssh/scp.0 @@ -1,7 +1,7 @@ SCP(1) General Commands Manual SCP(1) NAME - scp - secure copy (remote file copy program) + scp M-bM-^@M-^S secure copy (remote file copy program) SYNOPSIS scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] @@ -17,7 +17,7 @@ DESCRIPTION File names may contain a user and host specification to indicate that the file is to be copied to/from that host. Local file names can be made explicit using absolute or relative pathnames to avoid scp treating file - names containing `:' as host specifiers. Copies between two remote hosts + names containing M-bM-^@M-^X:M-bM-^@M-^Y as host specifiers. Copies between two remote hosts are also permitted. The options are as follows: @@ -89,6 +89,7 @@ DESCRIPTION HashKnownHosts Host HostbasedAuthentication + HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName @@ -117,6 +118,7 @@ DESCRIPTION ServerAliveCountMax StrictHostKeyChecking TCPKeepAlive + UpdateHostKeys UsePrivilegedPort User UserKnownHostsFile @@ -124,7 +126,7 @@ DESCRIPTION -P port Specifies the port to connect to on the remote host. Note that - this option is written with a capital `P', because -p is already + this option is written with a capital M-bM-^@M-^XPM-bM-^@M-^Y, because -p is already reserved for preserving the times and modes of the file. -p Preserves modification times, access times, and modes from the @@ -145,7 +147,7 @@ DESCRIPTION authentication, and configuration problems. EXIT STATUS - The scp utility exits 0 on success, and >0 if an error occurs. + The scp utility exitsM-BM- 0 on success, andM-BM- >0 if an error occurs. SEE ALSO sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh_config(5), @@ -159,4 +161,4 @@ AUTHORS Timo Rinne Tatu Ylonen -OpenBSD 5.6 March 19, 2014 OpenBSD 5.6 +OpenBSD 5.7 January 30, 2015 OpenBSD 5.7 diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1 index 1791b6189501..0e84780e0e5b 100644 --- a/crypto/openssh/scp.1 +++ b/crypto/openssh/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.62 2014/03/19 14:42:44 tedu Exp $ +.\" $OpenBSD: scp.1,v 1.66 2015/01/30 11:43:14 djm Exp $ .\" -.Dd $Mdocdate: March 19 2014 $ +.Dd $Mdocdate: January 30 2015 $ .Dt SCP 1 .Os .Sh NAME @@ -30,14 +30,14 @@ .Sm off .Oo .Op Ar user No @ -.Ar host1 No : +.Ar host1 : .Oc Ar file1 .Sm on .Ar ... .Sm off .Oo .Op Ar user No @ -.Ar host2 No : +.Ar host2 : .Oc Ar file2 .Sm on .Ek @@ -150,6 +150,7 @@ For full details of the options listed below, and their possible values, see .It HashKnownHosts .It Host .It HostbasedAuthentication +.It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName @@ -178,6 +179,7 @@ For full details of the options listed below, and their possible values, see .It ServerAliveCountMax .It StrictHostKeyChecking .It TCPKeepAlive +.It UpdateHostKeys .It UsePrivilegedPort .It User .It UserKnownHostsFile diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c index 1ec3b7087685..887b014b846c 100644 --- a/crypto/openssh/scp.c +++ b/crypto/openssh/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.180 2014/06/24 02:21:01 djm Exp $ */ +/* $OpenBSD: scp.c,v 1.181 2015/01/16 06:40:12 deraadt Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -95,6 +95,7 @@ #include #include #include +#include #include #include #include @@ -749,7 +750,7 @@ source(int argc, char **argv) off_t i, statbytes; size_t amt, nr; int fd = -1, haderr, indx; - char *last, *name, buf[2048], encname[MAXPATHLEN]; + char *last, *name, buf[2048], encname[PATH_MAX]; int len; for (indx = 0; indx < argc; ++indx) { @@ -858,7 +859,7 @@ rsource(char *name, struct stat *statp) { DIR *dirp; struct dirent *dp; - char *last, *vect[1], path[MAXPATHLEN]; + char *last, *vect[1], path[PATH_MAX]; if (!(dirp = opendir(name))) { run_err("%s: %s", name, strerror(errno)); diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c index 42a9fd202761..40c8b339357f 100644 --- a/crypto/openssh/servconf.c +++ b/crypto/openssh/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: servconf.c,v 1.260 2015/02/02 01:57:44 deraadt Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -29,6 +29,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include #include #ifdef HAVE_UTIL_H @@ -55,6 +56,8 @@ __RCSID("$FreeBSD$"); #include "packet.h" #include "hostfile.h" #include "auth.h" +#include "myproposal.h" +#include "digest.h" #include "version.h" static void add_listen_addr(ServerOptions *, char *, int); @@ -104,8 +107,10 @@ initialize_server_options(ServerOptions *options) options->rhosts_rsa_authentication = -1; options->hostbased_authentication = -1; options->hostbased_uses_name_from_packet_only = -1; + options->hostbased_key_types = NULL; options->rsa_authentication = -1; options->pubkey_authentication = -1; + options->pubkey_key_types = NULL; options->kerberos_authentication = -1; options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; @@ -159,11 +164,21 @@ initialize_server_options(ServerOptions *options) options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; options->version_addendum = NULL; + options->fingerprint_hash = -1; +} + +/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ +static int +option_clear_or_none(const char *o) +{ + return o == NULL || strcasecmp(o, "none") == 0; } void fill_default_server_options(ServerOptions *options) { + int i; + /* Portable-specific options */ if (options->use_pam == -1) options->use_pam = 1; @@ -195,7 +210,7 @@ fill_default_server_options(ServerOptions *options) if (options->listen_addrs == NULL) add_listen_addr(options, NULL, 0); if (options->pid_file == NULL) - options->pid_file = _PATH_SSH_DAEMON_PID_FILE; + options->pid_file = xstrdup(_PATH_SSH_DAEMON_PID_FILE); if (options->server_key_bits == -1) options->server_key_bits = 1024; if (options->login_grace_time == -1) @@ -219,7 +234,7 @@ fill_default_server_options(ServerOptions *options) if (options->x11_use_localhost == -1) options->x11_use_localhost = 1; if (options->xauth_location == NULL) - options->xauth_location = _PATH_XAUTH; + options->xauth_location = xstrdup(_PATH_XAUTH); if (options->permit_tty == -1) options->permit_tty = 1; if (options->permit_user_rc == -1) @@ -238,10 +253,14 @@ fill_default_server_options(ServerOptions *options) options->hostbased_authentication = 0; if (options->hostbased_uses_name_from_packet_only == -1) options->hostbased_uses_name_from_packet_only = 0; + if (options->hostbased_key_types == NULL) + options->hostbased_key_types = xstrdup("*"); if (options->rsa_authentication == -1) options->rsa_authentication = 1; if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; + if (options->pubkey_key_types == NULL) + options->pubkey_key_types = xstrdup("*"); if (options->kerberos_authentication == -1) options->kerberos_authentication = 0; if (options->kerberos_or_local_passwd == -1) @@ -291,7 +310,7 @@ fill_default_server_options(ServerOptions *options) if (options->max_sessions == -1) options->max_sessions = DEFAULT_SESSIONS_MAX; if (options->use_dns == -1) - options->use_dns = 1; + options->use_dns = 0; if (options->client_alive_interval == -1) options->client_alive_interval = 0; if (options->client_alive_count_max == -1) @@ -314,10 +333,30 @@ fill_default_server_options(ServerOptions *options) options->fwd_opts.streamlocal_bind_mask = 0177; if (options->fwd_opts.streamlocal_bind_unlink == -1) options->fwd_opts.streamlocal_bind_unlink = 0; + if (options->fingerprint_hash == -1) + options->fingerprint_hash = SSH_FP_HASH_DEFAULT; /* Turn privilege separation on by default */ if (use_privsep == -1) use_privsep = PRIVSEP_ON; +#define CLEAR_ON_NONE(v) \ + do { \ + if (option_clear_or_none(v)) { \ + free(v); \ + v = NULL; \ + } \ + } while(0) + CLEAR_ON_NONE(options->pid_file); + CLEAR_ON_NONE(options->xauth_location); + CLEAR_ON_NONE(options->banner); + CLEAR_ON_NONE(options->trusted_user_ca_keys); + CLEAR_ON_NONE(options->revoked_keys_file); + for (i = 0; i < options->num_host_key_files; i++) + CLEAR_ON_NONE(options->host_key_files[i]); + for (i = 0; i < options->num_host_cert_files; i++) + CLEAR_ON_NONE(options->host_cert_files[i]); +#undef CLEAR_ON_NONE + #ifndef HAVE_MMAP if (use_privsep && options->compression == 1) { error("This platform does not support both privilege " @@ -335,8 +374,8 @@ typedef enum { /* Portable-specific options */ sUsePAM, /* Standard Options */ - sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, - sPermitRootLogin, sLogFacility, sLogLevel, + sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, + sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, sKerberosGetAFSToken, @@ -349,11 +388,11 @@ typedef enum { sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, - sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sMaxStartups, sMaxAuthTries, sMaxSessions, + sGatewayPorts, sPubkeyAuthentication, sPubkeyAcceptedKeyTypes, + sXAuthLocation, sSubsystem, sMaxStartups, sMaxAuthTries, sMaxSessions, sBanner, sUseDNS, sHostbasedAuthentication, - sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, + sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes, + sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, @@ -363,7 +402,7 @@ typedef enum { sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, sStreamLocalBindMask, sStreamLocalBindUnlink, - sAllowStreamLocalForwarding, + sAllowStreamLocalForwarding, sFingerprintHash, sDeprecated, sUnsupported } ServerOpCodes; @@ -400,8 +439,10 @@ static struct { { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, + { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL }, { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, + { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ #ifdef KRB5 { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, @@ -494,6 +535,7 @@ static struct { { "streamlocalbindmask", sStreamLocalBindMask, SSHCFG_ALL }, { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, + { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; @@ -532,8 +574,10 @@ parse_token(const char *cp, const char *filename, char * derelativise_path(const char *path) { - char *expanded, *ret, cwd[MAXPATHLEN]; + char *expanded, *ret, cwd[PATH_MAX]; + if (strcasecmp(path, "none") == 0) + return xstrdup("none"); expanded = tilde_expand_filename(path, getuid()); if (*expanded == '/') return expanded; @@ -1078,6 +1122,20 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->hostbased_uses_name_from_packet_only; goto parse_flag; + case sHostbasedAcceptedKeyTypes: + charptr = &options->hostbased_key_types; + parse_keytypes: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", + filename, linenum); + if (!sshkey_names_valid2(arg, 1)) + fatal("%s line %d: Bad key types '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + case sRSAAuthentication: intptr = &options->rsa_authentication; goto parse_flag; @@ -1086,6 +1144,10 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->pubkey_authentication; goto parse_flag; + case sPubkeyAcceptedKeyTypes: + charptr = &options->pubkey_key_types; + goto parse_keytypes; + case sKerberosAuthentication: intptr = &options->kerberos_authentication; goto parse_flag; @@ -1613,6 +1675,9 @@ process_server_config_line(ServerOptions *options, char *line, return 0; case sAuthorizedKeysCommand: + if (cp == NULL) + fatal("%.200s line %d: Missing argument.", filename, + linenum); len = strspn(cp, WHITESPACE); if (*activep && options->authorized_keys_command == NULL) { if (cp[len] != '/' && strcasecmp(cp + len, "none") != 0) @@ -1627,6 +1692,9 @@ process_server_config_line(ServerOptions *options, char *line, charptr = &options->authorized_keys_command_user; arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing AuthorizedKeysCommandUser " + "argument.", filename, linenum); if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; @@ -1665,6 +1733,18 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->fwd_opts.streamlocal_bind_unlink; goto parse_flag; + case sFingerprintHash: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if ((value = ssh_digest_alg_by_name(arg)) == -1) + fatal("%.200s line %d: Invalid hash algorithm \"%s\".", + filename, linenum, arg); + if (*activep) + options->fingerprint_hash = value; + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1907,6 +1987,8 @@ fmt_intarg(ServerOpCodes code, int val) return fmt_multistate_int(val, multistate_tcpfwd); case sAllowStreamLocalForwarding: return fmt_multistate_int(val, multistate_tcpfwd); + case sFingerprintHash: + return ssh_digest_alg_name(val); case sProtocol: switch (val) { case SSH_PROTO_1: @@ -1958,7 +2040,8 @@ dump_cfg_string(ServerOpCodes code, const char *val) { if (val == NULL) return; - printf("%s %s\n", lookup_opcode_name(code), val); + printf("%s %s\n", lookup_opcode_name(code), + val == NULL ? "none" : val); } static void @@ -2068,13 +2151,13 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); dump_cfg_string(sXAuthLocation, o->xauth_location); - dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : - cipher_alg_list(',', 0)); - dump_cfg_string(sMacs, o->macs ? o->macs : mac_alg_list(',')); + dump_cfg_string(sCiphers, o->ciphers ? o->ciphers : KEX_SERVER_ENCRYPT); + dump_cfg_string(sMacs, o->macs ? o->macs : KEX_SERVER_MAC); dump_cfg_string(sBanner, o->banner); dump_cfg_string(sForceCommand, o->adm_forced_command); dump_cfg_string(sChrootDirectory, o->chroot_directory); @@ -2086,8 +2169,12 @@ dump_config(ServerOptions *o) dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command); dump_cfg_string(sAuthorizedKeysCommandUser, o->authorized_keys_command_user); dump_cfg_string(sHostKeyAgent, o->host_key_agent); - dump_cfg_string(sKexAlgorithms, o->kex_algorithms ? o->kex_algorithms : - kex_alg_list(',')); + dump_cfg_string(sKexAlgorithms, + o->kex_algorithms ? o->kex_algorithms : KEX_SERVER_KEX); + dump_cfg_string(sHostbasedAcceptedKeyTypes, o->hostbased_key_types ? + o->hostbased_key_types : KEX_DEFAULT_PK_ALG); + dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? + o->pubkey_key_types : KEX_DEFAULT_PK_ALG); /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h index 766db3a3dede..9922f0c8caf3 100644 --- a/crypto/openssh/servconf.h +++ b/crypto/openssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.114 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: servconf.h,v 1.116 2015/01/13 07:39:19 djm Exp $ */ /* * Author: Tatu Ylonen @@ -99,8 +99,10 @@ typedef struct { * authentication. */ int hostbased_authentication; /* If true, permit ssh2 hostbased auth */ int hostbased_uses_name_from_packet_only; /* experimental */ + char *hostbased_key_types; /* Key types allowed for hostbased */ int rsa_authentication; /* If true, permit RSA authentication. */ int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ + char *pubkey_key_types; /* Key types allowed for public key */ int kerberos_authentication; /* If true, permit Kerberos * authentication. */ int kerberos_or_local_passwd; /* If true, permit kerberos @@ -185,6 +187,8 @@ typedef struct { u_int num_auth_methods; char *auth_methods[MAX_AUTH_METHODS]; + + int fingerprint_hash; } ServerOptions; /* Information about the incoming connection as used by Match */ @@ -213,6 +217,8 @@ struct connection_info { M_CP_STROPT(authorized_principals_file); \ M_CP_STROPT(authorized_keys_command); \ M_CP_STROPT(authorized_keys_command_user); \ + M_CP_STROPT(hostbased_key_types); \ + M_CP_STROPT(pubkey_key_types); \ M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ M_CP_STRARRAYOPT(allow_users, num_allow_users); \ M_CP_STRARRAYOPT(deny_users, num_deny_users); \ diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index a24a06fb576f..f45baa576fae 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.172 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: serverloop.c,v 1.178 2015/02/20 22:17:21 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -38,8 +38,8 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* MIN MAX */ #include -#include #include #include #ifdef HAVE_SYS_TIME_H @@ -80,11 +80,11 @@ __RCSID("$FreeBSD$"); #include "auth-options.h" #include "serverloop.h" #include "roaming.h" +#include "ssherr.h" extern ServerOptions options; /* XXX */ -extern Kex *xxx_kex; extern Authctxt *the_authctxt; extern int use_privsep; @@ -546,7 +546,7 @@ drain_output(void) static void process_buffered_input_packets(void) { - dispatch_run(DISPATCH_NONBLOCK, NULL, compat20 ? xxx_kex : NULL); + dispatch_run(DISPATCH_NONBLOCK, NULL, active_state); } /* @@ -852,7 +852,7 @@ server_loop2(Authctxt *authctxt) for (;;) { process_buffered_input_packets(); - rekeying = (xxx_kex != NULL && !xxx_kex->done); + rekeying = (active_state->kex != NULL && !active_state->kex->done); if (!rekeying && packet_not_very_much_data_to_write()) channel_output_poll(); @@ -875,8 +875,8 @@ server_loop2(Authctxt *authctxt) channel_after_select(readset, writeset); if (packet_need_rekeying()) { debug("need rekeying"); - xxx_kex->done = 0; - kex_send_kexinit(xxx_kex); + active_state->kex->done = 0; + kex_send_kexinit(active_state); } } process_input(readset); @@ -896,7 +896,7 @@ server_loop2(Authctxt *authctxt) session_destroy_all(NULL); } -static void +static int server_input_keep_alive(int type, u_int32_t seq, void *ctxt) { debug("Got %d/%u for keepalive", type, seq); @@ -906,9 +906,10 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt) * the bogus CHANNEL_REQUEST we send for keepalives. */ packet_set_alive_timeouts(0); + return 0; } -static void +static int server_input_stdin_data(int type, u_int32_t seq, void *ctxt) { char *data; @@ -917,15 +918,16 @@ server_input_stdin_data(int type, u_int32_t seq, void *ctxt) /* Stdin data from the client. Append it to the buffer. */ /* Ignore any data if the client has closed stdin. */ if (fdin == -1) - return; + return 0; data = packet_get_string(&data_len); packet_check_eom(); buffer_append(&stdin_buffer, data, data_len); explicit_bzero(data, data_len); free(data); + return 0; } -static void +static int server_input_eof(int type, u_int32_t seq, void *ctxt) { /* @@ -936,9 +938,10 @@ server_input_eof(int type, u_int32_t seq, void *ctxt) debug("EOF received for stdin."); packet_check_eom(); stdin_eof = 1; + return 0; } -static void +static int server_input_window_size(int type, u_int32_t seq, void *ctxt) { u_int row = packet_get_int(); @@ -950,6 +953,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt) packet_check_eom(); if (fdin != -1) pty_change_window_size(fdin, row, col, xpixel, ypixel); + return 0; } static Channel * @@ -1094,7 +1098,7 @@ server_request_session(void) return c; } -static void +static int server_input_channel_open(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; @@ -1144,14 +1148,86 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt) packet_send(); } free(ctype); + return 0; } -static void +static int +server_input_hostkeys_prove(struct sshbuf **respp) +{ + struct ssh *ssh = active_state; /* XXX */ + struct sshbuf *resp = NULL; + struct sshbuf *sigbuf = NULL; + struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; + int r, ndx, success = 0; + const u_char *blob; + u_char *sig = 0; + size_t blen, slen; + + if ((resp = sshbuf_new()) == NULL || (sigbuf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new", __func__); + + while (ssh_packet_remaining(ssh) > 0) { + sshkey_free(key); + key = NULL; + if ((r = sshpkt_get_string_direct(ssh, &blob, &blen)) != 0 || + (r = sshkey_from_blob(blob, blen, &key)) != 0) { + error("%s: couldn't parse key: %s", + __func__, ssh_err(r)); + goto out; + } + /* + * Better check that this is actually one of our hostkeys + * before attempting to sign anything with it. + */ + if ((ndx = ssh->kex->host_key_index(key, 1, ssh)) == -1) { + error("%s: unknown host %s key", + __func__, sshkey_type(key)); + goto out; + } + /* + * XXX refactor: make kex->sign just use an index rather + * than passing in public and private keys + */ + if ((key_prv = get_hostkey_by_index(ndx)) == NULL && + (key_pub = get_hostkey_public_by_index(ndx, ssh)) == NULL) { + error("%s: can't retrieve hostkey %d", __func__, ndx); + goto out; + } + sshbuf_reset(sigbuf); + free(sig); + sig = NULL; + if ((r = sshbuf_put_cstring(sigbuf, + "hostkeys-prove-00@openssh.com")) != 0 || + (r = sshbuf_put_string(sigbuf, + ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || + (r = sshkey_puts(key, sigbuf)) != 0 || + (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, + sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 0)) != 0 || + (r = sshbuf_put_string(resp, sig, slen)) != 0) { + error("%s: couldn't prepare signature: %s", + __func__, ssh_err(r)); + goto out; + } + } + /* Success */ + *respp = resp; + resp = NULL; /* don't free it */ + success = 1; + out: + free(sig); + sshbuf_free(resp); + sshbuf_free(sigbuf); + sshkey_free(key); + return success; +} + +static int server_input_global_request(int type, u_int32_t seq, void *ctxt) { char *rtype; int want_reply; - int success = 0, allocated_listen_port = 0; + int r, success = 0, allocated_listen_port = 0; + struct sshbuf *resp = NULL; rtype = packet_get_string(NULL); want_reply = packet_get_char(); @@ -1188,6 +1264,10 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) &allocated_listen_port, &options.fwd_opts); } free(fwd.listen_host); + if ((resp = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new", __func__); + if ((r = sshbuf_put_u32(resp, allocated_listen_port)) != 0) + fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r)); } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { struct Forward fwd; @@ -1231,19 +1311,24 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { no_more_sessions = 1; success = 1; + } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { + success = server_input_hostkeys_prove(&resp); } if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); - if (success && allocated_listen_port > 0) - packet_put_int(allocated_listen_port); + if (success && resp != NULL) + ssh_packet_put_raw(active_state, sshbuf_ptr(resp), + sshbuf_len(resp)); packet_send(); packet_write_wait(); } free(rtype); + sshbuf_free(resp); + return 0; } -static void +static int server_input_channel_req(int type, u_int32_t seq, void *ctxt) { Channel *c; @@ -1273,6 +1358,7 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt) packet_send(); } free(rtype); + return 0; } static void diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c index e21cd8edea3e..42cc98110083 100644 --- a/crypto/openssh/session.c +++ b/crypto/openssh/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.274 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: session.c,v 1.277 2015/01/16 06:40:12 deraadt Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -61,6 +61,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -1449,7 +1450,7 @@ static void safely_chroot(const char *path, uid_t uid) { const char *cp; - char component[MAXPATHLEN]; + char component[PATH_MAX]; struct stat st; if (*path != '/') @@ -1632,11 +1633,11 @@ launch_login(struct passwd *pw, const char *hostname) static void child_close_fds(void) { - extern AuthenticationConnection *auth_conn; + extern int auth_sock; - if (auth_conn) { - ssh_close_authentication_connection(auth_conn); - auth_conn = NULL; + if (auth_sock != -1) { + close(auth_sock); + auth_sock = -1; } if (packet_get_connection_in() == packet_get_connection_out()) @@ -2660,7 +2661,7 @@ session_setup_x11fwd(Session *s) debug("X11 forwarding disabled in server configuration file."); return 0; } - if (!options.xauth_location || + if (options.xauth_location == NULL || (stat(options.xauth_location, &st) == -1)) { packet_send_debug("No xauth program; cannot forward with spoofing."); return 0; diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c index 990b58d14f9f..80f4805cb125 100644 --- a/crypto/openssh/sftp-client.c +++ b/crypto/openssh/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.115 2014/04/21 14:36:16 logan Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.117 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -22,8 +22,8 @@ #include "includes.h" +#include /* MIN MAX */ #include -#include #ifdef HAVE_SYS_STATVFS_H #include #endif @@ -47,7 +47,8 @@ #include #include "xmalloc.h" -#include "buffer.h" +#include "ssherr.h" +#include "sshbuf.h" #include "log.h" #include "atomicio.h" #include "progressmeter.h" @@ -83,8 +84,8 @@ struct sftp_conn { struct bwlimit bwlimit_in, bwlimit_out; }; -static char * -get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len, +static u_char * +get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, const char *errfmt, ...) __attribute__((format(printf, 4, 5))); /* ARGSUSED */ @@ -98,36 +99,39 @@ sftpio(void *_bwlimit, size_t amount) } static void -send_msg(struct sftp_conn *conn, Buffer *m) +send_msg(struct sftp_conn *conn, struct sshbuf *m) { u_char mlen[4]; struct iovec iov[2]; - if (buffer_len(m) > SFTP_MAX_MSG_LENGTH) - fatal("Outbound message too long %u", buffer_len(m)); + if (sshbuf_len(m) > SFTP_MAX_MSG_LENGTH) + fatal("Outbound message too long %zu", sshbuf_len(m)); /* Send length first */ - put_u32(mlen, buffer_len(m)); + put_u32(mlen, sshbuf_len(m)); iov[0].iov_base = mlen; iov[0].iov_len = sizeof(mlen); - iov[1].iov_base = buffer_ptr(m); - iov[1].iov_len = buffer_len(m); + iov[1].iov_base = (u_char *)sshbuf_ptr(m); + iov[1].iov_len = sshbuf_len(m); if (atomiciov6(writev, conn->fd_out, iov, 2, conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) != - buffer_len(m) + sizeof(mlen)) + sshbuf_len(m) + sizeof(mlen)) fatal("Couldn't send packet: %s", strerror(errno)); - buffer_clear(m); + sshbuf_reset(m); } static void -get_msg(struct sftp_conn *conn, Buffer *m) +get_msg(struct sftp_conn *conn, struct sshbuf *m) { u_int msg_len; + u_char *p; + int r; - buffer_append_space(m, 4); - if (atomicio6(read, conn->fd_in, buffer_ptr(m), 4, + if ((r = sshbuf_reserve(m, 4, &p)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (atomicio6(read, conn->fd_in, p, 4, conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) { if (errno == EPIPE) fatal("Connection closed"); @@ -135,12 +139,14 @@ get_msg(struct sftp_conn *conn, Buffer *m) fatal("Couldn't read packet: %s", strerror(errno)); } - msg_len = buffer_get_int(m); + if ((r = sshbuf_get_u32(m, &msg_len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (msg_len > SFTP_MAX_MSG_LENGTH) fatal("Received message too long %u", msg_len); - buffer_append_space(m, msg_len); - if (atomicio6(read, conn->fd_in, buffer_ptr(m), msg_len, + if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (atomicio6(read, conn->fd_in, p, msg_len, conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != msg_len) { if (errno == EPIPE) @@ -151,46 +157,56 @@ get_msg(struct sftp_conn *conn, Buffer *m) } static void -send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, +send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s, u_int len) { - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); - buffer_put_char(&msg, code); - buffer_put_int(&msg, id); - buffer_put_string(&msg, s, len); - send_msg(conn, &msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, code)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_string(msg, s, len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); - buffer_free(&msg); + sshbuf_free(msg); } static void send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, - char *s, u_int len, Attrib *a) + const void *s, u_int len, Attrib *a) { - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); - buffer_put_char(&msg, code); - buffer_put_int(&msg, id); - buffer_put_string(&msg, s, len); - encode_attrib(&msg, a); - send_msg(conn, &msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, code)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_string(msg, s, len)) != 0 || + (r = encode_attrib(msg, a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); - buffer_free(&msg); + sshbuf_free(msg); } static u_int get_status(struct sftp_conn *conn, u_int expected_id) { - Buffer msg; - u_int type, id, status; + struct sshbuf *msg; + u_char type; + u_int id, status; + int r; - buffer_init(&msg); - get_msg(conn, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + get_msg(conn, msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); @@ -198,112 +214,136 @@ get_status(struct sftp_conn *conn, u_int expected_id) fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u", SSH2_FXP_STATUS, type); - status = buffer_get_int(&msg); - buffer_free(&msg); + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_free(msg); debug3("SSH2_FXP_STATUS %u", status); return status; } -static char * -get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len, +static u_char * +get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, const char *errfmt, ...) { - Buffer msg; - u_int type, id; - char *handle, errmsg[256]; + struct sshbuf *msg; + u_int id, status; + u_char type; + u_char *handle; + char errmsg[256]; va_list args; - int status; + int r; va_start(args, errfmt); if (errfmt != NULL) vsnprintf(errmsg, sizeof(errmsg), errfmt, args); va_end(args); - buffer_init(&msg); - get_msg(conn, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + get_msg(conn, msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("%s: ID mismatch (%u != %u)", errfmt == NULL ? __func__ : errmsg, id, expected_id); if (type == SSH2_FXP_STATUS) { - status = buffer_get_int(&msg); + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (errfmt != NULL) error("%s: %s", errmsg, fx2txt(status)); - buffer_free(&msg); + sshbuf_free(msg); return(NULL); } else if (type != SSH2_FXP_HANDLE) fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u", errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type); - handle = buffer_get_string(&msg, len); - buffer_free(&msg); + if ((r = sshbuf_get_string(msg, &handle, len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_free(msg); - return(handle); + return handle; } static Attrib * get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet) { - Buffer msg; - u_int type, id; - Attrib *a; + struct sshbuf *msg; + u_int id; + u_char type; + int r; + static Attrib a; - buffer_init(&msg); - get_msg(conn, &msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + get_msg(conn, msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received stat reply T:%u I:%u", type, id); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); + u_int status; + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (quiet) debug("Couldn't stat remote file: %s", fx2txt(status)); else error("Couldn't stat remote file: %s", fx2txt(status)); - buffer_free(&msg); + sshbuf_free(msg); return(NULL); } else if (type != SSH2_FXP_ATTRS) { fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u", SSH2_FXP_ATTRS, type); } - a = decode_attrib(&msg); - buffer_free(&msg); + if ((r = decode_attrib(msg, &a)) != 0) { + error("%s: couldn't decode attrib: %s", __func__, ssh_err(r)); + sshbuf_free(msg); + return NULL; + } + sshbuf_free(msg); - return(a); + return &a; } static int get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, u_int expected_id, int quiet) { - Buffer msg; - u_int type, id, flag; + struct sshbuf *msg; + u_char type; + u_int id; + u_int64_t flag; + int r; - buffer_init(&msg); - get_msg(conn, &msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + get_msg(conn, msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received statvfs reply T:%u I:%u", type, id); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { - int status = buffer_get_int(&msg); + u_int status; + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (quiet) debug("Couldn't statvfs: %s", fx2txt(status)); else error("Couldn't statvfs: %s", fx2txt(status)); - buffer_free(&msg); + sshbuf_free(msg); return -1; } else if (type != SSH2_FXP_EXTENDED_REPLY) { fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", @@ -311,22 +351,23 @@ get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, } memset(st, 0, sizeof(*st)); - st->f_bsize = buffer_get_int64(&msg); - st->f_frsize = buffer_get_int64(&msg); - st->f_blocks = buffer_get_int64(&msg); - st->f_bfree = buffer_get_int64(&msg); - st->f_bavail = buffer_get_int64(&msg); - st->f_files = buffer_get_int64(&msg); - st->f_ffree = buffer_get_int64(&msg); - st->f_favail = buffer_get_int64(&msg); - st->f_fsid = buffer_get_int64(&msg); - flag = buffer_get_int64(&msg); - st->f_namemax = buffer_get_int64(&msg); + if ((r = sshbuf_get_u64(msg, &st->f_bsize)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_frsize)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_blocks)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_bfree)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_bavail)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_files)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_ffree)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_favail)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 || + (r = sshbuf_get_u64(msg, &flag)) != 0 || + (r = sshbuf_get_u64(msg, &st->f_namemax)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; - buffer_free(&msg); + sshbuf_free(msg); return 0; } @@ -335,9 +376,10 @@ struct sftp_conn * do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, u_int64_t limit_kbps) { - u_int type; - Buffer msg; + u_char type; + struct sshbuf *msg; struct sftp_conn *ret; + int r; ret = xcalloc(1, sizeof(*ret)); ret->msg_id = 1; @@ -348,52 +390,61 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, ret->exts = 0; ret->limit_kbps = 0; - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_INIT); - buffer_put_int(&msg, SSH2_FILEXFER_VERSION); - send_msg(ret, &msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 || + (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(ret, msg); - buffer_clear(&msg); + sshbuf_reset(msg); - get_msg(ret, &msg); + get_msg(ret, msg); /* Expecting a VERSION reply */ - if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { + if ((r = sshbuf_get_u8(msg, &type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (type != SSH2_FXP_VERSION) { error("Invalid packet back from SSH2_FXP_INIT (type %u)", type); - buffer_free(&msg); + sshbuf_free(msg); return(NULL); } - ret->version = buffer_get_int(&msg); + if ((r = sshbuf_get_u32(msg, &ret->version)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug2("Remote version: %u", ret->version); /* Check for extensions */ - while (buffer_len(&msg) > 0) { - char *name = buffer_get_string(&msg, NULL); - char *value = buffer_get_string(&msg, NULL); + while (sshbuf_len(msg) > 0) { + char *name; + u_char *value; + size_t vlen; int known = 0; + if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 || + (r = sshbuf_get_string(msg, &value, &vlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp(name, "posix-rename@openssh.com") == 0 && - strcmp(value, "1") == 0) { + strcmp((char *)value, "1") == 0) { ret->exts |= SFTP_EXT_POSIX_RENAME; known = 1; } else if (strcmp(name, "statvfs@openssh.com") == 0 && - strcmp(value, "2") == 0) { + strcmp((char *)value, "2") == 0) { ret->exts |= SFTP_EXT_STATVFS; known = 1; } else if (strcmp(name, "fstatvfs@openssh.com") == 0 && - strcmp(value, "2") == 0) { + strcmp((char *)value, "2") == 0) { ret->exts |= SFTP_EXT_FSTATVFS; known = 1; } else if (strcmp(name, "hardlink@openssh.com") == 0 && - strcmp(value, "1") == 0) { + strcmp((char *)value, "1") == 0) { ret->exts |= SFTP_EXT_HARDLINK; known = 1; - } else if (strcmp(name, "fsync@openssh.com") == 0 && - strcmp(value, "1") == 0) { - ret->exts |= SFTP_EXT_FSYNC; - known = 1; + } else if (strcmp(name, "fsync@openssh.com") == 0 && + strcmp((char *)value, "1") == 0) { + ret->exts |= SFTP_EXT_FSYNC; + known = 1; } if (known) { debug2("Server supports extension \"%s\" revision %s", @@ -405,7 +456,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, free(value); } - buffer_free(&msg); + sshbuf_free(msg); /* Some filexfer v.0 servers don't support large packets */ if (ret->version == 0) @@ -429,54 +480,62 @@ sftp_proto_version(struct sftp_conn *conn) } int -do_close(struct sftp_conn *conn, char *handle, u_int handle_len) +do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len) { u_int id, status; - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_CLOSE); - buffer_put_int(&msg, id); - buffer_put_string(&msg, handle, handle_len); - send_msg(conn, &msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_string(msg, handle, handle_len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message SSH2_FXP_CLOSE I:%u", id); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't close file: %s", fx2txt(status)); - buffer_free(&msg); + sshbuf_free(msg); - return status; + return status == SSH2_FX_OK ? 0 : -1; } static int -do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, +do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag, SFTP_DIRENT ***dir) { - Buffer msg; - u_int count, type, id, handle_len, i, expected_id, ents = 0; + struct sshbuf *msg; + u_int count, id, i, expected_id, ents = 0; + size_t handle_len; + u_char type; char *handle; int status = SSH2_FX_FAILURE; + int r; if (dir) *dir = NULL; id = conn->msg_id++; - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_OPENDIR); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, path); - send_msg(conn, &msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, path)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); handle = get_handle(conn, id, &handle_len, "remote readdir(\"%s\")", path); if (handle == NULL) { - buffer_free(&msg); + sshbuf_free(msg); return -1; } @@ -491,18 +550,20 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, debug3("Sending SSH2_FXP_READDIR I:%u", id); - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_READDIR); - buffer_put_int(&msg, id); - buffer_put_string(&msg, handle, handle_len); - send_msg(conn, &msg); + sshbuf_reset(msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_string(msg, handle, handle_len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); - buffer_clear(&msg); + sshbuf_reset(msg); - get_msg(conn, &msg); + get_msg(conn, msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received reply T:%u I:%u", type, id); @@ -510,27 +571,43 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { - status = buffer_get_int(&msg); - debug3("Received SSH2_FXP_STATUS %d", status); - if (status == SSH2_FX_EOF) + u_int rstatus; + + if ((r = sshbuf_get_u32(msg, &rstatus)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + debug3("Received SSH2_FXP_STATUS %d", rstatus); + if (rstatus == SSH2_FX_EOF) break; - error("Couldn't read directory: %s", fx2txt(status)); + error("Couldn't read directory: %s", fx2txt(rstatus)); goto out; } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); - count = buffer_get_int(&msg); + if ((r = sshbuf_get_u32(msg, &count)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (count == 0) break; debug3("Received %d SSH2_FXP_NAME responses", count); for (i = 0; i < count; i++) { char *filename, *longname; - Attrib *a; + Attrib a; - filename = buffer_get_string(&msg, NULL); - longname = buffer_get_string(&msg, NULL); - a = decode_attrib(&msg); + if ((r = sshbuf_get_cstring(msg, &filename, + NULL)) != 0 || + (r = sshbuf_get_cstring(msg, &longname, + NULL)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + if ((r = decode_attrib(msg, &a)) != 0) { + error("%s: couldn't decode attrib: %s", + __func__, ssh_err(r)); + free(filename); + free(longname); + sshbuf_free(msg); + return -1; + } if (print_flag) printf("%s\n", longname); @@ -548,7 +625,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, (*dir)[ents] = xcalloc(1, sizeof(***dir)); (*dir)[ents]->filename = xstrdup(filename); (*dir)[ents]->longname = xstrdup(longname); - memcpy(&(*dir)[ents]->a, a, sizeof(*a)); + memcpy(&(*dir)[ents]->a, &a, sizeof(a)); (*dir)[++ents] = NULL; } free(filename); @@ -558,7 +635,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, status = 0; out: - buffer_free(&msg); + sshbuf_free(msg); do_close(conn, handle, handle_len); free(handle); @@ -577,7 +654,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int print_flag, } int -do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir) +do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir) { return(do_lsreaddir(conn, path, 0, dir)); } @@ -597,7 +674,7 @@ void free_sftp_dirents(SFTP_DIRENT **s) } int -do_rm(struct sftp_conn *conn, char *path) +do_rm(struct sftp_conn *conn, const char *path) { u_int status, id; @@ -608,11 +685,11 @@ do_rm(struct sftp_conn *conn, char *path) status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't delete file: %s", fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } int -do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) +do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag) { u_int status, id; @@ -624,11 +701,11 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int print_flag) if (status != SSH2_FX_OK && print_flag) error("Couldn't create directory: %s", fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } int -do_rmdir(struct sftp_conn *conn, char *path) +do_rmdir(struct sftp_conn *conn, const char *path) { u_int status, id; @@ -640,11 +717,11 @@ do_rmdir(struct sftp_conn *conn, char *path) if (status != SSH2_FX_OK) error("Couldn't remove directory: %s", fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } Attrib * -do_stat(struct sftp_conn *conn, char *path, int quiet) +do_stat(struct sftp_conn *conn, const char *path, int quiet) { u_int id; @@ -658,7 +735,7 @@ do_stat(struct sftp_conn *conn, char *path, int quiet) } Attrib * -do_lstat(struct sftp_conn *conn, char *path, int quiet) +do_lstat(struct sftp_conn *conn, const char *path, int quiet) { u_int id; @@ -679,7 +756,8 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) #ifdef notyet Attrib * -do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) +do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, + int quiet) { u_int id; @@ -692,7 +770,7 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) #endif int -do_setstat(struct sftp_conn *conn, char *path, Attrib *a) +do_setstat(struct sftp_conn *conn, const char *path, Attrib *a) { u_int status, id; @@ -705,11 +783,11 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a) error("Couldn't setstat on \"%s\": %s", path, fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } int -do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, +do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len, Attrib *a) { u_int status, id; @@ -722,181 +800,201 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, if (status != SSH2_FX_OK) error("Couldn't fsetstat: %s", fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } char * -do_realpath(struct sftp_conn *conn, char *path) +do_realpath(struct sftp_conn *conn, const char *path) { - Buffer msg; - u_int type, expected_id, count, id; + struct sshbuf *msg; + u_int expected_id, count, id; char *filename, *longname; - Attrib *a; + Attrib a; + u_char type; + int r; expected_id = id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_REALPATH, path, strlen(path)); - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); - get_msg(conn, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + get_msg(conn, msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { - u_int status = buffer_get_int(&msg); + u_int status; + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); error("Couldn't canonicalize: %s", fx2txt(status)); - buffer_free(&msg); + sshbuf_free(msg); return NULL; } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); - count = buffer_get_int(&msg); + if ((r = sshbuf_get_u32(msg, &count)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (count != 1) fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count); - filename = buffer_get_string(&msg, NULL); - longname = buffer_get_string(&msg, NULL); - a = decode_attrib(&msg); + if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || + (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || + (r = decode_attrib(msg, &a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename, - (unsigned long)a->size); + (unsigned long)a.size); free(longname); - buffer_free(&msg); + sshbuf_free(msg); return(filename); } int -do_rename(struct sftp_conn *conn, char *oldpath, char *newpath, +do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath, int force_legacy) { - Buffer msg; + struct sshbuf *msg; u_int status, id; - int use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; + int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy; - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); /* Send rename request */ id = conn->msg_id++; if (use_ext) { - buffer_put_char(&msg, SSH2_FXP_EXTENDED); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, "posix-rename@openssh.com"); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, + "posix-rename@openssh.com")) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } else { - buffer_put_char(&msg, SSH2_FXP_RENAME); - buffer_put_int(&msg, id); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } - buffer_put_cstring(&msg, oldpath); - buffer_put_cstring(&msg, newpath); - send_msg(conn, &msg); + if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 || + (r = sshbuf_put_cstring(msg, newpath)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message %s \"%s\" -> \"%s\"", - use_ext ? "posix-rename@openssh.com" : "SSH2_FXP_RENAME", - oldpath, newpath); - buffer_free(&msg); + use_ext ? "posix-rename@openssh.com" : + "SSH2_FXP_RENAME", oldpath, newpath); + sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } int -do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) +do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) { - Buffer msg; + struct sshbuf *msg; u_int status, id; + int r; if ((conn->exts & SFTP_EXT_HARDLINK) == 0) { error("Server does not support hardlink@openssh.com extension"); return -1; } - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); /* Send link request */ id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_EXTENDED); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, "hardlink@openssh.com"); - buffer_put_cstring(&msg, oldpath); - buffer_put_cstring(&msg, newpath); - send_msg(conn, &msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, oldpath)) != 0 || + (r = sshbuf_put_cstring(msg, newpath)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"", oldpath, newpath); - buffer_free(&msg); + sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't link file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } int -do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) +do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath) { - Buffer msg; + struct sshbuf *msg; u_int status, id; + int r; if (conn->version < 3) { error("This server does not support the symlink operation"); return(SSH2_FX_OP_UNSUPPORTED); } - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); /* Send symlink request */ id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_SYMLINK); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, oldpath); - buffer_put_cstring(&msg, newpath); - send_msg(conn, &msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_SYMLINK)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, oldpath)) != 0 || + (r = sshbuf_put_cstring(msg, newpath)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, newpath); - buffer_free(&msg); + sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); - return(status); + return status == SSH2_FX_OK ? 0 : -1; } int -do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) +do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len) { - Buffer msg; + struct sshbuf *msg; u_int status, id; + int r; /* Silently return if the extension is not supported */ if ((conn->exts & SFTP_EXT_FSYNC) == 0) return -1; - buffer_init(&msg); - /* Send fsync request */ + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); id = conn->msg_id++; - - buffer_put_char(&msg, SSH2_FXP_EXTENDED); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, "fsync@openssh.com"); - buffer_put_string(&msg, handle, handle_len); - send_msg(conn, &msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || + (r = sshbuf_put_string(msg, handle, handle_len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message fsync@openssh.com I:%u", id); - buffer_free(&msg); + sshbuf_free(msg); status = get_status(conn, id); if (status != SSH2_FX_OK) @@ -907,50 +1005,58 @@ do_fsync(struct sftp_conn *conn, char *handle, u_int handle_len) #ifdef notyet char * -do_readlink(struct sftp_conn *conn, char *path) +do_readlink(struct sftp_conn *conn, const char *path) { - Buffer msg; - u_int type, expected_id, count, id; + struct sshbuf *msg; + u_int expected_id, count, id; char *filename, *longname; - Attrib *a; + Attrib a; + u_char type; + int r; expected_id = id = conn->msg_id++; send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path)); - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); - get_msg(conn, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + get_msg(conn, msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (id != expected_id) fatal("ID mismatch (%u != %u)", id, expected_id); if (type == SSH2_FXP_STATUS) { - u_int status = buffer_get_int(&msg); + u_int status; + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); error("Couldn't readlink: %s", fx2txt(status)); - buffer_free(&msg); + sshbuf_free(msg); return(NULL); } else if (type != SSH2_FXP_NAME) fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", SSH2_FXP_NAME, type); - count = buffer_get_int(&msg); + if ((r = sshbuf_get_u32(msg, &count)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (count != 1) fatal("Got multiple names (%d) from SSH_FXP_READLINK", count); - filename = buffer_get_string(&msg, NULL); - longname = buffer_get_string(&msg, NULL); - a = decode_attrib(&msg); + if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 || + (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 || + (r = decode_attrib(msg, &a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("SSH_FXP_READLINK %s -> %s", path, filename); free(longname); - buffer_free(&msg); + sshbuf_free(msg); - return(filename); + return filename; } #endif @@ -958,8 +1064,9 @@ int do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, int quiet) { - Buffer msg; + struct sshbuf *msg; u_int id; + int r; if ((conn->exts & SFTP_EXT_STATVFS) == 0) { error("Server does not support statvfs@openssh.com extension"); @@ -968,24 +1075,26 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, id = conn->msg_id++; - buffer_init(&msg); - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_EXTENDED); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, "statvfs@openssh.com"); - buffer_put_cstring(&msg, path); - send_msg(conn, &msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + sshbuf_reset(msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, path)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); + sshbuf_free(msg); return get_decode_statvfs(conn, st, id, quiet); } #ifdef notyet int -do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, +do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len, struct sftp_statvfs *st, int quiet) { - Buffer msg; + struct sshbuf *msg; u_int id; if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) { @@ -995,14 +1104,16 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, id = conn->msg_id++; - buffer_init(&msg); - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_EXTENDED); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, "fstatvfs@openssh.com"); - buffer_put_string(&msg, handle, handle_len); - send_msg(conn, &msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + sshbuf_reset(msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || + (r = sshbuf_put_string(msg, handle, handle_len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); + sshbuf_free(msg); return get_decode_statvfs(conn, st, id, quiet); } @@ -1010,42 +1121,48 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, static void send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, - u_int len, char *handle, u_int handle_len) + u_int len, const u_char *handle, u_int handle_len) { - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_READ); - buffer_put_int(&msg, id); - buffer_put_string(&msg, handle, handle_len); - buffer_put_int64(&msg, offset); - buffer_put_int(&msg, len); - send_msg(conn, &msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + sshbuf_reset(msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_string(msg, handle, handle_len)) != 0 || + (r = sshbuf_put_u64(msg, offset)) != 0 || + (r = sshbuf_put_u32(msg, len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(conn, msg); + sshbuf_free(msg); } int -do_download(struct sftp_conn *conn, char *remote_path, char *local_path, - Attrib *a, int preserve_flag, int resume_flag, int fsync_flag) +do_download(struct sftp_conn *conn, const char *remote_path, + const char *local_path, Attrib *a, int preserve_flag, int resume_flag, + int fsync_flag) { Attrib junk; - Buffer msg; - char *handle; - int local_fd = -1, status = 0, write_error; - int read_error, write_errno, reordered = 0; + struct sshbuf *msg; + u_char *handle; + int local_fd = -1, write_error; + int read_error, write_errno, reordered = 0, r; u_int64_t offset = 0, size, highwater; - u_int handle_len, mode, type, id, buflen, num_req, max_req; + u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK; off_t progress_counter; + size_t handle_len; struct stat st; struct request { u_int id; - u_int len; + size_t len; u_int64_t offset; TAILQ_ENTRY(request) tq; }; TAILQ_HEAD(reqhead, request) requests; struct request *req; + u_char type; TAILQ_INIT(&requests); @@ -1070,23 +1187,26 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, size = 0; buflen = conn->transfer_buflen; - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + + attrib_clear(&junk); /* Send empty attributes */ /* Send open request */ id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_OPEN); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, remote_path); - buffer_put_int(&msg, SSH2_FXF_READ); - attrib_clear(&junk); /* Send empty attributes */ - encode_attrib(&msg, &junk); - send_msg(conn, &msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, remote_path)) != 0 || + (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 || + (r = encode_attrib(msg, &junk)) != 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, remote_path); handle = get_handle(conn, id, &handle_len, "remote open(\"%s\")", remote_path); if (handle == NULL) { - buffer_free(&msg); + sshbuf_free(msg); return(-1); } @@ -1113,7 +1233,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, "local file is larger than remote", local_path); fail: do_close(conn, handle, handle_len); - buffer_free(&msg); + sshbuf_free(msg); free(handle); if (local_fd != -1) close(local_fd); @@ -1131,8 +1251,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, start_progress_meter(remote_path, size, &progress_counter); while (num_req > 0 || max_req > 0) { - char *data; - u_int len; + u_char *data; + size_t len; /* * Simulate EOF on interrupt: stop sending new requests and @@ -1161,10 +1281,11 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, req->len, handle, handle_len); } - buffer_clear(&msg); - get_msg(conn, &msg); - type = buffer_get_char(&msg); - id = buffer_get_int(&msg); + sshbuf_reset(msg); + get_msg(conn, msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("Received reply T:%u I:%u R:%d", type, id, max_req); /* Find the request in our queue */ @@ -1177,7 +1298,9 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, switch (type) { case SSH2_FXP_STATUS: - status = buffer_get_int(&msg); + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); if (status != SSH2_FX_EOF) read_error = 1; max_req = 0; @@ -1186,13 +1309,15 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, num_req--; break; case SSH2_FXP_DATA: - data = buffer_get_string(&msg, &len); + if ((r = sshbuf_get_string(msg, &data, &len)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); debug3("Received data %llu -> %llu", (unsigned long long)req->offset, (unsigned long long)req->offset + len - 1); if (len > req->len) fatal("Received more data than asked for " - "%u > %u", len, req->len); + "%zu > %zu", len, req->len); if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || atomicio(vwrite, local_fd, data, len) != len) && !write_error) { @@ -1269,12 +1394,13 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, } else if (write_error) { error("Couldn't write to \"%s\": %s", local_path, strerror(write_errno)); - status = -1; + status = SSH2_FX_FAILURE; do_close(conn, handle, handle_len); } else { - status = do_close(conn, handle, handle_len); - if (interrupted || status != SSH2_FX_OK) - status = -1; + if (do_close(conn, handle, handle_len) != 0 || interrupted) + status = SSH2_FX_FAILURE; + else + status = SSH2_FX_OK; /* Override umask and utimes if asked */ #ifdef HAVE_FCHMOD if (preserve_flag && fchmod(local_fd, mode) == -1) @@ -1301,16 +1427,16 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, } } close(local_fd); - buffer_free(&msg); + sshbuf_free(msg); free(handle); return(status); } static int -download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, - Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag, - int fsync_flag) +download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, + int depth, Attrib *dirattrib, int preserve_flag, int print_flag, + int resume_flag, int fsync_flag) { int i, ret = 0; SFTP_DIRENT **dir_entries; @@ -1400,9 +1526,9 @@ download_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, } int -download_dir(struct sftp_conn *conn, char *src, char *dst, - Attrib *dirattrib, int preserve_flag, int print_flag, - int resume_flag, int fsync_flag) +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) { char *src_canon; int ret; @@ -1419,15 +1545,16 @@ download_dir(struct sftp_conn *conn, char *src, char *dst, } int -do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, - int preserve_flag, int resume, int fsync_flag) +do_upload(struct sftp_conn *conn, const char *local_path, + const char *remote_path, int preserve_flag, int resume, int fsync_flag) { - int local_fd; - int status = SSH2_FX_OK; - u_int handle_len, id, type; + int r, local_fd; + u_int status = SSH2_FX_OK; + u_int id; + u_char type; off_t offset, progress_counter; - char *handle, *data; - Buffer msg; + u_char *handle, *data; + struct sshbuf *msg; struct stat sb; Attrib a, *c = NULL; u_int32_t startid; @@ -1440,6 +1567,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, }; TAILQ_HEAD(ackhead, outstanding_ack) acks; struct outstanding_ack *ack = NULL; + size_t handle_len; TAILQ_INIT(&acks); @@ -1487,26 +1615,28 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, } } - buffer_init(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); /* Send open request */ id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_OPEN); - buffer_put_int(&msg, id); - buffer_put_cstring(&msg, remote_path); - buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| - (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC)); - encode_attrib(&msg, &a); - send_msg(conn, &msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_cstring(msg, remote_path)) != 0 || + (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT| + (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 || + (r = encode_attrib(msg, &a)) != 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, remote_path); - buffer_clear(&msg); + sshbuf_reset(msg); handle = get_handle(conn, id, &handle_len, "remote open(\"%s\")", remote_path); if (handle == NULL) { close(local_fd); - buffer_free(&msg); + sshbuf_free(msg); return -1; } @@ -1546,13 +1676,16 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, ack->len = len; TAILQ_INSERT_TAIL(&acks, ack, tq); - buffer_clear(&msg); - buffer_put_char(&msg, SSH2_FXP_WRITE); - buffer_put_int(&msg, ack->id); - buffer_put_string(&msg, handle, handle_len); - buffer_put_int64(&msg, offset); - buffer_put_string(&msg, data, len); - send_msg(conn, &msg); + sshbuf_reset(msg); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 || + (r = sshbuf_put_u32(msg, ack->id)) != 0 || + (r = sshbuf_put_string(msg, handle, + handle_len)) != 0 || + (r = sshbuf_put_u64(msg, offset)) != 0 || + (r = sshbuf_put_string(msg, data, len)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + send_msg(conn, msg); debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", id, (unsigned long long)offset, len); } else if (TAILQ_FIRST(&acks) == NULL) @@ -1563,27 +1696,31 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, if (id == startid || len == 0 || id - ackid >= conn->num_requests) { - u_int r_id; + u_int rid; - buffer_clear(&msg); - get_msg(conn, &msg); - type = buffer_get_char(&msg); - r_id = buffer_get_int(&msg); + sshbuf_reset(msg); + get_msg(conn, msg); + if ((r = sshbuf_get_u8(msg, &type)) != 0 || + (r = sshbuf_get_u32(msg, &rid)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); if (type != SSH2_FXP_STATUS) fatal("Expected SSH2_FXP_STATUS(%d) packet, " "got %d", SSH2_FXP_STATUS, type); - status = buffer_get_int(&msg); - debug3("SSH2_FXP_STATUS %d", status); + if ((r = sshbuf_get_u32(msg, &status)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + debug3("SSH2_FXP_STATUS %u", status); /* Find the request in our queue */ for (ack = TAILQ_FIRST(&acks); - ack != NULL && ack->id != r_id; + ack != NULL && ack->id != rid; ack = TAILQ_NEXT(ack, tq)) ; if (ack == NULL) - fatal("Can't find request for ID %u", r_id); + fatal("Can't find request for ID %u", rid); TAILQ_REMOVE(&acks, ack, tq); debug3("In write loop, ack for %u %u bytes at %lld", ack->id, ack->len, (long long)ack->offset); @@ -1595,7 +1732,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, if (offset < 0) fatal("%s: offset < 0", __func__); } - buffer_free(&msg); + sshbuf_free(msg); if (showprogress) stop_progress_meter(); @@ -1604,13 +1741,13 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, if (status != SSH2_FX_OK) { error("Couldn't write to remote file \"%s\": %s", remote_path, fx2txt(status)); - status = -1; + status = SSH2_FX_FAILURE; } if (close(local_fd) == -1) { error("Couldn't close local file \"%s\": %s", local_path, strerror(errno)); - status = -1; + status = SSH2_FX_FAILURE; } /* Override umask and utimes if asked */ @@ -1621,17 +1758,19 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, (void)do_fsync(conn, handle, handle_len); if (do_close(conn, handle, handle_len) != SSH2_FX_OK) - status = -1; + status = SSH2_FX_FAILURE; + free(handle); - return status; + return status == SSH2_FX_OK ? 0 : -1; } static int -upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, - int preserve_flag, int print_flag, int resume, int fsync_flag) +upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, + int depth, int preserve_flag, int print_flag, int resume, int fsync_flag) { - int ret = 0, status; + int ret = 0; + u_int status; DIR *dirp; struct dirent *dp; char *filename, *new_src, *new_dst; @@ -1721,8 +1860,8 @@ upload_dir_internal(struct sftp_conn *conn, char *src, char *dst, int depth, } int -upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, - int print_flag, int resume, int fsync_flag) +upload_dir(struct sftp_conn *conn, const char *src, const char *dst, + int preserve_flag, int print_flag, int resume, int fsync_flag) { char *dst_canon; int ret; @@ -1740,7 +1879,7 @@ upload_dir(struct sftp_conn *conn, char *src, char *dst, int preserve_flag, } char * -path_append(char *p1, char *p2) +path_append(const char *p1, const char *p2) { char *ret; size_t len = strlen(p1) + strlen(p2) + 2; diff --git a/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h index 967840b9cb62..507d763ea510 100644 --- a/crypto/openssh/sftp-client.h +++ b/crypto/openssh/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.25 2014/04/21 14:36:16 logan Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.26 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -56,79 +56,81 @@ struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t); u_int sftp_proto_version(struct sftp_conn *); /* Close file referred to by 'handle' */ -int do_close(struct sftp_conn *, char *, u_int); +int do_close(struct sftp_conn *, const u_char *, u_int); /* Read contents of 'path' to NULL-terminated array 'dir' */ -int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***); +int do_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 **); /* Delete file 'path' */ -int do_rm(struct sftp_conn *, char *); +int do_rm(struct sftp_conn *, const char *); /* Create directory 'path' */ -int do_mkdir(struct sftp_conn *, char *, Attrib *, int); +int do_mkdir(struct sftp_conn *, const char *, Attrib *, int); /* Remove directory 'path' */ -int do_rmdir(struct sftp_conn *, char *); +int do_rmdir(struct sftp_conn *, const char *); /* Get file attributes of 'path' (follows symlinks) */ -Attrib *do_stat(struct sftp_conn *, char *, int); +Attrib *do_stat(struct sftp_conn *, const char *, int); /* Get file attributes of 'path' (does not follow symlinks) */ -Attrib *do_lstat(struct sftp_conn *, char *, int); +Attrib *do_lstat(struct sftp_conn *, const char *, int); /* Set file attributes of 'path' */ -int do_setstat(struct sftp_conn *, char *, Attrib *); +int do_setstat(struct sftp_conn *, const char *, Attrib *); /* Set file attributes of open file 'handle' */ -int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); +int do_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *); /* Canonicalise 'path' - caller must free result */ -char *do_realpath(struct sftp_conn *, char *); +char *do_realpath(struct sftp_conn *, const char *); /* Get statistics for filesystem hosting file at "path" */ int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); /* Rename 'oldpath' to 'newpath' */ -int do_rename(struct sftp_conn *, char *, char *m, int force_legacy); +int do_rename(struct sftp_conn *, const char *, const char *, int force_legacy); /* Link 'oldpath' to 'newpath' */ -int do_hardlink(struct sftp_conn *, char *, char *); +int do_hardlink(struct sftp_conn *, const char *, const char *); /* Rename 'oldpath' to 'newpath' */ -int do_symlink(struct sftp_conn *, char *, char *); +int do_symlink(struct sftp_conn *, const char *, const char *); /* Call fsync() on open file 'handle' */ -int do_fsync(struct sftp_conn *conn, char *, u_int); +int do_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 *, char *, char *, Attrib *, int, int, int); +int do_download(struct sftp_conn *, const char *, const char *, + Attrib *, int, int, int); /* * Recursively download 'remote_directory' to 'local_directory'. Preserve * times if 'pflag' is set */ -int download_dir(struct sftp_conn *, char *, char *, Attrib *, int, - int, int, int); +int download_dir(struct sftp_conn *, const char *, const char *, + Attrib *, int, int, int, int); /* * Upload 'local_path' to 'remote_path'. Preserve permissions and times * if 'pflag' is set */ -int do_upload(struct sftp_conn *, char *, char *, int, int, int); +int do_upload(struct sftp_conn *, const char *, const char *, int, int, int); /* * Recursively upload 'local_directory' to 'remote_directory'. Preserve * times if 'pflag' is set */ -int upload_dir(struct sftp_conn *, char *, char *, int, int, int, int); +int upload_dir(struct sftp_conn *, const char *, const char *, int, int, int, + int); /* Concatenate paths, taking care of slashes. Caller must free result. */ -char *path_append(char *, char *); +char *path_append(const char *, const char *); #endif diff --git a/crypto/openssh/sftp-common.c b/crypto/openssh/sftp-common.c index b546a9f56b06..feccfd632b92 100644 --- a/crypto/openssh/sftp-common.c +++ b/crypto/openssh/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.26 2014/01/09 03:26:00 guenther Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.28 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -27,9 +27,9 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* MAX */ #include #include -#include #include #include @@ -43,7 +43,8 @@ __RCSID("$FreeBSD$"); #endif #include "xmalloc.h" -#include "buffer.h" +#include "ssherr.h" +#include "sshbuf.h" #include "log.h" #include "sftp.h" @@ -101,59 +102,81 @@ attrib_to_stat(const Attrib *a, struct stat *st) } /* Decode attributes in buffer */ -Attrib * -decode_attrib(Buffer *b) +int +decode_attrib(struct sshbuf *b, Attrib *a) { - static Attrib a; + int r; - attrib_clear(&a); - a.flags = buffer_get_int(b); - if (a.flags & SSH2_FILEXFER_ATTR_SIZE) - a.size = buffer_get_int64(b); - if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { - a.uid = buffer_get_int(b); - a.gid = buffer_get_int(b); + attrib_clear(a); + if ((r = sshbuf_get_u32(b, &a->flags)) != 0) + return r; + if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { + if ((r = sshbuf_get_u64(b, &a->size)) != 0) + return r; } - if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - a.perm = buffer_get_int(b); - if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - a.atime = buffer_get_int(b); - a.mtime = buffer_get_int(b); + if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + if ((r = sshbuf_get_u32(b, &a->uid)) != 0 || + (r = sshbuf_get_u32(b, &a->gid)) != 0) + return r; + } + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { + if ((r = sshbuf_get_u32(b, &a->perm)) != 0) + return r; + } + if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + if ((r = sshbuf_get_u32(b, &a->atime)) != 0 || + (r = sshbuf_get_u32(b, &a->mtime)) != 0) + return r; } /* vendor-specific extensions */ - if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) { - char *type, *data; - int i, count; + if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) { + char *type; + u_char *data; + size_t dlen; + u_int i, count; - count = buffer_get_int(b); + if ((r = sshbuf_get_u32(b, &count)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; i < count; i++) { - type = buffer_get_string(b, NULL); - data = buffer_get_string(b, NULL); - debug3("Got file attribute \"%s\"", type); + if ((r = sshbuf_get_cstring(b, &type, NULL)) != 0 || + (r = sshbuf_get_string(b, &data, &dlen)) != 0) + return r; + debug3("Got file attribute \"%.100s\" len %zu", + type, dlen); free(type); free(data); } } - return &a; + return 0; } /* Encode attributes to buffer */ -void -encode_attrib(Buffer *b, const Attrib *a) +int +encode_attrib(struct sshbuf *b, const Attrib *a) { - buffer_put_int(b, a->flags); - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) - buffer_put_int64(b, a->size); + int r; + + if ((r = sshbuf_put_u32(b, a->flags)) != 0) + return r; + if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { + if ((r = sshbuf_put_u64(b, a->size)) != 0) + return r; + } if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { - buffer_put_int(b, a->uid); - buffer_put_int(b, a->gid); + if ((r = sshbuf_put_u32(b, a->uid)) != 0 || + (r = sshbuf_put_u32(b, a->gid)) != 0) + return r; + } + if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { + if ((r = sshbuf_put_u32(b, a->perm)) != 0) + return r; } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) - buffer_put_int(b, a->perm); if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { - buffer_put_int(b, a->atime); - buffer_put_int(b, a->mtime); + if ((r = sshbuf_put_u32(b, a->atime)) != 0 || + (r = sshbuf_put_u32(b, a->mtime)) != 0) + return r; } + return 0; } /* Convert from SSH2_FX_ status to text error message */ diff --git a/crypto/openssh/sftp-common.h b/crypto/openssh/sftp-common.h index 9ed86c070dd7..2e778a9ca0ba 100644 --- a/crypto/openssh/sftp-common.h +++ b/crypto/openssh/sftp-common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.h,v 1.11 2010/01/13 01:40:16 djm Exp $ */ +/* $OpenBSD: sftp-common.h,v 1.12 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -28,6 +28,7 @@ /* Maximum packet that we are willing to send/accept */ #define SFTP_MAX_MSG_LENGTH (256 * 1024) +struct sshbuf; typedef struct Attrib Attrib; /* File attributes */ @@ -44,8 +45,8 @@ struct Attrib { void attrib_clear(Attrib *); void stat_to_attrib(const struct stat *, Attrib *); void attrib_to_stat(const Attrib *, struct stat *); -Attrib *decode_attrib(Buffer *); -void encode_attrib(Buffer *, const Attrib *); +int decode_attrib(struct sshbuf *, Attrib *); +int encode_attrib(struct sshbuf *, const Attrib *); char *ls_file(const char *, const struct stat *, int, int); const char *fx2txt(int); diff --git a/crypto/openssh/sftp-glob.c b/crypto/openssh/sftp-glob.c index d85aecc9ab76..43a1bebadbd4 100644 --- a/crypto/openssh/sftp-glob.c +++ b/crypto/openssh/sftp-glob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-glob.c,v 1.26 2013/11/08 11:15:19 dtucker Exp $ */ +/* $OpenBSD: sftp-glob.c,v 1.27 2015/01/14 13:54:13 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -25,10 +25,10 @@ #include #include #include +#include #include "xmalloc.h" #include "sftp.h" -#include "buffer.h" #include "sftp-common.h" #include "sftp-client.h" diff --git a/crypto/openssh/sftp-server.0 b/crypto/openssh/sftp-server.0 index d811e252d28a..77b6bb5096d9 100644 --- a/crypto/openssh/sftp-server.0 +++ b/crypto/openssh/sftp-server.0 @@ -1,7 +1,7 @@ SFTP-SERVER(8) System Manager's Manual SFTP-SERVER(8) NAME - sftp-server - SFTP server subsystem + sftp-server M-bM-^@M-^S SFTP server subsystem SYNOPSIS sftp-server [-ehR] [-d start_directory] [-f log_facility] [-l log_level] @@ -23,7 +23,7 @@ DESCRIPTION -d start_directory specifies an alternate starting directory for users. The pathname may contain the following tokens that are expanded at - runtime: %% is replaced by a literal '%', %h is replaced by the + runtime: %% is replaced by a literal '%', %d is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. The default is to use the user's home directory. This option is useful in conjunction with @@ -65,8 +65,8 @@ DESCRIPTION -Q protocol_feature Query protocol features supported by sftp-server. At present the - only feature that may be queried is ``requests'', which may be - used for black or whitelisting (flags -P and -p respectively). + only feature that may be queried is M-bM-^@M-^\requestsM-bM-^@M-^], which may be used + for black or whitelisting (flags -P and -p respectively). -R Places this instance of sftp-server into a read-only mode. Attempts to open files for writing, as well as other operations @@ -93,4 +93,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.6 July 28, 2014 OpenBSD 5.6 +OpenBSD 5.7 December 11, 2014 OpenBSD 5.7 diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8 index 75d8d8d532d9..c117398e8583 100644 --- a/crypto/openssh/sftp-server.8 +++ b/crypto/openssh/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.26 2014/07/28 15:40:08 schwarze Exp $ +.\" $OpenBSD: sftp-server.8,v 1.27 2014/12/11 04:16:14 djm Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,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 28 2014 $ +.Dd $Mdocdate: December 11 2014 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -67,7 +67,7 @@ Valid options are: specifies an alternate starting directory for users. The pathname may contain the following tokens that are expanded at runtime: %% is replaced by a literal '%', -%h is replaced by the home directory of the user being authenticated, +%d is replaced by the home directory of the user being authenticated, and %u is replaced by the username of that user. The default is to use the user's home directory. This option is useful in conjunction with the diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c index 0177130cfb17..4f735cd9397c 100644 --- a/crypto/openssh/sftp-server.c +++ b/crypto/openssh/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.103 2014/01/17 06:23:24 dtucker Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.105 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -17,8 +17,8 @@ #include "includes.h" +#include /* MIN */ #include -#include #include #ifdef HAVE_SYS_TIME_H # include @@ -46,7 +46,8 @@ #include #include "xmalloc.h" -#include "buffer.h" +#include "sshbuf.h" +#include "ssherr.h" #include "log.h" #include "misc.h" #include "match.h" @@ -55,11 +56,6 @@ #include "sftp.h" #include "sftp-common.h" -/* helper */ -#define get_int64() buffer_get_int64(&iqueue); -#define get_int() buffer_get_int(&iqueue); -#define get_string(lenp) buffer_get_string(&iqueue, lenp); - /* Our verbosity */ static LogLevel log_level = SYSLOG_LEVEL_ERROR; @@ -68,8 +64,8 @@ static struct passwd *pw = NULL; static char *client_addr = NULL; /* input and output queue */ -static Buffer iqueue; -static Buffer oqueue; +struct sshbuf *iqueue; +struct sshbuf *oqueue; /* Version of client */ static u_int version; @@ -275,12 +271,6 @@ string_from_portable(int pflags) return ret; } -static Attrib * -get_attrib(void) -{ - return decode_attrib(&iqueue); -} - /* handle handles */ typedef struct Handle Handle; @@ -344,7 +334,7 @@ handle_is_ok(int i, int type) } static int -handle_to_string(int handle, char **stringp, int *hlenp) +handle_to_string(int handle, u_char **stringp, int *hlenp) { if (stringp == NULL || hlenp == NULL) return -1; @@ -355,7 +345,7 @@ handle_to_string(int handle, char **stringp, int *hlenp) } static int -handle_from_string(const char *handle, u_int hlen) +handle_from_string(const u_char *handle, u_int hlen) { int val; @@ -477,29 +467,31 @@ handle_log_exit(void) } static int -get_handle(void) +get_handle(struct sshbuf *queue, int *hp) { - char *handle; - int val = -1; - u_int hlen; + u_char *handle; + int r; + size_t hlen; - handle = get_string(&hlen); + *hp = -1; + if ((r = sshbuf_get_string(queue, &handle, &hlen)) != 0) + return r; if (hlen < 256) - val = handle_from_string(handle, hlen); + *hp = handle_from_string(handle, hlen); free(handle); - return val; + return 0; } /* send replies */ static void -send_msg(Buffer *m) +send_msg(struct sshbuf *m) { - int mlen = buffer_len(m); + int r; - buffer_put_int(&oqueue, mlen); - buffer_append(&oqueue, buffer_ptr(m), mlen); - buffer_consume(m, mlen); + if ((r = sshbuf_put_stringb(oqueue, m)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_reset(m); } static const char * @@ -523,38 +515,46 @@ status_to_message(u_int32_t status) static void send_status(u_int32_t id, u_int32_t status) { - Buffer msg; + struct sshbuf *msg; + int r; debug3("request %u: sent status %u", id, status); if (log_level > SYSLOG_LEVEL_VERBOSE || (status != SSH2_FX_OK && status != SSH2_FX_EOF)) logit("sent status %s", status_to_message(status)); - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_STATUS); - buffer_put_int(&msg, id); - buffer_put_int(&msg, status); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_STATUS)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_u32(msg, status)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (version >= 3) { - buffer_put_cstring(&msg, status_to_message(status)); - buffer_put_cstring(&msg, ""); + if ((r = sshbuf_put_cstring(msg, + status_to_message(status))) != 0 || + (r = sshbuf_put_cstring(msg, "")) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } - send_msg(&msg); - buffer_free(&msg); + send_msg(msg); + sshbuf_free(msg); } static void -send_data_or_handle(char type, u_int32_t id, const char *data, int dlen) +send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen) { - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); - buffer_put_char(&msg, type); - buffer_put_int(&msg, id); - buffer_put_string(&msg, data, dlen); - send_msg(&msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, type)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_string(msg, data, dlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(msg); + sshbuf_free(msg); } static void -send_data(u_int32_t id, const char *data, int dlen) +send_data(u_int32_t id, const u_char *data, int dlen) { debug("request %u: sent data len %d", id, dlen); send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); @@ -563,7 +563,7 @@ send_data(u_int32_t id, const char *data, int dlen) static void send_handle(u_int32_t id, int handle) { - char *string; + u_char *string; int hlen; handle_to_string(handle, &string, &hlen); @@ -575,62 +575,71 @@ send_handle(u_int32_t id, int handle) static void send_names(u_int32_t id, int count, const Stat *stats) { - Buffer msg; - int i; + struct sshbuf *msg; + int i, r; - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_NAME); - buffer_put_int(&msg, id); - buffer_put_int(&msg, count); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_NAME)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_u32(msg, count)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: sent names count %d", id, count); for (i = 0; i < count; i++) { - buffer_put_cstring(&msg, stats[i].name); - buffer_put_cstring(&msg, stats[i].long_name); - encode_attrib(&msg, &stats[i].attrib); + if ((r = sshbuf_put_cstring(msg, stats[i].name)) != 0 || + (r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0 || + (r = encode_attrib(msg, &stats[i].attrib)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } - send_msg(&msg); - buffer_free(&msg); + send_msg(msg); + sshbuf_free(msg); } static void send_attrib(u_int32_t id, const Attrib *a) { - Buffer msg; + struct sshbuf *msg; + int r; debug("request %u: sent attrib have 0x%x", id, a->flags); - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_ATTRS); - buffer_put_int(&msg, id); - encode_attrib(&msg, a); - send_msg(&msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_ATTRS)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = encode_attrib(msg, a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(msg); + sshbuf_free(msg); } static void send_statvfs(u_int32_t id, struct statvfs *st) { - Buffer msg; + struct sshbuf *msg; u_int64_t flag; + int r; flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); - buffer_put_int(&msg, id); - buffer_put_int64(&msg, st->f_bsize); - buffer_put_int64(&msg, st->f_frsize); - buffer_put_int64(&msg, st->f_blocks); - buffer_put_int64(&msg, st->f_bfree); - buffer_put_int64(&msg, st->f_bavail); - buffer_put_int64(&msg, st->f_files); - buffer_put_int64(&msg, st->f_ffree); - buffer_put_int64(&msg, st->f_favail); - buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid)); - buffer_put_int64(&msg, flag); - buffer_put_int64(&msg, st->f_namemax); - send_msg(&msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 || + (r = sshbuf_put_u32(msg, id)) != 0 || + (r = sshbuf_put_u64(msg, st->f_bsize)) != 0 || + (r = sshbuf_put_u64(msg, st->f_frsize)) != 0 || + (r = sshbuf_put_u64(msg, st->f_blocks)) != 0 || + (r = sshbuf_put_u64(msg, st->f_bfree)) != 0 || + (r = sshbuf_put_u64(msg, st->f_bavail)) != 0 || + (r = sshbuf_put_u64(msg, st->f_files)) != 0 || + (r = sshbuf_put_u64(msg, st->f_ffree)) != 0 || + (r = sshbuf_put_u64(msg, st->f_favail)) != 0 || + (r = sshbuf_put_u64(msg, FSID_TO_ULONG(st->f_fsid))) != 0 || + (r = sshbuf_put_u64(msg, flag)) != 0 || + (r = sshbuf_put_u64(msg, st->f_namemax)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(msg); + sshbuf_free(msg); } /* parse incoming */ @@ -638,53 +647,59 @@ send_statvfs(u_int32_t id, struct statvfs *st) static void process_init(void) { - Buffer msg; + struct sshbuf *msg; + int r; - version = get_int(); + if ((r = sshbuf_get_u32(iqueue, &version)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); verbose("received client version %u", version); - buffer_init(&msg); - buffer_put_char(&msg, SSH2_FXP_VERSION); - buffer_put_int(&msg, SSH2_FILEXFER_VERSION); - /* POSIX rename extension */ - buffer_put_cstring(&msg, "posix-rename@openssh.com"); - buffer_put_cstring(&msg, "1"); /* version */ - /* statvfs extension */ - buffer_put_cstring(&msg, "statvfs@openssh.com"); - buffer_put_cstring(&msg, "2"); /* version */ - /* fstatvfs extension */ - buffer_put_cstring(&msg, "fstatvfs@openssh.com"); - buffer_put_cstring(&msg, "2"); /* version */ - /* hardlink extension */ - buffer_put_cstring(&msg, "hardlink@openssh.com"); - buffer_put_cstring(&msg, "1"); /* version */ - /* fsync extension */ - buffer_put_cstring(&msg, "fsync@openssh.com"); - buffer_put_cstring(&msg, "1"); /* version */ - send_msg(&msg); - buffer_free(&msg); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, SSH2_FXP_VERSION)) != 0 || + (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0 || + /* POSIX rename extension */ + (r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ + /* statvfs extension */ + (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */ + /* fstatvfs extension */ + (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */ + /* hardlink extension */ + (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */ + /* fsync extension */ + (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 || + (r = sshbuf_put_cstring(msg, "1")) != 0) /* version */ + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send_msg(msg); + sshbuf_free(msg); } static void process_open(u_int32_t id) { u_int32_t pflags; - Attrib *a; + Attrib a; char *name; - int handle, fd, flags, mode, status = SSH2_FX_FAILURE; + int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */ + (r = decode_attrib(iqueue, &a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - name = get_string(NULL); - pflags = get_int(); /* portable flags */ debug3("request %u: open flags %d", id, pflags); - a = get_attrib(); flags = flags_from_portable(pflags); - mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; + mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666; logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); if (readonly && ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) { verbose("Refusing open request in read-only mode"); - status = SSH2_FX_PERMISSION_DENIED; + status = SSH2_FX_PERMISSION_DENIED; } else { fd = open(name, flags, mode); if (fd < 0) { @@ -707,9 +722,11 @@ process_open(u_int32_t id) static void process_close(u_int32_t id) { - int handle, ret, status = SSH2_FX_FAILURE; + int r, handle, ret, status = SSH2_FX_FAILURE; + + if ((r = get_handle(iqueue, &handle)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - handle = get_handle(); debug3("request %u: close handle %u", id, handle); handle_log_close(handle, NULL); ret = handle_close(handle); @@ -720,14 +737,15 @@ process_close(u_int32_t id) static void process_read(u_int32_t id) { - char buf[64*1024]; + u_char buf[64*1024]; u_int32_t len; - int handle, fd, ret, status = SSH2_FX_FAILURE; + int r, handle, fd, ret, status = SSH2_FX_FAILURE; u_int64_t off; - handle = get_handle(); - off = get_int64(); - len = get_int(); + if ((r = get_handle(iqueue, &handle)) != 0 || + (r = sshbuf_get_u64(iqueue, &off)) != 0 || + (r = sshbuf_get_u32(iqueue, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: read \"%s\" (handle %d) off %llu len %d", id, handle_to_name(handle), handle, (unsigned long long)off, len); @@ -761,18 +779,19 @@ static void process_write(u_int32_t id) { u_int64_t off; - u_int len; - int handle, fd, ret, status; - char *data; + size_t len; + int r, handle, fd, ret, status; + u_char *data; - handle = get_handle(); - off = get_int64(); - data = get_string(&len); + if ((r = get_handle(iqueue, &handle)) != 0 || + (r = sshbuf_get_u64(iqueue, &off)) != 0 || + (r = sshbuf_get_string(iqueue, &data, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - debug("request %u: write \"%s\" (handle %d) off %llu len %d", + debug("request %u: write \"%s\" (handle %d) off %llu len %zu", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); - + if (fd < 0) status = SSH2_FX_FAILURE; else { @@ -805,13 +824,15 @@ process_do_stat(u_int32_t id, int do_lstat) Attrib a; struct stat st; char *name; - int ret, status = SSH2_FX_FAILURE; + int r, status = SSH2_FX_FAILURE; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - name = get_string(NULL); debug3("request %u: %sstat", id, do_lstat ? "l" : ""); verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name); - ret = do_lstat ? lstat(name, &st) : stat(name, &st); - if (ret < 0) { + r = do_lstat ? lstat(name, &st) : stat(name, &st); + if (r < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); @@ -840,15 +861,16 @@ process_fstat(u_int32_t id) { Attrib a; struct stat st; - int fd, ret, handle, status = SSH2_FX_FAILURE; + int fd, r, handle, status = SSH2_FX_FAILURE; - handle = get_handle(); + if ((r = get_handle(iqueue, &handle)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); fd = handle_to_fd(handle); if (fd >= 0) { - ret = fstat(fd, &st); - if (ret < 0) { + r = fstat(fd, &st); + if (r < 0) { status = errno_to_portable(errno); } else { stat_to_attrib(&st, &a); @@ -875,42 +897,44 @@ attrib_to_tv(const Attrib *a) static void process_setstat(u_int32_t id) { - Attrib *a; + Attrib a; char *name; - int status = SSH2_FX_OK, ret; + int r, status = SSH2_FX_OK; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + (r = decode_attrib(iqueue, &a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - name = get_string(NULL); - a = get_attrib(); debug("request %u: setstat name \"%s\"", id, name); - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { + if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", - name, (unsigned long long)a->size); - ret = truncate(name, a->size); - if (ret == -1) + name, (unsigned long long)a.size); + r = truncate(name, a.size); + if (r == -1) status = errno_to_portable(errno); } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { - logit("set \"%s\" mode %04o", name, a->perm); - ret = chmod(name, a->perm & 07777); - if (ret == -1) + if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { + logit("set \"%s\" mode %04o", name, a.perm); + r = chmod(name, a.perm & 07777); + if (r == -1) status = errno_to_portable(errno); } - if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { char buf[64]; - time_t t = a->mtime; + time_t t = a.mtime; strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", localtime(&t)); logit("set \"%s\" modtime %s", name, buf); - ret = utimes(name, attrib_to_tv(a)); - if (ret == -1) + r = utimes(name, attrib_to_tv(&a)); + if (r == -1) status = errno_to_portable(errno); } - if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { logit("set \"%s\" owner %lu group %lu", name, - (u_long)a->uid, (u_long)a->gid); - ret = chown(name, a->uid, a->gid); - if (ret == -1) + (u_long)a.uid, (u_long)a.gid); + r = chown(name, a.uid, a.gid); + if (r == -1) status = errno_to_portable(errno); } send_status(id, status); @@ -920,12 +944,14 @@ process_setstat(u_int32_t id) static void process_fsetstat(u_int32_t id) { - Attrib *a; - int handle, fd, ret; + Attrib a; + int handle, fd, r; int status = SSH2_FX_OK; - handle = get_handle(); - a = get_attrib(); + if ((r = get_handle(iqueue, &handle)) != 0 || + (r = decode_attrib(iqueue, &a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); if (fd < 0) @@ -933,47 +959,47 @@ process_fsetstat(u_int32_t id) else { char *name = handle_to_name(handle); - if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { + if (a.flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", - name, (unsigned long long)a->size); - ret = ftruncate(fd, a->size); - if (ret == -1) + name, (unsigned long long)a.size); + r = ftruncate(fd, a.size); + if (r == -1) status = errno_to_portable(errno); } - if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { - logit("set \"%s\" mode %04o", name, a->perm); + if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { + logit("set \"%s\" mode %04o", name, a.perm); #ifdef HAVE_FCHMOD - ret = fchmod(fd, a->perm & 07777); + r = fchmod(fd, a.perm & 07777); #else - ret = chmod(name, a->perm & 07777); + r = chmod(name, a.perm & 07777); #endif - if (ret == -1) + if (r == -1) status = errno_to_portable(errno); } - if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { + if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) { char buf[64]; - time_t t = a->mtime; + time_t t = a.mtime; strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S", localtime(&t)); logit("set \"%s\" modtime %s", name, buf); #ifdef HAVE_FUTIMES - ret = futimes(fd, attrib_to_tv(a)); + r = futimes(fd, attrib_to_tv(&a)); #else - ret = utimes(name, attrib_to_tv(a)); + r = utimes(name, attrib_to_tv(&a)); #endif - if (ret == -1) + if (r == -1) status = errno_to_portable(errno); } - if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { + if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) { logit("set \"%s\" owner %lu group %lu", name, - (u_long)a->uid, (u_long)a->gid); + (u_long)a.uid, (u_long)a.gid); #ifdef HAVE_FCHOWN - ret = fchown(fd, a->uid, a->gid); + r = fchown(fd, a.uid, a.gid); #else - ret = chown(name, a->uid, a->gid); + r = chown(name, a.uid, a.gid); #endif - if (ret == -1) + if (r == -1) status = errno_to_portable(errno); } } @@ -985,9 +1011,11 @@ process_opendir(u_int32_t id) { DIR *dirp = NULL; char *path; - int handle, status = SSH2_FX_FAILURE; + int r, handle, status = SSH2_FX_FAILURE; + + if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - path = get_string(NULL); debug3("request %u: opendir", id); logit("opendir \"%s\"", path); dirp = opendir(path); @@ -1014,9 +1042,11 @@ process_readdir(u_int32_t id) DIR *dirp; struct dirent *dp; char *path; - int handle; + int r, handle; + + if ((r = get_handle(iqueue, &handle)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - handle = get_handle(); debug("request %u: readdir \"%s\" (handle %d)", id, handle_to_name(handle), handle); dirp = handle_to_dir(handle); @@ -1025,7 +1055,7 @@ process_readdir(u_int32_t id) send_status(id, SSH2_FX_FAILURE); } else { struct stat st; - char pathname[MAXPATHLEN]; + char pathname[PATH_MAX]; Stat *stats; int nstats = 10, count = 0, i; @@ -1066,14 +1096,15 @@ static void process_remove(u_int32_t id) { char *name; - int status = SSH2_FX_FAILURE; - int ret; + int r, status = SSH2_FX_FAILURE; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - name = get_string(NULL); debug3("request %u: remove", id); logit("remove name \"%s\"", name); - ret = unlink(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = unlink(name); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } @@ -1081,18 +1112,20 @@ process_remove(u_int32_t id) static void process_mkdir(u_int32_t id) { - Attrib *a; + Attrib a; char *name; - int ret, mode, status = SSH2_FX_FAILURE; + int r, mode, status = SSH2_FX_FAILURE; - name = get_string(NULL); - a = get_attrib(); - mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? - a->perm & 07777 : 0777; + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 || + (r = decode_attrib(iqueue, &a)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? + a.perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); - ret = mkdir(name, mode); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = mkdir(name, mode); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } @@ -1101,13 +1134,15 @@ static void process_rmdir(u_int32_t id) { char *name; - int ret, status; + int r, status; + + if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - name = get_string(NULL); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); - ret = rmdir(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = rmdir(name); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(name); } @@ -1115,10 +1150,13 @@ process_rmdir(u_int32_t id) static void process_realpath(u_int32_t id) { - char resolvedname[MAXPATHLEN]; + char resolvedname[PATH_MAX]; char *path; + int r; + + if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - path = get_string(NULL); if (path[0] == '\0') { free(path); path = xstrdup("."); @@ -1140,11 +1178,13 @@ static void process_rename(u_int32_t id) { char *oldpath, *newpath; - int status; + int r, status; struct stat sb; - oldpath = get_string(NULL); - newpath = get_string(NULL); + if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || + (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; @@ -1197,11 +1237,13 @@ process_rename(u_int32_t id) static void process_readlink(u_int32_t id) { - int len; - char buf[MAXPATHLEN]; + int r, len; + char buf[PATH_MAX]; char *path; - path = get_string(NULL); + if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug3("request %u: readlink", id); verbose("readlink \"%s\"", path); if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1) @@ -1221,15 +1263,17 @@ static void process_symlink(u_int32_t id) { char *oldpath, *newpath; - int ret, status; + int r, status; + + if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || + (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - oldpath = get_string(NULL); - newpath = get_string(NULL); debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ - ret = symlink(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = symlink(oldpath, newpath); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); @@ -1239,14 +1283,16 @@ static void process_extended_posix_rename(u_int32_t id) { char *oldpath, *newpath; - int ret, status; + int r, status; + + if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || + (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - oldpath = get_string(NULL); - newpath = get_string(NULL); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); - ret = rename(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = rename(oldpath, newpath); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); @@ -1257,8 +1303,10 @@ process_extended_statvfs(u_int32_t id) { char *path; struct statvfs st; + int r; - path = get_string(NULL); + if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: statvfs", id); logit("statvfs \"%s\"", path); @@ -1272,10 +1320,11 @@ process_extended_statvfs(u_int32_t id) static void process_extended_fstatvfs(u_int32_t id) { - int handle, fd; + int r, handle, fd; struct statvfs st; - handle = get_handle(); + if ((r = get_handle(iqueue, &handle)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: fstatvfs \"%s\" (handle %u)", id, handle_to_name(handle), handle); if ((fd = handle_to_fd(handle)) < 0) { @@ -1292,14 +1341,16 @@ static void process_extended_hardlink(u_int32_t id) { char *oldpath, *newpath; - int ret, status; + int r, status; + + if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 || + (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - oldpath = get_string(NULL); - newpath = get_string(NULL); debug3("request %u: hardlink", id); logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); - ret = link(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = link(oldpath, newpath); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; send_status(id, status); free(oldpath); free(newpath); @@ -1308,16 +1359,17 @@ process_extended_hardlink(u_int32_t id) static void process_extended_fsync(u_int32_t id) { - int handle, fd, ret, status = SSH2_FX_OP_UNSUPPORTED; + int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED; - handle = get_handle(); + if ((r = get_handle(iqueue, &handle)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("request %u: fsync (handle %u)", id, handle); verbose("fsync \"%s\"", handle_to_name(handle)); if ((fd = handle_to_fd(handle)) < 0) status = SSH2_FX_NO_SUCH_FILE; else if (handle_is_ok(handle, HANDLE_FILE)) { - ret = fsync(fd); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + r = fsync(fd); + status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK; } send_status(id, status); } @@ -1326,9 +1378,10 @@ static void process_extended(u_int32_t id) { char *request; - u_int i; + int i, r; - request = get_string(NULL); + if ((r = sshbuf_get_cstring(iqueue, &request, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; extended_handlers[i].handler != NULL; i++) { if (strcmp(request, extended_handlers[i].ext_name) == 0) { if (!request_permitted(&extended_handlers[i])) @@ -1350,14 +1403,18 @@ process_extended(u_int32_t id) static void process(void) { - u_int msg_len, buf_len, consumed, type, i; - u_char *cp; + u_int msg_len; + u_int buf_len; + u_int consumed; + u_char type; + const u_char *cp; + int i, r; u_int32_t id; - buf_len = buffer_len(&iqueue); + buf_len = sshbuf_len(iqueue); if (buf_len < 5) return; /* Incomplete message. */ - cp = buffer_ptr(&iqueue); + cp = sshbuf_ptr(iqueue); msg_len = get_u32(cp); if (msg_len > SFTP_MAX_MSG_LENGTH) { error("bad message from %s local user %s", @@ -1366,9 +1423,11 @@ process(void) } if (buf_len < msg_len + 4) return; - buffer_consume(&iqueue, 4); + if ((r = sshbuf_consume(iqueue, 4)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); buf_len -= 4; - type = buffer_get_char(&iqueue); + if ((r = sshbuf_get_u8(iqueue, &type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); switch (type) { case SSH2_FXP_INIT: @@ -1378,13 +1437,15 @@ process(void) case SSH2_FXP_EXTENDED: if (!init_done) fatal("Received extended request before init"); - id = get_int(); + if ((r = sshbuf_get_u32(iqueue, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); process_extended(id); break; default: if (!init_done) fatal("Received %u request before init", type); - id = get_int(); + if ((r = sshbuf_get_u32(iqueue, &id)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; handlers[i].handler != NULL; i++) { if (type == handlers[i].type) { if (!request_permitted(&handlers[i])) { @@ -1400,17 +1461,18 @@ process(void) error("Unknown message %u", type); } /* discard the remaining bytes from the current packet */ - if (buf_len < buffer_len(&iqueue)) { + if (buf_len < sshbuf_len(iqueue)) { error("iqueue grew unexpectedly"); sftp_server_cleanup_exit(255); } - consumed = buf_len - buffer_len(&iqueue); + consumed = buf_len - sshbuf_len(iqueue); if (msg_len < consumed) { error("msg_len %u < consumed %u", msg_len, consumed); sftp_server_cleanup_exit(255); } - if (msg_len > consumed) - buffer_consume(&iqueue, msg_len - consumed); + if (msg_len > consumed && + (r = sshbuf_consume(iqueue, msg_len - consumed)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } /* Cleanup handler that logs active handles upon normal exit */ @@ -1443,7 +1505,7 @@ int sftp_server_main(int argc, char **argv, struct passwd *user_pw) { fd_set *rset, *wset; - int i, in, out, max, ch, skipargs = 0, log_stderr = 0; + int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, *homedir = NULL, buf[4*4096]; @@ -1565,8 +1627,10 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) if (out > max) max = out; - buffer_init(&iqueue); - buffer_init(&oqueue); + if ((iqueue = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((oqueue = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); rset = (fd_set *)xmalloc(set_size); @@ -1588,11 +1652,15 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) * the worst-case length packet it can generate, * otherwise apply backpressure by stopping reads. */ - if (buffer_check_alloc(&iqueue, sizeof(buf)) && - buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH)) + if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && + (r = sshbuf_check_reserve(oqueue, + SFTP_MAX_MSG_LENGTH)) == 0) FD_SET(in, rset); + else if (r != SSH_ERR_NO_BUFFER_SPACE) + fatal("%s: sshbuf_check_reserve failed: %s", + __func__, ssh_err(r)); - olen = buffer_len(&oqueue); + olen = sshbuf_len(oqueue); if (olen > 0) FD_SET(out, wset); @@ -1612,18 +1680,20 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) } else if (len < 0) { error("read: %s", strerror(errno)); sftp_server_cleanup_exit(1); - } else { - buffer_append(&iqueue, buf, len); + } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) { + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); } } /* send oqueue to stdout */ if (FD_ISSET(out, wset)) { - len = write(out, buffer_ptr(&oqueue), olen); + len = write(out, sshbuf_ptr(oqueue), olen); if (len < 0) { error("write: %s", strerror(errno)); sftp_server_cleanup_exit(1); - } else { - buffer_consume(&oqueue, len); + } else if ((r = sshbuf_consume(oqueue, len)) != 0) { + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); } } @@ -1632,7 +1702,11 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) * into the output buffer, otherwise stop processing input * and let the output queue drain. */ - if (buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH)) + r = sshbuf_check_reserve(oqueue, SFTP_MAX_MSG_LENGTH); + if (r == 0) process(); + else if (r != SSH_ERR_NO_BUFFER_SPACE) + fatal("%s: sshbuf_check_reserve: %s", + __func__, ssh_err(r)); } } diff --git a/crypto/openssh/sftp.0 b/crypto/openssh/sftp.0 index e37043455836..24fd9916dcd6 100644 --- a/crypto/openssh/sftp.0 +++ b/crypto/openssh/sftp.0 @@ -1,7 +1,7 @@ SFTP(1) General Commands Manual SFTP(1) NAME - sftp - secure file transfer program + sftp M-bM-^@M-^S secure file transfer program SYNOPSIS sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] @@ -58,12 +58,12 @@ DESCRIPTION Batch mode reads a series of commands from an input batchfile instead of stdin. Since it lacks user interaction it should be used in conjunction with non-interactive authentication. A - batchfile of `-' may be used to indicate standard input. sftp + batchfile of M-bM-^@M-^X-M-bM-^@M-^Y may be used to indicate standard input. sftp will abort if any of the following commands fail: get, put, reget, reput, rename, ln, rm, mkdir, chdir, ls, lchdir, chmod, chown, chgrp, lpwd, df, symlink, and lmkdir. Termination on error can be suppressed on a command by command basis by - prefixing the command with a `-' character (for example, -rm + prefixing the command with a M-bM-^@M-^X-M-bM-^@M-^Y character (for example, -rm /tmp/blah*). -C Enables compression (via ssh's -C flag). @@ -125,6 +125,7 @@ DESCRIPTION HashKnownHosts Host HostbasedAuthentication + HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName @@ -153,6 +154,7 @@ DESCRIPTION ServerAliveCountMax StrictHostKeyChecking TCPKeepAlive + UpdateHostKeys UsePrivilegedPort User UserKnownHostsFile @@ -193,7 +195,7 @@ INTERACTIVE COMMANDS those of ftp(1). Commands are case insensitive. Pathnames that contain spaces must be enclosed in quotes. Any special characters contained within pathnames that are recognized by glob(3) must be escaped with - backslashes (`\'). + backslashes (M-bM-^@M-^X\M-bM-^@M-^Y). bye Quit sftp. @@ -220,7 +222,7 @@ INTERACTIVE COMMANDS the capacity information will be displayed using "human-readable" suffixes. The -i flag requests display of inode information in addition to capacity information. This command is only supported - on servers that implement the ``statvfs@openssh.com'' extension. + on servers that implement the M-bM-^@M-^\statvfs@openssh.comM-bM-^@M-^] extension. exit Quit sftp. @@ -279,7 +281,7 @@ INTERACTIVE COMMANDS -1 Produce single columnar output. - -a List files beginning with a dot (`.'). + -a List files beginning with a dot (M-bM-^@M-^X.M-bM-^@M-^Y). -f Do not sort the listing. The default sort order is lexicographical. @@ -378,4 +380,4 @@ SEE ALSO T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. -OpenBSD 5.6 April 22, 2014 OpenBSD 5.6 +OpenBSD 5.7 January 30, 2015 OpenBSD 5.7 diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1 index 7eb9970abcb9..214f0118c0bb 100644 --- a/crypto/openssh/sftp.1 +++ b/crypto/openssh/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.99 2014/04/22 14:16:30 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.101 2015/01/30 11:43:14 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,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: April 22 2014 $ +.Dd $Mdocdate: January 30 2015 $ .Dt SFTP 1 .Os .Sh NAME @@ -215,6 +215,7 @@ For full details of the options listed below, and their possible values, see .It HashKnownHosts .It Host .It HostbasedAuthentication +.It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName @@ -243,6 +244,7 @@ For full details of the options listed below, and their possible values, see .It ServerAliveCountMax .It StrictHostKeyChecking .It TCPKeepAlive +.It UpdateHostKeys .It UsePrivilegedPort .It User .It UserKnownHostsFile diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c index 429c8d89e274..7d8e22cb616b 100644 --- a/crypto/openssh/sftp.c +++ b/crypto/openssh/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.164 2014/07/09 01:45:10 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.170 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -18,6 +18,7 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* MIN MAX */ #include #include #ifdef HAVE_SYS_STAT_H @@ -47,6 +48,7 @@ __RCSID("$FreeBSD$"); #else typedef void EditLine; #endif +#include #include #include #include @@ -64,7 +66,8 @@ typedef void EditLine; #include "misc.h" #include "sftp.h" -#include "buffer.h" +#include "ssherr.h" +#include "sshbuf.h" #include "sftp-common.h" #include "sftp-client.h" @@ -203,7 +206,7 @@ static const struct CMD cmds[] = { { "quit", I_QUIT, NOARGS }, { "reget", I_REGET, REMOTE }, { "rename", I_RENAME, REMOTE }, - { "reput", I_REPUT, LOCAL }, + { "reput", I_REPUT, LOCAL }, { "rm", I_RM, REMOTE }, { "rmdir", I_RMDIR, REMOTE }, { "symlink", I_SYMLINK, REMOTE }, @@ -251,9 +254,9 @@ help(void) "df [-hi] [path] Display statistics for current directory or\n" " filesystem containing 'path'\n" "exit Quit sftp\n" - "get [-Ppr] remote [local] Download file\n" - "reget remote [local] Resume download file\n" - "reput [local] remote Resume upload file\n" + "get [-afPpRr] remote [local] Download file\n" + "reget [-fPpRr] remote [local] Resume download file\n" + "reput [-fPpRr] [local] remote Resume upload file\n" "help Display this help text\n" "lcd path Change local directory to 'path'\n" "lls [ls-options [path]] Display local directory listing\n" @@ -264,7 +267,7 @@ help(void) "lumask umask Set local umask to 'umask'\n" "mkdir path Create remote directory\n" "progress Toggle display of progress meter\n" - "put [-Ppr] local [remote] Upload file\n" + "put [-afPpRr] local [remote] Upload file\n" "pwd Display remote working directory\n" "quit Quit sftp\n" "rename oldpath newpath Rename remote file\n" @@ -1401,7 +1404,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int cmdnum, i; unsigned long n_arg = 0; Attrib a, *aa; - char path_buf[MAXPATHLEN]; + char path_buf[PATH_MAX]; int err = 0; glob_t g; @@ -1520,6 +1523,9 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, err = do_df(conn, path1, hflag, iflag); break; case I_LCHDIR: + tmp = tilde_expand_filename(path1, getuid()); + free(path1); + path1 = tmp; if (chdir(path1) == -1) { error("Couldn't change local directory to " "\"%s\": %s", path1, strerror(errno)); @@ -2082,8 +2088,8 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) free(dir); } - setlinebuf(stdout); - setlinebuf(infile); + setvbuf(stdout, NULL, _IOLBF, 0); + setvbuf(infile, NULL, _IOLBF, 0); interactive = !batchmode && isatty(STDIN_FILENO); err = 0; diff --git a/crypto/openssh/ssh-add.0 b/crypto/openssh/ssh-add.0 index f16165ae54f3..8ee39470a386 100644 --- a/crypto/openssh/ssh-add.0 +++ b/crypto/openssh/ssh-add.0 @@ -1,10 +1,10 @@ SSH-ADD(1) General Commands Manual SSH-ADD(1) NAME - ssh-add - adds private key identities to the authentication agent + ssh-add M-bM-^@M-^S adds private key identities to the authentication agent SYNOPSIS - ssh-add [-cDdkLlXx] [-t life] [file ...] + ssh-add [-cDdkLlXx] [-E fingerprint_hash] [-t life] [file ...] ssh-add -s pkcs11 ssh-add -e pkcs11 @@ -43,6 +43,11 @@ DESCRIPTION certificates to be removed from the agent. If no public key is found at a given path, ssh-add will append .pub and retry. + -E fingerprint_hash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. + -e pkcs11 Remove keys provided by the PKCS#11 shared library pkcs11. @@ -96,7 +101,7 @@ FILES the user. ~/.ssh/id_ed25519 - Contains the protocol version 2 ED25519 authentication identity + Contains the protocol version 2 Ed25519 authentication identity of the user. ~/.ssh/id_rsa @@ -120,4 +125,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.6 December 7, 2013 OpenBSD 5.6 +OpenBSD 5.7 December 21, 2014 OpenBSD 5.7 diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 index 4812448fa93d..926456f0bfe8 100644 --- a/crypto/openssh/ssh-add.1 +++ b/crypto/openssh/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.59 2013/12/07 11:58:46 naddy Exp $ +.\" $OpenBSD: ssh-add.1,v 1.61 2014/12/21 22:27:56 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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: December 7 2013 $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -44,6 +44,7 @@ .Sh SYNOPSIS .Nm ssh-add .Op Fl cDdkLlXx +.Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar .Nm ssh-add @@ -108,6 +109,14 @@ If no public key is found at a given path, will append .Pa .pub and retry. +.It Fl E Ar fingerprint_hash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Fl e Ar pkcs11 Remove keys provided by the PKCS#11 shared library .Ar pkcs11 . @@ -171,7 +180,7 @@ Contains the protocol version 2 DSA authentication identity of the user. .It Pa ~/.ssh/id_ecdsa Contains the protocol version 2 ECDSA authentication identity of the user. .It Pa ~/.ssh/id_ed25519 -Contains the protocol version 2 ED25519 authentication identity of the user. +Contains the protocol version 2 Ed25519 authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .El diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c index 78a3359ade41..98d46d3e5ead 100644 --- a/crypto/openssh/ssh-add.c +++ b/crypto/openssh/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.113 2014/07/09 14:15:56 benno Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.120 2015/02/21 21:46:57 halex Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -39,11 +39,11 @@ #include #include -#include #include #include "openbsd-compat/openssl-compat.h" +#include #include #include #include @@ -51,34 +51,40 @@ #include #include #include +#include #include "xmalloc.h" #include "ssh.h" #include "rsa.h" #include "log.h" -#include "key.h" -#include "buffer.h" +#include "sshkey.h" +#include "sshbuf.h" #include "authfd.h" #include "authfile.h" #include "pathnames.h" #include "misc.h" #include "ssherr.h" +#include "digest.h" /* argv0 */ extern char *__progname; /* Default files to add */ static char *default_files[] = { +#ifdef WITH_OPENSSL _PATH_SSH_CLIENT_ID_RSA, _PATH_SSH_CLIENT_ID_DSA, #ifdef OPENSSL_HAS_ECC _PATH_SSH_CLIENT_ID_ECDSA, #endif +#endif /* WITH_OPENSSL */ _PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_IDENTITY, NULL }; +static int fingerprint_hash = SSH_FP_HASH_DEFAULT; + /* Default lifetime (0 == forever) */ static int lifetime = 0; @@ -98,22 +104,22 @@ clear_pass(void) } static int -delete_file(AuthenticationConnection *ac, const char *filename, int key_only) +delete_file(int agent_fd, const char *filename, int key_only) { - Key *public = NULL, *cert = NULL; + struct sshkey *public, *cert = NULL; char *certpath = NULL, *comment = NULL; - int ret = -1; + int r, ret = -1; - public = key_load_public(filename, &comment); - if (public == NULL) { - printf("Bad key file %s\n", filename); + if ((r = sshkey_load_public(filename, &public, &comment)) != 0) { + printf("Bad key file %s: %s\n", filename, ssh_err(r)); return -1; } - if (ssh_remove_identity(ac, public)) { + if ((r = ssh_remove_identity(agent_fd, public)) == 0) { fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment); ret = 0; } else - fprintf(stderr, "Could not remove identity: %s\n", filename); + fprintf(stderr, "Could not remove identity \"%s\": %s\n", + filename, ssh_err(r)); if (key_only) goto out; @@ -122,24 +128,30 @@ delete_file(AuthenticationConnection *ac, const char *filename, int key_only) free(comment); comment = NULL; xasprintf(&certpath, "%s-cert.pub", filename); - if ((cert = key_load_public(certpath, &comment)) == NULL) + if ((r = sshkey_load_public(certpath, &cert, &comment)) != 0) { + if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) + error("Failed to load certificate \"%s\": %s", + certpath, ssh_err(r)); goto out; - if (!key_equal_public(cert, public)) + } + + if (!sshkey_equal_public(cert, public)) fatal("Certificate %s does not match private key %s", certpath, filename); - if (ssh_remove_identity(ac, cert)) { + if ((r = ssh_remove_identity(agent_fd, cert)) == 0) { fprintf(stderr, "Identity removed: %s (%s)\n", certpath, comment); ret = 0; } else - fprintf(stderr, "Could not remove identity: %s\n", certpath); + fprintf(stderr, "Could not remove identity \"%s\": %s\n", + certpath, ssh_err(r)); out: if (cert != NULL) - key_free(cert); + sshkey_free(cert); if (public != NULL) - key_free(public); + sshkey_free(public); free(certpath); free(comment); @@ -148,14 +160,15 @@ delete_file(AuthenticationConnection *ac, const char *filename, int key_only) /* Send a request to remove all identities. */ static int -delete_all(AuthenticationConnection *ac) +delete_all(int agent_fd) { int ret = -1; - if (ssh_remove_all_identities(ac, 1)) + if (ssh_remove_all_identities(agent_fd, 1) == 0) ret = 0; /* ignore error-code for ssh2 */ - ssh_remove_all_identities(ac, 2); + /* XXX revisit */ + ssh_remove_all_identities(agent_fd, 2); if (ret == 0) fprintf(stderr, "All identities removed.\n"); @@ -166,13 +179,13 @@ delete_all(AuthenticationConnection *ac) } static int -add_file(AuthenticationConnection *ac, const char *filename, int key_only) +add_file(int agent_fd, const char *filename, int key_only) { - Key *private, *cert; + struct sshkey *private, *cert; char *comment = NULL; char msg[1024], *certpath = NULL; - int r, fd, perms_ok, ret = -1; - Buffer keyblob; + int r, fd, ret = -1; + struct sshbuf *keyblob; if (strcmp(filename, "-") == 0) { fd = STDIN_FILENO; @@ -187,62 +200,73 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) * will occur multiple times, so check perms first and bail if wrong. */ if (fd != STDIN_FILENO) { - perms_ok = key_perm_ok(fd, filename); - if (!perms_ok) { + if (sshkey_perm_ok(fd, filename) != 0) { close(fd); return -1; } } - buffer_init(&keyblob); - if (!key_load_file(fd, filename, &keyblob)) { - buffer_free(&keyblob); + if ((keyblob = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshkey_load_file(fd, keyblob)) != 0) { + fprintf(stderr, "Error loading key \"%s\": %s\n", + filename, ssh_err(r)); + sshbuf_free(keyblob); close(fd); return -1; } close(fd); /* At first, try empty passphrase */ - if ((r = sshkey_parse_private_fileblob(&keyblob, "", filename, - &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) - fatal("Cannot parse %s: %s", filename, ssh_err(r)); + if ((r = sshkey_parse_private_fileblob(keyblob, "", filename, + &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + fprintf(stderr, "Error loading key \"%s\": %s\n", + filename, ssh_err(r)); + goto fail_load; + } /* try last */ if (private == NULL && pass != NULL) { - if ((r = sshkey_parse_private_fileblob(&keyblob, pass, filename, + if ((r = sshkey_parse_private_fileblob(keyblob, pass, filename, &private, &comment)) != 0 && - r != SSH_ERR_KEY_WRONG_PASSPHRASE) - fatal("Cannot parse %s: %s", filename, ssh_err(r)); + r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + fprintf(stderr, "Error loading key \"%s\": %s\n", + filename, ssh_err(r)); + goto fail_load; + } } if (comment == NULL) comment = xstrdup(filename); if (private == NULL) { /* clear passphrase since it did not work */ clear_pass(); - snprintf(msg, sizeof msg, "Enter passphrase for %.200s: ", - comment); + snprintf(msg, sizeof msg, "Enter passphrase for %.200s%s: ", + comment, confirm ? " (will confirm each use)" : ""); for (;;) { pass = read_passphrase(msg, RP_ALLOW_STDIN); - if (strcmp(pass, "") == 0) { + if (strcmp(pass, "") == 0) + goto fail_load; + if ((r = sshkey_parse_private_fileblob(keyblob, pass, + filename, &private, NULL)) == 0) + break; + else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + fprintf(stderr, + "Error loading key \"%s\": %s\n", + filename, ssh_err(r)); + fail_load: clear_pass(); free(comment); - buffer_free(&keyblob); + sshbuf_free(keyblob); return -1; } - if ((r = sshkey_parse_private_fileblob(&keyblob, - pass, filename, &private, NULL)) != 0 && - r != SSH_ERR_KEY_WRONG_PASSPHRASE) - fatal("Cannot parse %s: %s", - filename, ssh_err(r)); - if (private != NULL) - break; clear_pass(); snprintf(msg, sizeof msg, - "Bad passphrase, try again for %.200s: ", comment); + "Bad passphrase, try again for %.200s%s: ", comment, + confirm ? " (will confirm each use)" : ""); } } - buffer_free(&keyblob); + sshbuf_free(keyblob); - if (ssh_add_identity_constrained(ac, private, comment, lifetime, - confirm)) { + if ((r = ssh_add_identity_constrained(agent_fd, private, comment, + lifetime, confirm)) == 0) { fprintf(stderr, "Identity added: %s (%s)\n", filename, comment); ret = 0; if (lifetime != 0) @@ -252,7 +276,8 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) fprintf(stderr, "The user must confirm each use of the key\n"); } else { - fprintf(stderr, "Could not add identity: %s\n", filename); + fprintf(stderr, "Could not add identity \"%s\": %s\n", + filename, ssh_err(r)); } /* Skip trying to load the cert if requested */ @@ -261,29 +286,39 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) /* Now try to add the certificate flavour too */ xasprintf(&certpath, "%s-cert.pub", filename); - if ((cert = key_load_public(certpath, NULL)) == NULL) + if ((r = sshkey_load_public(certpath, &cert, NULL)) != 0) { + if (r != SSH_ERR_SYSTEM_ERROR || errno != ENOENT) + error("Failed to load certificate \"%s\": %s", + certpath, ssh_err(r)); goto out; + } - if (!key_equal_public(cert, private)) { + if (!sshkey_equal_public(cert, private)) { error("Certificate %s does not match private key %s", certpath, filename); - key_free(cert); + sshkey_free(cert); goto out; } /* Graft with private bits */ - if (key_to_certified(private, key_cert_is_legacy(cert)) != 0) { - error("%s: key_to_certified failed", __func__); - key_free(cert); + if ((r = sshkey_to_certified(private, + sshkey_cert_is_legacy(cert))) != 0) { + error("%s: sshkey_to_certified: %s", __func__, ssh_err(r)); + sshkey_free(cert); goto out; } - key_cert_copy(cert, private); - key_free(cert); + if ((r = sshkey_cert_copy(cert, private)) != 0) { + error("%s: key_cert_copy: %s", __func__, ssh_err(r)); + sshkey_free(cert); + goto out; + } + sshkey_free(cert); - if (!ssh_add_identity_constrained(ac, private, comment, - lifetime, confirm)) { - error("Certificate %s (%s) add failed", certpath, - private->cert->key_id); + if ((r = ssh_add_identity_constrained(agent_fd, private, comment, + lifetime, confirm)) != 0) { + error("Certificate %s (%s) add failed: %s", certpath, + private->cert->key_id, ssh_err(r)); + goto out; } fprintf(stderr, "Certificate added: %s (%s)\n", certpath, private->cert->key_id); @@ -292,19 +327,18 @@ add_file(AuthenticationConnection *ac, const char *filename, int key_only) if (confirm != 0) fprintf(stderr, "The user must confirm each use of the key\n"); out: - if (certpath != NULL) - free(certpath); + free(certpath); free(comment); - key_free(private); + sshkey_free(private); return ret; } static int -update_card(AuthenticationConnection *ac, int add, const char *id) +update_card(int agent_fd, int add, const char *id) { char *pin = NULL; - int ret = -1; + int r, ret = -1; if (add) { if ((pin = read_passphrase("Enter passphrase for PKCS#11: ", @@ -312,14 +346,14 @@ update_card(AuthenticationConnection *ac, int add, const char *id) return -1; } - if (ssh_update_card(ac, add, id, pin == NULL ? "" : pin, - lifetime, confirm)) { + if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin, + lifetime, confirm)) == 0) { fprintf(stderr, "Card %s: %s\n", add ? "added" : "removed", id); ret = 0; } else { - fprintf(stderr, "Could not %s card: %s\n", - add ? "add" : "remove", id); + fprintf(stderr, "Could not %s card \"%s\": %s\n", + add ? "add" : "remove", id, ssh_err(r)); ret = -1; } free(pin); @@ -327,32 +361,43 @@ update_card(AuthenticationConnection *ac, int add, const char *id) } static int -list_identities(AuthenticationConnection *ac, int do_fp) +list_identities(int agent_fd, int do_fp) { - Key *key; - char *comment, *fp; - int had_identities = 0; - int version; + char *fp; + int version, r, had_identities = 0; + struct ssh_identitylist *idlist; + size_t i; for (version = 1; version <= 2; version++) { - for (key = ssh_get_first_identity(ac, &comment, version); - key != NULL; - key = ssh_get_next_identity(ac, &comment, version)) { + if ((r = ssh_fetch_identitylist(agent_fd, version, + &idlist)) != 0) { + if (r != SSH_ERR_AGENT_NO_IDENTITIES) + fprintf(stderr, "error fetching identities for " + "protocol %d: %s\n", version, ssh_err(r)); + continue; + } + for (i = 0; i < idlist->nkeys; i++) { had_identities = 1; if (do_fp) { - fp = key_fingerprint(key, SSH_FP_MD5, - SSH_FP_HEX); + fp = sshkey_fingerprint(idlist->keys[i], + fingerprint_hash, SSH_FP_DEFAULT); printf("%d %s %s (%s)\n", - key_size(key), fp, comment, key_type(key)); + sshkey_size(idlist->keys[i]), + fp == NULL ? "(null)" : fp, + idlist->comments[i], + sshkey_type(idlist->keys[i])); free(fp); } else { - if (!key_write(key, stdout)) - fprintf(stderr, "key_write failed"); - fprintf(stdout, " %s\n", comment); + if ((r = sshkey_write(idlist->keys[i], + stdout)) != 0) { + fprintf(stderr, "sshkey_write: %s\n", + ssh_err(r)); + continue; + } + fprintf(stdout, " %s\n", idlist->comments[i]); } - key_free(key); - free(comment); } + ssh_free_identitylist(idlist); } if (!had_identities) { printf("The agent has no identities.\n"); @@ -362,10 +407,10 @@ list_identities(AuthenticationConnection *ac, int do_fp) } static int -lock_agent(AuthenticationConnection *ac, int lock) +lock_agent(int agent_fd, int lock) { char prompt[100], *p1, *p2; - int passok = 1, ret = -1; + int r, passok = 1, ret = -1; strlcpy(prompt, "Enter lock password: ", sizeof(prompt)); p1 = read_passphrase(prompt, RP_ALLOW_STDIN); @@ -379,24 +424,28 @@ lock_agent(AuthenticationConnection *ac, int lock) explicit_bzero(p2, strlen(p2)); free(p2); } - if (passok && ssh_lock_agent(ac, lock, p1)) { - fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); - ret = 0; - } else - fprintf(stderr, "Failed to %slock agent.\n", lock ? "" : "un"); + if (passok) { + if ((r = ssh_lock_agent(agent_fd, lock, p1)) == 0) { + fprintf(stderr, "Agent %slocked.\n", lock ? "" : "un"); + ret = 0; + } else { + fprintf(stderr, "Failed to %slock agent: %s\n", + lock ? "" : "un", ssh_err(r)); + } + } explicit_bzero(p1, strlen(p1)); free(p1); return (ret); } static int -do_file(AuthenticationConnection *ac, int deleting, int key_only, char *file) +do_file(int agent_fd, int deleting, int key_only, char *file) { if (deleting) { - if (delete_file(ac, file, key_only) == -1) + if (delete_file(agent_fd, file, key_only) == -1) return -1; } else { - if (add_file(ac, file, key_only) == -1) + if (add_file(agent_fd, file, key_only) == -1) return -1; } return 0; @@ -408,6 +457,7 @@ usage(void) fprintf(stderr, "usage: %s [options] [file ...]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -l List fingerprints of all identities.\n"); + fprintf(stderr, " -E hash Specify hash algorithm used for fingerprints.\n"); fprintf(stderr, " -L List public key parameters of all identities.\n"); fprintf(stderr, " -k Load only keys and not certificates.\n"); fprintf(stderr, " -c Require confirmation to sign using identities\n"); @@ -425,9 +475,10 @@ main(int argc, char **argv) { extern char *optarg; extern int optind; - AuthenticationConnection *ac = NULL; + int agent_fd; char *pkcs11provider = NULL; - int i, ch, deleting = 0, ret = 0, key_only = 0; + int r, i, ch, deleting = 0, ret = 0, key_only = 0; + int xflag = 0, lflag = 0, Dflag = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -435,32 +486,47 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); seed_rng(); +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); +#endif - setlinebuf(stdout); + setvbuf(stdout, NULL, _IOLBF, 0); - /* At first, get a connection to the authentication agent. */ - ac = ssh_get_authentication_connection(); - if (ac == NULL) { - fprintf(stderr, - "Could not open a connection to your authentication agent.\n"); + /* First, get a connection to the authentication agent. */ + switch (r = ssh_get_authentication_socket(&agent_fd)) { + case 0: + break; + case SSH_ERR_AGENT_NOT_PRESENT: + fprintf(stderr, "Could not open a connection to your " + "authentication agent.\n"); + exit(2); + default: + fprintf(stderr, "Error connecting to agent: %s\n", ssh_err(r)); exit(2); } - while ((ch = getopt(argc, argv, "klLcdDxXe:s:t:")) != -1) { + + while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) { switch (ch) { + case 'E': + fingerprint_hash = ssh_digest_alg_by_name(optarg); + if (fingerprint_hash == -1) + fatal("Invalid hash algorithm \"%s\"", optarg); + break; case 'k': key_only = 1; break; case 'l': case 'L': - if (list_identities(ac, ch == 'l' ? 1 : 0) == -1) - ret = 1; - goto done; + if (lflag != 0) + fatal("-%c flag already specified", lflag); + lflag = ch; + break; case 'x': case 'X': - if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1) - ret = 1; - goto done; + if (xflag != 0) + fatal("-%c flag already specified", xflag); + xflag = ch; + break; case 'c': confirm = 1; break; @@ -468,9 +534,8 @@ main(int argc, char **argv) deleting = 1; break; case 'D': - if (delete_all(ac) == -1) - ret = 1; - goto done; + Dflag = 1; + break; case 's': pkcs11provider = optarg; break; @@ -491,15 +556,32 @@ main(int argc, char **argv) goto done; } } + + if ((xflag != 0) + (lflag != 0) + (Dflag != 0) > 1) + fatal("Invalid combination of actions"); + else if (xflag) { + if (lock_agent(agent_fd, xflag == 'x' ? 1 : 0) == -1) + ret = 1; + goto done; + } else if (lflag) { + if (list_identities(agent_fd, lflag == 'l' ? 1 : 0) == -1) + ret = 1; + goto done; + } else if (Dflag) { + if (delete_all(agent_fd) == -1) + ret = 1; + goto done; + } + argc -= optind; argv += optind; if (pkcs11provider != NULL) { - if (update_card(ac, !deleting, pkcs11provider) == -1) + if (update_card(agent_fd, !deleting, pkcs11provider) == -1) ret = 1; goto done; } if (argc == 0) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; struct passwd *pw; struct stat st; int count = 0; @@ -516,7 +598,7 @@ main(int argc, char **argv) default_files[i]); if (stat(buf, &st) < 0) continue; - if (do_file(ac, deleting, key_only, buf) == -1) + if (do_file(agent_fd, deleting, key_only, buf) == -1) ret = 1; else count++; @@ -525,13 +607,14 @@ main(int argc, char **argv) ret = 1; } else { for (i = 0; i < argc; i++) { - if (do_file(ac, deleting, key_only, argv[i]) == -1) + if (do_file(agent_fd, deleting, key_only, + argv[i]) == -1) ret = 1; } } clear_pass(); done: - ssh_close_authentication_connection(ac); + ssh_close_authentication_socket(agent_fd); return ret; } diff --git a/crypto/openssh/ssh-agent.0 b/crypto/openssh/ssh-agent.0 index cac40e048168..30f4eb3bce1d 100644 --- a/crypto/openssh/ssh-agent.0 +++ b/crypto/openssh/ssh-agent.0 @@ -1,15 +1,16 @@ SSH-AGENT(1) General Commands Manual SSH-AGENT(1) NAME - ssh-agent - authentication agent + ssh-agent M-bM-^@M-^S authentication agent SYNOPSIS - ssh-agent [-c | -s] [-d] [-a bind_address] [-t life] [command [arg ...]] + ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash] + [-t life] [command [arg ...]] ssh-agent [-c | -s] -k DESCRIPTION ssh-agent is a program to hold private keys used for public key - authentication (RSA, DSA, ECDSA, ED25519). ssh-agent is usually started + authentication (RSA, DSA, ECDSA, Ed25519). ssh-agent is usually started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent program. Through use of environment variables the agent can be located and @@ -34,6 +35,11 @@ DESCRIPTION -d Debug mode. When this option is specified ssh-agent will not fork. + -E fingerprint_hash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. + -k Kill the current agent (given by the SSH_AGENT_PID environment variable). @@ -100,4 +106,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.6 April 16, 2014 OpenBSD 5.6 +OpenBSD 5.7 December 21, 2014 OpenBSD 5.7 diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 index 1ef66f26a4a2..ce1f40e8948e 100644 --- a/crypto/openssh/ssh-agent.1 +++ b/crypto/openssh/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.55 2014/04/16 23:28:12 djm Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.57 2014/12/21 22:27:56 djm Exp $ .\" $FreeBSD$ .\" .\" Author: Tatu Ylonen @@ -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: April 16 2014 $ +.Dd $Mdocdate: December 21 2014 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -46,6 +46,7 @@ .Op Fl c | s .Op Fl dx .Op Fl a Ar bind_address +.Op Fl E Ar fingerprint_hash .Op Fl t Ar life .Op Ar command Op Ar arg ... .Nm ssh-agent @@ -54,7 +55,7 @@ .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication -(RSA, DSA, ECDSA, ED25519). +(RSA, DSA, ECDSA, Ed25519). .Nm is usually started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent @@ -97,6 +98,14 @@ Debug mode. When this option is specified .Nm will not fork. +.It Fl E Ar fingerprint_hash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Fl k Kill the current agent (given by the .Ev SSH_AGENT_PID diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index f9c5475ae24c..92315cc27d82 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.190 2014/07/25 21:22:03 dtucker Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.199 2015/03/04 21:12:59 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -37,6 +37,7 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* MIN MAX */ #include #include #include @@ -57,6 +58,7 @@ __RCSID("$FreeBSD$"); #include #include +#include #ifdef HAVE_PATHS_H # include #endif @@ -68,16 +70,20 @@ __RCSID("$FreeBSD$"); #include #include +#include "key.h" /* XXX for typedef */ +#include "buffer.h" /* XXX for typedef */ + #include "xmalloc.h" #include "ssh.h" #include "rsa.h" -#include "buffer.h" -#include "key.h" +#include "sshbuf.h" +#include "sshkey.h" #include "authfd.h" #include "compat.h" #include "log.h" #include "misc.h" #include "digest.h" +#include "ssherr.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" @@ -96,9 +102,9 @@ typedef enum { typedef struct { int fd; sock_type type; - Buffer input; - Buffer output; - Buffer request; + struct sshbuf *input; + struct sshbuf *output; + struct sshbuf *request; } SocketEntry; u_int sockets_alloc = 0; @@ -106,7 +112,7 @@ SocketEntry *sockets = NULL; typedef struct identity { TAILQ_ENTRY(identity) next; - Key *key; + struct sshkey *key; char *comment; char *provider; time_t death; @@ -131,8 +137,8 @@ time_t parent_alive_interval = 0; pid_t cleanup_pid = 0; /* pathname and directory for AUTH_SOCKET */ -char socket_name[MAXPATHLEN]; -char socket_dir[MAXPATHLEN]; +char socket_name[PATH_MAX]; +char socket_dir[PATH_MAX]; /* locking */ int locked = 0; @@ -143,6 +149,8 @@ extern char *__progname; /* Default lifetime in seconds (0 == forever) */ static long lifetime = 0; +static int fingerprint_hash = SSH_FP_HASH_DEFAULT; + /* * Client connection count; incremented in new_socket() and decremented in * close_socket(). When it reaches 0, ssh-agent will exit. Since it is @@ -166,9 +174,9 @@ close_socket(SocketEntry *e) close(e->fd); e->fd = -1; e->type = AUTH_UNUSED; - buffer_free(&e->input); - buffer_free(&e->output); - buffer_free(&e->request); + sshbuf_free(e->input); + sshbuf_free(e->output); + sshbuf_free(e->request); if (last) cleanup_exit(0); } @@ -196,7 +204,7 @@ idtab_lookup(int version) static void free_identity(Identity *id) { - key_free(id->key); + sshkey_free(id->key); free(id->provider); free(id->comment); free(id); @@ -204,13 +212,13 @@ free_identity(Identity *id) /* return matching private key for given public key */ static Identity * -lookup_identity(Key *key, int version) +lookup_identity(struct sshkey *key, int version) { Identity *id; Idtab *tab = idtab_lookup(version); TAILQ_FOREACH(id, &tab->idlist, next) { - if (key_equal(key, id->key)) + if (sshkey_equal(key, id->key)) return (id); } return (NULL); @@ -223,8 +231,9 @@ confirm_key(Identity *id) char *p; int ret = -1; - p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); - if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", + p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); + if (p != NULL && + ask_permission("Allow use of key %s?\nKey fingerprint %s.", id->comment, p)) ret = 0; free(p); @@ -232,37 +241,65 @@ confirm_key(Identity *id) return (ret); } +static void +send_status(SocketEntry *e, int success) +{ + int r; + + if ((r = sshbuf_put_u32(e->output, 1)) != 0 || + (r = sshbuf_put_u8(e->output, success ? + SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); +} + /* send list of supported public keys to 'client' */ static void process_request_identities(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); Identity *id; - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); - buffer_put_char(&msg, (version == 1) ? - SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); - buffer_put_int(&msg, tab->nentries); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, (version == 1) ? + SSH_AGENT_RSA_IDENTITIES_ANSWER : + SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || + (r = sshbuf_put_u32(msg, tab->nentries)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); TAILQ_FOREACH(id, &tab->idlist, next) { if (id->key->type == KEY_RSA1) { #ifdef WITH_SSH1 - buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); - buffer_put_bignum(&msg, id->key->rsa->e); - buffer_put_bignum(&msg, id->key->rsa->n); + if ((r = sshbuf_put_u32(msg, + BN_num_bits(id->key->rsa->n))) != 0 || + (r = sshbuf_put_bignum1(msg, + id->key->rsa->e)) != 0 || + (r = sshbuf_put_bignum1(msg, + id->key->rsa->n)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); #endif } else { u_char *blob; - u_int blen; - key_to_blob(id->key, &blob, &blen); - buffer_put_string(&msg, blob, blen); + size_t blen; + + if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) { + error("%s: sshkey_to_blob: %s", __func__, + ssh_err(r)); + continue; + } + if ((r = sshbuf_put_string(msg, blob, blen)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); free(blob); } - buffer_put_cstring(&msg, id->comment); + if ((r = sshbuf_put_cstring(msg, id->comment)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } - buffer_put_int(&e->output, buffer_len(&msg)); - buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); - buffer_free(&msg); + if ((r = sshbuf_put_stringb(e->output, msg)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_free(msg); } #ifdef WITH_SSH1 @@ -274,40 +311,48 @@ process_authentication_challenge1(SocketEntry *e) u_int response_type; BIGNUM *challenge; Identity *id; - int i, len; - Buffer msg; + int r, len; + struct sshbuf *msg; struct ssh_digest_ctx *md; - Key *key; + struct sshkey *key; - buffer_init(&msg); - key = key_new(KEY_RSA1); + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((key = sshkey_new(KEY_RSA1)) == NULL) + fatal("%s: sshkey_new failed", __func__); if ((challenge = BN_new()) == NULL) - fatal("process_authentication_challenge1: BN_new failed"); + fatal("%s: BN_new failed", __func__); - (void) buffer_get_int(&e->request); /* ignored */ - buffer_get_bignum(&e->request, key->rsa->e); - buffer_get_bignum(&e->request, key->rsa->n); - buffer_get_bignum(&e->request, challenge); + if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ + (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || + (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || + (r = sshbuf_get_bignum1(e->request, challenge))) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* Only protocol 1.1 is supported */ - if (buffer_len(&e->request) == 0) + if (sshbuf_len(e->request) == 0) goto failure; - buffer_get(&e->request, session_id, 16); - response_type = buffer_get_int(&e->request); + if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 || + (r = sshbuf_get_u32(e->request, &response_type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (response_type != 1) goto failure; id = lookup_identity(key, 1); if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { - Key *private = id->key; + struct sshkey *private = id->key; /* Decrypt the challenge using the private key. */ - if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0) - goto failure; + if ((r = rsa_private_decrypt(challenge, challenge, + private->rsa) != 0)) { + fatal("%s: rsa_public_encrypt: %s", __func__, + ssh_err(r)); + goto failure; /* XXX ? */ + } - /* The response is MD5 of decrypted challenge plus session id. */ + /* The response is MD5 of decrypted challenge plus session id */ len = BN_num_bytes(challenge); if (len <= 0 || len > 32) { - logit("process_authentication_challenge: bad challenge length %d", len); + logit("%s: bad challenge length %d", __func__, len); goto failure; } memset(buf, 0, 32); @@ -320,21 +365,22 @@ process_authentication_challenge1(SocketEntry *e) ssh_digest_free(md); /* Send the response. */ - buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); - for (i = 0; i < 16; i++) - buffer_put_char(&msg, mdbuf[i]); + if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 || + (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); goto send; } -failure: + failure: /* Unknown identity or protocol error. Send failure. */ - buffer_put_char(&msg, SSH_AGENT_FAILURE); -send: - buffer_put_int(&e->output, buffer_len(&msg)); - buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); - key_free(key); + if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + send: + if ((r = sshbuf_put_stringb(e->output, msg)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshkey_free(key); BN_clear_free(challenge); - buffer_free(&msg); + sshbuf_free(msg); } #endif @@ -343,54 +389,65 @@ static void process_sign_request2(SocketEntry *e) { u_char *blob, *data, *signature = NULL; - u_int blen, dlen, slen = 0; - extern int datafellows; - int odatafellows; - int ok = -1, flags; - Buffer msg; - Key *key; + size_t blen, dlen, slen = 0; + u_int compat = 0, flags; + int r, ok = -1; + struct sshbuf *msg; + struct sshkey *key; + struct identity *id; - datafellows = 0; - - blob = buffer_get_string(&e->request, &blen); - data = buffer_get_string(&e->request, &dlen); - - flags = buffer_get_int(&e->request); - odatafellows = datafellows; + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 || + (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 || + (r = sshbuf_get_u32(e->request, &flags)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (flags & SSH_AGENT_OLD_SIGNATURE) - datafellows = SSH_BUG_SIGBLOB; - - key = key_from_blob(blob, blen); - if (key != NULL) { - Identity *id = lookup_identity(key, 2); - if (id != NULL && (!id->confirm || confirm_key(id) == 0)) - ok = key_sign(id->key, &signature, &slen, data, dlen); - key_free(key); + compat = SSH_BUG_SIGBLOB; + if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { + error("%s: cannot parse key blob: %s", __func__, ssh_err(ok)); + goto send; } - buffer_init(&msg); + if ((id = lookup_identity(key, 2)) == NULL) { + verbose("%s: %s key not found", __func__, sshkey_type(key)); + goto send; + } + if (id->confirm && confirm_key(id) != 0) { + verbose("%s: user refused key", __func__); + goto send; + } + if ((r = sshkey_sign(id->key, &signature, &slen, + data, dlen, compat)) != 0) { + error("%s: sshkey_sign: %s", __func__, ssh_err(ok)); + goto send; + } + /* Success */ + ok = 0; + send: + sshkey_free(key); if (ok == 0) { - buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); - buffer_put_string(&msg, signature, slen); - } else { - buffer_put_char(&msg, SSH_AGENT_FAILURE); - } - buffer_put_int(&e->output, buffer_len(&msg)); - buffer_append(&e->output, buffer_ptr(&msg), - buffer_len(&msg)); - buffer_free(&msg); + if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || + (r = sshbuf_put_string(msg, signature, slen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + if ((r = sshbuf_put_stringb(e->output, msg)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + sshbuf_free(msg); free(data); free(blob); free(signature); - datafellows = odatafellows; } /* shared */ static void process_remove_identity(SocketEntry *e, int version) { - u_int blen; - int success = 0; - Key *key = NULL; + size_t blen; + int r, success = 0; + struct sshkey *key = NULL; u_char *blob; #ifdef WITH_SSH1 u_int bits; @@ -399,19 +456,27 @@ process_remove_identity(SocketEntry *e, int version) switch (version) { #ifdef WITH_SSH1 case 1: - key = key_new(KEY_RSA1); - bits = buffer_get_int(&e->request); - buffer_get_bignum(&e->request, key->rsa->e); - buffer_get_bignum(&e->request, key->rsa->n); + if ((key = sshkey_new(KEY_RSA1)) == NULL) { + error("%s: sshkey_new failed", __func__); + return; + } + if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || + (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || + (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (bits != key_size(key)) - logit("Warning: identity keysize mismatch: actual %u, announced %u", - key_size(key), bits); + if (bits != sshkey_size(key)) + logit("Warning: identity keysize mismatch: " + "actual %u, announced %u", + sshkey_size(key), bits); break; #endif /* WITH_SSH1 */ case 2: - blob = buffer_get_string(&e->request, &blen); - key = key_from_blob(blob, blen); + if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if ((r = sshkey_from_blob(blob, blen, &key)) != 0) + error("%s: sshkey_from_blob failed: %s", + __func__, ssh_err(r)); free(blob); break; } @@ -435,11 +500,9 @@ process_remove_identity(SocketEntry *e, int version) tab->nentries--; success = 1; } - key_free(key); + sshkey_free(key); } - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); + send_status(e, success); } static void @@ -459,8 +522,7 @@ process_remove_all_identities(SocketEntry *e, int version) tab->nentries = 0; /* Send success. */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_SUCCESS); + send_status(e, 1); } /* removes expired keys and returns number of seconds until the next expiry */ @@ -494,71 +556,106 @@ reaper(void) return (deadline - now); } +/* + * XXX this and the corresponding serialisation function probably belongs + * in key.c + */ +#ifdef WITH_SSH1 +static int +agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp) +{ + struct sshkey *k = NULL; + int r = SSH_ERR_INTERNAL_ERROR; + + *kp = NULL; + if ((k = sshkey_new_private(KEY_RSA1)) == NULL) + return SSH_ERR_ALLOC_FAIL; + + if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ + (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || + (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || + (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || + (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || + /* SSH1 and SSL have p and q swapped */ + (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ + (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ + goto out; + + /* Generate additional parameters */ + if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) + goto out; + /* enable blinding */ + if (RSA_blinding_on(k->rsa, NULL) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + + r = 0; /* success */ + out: + if (r == 0) + *kp = k; + else + sshkey_free(k); + return r; +} +#endif /* WITH_SSH1 */ + static void process_add_identity(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); Identity *id; - int type, success = 0, confirm = 0; - char *comment; + int success = 0, confirm = 0; + u_int seconds; + char *comment = NULL; time_t death = 0; - Key *k = NULL; + struct sshkey *k = NULL; + u_char ctype; + int r = SSH_ERR_INTERNAL_ERROR; switch (version) { #ifdef WITH_SSH1 case 1: - k = key_new_private(KEY_RSA1); - (void) buffer_get_int(&e->request); /* ignored */ - buffer_get_bignum(&e->request, k->rsa->n); - buffer_get_bignum(&e->request, k->rsa->e); - buffer_get_bignum(&e->request, k->rsa->d); - buffer_get_bignum(&e->request, k->rsa->iqmp); - - /* SSH and SSL have p and q swapped */ - buffer_get_bignum(&e->request, k->rsa->q); /* p */ - buffer_get_bignum(&e->request, k->rsa->p); /* q */ - - /* Generate additional parameters */ - if (rsa_generate_additional_parameters(k->rsa) != 0) - fatal("%s: rsa_generate_additional_parameters " - "error", __func__); - - /* enable blinding */ - if (RSA_blinding_on(k->rsa, NULL) != 1) { - error("process_add_identity: RSA_blinding_on failed"); - key_free(k); - goto send; - } + r = agent_decode_rsa1(e->request, &k); break; #endif /* WITH_SSH1 */ case 2: - k = key_private_deserialize(&e->request); - if (k == NULL) { - buffer_clear(&e->request); - goto send; - } + r = sshkey_private_deserialize(e->request, &k); break; } - if (k == NULL) - goto send; - comment = buffer_get_string(&e->request, NULL); + if (r != 0 || k == NULL || + (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { + error("%s: decode private key: %s", __func__, ssh_err(r)); + goto err; + } - while (buffer_len(&e->request)) { - switch ((type = buffer_get_char(&e->request))) { + while (sshbuf_len(e->request)) { + if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + goto err; + } + switch (ctype) { case SSH_AGENT_CONSTRAIN_LIFETIME: - death = monotime() + buffer_get_int(&e->request); + if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) { + error("%s: bad lifetime constraint: %s", + __func__, ssh_err(r)); + goto err; + } + death = monotime() + seconds; break; case SSH_AGENT_CONSTRAIN_CONFIRM: confirm = 1; break; default: - error("process_add_identity: " - "Unknown constraint type %d", type); + error("%s: Unknown constraint %d", __func__, ctype); + err: + sshbuf_reset(e->request); free(comment); - key_free(k); + sshkey_free(k); goto send; } } + success = 1; if (lifetime && !death) death = monotime() + lifetime; @@ -569,26 +666,25 @@ process_add_identity(SocketEntry *e, int version) /* Increment the number of identities. */ tab->nentries++; } else { - key_free(k); + sshkey_free(k); free(id->comment); } id->comment = comment; id->death = death; id->confirm = confirm; send: - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); + send_status(e, success); } /* XXX todo: encrypt sensitive data with passphrase */ static void process_lock_agent(SocketEntry *e, int lock) { - int success = 0; + int r, success = 0; char *passwd; - passwd = buffer_get_string(&e->request, NULL); + if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { locked = 0; explicit_bzero(lock_passwd, strlen(lock_passwd)); @@ -602,25 +698,25 @@ process_lock_agent(SocketEntry *e, int lock) } explicit_bzero(passwd, strlen(passwd)); free(passwd); - - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); + send_status(e, success); } static void no_identities(SocketEntry *e, u_int type) { - Buffer msg; + struct sshbuf *msg; + int r; - buffer_init(&msg); - buffer_put_char(&msg, + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_u8(msg, (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? - SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); - buffer_put_int(&msg, 0); - buffer_put_int(&e->output, buffer_len(&msg)); - buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); - buffer_free(&msg); + SSH_AGENT_RSA_IDENTITIES_ANSWER : + SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || + (r = sshbuf_put_u32(msg, 0)) != 0 || + (r = sshbuf_put_stringb(e->output, msg)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_free(msg); } #ifdef ENABLE_PKCS11 @@ -628,19 +724,27 @@ static void process_add_smartcard_key(SocketEntry *e) { char *provider = NULL, *pin; - int i, type, version, count = 0, success = 0, confirm = 0; + int r, i, version, count = 0, success = 0, confirm = 0; + u_int seconds; time_t death = 0; - Key **keys = NULL, *k; + u_char type; + struct sshkey **keys = NULL, *k; Identity *id; Idtab *tab; - provider = buffer_get_string(&e->request, NULL); - pin = buffer_get_string(&e->request, NULL); + if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || + (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - while (buffer_len(&e->request)) { - switch ((type = buffer_get_char(&e->request))) { + while (sshbuf_len(e->request)) { + if ((r = sshbuf_get_u8(e->request, &type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + switch (type) { case SSH_AGENT_CONSTRAIN_LIFETIME: - death = monotime() + buffer_get_int(&e->request); + if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + death = monotime() + seconds; break; case SSH_AGENT_CONSTRAIN_CONFIRM: confirm = 1; @@ -670,7 +774,7 @@ process_add_smartcard_key(SocketEntry *e) tab->nentries++; success = 1; } else { - key_free(k); + sshkey_free(k); } keys[i] = NULL; } @@ -678,21 +782,20 @@ process_add_smartcard_key(SocketEntry *e) free(pin); free(provider); free(keys); - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); + send_status(e, success); } static void process_remove_smartcard_key(SocketEntry *e) { char *provider = NULL, *pin = NULL; - int version, success = 0; + int r, version, success = 0; Identity *id, *nxt; Idtab *tab; - provider = buffer_get_string(&e->request, NULL); - pin = buffer_get_string(&e->request, NULL); + if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || + (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); free(pin); for (version = 1; version < 3; version++) { @@ -715,9 +818,7 @@ process_remove_smartcard_key(SocketEntry *e) error("process_remove_smartcard_key:" " pkcs11_del_provider failed"); free(provider); - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, - success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); + send_status(e, success); } #endif /* ENABLE_PKCS11 */ @@ -726,30 +827,31 @@ process_remove_smartcard_key(SocketEntry *e) static void process_message(SocketEntry *e) { - u_int msg_len, type; - u_char *cp; + u_int msg_len; + u_char type; + const u_char *cp; + int r; - if (buffer_len(&e->input) < 5) + if (sshbuf_len(e->input) < 5) return; /* Incomplete message. */ - cp = buffer_ptr(&e->input); - msg_len = get_u32(cp); + cp = sshbuf_ptr(e->input); + msg_len = PEEK_U32(cp); if (msg_len > 256 * 1024) { close_socket(e); return; } - if (buffer_len(&e->input) < msg_len + 4) + if (sshbuf_len(e->input) < msg_len + 4) return; /* move the current input to e->request */ - buffer_consume(&e->input, 4); - buffer_clear(&e->request); - buffer_append(&e->request, buffer_ptr(&e->input), msg_len); - buffer_consume(&e->input, msg_len); - type = buffer_get_char(&e->request); + sshbuf_reset(e->request); + if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 || + (r = sshbuf_get_u8(e->request, &type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* check wheter agent is locked */ if (locked && type != SSH_AGENTC_UNLOCK) { - buffer_clear(&e->request); + sshbuf_reset(e->request); switch (type) { case SSH_AGENTC_REQUEST_RSA_IDENTITIES: case SSH2_AGENTC_REQUEST_IDENTITIES: @@ -758,8 +860,7 @@ process_message(SocketEntry *e) break; default: /* send a fail message for all other request types */ - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); + send_status(e, 0); } return; } @@ -785,10 +886,10 @@ process_message(SocketEntry *e) case SSH_AGENTC_REMOVE_RSA_IDENTITY: process_remove_identity(e, 1); break; - case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: - process_remove_all_identities(e, 1); - break; #endif + case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: + process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */ + break; /* ssh2 */ case SSH2_AGENTC_SIGN_REQUEST: process_sign_request2(e); @@ -818,9 +919,8 @@ process_message(SocketEntry *e) default: /* Unknown message. Respond with failure. */ error("Unknown message %d", type); - buffer_clear(&e->request); - buffer_put_int(&e->output, 1); - buffer_put_char(&e->output, SSH_AGENT_FAILURE); + sshbuf_reset(e->request); + send_status(e, 0); break; } } @@ -842,9 +942,12 @@ new_socket(sock_type type, int fd) for (i = 0; i < sockets_alloc; i++) if (sockets[i].type == AUTH_UNUSED) { sockets[i].fd = fd; - buffer_init(&sockets[i].input); - buffer_init(&sockets[i].output); - buffer_init(&sockets[i].request); + if ((sockets[i].input = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((sockets[i].output = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((sockets[i].request = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); sockets[i].type = type; return; } @@ -855,9 +958,12 @@ new_socket(sock_type type, int fd) sockets[i].type = AUTH_UNUSED; sockets_alloc = new_alloc; sockets[old_alloc].fd = fd; - buffer_init(&sockets[old_alloc].input); - buffer_init(&sockets[old_alloc].output); - buffer_init(&sockets[old_alloc].request); + if ((sockets[old_alloc].input = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((sockets[old_alloc].output = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((sockets[old_alloc].request = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); sockets[old_alloc].type = type; } @@ -903,7 +1009,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, case AUTH_SOCKET: case AUTH_CONNECTION: FD_SET(sockets[i].fd, *fdrp); - if (buffer_len(&sockets[i].output) > 0) + if (sshbuf_len(sockets[i].output) > 0) FD_SET(sockets[i].fd, *fdwp); break; default: @@ -930,7 +1036,7 @@ after_select(fd_set *readset, fd_set *writeset) struct sockaddr_un sunaddr; socklen_t slen; char buf[1024]; - int len, sock; + int len, sock, r; u_int i, orig_alloc; uid_t euid; gid_t egid; @@ -966,11 +1072,11 @@ after_select(fd_set *readset, fd_set *writeset) } break; case AUTH_CONNECTION: - if (buffer_len(&sockets[i].output) > 0 && + if (sshbuf_len(sockets[i].output) > 0 && FD_ISSET(sockets[i].fd, writeset)) { len = write(sockets[i].fd, - buffer_ptr(&sockets[i].output), - buffer_len(&sockets[i].output)); + sshbuf_ptr(sockets[i].output), + sshbuf_len(sockets[i].output)); if (len == -1 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) @@ -979,7 +1085,10 @@ after_select(fd_set *readset, fd_set *writeset) close_socket(&sockets[i]); break; } - buffer_consume(&sockets[i].output, len); + if ((r = sshbuf_consume(sockets[i].output, + len)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); } if (FD_ISSET(sockets[i].fd, readset)) { len = read(sockets[i].fd, buf, sizeof(buf)); @@ -991,7 +1100,10 @@ after_select(fd_set *readset, fd_set *writeset) close_socket(&sockets[i]); break; } - buffer_append(&sockets[i].input, buf, len); + if ((r = sshbuf_put(sockets[i].input, + buf, len)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); explicit_bzero(buf, sizeof(buf)); process_message(&sockets[i]); } @@ -1049,8 +1161,8 @@ static void usage(void) { fprintf(stderr, - "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n" - " [command [arg ...]]\n" + "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash]\n" + " [-t life] [command [arg ...]]\n" " ssh-agent [-c | -s] -k\n"); fprintf(stderr, " -x Exit when the last client disconnects.\n"); exit(1); @@ -1095,8 +1207,13 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); seed_rng(); - while ((ch = getopt(ac, av, "cdksa:t:x")) != -1) { + while ((ch = getopt(ac, av, "cdksE:a:t:x")) != -1) { switch (ch) { + case 'E': + fingerprint_hash = ssh_digest_alg_by_name(optarg); + if (fingerprint_hash == -1) + fatal("Invalid hash algorithm \"%s\"", optarg); + break; case 'c': if (s_flag) usage(); diff --git a/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c index 9643d90d87ea..8ed19d84977f 100644 --- a/crypto/openssh/ssh-dss.c +++ b/crypto/openssh/ssh-dss.c @@ -25,6 +25,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -217,3 +219,4 @@ ssh_dss_verify(const struct sshkey *key, } return ret; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/ssh-ecdsa.c b/crypto/openssh/ssh-ecdsa.c index 1119db04521e..2c76f8b43793 100644 --- a/crypto/openssh/ssh-ecdsa.c +++ b/crypto/openssh/ssh-ecdsa.c @@ -26,7 +26,7 @@ #include "includes.h" -#ifdef OPENSSL_HAS_ECC +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include @@ -189,4 +189,4 @@ ssh_ecdsa_verify(const struct sshkey *key, return ret; } -#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ diff --git a/crypto/openssh/ssh-ed25519.c b/crypto/openssh/ssh-ed25519.c index cb87d47909c5..b159ff5ee0ba 100644 --- a/crypto/openssh/ssh-ed25519.c +++ b/crypto/openssh/ssh-ed25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519.c,v 1.4 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-ed25519.c,v 1.6 2015/01/15 21:38:50 markus Exp $ */ /* * Copyright (c) 2013 Markus Friedl * @@ -25,9 +25,8 @@ #include #include -#include "xmalloc.h" #include "log.h" -#include "buffer.h" +#include "sshbuf.h" #define SSHKEY_INTERNAL #include "sshkey.h" #include "ssherr.h" @@ -128,11 +127,13 @@ ssh_ed25519_verify(const struct sshkey *key, r = SSH_ERR_INVALID_FORMAT; goto out; } - if (datalen >= SIZE_MAX - len) - return SSH_ERR_INVALID_ARGUMENT; + if (datalen >= SIZE_MAX - len) { + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } smlen = len + datalen; mlen = smlen; - if ((sm = malloc(smlen)) == NULL || (m = xmalloc(mlen)) == NULL) { + if ((sm = malloc(smlen)) == NULL || (m = malloc(mlen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -163,4 +164,3 @@ ssh_ed25519_verify(const struct sshkey *key, free(ktype); return r; } - diff --git a/crypto/openssh/ssh-keygen.0 b/crypto/openssh/ssh-keygen.0 index 648f3017f647..784ad032f601 100644 --- a/crypto/openssh/ssh-keygen.0 +++ b/crypto/openssh/ssh-keygen.0 @@ -1,7 +1,7 @@ SSH-KEYGEN(1) General Commands Manual SSH-KEYGEN(1) NAME - ssh-keygen - authentication key generation, management and conversion + ssh-keygen M-bM-^@M-^S authentication key generation, management and conversion SYNOPSIS ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa | rsa1] @@ -11,7 +11,7 @@ SYNOPSIS ssh-keygen -e [-m key_format] [-f input_keyfile] ssh-keygen -y [-f input_keyfile] ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile] - ssh-keygen -l [-f input_keyfile] + ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile] ssh-keygen -B [-f input_keyfile] ssh-keygen -D pkcs11 ssh-keygen -F hostname [-f known_hosts_file] [-l] @@ -32,7 +32,7 @@ SYNOPSIS DESCRIPTION ssh-keygen generates, manages and converts authentication keys for ssh(1). ssh-keygen can create RSA keys for use by SSH protocol version 1 - and DSA, ECDSA, ED25519 or RSA keys for use by SSH protocol version 2. + and DSA, ECDSA, Ed25519 or RSA 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 for use in SSH protocol 2 connections. @@ -52,7 +52,7 @@ DESCRIPTION Normally this program generates the key and asks for a file in which to store the private key. The public key is stored in a file with the same - name but ``.pub'' appended. The program also asks for a passphrase. The + name but M-bM-^@M-^\.pubM-bM-^@M-^] appended. The program also asks for a passphrase. The passphrase may be empty to indicate no passphrase (host keys must have an empty passphrase), or it may be a string of arbitrary length. A passphrase is similar to a password, except it can be a phrase with a @@ -71,7 +71,7 @@ DESCRIPTION For RSA1 keys, there is also a comment field in the key file that is only for convenience to the user to help identify the key. The comment can tell what the key is for, or whatever is useful. The comment is - initialized to ``user@host'' when the key is created, but can be changed + initialized to M-bM-^@M-^\user@hostM-bM-^@M-^] when the key is created, but can be changed using the -c option. After a key is generated, instructions below detail where the keys should @@ -107,7 +107,7 @@ DESCRIPTION the -b flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will - fail. ED25519 keys have a fixed length and the -b flag will be + fail. Ed25519 keys have a fixed length and the -b flag will be ignored. -C comment @@ -124,9 +124,14 @@ DESCRIPTION indicates that a CA key resides in a PKCS#11 token (see the CERTIFICATES section for details). + -E fingerprint_hash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. + -e This option will read a private or public OpenSSH key file and print to stdout the key in one of the formats specified by the -m - option. The default export format is ``RFC4716''. This option + option. The default export format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. This option allows exporting OpenSSH keys for use by other programs, including several commercial SSH implementations. @@ -166,7 +171,7 @@ DESCRIPTION in the format specified by the -m option and print an OpenSSH compatible private (or public) key to stdout. This option allows importing keys from other software, including several commercial - SSH implementations. The default import format is ``RFC4716''. + SSH implementations. The default import format is M-bM-^@M-^\RFC4716M-bM-^@M-^]. -J num_lines Exit after screening the specified number of lines while @@ -203,10 +208,10 @@ DESCRIPTION -m key_format Specify a key format for the -i (import) or -e (export) - conversion options. The supported key formats are: ``RFC4716'' - (RFC 4716/SSH2 public or private key), ``PKCS8'' (PEM PKCS8 - public key) or ``PEM'' (PEM public key). The default conversion - format is ``RFC4716''. + conversion options. The supported key formats are: M-bM-^@M-^\RFC4716M-bM-^@M-^] + (RFC 4716/SSH2 public or private key), M-bM-^@M-^\PKCS8M-bM-^@M-^] (PEM PKCS8 public + key) or M-bM-^@M-^\PEMM-bM-^@M-^] (PEM public key). The default conversion format is + M-bM-^@M-^\RFC4716M-bM-^@M-^]. -N new_passphrase Provides the new passphrase. @@ -315,8 +320,8 @@ DESCRIPTION -t dsa | ecdsa | ed25519 | rsa | rsa1 Specifies the type of key to create. The possible values are - ``rsa1'' for protocol version 1 and ``dsa'', ``ecdsa'', - ``ed25519'', or ``rsa'' for protocol version 2. + M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or + M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. -u Update a KRL. When specified with -k, keys listed via the command line are added to the existing KRL rather than a new KRL @@ -335,12 +340,11 @@ DESCRIPTION as a YYYYMMDD date, a YYYYMMDDHHMMSS time or a relative time starting with a plus character. - For example: ``+52w1d'' (valid from now to 52 weeks and one day - from now), ``-4w:+4w'' (valid from four weeks ago to four weeks - from now), ``20100101123000:20110101123000'' (valid from 12:30 - PM, January 1st, 2010 to 12:30 PM, January 1st, 2011), - ``-1d:20110101'' (valid from yesterday to midnight, January 1st, - 2011). + For example: M-bM-^@M-^\+52w1dM-bM-^@M-^] (valid from now to 52 weeks and one day + from now), M-bM-^@M-^\-4w:+4wM-bM-^@M-^] (valid from four weeks ago to four weeks + from now), M-bM-^@M-^\20100101123000:20110101123000M-bM-^@M-^] (valid from 12:30 PM, + January 1st, 2010 to 12:30 PM, January 1st, 2011), M-bM-^@M-^\-1d:20110101M-bM-^@M-^] + (valid from yesterday to midnight, January 1st, 2011). -v Verbose mode. Causes ssh-keygen to print debugging messages about its progress. This is helpful for debugging moduli @@ -524,7 +528,7 @@ FILES ~/.ssh/id_ecdsa ~/.ssh/id_ed25519 ~/.ssh/id_rsa - Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA + Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be used @@ -537,7 +541,7 @@ FILES ~/.ssh/id_ecdsa.pub ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub - Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA public + Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public key for authentication. The contents of this file should be added to ~/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no @@ -559,4 +563,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.6 March 31, 2014 OpenBSD 5.6 +OpenBSD 5.7 February 24, 2015 OpenBSD 5.7 diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1 index 723a0162e9aa..9b93666c9e44 100644 --- a/crypto/openssh/ssh-keygen.1 +++ b/crypto/openssh/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.122 2014/03/31 13:39:34 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.125 2015/02/24 15:24:05 naddy Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , 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: March 31 2014 $ +.Dd $Mdocdate: February 24 2015 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -73,6 +73,8 @@ .Op Fl f Ar keyfile .Nm ssh-keygen .Fl l +.Op Fl v +.Op Fl E Ar fingerprint_hash .Op Fl f Ar input_keyfile .Nm ssh-keygen .Fl B @@ -140,7 +142,7 @@ generates, manages and converts authentication keys for .Xr ssh 1 . .Nm can create RSA keys for use by SSH protocol version 1 and -DSA, ECDSA, ED25519 or RSA keys for use by SSH protocol version 2. +DSA, ECDSA, Ed25519 or RSA keys for use by SSH protocol version 2. The type of key to be generated is specified with the .Fl t option. @@ -251,7 +253,7 @@ flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits. Attempting to use bit lengths other than these three values for ECDSA keys will fail. -ED25519 keys have a fixed length and the +Ed25519 keys have a fixed length and the .Fl b flag will be ignored. .It Fl C Ar comment @@ -269,6 +271,14 @@ When used in combination with this option indicates that a CA key resides in a PKCS#11 token (see the .Sx CERTIFICATES section for details). +.It Fl E Ar fingerprint_hash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Fl e This option will read a private or public OpenSSH key file and print to stdout the key in one of the formats specified by the @@ -803,7 +813,7 @@ There is no need to keep the contents of this file secret. .It Pa ~/.ssh/id_ecdsa .It Pa ~/.ssh/id_ed25519 .It Pa ~/.ssh/id_rsa -Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA +Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to @@ -819,7 +829,7 @@ will read this file when a login attempt is made. .It Pa ~/.ssh/id_ecdsa.pub .It Pa ~/.ssh/id_ed25519.pub .It Pa ~/.ssh/id_rsa.pub -Contains the protocol version 2 DSA, ECDSA, ED25519 or RSA +Contains the protocol version 2 DSA, ECDSA, Ed25519 or RSA public key for authentication. The contents of this file should be added to .Pa ~/.ssh/authorized_keys diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c index 23058ee9964c..a3c2362a284a 100644 --- a/crypto/openssh/ssh-keygen.c +++ b/crypto/openssh/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.249 2014/07/03 03:47:27 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.266 2015/02/26 20:45:47 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -17,11 +17,12 @@ #include #include #include -#include +#ifdef WITH_OPENSSL #include #include #include "openbsd-compat/openssl-compat.h" +#endif #include #include @@ -35,13 +36,14 @@ #include #include #include +#include #include "xmalloc.h" -#include "key.h" +#include "sshkey.h" #include "rsa.h" #include "authfile.h" #include "uuencode.h" -#include "buffer.h" +#include "sshbuf.h" #include "pathnames.h" #include "log.h" #include "misc.h" @@ -50,9 +52,11 @@ #include "dns.h" #include "ssh.h" #include "ssh2.h" +#include "ssherr.h" #include "ssh-pkcs11.h" #include "atomicio.h" #include "krl.h" +#include "digest.h" /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ #define DEFAULT_BITS 2048 @@ -90,6 +94,9 @@ int show_cert = 0; int print_fingerprint = 0; int print_bubblebabble = 0; +/* Hash algorithm to use for fingerprints. */ +int fingerprint_hash = SSH_FP_HASH_DEFAULT; + /* The identity file name, given on the command line or entered by the user. */ char identity_file[1024]; int have_identity = 0; @@ -173,34 +180,43 @@ int prime_test(FILE *, FILE *, u_int32_t, u_int32_t, char *, unsigned long, unsigned long); static void -type_bits_valid(int type, u_int32_t *bitsp) +type_bits_valid(int type, const char *name, u_int32_t *bitsp) { +#ifdef WITH_OPENSSL u_int maxbits; + int nid; +#endif if (type == KEY_UNSPEC) { fprintf(stderr, "unknown key type %s\n", key_type_name); exit(1); } if (*bitsp == 0) { +#ifdef WITH_OPENSSL if (type == KEY_DSA) *bitsp = DEFAULT_BITS_DSA; - else if (type == KEY_ECDSA) - *bitsp = DEFAULT_BITS_ECDSA; - else + else if (type == KEY_ECDSA) { + if (name != NULL && + (nid = sshkey_ecdsa_nid_from_name(name)) > 0) + *bitsp = sshkey_curve_nid_to_bits(nid); + if (*bitsp == 0) + *bitsp = DEFAULT_BITS_ECDSA; + } else +#endif *bitsp = DEFAULT_BITS; } +#ifdef WITH_OPENSSL maxbits = (type == KEY_DSA) ? OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; if (*bitsp > maxbits) { fprintf(stderr, "key bits exceeds maximum %d\n", maxbits); exit(1); } -#ifdef WITH_OPENSSL if (type == KEY_DSA && *bitsp != 1024) fatal("DSA keys must be 1024 bits"); else if (type != KEY_ECDSA && type != KEY_ED25519 && *bitsp < 768) fatal("Key must at least be 768 bits"); - else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(*bitsp) == -1) + else if (type == KEY_ECDSA && sshkey_ecdsa_bits_to_nid(*bitsp) == -1) fatal("Invalid ECDSA key length - valid lengths are " "256, 384 or 521 bits"); #endif @@ -215,7 +231,7 @@ ask_filename(struct passwd *pw, const char *prompt) if (key_type_name == NULL) name = _PATH_SSH_CLIENT_ID_RSA; else { - switch (key_type_from_name(key_type_name)) { + switch (sshkey_type_from_name(key_type_name)) { case KEY_RSA1: name = _PATH_SSH_CLIENT_IDENTITY; break; @@ -255,23 +271,26 @@ ask_filename(struct passwd *pw, const char *prompt) have_identity = 1; } -static Key * +static struct sshkey * load_identity(char *filename) { char *pass; - Key *prv; + struct sshkey *prv; + int r; - prv = key_load_private(filename, "", NULL); - if (prv == NULL) { - if (identity_passphrase) - pass = xstrdup(identity_passphrase); - else - pass = read_passphrase("Enter passphrase: ", - RP_ALLOW_STDIN); - prv = key_load_private(filename, pass, NULL); - explicit_bzero(pass, strlen(pass)); - free(pass); - } + if ((r = sshkey_load_private(filename, "", &prv, NULL)) == 0) + return prv; + if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) + fatal("Load key \"%s\": %s", filename, ssh_err(r)); + if (identity_passphrase) + pass = xstrdup(identity_passphrase); + else + pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); + r = sshkey_load_private(filename, pass, &prv, NULL); + explicit_bzero(pass, strlen(pass)); + free(pass); + if (r != 0) + fatal("Load key \"%s\": %s", filename, ssh_err(r)); return prv; } @@ -282,39 +301,40 @@ load_identity(char *filename) #ifdef WITH_OPENSSL static void -do_convert_to_ssh2(struct passwd *pw, Key *k) +do_convert_to_ssh2(struct passwd *pw, struct sshkey *k) { - u_int len; + size_t len; u_char *blob; char comment[61]; + int r; if (k->type == KEY_RSA1) { fprintf(stderr, "version 1 keys are not supported\n"); exit(1); } - if (key_to_blob(k, &blob, &len) <= 0) { - fprintf(stderr, "key_to_blob failed\n"); + if ((r = sshkey_to_blob(k, &blob, &len)) != 0) { + fprintf(stderr, "key_to_blob failed: %s\n", ssh_err(r)); exit(1); } /* Comment + surrounds must fit into 72 chars (RFC 4716 sec 3.3) */ snprintf(comment, sizeof(comment), "%u-bit %s, converted by %s@%s from OpenSSH", - key_size(k), key_type(k), + sshkey_size(k), sshkey_type(k), pw->pw_name, hostname); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); fprintf(stdout, "Comment: \"%s\"\n", comment); dump_base64(stdout, blob, len); fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END); - key_free(k); + sshkey_free(k); free(blob); exit(0); } static void -do_convert_to_pkcs8(Key *k) +do_convert_to_pkcs8(struct sshkey *k) { - switch (key_type_plain(k->type)) { + switch (sshkey_type_plain(k->type)) { case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) @@ -331,15 +351,15 @@ do_convert_to_pkcs8(Key *k) break; #endif default: - fatal("%s: unsupported key type %s", __func__, key_type(k)); + fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } exit(0); } static void -do_convert_to_pem(Key *k) +do_convert_to_pem(struct sshkey *k) { - switch (key_type_plain(k->type)) { + switch (sshkey_type_plain(k->type)) { case KEY_RSA1: case KEY_RSA: if (!PEM_write_RSAPublicKey(stdout, k->rsa)) @@ -353,7 +373,7 @@ do_convert_to_pem(Key *k) #endif /* XXX ECDSA? */ default: - fatal("%s: unsupported key type %s", __func__, key_type(k)); + fatal("%s: unsupported key type %s", __func__, sshkey_type(k)); } exit(0); } @@ -361,20 +381,16 @@ do_convert_to_pem(Key *k) static void do_convert_to(struct passwd *pw) { - Key *k; + struct sshkey *k; struct stat st; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((k = key_load_public(identity_file, NULL)) == NULL) { - if ((k = load_identity(identity_file)) == NULL) { - fprintf(stderr, "load failed\n"); - exit(1); - } - } - + if ((r = sshkey_load_public(identity_file, &k, NULL)) != 0) + k = load_identity(identity_file); switch (convert_format) { case FMT_RFC4716: do_convert_to_ssh2(pw, k); @@ -391,51 +407,63 @@ do_convert_to(struct passwd *pw) exit(0); } +/* + * This is almost exactly the bignum1 encoding, but with 32 bit for length + * instead of 16. + */ static void -buffer_get_bignum_bits(Buffer *b, BIGNUM *value) +buffer_get_bignum_bits(struct sshbuf *b, BIGNUM *value) { - u_int bignum_bits = buffer_get_int(b); - u_int bytes = (bignum_bits + 7) / 8; + u_int bytes, bignum_bits; + int r; - if (buffer_len(b) < bytes) - fatal("buffer_get_bignum_bits: input buffer too small: " - "need %d have %d", bytes, buffer_len(b)); - if (BN_bin2bn(buffer_ptr(b), bytes, value) == NULL) - fatal("buffer_get_bignum_bits: BN_bin2bn failed"); - buffer_consume(b, bytes); + if ((r = sshbuf_get_u32(b, &bignum_bits)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + bytes = (bignum_bits + 7) / 8; + if (sshbuf_len(b) < bytes) + fatal("%s: input buffer too small: need %d have %zu", + __func__, bytes, sshbuf_len(b)); + if (BN_bin2bn(sshbuf_ptr(b), bytes, value) == NULL) + fatal("%s: BN_bin2bn failed", __func__); + if ((r = sshbuf_consume(b, bytes)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } -static Key * +static struct sshkey * do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) { - Buffer b; - Key *key = NULL; + struct sshbuf *b; + struct sshkey *key = NULL; char *type, *cipher; - u_char *sig = NULL, data[] = "abcde12345"; - int magic, rlen, ktype, i1, i2, i3, i4; - u_int slen; + u_char e1, e2, e3, *sig = NULL, data[] = "abcde12345"; + int r, rlen, ktype; + u_int magic, i1, i2, i3, i4; + size_t slen; u_long e; - buffer_init(&b); - buffer_append(&b, blob, blen); + if ((b = sshbuf_from(blob, blen)) == NULL) + fatal("%s: sshbuf_from failed", __func__); + if ((r = sshbuf_get_u32(b, &magic)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - magic = buffer_get_int(&b); if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { - error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); - buffer_free(&b); + error("bad magic 0x%x != 0x%x", magic, + SSH_COM_PRIVATE_KEY_MAGIC); + sshbuf_free(b); return NULL; } - i1 = buffer_get_int(&b); - type = buffer_get_string(&b, NULL); - cipher = buffer_get_string(&b, NULL); - i2 = buffer_get_int(&b); - i3 = buffer_get_int(&b); - i4 = buffer_get_int(&b); + if ((r = sshbuf_get_u32(b, &i1)) != 0 || + (r = sshbuf_get_cstring(b, &type, NULL)) != 0 || + (r = sshbuf_get_cstring(b, &cipher, NULL)) != 0 || + (r = sshbuf_get_u32(b, &i2)) != 0 || + (r = sshbuf_get_u32(b, &i3)) != 0 || + (r = sshbuf_get_u32(b, &i4)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("ignore (%d %d %d %d)", i1, i2, i3, i4); if (strcmp(cipher, "none") != 0) { error("unsupported cipher %s", cipher); free(cipher); - buffer_free(&b); + sshbuf_free(b); free(type); return NULL; } @@ -446,56 +474,64 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) } else if (strstr(type, "rsa")) { ktype = KEY_RSA; } else { - buffer_free(&b); + sshbuf_free(b); free(type); return NULL; } - key = key_new_private(ktype); + if ((key = sshkey_new_private(ktype)) == NULL) + fatal("key_new_private failed"); free(type); switch (key->type) { case KEY_DSA: - buffer_get_bignum_bits(&b, key->dsa->p); - buffer_get_bignum_bits(&b, key->dsa->g); - buffer_get_bignum_bits(&b, key->dsa->q); - buffer_get_bignum_bits(&b, key->dsa->pub_key); - buffer_get_bignum_bits(&b, key->dsa->priv_key); + buffer_get_bignum_bits(b, key->dsa->p); + buffer_get_bignum_bits(b, key->dsa->g); + buffer_get_bignum_bits(b, key->dsa->q); + buffer_get_bignum_bits(b, key->dsa->pub_key); + buffer_get_bignum_bits(b, key->dsa->priv_key); break; case KEY_RSA: - e = buffer_get_char(&b); + if ((r = sshbuf_get_u8(b, &e1)) != 0 || + (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || + (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + e = e1; debug("e %lx", e); if (e < 30) { e <<= 8; - e += buffer_get_char(&b); + e += e2; debug("e %lx", e); e <<= 8; - e += buffer_get_char(&b); + e += e3; debug("e %lx", e); } if (!BN_set_word(key->rsa->e, e)) { - buffer_free(&b); - key_free(key); + sshbuf_free(b); + sshkey_free(key); return NULL; } - buffer_get_bignum_bits(&b, key->rsa->d); - buffer_get_bignum_bits(&b, key->rsa->n); - buffer_get_bignum_bits(&b, key->rsa->iqmp); - buffer_get_bignum_bits(&b, key->rsa->q); - buffer_get_bignum_bits(&b, key->rsa->p); - if (rsa_generate_additional_parameters(key->rsa) != 0) - fatal("%s: rsa_generate_additional_parameters " - "error", __func__); + buffer_get_bignum_bits(b, key->rsa->d); + buffer_get_bignum_bits(b, key->rsa->n); + buffer_get_bignum_bits(b, key->rsa->iqmp); + buffer_get_bignum_bits(b, key->rsa->q); + buffer_get_bignum_bits(b, key->rsa->p); + if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) + fatal("generate RSA parameters failed: %s", ssh_err(r)); break; } - rlen = buffer_len(&b); + rlen = sshbuf_len(b); if (rlen != 0) error("do_convert_private_ssh2_from_blob: " "remaining bytes in key blob %d", rlen); - buffer_free(&b); + sshbuf_free(b); /* try the key */ - key_sign(key, &sig, &slen, data, sizeof(data)); - key_verify(key, sig, slen, data, sizeof(data)); + if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 0) != 0 || + sshkey_verify(key, sig, slen, data, sizeof(data), 0) != 0) { + sshkey_free(key); + free(sig); + return NULL; + } free(sig); return key; } @@ -531,14 +567,13 @@ get_line(FILE *fp, char *line, size_t len) } static void -do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) +do_convert_from_ssh2(struct passwd *pw, struct sshkey **k, int *private) { - int blen; + int r, blen, escaped = 0; u_int len; char line[1024]; u_char blob[8096]; char encoded[8096]; - int escaped = 0; FILE *fp; if ((fp = fopen(identity_file, "r")) == NULL) @@ -575,18 +610,17 @@ do_convert_from_ssh2(struct passwd *pw, Key **k, int *private) fprintf(stderr, "uudecode failed.\n"); exit(1); } - *k = *private ? - do_convert_private_ssh2_from_blob(blob, blen) : - key_from_blob(blob, blen); - if (*k == NULL) { - fprintf(stderr, "decode blob failed.\n"); + if (*private) + *k = do_convert_private_ssh2_from_blob(blob, blen); + else if ((r = sshkey_from_blob(blob, blen, k)) != 0) { + fprintf(stderr, "decode blob failed: %s\n", ssh_err(r)); exit(1); } fclose(fp); } static void -do_convert_from_pkcs8(Key **k, int *private) +do_convert_from_pkcs8(struct sshkey **k, int *private) { EVP_PKEY *pubkey; FILE *fp; @@ -600,21 +634,24 @@ do_convert_from_pkcs8(Key **k, int *private) fclose(fp); switch (EVP_PKEY_type(pubkey->type)) { case EVP_PKEY_RSA: - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_RSA; (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); break; case EVP_PKEY_DSA: - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_DSA; (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); break; #ifdef OPENSSL_HAS_ECC case EVP_PKEY_EC: - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_ECDSA; (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); - (*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa); + (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); break; #endif default: @@ -626,7 +663,7 @@ do_convert_from_pkcs8(Key **k, int *private) } static void -do_convert_from_pem(Key **k, int *private) +do_convert_from_pem(struct sshkey **k, int *private) { FILE *fp; RSA *rsa; @@ -637,7 +674,8 @@ do_convert_from_pem(Key **k, int *private) if ((fp = fopen(identity_file, "r")) == NULL) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_RSA; (*k)->rsa = rsa; fclose(fp); @@ -646,7 +684,8 @@ do_convert_from_pem(Key **k, int *private) #if notyet /* OpenSSH 0.9.8 lacks this function */ rewind(fp); if ((dsa = PEM_read_DSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { - *k = key_new(KEY_UNSPEC); + if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); (*k)->type = KEY_DSA; (*k)->dsa = dsa; fclose(fp); @@ -660,8 +699,8 @@ do_convert_from_pem(Key **k, int *private) static void do_convert_from(struct passwd *pw) { - Key *k = NULL; - int private = 0, ok = 0; + struct sshkey *k = NULL; + int r, private = 0, ok = 0; struct stat st; if (!have_identity) @@ -683,11 +722,12 @@ do_convert_from(struct passwd *pw) fatal("%s: unknown key format %d", __func__, convert_format); } - if (!private) - ok = key_write(k, stdout); + if (!private) { + if ((r = sshkey_write(k, stdout)) == 0) + ok = 1; if (ok) fprintf(stdout, "\n"); - else { + } else { switch (k->type) { case KEY_DSA: ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, @@ -705,7 +745,7 @@ do_convert_from(struct passwd *pw) break; default: fatal("%s: unsupported key type %s", __func__, - key_type(k)); + sshkey_type(k)); } } @@ -713,7 +753,7 @@ do_convert_from(struct passwd *pw) fprintf(stderr, "key write failed\n"); exit(1); } - key_free(k); + sshkey_free(k); exit(0); } #endif @@ -721,8 +761,9 @@ do_convert_from(struct passwd *pw) static void do_print_public(struct passwd *pw) { - Key *prv; + struct sshkey *prv; struct stat st; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); @@ -731,13 +772,9 @@ do_print_public(struct passwd *pw) exit(1); } prv = load_identity(identity_file); - if (prv == NULL) { - fprintf(stderr, "load failed\n"); - exit(1); - } - if (!key_write(prv, stdout)) - fprintf(stderr, "key_write failed"); - key_free(prv); + if ((r = sshkey_write(prv, stdout)) != 0) + fprintf(stderr, "key_write failed: %s", ssh_err(r)); + sshkey_free(prv); fprintf(stdout, "\n"); exit(0); } @@ -746,14 +783,14 @@ static void do_download(struct passwd *pw) { #ifdef ENABLE_PKCS11 - Key **keys = NULL; + struct sshkey **keys = NULL; int i, nkeys; - enum fp_rep rep; - enum fp_type fptype; + enum sshkey_fp_rep rep; + int fptype; char *fp, *ra; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; pkcs11_init(0); nkeys = pkcs11_add_provider(pkcs11provider, NULL, &keys); @@ -761,20 +798,22 @@ do_download(struct passwd *pw) fatal("cannot read public key from pkcs11"); for (i = 0; i < nkeys; i++) { if (print_fingerprint) { - fp = key_fingerprint(keys[i], fptype, rep); - ra = key_fingerprint(keys[i], SSH_FP_MD5, + fp = sshkey_fingerprint(keys[i], fptype, rep); + ra = sshkey_fingerprint(keys[i], fingerprint_hash, SSH_FP_RANDOMART); - printf("%u %s %s (PKCS11 key)\n", key_size(keys[i]), - fp, key_type(keys[i])); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + printf("%u %s %s (PKCS11 key)\n", sshkey_size(keys[i]), + fp, sshkey_type(keys[i])); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); } else { - key_write(keys[i], stdout); + (void) sshkey_write(keys[i], stdout); /* XXX check */ fprintf(stdout, "\n"); } - key_free(keys[i]); + sshkey_free(keys[i]); } free(keys); pkcs11_terminate(); @@ -788,31 +827,35 @@ static void do_fingerprint(struct passwd *pw) { FILE *f; - Key *public; + struct sshkey *public; char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; - int i, skip = 0, num = 0, invalid = 1; - enum fp_rep rep; - enum fp_type fptype; + int r, i, skip = 0, num = 0, invalid = 1; + enum sshkey_fp_rep rep; + int fptype; struct stat st; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - + fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) { perror(identity_file); exit(1); } - public = key_load_public(identity_file, &comment); - if (public != NULL) { - fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", key_size(public), fp, comment, - key_type(public)); + if ((r = sshkey_load_public(identity_file, &public, &comment)) != 0) + debug2("Error loading public key \"%s\": %s", + identity_file, ssh_err(r)); + else { + fp = sshkey_fingerprint(public, fptype, rep); + ra = sshkey_fingerprint(public, fingerprint_hash, + SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + printf("%u %s %s (%s)\n", sshkey_size(public), fp, comment, + sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); - key_free(public); + sshkey_free(public); free(comment); free(ra); free(fp); @@ -861,26 +904,31 @@ do_fingerprint(struct passwd *pw) *cp++ = '\0'; } ep = cp; - public = key_new(KEY_RSA1); - if (key_read(public, &cp) != 1) { + if ((public = sshkey_new(KEY_RSA1)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(public, &cp)) != 0) { cp = ep; - key_free(public); - public = key_new(KEY_UNSPEC); - if (key_read(public, &cp) != 1) { - key_free(public); + sshkey_free(public); + if ((public = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(public, &cp)) != 0) { + sshkey_free(public); continue; } } comment = *cp ? cp : comment; - fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", key_size(public), fp, - comment ? comment : "no comment", key_type(public)); + fp = sshkey_fingerprint(public, fptype, rep); + ra = sshkey_fingerprint(public, fingerprint_hash, + SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); + printf("%u %s %s (%s)\n", sshkey_size(public), fp, + comment ? comment : "no comment", sshkey_type(public)); if (log_level >= SYSLOG_LEVEL_VERBOSE) printf("%s\n", ra); free(ra); free(fp); - key_free(public); + sshkey_free(public); invalid = 0; } fclose(f); @@ -912,9 +960,9 @@ do_gen_all_hostkeys(struct passwd *pw) int first = 0; struct stat st; - Key *private, *public; + struct sshkey *private, *public; char comment[1024]; - int i, type, fd; + int i, type, fd, r; FILE *f; for (i = 0; key_types[i].key_type; i++) { @@ -933,98 +981,175 @@ do_gen_all_hostkeys(struct passwd *pw) } printf("%s ", key_types[i].key_type_display); fflush(stdout); - type = key_type_from_name(key_types[i].key_type); + type = sshkey_type_from_name(key_types[i].key_type); strlcpy(identity_file, key_types[i].path, sizeof(identity_file)); bits = 0; - type_bits_valid(type, &bits); - private = key_generate(type, bits); - if (private == NULL) { - fprintf(stderr, "key_generate failed\n"); + type_bits_valid(type, NULL, &bits); + if ((r = sshkey_generate(type, bits, &private)) != 0) { + fprintf(stderr, "key_generate failed: %s\n", + ssh_err(r)); first = 0; continue; } - public = key_from_private(private); + if ((r = sshkey_from_private(private, &public)) != 0) + fatal("sshkey_from_private failed: %s", ssh_err(r)); snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); - if (!key_save_private(private, identity_file, "", comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); - key_free(private); - key_free(public); + if ((r = sshkey_save_private(private, identity_file, "", + comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s\n", identity_file, + ssh_err(r)); + sshkey_free(private); + sshkey_free(public); first = 0; continue; } - key_free(private); + sshkey_free(private); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { printf("Could not save your public key in %s\n", identity_file); - key_free(public); + sshkey_free(public); first = 0; continue; } f = fdopen(fd, "w"); if (f == NULL) { printf("fdopen %s failed\n", identity_file); - key_free(public); + close(fd); + sshkey_free(public); first = 0; continue; } - if (!key_write(public, f)) { - fprintf(stderr, "write key failed\n"); - key_free(public); + if ((r = sshkey_write(public, f)) != 0) { + fprintf(stderr, "write key failed: %s\n", ssh_err(r)); + fclose(f); + sshkey_free(public); first = 0; continue; } fprintf(f, " %s\n", comment); fclose(f); - key_free(public); + sshkey_free(public); } if (first != 0) printf("\n"); } -static void -printhost(FILE *f, const char *name, Key *public, int ca, int revoked, int hash) -{ - if (print_fingerprint) { - enum fp_rep rep; - enum fp_type fptype; - char *fp, *ra; +struct known_hosts_ctx { + const char *host; /* Hostname searched for in find/delete case */ + FILE *out; /* Output file, stdout for find_hosts case */ + int has_unhashed; /* When hashing, original had unhashed hosts */ + int found_key; /* For find/delete, host was found */ + int invalid; /* File contained invalid items; don't delete */ +}; - fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - fp = key_fingerprint(public, fptype, rep); - ra = key_fingerprint(public, SSH_FP_MD5, SSH_FP_RANDOMART); - printf("%u %s %s (%s)\n", key_size(public), fp, name, - key_type(public)); - if (log_level >= SYSLOG_LEVEL_VERBOSE) - printf("%s\n", ra); - free(ra); - free(fp); - } else { - if (hash && (name = host_hash(name, NULL, 0)) == NULL) - fatal("hash_host failed"); - fprintf(f, "%s%s%s ", ca ? CA_MARKER " " : "", - revoked ? REVOKE_MARKER " " : "" , name); - if (!key_write(public, f)) - fatal("key_write failed"); - fprintf(f, "\n"); +static int +known_hosts_hash(struct hostkey_foreach_line *l, void *_ctx) +{ + struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; + char *hashed, *cp, *hosts, *ohosts; + int has_wild = l->hosts && strcspn(l->hosts, "*?!") != strlen(l->hosts); + + switch (l->status) { + case HKF_STATUS_OK: + case HKF_STATUS_MATCHED: + /* + * Don't hash hosts already already hashed, with wildcard + * characters or a CA/revocation marker. + */ + if ((l->match & HKF_MATCH_HOST_HASHED) != 0 || + has_wild || l->marker != MRK_NONE) { + fprintf(ctx->out, "%s\n", l->line); + if (has_wild && !find_host) { + fprintf(stderr, "%s:%ld: ignoring host name " + "with wildcard: %.64s\n", l->path, + l->linenum, l->hosts); + } + return 0; + } + /* + * Split any comma-separated hostnames from the host list, + * hash and store separately. + */ + ohosts = hosts = xstrdup(l->hosts); + while ((cp = strsep(&hosts, ",")) != NULL && *cp != '\0') { + if ((hashed = host_hash(cp, NULL, 0)) == NULL) + fatal("hash_host failed"); + fprintf(ctx->out, "%s %s\n", hashed, l->rawkey); + ctx->has_unhashed = 1; + } + free(ohosts); + return 0; + case HKF_STATUS_INVALID: + /* Retain invalid lines, but mark file as invalid. */ + ctx->invalid = 1; + fprintf(stderr, "%s:%ld: invalid line\n", l->path, l->linenum); + /* FALLTHROUGH */ + default: + fprintf(ctx->out, "%s\n", l->line); + return 0; } + /* NOTREACHED */ + return -1; +} + +static int +known_hosts_find_delete(struct hostkey_foreach_line *l, void *_ctx) +{ + struct known_hosts_ctx *ctx = (struct known_hosts_ctx *)_ctx; + + if (l->status == HKF_STATUS_MATCHED) { + if (delete_host) { + if (l->marker != MRK_NONE) { + /* Don't remove CA and revocation lines */ + fprintf(ctx->out, "%s\n", l->line); + } else { + /* + * Hostname matches and has no CA/revoke + * marker, delete it by *not* writing the + * line to ctx->out. + */ + ctx->found_key = 1; + if (!quiet) + printf("# Host %s found: line %ld\n", + ctx->host, l->linenum); + } + return 0; + } else if (find_host) { + ctx->found_key = 1; + if (!quiet) { + printf("# Host %s found: line %ld %s\n", + ctx->host, + l->linenum, l->marker == MRK_CA ? "CA" : + (l->marker == MRK_REVOKE ? "REVOKED" : "")); + } + if (hash_hosts) + known_hosts_hash(l, ctx); + else + fprintf(ctx->out, "%s\n", l->line); + return 0; + } + } else if (delete_host) { + /* Retain non-matching hosts when deleting */ + if (l->status == HKF_STATUS_INVALID) { + ctx->invalid = 1; + fprintf(stderr, "%s:%ld: invalid line\n", + l->path, l->linenum); + } + fprintf(ctx->out, "%s\n", l->line); + } + return 0; } static void do_known_hosts(struct passwd *pw, const char *name) { - FILE *in, *out = stdout; - Key *pub; - char *cp, *cp2, *kp, *kp2; - char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; - int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; - int ca, revoked; - int found_key = 0; + char *cp, tmp[PATH_MAX], old[PATH_MAX]; + int r, fd, oerrno, inplace = 0; + struct known_hosts_ctx ctx; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); @@ -1034,10 +1159,11 @@ do_known_hosts(struct passwd *pw, const char *name) free(cp); have_identity = 1; } - if ((in = fopen(identity_file, "r")) == NULL) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - /* XXX this code is a mess; refactor -djm */ + memset(&ctx, 0, sizeof(ctx)); + ctx.out = stdout; + ctx.host = name; + /* * Find hosts goes to stdout, hash and deletions happen in-place * A corner case is ssh-keygen -HF foo, which should go to stdout @@ -1049,182 +1175,39 @@ do_known_hosts(struct passwd *pw, const char *name) strlcat(old, ".old", sizeof(old)) >= sizeof(old)) fatal("known_hosts path too long"); umask(077); - if ((c = mkstemp(tmp)) == -1) + if ((fd = mkstemp(tmp)) == -1) fatal("mkstemp: %s", strerror(errno)); - if ((out = fdopen(c, "w")) == NULL) { - c = errno; + if ((ctx.out = fdopen(fd, "w")) == NULL) { + oerrno = errno; unlink(tmp); - fatal("fdopen: %s", strerror(c)); + fatal("fdopen: %s", strerror(oerrno)); } inplace = 1; } - while (fgets(line, sizeof(line), in)) { - if ((cp = strchr(line, '\n')) == NULL) { - error("line %d too long: %.40s...", num + 1, line); - skip = 1; - invalid = 1; - continue; - } - num++; - if (skip) { - skip = 0; - continue; - } - *cp = '\0'; + /* XXX support identity_file == "-" for stdin */ + if ((r = hostkeys_foreach(identity_file, + hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, + name, NULL, find_host ? HKF_WANT_MATCH : 0)) != 0) + fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) - ; - if (!*cp || *cp == '\n' || *cp == '#') { - if (inplace) - fprintf(out, "%s\n", cp); - continue; - } - /* Check whether this is a CA key or revocation marker */ - if (strncasecmp(cp, CA_MARKER, sizeof(CA_MARKER) - 1) == 0 && - (cp[sizeof(CA_MARKER) - 1] == ' ' || - cp[sizeof(CA_MARKER) - 1] == '\t')) { - ca = 1; - cp += sizeof(CA_MARKER); - } else - ca = 0; - if (strncasecmp(cp, REVOKE_MARKER, - sizeof(REVOKE_MARKER) - 1) == 0 && - (cp[sizeof(REVOKE_MARKER) - 1] == ' ' || - cp[sizeof(REVOKE_MARKER) - 1] == '\t')) { - revoked = 1; - cp += sizeof(REVOKE_MARKER); - } else - revoked = 0; + if (inplace) + fclose(ctx.out); - /* Find the end of the host name portion. */ - for (kp = cp; *kp && *kp != ' ' && *kp != '\t'; kp++) - ; - - if (*kp == '\0' || *(kp + 1) == '\0') { - error("line %d missing key: %.40s...", - num, line); - invalid = 1; - continue; - } - *kp++ = '\0'; - kp2 = kp; - - pub = key_new(KEY_RSA1); - if (key_read(pub, &kp) != 1) { - kp = kp2; - key_free(pub); - pub = key_new(KEY_UNSPEC); - if (key_read(pub, &kp) != 1) { - error("line %d invalid key: %.40s...", - num, line); - key_free(pub); - invalid = 1; - continue; - } - } - - if (*cp == HASH_DELIM) { - if (find_host || delete_host) { - cp2 = host_hash(name, cp, strlen(cp)); - if (cp2 == NULL) { - error("line %d: invalid hashed " - "name: %.64s...", num, line); - invalid = 1; - continue; - } - c = (strcmp(cp2, cp) == 0); - if (find_host && c) { - if (!quiet) - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, key_type(pub), - ca ? " (CA key)" : - revoked? " (revoked)" : ""); - printhost(out, cp, pub, ca, revoked, 0); - found_key = 1; - } - if (delete_host) { - if (!c || ca || revoked) { - printhost(out, cp, pub, - ca, revoked, 0); - } else { - printf("# Host %s found: " - "line %d type %s\n", name, - num, key_type(pub)); - } - } - } else if (hash_hosts) - printhost(out, cp, pub, ca, revoked, 0); - } else { - if (find_host || delete_host) { - c = (match_hostname(name, cp, - strlen(cp)) == 1); - if (find_host && c) { - if (!quiet) - printf("# Host %s found: " - "line %d type %s%s\n", name, - num, key_type(pub), - ca ? " (CA key)" : ""); - printhost(out, name, pub, ca, revoked, - hash_hosts && !(ca || revoked)); - found_key = 1; - } - if (delete_host) { - if (!c || ca || revoked) { - printhost(out, cp, pub, - ca, revoked, 0); - } else { - printf("# Host %s found: " - "line %d type %s\n", name, - num, key_type(pub)); - } - } - } else if (hash_hosts && (ca || revoked)) { - /* Don't hash CA and revoked keys' hostnames */ - printhost(out, cp, pub, ca, revoked, 0); - has_unhashed = 1; - } else if (hash_hosts) { - /* Hash each hostname separately */ - for (cp2 = strsep(&cp, ","); - cp2 != NULL && *cp2 != '\0'; - cp2 = strsep(&cp, ",")) { - if (strcspn(cp2, "*?!") != - strlen(cp2)) { - fprintf(stderr, "Warning: " - "ignoring host name with " - "metacharacters: %.64s\n", - cp2); - printhost(out, cp2, pub, ca, - revoked, 0); - has_unhashed = 1; - } else { - printhost(out, cp2, pub, ca, - revoked, 1); - } - } - } - } - key_free(pub); - } - fclose(in); - - if (invalid) { + if (ctx.invalid) { fprintf(stderr, "%s is not a valid known_hosts file.\n", identity_file); if (inplace) { fprintf(stderr, "Not replacing existing known_hosts " "file because of errors\n"); - fclose(out); unlink(tmp); } exit(1); - } - - if (inplace) { - fclose(out); - + } else if (delete_host && !ctx.found_key) { + fprintf(stderr, "Host %s not found in %s\n", + name, identity_file); + unlink(tmp); + } else if (inplace) { /* Backup existing file */ if (unlink(old) == -1 && errno != ENOENT) fatal("unlink %.100s: %s", old, strerror(errno)); @@ -1242,7 +1225,7 @@ do_known_hosts(struct passwd *pw, const char *name) fprintf(stderr, "%s updated.\n", identity_file); fprintf(stderr, "Original contents retained as %s\n", old); - if (has_unhashed) { + if (ctx.has_unhashed) { fprintf(stderr, "WARNING: %s contains unhashed " "entries\n", old); fprintf(stderr, "Delete this file to ensure privacy " @@ -1250,7 +1233,7 @@ do_known_hosts(struct passwd *pw, const char *name) } } - exit (find_host && !found_key); + exit (find_host && !ctx.found_key); } /* @@ -1263,7 +1246,8 @@ do_change_passphrase(struct passwd *pw) char *comment; char *old_passphrase, *passphrase1, *passphrase2; struct stat st; - Key *private; + struct sshkey *private; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); @@ -1272,24 +1256,28 @@ do_change_passphrase(struct passwd *pw) exit(1); } /* Try to load the file with empty passphrase. */ - private = key_load_private(identity_file, "", &comment); - if (private == NULL) { + r = sshkey_load_private(identity_file, "", &private, &comment); + if (r == SSH_ERR_KEY_WRONG_PASSPHRASE) { if (identity_passphrase) old_passphrase = xstrdup(identity_passphrase); else old_passphrase = read_passphrase("Enter old passphrase: ", RP_ALLOW_STDIN); - private = key_load_private(identity_file, old_passphrase, - &comment); + r = sshkey_load_private(identity_file, old_passphrase, + &private, &comment); explicit_bzero(old_passphrase, strlen(old_passphrase)); free(old_passphrase); - if (private == NULL) { - printf("Bad passphrase.\n"); - exit(1); - } + if (r != 0) + goto badkey; + } else if (r != 0) { + badkey: + fprintf(stderr, "Failed to load key \"%s\": %s\n", + identity_file, ssh_err(r)); + exit(1); } - printf("Key has comment '%s'\n", comment); + if (comment) + printf("Key has comment '%s'\n", comment); /* Ask the new passphrase (twice). */ if (identity_new_passphrase) { @@ -1317,19 +1305,20 @@ do_change_passphrase(struct passwd *pw) } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase1, comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); + if ((r = sshkey_save_private(private, identity_file, passphrase1, + comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s.\n", + identity_file, ssh_err(r)); explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); - key_free(private); + sshkey_free(private); free(comment); exit(1); } /* Destroy the passphrase and the copy of the key in memory. */ explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); - key_free(private); /* Destroys contents */ + sshkey_free(private); /* Destroys contents */ free(comment); printf("Your identification has been saved with the new passphrase.\n"); @@ -1342,9 +1331,10 @@ do_change_passphrase(struct passwd *pw) static int do_print_resource_record(struct passwd *pw, char *fname, char *hname) { - Key *public; + struct sshkey *public; char *comment = NULL; struct stat st; + int r; if (fname == NULL) fatal("%s: no filename", __func__); @@ -1354,18 +1344,15 @@ do_print_resource_record(struct passwd *pw, char *fname, char *hname) perror(fname); exit(1); } - public = key_load_public(fname, &comment); - if (public != NULL) { - export_dns_rr(hname, public, stdout, print_generic); - key_free(public); - free(comment); - return 1; + if ((r = sshkey_load_public(fname, &public, &comment)) != 0) { + printf("Failed to read v2 public key from \"%s\": %s.\n", + fname, ssh_err(r)); + exit(1); } - if (comment) - free(comment); - - printf("failed to read v2 public key from %s.\n", fname); - exit(1); + export_dns_rr(hname, public, stdout, print_generic); + sshkey_free(public); + free(comment); + return 1; } /* @@ -1375,11 +1362,11 @@ static void do_change_comment(struct passwd *pw) { char new_comment[1024], *comment, *passphrase; - Key *private; - Key *public; + struct sshkey *private; + struct sshkey *public; struct stat st; FILE *f; - int fd; + int r, fd; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); @@ -1387,8 +1374,14 @@ do_change_comment(struct passwd *pw) perror(identity_file); exit(1); } - private = key_load_private(identity_file, "", &comment); - if (private == NULL) { + if ((r = sshkey_load_private(identity_file, "", + &private, &comment)) == 0) + passphrase = xstrdup(""); + else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + printf("Cannot load private key \"%s\": %s.\n", + identity_file, ssh_err(r)); + exit(1); + } else { if (identity_passphrase) passphrase = xstrdup(identity_passphrase); else if (identity_new_passphrase) @@ -1397,19 +1390,18 @@ do_change_comment(struct passwd *pw) passphrase = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); /* Try to load using the passphrase. */ - private = key_load_private(identity_file, passphrase, &comment); - if (private == NULL) { + if ((r = sshkey_load_private(identity_file, passphrase, + &private, &comment)) != 0) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - printf("Bad passphrase.\n"); + printf("Cannot load private key \"%s\": %s.\n", + identity_file, ssh_err(r)); exit(1); } - } else { - passphrase = xstrdup(""); } if (private->type != KEY_RSA1) { fprintf(stderr, "Comments are only supported for RSA1 keys.\n"); - key_free(private); + sshkey_free(private); exit(1); } printf("Key now has comment '%s'\n", comment); @@ -1421,26 +1413,28 @@ do_change_comment(struct passwd *pw) fflush(stdout); if (!fgets(new_comment, sizeof(new_comment), stdin)) { explicit_bzero(passphrase, strlen(passphrase)); - key_free(private); + sshkey_free(private); exit(1); } new_comment[strcspn(new_comment, "\n")] = '\0'; } /* Save the file using the new passphrase. */ - if (!key_save_private(private, identity_file, passphrase, new_comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); + if ((r = sshkey_save_private(private, identity_file, passphrase, + new_comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s\n", + identity_file, ssh_err(r)); explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - key_free(private); + sshkey_free(private); free(comment); exit(1); } explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - public = key_from_private(private); - key_free(private); + if ((r = sshkey_from_private(private, &public)) != 0) + fatal("key_from_private failed: %s", ssh_err(r)); + sshkey_free(private); strlcat(identity_file, ".pub", sizeof(identity_file)); fd = open(identity_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); @@ -1453,9 +1447,9 @@ do_change_comment(struct passwd *pw) printf("fdopen %s failed\n", identity_file); exit(1); } - if (!key_write(public, f)) - fprintf(stderr, "write key failed\n"); - key_free(public); + if ((r = sshkey_write(public, f)) != 0) + fprintf(stderr, "write key failed: %s\n", ssh_err(r)); + sshkey_free(public); fprintf(f, " %s\n", new_comment); fclose(f); @@ -1504,34 +1498,39 @@ fmt_validity(u_int64_t valid_from, u_int64_t valid_to) } static void -add_flag_option(Buffer *c, const char *name) +add_flag_option(struct sshbuf *c, const char *name) { + int r; + debug3("%s: %s", __func__, name); - buffer_put_cstring(c, name); - buffer_put_string(c, NULL, 0); + if ((r = sshbuf_put_cstring(c, name)) != 0 || + (r = sshbuf_put_string(c, NULL, 0)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); } static void -add_string_option(Buffer *c, const char *name, const char *value) +add_string_option(struct sshbuf *c, const char *name, const char *value) { - Buffer b; + struct sshbuf *b; + int r; debug3("%s: %s=%s", __func__, name, value); - buffer_init(&b); - buffer_put_cstring(&b, value); + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_cstring(b, value)) != 0 || + (r = sshbuf_put_cstring(c, name)) != 0 || + (r = sshbuf_put_stringb(c, b)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - buffer_put_cstring(c, name); - buffer_put_string(c, buffer_ptr(&b), buffer_len(&b)); - - buffer_free(&b); + sshbuf_free(b); } #define OPTIONS_CRITICAL 1 #define OPTIONS_EXTENSIONS 2 static void -prepare_options_buf(Buffer *c, int which) +prepare_options_buf(struct sshbuf *c, int which) { - buffer_clear(c); + sshbuf_reset(c); if ((which & OPTIONS_CRITICAL) != 0 && certflags_command != NULL) add_string_option(c, "force-command", certflags_command); @@ -1555,29 +1554,30 @@ prepare_options_buf(Buffer *c, int which) add_string_option(c, "source-address", certflags_src_addr); } -static Key * +static struct sshkey * load_pkcs11_key(char *path) { #ifdef ENABLE_PKCS11 - Key **keys = NULL, *public, *private = NULL; - int i, nkeys; + struct sshkey **keys = NULL, *public, *private = NULL; + int r, i, nkeys; - if ((public = key_load_public(path, NULL)) == NULL) - fatal("Couldn't load CA public key \"%s\"", path); + if ((r = sshkey_load_public(path, &public, NULL)) != 0) + fatal("Couldn't load CA public key \"%s\": %s", + path, ssh_err(r)); nkeys = pkcs11_add_provider(pkcs11provider, identity_passphrase, &keys); debug3("%s: %d keys", __func__, nkeys); if (nkeys <= 0) fatal("cannot read public key from pkcs11"); for (i = 0; i < nkeys; i++) { - if (key_equal_public(public, keys[i])) { + if (sshkey_equal_public(public, keys[i])) { private = keys[i]; continue; } - key_free(keys[i]); + sshkey_free(keys[i]); } free(keys); - key_free(public); + sshkey_free(public); return private; #else fatal("no pkcs11 support"); @@ -1587,15 +1587,15 @@ load_pkcs11_key(char *path) static void do_ca_sign(struct passwd *pw, int argc, char **argv) { - int i, fd; + int r, i, fd; u_int n; - Key *ca, *public; + struct sshkey *ca, *public; char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; FILE *f; int v00 = 0; /* legacy keys */ if (key_type_name != NULL) { - switch (key_type_from_name(key_type_name)) { + switch (sshkey_type_from_name(key_type_name)) { case KEY_RSA_CERT_V00: case KEY_DSA_CERT_V00: v00 = 1; @@ -1620,8 +1620,8 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) if (pkcs11provider != NULL) { if ((ca = load_pkcs11_key(tmp)) == NULL) fatal("No PKCS#11 key matching %s found", ca_key_path); - } else if ((ca = load_identity(tmp)) == NULL) - fatal("Couldn't load CA key \"%s\"", tmp); + } else + ca = load_identity(tmp); free(tmp); for (i = 0; i < argc; i++) { @@ -1639,16 +1639,18 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) } tmp = tilde_expand_filename(argv[i], pw->pw_uid); - if ((public = key_load_public(tmp, &comment)) == NULL) - fatal("%s: unable to open \"%s\"", __func__, tmp); + if ((r = sshkey_load_public(tmp, &public, &comment)) != 0) + fatal("%s: unable to open \"%s\": %s", + __func__, tmp, ssh_err(r)); if (public->type != KEY_RSA && public->type != KEY_DSA && public->type != KEY_ECDSA && public->type != KEY_ED25519) fatal("%s: key \"%s\" type %s cannot be certified", - __func__, tmp, key_type(public)); + __func__, tmp, sshkey_type(public)); /* Prepare certificate to sign */ - if (key_to_certified(public, v00) != 0) - fatal("Could not upgrade key %s to certificate", tmp); + if ((r = sshkey_to_certified(public, v00)) != 0) + fatal("Could not upgrade key %s to certificate: %s", + tmp, ssh_err(r)); public->cert->type = cert_key_type; public->cert->serial = (u_int64_t)cert_serial; public->cert->key_id = xstrdup(cert_key_id); @@ -1665,9 +1667,11 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) prepare_options_buf(public->cert->extensions, OPTIONS_EXTENSIONS); } - public->cert->signature_key = key_from_private(ca); + if ((r = sshkey_from_private(ca, + &public->cert->signature_key)) != 0) + fatal("key_from_private (ca key): %s", ssh_err(r)); - if (key_certify(public, ca) != 0) + if (sshkey_certify(public, ca) != 0) fatal("Couldn't not certify key %s", tmp); if ((cp = strrchr(tmp, '.')) != NULL && strcmp(cp, ".pub") == 0) @@ -1680,14 +1684,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) strerror(errno)); if ((f = fdopen(fd, "w")) == NULL) fatal("%s: fdopen: %s", __func__, strerror(errno)); - if (!key_write(public, f)) - fatal("Could not write certified key to %s", out); + if ((r = sshkey_write(public, f)) != 0) + fatal("Could not write certified key to %s: %s", + out, ssh_err(r)); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { logit("Signed %s key %s: id \"%s\" serial %llu%s%s " - "valid %s", key_cert_type(public), + "valid %s", sshkey_cert_type(public), out, public->cert->key_id, (unsigned long long)public->cert->serial, cert_principals != NULL ? " for " : "", @@ -1695,7 +1700,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) fmt_validity(cert_valid_from, cert_valid_to)); } - key_free(public); + sshkey_free(public); free(out); } #ifdef ENABLE_PKCS11 @@ -1846,21 +1851,20 @@ add_cert_option(char *opt) } static void -show_options(const Buffer *optbuf, int v00, int in_critical) +show_options(struct sshbuf *optbuf, int v00, int in_critical) { char *name, *arg; - const u_char *data; - u_int dlen; - Buffer options, option; + struct sshbuf *options, *option = NULL; + int r; - buffer_init(&options); - buffer_append(&options, buffer_ptr(optbuf), buffer_len(optbuf)); - - buffer_init(&option); - while (buffer_len(&options) != 0) { - name = buffer_get_string(&options, NULL); - data = buffer_get_string_ptr(&options, &dlen); - buffer_append(&option, data, dlen); + if ((options = sshbuf_fromb(optbuf)) == NULL) + fatal("%s: sshbuf_fromb failed", __func__); + while (sshbuf_len(options) != 0) { + sshbuf_free(option); + option = NULL; + if ((r = sshbuf_get_cstring(options, &name, NULL)) != 0 || + (r = sshbuf_froms(options, &option)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); printf(" %s", name); if ((v00 || !in_critical) && (strcmp(name, "permit-X11-forwarding") == 0 || @@ -1872,50 +1876,56 @@ show_options(const Buffer *optbuf, int v00, int in_critical) else if ((v00 || in_critical) && (strcmp(name, "force-command") == 0 || strcmp(name, "source-address") == 0)) { - arg = buffer_get_cstring(&option, NULL); + if ((r = sshbuf_get_cstring(option, &arg, NULL)) != 0) + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); printf(" %s\n", arg); free(arg); } else { - printf(" UNKNOWN OPTION (len %u)\n", - buffer_len(&option)); - buffer_clear(&option); + printf(" UNKNOWN OPTION (len %zu)\n", + sshbuf_len(option)); + sshbuf_reset(option); } free(name); - if (buffer_len(&option) != 0) + if (sshbuf_len(option) != 0) fatal("Option corrupt: extra data at end"); } - buffer_free(&option); - buffer_free(&options); + sshbuf_free(option); + sshbuf_free(options); } static void do_show_cert(struct passwd *pw) { - Key *key; + struct sshkey *key; struct stat st; char *key_fp, *ca_fp; u_int i, v00; + int r; if (!have_identity) ask_filename(pw, "Enter file in which the key is"); if (stat(identity_file, &st) < 0) fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); - if ((key = key_load_public(identity_file, NULL)) == NULL) - fatal("%s is not a public key", identity_file); - if (!key_is_cert(key)) + if ((r = sshkey_load_public(identity_file, &key, NULL)) != 0) + fatal("Cannot load public key \"%s\": %s", + identity_file, ssh_err(r)); + if (!sshkey_is_cert(key)) fatal("%s is not a certificate", identity_file); v00 = key->type == KEY_RSA_CERT_V00 || key->type == KEY_DSA_CERT_V00; - key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); - ca_fp = key_fingerprint(key->cert->signature_key, - SSH_FP_MD5, SSH_FP_HEX); + key_fp = sshkey_fingerprint(key, fingerprint_hash, SSH_FP_DEFAULT); + ca_fp = sshkey_fingerprint(key->cert->signature_key, + fingerprint_hash, SSH_FP_DEFAULT); + if (key_fp == NULL || ca_fp == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); printf("%s:\n", identity_file); - printf(" Type: %s %s certificate\n", key_ssh_name(key), - key_cert_type(key)); - printf(" Public key: %s %s\n", key_type(key), key_fp); + printf(" Type: %s %s certificate\n", sshkey_ssh_name(key), + sshkey_cert_type(key)); + printf(" Public key: %s %s\n", sshkey_type(key), key_fp); printf(" Signing CA: %s %s\n", - key_type(key->cert->signature_key), ca_fp); + sshkey_type(key->cert->signature_key), ca_fp); printf(" Key ID: \"%s\"\n", key->cert->key_id); if (!v00) { printf(" Serial: %llu\n", @@ -1933,7 +1943,7 @@ do_show_cert(struct passwd *pw) printf("\n"); } printf(" Critical Options: "); - if (buffer_len(key->cert->critical) == 0) + if (sshbuf_len(key->cert->critical) == 0) printf("(none)\n"); else { printf("\n"); @@ -1941,7 +1951,7 @@ do_show_cert(struct passwd *pw) } if (!v00) { printf(" Extensions: "); - if (buffer_len(key->cert->extensions) == 0) + if (sshbuf_len(key->cert->extensions) == 0) printf("(none)\n"); else { printf("\n"); @@ -1951,31 +1961,31 @@ do_show_cert(struct passwd *pw) exit(0); } -#ifdef WITH_OPENSSL static void load_krl(const char *path, struct ssh_krl **krlp) { - Buffer krlbuf; - int fd; + struct sshbuf *krlbuf; + int r, fd; - buffer_init(&krlbuf); + if ((krlbuf = sshbuf_new()) == NULL) + fatal("sshbuf_new failed"); if ((fd = open(path, O_RDONLY)) == -1) fatal("open %s: %s", path, strerror(errno)); - if (!key_load_file(fd, path, &krlbuf)) - fatal("Unable to load KRL"); + if ((r = sshkey_load_file(fd, krlbuf)) != 0) + fatal("Unable to load KRL: %s", ssh_err(r)); close(fd); /* XXX check sigs */ - if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 || + if ((r = ssh_krl_from_blob(krlbuf, krlp, NULL, 0)) != 0 || *krlp == NULL) - fatal("Invalid KRL file"); - buffer_free(&krlbuf); + fatal("Invalid KRL file: %s", ssh_err(r)); + sshbuf_free(krlbuf); } static void -update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, - struct ssh_krl *krl) +update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, + const struct sshkey *ca, struct ssh_krl *krl) { - Key *key = NULL; + struct sshkey *key = NULL; u_long lnum = 0; char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; unsigned long long serial, serial2; @@ -2014,7 +2024,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, if (*cp == '\0') continue; if (strncasecmp(cp, "serial:", 7) == 0) { - if (ca == NULL) { + if (ca == NULL && !wild_ca) { fatal("revoking certificates by serial number " "requires specification of a CA key"); } @@ -2051,7 +2061,7 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, __func__); } } else if (strncasecmp(cp, "id:", 3) == 0) { - if (ca == NULL) { + if (ca == NULL && !wild_ca) { fatal("revoking certificates by key ID " "requires specification of a CA key"); } @@ -2074,10 +2084,11 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, * Parsing will fail if it isn't. */ } - if ((key = key_new(KEY_UNSPEC)) == NULL) + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) fatal("key_new"); - if (key_read(key, &cp) != 1) - fatal("%s:%lu: invalid key", path, lnum); + if ((r = sshkey_read(key, &cp)) != 0) + fatal("%s:%lu: invalid key: %s", + path, lnum, ssh_err(r)); if (was_explicit_key) r = ssh_krl_revoke_key_explicit(krl, key); else if (was_sha1) @@ -2085,8 +2096,9 @@ update_krl_from_file(struct passwd *pw, const char *file, const Key *ca, else r = ssh_krl_revoke_key(krl, key); if (r != 0) - fatal("%s: revoke key failed", __func__); - key_free(key); + fatal("%s: revoke key failed: %s", + __func__, ssh_err(r)); + sshkey_free(key); } } if (strcmp(path, "-") != 0) @@ -2099,10 +2111,10 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) { struct ssh_krl *krl; struct stat sb; - Key *ca = NULL; - int fd, i; + struct sshkey *ca = NULL; + int fd, i, r, wild_ca = 0; char *tmp; - Buffer kbuf; + struct sshbuf *kbuf; if (*identity_file == '\0') fatal("KRL generation requires an output file"); @@ -2114,10 +2126,15 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) fatal("KRL \"%s\" does not exist", identity_file); } if (ca_key_path != NULL) { - tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); - if ((ca = key_load_public(tmp, NULL)) == NULL) - fatal("Cannot load CA public key %s", tmp); - free(tmp); + if (strcasecmp(ca_key_path, "none") == 0) + wild_ca = 1; + else { + tmp = tilde_expand_filename(ca_key_path, pw->pw_uid); + if ((r = sshkey_load_public(tmp, &ca, NULL)) != 0) + fatal("Cannot load CA public key %s: %s", + tmp, ssh_err(r)); + free(tmp); + } } if (updating) @@ -2131,21 +2148,22 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) ssh_krl_set_comment(krl, identity_comment); for (i = 0; i < argc; i++) - update_krl_from_file(pw, argv[i], ca, krl); + update_krl_from_file(pw, argv[i], wild_ca, ca, krl); - buffer_init(&kbuf); - if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0) + if ((kbuf = sshbuf_new()) == NULL) + fatal("sshbuf_new failed"); + if (ssh_krl_to_blob(krl, kbuf, NULL, 0) != 0) fatal("Couldn't generate KRL"); if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) fatal("open %s: %s", identity_file, strerror(errno)); - if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) != - buffer_len(&kbuf)) + if (atomicio(vwrite, fd, (void *)sshbuf_ptr(kbuf), sshbuf_len(kbuf)) != + sshbuf_len(kbuf)) fatal("write %s: %s", identity_file, strerror(errno)); close(fd); - buffer_free(&kbuf); + sshbuf_free(kbuf); ssh_krl_free(krl); if (ca != NULL) - key_free(ca); + sshkey_free(ca); } static void @@ -2154,27 +2172,27 @@ do_check_krl(struct passwd *pw, int argc, char **argv) int i, r, ret = 0; char *comment; struct ssh_krl *krl; - Key *k; + struct sshkey *k; if (*identity_file == '\0') fatal("KRL checking requires an input file"); load_krl(identity_file, &krl); for (i = 0; i < argc; i++) { - if ((k = key_load_public(argv[i], &comment)) == NULL) - fatal("Cannot load public key %s", argv[i]); + if ((r = sshkey_load_public(argv[i], &k, &comment)) != 0) + fatal("Cannot load public key %s: %s", + argv[i], ssh_err(r)); r = ssh_krl_check_key(krl, k); printf("%s%s%s%s: %s\n", argv[i], *comment ? " (" : "", comment, *comment ? ")" : "", r == 0 ? "ok" : "REVOKED"); if (r != 0) ret = 1; - key_free(k); + sshkey_free(k); free(comment); } ssh_krl_free(krl); exit(ret); } -#endif static void usage(void) @@ -2187,7 +2205,7 @@ usage(void) " ssh-keygen -e [-m key_format] [-f input_keyfile]\n" " ssh-keygen -y [-f input_keyfile]\n" " ssh-keygen -c [-P passphrase] [-C comment] [-f keyfile]\n" - " ssh-keygen -l [-f input_keyfile]\n" + " ssh-keygen -l [-v] [-E fingerprint_hash] [-f input_keyfile]\n" " ssh-keygen -B [-f input_keyfile]\n"); #ifdef ENABLE_PKCS11 fprintf(stderr, @@ -2217,13 +2235,13 @@ usage(void) int main(int argc, char **argv) { - char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; + char dotsshdir[PATH_MAX], comment[1024], *passphrase1, *passphrase2; char *checkpoint = NULL; - char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL; - Key *private, *public; + char out_file[PATH_MAX], *rr_hostname = NULL, *ep, *fp, *ra; + struct sshkey *private, *public; struct passwd *pw; struct stat st; - int opt, type, fd; + int r, opt, type, fd; u_int32_t memory = 0, generator_wanted = 0; int do_gen_candidates = 0, do_screen_candidates = 0; int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0; @@ -2240,7 +2258,9 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); +#endif log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); seed_rng(); @@ -2256,9 +2276,10 @@ main(int argc, char **argv) exit(1); } - /* Remaining characters: EUYdw */ + /* Remaining characters: UYdw */ while ((opt = getopt(argc, argv, "ABHLQXceghiklopquvxy" - "C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:a:b:f:g:j:m:n:r:s:t:z:")) != -1) { + "C:D:E:F:G:I:J:K:M:N:O:P:R:S:T:V:W:Z:" + "a:b:f:g:j:m:n:r:s:t:z:")) != -1) { switch (opt) { case 'A': gen_all_hostkeys = 1; @@ -2269,6 +2290,11 @@ main(int argc, char **argv) fatal("Bits has bad value %s (%s)", optarg, errstr); break; + case 'E': + fingerprint_hash = ssh_digest_alg_by_name(optarg); + if (fingerprint_hash == -1) + fatal("Invalid hash algorithm \"%s\"", optarg); + break; case 'F': find_host = 1; rr_hostname = optarg; @@ -2412,6 +2438,7 @@ main(int argc, char **argv) fatal("Invalid number: %s (%s)", optarg, errstr); break; +#ifdef WITH_OPENSSL case 'M': memory = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); if (errstr) @@ -2430,7 +2457,7 @@ main(int argc, char **argv) fatal("Output filename too long"); break; case 'K': - if (strlen(optarg) >= MAXPATHLEN) + if (strlen(optarg) >= PATH_MAX) fatal("Checkpoint filename too long"); checkpoint = xstrdup(optarg); break; @@ -2439,6 +2466,7 @@ main(int argc, char **argv) if (BN_hex2bn(&start, optarg) == 0) fatal("Invalid start point."); break; +#endif /* WITH_OPENSSL */ case 'V': parse_cert_times(optarg); break; @@ -2478,7 +2506,6 @@ main(int argc, char **argv) printf("Cannot use -l with -H or -R.\n"); usage(); } -#ifdef WITH_OPENSSL if (gen_krl) { do_gen_krl(pw, update_krl, argc, argv); return (0); @@ -2487,7 +2514,6 @@ main(int argc, char **argv) do_check_krl(pw, argc, argv); return (0); } -#endif if (ca_key_path != NULL) { if (cert_key_id == NULL) fatal("Must specify key id (-I) when certifying"); @@ -2588,17 +2614,20 @@ main(int argc, char **argv) if (key_type_name == NULL) key_type_name = "rsa"; - type = key_type_from_name(key_type_name); - type_bits_valid(type, &bits); + type = sshkey_type_from_name(key_type_name); + type_bits_valid(type, key_type_name, &bits); if (!quiet) - printf("Generating public/private %s key pair.\n", key_type_name); - private = key_generate(type, bits); - if (private == NULL) { + printf("Generating public/private %s key pair.\n", + key_type_name); + if ((r = sshkey_generate(type, bits, &private)) != 0) { fprintf(stderr, "key_generate failed\n"); exit(1); } - public = key_from_private(private); + if ((r = sshkey_from_private(private, &public)) != 0) { + fprintf(stderr, "key_from_private failed: %s\n", ssh_err(r)); + exit(1); + } if (!have_identity) ask_filename(pw, "Enter file in which to save the key"); @@ -2666,9 +2695,10 @@ main(int argc, char **argv) } /* Save the key with the given passphrase and comment. */ - if (!key_save_private(private, identity_file, passphrase1, comment, - use_new_format, new_format_cipher, rounds)) { - printf("Saving the key failed: %s.\n", identity_file); + if ((r = sshkey_save_private(private, identity_file, passphrase1, + comment, use_new_format, new_format_cipher, rounds)) != 0) { + printf("Saving key \"%s\" failed: %s\n", + identity_file, ssh_err(r)); explicit_bzero(passphrase1, strlen(passphrase1)); free(passphrase1); exit(1); @@ -2678,7 +2708,7 @@ main(int argc, char **argv) free(passphrase1); /* Clear the private key and the random number generator. */ - key_free(private); + sshkey_free(private); if (!quiet) printf("Your identification has been saved in %s.\n", identity_file); @@ -2694,15 +2724,18 @@ main(int argc, char **argv) printf("fdopen %s failed\n", identity_file); exit(1); } - if (!key_write(public, f)) - fprintf(stderr, "write key failed\n"); + if ((r = sshkey_write(public, f)) != 0) + fprintf(stderr, "write key failed: %s\n", ssh_err(r)); fprintf(f, " %s\n", comment); fclose(f); if (!quiet) { - char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); - char *ra = key_fingerprint(public, SSH_FP_MD5, + fp = sshkey_fingerprint(public, fingerprint_hash, + SSH_FP_DEFAULT); + ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("sshkey_fingerprint failed"); printf("Your public key has been saved in %s.\n", identity_file); printf("The key fingerprint is:\n"); @@ -2713,6 +2746,6 @@ main(int argc, char **argv) free(fp); } - key_free(public); + sshkey_free(public); exit(0); } diff --git a/crypto/openssh/ssh-keyscan.0 b/crypto/openssh/ssh-keyscan.0 index 853bd5152502..fe7aa8559185 100644 --- a/crypto/openssh/ssh-keyscan.0 +++ b/crypto/openssh/ssh-keyscan.0 @@ -1,7 +1,7 @@ SSH-KEYSCAN(1) General Commands Manual SSH-KEYSCAN(1) NAME - ssh-keyscan - gather ssh public keys + ssh-keyscan M-bM-^@M-^S gather ssh public keys SYNOPSIS ssh-keyscan [-46Hv] [-f file] [-p port] [-T timeout] [-t type] @@ -27,10 +27,9 @@ DESCRIPTION -6 Forces ssh-keyscan to use IPv6 addresses only. -f file - Read hosts or ``addrlist namelist'' pairs from file, one per - line. If - is supplied instead of a filename, ssh-keyscan will - read hosts or ``addrlist namelist'' pairs from the standard - input. + Read hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from file, one per line. + If - is supplied instead of a filename, ssh-keyscan will read + hosts or M-bM-^@M-^\addrlist namelistM-bM-^@M-^] pairs from the standard input. -H Hash all hostnames and addresses in the output. Hashed names may be used normally by ssh and sshd, but they do not reveal @@ -48,11 +47,10 @@ DESCRIPTION -t type Specifies the type of the key to fetch from the scanned hosts. - The possible values are ``rsa1'' for protocol version 1 and - ``dsa'', ``ecdsa'', ``ed25519'', or ``rsa'' for protocol version - 2. Multiple values may be specified by separating them with - commas. The default is to fetch ``rsa'', ``ecdsa'', and - ``ed25519'' keys. + The possible values are M-bM-^@M-^\rsa1M-bM-^@M-^] for protocol version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], + M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^] for protocol version 2. Multiple + values may be specified by separating them with commas. The + default is to fetch M-bM-^@M-^\rsaM-bM-^@M-^], M-bM-^@M-^\ecdsaM-bM-^@M-^], and M-bM-^@M-^\ed25519M-bM-^@M-^] keys. -v Verbose mode. Causes ssh-keyscan to print debugging messages about its progress. @@ -74,12 +72,12 @@ FILES host-or-namelist bits exponent modulus - Output format for RSA, DSA, ECDSA, and ED25519 keys: + Output format for RSA, DSA, ECDSA, and Ed25519 keys: host-or-namelist keytype base64-encoded-key - Where keytype is either ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'', - ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', ``ssh-dss'' or ``ssh-rsa''. + Where keytype is either M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^], + M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or M-bM-^@M-^\ssh-rsaM-bM-^@M-^]. /etc/ssh/ssh_known_hosts @@ -108,4 +106,4 @@ BUGS This is because it opens a connection to the ssh port, reads the public key, and drops the connection as soon as it gets the key. -OpenBSD 5.6 March 12, 2014 OpenBSD 5.6 +OpenBSD 5.7 August 30, 2014 OpenBSD 5.7 diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1 index 5c32ea9c704e..6bbc480cd5c6 100644 --- a/crypto/openssh/ssh-keyscan.1 +++ b/crypto/openssh/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.35 2014/03/12 13:06:59 naddy Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.36 2014/08/30 15:33:50 sobrado Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: March 12 2014 $ +.Dd $Mdocdate: August 30 2014 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -130,7 +130,7 @@ Output format for RSA1 keys: host-or-namelist bits exponent modulus .Ed .Pp -Output format for RSA, DSA, ECDSA, and ED25519 keys: +Output format for RSA, DSA, ECDSA, and Ed25519 keys: .Bd -literal host-or-namelist keytype base64-encoded-key .Ed diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c index 3fabfba14076..c5fb3b524fcc 100644 --- a/crypto/openssh/ssh-keyscan.c +++ b/crypto/openssh/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.92 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.99 2015/01/30 10:44:49 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -9,6 +9,7 @@ #include "includes.h" +#include #include "openbsd-compat/sys-queue.h" #include #ifdef HAVE_SYS_TIME_H @@ -22,7 +23,6 @@ #include #include -#include #include #include #include @@ -33,8 +33,8 @@ #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" -#include "buffer.h" -#include "key.h" +#include "sshbuf.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" #include "compat.h" @@ -45,6 +45,8 @@ #include "atomicio.h" #include "misc.h" #include "hostfile.h" +#include "ssherr.h" +#include "ssh_api.h" /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. Default value is AF_UNSPEC means both IPv4 and IPv6. */ @@ -74,9 +76,8 @@ extern char *__progname; fd_set *read_wait; size_t read_wait_nfdset; int ncon; -int nonfatal_fatal = 0; -jmp_buf kexjmp; -Key *kexjmp_key; + +struct ssh *active_state = NULL; /* XXX needed for linking */ /* * Keep a connection structure for each file descriptor. The state @@ -93,12 +94,13 @@ typedef struct Connection { int c_len; /* Total bytes which must be read. */ int c_off; /* Length of data read so far. */ int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */ + int c_done; /* SSH2 done */ char *c_namebase; /* Address to free for c_name and c_namelist */ char *c_name; /* Hostname of connection for errors */ char *c_namelist; /* Pointer to other possible addresses */ char *c_output_name; /* Hostname of connection for output */ char *c_data; /* Data read from this fd */ - Kex *c_kex; /* The key-exchange struct for ssh2 */ + struct ssh *c_ssh; /* SSH-connection */ struct timeval c_tv; /* Time at which connection gets aborted */ TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */ } con; @@ -106,6 +108,8 @@ typedef struct Connection { TAILQ_HEAD(conlist, Connection) tq; /* Timeout Queue */ con *fdcon; +static void keyprint(con *c, struct sshkey *key); + static int fdlim_get(int hard) { @@ -183,46 +187,61 @@ strnnsep(char **stringp, char *delim) } #ifdef WITH_SSH1 -static Key * +static struct sshkey * keygrab_ssh1(con *c) { - static Key *rsa; - static Buffer msg; + static struct sshkey *rsa; + static struct sshbuf *msg; + int r; + u_char type; if (rsa == NULL) { - buffer_init(&msg); - rsa = key_new(KEY_RSA1); + if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { + error("%s: sshkey_new failed", __func__); + return NULL; + } + if ((msg = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); } - buffer_append(&msg, c->c_data, c->c_plen); - buffer_consume(&msg, 8 - (c->c_plen & 7)); /* padding */ - if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) { + if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 || + (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */ + (r = sshbuf_get_u8(msg, &type)) != 0) + goto buf_err; + if (type != (int) SSH_SMSG_PUBLIC_KEY) { error("%s: invalid packet type", c->c_name); - buffer_clear(&msg); + sshbuf_reset(msg); + return NULL; + } + if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ + /* server key */ + (r = sshbuf_get_u32(msg, NULL)) != 0 || + (r = sshbuf_get_bignum1(msg, NULL)) != 0 || + (r = sshbuf_get_bignum1(msg, NULL)) != 0 || + /* host key */ + (r = sshbuf_get_u32(msg, NULL)) != 0 || + (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || + (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { + buf_err: + error("%s: buffer error: %s", __func__, ssh_err(r)); + sshbuf_reset(msg); return NULL; } - buffer_consume(&msg, 8); /* cookie */ - /* server key */ - (void) buffer_get_int(&msg); - buffer_get_bignum(&msg, rsa->rsa->e); - buffer_get_bignum(&msg, rsa->rsa->n); - - /* host key */ - (void) buffer_get_int(&msg); - buffer_get_bignum(&msg, rsa->rsa->e); - buffer_get_bignum(&msg, rsa->rsa->n); - - buffer_clear(&msg); + sshbuf_reset(msg); return (rsa); } #endif static int -hostjump(Key *hostkey) +key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) { - kexjmp_key = hostkey; - longjmp(kexjmp, 1); + con *c; + + if ((c = ssh_get_app_data(ssh)) != NULL) + keyprint(c, hostkey); + /* always abort key exchange */ + return -1; } static int @@ -241,46 +260,43 @@ ssh2_capable(int remote_major, int remote_minor) return 0; } -static Key * +static void keygrab_ssh2(con *c) { char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; - int j; + int r; - packet_set_connection(c->c_fd, c->c_fd); enable_compat20(); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA ? "ssh-dss" : (c->c_keytype == KT_RSA ? "ssh-rsa" : (c->c_keytype == KT_ED25519 ? "ssh-ed25519" : "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521")); - c->c_kex = kex_setup(myproposal); -#ifdef WITH_OPENSSL - c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; - c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; - c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; - c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; - c->c_kex->kex[KEX_ECDH_SHA2] = kexecdh_client; -#endif - c->c_kex->kex[KEX_C25519_SHA256] = kexc25519_client; - c->c_kex->verify_host_key = hostjump; - - if (!(j = setjmp(kexjmp))) { - nonfatal_fatal = 1; - dispatch_run(DISPATCH_BLOCK, &c->c_kex->done, c->c_kex); - fprintf(stderr, "Impossible! dispatch_run() returned!\n"); + if ((r = kex_setup(c->c_ssh, myproposal)) != 0) { + free(c->c_ssh); + fprintf(stderr, "kex_setup: %s\n", ssh_err(r)); exit(1); } - nonfatal_fatal = 0; - free(c->c_kex); - c->c_kex = NULL; - packet_close(); - - return j < 0? NULL : kexjmp_key; +#ifdef WITH_OPENSSL + c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; + c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; + c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; + c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; +# ifdef OPENSSL_HAS_ECC + c->c_ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; +# endif +#endif + c->c_ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; + ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper); + /* + * do the key-exchange until an error occurs or until + * the key_print_wrapper() callback sets c_done. + */ + ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done, c->c_ssh); } static void -keyprint(con *c, Key *key) +keyprint(con *c, struct sshkey *key) { char *host = c->c_output_name ? c->c_output_name : c->c_name; @@ -290,7 +306,7 @@ keyprint(con *c, Key *key) fatal("host_hash failed"); fprintf(stdout, "%s ", host); - key_write(key, stdout); + sshkey_write(key, stdout); fputs("\n", stdout); } @@ -305,8 +321,10 @@ tcpconnect(char *host) memset(&hints, 0, sizeof(hints)); hints.ai_family = IPv4or6; hints.ai_socktype = SOCK_STREAM; - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); + if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { + error("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); + return -1; + } for (ai = aitop; ai; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { @@ -378,6 +396,11 @@ confree(int s) free(fdcon[s].c_data); fdcon[s].c_status = CS_UNUSED; fdcon[s].c_keytype = 0; + if (fdcon[s].c_ssh) { + ssh_packet_close(fdcon[s].c_ssh); + free(fdcon[s].c_ssh); + fdcon[s].c_ssh = NULL; + } TAILQ_REMOVE(&tq, &fdcon[s], c_link); FD_CLR(s, read_wait); ncon--; @@ -445,11 +468,15 @@ congreet(int s) return; } *cp = '\0'; + if ((c->c_ssh = ssh_packet_set_connection(NULL, s, s)) == NULL) + fatal("ssh_packet_set_connection failed"); + ssh_packet_set_timeout(c->c_ssh, timeout, 1); + ssh_set_app_data(c->c_ssh, c); /* back link */ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) == 3) - compat_datafellows(remote_version); + c->c_ssh->compat = compat_datafellows(remote_version); else - datafellows = 0; + c->c_ssh->compat = 0; if (c->c_keytype != KT_RSA1) { if (!ssh2_capable(remote_major, remote_minor)) { debug("%s doesn't support ssh2", c->c_name); @@ -476,7 +503,7 @@ congreet(int s) return; } if (c->c_keytype != KT_RSA1) { - keyprint(c, keygrab_ssh2(c)); + keygrab_ssh2(c); confree(s); return; } @@ -602,10 +629,7 @@ fatal(const char *fmt,...) va_start(args, fmt); do_log(SYSLOG_LEVEL_FATAL, fmt, args); va_end(args); - if (nonfatal_fatal) - longjmp(kexjmp, -1); - else - exit(255); + exit(255); } static void @@ -678,7 +702,7 @@ main(int argc, char **argv) get_keytypes = 0; tname = strtok(optarg, ","); while (tname) { - int type = key_type_from_name(tname); + int type = sshkey_type_from_name(tname); switch (type) { case KEY_RSA1: get_keytypes |= KT_RSA1; diff --git a/crypto/openssh/ssh-keysign.0 b/crypto/openssh/ssh-keysign.0 index c34125b72911..b06107617b87 100644 --- a/crypto/openssh/ssh-keysign.0 +++ b/crypto/openssh/ssh-keysign.0 @@ -1,7 +1,7 @@ SSH-KEYSIGN(8) System Manager's Manual SSH-KEYSIGN(8) NAME - ssh-keysign - ssh helper program for host-based authentication + ssh-keysign M-bM-^@M-^S ssh helper program for host-based authentication SYNOPSIS ssh-keysign @@ -13,7 +13,7 @@ DESCRIPTION ssh-keysign is disabled by default and can only be enabled in the global client configuration file /etc/ssh/ssh_config by setting EnableSSHKeysign - to ``yes''. + to M-bM-^@M-^\yesM-bM-^@M-^]. ssh-keysign is not intended to be invoked by the user, but from ssh(1). See ssh(1) and sshd(8) for more information about host-based @@ -50,4 +50,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.6 December 7, 2013 OpenBSD 5.6 +OpenBSD 5.7 December 7, 2013 OpenBSD 5.7 diff --git a/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c index d95bb7d9d883..bcf897a05400 100644 --- a/crypto/openssh/ssh-keysign.c +++ b/crypto/openssh/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.42 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.47 2015/01/28 22:36:00 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -35,23 +35,29 @@ #include #include +#ifdef WITH_OPENSSL #include #include #include +#endif #include "xmalloc.h" #include "log.h" -#include "key.h" +#include "sshkey.h" #include "ssh.h" #include "ssh2.h" #include "misc.h" -#include "buffer.h" +#include "sshbuf.h" #include "authfile.h" #include "msg.h" #include "canohost.h" #include "pathnames.h" #include "readconf.h" #include "uidswap.h" +#include "sshkey.h" +#include "ssherr.h" + +struct ssh *active_state = NULL; /* XXX needed for linking */ /* XXX readconf.c needs these */ uid_t original_real_uid; @@ -59,62 +65,73 @@ uid_t original_real_uid; extern char *__progname; static int -valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, - u_int datalen) +valid_request(struct passwd *pw, char *host, struct sshkey **ret, + u_char *data, size_t datalen) { - Buffer b; - Key *key = NULL; - u_char *pkblob; - u_int blen, len; - char *pkalg, *p; - int pktype, fail; + struct sshbuf *b; + struct sshkey *key = NULL; + u_char type, *pkblob; + char *p; + size_t blen, len; + char *pkalg, *luser; + int r, pktype, fail; + if (ret != NULL) + *ret = NULL; fail = 0; - buffer_init(&b); - buffer_append(&b, data, datalen); + if ((b = sshbuf_from(data, datalen)) == NULL) + fatal("%s: sshbuf_from failed", __func__); /* session id, currently limited to SHA1 (20 bytes) or SHA256 (32) */ - p = buffer_get_string(&b, &len); + if ((r = sshbuf_get_string(b, NULL, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (len != 20 && len != 32) fail++; - free(p); - if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + if ((r = sshbuf_get_u8(b, &type)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (type != SSH2_MSG_USERAUTH_REQUEST) fail++; /* server user */ - buffer_skip_string(&b); + if ((r = sshbuf_skip_string(b)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* service */ - p = buffer_get_string(&b, NULL); + if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp("ssh-connection", p) != 0) fail++; free(p); /* method */ - p = buffer_get_string(&b, NULL); + if ((r = sshbuf_get_cstring(b, &p, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (strcmp("hostbased", p) != 0) fail++; free(p); /* pubkey */ - pkalg = buffer_get_string(&b, NULL); - pkblob = buffer_get_string(&b, &blen); + if ((r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || + (r = sshbuf_get_string(b, &pkblob, &blen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - pktype = key_type_from_name(pkalg); + pktype = sshkey_type_from_name(pkalg); if (pktype == KEY_UNSPEC) fail++; - else if ((key = key_from_blob(pkblob, blen)) == NULL) + else if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { + error("%s: bad key blob: %s", __func__, ssh_err(r)); fail++; - else if (key->type != pktype) + } else if (key->type != pktype) fail++; free(pkalg); free(pkblob); /* client host name, handle trailing dot */ - p = buffer_get_string(&b, &len); - debug2("valid_request: check expect chost %s got %s", host, p); + if ((r = sshbuf_get_cstring(b, &p, &len)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug2("%s: check expect chost %s got %s", __func__, host, p); if (strlen(host) != len - 1) fail++; else if (p[len - 1] != '.') @@ -124,21 +141,22 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, free(p); /* local user */ - p = buffer_get_string(&b, NULL); + if ((r = sshbuf_get_cstring(b, &luser, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (strcmp(pw->pw_name, p) != 0) + if (strcmp(pw->pw_name, luser) != 0) fail++; - free(p); + free(luser); /* end of message */ - if (buffer_len(&b) != 0) + if (sshbuf_len(b) != 0) fail++; - buffer_free(&b); + sshbuf_free(b); - debug3("valid_request: fail %d", fail); + debug3("%s: fail %d", __func__, fail); if (fail && key != NULL) - key_free(key); + sshkey_free(key); else *ret = key; @@ -148,16 +166,18 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, int main(int argc, char **argv) { - Buffer b; + struct sshbuf *b; Options options; #define NUM_KEYTYPES 4 - Key *keys[NUM_KEYTYPES], *key = NULL; + struct sshkey *keys[NUM_KEYTYPES], *key = NULL; struct passwd *pw; - int key_fd[NUM_KEYTYPES], i, found, version = 2, fd; - u_char *signature, *data; + int r, key_fd[NUM_KEYTYPES], i, found, version = 2, fd; + u_char *signature, *data, rver; char *host, *fp; - u_int slen, dlen; + size_t slen, dlen; +#ifdef WITH_OPENSSL u_int32_t rnd[256]; +#endif /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) @@ -187,7 +207,7 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", &options, 0); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0); fill_default_options(&options); if (options.enable_ssh_keysign != 1) fatal("ssh-keysign not enabled in %s", @@ -200,39 +220,47 @@ main(int argc, char **argv) if (found == 0) fatal("could not open any host key"); +#ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); arc4random_buf(rnd, sizeof(rnd)); RAND_seed(rnd, sizeof(rnd)); +#endif found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { keys[i] = NULL; if (key_fd[i] == -1) continue; -#ifdef WITH_OPENSSL -/* XXX wrong api */ - keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC, - NULL, NULL); -#endif + r = sshkey_load_private_type_fd(key_fd[i], KEY_UNSPEC, + NULL, &key, NULL); close(key_fd[i]); - if (keys[i] != NULL) + if (r != 0) + debug("parse key %d: %s", i, ssh_err(r)); + else if (key != NULL) { + keys[i] = key; found = 1; + } } if (!found) fatal("no hostkey found"); - buffer_init(&b); - if (ssh_msg_recv(STDIN_FILENO, &b) < 0) + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if (ssh_msg_recv(STDIN_FILENO, b) < 0) fatal("ssh_msg_recv failed"); - if (buffer_get_char(&b) != version) - fatal("bad version"); - fd = buffer_get_int(&b); - if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO)) + if ((r = sshbuf_get_u8(b, &rver)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (rver != version) + fatal("bad version: received %d, expected %d", rver, version); + if ((r = sshbuf_get_u32(b, (u_int *)&fd)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (fd < 0 || fd == STDIN_FILENO || fd == STDOUT_FILENO) fatal("bad fd"); if ((host = get_local_name(fd)) == NULL) fatal("cannot get local name for fd"); - data = buffer_get_string(&b, &dlen); + if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (valid_request(pw, host, &key, data, dlen) < 0) fatal("not a valid request"); free(host); @@ -240,25 +268,28 @@ main(int argc, char **argv) found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { if (keys[i] != NULL && - key_equal_public(key, keys[i])) { + sshkey_equal_public(key, keys[i])) { found = 1; break; } } if (!found) { - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + fatal("%s: sshkey_fingerprint failed", __func__); fatal("no matching hostkey found for key %s %s", - key_type(key), fp); + sshkey_type(key), fp ? fp : ""); } - if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) - fatal("key_sign failed"); + if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, 0)) != 0) + fatal("sshkey_sign failed: %s", ssh_err(r)); free(data); /* send reply */ - buffer_clear(&b); - buffer_put_string(&b, signature, slen); - if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1) + sshbuf_reset(b); + if ((r = sshbuf_put_string(b, signature, slen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (ssh_msg_send(STDOUT_FILENO, version, b) == -1) fatal("ssh_msg_send failed"); return (0); diff --git a/crypto/openssh/ssh-pkcs11-helper.0 b/crypto/openssh/ssh-pkcs11-helper.0 index 279ec548688e..a4d6dd4c06e5 100644 --- a/crypto/openssh/ssh-pkcs11-helper.0 +++ b/crypto/openssh/ssh-pkcs11-helper.0 @@ -1,7 +1,7 @@ SSH-PKCS11-HELPER(8) System Manager's Manual SSH-PKCS11-HELPER(8) NAME - ssh-pkcs11-helper - ssh-agent helper program for PKCS#11 support + ssh-pkcs11-helper M-bM-^@M-^S ssh-agent helper program for PKCS#11 support SYNOPSIS ssh-pkcs11-helper @@ -22,4 +22,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.6 July 16, 2013 OpenBSD 5.6 +OpenBSD 5.7 July 16, 2013 OpenBSD 5.7 diff --git a/crypto/openssh/ssh-pkcs11-helper.c b/crypto/openssh/ssh-pkcs11-helper.c index 0b1d8e4cc4cc..ceabc8ba7fe4 100644 --- a/crypto/openssh/ssh-pkcs11-helper.c +++ b/crypto/openssh/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.8 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.10 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * diff --git a/crypto/openssh/ssh-pkcs11.c b/crypto/openssh/ssh-pkcs11.c index c96be3bd2c3f..c3a112fa16c0 100644 --- a/crypto/openssh/ssh-pkcs11.c +++ b/crypto/openssh/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.14 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.17 2015/02/03 08:07:20 deraadt Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -38,7 +38,7 @@ #include "log.h" #include "misc.h" -#include "key.h" +#include "sshkey.h" #include "ssh-pkcs11.h" #include "xmalloc.h" @@ -263,8 +263,9 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, pin = read_passphrase(prompt, RP_ALLOW_EOF); if (pin == NULL) return (-1); /* bail out */ - if ((rv = f->C_Login(si->session, CKU_USER, - (u_char *)pin, strlen(pin))) != CKR_OK) { + rv = f->C_Login(si->session, CKU_USER, + (u_char *)pin, strlen(pin)); + if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { free(pin); error("C_Login failed: %lu", rv); return (-1); @@ -366,8 +367,9 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) return (-1); } if (login_required && pin) { - if ((rv = f->C_Login(session, CKU_USER, - (u_char *)pin, strlen(pin))) != CKR_OK) { + rv = f->C_Login(session, CKU_USER, + (u_char *)pin, strlen(pin)); + if (rv != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN) { error("C_Login failed: %lu", rv); if ((rv = f->C_CloseSession(session)) != CKR_OK) error("C_CloseSession failed: %lu", rv); @@ -385,12 +387,12 @@ pkcs11_open_session(struct pkcs11_provider *p, CK_ULONG slotidx, char *pin) * keysp points to an (possibly empty) array with *nkeys keys. */ static int pkcs11_fetch_keys_filter(struct pkcs11_provider *, CK_ULONG, - CK_ATTRIBUTE [], CK_ATTRIBUTE [3], Key ***, int *) + CK_ATTRIBUTE [], CK_ATTRIBUTE [3], struct sshkey ***, int *) __attribute__((__bounded__(__minbytes__,4, 3 * sizeof(CK_ATTRIBUTE)))); static int pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, - Key ***keysp, int *nkeys) + struct sshkey ***keysp, int *nkeys) { CK_OBJECT_CLASS pubkey_class = CKO_PUBLIC_KEY; CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; @@ -422,12 +424,12 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, } static int -pkcs11_key_included(Key ***keysp, int *nkeys, Key *key) +pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key) { int i; for (i = 0; i < *nkeys; i++) - if (key_equal(key, (*keysp)[i])) + if (sshkey_equal(key, (*keysp)[i])) return (1); return (0); } @@ -435,9 +437,9 @@ pkcs11_key_included(Key ***keysp, int *nkeys, Key *key) static int pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, CK_ATTRIBUTE filter[], CK_ATTRIBUTE attribs[3], - Key ***keysp, int *nkeys) + struct sshkey ***keysp, int *nkeys) { - Key *key; + struct sshkey *key; RSA *rsa; X509 *x509; EVP_PKEY *evp; @@ -517,16 +519,16 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, } if (rsa && rsa->n && rsa->e && pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) { - key = key_new(KEY_UNSPEC); + key = sshkey_new(KEY_UNSPEC); key->rsa = rsa; key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; if (pkcs11_key_included(keysp, nkeys, key)) { - key_free(key); + sshkey_free(key); } else { /* expand key array and add key */ *keysp = xrealloc(*keysp, *nkeys + 1, - sizeof(Key *)); + sizeof(struct sshkey *)); (*keysp)[*nkeys] = key; *nkeys = *nkeys + 1; debug("have %d keys", *nkeys); @@ -544,7 +546,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, /* register a new provider, fails if provider already exists */ int -pkcs11_add_provider(char *provider_id, char *pin, Key ***keyp) +pkcs11_add_provider(char *provider_id, char *pin, struct sshkey ***keyp) { int nkeys, need_finalize = 0; struct pkcs11_provider *p = NULL; diff --git a/crypto/openssh/ssh-pkcs11.h b/crypto/openssh/ssh-pkcs11.h index 4d2efda13f15..0ced74f29ce7 100644 --- a/crypto/openssh/ssh-pkcs11.h +++ b/crypto/openssh/ssh-pkcs11.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.h,v 1.3 2014/04/29 18:01:49 markus Exp $ */ +/* $OpenBSD: ssh-pkcs11.h,v 1.4 2015/01/15 09:40:00 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -16,7 +16,7 @@ */ int pkcs11_init(int); void pkcs11_terminate(void); -int pkcs11_add_provider(char *, char *, Key ***); +int pkcs11_add_provider(char *, char *, struct sshkey ***); int pkcs11_del_provider(char *); #if !defined(WITH_OPENSSL) && defined(ENABLE_PKCS11) diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c index fec1953b49a1..aef798da62c4 100644 --- a/crypto/openssh/ssh-rsa.c +++ b/crypto/openssh/ssh-rsa.c @@ -17,6 +17,8 @@ #include "includes.h" +#ifdef WITH_OPENSSL + #include #include @@ -263,3 +265,4 @@ openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, } return ret; } +#endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/ssh.0 b/crypto/openssh/ssh.0 index 70ea37733885..5e5f3b5e93e3 100644 --- a/crypto/openssh/ssh.0 +++ b/crypto/openssh/ssh.0 @@ -1,15 +1,15 @@ SSH(1) General Commands Manual SSH(1) NAME - ssh - OpenSSH SSH client (remote login program) + ssh M-bM-^@M-^S OpenSSH SSH client (remote login program) SYNOPSIS - ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] + ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] - [-Q cipher | cipher-auth | mac | kex | key] + [-Q cipher | cipher-auth | mac | kex | key | protocol-version] [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command] @@ -61,7 +61,7 @@ DESCRIPTION -C Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11, TCP and UNIX-domain connections). The compression algorithm is the same used by - gzip(1), and the ``level'' can be controlled by the + gzip(1), and the M-bM-^@M-^\levelM-bM-^@M-^] can be controlled by the CompressionLevel option for protocol version 1. Compression is desirable on modem lines and other slow connections, but will only slow down things on fast networks. The default value can be @@ -72,13 +72,13 @@ DESCRIPTION Selects the cipher specification for encrypting the session. Protocol version 1 allows specification of a single cipher. The - supported values are ``3des'', ``blowfish'', and ``des''. For - protocol version 2, cipher_spec is a comma-separated list of - ciphers listed in order of preference. See the Ciphers keyword - in ssh_config(5) for more information. + supported values are M-bM-^@M-^\3desM-bM-^@M-^], M-bM-^@M-^\blowfishM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^]. For protocol + version 2, cipher_spec is a comma-separated list of ciphers + listed in order of preference. See the Ciphers keyword in + ssh_config(5) for more information. -D [bind_address:]port - Specifies a local ``dynamic'' application-level port forwarding. + Specifies a local M-bM-^@M-^\dynamicM-bM-^@M-^] application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over @@ -94,20 +94,20 @@ DESCRIPTION ports. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The - bind_address of ``localhost'' indicates that the listening port - be bound for local use only, while an empty address or `*' - indicates that the port should be available from all interfaces. + bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be + bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates + that the port should be available from all interfaces. -E log_file Append debug logs to log_file instead of standard error. -e escape_char - Sets the escape character for sessions with a pty (default: `~'). + Sets the escape character for sessions with a pty (default: M-bM-^@M-^X~M-bM-^@M-^Y). The escape character is only recognized at the beginning of a - line. The escape character followed by a dot (`.') closes the + line. The escape character followed by a dot (M-bM-^@M-^X.M-bM-^@M-^Y) closes the connection; followed by control-Z suspends the connection; and followed by itself sends the escape character once. Setting the - character to ``none'' disables any escapes and makes the session + character to M-bM-^@M-^\noneM-bM-^@M-^] disables any escapes and makes the session fully transparent. -F configfile @@ -122,10 +122,13 @@ DESCRIPTION implies -n. The recommended way to start X11 programs at a remote site is with something like ssh -f host xterm. - If the ExitOnForwardFailure configuration option is set to - ``yes'', then a client started with -f will wait for all remote - port forwards to be successfully established before placing - itself in the background. + If the ExitOnForwardFailure configuration option is set to M-bM-^@M-^\yesM-bM-^@M-^], + then a client started with -f will wait for all remote port + forwards to be successfully established before placing itself in + the background. + + -G Causes ssh to print its configuration after evaluating Host and + Match blocks and exit. -g Allows remote hosts to connect to local forwarded ports. If used on a multiplexed connection, then this option must be specified @@ -166,17 +169,17 @@ DESCRIPTION port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of - ``localhost'' indicates that the listening port be bound for - local use only, while an empty address or `*' indicates that the - port should be available from all interfaces. + M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local + use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port + should be available from all interfaces. -l login_name Specifies the user to log in as on the remote machine. This also may be specified on a per-host basis in the configuration file. - -M Places the ssh client into ``master'' mode for connection - sharing. Multiple -M options places ssh into ``master'' mode - with confirmation required before slave connections are accepted. + -M Places the ssh client into M-bM-^@M-^\masterM-bM-^@M-^] mode for connection sharing. + Multiple -M options places ssh into M-bM-^@M-^\masterM-bM-^@M-^] mode with + confirmation required before slave connections are accepted. Refer to the description of ControlMaster in ssh_config(5) for details. @@ -201,10 +204,10 @@ DESCRIPTION -O ctl_cmd Control an active connection multiplexing master process. When the -O option is specified, the ctl_cmd argument is interpreted - and passed to the master process. Valid commands are: ``check'' - (check that the master process is running), ``forward'' (request - forwardings without command execution), ``cancel'' (cancel - forwardings), ``exit'' (request the master to exit), and ``stop'' + and passed to the master process. Valid commands are: M-bM-^@M-^\checkM-bM-^@M-^] + (check that the master process is running), M-bM-^@M-^\forwardM-bM-^@M-^] (request + forwardings without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel + forwardings), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] (request the master to stop accepting further multiplexing requests). @@ -238,6 +241,7 @@ DESCRIPTION DynamicForward EscapeChar ExitOnForwardFailure + FingerprintHash ForwardAgent ForwardX11 ForwardX11Timeout @@ -249,6 +253,7 @@ DESCRIPTION HashKnownHosts Host HostbasedAuthentication + HostbasedKeyTypes HostKeyAlgorithms HostKeyAlias HostName @@ -288,6 +293,7 @@ DESCRIPTION TCPKeepAlive Tunnel TunnelDevice + UpdateHostKeys UsePrivilegedPort User UserKnownHostsFile @@ -299,12 +305,13 @@ DESCRIPTION Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. - -Q cipher | cipher-auth | mac | kex | key + -Q cipher | cipher-auth | mac | kex | key | protocol-version Queries ssh for the algorithms supported for the specified version 2. The available features are: cipher (supported symmetric ciphers), cipher-auth (supported symmetric ciphers that support authenticated encryption), mac (supported message - integrity codes), kex (key exchange algorithms), key (key types). + integrity codes), kex (key exchange algorithms), key (key types) + and protocol-version (supported SSH protocol versions). -q Quiet mode. Causes most warning and diagnostic messages to be suppressed. @@ -325,19 +332,19 @@ DESCRIPTION By default, the listening socket on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address - `*', indicates that the remote socket should listen on all + M-bM-^@M-^X*M-bM-^@M-^Y, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)). - If the port argument is `0', the listen port will be dynamically + If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically allocated on the server and reported to the client at run time. When used together with -O forward the allocated port will be printed to the standard output. -S ctl_path Specifies the location of a control socket for connection - sharing, or the string ``none'' to disable connection sharing. + sharing, or the string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing. Refer to the description of ControlPath and ControlMaster in ssh_config(5) for details. @@ -373,11 +380,11 @@ DESCRIPTION (remote_tun). The devices may be specified by numerical ID or the keyword - ``any'', which uses the next available tunnel device. If - remote_tun is not specified, it defaults to ``any''. See also - the Tunnel and TunnelDevice directives in ssh_config(5). If the + M-bM-^@M-^\anyM-bM-^@M-^], which uses the next available tunnel device. If + remote_tun is not specified, it defaults to M-bM-^@M-^\anyM-bM-^@M-^]. See also the + Tunnel and TunnelDevice directives in ssh_config(5). If the Tunnel directive is unset, it is set to the default tunnel mode, - which is ``point-to-point''. + which is M-bM-^@M-^\point-to-pointM-bM-^@M-^]. -X Enables X11 forwarding. This can also be specified on a per-host basis in a configuration file. @@ -444,7 +451,7 @@ AUTHENTICATION creates a public/private key pair for authentication purposes. The server knows the public key, and only the user knows the private key. ssh implements public key authentication protocol automatically, using - one of the DSA, ECDSA, ED25519 or RSA algorithms. Protocol 1 is + one of the DSA, ECDSA, Ed25519 or RSA algorithms. Protocol 1 is restricted to using only RSA keys, but protocol 2 may use any. The HISTORY section of ssl(8) contains a brief discussion of the DSA and RSA algorithms. @@ -458,10 +465,10 @@ AUTHENTICATION The user creates his/her key pair by running ssh-keygen(1). This stores the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (protocol 2 DSA), ~/.ssh/id_ecdsa (protocol 2 ECDSA), ~/.ssh/id_ed25519 (protocol 2 - ED25519), or ~/.ssh/id_rsa (protocol 2 RSA) and stores the public key in + Ed25519), or ~/.ssh/id_rsa (protocol 2 RSA) and stores the public key in ~/.ssh/identity.pub (protocol 1), ~/.ssh/id_dsa.pub (protocol 2 DSA), ~/.ssh/id_ecdsa.pub (protocol 2 ECDSA), ~/.ssh/id_ed25519.pub (protocol 2 - ED25519), or ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home + Ed25519), or ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home directory. The user should then copy the public key to ~/.ssh/authorized_keys in his/her home directory on the remote machine. The authorized_keys file corresponds to the conventional ~/.rhosts file, @@ -512,8 +519,8 @@ AUTHENTICATION If no pseudo-tty has been allocated, the session is transparent and can be used to reliably transfer binary data. On most systems, setting the - escape character to ``none'' will also make the session transparent even - if a tty is used. + escape character to M-bM-^@M-^\noneM-bM-^@M-^] will also make the session transparent even if + a tty is used. The session terminates when the command or shell on the remote machine exits and all X11 and TCP connections have been closed. @@ -528,7 +535,7 @@ ESCAPE CHARACTERS character can be changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option. - The supported escapes (assuming the default `~') are: + The supported escapes (assuming the default M-bM-^@M-^X~M-bM-^@M-^Y) are: ~. Disconnect. @@ -577,26 +584,26 @@ TCP FORWARDING same local port, and ssh will encrypt and forward the connection. The following example tunnels an IRC session from client machine - ``127.0.0.1'' (localhost) to remote server ``server.example.com'': + M-bM-^@M-^\127.0.0.1M-bM-^@M-^] (localhost) to remote server M-bM-^@M-^\server.example.comM-bM-^@M-^]: $ ssh -f -L 1234:localhost:6667 server.example.com sleep 10 $ irc -c '#users' -p 1234 pinky 127.0.0.1 - This tunnels a connection to IRC server ``server.example.com'', joining - channel ``#users'', nickname ``pinky'', using port 1234. It doesn't - matter which port is used, as long as it's greater than 1023 (remember, - only root can open sockets on privileged ports) and doesn't conflict with - any ports already in use. The connection is forwarded to port 6667 on - the remote server, since that's the standard port for IRC services. + This tunnels a connection to IRC server M-bM-^@M-^\server.example.comM-bM-^@M-^], joining + channel M-bM-^@M-^\#usersM-bM-^@M-^], nickname M-bM-^@M-^\pinkyM-bM-^@M-^], using port 1234. It doesn't matter + which port is used, as long as it's greater than 1023 (remember, only + root can open sockets on privileged ports) and doesn't conflict with any + ports already in use. The connection is forwarded to port 6667 on the + remote server, since that's the standard port for IRC services. - The -f option backgrounds ssh and the remote command ``sleep 10'' is + The -f option backgrounds ssh and the remote command M-bM-^@M-^\sleep 10M-bM-^@M-^] is specified to allow an amount of time (10 seconds, in the example) to start the service which is to be tunnelled. If no connections are made within the time specified, ssh will exit. X11 FORWARDING - If the ForwardX11 variable is set to ``yes'' (or see the description of - the -X, -x, and -Y options above) and the user is using X11 (the DISPLAY + If the ForwardX11 variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of the + -X, -x, and -Y options above) and the user is using X11 (the DISPLAY environment variable is set), the connection to the X11 display is automatically forwarded to the remote side in such a way that any X11 programs started from the shell (or command) will go through the @@ -607,7 +614,7 @@ X11 FORWARDING The DISPLAY value set by ssh will point to the server machine, but with a display number greater than zero. This is normal, and happens because - ssh creates a ``proxy'' X server on the server machine for forwarding the + ssh creates a M-bM-^@M-^\proxyM-bM-^@M-^] X server on the server machine for forwarding the connections over the encrypted channel. ssh will also automatically set up Xauthority data on the server machine. @@ -617,7 +624,7 @@ X11 FORWARDING is opened. The real authentication cookie is never sent to the server machine (and no cookies are sent in the plain). - If the ForwardAgent variable is set to ``yes'' (or see the description of + If the ForwardAgent variable is set to M-bM-^@M-^\yesM-bM-^@M-^] (or see the description of the -A and -a options above) and the user is using an authentication agent, the connection to the agent is automatically forwarded to the remote side. @@ -632,15 +639,15 @@ VERIFYING HOST KEYS If the fingerprint is already known, it can be matched and the key can be accepted or rejected. Because of the difficulty of comparing host keys - just by looking at hex strings, there is also support to compare host - keys visually, using random art. By setting the VisualHostKey option to - ``yes'', a small ASCII graphic gets displayed on every login to a server, - no matter if the session itself is interactive or not. By learning the - pattern a known server produces, a user can easily find out that the host - key has changed when a completely different pattern is displayed. - Because these patterns are not unambiguous however, a pattern that looks - similar to the pattern remembered only gives a good probability that the - host key is the same, not guaranteed proof. + just by looking at fingerprint strings, there is also support to compare + host keys visually, using random art. By setting the VisualHostKey + option to M-bM-^@M-^\yesM-bM-^@M-^], a small ASCII graphic gets displayed on every login to a + server, no matter if the session itself is interactive or not. By + learning the pattern a known server produces, a user can easily find out + that the host key has changed when a completely different pattern is + displayed. Because these patterns are not unambiguous however, a pattern + that looks similar to the pattern remembered only gives a good + probability that the host key is the same, not guaranteed proof. To get a listing of the fingerprints along with their random art for all known hosts, the following command line can be used: @@ -653,8 +660,8 @@ VERIFYING HOST KEYS able to match the fingerprint with that of the key presented. In this example, we are connecting a client to a server, - ``host.example.com''. The SSHFP resource records should first be added - to the zonefile for host.example.com: + M-bM-^@M-^\host.example.comM-bM-^@M-^]. The SSHFP resource records should first be added to + the zonefile for host.example.com: $ ssh-keygen -r host.example.com. @@ -697,9 +704,9 @@ SSH-BASED VIRTUAL PRIVATE NETWORKS Client access may be more finely tuned via the /root/.ssh/authorized_keys file (see below) and the PermitRootLogin server option. The following - entry would permit connections on tun(4) device 1 from user ``jane'' and - on tun device 2 from user ``john'', if PermitRootLogin is set to - ``forced-commands-only'': + entry would permit connections on tun(4) device 1 from user M-bM-^@M-^\janeM-bM-^@M-^] and on + tun device 2 from user M-bM-^@M-^\johnM-bM-^@M-^], if PermitRootLogin is set to + M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^]: tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john @@ -714,14 +721,14 @@ ENVIRONMENT DISPLAY The DISPLAY variable indicates the location of the X11 server. It is automatically set by ssh to - point to a value of the form ``hostname:n'', where - ``hostname'' indicates the host where the shell - runs, and `n' is an integer >= 1. ssh uses this - special value to forward X11 connections over the - secure channel. The user should normally not set - DISPLAY explicitly, as that will render the X11 - connection insecure (and will require the user to - manually copy any required authorization cookies). + point to a value of the form M-bM-^@M-^\hostname:nM-bM-^@M-^], where + M-bM-^@M-^\hostnameM-bM-^@M-^] indicates the host where the shell runs, + and M-bM-^@M-^XnM-bM-^@M-^Y is an integer M-bM-^IM-% 1. ssh uses this special + value to forward X11 connections over the secure + channel. The user should normally not set DISPLAY + explicitly, as that will render the X11 connection + insecure (and will require the user to manually + copy any required authorization cookies). HOME Set to the path of the user's home directory. @@ -770,7 +777,7 @@ ENVIRONMENT USER Set to the name of the user logging in. Additionally, ssh reads ~/.ssh/environment, and adds lines of the format - ``VARNAME=value'' to the environment if the file exists and users are + M-bM-^@M-^\VARNAME=valueM-bM-^@M-^] to the environment if the file exists and users are allowed to change their environment. For more information, see the PermitUserEnvironment option in sshd_config(5). @@ -797,7 +804,7 @@ FILES for the user, and not accessible by others. ~/.ssh/authorized_keys - Lists the public keys (DSA, ECDSA, ED25519, RSA) that can be used + Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described in the sshd(8) manual page. This file is not highly sensitive, but the recommended permissions are read/write for the @@ -941,4 +948,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.6 July 24, 2014 OpenBSD 5.6 +OpenBSD 5.7 March 3, 2015 OpenBSD 5.7 diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1 index f978c994231e..a57341777556 100644 --- a/crypto/openssh/ssh.1 +++ b/crypto/openssh/ssh.1 @@ -33,9 +33,9 @@ .\" (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.1,v 1.348 2014/07/24 22:57:10 millert Exp $ +.\" $OpenBSD: ssh.1,v 1.356 2015/03/03 06:48:58 djm Exp $ .\" $FreeBSD$ -.Dd $Mdocdate: July 24 2014 $ +.Dd $Mdocdate: March 3 2015 $ .Dt SSH 1 .Os .Sh NAME @@ -44,7 +44,7 @@ .Sh SYNOPSIS .Nm ssh .Bk -words -.Op Fl 1246AaCfgKkMNnqsTtVvXxYy +.Op Fl 1246AaCfGgKkMNnqsTtVvXxYy .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl D Oo Ar bind_address : Oc Ns Ar port @@ -59,7 +59,7 @@ .Op Fl O Ar ctl_cmd .Op Fl o Ar option .Op Fl p Ar port -.Op Fl Q Cm cipher | cipher-auth | mac | kex | key +.Op Fl Q Cm cipher | cipher-auth | mac | kex | key | protocol-version .Op Fl R Oo Ar bind_address : Oc Ns Ar port : Ns Ar host : Ns Ar hostport .Op Fl S Ar ctl_path .Op Fl W Ar host : Ns Ar port @@ -252,6 +252,14 @@ then a client started with .Fl f will wait for all remote port forwards to be successfully established before placing itself in the background. +.It Fl G +Causes +.Nm +to print its configuration after evaluating +.Cm Host +and +.Cm Match +blocks and exit. .It Fl g Allows remote hosts to connect to local forwarded ports. If used on a multiplexed connection, then this option must be specified @@ -426,6 +434,7 @@ For full details of the options listed below, and their possible values, see .It DynamicForward .It EscapeChar .It ExitOnForwardFailure +.It FingerprintHash .It ForwardAgent .It ForwardX11 .It ForwardX11Timeout @@ -437,6 +446,7 @@ For full details of the options listed below, and their possible values, see .It HashKnownHosts .It Host .It HostbasedAuthentication +.It HostbasedKeyTypes .It HostKeyAlgorithms .It HostKeyAlias .It HostName @@ -476,6 +486,7 @@ For full details of the options listed below, and their possible values, see .It TCPKeepAlive .It Tunnel .It TunnelDevice +.It UpdateHostKeys .It UsePrivilegedPort .It User .It UserKnownHostsFile @@ -488,7 +499,7 @@ For full details of the options listed below, and their possible values, see Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. -.It Fl Q Cm cipher | cipher-auth | mac | kex | key +.It Fl Q Cm cipher | cipher-auth | mac | kex | key | protocol-version Queries .Nm for the algorithms supported for the specified version 2. @@ -502,7 +513,9 @@ The available features are: .Ar kex (key exchange algorithms), .Ar key -(key types). +(key types) and +.Ar protocol-version +(supported SSH protocol versions). .It Fl q Quiet mode. Causes most warning and diagnostic messages to be suppressed. @@ -750,7 +763,7 @@ key pair for authentication purposes. The server knows the public key, and only the user knows the private key. .Nm implements public key authentication protocol automatically, -using one of the DSA, ECDSA, ED25519 or RSA algorithms. +using one of the DSA, ECDSA, Ed25519 or RSA algorithms. Protocol 1 is restricted to using only RSA keys, but protocol 2 may use any. The HISTORY section of @@ -778,7 +791,7 @@ This stores the private key in .Pa ~/.ssh/id_ecdsa (protocol 2 ECDSA), .Pa ~/.ssh/id_ed25519 -(protocol 2 ED25519), +(protocol 2 Ed25519), or .Pa ~/.ssh/id_rsa (protocol 2 RSA) @@ -790,7 +803,7 @@ and stores the public key in .Pa ~/.ssh/id_ecdsa.pub (protocol 2 ECDSA), .Pa ~/.ssh/id_ed25519.pub -(protocol 2 ED25519), +(protocol 2 Ed25519), or .Pa ~/.ssh/id_rsa.pub (protocol 2 RSA) @@ -1085,7 +1098,7 @@ Fingerprints can be determined using If the fingerprint is already known, it can be matched and the key can be accepted or rejected. Because of the difficulty of comparing host keys -just by looking at hex strings, +just by looking at fingerprint strings, there is also support to compare host keys visually, using .Em random art . @@ -1330,7 +1343,7 @@ secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp .It Pa ~/.ssh/authorized_keys -Lists the public keys (DSA, ECDSA, ED25519, RSA) +Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described in the .Xr sshd 8 diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index c3350cd0b3e6..ae7bfee2782d 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.407 2014/07/17 07:22:19 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.416 2015/03/03 06:48:58 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -49,7 +49,6 @@ __RCSID("$FreeBSD$"); #endif #include #include -#include #include #include @@ -68,6 +67,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #include #include @@ -108,6 +108,7 @@ __RCSID("$FreeBSD$"); #include "uidswap.h" #include "roaming.h" #include "version.h" +#include "ssherr.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" @@ -200,7 +201,7 @@ static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" " [-F configfile] [-I pkcs11] [-i identity_file]\n" " [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]\n" @@ -276,6 +277,60 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) return res; } +/* + * Attempt to resolve a numeric host address / port to a single address. + * Returns a canonical address string. + * Returns NULL on failure. + * NB. this function must operate with a options having undefined members. + */ +static struct addrinfo * +resolve_addr(const char *name, int port, char *caddr, size_t clen) +{ + char addr[NI_MAXHOST], strport[NI_MAXSERV]; + struct addrinfo hints, *res; + int gaierr; + + if (port <= 0) + port = default_ssh_port(); + snprintf(strport, sizeof strport, "%u", port); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = options.address_family == -1 ? + AF_UNSPEC : options.address_family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; + if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { + debug2("%s: could not resolve name %.100s as address: %s", + __func__, name, ssh_gai_strerror(gaierr)); + return NULL; + } + if (res == NULL) { + debug("%s: getaddrinfo %.100s returned no addresses", + __func__, name); + return NULL; + } + if (res->ai_next != NULL) { + debug("%s: getaddrinfo %.100s returned multiple addresses", + __func__, name); + goto fail; + } + if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen, + addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) { + debug("%s: Could not format address for name %.100s: %s", + __func__, name, ssh_gai_strerror(gaierr)); + goto fail; + } + if (strlcpy(caddr, addr, clen) >= clen) { + error("%s: host \"%s\" addr \"%s\" too long (max %lu)", + __func__, name, addr, (u_long)clen); + if (clen > 0) + *caddr = '\0'; + fail: + freeaddrinfo(res); + return NULL; + } + return res; +} + /* * Check whether the cname is a permitted replacement for the hostname * and perform the replacement if it is. @@ -326,7 +381,7 @@ static struct addrinfo * resolve_canonicalize(char **hostp, int port) { int i, ndots; - char *cp, *fullhost, cname_target[NI_MAXHOST]; + char *cp, *fullhost, newname[NI_MAXHOST]; struct addrinfo *addrs; if (options.canonicalize_hostname == SSH_CANONICALISE_NO) @@ -340,6 +395,19 @@ resolve_canonicalize(char **hostp, int port) options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) return NULL; + /* Try numeric hostnames first */ + if ((addrs = resolve_addr(*hostp, port, + newname, sizeof(newname))) != NULL) { + debug2("%s: hostname %.100s is address", __func__, *hostp); + if (strcasecmp(*hostp, newname) != 0) { + debug2("%s: canonicalised address \"%s\" => \"%s\"", + __func__, *hostp, newname); + free(*hostp); + *hostp = xstrdup(newname); + } + return addrs; + } + /* Don't apply canonicalization to sufficiently-qualified hostnames */ ndots = 0; for (cp = *hostp; *cp != '\0'; cp++) { @@ -353,20 +421,20 @@ resolve_canonicalize(char **hostp, int port) } /* Attempt each supplied suffix */ for (i = 0; i < options.num_canonical_domains; i++) { - *cname_target = '\0'; + *newname = '\0'; xasprintf(&fullhost, "%s.%s.", *hostp, options.canonical_domains[i]); debug3("%s: attempting \"%s\" => \"%s\"", __func__, *hostp, fullhost); if ((addrs = resolve_host(fullhost, port, 0, - cname_target, sizeof(cname_target))) == NULL) { + newname, sizeof(newname))) == NULL) { free(fullhost); continue; } /* Remove trailing '.' */ fullhost[strlen(fullhost) - 1] = '\0'; /* Follow CNAME if requested */ - if (!check_follow_cname(&fullhost, cname_target)) { + if (!check_follow_cname(&fullhost, newname)) { debug("Canonicalized hostname \"%s\" => \"%s\"", *hostp, fullhost); } @@ -385,27 +453,49 @@ resolve_canonicalize(char **hostp, int port) * file if the user specifies a config file on the command line. */ static void -process_config_files(struct passwd *pw) +process_config_files(const char *host_arg, struct passwd *pw, int post_canon) { - char buf[MAXPATHLEN]; + char buf[PATH_MAX]; int r; if (config != NULL) { if (strcasecmp(config, "none") != 0 && - !read_config_file(config, pw, host, &options, - SSHCONF_USERCONF)) + !read_config_file(config, pw, host, host_arg, &options, + SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) - (void)read_config_file(buf, pw, host, &options, - SSHCONF_CHECKPERM|SSHCONF_USERCONF); + (void)read_config_file(buf, pw, host, host_arg, + &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | + (post_canon ? SSHCONF_POSTCANON : 0)); /* Read systemwide configuration file after user config. */ - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, - &options, 0); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, + host, host_arg, &options, + post_canon ? SSHCONF_POSTCANON : 0); + } +} + +/* Rewrite the port number in an addrinfo list of addresses */ +static void +set_addrinfo_port(struct addrinfo *addrs, int port) +{ + struct addrinfo *addr; + + for (addr = addrs; addr != NULL; addr = addr->ai_next) { + switch (addr->ai_family) { + case AF_INET: + ((struct sockaddr_in *)addr->ai_addr)-> + sin_port = htons(port); + break; + case AF_INET6: + ((struct sockaddr_in6 *)addr->ai_addr)-> + sin6_port = htons(port); + break; + } } } @@ -415,8 +505,8 @@ process_config_files(struct passwd *pw) int main(int ac, char **av) { - int i, r, opt, exit_status, use_syslog; - char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile; + int i, r, opt, exit_status, use_syslog, config_test = 0; + char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; char cname[NI_MAXHOST]; struct stat st; @@ -508,7 +598,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" - "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { + "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -541,6 +631,9 @@ main(int ac, char **av) case 'E': logfile = xstrdup(optarg); break; + case 'G': + config_test = 1; + break; case 'Y': options.forward_x11 = 1; options.forward_x11_trusted = 1; @@ -586,6 +679,13 @@ main(int ac, char **av) cp = key_alg_list(1, 0); else if (strcmp(optarg, "key-plain") == 0) cp = key_alg_list(0, 1); + else if (strcmp(optarg, "protocol-version") == 0) { +#ifdef WITH_SSH1 + cp = xstrdup("1\n2"); +#else + cp = xstrdup("2"); +#endif + } if (cp == NULL) fatal("Unsupported query \"%s\"", optarg); printf("%s\n", cp); @@ -789,9 +889,9 @@ main(int ac, char **av) break; case 'o': line = xstrdup(optarg); - if (process_config_line(&options, pw, host ? host : "", - line, "command-line", 0, NULL, SSHCONF_USERCONF) - != 0) + if (process_config_line(&options, pw, + host ? host : "", host ? host : "", line, + "command-line", 0, NULL, SSHCONF_USERCONF) != 0) exit(255); free(line); break; @@ -894,7 +994,7 @@ main(int ac, char **av) logit("%s, %s", SSH_RELEASE, OPENSSL_VERSION); /* Parse the configuration files */ - process_config_files(pw); + process_config_files(host_arg, pw, 0); /* Hostname canonicalisation needs a few options filled. */ fill_default_options_for_canonicalization(&options); @@ -906,6 +1006,8 @@ main(int ac, char **av) "h", host, (char *)NULL); free(host); host = cp; + free(options.hostname); + options.hostname = xstrdup(host); } /* If canonicalization requested then try to apply it */ @@ -940,12 +1042,22 @@ main(int ac, char **av) } /* - * If the target hostname has changed as a result of canonicalisation - * then re-parse the configuration files as new stanzas may match. + * If canonicalisation is enabled then re-parse the configuration + * files as new stanzas may match. */ - if (strcasecmp(host_arg, host) != 0) { - debug("Hostname has changed; re-reading configuration"); - process_config_files(pw); + if (options.canonicalize_hostname != 0) { + debug("Re-reading configuration after hostname " + "canonicalisation"); + free(options.hostname); + options.hostname = xstrdup(host); + process_config_files(host_arg, pw, 1); + /* + * Address resolution happens early with canonicalisation + * enabled and the port number may have changed since, so + * reset it in address list + */ + if (addrs != NULL && options.port > 0) + set_addrinfo_port(addrs, options.port); } /* Fill configuration defaults. */ @@ -962,6 +1074,12 @@ main(int ac, char **av) strcmp(options.proxy_command, "-") == 0 && options.proxy_use_fdpass) fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); + if (options.control_persist && + options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { + debug("UpdateHostKeys=ask is incompatible with ControlPersist; " + "disabling"); + options.update_hostkeys = 0; + } #ifndef HAVE_CYGWIN if (original_effective_uid != 0) options.use_privileged_port = 0; @@ -1064,6 +1182,11 @@ main(int ac, char **av) } free(conn_hash_hex); + if (config_test) { + dump_client_config(&options, host); + exit(0); + } + if (muxclient_command != 0 && options.control_path == NULL) fatal("No ControlPath specified for \"-O\" command"); if (options.control_path != NULL) @@ -1119,26 +1242,26 @@ main(int ac, char **av) PRIV_START; sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, _PATH_HOST_KEY_FILE, "", NULL, NULL); - sensitive_data.keys[1] = key_load_private_cert(KEY_DSA, - _PATH_HOST_DSA_KEY_FILE, "", NULL); #ifdef OPENSSL_HAS_ECC - sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA, + sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, "", NULL); #endif + sensitive_data.keys[2] = key_load_private_cert(KEY_ED25519, + _PATH_HOST_ED25519_KEY_FILE, "", NULL); sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL); - sensitive_data.keys[4] = key_load_private_cert(KEY_ED25519, - _PATH_HOST_ED25519_KEY_FILE, "", NULL); - sensitive_data.keys[5] = key_load_private_type(KEY_DSA, - _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); + sensitive_data.keys[4] = key_load_private_cert(KEY_DSA, + _PATH_HOST_DSA_KEY_FILE, "", NULL); #ifdef OPENSSL_HAS_ECC - sensitive_data.keys[6] = key_load_private_type(KEY_ECDSA, + sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); #endif + sensitive_data.keys[6] = key_load_private_type(KEY_ED25519, + _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); sensitive_data.keys[7] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); - sensitive_data.keys[8] = key_load_private_type(KEY_ED25519, - _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); + sensitive_data.keys[8] = key_load_private_type(KEY_DSA, + _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); PRIV_END; if (options.hostbased_authentication == 1 && @@ -1147,26 +1270,26 @@ main(int ac, char **av) sensitive_data.keys[6] == NULL && sensitive_data.keys[7] == NULL && sensitive_data.keys[8] == NULL) { - sensitive_data.keys[1] = key_load_cert( - _PATH_HOST_DSA_KEY_FILE); #ifdef OPENSSL_HAS_ECC - sensitive_data.keys[2] = key_load_cert( + sensitive_data.keys[1] = key_load_cert( _PATH_HOST_ECDSA_KEY_FILE); #endif + sensitive_data.keys[2] = key_load_cert( + _PATH_HOST_ED25519_KEY_FILE); sensitive_data.keys[3] = key_load_cert( _PATH_HOST_RSA_KEY_FILE); sensitive_data.keys[4] = key_load_cert( - _PATH_HOST_ED25519_KEY_FILE); - sensitive_data.keys[5] = key_load_public( - _PATH_HOST_DSA_KEY_FILE, NULL); + _PATH_HOST_DSA_KEY_FILE); #ifdef OPENSSL_HAS_ECC - sensitive_data.keys[6] = key_load_public( + sensitive_data.keys[5] = key_load_public( _PATH_HOST_ECDSA_KEY_FILE, NULL); #endif + sensitive_data.keys[6] = key_load_public( + _PATH_HOST_ED25519_KEY_FILE, NULL); sensitive_data.keys[7] = key_load_public( _PATH_HOST_RSA_KEY_FILE, NULL); sensitive_data.keys[8] = key_load_public( - _PATH_HOST_ED25519_KEY_FILE, NULL); + _PATH_HOST_DSA_KEY_FILE, NULL); sensitive_data.external_keysign = 1; } } @@ -1472,10 +1595,16 @@ ssh_init_forwarding(void) static void check_agent_present(void) { + int r; + if (options.forward_agent) { /* Clear agent forwarding if we don't have an agent. */ - if (!ssh_agent_present()) + if ((r = ssh_get_authentication_socket(NULL)) != 0) { options.forward_agent = 0; + if (r != SSH_ERR_AGENT_NOT_PRESENT) + debug("ssh_get_authentication_socket: %s", + ssh_err(r)); + } } } diff --git a/crypto/openssh/ssh_api.c b/crypto/openssh/ssh_api.c new file mode 100644 index 000000000000..6c712584f49e --- /dev/null +++ b/crypto/openssh/ssh_api.c @@ -0,0 +1,537 @@ +/* $OpenBSD: ssh_api.c,v 1.4 2015/02/16 22:13:32 djm Exp $ */ +/* + * Copyright (c) 2012 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include "ssh1.h" /* For SSH_MSG_NONE */ +#include "ssh_api.h" +#include "compat.h" +#include "log.h" +#include "authfile.h" +#include "sshkey.h" +#include "misc.h" +#include "ssh1.h" +#include "ssh2.h" +#include "version.h" +#include "myproposal.h" +#include "ssherr.h" +#include "sshbuf.h" + +#include + +int _ssh_exchange_banner(struct ssh *); +int _ssh_send_banner(struct ssh *, char **); +int _ssh_read_banner(struct ssh *, char **); +int _ssh_order_hostkeyalgs(struct ssh *); +int _ssh_verify_host_key(struct sshkey *, struct ssh *); +struct sshkey *_ssh_host_public_key(int, int, struct ssh *); +struct sshkey *_ssh_host_private_key(int, int, struct ssh *); +int _ssh_host_key_sign(struct sshkey *, struct sshkey *, u_char **, + size_t *, const u_char *, size_t, u_int); + +/* + * stubs for the server side implementation of kex. + * disable privsep so our stubs will never be called. + */ +int use_privsep = 0; +int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, + u_char *, u_int, u_int); +DH *mm_choose_dh(int, int, int); + +/* Define these two variables here so that they are part of the library */ +u_char *session_id2 = NULL; +u_int session_id2_len = 0; + +int +mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, + u_char *data, u_int datalen, u_int compat) +{ + return (-1); +} + +DH * +mm_choose_dh(int min, int nbits, int max) +{ + return (NULL); +} + +/* API */ + +int +ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) +{ + char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; + struct ssh *ssh; + char **proposal; + static int called; + int r; + + if (!called) { +#ifdef WITH_OPENSSL + OpenSSL_add_all_algorithms(); +#endif /* WITH_OPENSSL */ + called = 1; + } + + if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL) + return SSH_ERR_ALLOC_FAIL; + if (is_server) + ssh_packet_set_server(ssh); + + /* Initialize key exchange */ + proposal = kex_params ? kex_params->proposal : myproposal; + if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) { + ssh_free(ssh); + return r; + } + ssh->kex->server = is_server; + if (is_server) { +#ifdef WITH_OPENSSL + ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; + ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +# ifdef OPENSSL_HAS_ECC + ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_server; +# endif +#endif /* WITH_OPENSSL */ + ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server; + ssh->kex->load_host_public_key=&_ssh_host_public_key; + ssh->kex->load_host_private_key=&_ssh_host_private_key; + ssh->kex->sign=&_ssh_host_key_sign; + } else { +#ifdef WITH_OPENSSL + ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; + ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; + ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; + ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; +# ifdef OPENSSL_HAS_ECC + ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client; +# endif +#endif /* WITH_OPENSSL */ + ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client; + ssh->kex->verify_host_key =&_ssh_verify_host_key; + } + *sshp = ssh; + return 0; +} + +void +ssh_free(struct ssh *ssh) +{ + struct key_entry *k; + + ssh_packet_close(ssh); + /* + * we've only created the public keys variants in case we + * are a acting as a server. + */ + while ((k = TAILQ_FIRST(&ssh->public_keys)) != NULL) { + TAILQ_REMOVE(&ssh->public_keys, k, next); + if (ssh->kex && ssh->kex->server) + sshkey_free(k->key); + free(k); + } + while ((k = TAILQ_FIRST(&ssh->private_keys)) != NULL) { + TAILQ_REMOVE(&ssh->private_keys, k, next); + free(k); + } + if (ssh->kex) + kex_free(ssh->kex); + free(ssh); +} + +void +ssh_set_app_data(struct ssh *ssh, void *app_data) +{ + ssh->app_data = app_data; +} + +void * +ssh_get_app_data(struct ssh *ssh) +{ + return ssh->app_data; +} + +/* Returns < 0 on error, 0 otherwise */ +int +ssh_add_hostkey(struct ssh *ssh, struct sshkey *key) +{ + struct sshkey *pubkey = NULL; + struct key_entry *k = NULL, *k_prv = NULL; + int r; + + if (ssh->kex->server) { + if ((r = sshkey_from_private(key, &pubkey)) != 0) + return r; + if ((k = malloc(sizeof(*k))) == NULL || + (k_prv = malloc(sizeof(*k_prv))) == NULL) { + free(k); + sshkey_free(pubkey); + return SSH_ERR_ALLOC_FAIL; + } + k_prv->key = key; + TAILQ_INSERT_TAIL(&ssh->private_keys, k_prv, next); + + /* add the public key, too */ + k->key = pubkey; + TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); + r = 0; + } else { + if ((k = malloc(sizeof(*k))) == NULL) + return SSH_ERR_ALLOC_FAIL; + k->key = key; + TAILQ_INSERT_TAIL(&ssh->public_keys, k, next); + r = 0; + } + + return r; +} + +int +ssh_set_verify_host_key_callback(struct ssh *ssh, + int (*cb)(struct sshkey *, struct ssh *)) +{ + if (cb == NULL || ssh->kex == NULL) + return SSH_ERR_INVALID_ARGUMENT; + + ssh->kex->verify_host_key = cb; + + return 0; +} + +int +ssh_input_append(struct ssh *ssh, const u_char *data, size_t len) +{ + return sshbuf_put(ssh_packet_get_input(ssh), data, len); +} + +int +ssh_packet_next(struct ssh *ssh, u_char *typep) +{ + int r; + u_int32_t seqnr; + u_char type; + + /* + * Try to read a packet. Return SSH_MSG_NONE if no packet or not + * enough data. + */ + *typep = SSH_MSG_NONE; + if (ssh->kex->client_version_string == NULL || + ssh->kex->server_version_string == NULL) + return _ssh_exchange_banner(ssh); + /* + * If we enough data and a dispatch function then + * call the function and get the next packet. + * Otherwise return the packet type to the caller so it + * can decide how to go on. + * + * We will only call the dispatch function for: + * 20-29 Algorithm negotiation + * 30-49 Key exchange method specific (numbers can be reused for + * different authentication methods) + */ + for (;;) { + if ((r = ssh_packet_read_poll2(ssh, &type, &seqnr)) != 0) + return r; + if (type > 0 && type < DISPATCH_MAX && + type >= SSH2_MSG_KEXINIT && type <= SSH2_MSG_TRANSPORT_MAX && + ssh->dispatch[type] != NULL) { + if ((r = (*ssh->dispatch[type])(type, seqnr, ssh)) != 0) + return r; + } else { + *typep = type; + return 0; + } + } +} + +const u_char * +ssh_packet_payload(struct ssh *ssh, size_t *lenp) +{ + return sshpkt_ptr(ssh, lenp); +} + +int +ssh_packet_put(struct ssh *ssh, int type, const u_char *data, size_t len) +{ + int r; + + if ((r = sshpkt_start(ssh, type)) != 0 || + (r = sshpkt_put(ssh, data, len)) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; + return 0; +} + +const u_char * +ssh_output_ptr(struct ssh *ssh, size_t *len) +{ + struct sshbuf *output = ssh_packet_get_output(ssh); + + *len = sshbuf_len(output); + return sshbuf_ptr(output); +} + +int +ssh_output_consume(struct ssh *ssh, size_t len) +{ + return sshbuf_consume(ssh_packet_get_output(ssh), len); +} + +int +ssh_output_space(struct ssh *ssh, size_t len) +{ + return (0 == sshbuf_check_reserve(ssh_packet_get_output(ssh), len)); +} + +int +ssh_input_space(struct ssh *ssh, size_t len) +{ + return (0 == sshbuf_check_reserve(ssh_packet_get_input(ssh), len)); +} + +/* Read other side's version identification. */ +int +_ssh_read_banner(struct ssh *ssh, char **bannerp) +{ + struct sshbuf *input; + const char *s; + char buf[256], remote_version[256]; /* must be same size! */ + const char *mismatch = "Protocol mismatch.\r\n"; + int r, remote_major, remote_minor; + size_t i, n, j, len; + + *bannerp = NULL; + input = ssh_packet_get_input(ssh); + len = sshbuf_len(input); + s = (const char *)sshbuf_ptr(input); + for (j = n = 0;;) { + for (i = 0; i < sizeof(buf) - 1; i++) { + if (j >= len) + return (0); + buf[i] = s[j++]; + if (buf[i] == '\r') { + buf[i] = '\n'; + buf[i + 1] = 0; + continue; /**XXX wait for \n */ + } + if (buf[i] == '\n') { + buf[i + 1] = 0; + break; + } + } + buf[sizeof(buf) - 1] = 0; + if (strncmp(buf, "SSH-", 4) == 0) + break; + debug("ssh_exchange_identification: %s", buf); + if (ssh->kex->server || ++n > 65536) { + if ((r = sshbuf_put(ssh_packet_get_output(ssh), + mismatch, strlen(mismatch))) != 0) + return r; + return SSH_ERR_NO_PROTOCOL_VERSION; + } + } + if ((r = sshbuf_consume(input, j)) != 0) + return r; + + /* + * Check that the versions match. In future this might accept + * several versions and set appropriate flags to handle them. + */ + if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", + &remote_major, &remote_minor, remote_version) != 3) + return SSH_ERR_INVALID_FORMAT; + debug("Remote protocol version %d.%d, remote software version %.100s", + remote_major, remote_minor, remote_version); + + ssh->compat = compat_datafellows(remote_version); + if (remote_major == 1 && remote_minor == 99) { + remote_major = 2; + remote_minor = 0; + } + if (remote_major != 2) + return SSH_ERR_PROTOCOL_MISMATCH; + enable_compat20(); + chop(buf); + debug("Remote version string %.100s", buf); + if ((*bannerp = strdup(buf)) == NULL) + return SSH_ERR_ALLOC_FAIL; + return 0; +} + +/* Send our own protocol version identification. */ +int +_ssh_send_banner(struct ssh *ssh, char **bannerp) +{ + char buf[256]; + int r; + + snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION); + if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0) + return r; + chop(buf); + debug("Local version string %.100s", buf); + if ((*bannerp = strdup(buf)) == NULL) + return SSH_ERR_ALLOC_FAIL; + return 0; +} + +int +_ssh_exchange_banner(struct ssh *ssh) +{ + struct kex *kex = ssh->kex; + int r; + + /* + * if _ssh_read_banner() cannot parse a full version string + * it will return NULL and we end up calling it again. + */ + + r = 0; + if (kex->server) { + if (kex->server_version_string == NULL) + r = _ssh_send_banner(ssh, &kex->server_version_string); + if (r == 0 && + kex->server_version_string != NULL && + kex->client_version_string == NULL) + r = _ssh_read_banner(ssh, &kex->client_version_string); + } else { + if (kex->server_version_string == NULL) + r = _ssh_read_banner(ssh, &kex->server_version_string); + if (r == 0 && + kex->server_version_string != NULL && + kex->client_version_string == NULL) + r = _ssh_send_banner(ssh, &kex->client_version_string); + } + if (r != 0) + return r; + /* start initial kex as soon as we have exchanged the banners */ + if (kex->server_version_string != NULL && + kex->client_version_string != NULL) { + if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 || + (r = kex_send_kexinit(ssh)) != 0) + return r; + } + return 0; +} + +struct sshkey * +_ssh_host_public_key(int type, int nid, struct ssh *ssh) +{ + struct key_entry *k; + + debug3("%s: need %d", __func__, type); + TAILQ_FOREACH(k, &ssh->public_keys, next) { + debug3("%s: check %s", __func__, sshkey_type(k->key)); + if (k->key->type == type && + (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) + return (k->key); + } + return (NULL); +} + +struct sshkey * +_ssh_host_private_key(int type, int nid, struct ssh *ssh) +{ + struct key_entry *k; + + debug3("%s: need %d", __func__, type); + TAILQ_FOREACH(k, &ssh->private_keys, next) { + debug3("%s: check %s", __func__, sshkey_type(k->key)); + if (k->key->type == type && + (type != KEY_ECDSA || k->key->ecdsa_nid == nid)) + return (k->key); + } + return (NULL); +} + +int +_ssh_verify_host_key(struct sshkey *hostkey, struct ssh *ssh) +{ + struct key_entry *k; + + debug3("%s: need %s", __func__, sshkey_type(hostkey)); + TAILQ_FOREACH(k, &ssh->public_keys, next) { + debug3("%s: check %s", __func__, sshkey_type(k->key)); + if (sshkey_equal_public(hostkey, k->key)) + return (0); /* ok */ + } + return (-1); /* failed */ +} + +/* offer hostkey algorithms in kexinit depending on registered keys */ +int +_ssh_order_hostkeyalgs(struct ssh *ssh) +{ + struct key_entry *k; + char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; + char **proposal; + size_t maxlen; + int ktype, r; + + /* XXX we de-serialize ssh->kex->my, modify it, and change it */ + if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) + return r; + orig = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; + if ((oavail = avail = strdup(orig)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + maxlen = strlen(avail) + 1; + if ((replace = calloc(1, maxlen)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + *replace = '\0'; + while ((alg = strsep(&avail, ",")) && *alg != '\0') { + if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) + continue; + TAILQ_FOREACH(k, &ssh->public_keys, next) { + if (k->key->type == ktype || + (sshkey_is_cert(k->key) && k->key->type == + sshkey_type_plain(ktype))) { + if (*replace != '\0') + strlcat(replace, ",", maxlen); + strlcat(replace, alg, maxlen); + break; + } + } + } + if (*replace != '\0') { + debug2("%s: orig/%d %s", __func__, ssh->kex->server, orig); + debug2("%s: replace/%d %s", __func__, ssh->kex->server, replace); + free(orig); + proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = replace; + replace = NULL; /* owned by proposal */ + r = kex_prop2buf(ssh->kex->my, proposal); + } + out: + free(oavail); + free(replace); + kex_prop_free(proposal); + return r; +} + +int +_ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey, + u_char **signature, size_t *slen, + const u_char *data, size_t dlen, u_int compat) +{ + return sshkey_sign(privkey, signature, slen, data, dlen, compat); +} diff --git a/crypto/openssh/ssh_api.h b/crypto/openssh/ssh_api.h new file mode 100644 index 000000000000..642acd5b2eb2 --- /dev/null +++ b/crypto/openssh/ssh_api.h @@ -0,0 +1,137 @@ +/* $OpenBSD: ssh_api.h,v 1.1 2015/01/19 20:30:23 markus Exp $ */ +/* + * Copyright (c) 2012 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef API_H +#define API_H + +#include +#include + +#include "openbsd-compat/sys-queue.h" + +#include "cipher.h" +#include "sshkey.h" +#include "kex.h" +#include "ssh.h" +#include "ssh2.h" +#include "packet.h" + +struct kex_params { + char *proposal[PROPOSAL_MAX]; +}; + +/* public SSH API functions */ + +/* + * ssh_init() create a ssh connection object with given (optional) + * key exchange parameters. + */ +int ssh_init(struct ssh **, int is_server, struct kex_params *kex_params); + +/* + * release ssh connection state. + */ +void ssh_free(struct ssh *); + +/* + * attach application specific data to the connection state + */ +void ssh_set_app_data(struct ssh *, void *); +void *ssh_get_app_data(struct ssh *); + +/* + * ssh_add_hostkey() registers a private/public hostkey for an ssh + * connection. + * ssh_add_hostkey() needs to be called before a key exchange is + * initiated with ssh_packet_next(). + * private hostkeys are required if we need to act as a server. + * public hostkeys are used to verify the servers hostkey. + */ +int ssh_add_hostkey(struct ssh *ssh, struct sshkey *key); + +/* + * ssh_set_verify_host_key_callback() registers a callback function + * which should be called instead of the default verification. The + * function given must return 0 if the hostkey is ok, -1 if the + * verification has failed. + */ +int ssh_set_verify_host_key_callback(struct ssh *ssh, + int (*cb)(struct sshkey *, struct ssh *)); + +/* + * ssh_packet_next() advances to the next input packet and returns + * the packet type in typep. + * ssh_packet_next() works by processing an input byte-stream, + * decrypting the received data and hiding the key-exchange from + * the caller. + * ssh_packet_next() sets typep if there is no new packet available. + * in this case the caller must fill the input byte-stream by passing + * the data received over network to ssh_input_append(). + * additinally, the caller needs to send the resulting output + * byte-stream back over the network. otherwise the key exchange + * would not proceed. the output byte-stream is accessed through + * ssh_output_ptr(). + */ +int ssh_packet_next(struct ssh *ssh, u_char *typep); + +/* + * ssh_packet_payload() returns a pointer to the raw payload data of + * the current input packet and the length of this payload. + * the payload is accessible until ssh_packet_next() is called again. + */ +const u_char *ssh_packet_payload(struct ssh *ssh, size_t *lenp); + +/* + * ssh_packet_put() creates an encrypted packet with the given type + * and payload. + * the encrypted packet is appended to the output byte-stream. + */ +int ssh_packet_put(struct ssh *ssh, int type, const u_char *data, + size_t len); + +/* + * ssh_input_space() checks if 'len' bytes can be appended to the + * input byte-stream. + */ +int ssh_input_space(struct ssh *ssh, size_t len); + +/* + * ssh_input_append() appends data to the input byte-stream. + */ +int ssh_input_append(struct ssh *ssh, const u_char *data, size_t len); + +/* + * ssh_output_space() checks if 'len' bytes can be appended to the + * output byte-stream. XXX + */ +int ssh_output_space(struct ssh *ssh, size_t len); + +/* + * ssh_output_ptr() retrieves both a pointer and the length of the + * current output byte-stream. the bytes need to be sent over the + * network. the number of bytes that have been successfully sent can + * be removed from the output byte-stream with ssh_output_consume(). + */ +const u_char *ssh_output_ptr(struct ssh *ssh, size_t *len); + +/* + * ssh_output_consume() removes the given number of bytes from + * the output byte-stream. + */ +int ssh_output_consume(struct ssh *ssh, size_t len); + +#endif diff --git a/crypto/openssh/ssh_config.0 b/crypto/openssh/ssh_config.0 index c40ce5f08fd7..3bdd752379bd 100644 --- a/crypto/openssh/ssh_config.0 +++ b/crypto/openssh/ssh_config.0 @@ -1,7 +1,7 @@ SSH_CONFIG(5) File Formats Manual SSH_CONFIG(5) NAME - ssh_config - OpenSSH SSH client configuration files + ssh_config M-bM-^@M-^S OpenSSH SSH client configuration files SYNOPSIS ~/.ssh/config @@ -16,10 +16,11 @@ DESCRIPTION 3. system-wide configuration file (/etc/ssh/ssh_config) For each parameter, the first obtained value will be used. The - configuration files contain sections separated by ``Host'' - specifications, and that section is only applied for hosts that match one - of the patterns given in the specification. The matched host name is the - one given on the command line. + configuration files contain sections separated by M-bM-^@M-^\HostM-bM-^@M-^] specifications, + and that section is only applied for hosts that match one of the patterns + given in the specification. The matched host name is usually the one + given on the command line (see the CanonicalizeHostname option for + exceptions.) Since the first obtained value for each parameter is used, more host- specific declarations should be given near the beginning of the file, and @@ -27,9 +28,9 @@ DESCRIPTION The configuration file has the following format: - Empty lines and lines starting with `#' are comments. Otherwise a line - is of the format ``keyword arguments''. Configuration options may be - separated by whitespace or optional whitespace and exactly one `='; the + Empty lines and lines starting with M-bM-^@M-^X#M-bM-^@M-^Y are comments. Otherwise a line + is of the format M-bM-^@M-^\keyword argumentsM-bM-^@M-^]. Configuration options may be + separated by whitespace or optional whitespace and exactly one M-bM-^@M-^X=M-bM-^@M-^Y; the latter format is useful to avoid the need to quote whitespace when specifying configuration options using the ssh, scp, and sftp -o option. Arguments may optionally be enclosed in double quotes (") in order to @@ -41,14 +42,14 @@ DESCRIPTION Host Restricts the following declarations (up to the next Host or Match keyword) to be only for those hosts that match one of the patterns given after the keyword. If more than one pattern is - provided, they should be separated by whitespace. A single `*' + provided, they should be separated by whitespace. A single M-bM-^@M-^X*M-bM-^@M-^Y as a pattern can be used to provide global defaults for all - hosts. The host is the hostname argument given on the command - line (i.e. the name is not converted to a canonicalized host name - before matching). + hosts. The host is usually the hostname argument given on the + command line (see the CanonicalizeHostname option for + exceptions.) A pattern entry may be negated by prefixing it with an - exclamation mark (`!'). If a negated entry is matched, then the + exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). If a negated entry is matched, then the Host entry is ignored, regardless of whether any other patterns on the line match. Negated matches are therefore useful to provide exceptions for wildcard matches. @@ -58,50 +59,57 @@ DESCRIPTION Match Restricts the following declarations (up to the next Host or Match keyword) to be used only when the conditions following the Match keyword are satisfied. Match conditions are specified - using one or more keyword/criteria pairs or the single token all - which matches all criteria. The available keywords are: exec, - host, originalhost, user, and localuser. + using one or more critera or the single token all which always + matches. The available criteria keywords are: canonical, exec, + host, originalhost, user, and localuser. The all criteria must + appear alone or immediately after canonical. Other criteria may + be combined arbitrarily. All criteria but all and canonical + require an argument. Criteria may be negated by prepending an + exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). - The exec keyword executes the specified command under the user's - shell. If the command returns a zero exit status then the - condition is considered true. Commands containing whitespace - characters must be quoted. The following character sequences in - the command will be expanded prior to execution: `%L' will be - substituted by the first component of the local host name, `%l' - will be substituted by the local host name (including any domain - name), `%h' will be substituted by the target host name, `%n' - will be substituted by the original target host name specified on - the command-line, `%p' the destination port, `%r' by the remote - login username, and `%u' by the username of the user running - ssh(1). + The canonical keywork matches only when the configuration file is + being re-parsed after hostname canonicalization (see the + CanonicalizeHostname option.) This may be useful to specify + conditions that work with canonical host names only. The exec + keyword executes the specified command under the user's shell. + If the command returns a zero exit status then the condition is + considered true. Commands containing whitespace characters must + be quoted. The following character sequences in the command will + be expanded prior to execution: M-bM-^@M-^X%LM-bM-^@M-^Y will be substituted by the + first component of the local host name, M-bM-^@M-^X%lM-bM-^@M-^Y will be substituted + by the local host name (including any domain name), M-bM-^@M-^X%hM-bM-^@M-^Y will be + substituted by the target host name, M-bM-^@M-^X%nM-bM-^@M-^Y will be substituted by + the original target host name specified on the command-line, M-bM-^@M-^X%pM-bM-^@M-^Y + the destination port, M-bM-^@M-^X%rM-bM-^@M-^Y by the remote login username, and M-bM-^@M-^X%uM-bM-^@M-^Y + by the username of the user running ssh(1). The other keywords' criteria must be single entries or comma- separated lists and may use the wildcard and negation operators described in the PATTERNS section. The criteria for the host keyword are matched against the target hostname, after any - substitution by the Hostname option. The originalhost keyword - matches against the hostname as it was specified on the command- - line. The user keyword matches against the target username on - the remote host. The localuser keyword matches against the name - of the local user running ssh(1) (this keyword may be useful in - system-wide ssh_config files). + substitution by the Hostname or CanonicalizeHostname options. + The originalhost keyword matches against the hostname as it was + specified on the command-line. The user keyword matches against + the target username on the remote host. The localuser keyword + matches against the name of the local user running ssh(1) (this + keyword may be useful in system-wide ssh_config files). AddressFamily Specifies which address family to use when connecting. Valid - arguments are ``any'', ``inet'' (use IPv4 only), or ``inet6'' - (use IPv6 only). + arguments are M-bM-^@M-^\anyM-bM-^@M-^], M-bM-^@M-^\inetM-bM-^@M-^] (use IPv4 only), or M-bM-^@M-^\inet6M-bM-^@M-^] (use IPv6 + only). BatchMode - If set to ``yes'', passphrase/password querying will be disabled. + If set to M-bM-^@M-^\yesM-bM-^@M-^], passphrase/password querying will be disabled. This option is useful in scripts and other batch jobs where no user is present to supply the password. The argument must be - ``yes'' or ``no''. The default is ``no''. + M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. BindAddress Use the specified address on the local machine as the source address of the connection. Only useful on systems with more than one address. Note that this option does not work if - UsePrivilegedPort is set to ``yes''. + UsePrivilegedPort is set to M-bM-^@M-^\yesM-bM-^@M-^]. CanonicalDomains When CanonicalizeHostname is enabled, this option specifies the @@ -110,33 +118,31 @@ DESCRIPTION CanonicalizeFallbackLocal Specifies whether to fail with an error when hostname - canonicalization fails. The default, ``yes'', will attempt to - look up the unqualified hostname using the system resolver's - search rules. A value of ``no'' will cause ssh(1) to fail - instantly if CanonicalizeHostname is enabled and the target - hostname cannot be found in any of the domains specified by - CanonicalDomains. + canonicalization fails. The default, M-bM-^@M-^\yesM-bM-^@M-^], will attempt to look + up the unqualified hostname using the system resolver's search + rules. A value of M-bM-^@M-^\noM-bM-^@M-^] will cause ssh(1) to fail instantly if + CanonicalizeHostname is enabled and the target hostname cannot be + found in any of the domains specified by CanonicalDomains. CanonicalizeHostname Controls whether explicit hostname canonicalization is performed. - The default, ``no'', is not to perform any name rewriting and let - the system resolver handle all hostname lookups. If set to - ``yes'' then, for connections that do not use a ProxyCommand, - ssh(1) will attempt to canonicalize the hostname specified on the - command line using the CanonicalDomains suffixes and + The default, M-bM-^@M-^\noM-bM-^@M-^], is not to perform any name rewriting and let + the system resolver handle all hostname lookups. If set to M-bM-^@M-^\yesM-bM-^@M-^] + then, for connections that do not use a ProxyCommand, ssh(1) will + attempt to canonicalize the hostname specified on the command + line using the CanonicalDomains suffixes and CanonicalizePermittedCNAMEs rules. If CanonicalizeHostname is - set to ``always'', then canonicalization is applied to proxied + set to M-bM-^@M-^\alwaysM-bM-^@M-^], then canonicalization is applied to proxied connections too. - If this option is enabled and canonicalisation results in the - target hostname changing, then the configuration files are + If this option is enabled, then the configuration files are processed again using the new target name to pick up any new - configuration in matching Host stanzas. + configuration in matching Host and Match stanzas. CanonicalizeMaxDots Specifies the maximum number of dot characters in a hostname - before canonicalization is disabled. The default, ``1'', allows - a single dot (i.e. hostname.subdomain). + before canonicalization is disabled. The default, M-bM-^@M-^\1M-bM-^@M-^], allows a + single dot (i.e. hostname.subdomain). CanonicalizePermittedCNAMEs Specifies rules to determine whether CNAMEs should be followed @@ -146,30 +152,29 @@ DESCRIPTION CNAMEs in canonicalization, and target_domain_list is a pattern- list of domains that they may resolve to. - For example, ``*.a.example.com:*.b.example.com,*.c.example.com'' - will allow hostnames matching ``*.a.example.com'' to be - canonicalized to names in the ``*.b.example.com'' or - ``*.c.example.com'' domains. + For example, M-bM-^@M-^\*.a.example.com:*.b.example.com,*.c.example.comM-bM-^@M-^] + will allow hostnames matching M-bM-^@M-^\*.a.example.comM-bM-^@M-^] to be + canonicalized to names in the M-bM-^@M-^\*.b.example.comM-bM-^@M-^] or + M-bM-^@M-^\*.c.example.comM-bM-^@M-^] domains. ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The - argument to this keyword must be ``yes'' or ``no''. The default - is ``yes''. + argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is + M-bM-^@M-^\yesM-bM-^@M-^]. CheckHostIP - If this flag is set to ``yes'', ssh(1) will additionally check - the host IP address in the known_hosts file. This allows ssh to + If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will additionally check the + host IP address in the known_hosts file. This allows ssh to detect if a host key changed due to DNS spoofing. If the option - is set to ``no'', the check will not be executed. The default is - ``yes''. + is set to M-bM-^@M-^\noM-bM-^@M-^], the check will not be executed. The default is + M-bM-^@M-^\yesM-bM-^@M-^]. Cipher Specifies the cipher to use for encrypting the session in - protocol version 1. Currently, ``blowfish'', ``3des'', and - ``des'' are supported. des is only supported in the ssh(1) - client for interoperability with legacy protocol 1 - implementations that do not support the 3des cipher. Its use is - strongly discouraged due to cryptographic weaknesses. The - default is ``3des''. + protocol version 1. Currently, M-bM-^@M-^\blowfishM-bM-^@M-^], M-bM-^@M-^\3desM-bM-^@M-^], and M-bM-^@M-^\desM-bM-^@M-^] are + supported. des is only supported in the ssh(1) client for + interoperability with legacy protocol 1 implementations that do + not support the 3des cipher. Its use is strongly discouraged due + to cryptographic weaknesses. The default is M-bM-^@M-^\3desM-bM-^@M-^]. Ciphers Specifies the ciphers allowed for protocol version 2 in order of @@ -202,7 +207,7 @@ DESCRIPTION aes192-cbc,aes256-cbc,arcfour The list of available ciphers may also be obtained using the -Q - option of ssh(1). + option of ssh(1) with an argument of M-bM-^@M-^\cipherM-bM-^@M-^]. ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings @@ -210,12 +215,12 @@ DESCRIPTION cleared. This option is primarily useful when used from the ssh(1) command line to clear port forwardings set in configuration files, and is automatically set by scp(1) and - sftp(1). The argument must be ``yes'' or ``no''. The default is - ``no''. + sftp(1). The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is + M-bM-^@M-^\noM-bM-^@M-^]. Compression - Specifies whether to use compression. The argument must be - ``yes'' or ``no''. The default is ``no''. + Specifies whether to use compression. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] + or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. CompressionLevel Specifies the compression level to use if compression is enabled. @@ -237,16 +242,16 @@ DESCRIPTION ControlMaster Enables the sharing of multiple sessions over a single network - connection. When set to ``yes'', ssh(1) will listen for + connection. When set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will listen for connections on a control socket specified using the ControlPath argument. Additional sessions can connect to this socket using - the same ControlPath with ControlMaster set to ``no'' (the + the same ControlPath with ControlMaster set to M-bM-^@M-^\noM-bM-^@M-^] (the default). These sessions will try to reuse the master instance's network connection rather than initiating new ones, but will fall back to connecting normally if the control socket does not exist, or is not listening. - Setting this to ``ask'' will cause ssh to listen for control + Setting this to M-bM-^@M-^\askM-bM-^@M-^] will cause ssh to listen for control connections, but require confirmation using the SSH_ASKPASS program before they are accepted (see ssh-add(1) for details). If the ControlPath cannot be opened, ssh will continue without @@ -259,40 +264,41 @@ DESCRIPTION Two additional options allow for opportunistic multiplexing: try to use a master connection but fall back to creating a new one if - one does not already exist. These options are: ``auto'' and - ``autoask''. The latter requires confirmation like the ``ask'' + one does not already exist. These options are: M-bM-^@M-^\autoM-bM-^@M-^] and + M-bM-^@M-^\autoaskM-bM-^@M-^]. The latter requires confirmation like the M-bM-^@M-^\askM-bM-^@M-^] option. ControlPath Specify the path to the control socket used for connection sharing as described in the ControlMaster section above or the - string ``none'' to disable connection sharing. In the path, `%L' + string M-bM-^@M-^\noneM-bM-^@M-^] to disable connection sharing. In the path, M-bM-^@M-^X%LM-bM-^@M-^Y will be substituted by the first component of the local host - name, `%l' will be substituted by the local host name (including - any domain name), `%h' will be substituted by the target host - name, `%n' will be substituted by the original target host name - specified on the command line, `%p' the destination port, `%r' by - the remote login username, `%u' by the username of the user - running ssh(1), and `%C' by a hash of the concatenation: + name, M-bM-^@M-^X%lM-bM-^@M-^Y will be substituted by the local host name (including + any domain name), M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted by the target host + name, M-bM-^@M-^X%nM-bM-^@M-^Y will be substituted by the original target host name + specified on the command line, M-bM-^@M-^X%pM-bM-^@M-^Y the destination port, M-bM-^@M-^X%rM-bM-^@M-^Y by + the remote login username, M-bM-^@M-^X%uM-bM-^@M-^Y by the username of the user + running ssh(1), and M-bM-^@M-^X%CM-bM-^@M-^Y by a hash of the concatenation: %l%h%p%r. It is recommended that any ControlPath used for opportunistic connection sharing include at least %h, %p, and %r - (or alternatively %C). This ensures that shared connections are - uniquely identified. + (or alternatively %C) and be placed in a directory that is not + writable by other users. This ensures that shared connections + are uniquely identified. ControlPersist When used in conjunction with ControlMaster, specifies that the master connection should remain open in the background (waiting for future client connections) after the initial client - connection has been closed. If set to ``no'', then the master + connection has been closed. If set to M-bM-^@M-^\noM-bM-^@M-^], then the master connection will not be placed into the background, and will close as soon as the initial client connection is closed. If set to - ``yes'', then the master connection will remain in the background - indefinitely (until killed or closed via a mechanism such as the - ssh(1) ``-O exit'' option). If set to a time in seconds, or a - time in any of the formats documented in sshd_config(5), then the - backgrounded master connection will automatically terminate after - it has remained idle (with no client connections) for the - specified time. + M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\0M-bM-^@M-^], then the master connection will remain in the + background indefinitely (until killed or closed via a mechanism + such as the ssh(1) M-bM-^@M-^\-O exitM-bM-^@M-^] option). If set to a time in + seconds, or a time in any of the formats documented in + sshd_config(5), then the backgrounded master connection will + automatically terminate after it has remained idle (with no + client connections) for the specified time. DynamicForward Specifies that a TCP port on the local machine be forwarded over @@ -304,9 +310,9 @@ DESCRIPTION the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of - ``localhost'' indicates that the listening port be bound for - local use only, while an empty address or `*' indicates that the - port should be available from all interfaces. + M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local + use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port + should be available from all interfaces. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh(1) will act as a SOCKS server. Multiple forwardings may be @@ -314,30 +320,35 @@ DESCRIPTION line. Only the superuser can forward privileged ports. EnableSSHKeysign - Setting this option to ``yes'' in the global client configuration + Setting this option to M-bM-^@M-^\yesM-bM-^@M-^] in the global client configuration file /etc/ssh/ssh_config enables the use of the helper program ssh-keysign(8) during HostbasedAuthentication. The argument must - be ``yes'' or ``no''. The default is ``no''. This option should - be placed in the non-hostspecific section. See ssh-keysign(8) - for more information. + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. This option should be + placed in the non-hostspecific section. See ssh-keysign(8) for + more information. EscapeChar - Sets the escape character (default: `~'). The escape character + Sets the escape character (default: M-bM-^@M-^X~M-bM-^@M-^Y). The escape character can also be set on the command line. The argument should be a - single character, `^' followed by a letter, or ``none'' to - disable the escape character entirely (making the connection - transparent for binary data). + single character, M-bM-^@M-^X^M-bM-^@M-^Y followed by a letter, or M-bM-^@M-^\noneM-bM-^@M-^] to disable + the escape character entirely (making the connection transparent + for binary data). ExitOnForwardFailure Specifies whether ssh(1) should terminate the connection if it cannot set up all requested dynamic, tunnel, local, and remote - port forwardings. The argument must be ``yes'' or ``no''. The - default is ``no''. + port forwardings. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. + + FingerprintHash + Specifies the hash algorithm used when displaying key + fingerprints. Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The + default is M-bM-^@M-^\sha256M-bM-^@M-^]. ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. The argument must - be ``yes'' or ``no''. The default is ``no''. + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. Agent forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the @@ -350,7 +361,7 @@ DESCRIPTION ForwardX11 Specifies whether X11 connections will be automatically redirected over the secure channel and DISPLAY set. The argument - must be ``yes'' or ``no''. The default is ``no''. + must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. X11 forwarding should be enabled with caution. Users with the ability to bypass file permissions on the remote host (for the @@ -367,17 +378,17 @@ DESCRIPTION minutes has elapsed. ForwardX11Trusted - If this option is set to ``yes'', remote X11 clients will have - full access to the original X11 display. + If this option is set to M-bM-^@M-^\yesM-bM-^@M-^], remote X11 clients will have full + access to the original X11 display. - If this option is set to ``no'', remote X11 clients will be + If this option is set to M-bM-^@M-^\noM-bM-^@M-^], remote X11 clients will be considered untrusted and prevented from stealing or tampering with data belonging to trusted X11 clients. Furthermore, the xauth(1) token used for the session will be set to expire after 20 minutes. Remote clients will be refused access after this time. - The default is ``no''. + The default is M-bM-^@M-^\noM-bM-^@M-^]. See the X11 SECURITY extension specification for full details on the restrictions imposed on untrusted clients. @@ -389,8 +400,8 @@ DESCRIPTION connecting to forwarded ports. GatewayPorts can be used to specify that ssh should bind local port forwardings to the wildcard address, thus allowing remote hosts to connect to - forwarded ports. The argument must be ``yes'' or ``no''. The - default is ``no''. + forwarded ports. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. GlobalKnownHostsFile Specifies one or more files to use for the global host key @@ -399,28 +410,33 @@ DESCRIPTION GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. - The default is ``no''. Note that this option applies to protocol + The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 only. GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is - ``no''. Note that this option applies to protocol version 2 - only. + M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 only. HashKnownHosts Indicates that ssh(1) should hash host names and addresses when they are added to ~/.ssh/known_hosts. These hashed names may be used normally by ssh(1) and sshd(8), but they do not reveal identifying information should the file's contents be disclosed. - The default is ``no''. Note that existing names and addresses in + The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that existing names and addresses in known hosts files will not be converted automatically, but may be manually hashed using ssh-keygen(1). HostbasedAuthentication Specifies whether to try rhosts based authentication with public - key authentication. The argument must be ``yes'' or ``no''. The - default is ``no''. This option applies to protocol version 2 - only and is similar to RhostsRSAAuthentication. + key authentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 2 only + and is similar to RhostsRSAAuthentication. + + HostbasedKeyTypes + Specifies the key types that will be used for hostbased + authentication as a comma-separated pattern list. The default + M-bM-^@M-^\*M-bM-^@M-^] will allow all key types. The -Q option of ssh(1) may be + used to list supported key types. HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the @@ -439,6 +455,9 @@ DESCRIPTION If hostkeys are known for the destination host then this default is modified to prefer their algorithms. + The list of available key types may also be obtained using the -Q + option of ssh(1) with an argument of M-bM-^@M-^\keyM-bM-^@M-^]. + HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key in the host key @@ -448,10 +467,10 @@ DESCRIPTION HostName Specifies the real host name to log into. This can be used to specify nicknames or abbreviations for hosts. If the hostname - contains the character sequence `%h', then this will be replaced + contains the character sequence M-bM-^@M-^X%hM-bM-^@M-^Y, then this will be replaced with the host name specified on the command line (this is useful - for manipulating unqualified names). The character sequence `%%' - will be replaced by a single `%' character, which may be used + for manipulating unqualified names). The character sequence M-bM-^@M-^X%%M-bM-^@M-^Y + will be replaced by a single M-bM-^@M-^X%M-bM-^@M-^Y character, which may be used when specifying IPv6 link-local addresses. The default is the name given on the command line. Numeric IP @@ -462,12 +481,12 @@ DESCRIPTION Specifies that ssh(1) should only use the authentication identity files configured in the ssh_config files, even if ssh-agent(1) or a PKCS11Provider offers more identities. The argument to this - keyword must be ``yes'' or ``no''. This option is intended for + keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. This option is intended for situations where ssh-agent offers many different identities. The - default is ``no''. + default is M-bM-^@M-^\noM-bM-^@M-^]. IdentityFile - Specifies a file from which the user's DSA, ECDSA, ED25519 or RSA + Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication identity is read. The default is ~/.ssh/identity for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. @@ -478,9 +497,9 @@ DESCRIPTION specified IdentityFile. The file name may use the tilde syntax to refer to a user's home - directory or one of the following escape characters: `%d' (local - user's home directory), `%u' (local user name), `%l' (local host - name), `%h' (remote host name) or `%r' (remote user name). + directory or one of the following escape characters: M-bM-^@M-^X%dM-bM-^@M-^Y (local + user's home directory), M-bM-^@M-^X%uM-bM-^@M-^Y (local user name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host + name), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host name) or M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name). It is possible to have multiple identity files specified in configuration files; all these identities will be tried in @@ -501,30 +520,30 @@ DESCRIPTION to unknown options that appear before it. IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. - Accepted values are ``af11'', ``af12'', ``af13'', ``af21'', - ``af22'', ``af23'', ``af31'', ``af32'', ``af33'', ``af41'', - ``af42'', ``af43'', ``cs0'', ``cs1'', ``cs2'', ``cs3'', ``cs4'', - ``cs5'', ``cs6'', ``cs7'', ``ef'', ``lowdelay'', ``throughput'', - ``reliability'', or a numeric value. This option may take one or - two arguments, separated by whitespace. If one argument is - specified, it is used as the packet class unconditionally. If - two values are specified, the first is automatically selected for - interactive sessions and the second for non-interactive sessions. - The default is ``lowdelay'' for interactive sessions and - ``throughput'' for non-interactive sessions. + Accepted values are M-bM-^@M-^\af11M-bM-^@M-^], M-bM-^@M-^\af12M-bM-^@M-^], M-bM-^@M-^\af13M-bM-^@M-^], M-bM-^@M-^\af21M-bM-^@M-^], M-bM-^@M-^\af22M-bM-^@M-^], + M-bM-^@M-^\af23M-bM-^@M-^], M-bM-^@M-^\af31M-bM-^@M-^], M-bM-^@M-^\af32M-bM-^@M-^], M-bM-^@M-^\af33M-bM-^@M-^], M-bM-^@M-^\af41M-bM-^@M-^], M-bM-^@M-^\af42M-bM-^@M-^], M-bM-^@M-^\af43M-bM-^@M-^], M-bM-^@M-^\cs0M-bM-^@M-^], + M-bM-^@M-^\cs1M-bM-^@M-^], M-bM-^@M-^\cs2M-bM-^@M-^], M-bM-^@M-^\cs3M-bM-^@M-^], M-bM-^@M-^\cs4M-bM-^@M-^], M-bM-^@M-^\cs5M-bM-^@M-^], M-bM-^@M-^\cs6M-bM-^@M-^], M-bM-^@M-^\cs7M-bM-^@M-^], M-bM-^@M-^\efM-bM-^@M-^], + M-bM-^@M-^\lowdelayM-bM-^@M-^], M-bM-^@M-^\throughputM-bM-^@M-^], M-bM-^@M-^\reliabilityM-bM-^@M-^], or a numeric value. + This option may take one or two arguments, separated by + whitespace. If one argument is specified, it is used as the + packet class unconditionally. If two values are specified, the + first is automatically selected for interactive sessions and the + second for non-interactive sessions. The default is M-bM-^@M-^\lowdelayM-bM-^@M-^] + for interactive sessions and M-bM-^@M-^\throughputM-bM-^@M-^] for non-interactive + sessions. KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. - The argument to this keyword must be ``yes'' or ``no''. The - default is ``yes''. + The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default + is M-bM-^@M-^\yesM-bM-^@M-^]. KbdInteractiveDevices Specifies the list of methods to use in keyboard-interactive authentication. Multiple method names must be comma-separated. The default is to use the server specified list. The methods available vary depending on what the server supports. For an - OpenSSH server, it may be zero or more of: ``bsdauth'', ``pam'', - and ``skey''. + OpenSSH server, it may be zero or more of: M-bM-^@M-^\bsdauthM-bM-^@M-^], M-bM-^@M-^\pamM-bM-^@M-^], and + M-bM-^@M-^\skeyM-bM-^@M-^]. KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple @@ -537,15 +556,18 @@ DESCRIPTION diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1 + The list of available key exchange algorithms may also be + obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\kexM-bM-^@M-^]. + LocalCommand Specifies a command to execute on the local machine after successfully connecting to the server. The command string extends to the end of the line, and is executed with the user's shell. The following escape character substitutions will be - performed: `%d' (local user's home directory), `%h' (remote host - name), `%l' (local host name), `%n' (host name as provided on the - command line), `%p' (remote port), `%r' (remote user name) or - `%u' (local user name) or `%C' by a hash of the concatenation: + performed: M-bM-^@M-^X%dM-bM-^@M-^Y (local user's home directory), M-bM-^@M-^X%hM-bM-^@M-^Y (remote host + name), M-bM-^@M-^X%lM-bM-^@M-^Y (local host name), M-bM-^@M-^X%nM-bM-^@M-^Y (host name as provided on the + command line), M-bM-^@M-^X%pM-bM-^@M-^Y (remote port), M-bM-^@M-^X%rM-bM-^@M-^Y (remote user name) or + M-bM-^@M-^X%uM-bM-^@M-^Y (local user name) or M-bM-^@M-^X%CM-bM-^@M-^Y by a hash of the concatenation: %l%h%p%r. The command is run synchronously and does not have access to the @@ -566,9 +588,9 @@ DESCRIPTION privileged ports. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific - address. The bind_address of ``localhost'' indicates that the + address. The bind_address of M-bM-^@M-^\localhostM-bM-^@M-^] indicates that the listening port be bound for local use only, while an empty - address or `*' indicates that the port should be available from + address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. LogLevel @@ -581,7 +603,7 @@ DESCRIPTION MACs Specifies the MAC (message authentication code) algorithms in order of preference. The MAC algorithm is used in protocol version 2 for data integrity protection. Multiple algorithms - must be comma-separated. The algorithms that contain ``-etm'' + must be comma-separated. The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC after encryption (encrypt-then-mac). These are considered safer and their use recommended. The default is: @@ -595,14 +617,17 @@ DESCRIPTION hmac-md5,hmac-sha1,hmac-ripemd160, hmac-sha1-96,hmac-md5-96 + The list of available MAC algorithms may also be obtained using + the -Q option of ssh(1) with an argument of M-bM-^@M-^\macM-bM-^@M-^]. + NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different machine on each of the machines and the user will get many warnings about changed host keys. However, this option disables host authentication for localhost. The argument to this keyword - must be ``yes'' or ``no''. The default is to check the host key - for localhost. + must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is to check the host key for + localhost. NumberOfPasswordPrompts Specifies the number of password prompts before giving up. The @@ -610,13 +635,12 @@ DESCRIPTION PasswordAuthentication Specifies whether to use password authentication. The argument - to this keyword must be ``yes'' or ``no''. The default is - ``yes''. + to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. PermitLocalCommand Allow local command execution via the LocalCommand option or using the !command escape sequence in ssh(1). The argument must - be ``yes'' or ``no''. The default is ``no''. + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. PKCS11Provider Specifies which PKCS#11 provider to use. The argument to this @@ -638,26 +662,26 @@ DESCRIPTION Protocol Specifies the protocol versions ssh(1) should support in order of - preference. The possible values are `1' and `2'. Multiple + preference. The possible values are M-bM-^@M-^X1M-bM-^@M-^Y and M-bM-^@M-^X2M-bM-^@M-^Y. Multiple versions must be comma-separated. When this option is set to - ``2,1'' ssh will try version 2 and fall back to version 1 if - version 2 is not available. The default is `2'. + M-bM-^@M-^\2,1M-bM-^@M-^] ssh will try version 2 and fall back to version 1 if + version 2 is not available. The default is M-bM-^@M-^X2M-bM-^@M-^Y. ProxyCommand Specifies the command to use to connect to the server. The command string extends to the end of the line, and is executed - using the user's shell `exec' directive to avoid a lingering + using the user's shell M-bM-^@M-^XexecM-bM-^@M-^Y directive to avoid a lingering shell process. - In the command string, any occurrence of `%h' will be substituted - by the host name to connect, `%p' by the port, and `%r' by the + In the command string, any occurrence of M-bM-^@M-^X%hM-bM-^@M-^Y will be substituted + by the host name to connect, M-bM-^@M-^X%pM-bM-^@M-^Y by the port, and M-bM-^@M-^X%rM-bM-^@M-^Y by the remote user name. The command can be basically anything, and should read from its standard input and write to its standard output. It should eventually connect an sshd(8) server running on some machine, or execute sshd -i somewhere. Host key management will be done using the HostName of the host being connected (defaulting to the name typed by the user). Setting - the command to ``none'' disables this option entirely. Note that + the command to M-bM-^@M-^\noneM-bM-^@M-^] disables this option entirely. Note that CheckHostIP is not available for connects with a proxy command. This directive is useful in conjunction with nc(1) and its proxy @@ -669,27 +693,27 @@ DESCRIPTION ProxyUseFdpass Specifies that ProxyCommand will pass a connected file descriptor back to ssh(1) instead of continuing to execute and pass data. - The default is ``no''. + The default is M-bM-^@M-^\noM-bM-^@M-^]. PubkeyAuthentication Specifies whether to try public key authentication. The argument - to this keyword must be ``yes'' or ``no''. The default is - ``yes''. This option applies to protocol version 2 only. + to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. + This option applies to protocol version 2 only. RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of time that may pass before the session key is renegotiated. The first argument is specified in bytes and may - have a suffix of `K', `M', or `G' to indicate Kilobytes, + have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes, Megabytes, or Gigabytes, respectively. The default is between - `1G' and `4G', depending on the cipher. The optional second + M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher. The optional second value is specified in seconds and may use any of the units documented in the TIME FORMATS section of sshd_config(5). The - default value for RekeyLimit is ``default none'', which means - that rekeying is performed after the cipher's default amount of - data has been sent or received and no time based rekeying is - done. This option applies to protocol version 2 only. + default value for RekeyLimit is M-bM-^@M-^\default noneM-bM-^@M-^], which means that + rekeying is performed after the cipher's default amount of data + has been sent or received and no time based rekeying is done. + This option applies to protocol version 2 only. RemoteForward Specifies that a TCP port on the remote machine be forwarded over @@ -701,11 +725,11 @@ DESCRIPTION given on the command line. Privileged ports can be forwarded only when logging in as root on the remote machine. - If the port argument is `0', the listen port will be dynamically + If the port argument is M-bM-^@M-^X0M-bM-^@M-^Y, the listen port will be dynamically allocated on the server and reported to the client at run time. If the bind_address is not specified, the default is to only bind - to loopback addresses. If the bind_address is `*' or an empty + to loopback addresses. If the bind_address is M-bM-^@M-^X*M-bM-^@M-^Y or an empty string, then the forwarding is requested to listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see @@ -713,24 +737,32 @@ DESCRIPTION RequestTTY Specifies whether to request a pseudo-tty for the session. The - argument may be one of: ``no'' (never request a TTY), ``yes'' - (always request a TTY when standard input is a TTY), ``force'' - (always request a TTY) or ``auto'' (request a TTY when opening a - login session). This option mirrors the -t and -T flags for - ssh(1). + argument may be one of: M-bM-^@M-^\noM-bM-^@M-^] (never request a TTY), M-bM-^@M-^\yesM-bM-^@M-^] (always + request a TTY when standard input is a TTY), M-bM-^@M-^\forceM-bM-^@M-^] (always + request a TTY) or M-bM-^@M-^\autoM-bM-^@M-^] (request a TTY when opening a login + session). This option mirrors the -t and -T flags for ssh(1). + + RevokedHostKeys + Specifies revoked host public keys. Keys listed in this file + will be refused for host authentication. Note that if this file + does not exist or is not readable, then host authentication will + be refused for all hosts. Keys may be specified as a text file, + listing one public key per line, or as an OpenSSH Key Revocation + List (KRL) as generated by ssh-keygen(1). For more information + on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1). RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA - host authentication. The argument must be ``yes'' or ``no''. - The default is ``no''. This option applies to protocol version 1 - only and requires ssh(1) to be setuid root. + host authentication. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 1 only + and requires ssh(1) to be setuid root. RSAAuthentication Specifies whether to try RSA authentication. The argument to - this keyword must be ``yes'' or ``no''. RSA authentication will - only be attempted if the identity file exists, or an - authentication agent is running. The default is ``yes''. Note - that this option applies to protocol version 1 only. + this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. RSA authentication will only + be attempted if the identity file exists, or an authentication + agent is running. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option + applies to protocol version 1 only. SendEnv Specifies what variables from the local environ(7) should be sent @@ -790,24 +822,24 @@ DESCRIPTION domain socket file. This option is only used for port forwarding to a Unix-domain socket file. - The argument must be ``yes'' or ``no''. The default is ``no''. + The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. StrictHostKeyChecking - If this flag is set to ``yes'', ssh(1) will never automatically - add host keys to the ~/.ssh/known_hosts file, and refuses to - connect to hosts whose host key has changed. This provides - maximum protection against trojan horse attacks, though it can be + If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) will never automatically add + host keys to the ~/.ssh/known_hosts file, and refuses to connect + to hosts whose host key has changed. This provides maximum + protection against trojan horse attacks, though it can be annoying when the /etc/ssh/ssh_known_hosts file is poorly maintained or when connections to new hosts are frequently made. This option forces the user to manually add all new hosts. If - this flag is set to ``no'', ssh will automatically add new host + this flag is set to M-bM-^@M-^\noM-bM-^@M-^], ssh will automatically add new host keys to the user known hosts files. If this flag is set to - ``ask'', new host keys will be added to the user known host files + M-bM-^@M-^\askM-bM-^@M-^], new host keys will be added to the user known host files only after the user has confirmed that is what they really want to do, and ssh will refuse to connect to hosts whose host key has changed. The host keys of known hosts will be verified - automatically in all cases. The argument must be ``yes'', - ``no'', or ``ask''. The default is ``ask''. + automatically in all cases. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or + M-bM-^@M-^\askM-bM-^@M-^]. The default is M-bM-^@M-^\askM-bM-^@M-^]. TCPKeepAlive Specifies whether the system should send TCP keepalive messages @@ -816,34 +848,53 @@ DESCRIPTION this means that connections will die if the route is down temporarily, and some people find it annoying. - The default is ``yes'' (to send TCP keepalive messages), and the + The default is M-bM-^@M-^\yesM-bM-^@M-^] (to send TCP keepalive messages), and the client will notice if the network goes down or the remote host dies. This is important in scripts, and many users want it too. To disable TCP keepalive messages, the value should be set to - ``no''. + M-bM-^@M-^\noM-bM-^@M-^]. Tunnel Request tun(4) device forwarding between the client and the - server. The argument must be ``yes'', ``point-to-point'' (layer - 3), ``ethernet'' (layer 2), or ``no''. Specifying ``yes'' - requests the default tunnel mode, which is ``point-to-point''. - The default is ``no''. + server. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\point-to-pointM-bM-^@M-^] (layer 3), + M-bM-^@M-^\ethernetM-bM-^@M-^] (layer 2), or M-bM-^@M-^\noM-bM-^@M-^]. Specifying M-bM-^@M-^\yesM-bM-^@M-^] requests the + default tunnel mode, which is M-bM-^@M-^\point-to-pointM-bM-^@M-^]. The default is + M-bM-^@M-^\noM-bM-^@M-^]. TunnelDevice Specifies the tun(4) devices to open on the client (local_tun) and the server (remote_tun). The argument must be local_tun[:remote_tun]. The devices may be - specified by numerical ID or the keyword ``any'', which uses the + specified by numerical ID or the keyword M-bM-^@M-^\anyM-bM-^@M-^], which uses the next available tunnel device. If remote_tun is not specified, it - defaults to ``any''. The default is ``any:any''. + defaults to M-bM-^@M-^\anyM-bM-^@M-^]. The default is M-bM-^@M-^\any:anyM-bM-^@M-^]. + + UpdateHostKeys + Specifies whether ssh(1) should accept notifications of + additional hostkeys from the server sent after authentication has + completed and add them to UserKnownHostsFile. The argument must + be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^] (the default) or M-bM-^@M-^\askM-bM-^@M-^]. Enabling this option + allows learning alternate hostkeys for a server and supports + graceful key rotation by allowing a server to send replacement + public keys before old ones are removed. Additional hostkeys are + only accepted if the key used to authenticate the host was + already trusted or explicity accepted by the user. If + UpdateHostKeys is set to M-bM-^@M-^\askM-bM-^@M-^], then the user is asked to confirm + the modifications to the known_hosts file. Confirmation is + currently incompatible with ControlPersist, and will be disabled + if it is enabled. + + Presently, only sshd(8) from OpenSSH 6.8 and greater support the + M-bM-^@M-^\hostkeys@openssh.comM-bM-^@M-^] protocol extension used to inform the + client of all the server's hostkeys. UsePrivilegedPort Specifies whether to use a privileged port for outgoing - connections. The argument must be ``yes'' or ``no''. The - default is ``no''. If set to ``yes'', ssh(1) must be setuid - root. Note that this option must be set to ``yes'' for - RhostsRSAAuthentication with older servers. + connections. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is + M-bM-^@M-^\noM-bM-^@M-^]. If set to M-bM-^@M-^\yesM-bM-^@M-^], ssh(1) must be setuid root. Note that + this option must be set to M-bM-^@M-^\yesM-bM-^@M-^] for RhostsRSAAuthentication with + older servers. User Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves @@ -857,35 +908,35 @@ DESCRIPTION VerifyHostKeyDNS Specifies whether to verify the remote key using DNS and SSHFP - resource records. If this option is set to ``yes'', the client + resource records. If this option is set to M-bM-^@M-^\yesM-bM-^@M-^], the client will implicitly trust keys that match a secure fingerprint from DNS. Insecure fingerprints will be handled as if this option was - set to ``ask''. If this option is set to ``ask'', information on + set to M-bM-^@M-^\askM-bM-^@M-^]. If this option is set to M-bM-^@M-^\askM-bM-^@M-^], information on fingerprint match will be displayed, but the user will still need to confirm new host keys according to the StrictHostKeyChecking - option. The argument must be ``yes'', ``no'', or ``ask''. The - default is ``no''. Note that this option applies to protocol - version 2 only. + option. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\askM-bM-^@M-^]. The default + is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 + only. See also VERIFYING HOST KEYS in ssh(1). VisualHostKey - If this flag is set to ``yes'', an ASCII art representation of - the remote host key fingerprint is printed in addition to the hex + If this flag is set to M-bM-^@M-^\yesM-bM-^@M-^], an ASCII art representation of the + remote host key fingerprint is printed in addition to the fingerprint string at login and for unknown host keys. If this - flag is set to ``no'', no fingerprint strings are printed at - login and only the hex fingerprint string will be printed for - unknown host keys. The default is ``no''. + flag is set to M-bM-^@M-^\noM-bM-^@M-^], no fingerprint strings are printed at login + and only the fingerprint string will be printed for unknown host + keys. The default is M-bM-^@M-^\noM-bM-^@M-^]. XAuthLocation Specifies the full pathname of the xauth(1) program. The default is /usr/X11R6/bin/xauth. PATTERNS - A pattern consists of zero or more non-whitespace characters, `*' (a - wildcard that matches zero or more characters), or `?' (a wildcard that + A pattern consists of zero or more non-whitespace characters, M-bM-^@M-^X*M-bM-^@M-^Y (a + wildcard that matches zero or more characters), or M-bM-^@M-^X?M-bM-^@M-^Y (a wildcard that matches exactly one character). For example, to specify a set of - declarations for any host in the ``.co.uk'' set of domains, the following + declarations for any host in the M-bM-^@M-^\.co.ukM-bM-^@M-^] set of domains, the following pattern could be used: Host *.co.uk @@ -897,8 +948,8 @@ PATTERNS A pattern-list is a comma-separated list of patterns. Patterns within pattern-lists may be negated by preceding them with an exclamation mark - (`!'). For example, to allow a key to be used from anywhere within an - organization except from the ``dialup'' pool, the following entry (in + (M-bM-^@M-^X!M-bM-^@M-^Y). For example, to allow a key to be used from anywhere within an + organization except from the M-bM-^@M-^\dialupM-bM-^@M-^] pool, the following entry (in authorized_keys) could be used: from="!*.dialup.example.com,*.example.com" @@ -927,4 +978,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.6 July 15, 2014 OpenBSD 5.6 +OpenBSD 5.7 February 20, 2015 OpenBSD 5.7 diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5 index 6049e4a1d6b1..16769a448744 100644 --- a/crypto/openssh/ssh_config.5 +++ b/crypto/openssh/ssh_config.5 @@ -33,9 +33,9 @@ .\" (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.191 2014/07/15 15:54:14 millert Exp $ +.\" $OpenBSD: ssh_config.5,v 1.205 2015/02/20 22:17:21 djm Exp $ .\" $FreeBSD$ -.Dd $Mdocdate: July 15 2014 $ +.Dd $Mdocdate: February 20 2015 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -66,7 +66,10 @@ The configuration files contain sections separated by .Dq Host specifications, and that section is only applied for hosts that match one of the patterns given in the specification. -The matched host name is the one given on the command line. +The matched host name is usually the one given on the command line +(see the +.Cm CanonicalizeHostname +option for exceptions.) .Pp Since the first obtained value for each parameter is used, more host-specific declarations should be given near the beginning of the @@ -110,10 +113,12 @@ A single .Ql * as a pattern can be used to provide global defaults for all hosts. -The host is the +The host is usually the .Ar hostname -argument given on the command line (i.e. the name is not converted to -a canonicalized host name before matching). +argument given on the command line +(see the +.Cm CanonicalizeHostname +option for exceptions.) .Pp A pattern entry may be negated by prefixing it with an exclamation mark .Pq Sq !\& . @@ -135,19 +140,40 @@ or keyword) to be used only when the conditions following the .Cm Match keyword are satisfied. -Match conditions are specified using one or more keyword/criteria pairs +Match conditions are specified using one or more critera or the single token .Cm all -which matches all criteria. -The available keywords are: +which always matches. +The available criteria keywords are: +.Cm canonical , .Cm exec , .Cm host , .Cm originalhost , .Cm user , and .Cm localuser . +The +.Cm all +criteria must appear alone or immediately after +.Cm canonical . +Other criteria may be combined arbitrarily. +All criteria but +.Cm all +and +.Cm canonical +require an argument. +Criteria may be negated by prepending an exclamation mark +.Pq Sq !\& . .Pp The +.Cm canonical +keywork matches only when the configuration file is being re-parsed +after hostname canonicalization (see the +.Cm CanonicalizeHostname +option.) +This may be useful to specify conditions that work with canonical host +names only. +The .Cm exec keyword executes the specified command under the user's shell. If the command returns a zero exit status then the condition is considered true. @@ -180,7 +206,9 @@ The criteria for the keyword are matched against the target hostname, after any substitution by the .Cm Hostname -option. +or +.Cm CanonicalizeHostname +options. The .Cm originalhost keyword matches against the hostname as it was specified on the command-line. @@ -265,10 +293,11 @@ is set to .Dq always , then canonicalization is applied to proxied connections too. .Pp -If this option is enabled and canonicalisation results in the target hostname -changing, then the configuration files are processed again using the new -target name to pick up any new configuration in matching +If this option is enabled, then the configuration files are processed +again using the new target name to pick up any new configuration in matching .Cm Host +and +.Cm Match stanzas. .It Cm CanonicalizeMaxDots Specifies the maximum number of dot characters in a hostname before @@ -389,7 +418,9 @@ aes192-cbc,aes256-cbc,arcfour The list of available ciphers may also be obtained using the .Fl Q option of -.Xr ssh 1 . +.Xr ssh 1 +with an argument of +.Dq cipher . .It Cm ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings specified in the configuration files or on the command line be @@ -509,7 +540,8 @@ by a hash of the concatenation: %l%h%p%r. It is recommended that any .Cm ControlPath used for opportunistic connection sharing include -at least %h, %p, and %r (or alternatively %C). +at least %h, %p, and %r (or alternatively %C) and be placed in a directory +that is not writable by other users. This ensures that shared connections are uniquely identified. .It Cm ControlPersist When used in conjunction with @@ -522,7 +554,9 @@ If set to then the master connection will not be placed into the background, and will close as soon as the initial client connection is closed. If set to -.Dq yes , +.Dq yes +or +.Dq 0 , then the master connection will remain in the background indefinitely (until killed or closed via a mechanism such as the .Xr ssh 1 @@ -607,6 +641,14 @@ or .Dq no . The default is .Dq no . +.It Cm FingerprintHash +Specifies the hash algorithm used when displaying key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. @@ -736,6 +778,17 @@ The default is This option applies to protocol version 2 only and is similar to .Cm RhostsRSAAuthentication . +.It Cm HostbasedKeyTypes +Specifies the key types that will be used for hostbased authentication +as a comma-separated pattern list. +The default +.Dq * +will allow all key types. +The +.Fl Q +option of +.Xr ssh 1 +may be used to list supported key types. .It Cm HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. @@ -753,6 +806,13 @@ ssh-ed25519,ssh-rsa,ssh-dss .Pp If hostkeys are known for the destination host then this default is modified to prefer their algorithms. +.Pp +The list of available key types may also be obtained using the +.Fl Q +option of +.Xr ssh 1 +with an argument of +.Dq key . .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key @@ -796,7 +856,7 @@ offers many different identities. The default is .Dq no . .It Cm IdentityFile -Specifies a file from which the user's DSA, ECDSA, ED25519 or RSA authentication +Specifies a file from which the user's DSA, ECDSA, Ed25519 or RSA authentication identity is read. The default is .Pa ~/.ssh/identity @@ -923,6 +983,13 @@ diffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1 .Ed +.Pp +The list of available key exchange algorithms may also be obtained using the +.Fl Q +option of +.Xr ssh 1 +with an argument of +.Dq kex . .It Cm LocalCommand Specifies a command to execute on the local machine after successfully connecting to the server. @@ -1012,6 +1079,13 @@ hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com, hmac-md5,hmac-sha1,hmac-ripemd160, hmac-sha1-96,hmac-md5-96 .Ed +.Pp +The list of available MAC algorithms may also be obtained using the +.Fl Q +option of +.Xr ssh 1 +with an argument of +.Dq mac . .It Cm NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different machine on each of @@ -1222,6 +1296,16 @@ and .Fl T flags for .Xr ssh 1 . +.It Cm RevokedHostKeys +Specifies revoked host public keys. +Keys listed in this file will be refused for host authentication. +Note that if this file does not exist or is not readable, +then host authentication will be refused for all hosts. +Keys may be specified as a text file, listing one public key per line, or as +an OpenSSH Key Revocation List (KRL) as generated by +.Xr ssh-keygen 1 . +For more information on KRLs, see the KEY REVOCATION LISTS section in +.Xr ssh-keygen 1 . .It Cm RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. @@ -1420,6 +1504,36 @@ is not specified, it defaults to .Dq any . The default is .Dq any:any . +.It Cm UpdateHostKeys +Specifies whether +.Xr ssh 1 +should accept notifications of additional hostkeys from the server sent +after authentication has completed and add them to +.Cm UserKnownHostsFile . +The argument must be +.Dq yes , +.Dq no +(the default) or +.Dq ask . +Enabling this option allows learning alternate hostkeys for a server +and supports graceful key rotation by allowing a server to send replacement +public keys before old ones are removed. +Additional hostkeys are only accepted if the key used to authenticate the +host was already trusted or explicity accepted by the user. +If +.Cm UpdateHostKeys +is set to +.Dq ask , +then the user is asked to confirm the modifications to the known_hosts file. +Confirmation is currently incompatible with +.Cm ControlPersist , +and will be disabled if it is enabled. +.Pp +Presently, only +.Xr sshd 8 +from OpenSSH 6.8 and greater support the +.Dq hostkeys@openssh.com +protocol extension used to inform the client of all the server's hostkeys. .It Cm UsePrivilegedPort Specifies whether to use a privileged port for outgoing connections. The argument must be @@ -1489,12 +1603,12 @@ may be used to disable this. If this flag is set to .Dq yes , an ASCII art representation of the remote host key fingerprint is -printed in addition to the hex fingerprint string at login and +printed in addition to the fingerprint string at login and for unknown host keys. If this flag is set to .Dq no , no fingerprint strings are printed at login and -only the hex fingerprint string will be printed for unknown host keys. +only the fingerprint string will be printed for unknown host keys. The default is .Dq no . .It Cm XAuthLocation diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h index c26f3903a7ed..cfaa7f503fec 100644 --- a/crypto/openssh/ssh_namespace.h +++ b/crypto/openssh/ssh_namespace.h @@ -8,749 +8,924 @@ * A list of symbols which need munging is obtained as follows: * # nm libprivatessh.a | LC_ALL=C awk ' - /^[0-9a-z]+ [Tt] [A-Za-z_][0-9A-Za-z_]*$/ && $3 !~ /^ssh_/ { - printf("#define %-39s ssh_%s\n", $3, $3) + /^[0-9a-z]+ [Tt] [A-Za-z_][0-9A-Za-z_]*$/ && $3 !~ /^Fssh_/ { + printf("#define %-39s Fssh_%s\n", $3, $3) }' | unexpand -a | LC_ALL=C sort -u * * $FreeBSD$ */ -#define Blowfish_decipher ssh_Blowfish_decipher -#define Blowfish_encipher ssh_Blowfish_encipher -#define Blowfish_expand0state ssh_Blowfish_expand0state -#define Blowfish_expandstate ssh_Blowfish_expandstate -#define Blowfish_initstate ssh_Blowfish_initstate -#define Blowfish_stream2word ssh_Blowfish_stream2word -#define a2port ssh_a2port -#define a2tun ssh_a2tun -#define add_host_to_hostfile ssh_add_host_to_hostfile -#define add_p1p1 ssh_add_p1p1 -#define addargs ssh_addargs -#define addr_match_cidr_list ssh_addr_match_cidr_list -#define addr_match_list ssh_addr_match_list -#define addr_netmatch ssh_addr_netmatch -#define addr_pton ssh_addr_pton -#define addr_pton_cidr ssh_addr_pton_cidr -#define ask_permission ssh_ask_permission -#define atomicio ssh_atomicio -#define atomicio6 ssh_atomicio6 -#define atomiciov ssh_atomiciov -#define atomiciov6 ssh_atomiciov6 -#define auth_request_forwarding ssh_auth_request_forwarding -#define bandwidth_limit ssh_bandwidth_limit -#define bandwidth_limit_init ssh_bandwidth_limit_init -#define barrett_reduce ssh_barrett_reduce -#define bcrypt_hash ssh_bcrypt_hash -#define bcrypt_pbkdf ssh_bcrypt_pbkdf -#define bf_ssh1_cipher ssh_bf_ssh1_cipher -#define blf_cbc_decrypt ssh_blf_cbc_decrypt -#define blf_cbc_encrypt ssh_blf_cbc_encrypt -#define blf_dec ssh_blf_dec -#define blf_ecb_decrypt ssh_blf_ecb_decrypt -#define blf_ecb_encrypt ssh_blf_ecb_encrypt -#define blf_enc ssh_blf_enc -#define blf_key ssh_blf_key -#define buffer_append ssh_buffer_append -#define buffer_append_space ssh_buffer_append_space -#define buffer_check_alloc ssh_buffer_check_alloc -#define buffer_compress ssh_buffer_compress -#define buffer_compress_init_recv ssh_buffer_compress_init_recv -#define buffer_compress_init_send ssh_buffer_compress_init_send -#define buffer_compress_uninit ssh_buffer_compress_uninit -#define buffer_consume ssh_buffer_consume -#define buffer_consume_end ssh_buffer_consume_end -#define buffer_consume_end_ret ssh_buffer_consume_end_ret -#define buffer_consume_ret ssh_buffer_consume_ret -#define buffer_get ssh_buffer_get -#define buffer_get_bignum ssh_buffer_get_bignum -#define buffer_get_bignum2 ssh_buffer_get_bignum2 -#define buffer_get_bignum2_ret ssh_buffer_get_bignum2_ret -#define buffer_get_bignum_ret ssh_buffer_get_bignum_ret -#define buffer_get_char ssh_buffer_get_char -#define buffer_get_char_ret ssh_buffer_get_char_ret -#define buffer_get_cstring ssh_buffer_get_cstring -#define buffer_get_cstring_ret ssh_buffer_get_cstring_ret -#define buffer_get_ecpoint ssh_buffer_get_ecpoint -#define buffer_get_ecpoint_ret ssh_buffer_get_ecpoint_ret -#define buffer_get_int ssh_buffer_get_int -#define buffer_get_int64 ssh_buffer_get_int64 -#define buffer_get_int64_ret ssh_buffer_get_int64_ret -#define buffer_get_int_ret ssh_buffer_get_int_ret -#define buffer_get_ret ssh_buffer_get_ret -#define buffer_get_short ssh_buffer_get_short -#define buffer_get_short_ret ssh_buffer_get_short_ret -#define buffer_get_string ssh_buffer_get_string -#define buffer_get_string_ptr ssh_buffer_get_string_ptr -#define buffer_get_string_ptr_ret ssh_buffer_get_string_ptr_ret -#define buffer_get_string_ret ssh_buffer_get_string_ret -#define buffer_put_bignum ssh_buffer_put_bignum -#define buffer_put_bignum2 ssh_buffer_put_bignum2 -#define buffer_put_bignum2_from_string ssh_buffer_put_bignum2_from_string -#define buffer_put_bignum2_ret ssh_buffer_put_bignum2_ret -#define buffer_put_bignum_ret ssh_buffer_put_bignum_ret -#define buffer_put_char ssh_buffer_put_char -#define buffer_put_cstring ssh_buffer_put_cstring -#define buffer_put_ecpoint ssh_buffer_put_ecpoint -#define buffer_put_ecpoint_ret ssh_buffer_put_ecpoint_ret -#define buffer_put_int ssh_buffer_put_int -#define buffer_put_int64 ssh_buffer_put_int64 -#define buffer_put_short ssh_buffer_put_short -#define buffer_put_string ssh_buffer_put_string -#define buffer_uncompress ssh_buffer_uncompress -#define cert_free ssh_cert_free -#define cert_new ssh_cert_new -#define chacha_encrypt_bytes ssh_chacha_encrypt_bytes -#define chacha_ivsetup ssh_chacha_ivsetup -#define chacha_keysetup ssh_chacha_keysetup -#define chachapoly_crypt ssh_chachapoly_crypt -#define chachapoly_get_length ssh_chachapoly_get_length -#define chachapoly_init ssh_chachapoly_init -#define chan_ibuf_empty ssh_chan_ibuf_empty -#define chan_is_dead ssh_chan_is_dead -#define chan_mark_dead ssh_chan_mark_dead -#define chan_obuf_empty ssh_chan_obuf_empty -#define chan_rcvd_eow ssh_chan_rcvd_eow -#define chan_rcvd_ieof ssh_chan_rcvd_ieof -#define chan_rcvd_oclose ssh_chan_rcvd_oclose -#define chan_read_failed ssh_chan_read_failed -#define chan_send_eof2 ssh_chan_send_eof2 -#define chan_send_oclose1 ssh_chan_send_oclose1 -#define chan_shutdown_read ssh_chan_shutdown_read -#define chan_shutdown_write ssh_chan_shutdown_write -#define chan_write_failed ssh_chan_write_failed -#define channel_add_adm_permitted_opens ssh_channel_add_adm_permitted_opens -#define channel_add_permitted_opens ssh_channel_add_permitted_opens -#define channel_after_select ssh_channel_after_select -#define channel_by_id ssh_channel_by_id -#define channel_cancel_cleanup ssh_channel_cancel_cleanup -#define channel_cancel_lport_listener ssh_channel_cancel_lport_listener -#define channel_cancel_rport_listener ssh_channel_cancel_rport_listener -#define channel_clear_adm_permitted_opens ssh_channel_clear_adm_permitted_opens -#define channel_clear_permitted_opens ssh_channel_clear_permitted_opens -#define channel_close_all ssh_channel_close_all -#define channel_close_fd ssh_channel_close_fd -#define channel_close_fds ssh_channel_close_fds -#define channel_connect_by_listen_address ssh_channel_connect_by_listen_address -#define channel_connect_by_listen_path ssh_channel_connect_by_listen_path -#define channel_connect_stdio_fwd ssh_channel_connect_stdio_fwd -#define channel_connect_to_path ssh_channel_connect_to_path -#define channel_connect_to_port ssh_channel_connect_to_port -#define channel_disable_adm_local_opens ssh_channel_disable_adm_local_opens -#define channel_find_open ssh_channel_find_open -#define channel_free ssh_channel_free -#define channel_free_all ssh_channel_free_all -#define channel_fwd_bind_addr ssh_channel_fwd_bind_addr -#define channel_handler ssh_channel_handler -#define channel_input_close ssh_channel_input_close -#define channel_input_close_confirmation ssh_channel_input_close_confirmation -#define channel_input_data ssh_channel_input_data -#define channel_input_extended_data ssh_channel_input_extended_data -#define channel_input_ieof ssh_channel_input_ieof -#define channel_input_oclose ssh_channel_input_oclose -#define channel_input_open_confirmation ssh_channel_input_open_confirmation -#define channel_input_open_failure ssh_channel_input_open_failure -#define channel_input_port_forward_request ssh_channel_input_port_forward_request -#define channel_input_port_open ssh_channel_input_port_open -#define channel_input_status_confirm ssh_channel_input_status_confirm -#define channel_input_window_adjust ssh_channel_input_window_adjust -#define channel_lookup ssh_channel_lookup -#define channel_new ssh_channel_new -#define channel_not_very_much_buffered_data ssh_channel_not_very_much_buffered_data -#define channel_open_message ssh_channel_open_message -#define channel_output_poll ssh_channel_output_poll -#define channel_permit_all_opens ssh_channel_permit_all_opens -#define channel_post_auth_listener ssh_channel_post_auth_listener -#define channel_post_connecting ssh_channel_post_connecting -#define channel_post_mux_client ssh_channel_post_mux_client -#define channel_post_mux_listener ssh_channel_post_mux_listener -#define channel_post_open ssh_channel_post_open -#define channel_post_output_drain_13 ssh_channel_post_output_drain_13 -#define channel_post_port_listener ssh_channel_post_port_listener -#define channel_post_x11_listener ssh_channel_post_x11_listener -#define channel_pre_connecting ssh_channel_pre_connecting -#define channel_pre_dynamic ssh_channel_pre_dynamic -#define channel_pre_input_draining ssh_channel_pre_input_draining -#define channel_pre_listener ssh_channel_pre_listener -#define channel_pre_mux_client ssh_channel_pre_mux_client -#define channel_pre_open ssh_channel_pre_open -#define channel_pre_open_13 ssh_channel_pre_open_13 -#define channel_pre_output_draining ssh_channel_pre_output_draining -#define channel_pre_x11_open ssh_channel_pre_x11_open -#define channel_pre_x11_open_13 ssh_channel_pre_x11_open_13 -#define channel_prepare_select ssh_channel_prepare_select -#define channel_print_adm_permitted_opens ssh_channel_print_adm_permitted_opens -#define channel_register_cleanup ssh_channel_register_cleanup -#define channel_register_fds ssh_channel_register_fds -#define channel_register_filter ssh_channel_register_filter -#define channel_register_open_confirm ssh_channel_register_open_confirm -#define channel_register_status_confirm ssh_channel_register_status_confirm -#define channel_request_remote_forwarding ssh_channel_request_remote_forwarding -#define channel_request_rforward_cancel ssh_channel_request_rforward_cancel -#define channel_request_start ssh_channel_request_start -#define channel_send_open ssh_channel_send_open -#define channel_send_window_changes ssh_channel_send_window_changes -#define channel_set_af ssh_channel_set_af -#define channel_set_fds ssh_channel_set_fds -#define channel_setup_fwd_listener_streamlocal ssh_channel_setup_fwd_listener_streamlocal -#define channel_setup_fwd_listener_tcpip ssh_channel_setup_fwd_listener_tcpip -#define channel_setup_local_fwd_listener ssh_channel_setup_local_fwd_listener -#define channel_setup_remote_fwd_listener ssh_channel_setup_remote_fwd_listener -#define channel_still_open ssh_channel_still_open -#define channel_stop_listening ssh_channel_stop_listening -#define channel_update_permitted_opens ssh_channel_update_permitted_opens -#define check_crc ssh_check_crc -#define check_hostkeys_by_key_or_type ssh_check_hostkeys_by_key_or_type -#define check_key_in_hostkeys ssh_check_key_in_hostkeys -#define choose_dh ssh_choose_dh -#define choose_t ssh_choose_t -#define chop ssh_chop -#define cipher_alg_list ssh_cipher_alg_list -#define cipher_authlen ssh_cipher_authlen -#define cipher_blocksize ssh_cipher_blocksize -#define cipher_by_name ssh_cipher_by_name -#define cipher_by_number ssh_cipher_by_number -#define cipher_cleanup ssh_cipher_cleanup -#define cipher_crypt ssh_cipher_crypt -#define cipher_get_keycontext ssh_cipher_get_keycontext -#define cipher_get_keyiv ssh_cipher_get_keyiv -#define cipher_get_keyiv_len ssh_cipher_get_keyiv_len -#define cipher_get_length ssh_cipher_get_length -#define cipher_get_number ssh_cipher_get_number -#define cipher_init ssh_cipher_init -#define cipher_is_cbc ssh_cipher_is_cbc -#define cipher_ivlen ssh_cipher_ivlen -#define cipher_keylen ssh_cipher_keylen -#define cipher_mask_ssh1 ssh_cipher_mask_ssh1 -#define cipher_name ssh_cipher_name -#define cipher_number ssh_cipher_number -#define cipher_seclen ssh_cipher_seclen -#define cipher_set_key_string ssh_cipher_set_key_string -#define cipher_set_keycontext ssh_cipher_set_keycontext -#define cipher_set_keyiv ssh_cipher_set_keyiv -#define cipher_warning_message ssh_cipher_warning_message -#define ciphers_valid ssh_ciphers_valid -#define cleanhostname ssh_cleanhostname -#define cleanup_exit ssh_cleanup_exit -#define clear_cached_addr ssh_clear_cached_addr -#define colon ssh_colon -#define compare ssh_compare -#define compare_gps ssh_compare_gps -#define compat_cipher_proposal ssh_compat_cipher_proposal -#define compat_datafellows ssh_compat_datafellows -#define compat_kex_proposal ssh_compat_kex_proposal -#define compat_pkalg_proposal ssh_compat_pkalg_proposal -#define connect_next ssh_connect_next -#define connect_to ssh_connect_to -#define convtime ssh_convtime -#define crypto_hash_sha512 ssh_crypto_hash_sha512 -#define crypto_hashblocks_sha512 ssh_crypto_hashblocks_sha512 -#define crypto_scalarmult_curve25519 ssh_crypto_scalarmult_curve25519 -#define crypto_sign_ed25519 ssh_crypto_sign_ed25519 -#define crypto_sign_ed25519_keypair ssh_crypto_sign_ed25519_keypair -#define crypto_sign_ed25519_open ssh_crypto_sign_ed25519_open -#define crypto_sign_ed25519_ref_double_scalarmult_vartime ssh_crypto_sign_ed25519_ref_double_scalarmult_vartime -#define crypto_sign_ed25519_ref_fe25519_add ssh_crypto_sign_ed25519_ref_fe25519_add -#define crypto_sign_ed25519_ref_fe25519_cmov ssh_crypto_sign_ed25519_ref_fe25519_cmov -#define crypto_sign_ed25519_ref_fe25519_freeze ssh_crypto_sign_ed25519_ref_fe25519_freeze -#define crypto_sign_ed25519_ref_fe25519_getparity ssh_crypto_sign_ed25519_ref_fe25519_getparity -#define crypto_sign_ed25519_ref_fe25519_invert ssh_crypto_sign_ed25519_ref_fe25519_invert -#define crypto_sign_ed25519_ref_fe25519_iseq_vartime ssh_crypto_sign_ed25519_ref_fe25519_iseq_vartime -#define crypto_sign_ed25519_ref_fe25519_iszero ssh_crypto_sign_ed25519_ref_fe25519_iszero -#define crypto_sign_ed25519_ref_fe25519_mul ssh_crypto_sign_ed25519_ref_fe25519_mul -#define crypto_sign_ed25519_ref_fe25519_neg ssh_crypto_sign_ed25519_ref_fe25519_neg -#define crypto_sign_ed25519_ref_fe25519_pack ssh_crypto_sign_ed25519_ref_fe25519_pack -#define crypto_sign_ed25519_ref_fe25519_pow2523 ssh_crypto_sign_ed25519_ref_fe25519_pow2523 -#define crypto_sign_ed25519_ref_fe25519_setone ssh_crypto_sign_ed25519_ref_fe25519_setone -#define crypto_sign_ed25519_ref_fe25519_setzero ssh_crypto_sign_ed25519_ref_fe25519_setzero -#define crypto_sign_ed25519_ref_fe25519_square ssh_crypto_sign_ed25519_ref_fe25519_square -#define crypto_sign_ed25519_ref_fe25519_sub ssh_crypto_sign_ed25519_ref_fe25519_sub -#define crypto_sign_ed25519_ref_fe25519_unpack ssh_crypto_sign_ed25519_ref_fe25519_unpack -#define crypto_sign_ed25519_ref_isneutral_vartime ssh_crypto_sign_ed25519_ref_isneutral_vartime -#define crypto_sign_ed25519_ref_pack ssh_crypto_sign_ed25519_ref_pack -#define crypto_sign_ed25519_ref_sc25519_2interleave2 ssh_crypto_sign_ed25519_ref_sc25519_2interleave2 -#define crypto_sign_ed25519_ref_sc25519_add ssh_crypto_sign_ed25519_ref_sc25519_add -#define crypto_sign_ed25519_ref_sc25519_from32bytes ssh_crypto_sign_ed25519_ref_sc25519_from32bytes -#define crypto_sign_ed25519_ref_sc25519_from64bytes ssh_crypto_sign_ed25519_ref_sc25519_from64bytes -#define crypto_sign_ed25519_ref_sc25519_from_shortsc ssh_crypto_sign_ed25519_ref_sc25519_from_shortsc -#define crypto_sign_ed25519_ref_sc25519_isshort_vartime ssh_crypto_sign_ed25519_ref_sc25519_isshort_vartime -#define crypto_sign_ed25519_ref_sc25519_iszero_vartime ssh_crypto_sign_ed25519_ref_sc25519_iszero_vartime -#define crypto_sign_ed25519_ref_sc25519_lt_vartime ssh_crypto_sign_ed25519_ref_sc25519_lt_vartime -#define crypto_sign_ed25519_ref_sc25519_mul ssh_crypto_sign_ed25519_ref_sc25519_mul -#define crypto_sign_ed25519_ref_sc25519_mul_shortsc ssh_crypto_sign_ed25519_ref_sc25519_mul_shortsc -#define crypto_sign_ed25519_ref_sc25519_sub_nored ssh_crypto_sign_ed25519_ref_sc25519_sub_nored -#define crypto_sign_ed25519_ref_sc25519_to32bytes ssh_crypto_sign_ed25519_ref_sc25519_to32bytes -#define crypto_sign_ed25519_ref_sc25519_window3 ssh_crypto_sign_ed25519_ref_sc25519_window3 -#define crypto_sign_ed25519_ref_sc25519_window5 ssh_crypto_sign_ed25519_ref_sc25519_window5 -#define crypto_sign_ed25519_ref_scalarmult_base ssh_crypto_sign_ed25519_ref_scalarmult_base -#define crypto_sign_ed25519_ref_shortsc25519_from16bytes ssh_crypto_sign_ed25519_ref_shortsc25519_from16bytes -#define crypto_sign_ed25519_ref_unpackneg_vartime ssh_crypto_sign_ed25519_ref_unpackneg_vartime -#define crypto_verify_32 ssh_crypto_verify_32 -#define dbl_p1p1 ssh_dbl_p1p1 -#define debug ssh_debug -#define debug2 ssh_debug2 -#define debug3 ssh_debug3 -#define decode_reply ssh_decode_reply -#define deny_input_open ssh_deny_input_open -#define derive_ssh1_session_id ssh_derive_ssh1_session_id -#define detect_attack ssh_detect_attack -#define dh_estimate ssh_dh_estimate -#define dh_gen_key ssh_dh_gen_key -#define dh_new_group ssh_dh_new_group -#define dh_new_group1 ssh_dh_new_group1 -#define dh_new_group14 ssh_dh_new_group14 -#define dh_new_group_asc ssh_dh_new_group_asc -#define dh_pub_is_valid ssh_dh_pub_is_valid -#define dispatch_init ssh_dispatch_init -#define dispatch_protocol_error ssh_dispatch_protocol_error -#define dispatch_protocol_ignore ssh_dispatch_protocol_ignore -#define dispatch_range ssh_dispatch_range -#define dispatch_run ssh_dispatch_run -#define dispatch_set ssh_dispatch_set -#define do_log ssh_do_log -#define do_log2 ssh_do_log2 -#define dump_base64 ssh_dump_base64 -#define enable_compat13 ssh_enable_compat13 -#define enable_compat20 ssh_enable_compat20 -#define error ssh_error -#define evp_ssh1_3des ssh_evp_ssh1_3des -#define evp_ssh1_bf ssh_evp_ssh1_bf -#define export_dns_rr ssh_export_dns_rr -#define fatal ssh_fatal -#define filter_proposal ssh_filter_proposal -#define fmt_scaled ssh_fmt_scaled -#define free_hostkeys ssh_free_hostkeys -#define freeargs ssh_freeargs -#define freerrset ssh_freerrset -#define gen_candidates ssh_gen_candidates -#define get_canonical_hostname ssh_get_canonical_hostname -#define get_local_ipaddr ssh_get_local_ipaddr -#define get_local_name ssh_get_local_name -#define get_local_port ssh_get_local_port -#define get_peer_ipaddr ssh_get_peer_ipaddr -#define get_peer_port ssh_get_peer_port -#define get_remote_ipaddr ssh_get_remote_ipaddr -#define get_remote_name_or_ip ssh_get_remote_name_or_ip -#define get_remote_port ssh_get_remote_port -#define get_sock_port ssh_get_sock_port -#define get_socket_address ssh_get_socket_address -#define get_u16 ssh_get_u16 -#define get_u32 ssh_get_u32 -#define get_u32_le ssh_get_u32_le -#define get_u64 ssh_get_u64 -#define getrrsetbyname ssh_getrrsetbyname -#define glob ssh_glob -#define glob0 ssh_glob0 -#define glob2 ssh_glob2 -#define globexp1 ssh_globexp1 -#define globextend ssh_globextend -#define globfree ssh_globfree -#define host_hash ssh_host_hash -#define hostfile_read_key ssh_hostfile_read_key -#define hpdelim ssh_hpdelim -#define init_hostkeys ssh_init_hostkeys -#define iptos2str ssh_iptos2str -#define ipv64_normalise_mapped ssh_ipv64_normalise_mapped -#define is_key_revoked ssh_is_key_revoked -#define kex_alg_by_name ssh_kex_alg_by_name -#define kex_alg_list ssh_kex_alg_list -#define kex_buf2prop ssh_kex_buf2prop -#define kex_c25519_hash ssh_kex_c25519_hash -#define kex_derive_keys ssh_kex_derive_keys -#define kex_derive_keys_bn ssh_kex_derive_keys_bn -#define kex_dh_hash ssh_kex_dh_hash -#define kex_ecdh_hash ssh_kex_ecdh_hash -#define kex_finish ssh_kex_finish -#define kex_get_newkeys ssh_kex_get_newkeys -#define kex_input_kexinit ssh_kex_input_kexinit -#define kex_names_valid ssh_kex_names_valid -#define kex_prop_free ssh_kex_prop_free -#define kex_protocol_error ssh_kex_protocol_error -#define kex_send_kexinit ssh_kex_send_kexinit -#define kex_setup ssh_kex_setup -#define kexc25519_client ssh_kexc25519_client -#define kexc25519_keygen ssh_kexc25519_keygen -#define kexc25519_shared_key ssh_kexc25519_shared_key -#define kexdh_client ssh_kexdh_client -#define kexecdh_client ssh_kexecdh_client -#define kexgex_client ssh_kexgex_client -#define kexgex_hash ssh_kexgex_hash -#define key_add_private ssh_key_add_private -#define key_alg_list ssh_key_alg_list -#define key_cert_check_authority ssh_key_cert_check_authority -#define key_cert_copy ssh_key_cert_copy -#define key_certify ssh_key_certify -#define key_demote ssh_key_demote -#define key_drop_cert ssh_key_drop_cert -#define key_ec_validate_private ssh_key_ec_validate_private -#define key_ec_validate_public ssh_key_ec_validate_public -#define key_fingerprint_raw ssh_key_fingerprint_raw -#define key_from_blob ssh_key_from_blob -#define key_from_private ssh_key_from_private -#define key_generate ssh_key_generate -#define key_in_file ssh_key_in_file -#define key_load_cert ssh_key_load_cert -#define key_load_file ssh_key_load_file -#define key_load_private ssh_key_load_private -#define key_load_private_cert ssh_key_load_private_cert -#define key_load_private_pem ssh_key_load_private_pem -#define key_load_private_type ssh_key_load_private_type -#define key_load_public ssh_key_load_public -#define key_new_private ssh_key_new_private -#define key_perm_ok ssh_key_perm_ok -#define key_private_deserialize ssh_key_private_deserialize -#define key_private_serialize ssh_key_private_serialize -#define key_read ssh_key_read -#define key_save_private ssh_key_save_private -#define key_sign ssh_key_sign -#define key_to_blob ssh_key_to_blob -#define key_to_certified ssh_key_to_certified -#define key_verify ssh_key_verify -#define key_write ssh_key_write -#define load_hostkeys ssh_load_hostkeys -#define log_change_level ssh_log_change_level -#define log_facility_name ssh_log_facility_name -#define log_facility_number ssh_log_facility_number -#define log_init ssh_log_init -#define log_is_on_stderr ssh_log_is_on_stderr -#define log_level_name ssh_log_level_name -#define log_level_number ssh_log_level_number -#define log_redirect_stderr_to ssh_log_redirect_stderr_to -#define logit ssh_logit -#define lookup_key_in_hostkeys_by_type ssh_lookup_key_in_hostkeys_by_type -#define lowercase ssh_lowercase -#define mac_alg_list ssh_mac_alg_list -#define mac_clear ssh_mac_clear -#define mac_compute ssh_mac_compute -#define mac_init ssh_mac_init -#define mac_setup ssh_mac_setup -#define mac_valid ssh_mac_valid -#define match ssh_match -#define match_host_and_ip ssh_match_host_and_ip -#define match_hostname ssh_match_hostname -#define match_list ssh_match_list -#define match_pattern ssh_match_pattern -#define match_pattern_list ssh_match_pattern_list -#define match_user ssh_match_user -#define mktemp_proto ssh_mktemp_proto -#define mm_receive_fd ssh_mm_receive_fd -#define mm_send_fd ssh_mm_send_fd -#define monotime ssh_monotime -#define ms_subtract_diff ssh_ms_subtract_diff -#define ms_to_timeval ssh_ms_to_timeval -#define mult ssh_mult -#define mysignal ssh_mysignal -#define nh_aux ssh_nh_aux -#define nh_final ssh_nh_final -#define packet_add_padding ssh_packet_add_padding -#define packet_backup_state ssh_packet_backup_state -#define packet_close ssh_packet_close -#define packet_connection_is_on_socket ssh_packet_connection_is_on_socket -#define packet_disconnect ssh_packet_disconnect -#define packet_enable_delayed_compress ssh_packet_enable_delayed_compress -#define packet_get_bignum ssh_packet_get_bignum -#define packet_get_bignum2 ssh_packet_get_bignum2 -#define packet_get_char ssh_packet_get_char -#define packet_get_connection_in ssh_packet_get_connection_in -#define packet_get_connection_out ssh_packet_get_connection_out -#define packet_get_cstring ssh_packet_get_cstring -#define packet_get_ecpoint ssh_packet_get_ecpoint -#define packet_get_encryption_key ssh_packet_get_encryption_key -#define packet_get_input ssh_packet_get_input -#define packet_get_int ssh_packet_get_int -#define packet_get_int64 ssh_packet_get_int64 -#define packet_get_keycontext ssh_packet_get_keycontext -#define packet_get_keyiv ssh_packet_get_keyiv -#define packet_get_keyiv_len ssh_packet_get_keyiv_len -#define packet_get_maxsize ssh_packet_get_maxsize -#define packet_get_newkeys ssh_packet_get_newkeys -#define packet_get_output ssh_packet_get_output -#define packet_get_protocol_flags ssh_packet_get_protocol_flags -#define packet_get_raw ssh_packet_get_raw -#define packet_get_rekey_timeout ssh_packet_get_rekey_timeout -#define packet_get_ssh1_cipher ssh_packet_get_ssh1_cipher -#define packet_get_state ssh_packet_get_state -#define packet_get_string ssh_packet_get_string -#define packet_get_string_ptr ssh_packet_get_string_ptr -#define packet_have_data_to_write ssh_packet_have_data_to_write -#define packet_inc_alive_timeouts ssh_packet_inc_alive_timeouts -#define packet_init_compression ssh_packet_init_compression -#define packet_is_interactive ssh_packet_is_interactive -#define packet_need_rekeying ssh_packet_need_rekeying -#define packet_not_very_much_data_to_write ssh_packet_not_very_much_data_to_write -#define packet_process_incoming ssh_packet_process_incoming -#define packet_put_bignum ssh_packet_put_bignum -#define packet_put_bignum2 ssh_packet_put_bignum2 -#define packet_put_char ssh_packet_put_char -#define packet_put_cstring ssh_packet_put_cstring -#define packet_put_ecpoint ssh_packet_put_ecpoint -#define packet_put_int ssh_packet_put_int -#define packet_put_int64 ssh_packet_put_int64 -#define packet_put_raw ssh_packet_put_raw -#define packet_put_string ssh_packet_put_string -#define packet_read ssh_packet_read -#define packet_read_expect ssh_packet_read_expect -#define packet_read_poll_seqnr ssh_packet_read_poll_seqnr -#define packet_read_seqnr ssh_packet_read_seqnr -#define packet_remaining ssh_packet_remaining -#define packet_restore_state ssh_packet_restore_state -#define packet_send ssh_packet_send -#define packet_send2_wrapped ssh_packet_send2_wrapped -#define packet_send_debug ssh_packet_send_debug -#define packet_send_ignore ssh_packet_send_ignore -#define packet_set_alive_timeouts ssh_packet_set_alive_timeouts -#define packet_set_authenticated ssh_packet_set_authenticated -#define packet_set_connection ssh_packet_set_connection -#define packet_set_encryption_key ssh_packet_set_encryption_key -#define packet_set_interactive ssh_packet_set_interactive -#define packet_set_iv ssh_packet_set_iv -#define packet_set_keycontext ssh_packet_set_keycontext -#define packet_set_maxsize ssh_packet_set_maxsize -#define packet_set_nonblocking ssh_packet_set_nonblocking -#define packet_set_postauth ssh_packet_set_postauth -#define packet_set_protocol_flags ssh_packet_set_protocol_flags -#define packet_set_rekey_limits ssh_packet_set_rekey_limits -#define packet_set_server ssh_packet_set_server -#define packet_set_state ssh_packet_set_state -#define packet_set_timeout ssh_packet_set_timeout -#define packet_start ssh_packet_start -#define packet_start_compression ssh_packet_start_compression -#define packet_start_discard ssh_packet_start_discard -#define packet_stop_discard ssh_packet_stop_discard -#define packet_write_poll ssh_packet_write_poll -#define packet_write_wait ssh_packet_write_wait -#define parse_ipqos ssh_parse_ipqos -#define parse_prime ssh_parse_prime -#define percent_expand ssh_percent_expand -#define permanently_drop_suid ssh_permanently_drop_suid -#define permanently_set_uid ssh_permanently_set_uid -#define permitopen_port ssh_permitopen_port -#define pkcs11_add_provider ssh_pkcs11_add_provider -#define pkcs11_del_provider ssh_pkcs11_del_provider -#define pkcs11_fetch_keys_filter ssh_pkcs11_fetch_keys_filter -#define pkcs11_find ssh_pkcs11_find -#define pkcs11_init ssh_pkcs11_init -#define pkcs11_provider_finalize ssh_pkcs11_provider_finalize -#define pkcs11_provider_unref ssh_pkcs11_provider_unref -#define pkcs11_rsa_finish ssh_pkcs11_rsa_finish -#define pkcs11_rsa_private_decrypt ssh_pkcs11_rsa_private_decrypt -#define pkcs11_rsa_private_encrypt ssh_pkcs11_rsa_private_encrypt -#define pkcs11_terminate ssh_pkcs11_terminate -#define plain_key_blob ssh_plain_key_blob -#define poly1305_auth ssh_poly1305_auth -#define poly64 ssh_poly64 -#define poly_hash ssh_poly_hash -#define port_open_helper ssh_port_open_helper -#define prime_test ssh_prime_test -#define proto_spec ssh_proto_spec -#define put_host_port ssh_put_host_port -#define put_u16 ssh_put_u16 -#define put_u32 ssh_put_u32 -#define put_u32_le ssh_put_u32_le -#define put_u64 ssh_put_u64 -#define pwcopy ssh_pwcopy -#define qfileout ssh_qfileout -#define read_keyfile_line ssh_read_keyfile_line -#define read_mux ssh_read_mux -#define read_passphrase ssh_read_passphrase -#define reduce_add_sub ssh_reduce_add_sub -#define refresh_progress_meter ssh_refresh_progress_meter -#define replacearg ssh_replacearg -#define restore_uid ssh_restore_uid -#define revoke_blob ssh_revoke_blob -#define revoked_blob_tree_RB_REMOVE ssh_revoked_blob_tree_RB_REMOVE -#define revoked_certs_for_ca_key ssh_revoked_certs_for_ca_key -#define revoked_serial_tree_RB_REMOVE ssh_revoked_serial_tree_RB_REMOVE -#define rijndaelEncrypt ssh_rijndaelEncrypt -#define rijndaelKeySetupDec ssh_rijndaelKeySetupDec -#define rijndaelKeySetupEnc ssh_rijndaelKeySetupEnc -#define rijndael_decrypt ssh_rijndael_decrypt -#define rijndael_encrypt ssh_rijndael_encrypt -#define rijndael_set_key ssh_rijndael_set_key -#define rsa_generate_additional_parameters ssh_rsa_generate_additional_parameters -#define rsa_private_decrypt ssh_rsa_private_decrypt -#define rsa_public_encrypt ssh_rsa_public_encrypt -#define sanitise_stdfd ssh_sanitise_stdfd -#define scan_scaled ssh_scan_scaled -#define seed_rng ssh_seed_rng -#define set_log_handler ssh_set_log_handler -#define set_newkeys ssh_set_newkeys -#define set_nodelay ssh_set_nodelay -#define set_nonblock ssh_set_nonblock -#define shadow_pw ssh_shadow_pw -#define sieve_large ssh_sieve_large -#define sig_winch ssh_sig_winch -#define sigdie ssh_sigdie -#define sock_set_v6only ssh_sock_set_v6only -#define square ssh_square -#define ssh1_3des_cbc ssh_ssh1_3des_cbc -#define ssh1_3des_cleanup ssh_ssh1_3des_cleanup -#define ssh1_3des_init ssh_ssh1_3des_init -#define ssh1_3des_iv ssh_ssh1_3des_iv -#define sshbuf_alloc ssh_sshbuf_alloc -#define sshbuf_avail ssh_sshbuf_avail -#define sshbuf_b64tod ssh_sshbuf_b64tod -#define sshbuf_check_reserve ssh_sshbuf_check_reserve -#define sshbuf_consume ssh_sshbuf_consume -#define sshbuf_consume_end ssh_sshbuf_consume_end -#define sshbuf_dtob16 ssh_sshbuf_dtob16 -#define sshbuf_dtob64 ssh_sshbuf_dtob64 -#define sshbuf_dump ssh_sshbuf_dump -#define sshbuf_dump_data ssh_sshbuf_dump_data -#define sshbuf_free ssh_sshbuf_free -#define sshbuf_from ssh_sshbuf_from -#define sshbuf_fromb ssh_sshbuf_fromb -#define sshbuf_froms ssh_sshbuf_froms -#define sshbuf_get ssh_sshbuf_get -#define sshbuf_get_bignum1 ssh_sshbuf_get_bignum1 -#define sshbuf_get_bignum2 ssh_sshbuf_get_bignum2 -#define sshbuf_get_cstring ssh_sshbuf_get_cstring -#define sshbuf_get_ec ssh_sshbuf_get_ec -#define sshbuf_get_eckey ssh_sshbuf_get_eckey -#define sshbuf_get_string ssh_sshbuf_get_string -#define sshbuf_get_string_direct ssh_sshbuf_get_string_direct -#define sshbuf_get_stringb ssh_sshbuf_get_stringb -#define sshbuf_get_u16 ssh_sshbuf_get_u16 -#define sshbuf_get_u32 ssh_sshbuf_get_u32 -#define sshbuf_get_u64 ssh_sshbuf_get_u64 -#define sshbuf_get_u8 ssh_sshbuf_get_u8 -#define sshbuf_init ssh_sshbuf_init -#define sshbuf_len ssh_sshbuf_len -#define sshbuf_max_size ssh_sshbuf_max_size -#define sshbuf_mutable_ptr ssh_sshbuf_mutable_ptr -#define sshbuf_new ssh_sshbuf_new -#define sshbuf_parent ssh_sshbuf_parent -#define sshbuf_peek_string_direct ssh_sshbuf_peek_string_direct -#define sshbuf_ptr ssh_sshbuf_ptr -#define sshbuf_put ssh_sshbuf_put -#define sshbuf_put_bignum1 ssh_sshbuf_put_bignum1 -#define sshbuf_put_bignum2 ssh_sshbuf_put_bignum2 -#define sshbuf_put_bignum2_bytes ssh_sshbuf_put_bignum2_bytes -#define sshbuf_put_cstring ssh_sshbuf_put_cstring -#define sshbuf_put_ec ssh_sshbuf_put_ec -#define sshbuf_put_eckey ssh_sshbuf_put_eckey -#define sshbuf_put_string ssh_sshbuf_put_string -#define sshbuf_put_stringb ssh_sshbuf_put_stringb -#define sshbuf_put_u16 ssh_sshbuf_put_u16 -#define sshbuf_put_u32 ssh_sshbuf_put_u32 -#define sshbuf_put_u64 ssh_sshbuf_put_u64 -#define sshbuf_put_u8 ssh_sshbuf_put_u8 -#define sshbuf_putb ssh_sshbuf_putb -#define sshbuf_putf ssh_sshbuf_putf -#define sshbuf_putfv ssh_sshbuf_putfv -#define sshbuf_refcount ssh_sshbuf_refcount -#define sshbuf_reserve ssh_sshbuf_reserve -#define sshbuf_reset ssh_sshbuf_reset -#define sshbuf_set_max_size ssh_sshbuf_set_max_size -#define sshbuf_set_parent ssh_sshbuf_set_parent -#define sshkey_add_private ssh_sshkey_add_private -#define sshkey_cert_check_authority ssh_sshkey_cert_check_authority -#define sshkey_cert_copy ssh_sshkey_cert_copy -#define sshkey_cert_is_legacy ssh_sshkey_cert_is_legacy -#define sshkey_cert_type ssh_sshkey_cert_type -#define sshkey_certify ssh_sshkey_certify -#define sshkey_curve_name_to_nid ssh_sshkey_curve_name_to_nid -#define sshkey_curve_nid_to_bits ssh_sshkey_curve_nid_to_bits -#define sshkey_curve_nid_to_name ssh_sshkey_curve_nid_to_name -#define sshkey_demote ssh_sshkey_demote -#define sshkey_drop_cert ssh_sshkey_drop_cert -#define sshkey_dump_ec_key ssh_sshkey_dump_ec_key -#define sshkey_dump_ec_point ssh_sshkey_dump_ec_point -#define sshkey_ec_nid_to_hash_alg ssh_sshkey_ec_nid_to_hash_alg -#define sshkey_ec_validate_private ssh_sshkey_ec_validate_private -#define sshkey_ec_validate_public ssh_sshkey_ec_validate_public -#define sshkey_ecdsa_bits_to_nid ssh_sshkey_ecdsa_bits_to_nid -#define sshkey_ecdsa_key_to_nid ssh_sshkey_ecdsa_key_to_nid -#define sshkey_ecdsa_nid_from_name ssh_sshkey_ecdsa_nid_from_name -#define sshkey_equal ssh_sshkey_equal -#define sshkey_equal_public ssh_sshkey_equal_public -#define sshkey_fingerprint ssh_sshkey_fingerprint -#define sshkey_fingerprint_raw ssh_sshkey_fingerprint_raw -#define sshkey_free ssh_sshkey_free -#define sshkey_from_blob ssh_sshkey_from_blob -#define sshkey_from_blob_internal ssh_sshkey_from_blob_internal -#define sshkey_from_private ssh_sshkey_from_private -#define sshkey_generate ssh_sshkey_generate -#define sshkey_in_file ssh_sshkey_in_file -#define sshkey_is_cert ssh_sshkey_is_cert -#define sshkey_load_cert ssh_sshkey_load_cert -#define sshkey_load_file ssh_sshkey_load_file -#define sshkey_load_private ssh_sshkey_load_private -#define sshkey_load_private_cert ssh_sshkey_load_private_cert -#define sshkey_load_private_pem ssh_sshkey_load_private_pem -#define sshkey_load_private_type ssh_sshkey_load_private_type -#define sshkey_load_public ssh_sshkey_load_public -#define sshkey_names_valid2 ssh_sshkey_names_valid2 -#define sshkey_new ssh_sshkey_new -#define sshkey_new_private ssh_sshkey_new_private -#define sshkey_parse_private2 ssh_sshkey_parse_private2 -#define sshkey_parse_private_fileblob ssh_sshkey_parse_private_fileblob -#define sshkey_parse_private_fileblob_type ssh_sshkey_parse_private_fileblob_type -#define sshkey_parse_private_pem_fileblob ssh_sshkey_parse_private_pem_fileblob -#define sshkey_parse_public_rsa1_fileblob ssh_sshkey_parse_public_rsa1_fileblob -#define sshkey_perm_ok ssh_sshkey_perm_ok -#define sshkey_plain_to_blob ssh_sshkey_plain_to_blob -#define sshkey_plain_to_blob_buf ssh_sshkey_plain_to_blob_buf -#define sshkey_private_deserialize ssh_sshkey_private_deserialize -#define sshkey_private_serialize ssh_sshkey_private_serialize -#define sshkey_private_to_blob2 ssh_sshkey_private_to_blob2 -#define sshkey_private_to_fileblob ssh_sshkey_private_to_fileblob -#define sshkey_read ssh_sshkey_read -#define sshkey_save_private ssh_sshkey_save_private -#define sshkey_sign ssh_sshkey_sign -#define sshkey_size ssh_sshkey_size -#define sshkey_ssh_name ssh_sshkey_ssh_name -#define sshkey_ssh_name_plain ssh_sshkey_ssh_name_plain -#define sshkey_to_blob ssh_sshkey_to_blob -#define sshkey_to_blob_buf ssh_sshkey_to_blob_buf -#define sshkey_to_certified ssh_sshkey_to_certified -#define sshkey_try_load_public ssh_sshkey_try_load_public -#define sshkey_type ssh_sshkey_type -#define sshkey_type_from_name ssh_sshkey_type_from_name -#define sshkey_type_is_cert ssh_sshkey_type_is_cert -#define sshkey_type_plain ssh_sshkey_type_plain -#define sshkey_verify ssh_sshkey_verify -#define sshkey_write ssh_sshkey_write -#define start_progress_meter ssh_start_progress_meter -#define stop_progress_meter ssh_stop_progress_meter -#define strdelim ssh_strdelim -#define strnvis ssh_strnvis -#define strvis ssh_strvis -#define strvisx ssh_strvisx -#define sys_tun_open ssh_sys_tun_open -#define temporarily_use_uid ssh_temporarily_use_uid -#define tilde_expand_filename ssh_tilde_expand_filename -#define timingsafe_bcmp ssh_timingsafe_bcmp -#define to_blob ssh_to_blob -#define to_blob_buf ssh_to_blob_buf -#define tohex ssh_tohex -#define tty_make_modes ssh_tty_make_modes -#define tty_parse_modes ssh_tty_parse_modes -#define tun_open ssh_tun_open -#define umac128_delete ssh_umac128_delete -#define umac128_final ssh_umac128_final -#define umac128_new ssh_umac128_new -#define umac128_update ssh_umac128_update -#define umac_delete ssh_umac_delete -#define umac_final ssh_umac_final -#define umac_new ssh_umac_new -#define umac_update ssh_umac_update -#define unix_listener ssh_unix_listener -#define unset_nonblock ssh_unset_nonblock -#define update_progress_meter ssh_update_progress_meter -#define uudecode ssh_uudecode -#define uuencode ssh_uuencode -#define verbose ssh_verbose -#define verify_host_key_dns ssh_verify_host_key_dns -#define vis ssh_vis -#define x11_connect_display ssh_x11_connect_display -#define x11_create_display_inet ssh_x11_create_display_inet -#define x11_input_open ssh_x11_input_open -#define x11_open_helper ssh_x11_open_helper -#define x11_request_forwarding_with_spoofing ssh_x11_request_forwarding_with_spoofing -#define xasprintf ssh_xasprintf -#define xcalloc ssh_xcalloc -#define xcrypt ssh_xcrypt -#define xmalloc ssh_xmalloc -#define xmmap ssh_xmmap -#define xrealloc ssh_xrealloc -#define xstrdup ssh_xstrdup +#define Blowfish_decipher Fssh_Blowfish_decipher +#define Blowfish_encipher Fssh_Blowfish_encipher +#define Blowfish_expand0state Fssh_Blowfish_expand0state +#define Blowfish_expandstate Fssh_Blowfish_expandstate +#define Blowfish_initstate Fssh_Blowfish_initstate +#define Blowfish_stream2word Fssh_Blowfish_stream2word +#define _ssh_exchange_banner Fssh__ssh_exchange_banner +#define _ssh_host_key_sign Fssh__ssh_host_key_sign +#define _ssh_host_private_key Fssh__ssh_host_private_key +#define _ssh_host_public_key Fssh__ssh_host_public_key +#define _ssh_order_hostkeyalgs Fssh__ssh_order_hostkeyalgs +#define _ssh_read_banner Fssh__ssh_read_banner +#define _ssh_send_banner Fssh__ssh_send_banner +#define _ssh_verify_host_key Fssh__ssh_verify_host_key +#define a2port Fssh_a2port +#define a2tun Fssh_a2tun +#define add_host_to_hostfile Fssh_add_host_to_hostfile +#define add_p1p1 Fssh_add_p1p1 +#define addargs Fssh_addargs +#define addr_match_cidr_list Fssh_addr_match_cidr_list +#define addr_match_list Fssh_addr_match_list +#define addr_netmatch Fssh_addr_netmatch +#define addr_pton Fssh_addr_pton +#define addr_pton_cidr Fssh_addr_pton_cidr +#define ask_permission Fssh_ask_permission +#define atomicio Fssh_atomicio +#define atomicio6 Fssh_atomicio6 +#define atomiciov Fssh_atomiciov +#define atomiciov6 Fssh_atomiciov6 +#define auth_request_forwarding Fssh_auth_request_forwarding +#define bandwidth_limit Fssh_bandwidth_limit +#define bandwidth_limit_init Fssh_bandwidth_limit_init +#define barrett_reduce Fssh_barrett_reduce +#define bcrypt_hash Fssh_bcrypt_hash +#define bcrypt_pbkdf Fssh_bcrypt_pbkdf +#define bf_ssh1_cipher Fssh_bf_ssh1_cipher +#define bitmap_clear_bit Fssh_bitmap_clear_bit +#define bitmap_free Fssh_bitmap_free +#define bitmap_from_string Fssh_bitmap_from_string +#define bitmap_nbits Fssh_bitmap_nbits +#define bitmap_nbytes Fssh_bitmap_nbytes +#define bitmap_new Fssh_bitmap_new +#define bitmap_set_bit Fssh_bitmap_set_bit +#define bitmap_test_bit Fssh_bitmap_test_bit +#define bitmap_to_string Fssh_bitmap_to_string +#define bitmap_zero Fssh_bitmap_zero +#define blf_cbc_decrypt Fssh_blf_cbc_decrypt +#define blf_cbc_encrypt Fssh_blf_cbc_encrypt +#define blf_dec Fssh_blf_dec +#define blf_ecb_decrypt Fssh_blf_ecb_decrypt +#define blf_ecb_encrypt Fssh_blf_ecb_encrypt +#define blf_enc Fssh_blf_enc +#define blf_key Fssh_blf_key +#define buffer_append Fssh_buffer_append +#define buffer_append_space Fssh_buffer_append_space +#define buffer_check_alloc Fssh_buffer_check_alloc +#define buffer_consume Fssh_buffer_consume +#define buffer_consume_end Fssh_buffer_consume_end +#define buffer_consume_end_ret Fssh_buffer_consume_end_ret +#define buffer_consume_ret Fssh_buffer_consume_ret +#define buffer_get Fssh_buffer_get +#define buffer_get_bignum Fssh_buffer_get_bignum +#define buffer_get_bignum2 Fssh_buffer_get_bignum2 +#define buffer_get_bignum2_ret Fssh_buffer_get_bignum2_ret +#define buffer_get_bignum_ret Fssh_buffer_get_bignum_ret +#define buffer_get_char Fssh_buffer_get_char +#define buffer_get_char_ret Fssh_buffer_get_char_ret +#define buffer_get_cstring Fssh_buffer_get_cstring +#define buffer_get_cstring_ret Fssh_buffer_get_cstring_ret +#define buffer_get_ecpoint Fssh_buffer_get_ecpoint +#define buffer_get_ecpoint_ret Fssh_buffer_get_ecpoint_ret +#define buffer_get_int Fssh_buffer_get_int +#define buffer_get_int64 Fssh_buffer_get_int64 +#define buffer_get_int64_ret Fssh_buffer_get_int64_ret +#define buffer_get_int_ret Fssh_buffer_get_int_ret +#define buffer_get_ret Fssh_buffer_get_ret +#define buffer_get_short Fssh_buffer_get_short +#define buffer_get_short_ret Fssh_buffer_get_short_ret +#define buffer_get_string Fssh_buffer_get_string +#define buffer_get_string_ptr Fssh_buffer_get_string_ptr +#define buffer_get_string_ptr_ret Fssh_buffer_get_string_ptr_ret +#define buffer_get_string_ret Fssh_buffer_get_string_ret +#define buffer_put_bignum Fssh_buffer_put_bignum +#define buffer_put_bignum2 Fssh_buffer_put_bignum2 +#define buffer_put_bignum2_from_string Fssh_buffer_put_bignum2_from_string +#define buffer_put_bignum2_ret Fssh_buffer_put_bignum2_ret +#define buffer_put_bignum_ret Fssh_buffer_put_bignum_ret +#define buffer_put_char Fssh_buffer_put_char +#define buffer_put_cstring Fssh_buffer_put_cstring +#define buffer_put_ecpoint Fssh_buffer_put_ecpoint +#define buffer_put_ecpoint_ret Fssh_buffer_put_ecpoint_ret +#define buffer_put_int Fssh_buffer_put_int +#define buffer_put_int64 Fssh_buffer_put_int64 +#define buffer_put_short Fssh_buffer_put_short +#define buffer_put_string Fssh_buffer_put_string +#define cert_free Fssh_cert_free +#define cert_new Fssh_cert_new +#define chacha_encrypt_bytes Fssh_chacha_encrypt_bytes +#define chacha_ivsetup Fssh_chacha_ivsetup +#define chacha_keysetup Fssh_chacha_keysetup +#define chachapoly_crypt Fssh_chachapoly_crypt +#define chachapoly_get_length Fssh_chachapoly_get_length +#define chachapoly_init Fssh_chachapoly_init +#define chan_ibuf_empty Fssh_chan_ibuf_empty +#define chan_is_dead Fssh_chan_is_dead +#define chan_mark_dead Fssh_chan_mark_dead +#define chan_obuf_empty Fssh_chan_obuf_empty +#define chan_rcvd_eow Fssh_chan_rcvd_eow +#define chan_rcvd_ieof Fssh_chan_rcvd_ieof +#define chan_rcvd_oclose Fssh_chan_rcvd_oclose +#define chan_read_failed Fssh_chan_read_failed +#define chan_send_eof2 Fssh_chan_send_eof2 +#define chan_send_ieof1 Fssh_chan_send_ieof1 +#define chan_send_oclose1 Fssh_chan_send_oclose1 +#define chan_shutdown_read Fssh_chan_shutdown_read +#define chan_shutdown_write Fssh_chan_shutdown_write +#define chan_write_failed Fssh_chan_write_failed +#define channel_add_adm_permitted_opens Fssh_channel_add_adm_permitted_opens +#define channel_add_permitted_opens Fssh_channel_add_permitted_opens +#define channel_after_select Fssh_channel_after_select +#define channel_by_id Fssh_channel_by_id +#define channel_cancel_cleanup Fssh_channel_cancel_cleanup +#define channel_cancel_lport_listener Fssh_channel_cancel_lport_listener +#define channel_cancel_rport_listener Fssh_channel_cancel_rport_listener +#define channel_clear_adm_permitted_opens Fssh_channel_clear_adm_permitted_opens +#define channel_clear_permitted_opens Fssh_channel_clear_permitted_opens +#define channel_close_all Fssh_channel_close_all +#define channel_close_fd Fssh_channel_close_fd +#define channel_close_fds Fssh_channel_close_fds +#define channel_connect_by_listen_address Fssh_channel_connect_by_listen_address +#define channel_connect_by_listen_path Fssh_channel_connect_by_listen_path +#define channel_connect_stdio_fwd Fssh_channel_connect_stdio_fwd +#define channel_connect_to_path Fssh_channel_connect_to_path +#define channel_connect_to_port Fssh_channel_connect_to_port +#define channel_disable_adm_local_opens Fssh_channel_disable_adm_local_opens +#define channel_find_open Fssh_channel_find_open +#define channel_free Fssh_channel_free +#define channel_free_all Fssh_channel_free_all +#define channel_fwd_bind_addr Fssh_channel_fwd_bind_addr +#define channel_handler Fssh_channel_handler +#define channel_input_close Fssh_channel_input_close +#define channel_input_close_confirmation Fssh_channel_input_close_confirmation +#define channel_input_data Fssh_channel_input_data +#define channel_input_extended_data Fssh_channel_input_extended_data +#define channel_input_ieof Fssh_channel_input_ieof +#define channel_input_oclose Fssh_channel_input_oclose +#define channel_input_open_confirmation Fssh_channel_input_open_confirmation +#define channel_input_open_failure Fssh_channel_input_open_failure +#define channel_input_port_forward_request Fssh_channel_input_port_forward_request +#define channel_input_port_open Fssh_channel_input_port_open +#define channel_input_status_confirm Fssh_channel_input_status_confirm +#define channel_input_window_adjust Fssh_channel_input_window_adjust +#define channel_lookup Fssh_channel_lookup +#define channel_new Fssh_channel_new +#define channel_not_very_much_buffered_data Fssh_channel_not_very_much_buffered_data +#define channel_open_message Fssh_channel_open_message +#define channel_output_poll Fssh_channel_output_poll +#define channel_permit_all_opens Fssh_channel_permit_all_opens +#define channel_post_auth_listener Fssh_channel_post_auth_listener +#define channel_post_connecting Fssh_channel_post_connecting +#define channel_post_mux_client Fssh_channel_post_mux_client +#define channel_post_mux_listener Fssh_channel_post_mux_listener +#define channel_post_open Fssh_channel_post_open +#define channel_post_output_drain_13 Fssh_channel_post_output_drain_13 +#define channel_post_port_listener Fssh_channel_post_port_listener +#define channel_post_x11_listener Fssh_channel_post_x11_listener +#define channel_pre_connecting Fssh_channel_pre_connecting +#define channel_pre_dynamic Fssh_channel_pre_dynamic +#define channel_pre_input_draining Fssh_channel_pre_input_draining +#define channel_pre_listener Fssh_channel_pre_listener +#define channel_pre_mux_client Fssh_channel_pre_mux_client +#define channel_pre_open Fssh_channel_pre_open +#define channel_pre_open_13 Fssh_channel_pre_open_13 +#define channel_pre_output_draining Fssh_channel_pre_output_draining +#define channel_pre_x11_open Fssh_channel_pre_x11_open +#define channel_pre_x11_open_13 Fssh_channel_pre_x11_open_13 +#define channel_prepare_select Fssh_channel_prepare_select +#define channel_print_adm_permitted_opens Fssh_channel_print_adm_permitted_opens +#define channel_register_cleanup Fssh_channel_register_cleanup +#define channel_register_fds Fssh_channel_register_fds +#define channel_register_filter Fssh_channel_register_filter +#define channel_register_open_confirm Fssh_channel_register_open_confirm +#define channel_register_status_confirm Fssh_channel_register_status_confirm +#define channel_request_remote_forwarding Fssh_channel_request_remote_forwarding +#define channel_request_rforward_cancel Fssh_channel_request_rforward_cancel +#define channel_request_start Fssh_channel_request_start +#define channel_send_open Fssh_channel_send_open +#define channel_send_window_changes Fssh_channel_send_window_changes +#define channel_set_af Fssh_channel_set_af +#define channel_set_fds Fssh_channel_set_fds +#define channel_setup_fwd_listener_streamlocal Fssh_channel_setup_fwd_listener_streamlocal +#define channel_setup_fwd_listener_tcpip Fssh_channel_setup_fwd_listener_tcpip +#define channel_setup_local_fwd_listener Fssh_channel_setup_local_fwd_listener +#define channel_setup_remote_fwd_listener Fssh_channel_setup_remote_fwd_listener +#define channel_still_open Fssh_channel_still_open +#define channel_stop_listening Fssh_channel_stop_listening +#define channel_update_permitted_opens Fssh_channel_update_permitted_opens +#define check_crc Fssh_check_crc +#define check_hostkeys_by_key_or_type Fssh_check_hostkeys_by_key_or_type +#define check_key_in_hostkeys Fssh_check_key_in_hostkeys +#define choose_dh Fssh_choose_dh +#define choose_t Fssh_choose_t +#define chop Fssh_chop +#define cipher_alg_list Fssh_cipher_alg_list +#define cipher_authlen Fssh_cipher_authlen +#define cipher_blocksize Fssh_cipher_blocksize +#define cipher_by_name Fssh_cipher_by_name +#define cipher_by_number Fssh_cipher_by_number +#define cipher_cleanup Fssh_cipher_cleanup +#define cipher_crypt Fssh_cipher_crypt +#define cipher_get_keycontext Fssh_cipher_get_keycontext +#define cipher_get_keyiv Fssh_cipher_get_keyiv +#define cipher_get_keyiv_len Fssh_cipher_get_keyiv_len +#define cipher_get_length Fssh_cipher_get_length +#define cipher_get_number Fssh_cipher_get_number +#define cipher_init Fssh_cipher_init +#define cipher_is_cbc Fssh_cipher_is_cbc +#define cipher_ivlen Fssh_cipher_ivlen +#define cipher_keylen Fssh_cipher_keylen +#define cipher_mask_ssh1 Fssh_cipher_mask_ssh1 +#define cipher_name Fssh_cipher_name +#define cipher_number Fssh_cipher_number +#define cipher_seclen Fssh_cipher_seclen +#define cipher_set_key_string Fssh_cipher_set_key_string +#define cipher_set_keycontext Fssh_cipher_set_keycontext +#define cipher_set_keyiv Fssh_cipher_set_keyiv +#define cipher_warning_message Fssh_cipher_warning_message +#define ciphers_valid Fssh_ciphers_valid +#define cleanhostname Fssh_cleanhostname +#define cleanup_exit Fssh_cleanup_exit +#define clear_cached_addr Fssh_clear_cached_addr +#define colon Fssh_colon +#define compare Fssh_compare +#define compare_gps Fssh_compare_gps +#define compat_cipher_proposal Fssh_compat_cipher_proposal +#define compat_datafellows Fssh_compat_datafellows +#define compat_kex_proposal Fssh_compat_kex_proposal +#define compat_pkalg_proposal Fssh_compat_pkalg_proposal +#define compress_buffer Fssh_compress_buffer +#define connect_next Fssh_connect_next +#define connect_to Fssh_connect_to +#define convtime Fssh_convtime +#define crypto_hash_sha512 Fssh_crypto_hash_sha512 +#define crypto_hashblocks_sha512 Fssh_crypto_hashblocks_sha512 +#define crypto_scalarmult_curve25519 Fssh_crypto_scalarmult_curve25519 +#define crypto_sign_ed25519 Fssh_crypto_sign_ed25519 +#define crypto_sign_ed25519_keypair Fssh_crypto_sign_ed25519_keypair +#define crypto_sign_ed25519_open Fssh_crypto_sign_ed25519_open +#define crypto_sign_ed25519_ref_double_scalarmult_vartime Fssh_crypto_sign_ed25519_ref_double_scalarmult_vartime +#define crypto_sign_ed25519_ref_fe25519_add Fssh_crypto_sign_ed25519_ref_fe25519_add +#define crypto_sign_ed25519_ref_fe25519_cmov Fssh_crypto_sign_ed25519_ref_fe25519_cmov +#define crypto_sign_ed25519_ref_fe25519_freeze Fssh_crypto_sign_ed25519_ref_fe25519_freeze +#define crypto_sign_ed25519_ref_fe25519_getparity Fssh_crypto_sign_ed25519_ref_fe25519_getparity +#define crypto_sign_ed25519_ref_fe25519_invert Fssh_crypto_sign_ed25519_ref_fe25519_invert +#define crypto_sign_ed25519_ref_fe25519_iseq_vartime Fssh_crypto_sign_ed25519_ref_fe25519_iseq_vartime +#define crypto_sign_ed25519_ref_fe25519_iszero Fssh_crypto_sign_ed25519_ref_fe25519_iszero +#define crypto_sign_ed25519_ref_fe25519_mul Fssh_crypto_sign_ed25519_ref_fe25519_mul +#define crypto_sign_ed25519_ref_fe25519_neg Fssh_crypto_sign_ed25519_ref_fe25519_neg +#define crypto_sign_ed25519_ref_fe25519_pack Fssh_crypto_sign_ed25519_ref_fe25519_pack +#define crypto_sign_ed25519_ref_fe25519_pow2523 Fssh_crypto_sign_ed25519_ref_fe25519_pow2523 +#define crypto_sign_ed25519_ref_fe25519_setone Fssh_crypto_sign_ed25519_ref_fe25519_setone +#define crypto_sign_ed25519_ref_fe25519_setzero Fssh_crypto_sign_ed25519_ref_fe25519_setzero +#define crypto_sign_ed25519_ref_fe25519_square Fssh_crypto_sign_ed25519_ref_fe25519_square +#define crypto_sign_ed25519_ref_fe25519_sub Fssh_crypto_sign_ed25519_ref_fe25519_sub +#define crypto_sign_ed25519_ref_fe25519_unpack Fssh_crypto_sign_ed25519_ref_fe25519_unpack +#define crypto_sign_ed25519_ref_isneutral_vartime Fssh_crypto_sign_ed25519_ref_isneutral_vartime +#define crypto_sign_ed25519_ref_pack Fssh_crypto_sign_ed25519_ref_pack +#define crypto_sign_ed25519_ref_sc25519_2interleave2 Fssh_crypto_sign_ed25519_ref_sc25519_2interleave2 +#define crypto_sign_ed25519_ref_sc25519_add Fssh_crypto_sign_ed25519_ref_sc25519_add +#define crypto_sign_ed25519_ref_sc25519_from32bytes Fssh_crypto_sign_ed25519_ref_sc25519_from32bytes +#define crypto_sign_ed25519_ref_sc25519_from64bytes Fssh_crypto_sign_ed25519_ref_sc25519_from64bytes +#define crypto_sign_ed25519_ref_sc25519_from_shortsc Fssh_crypto_sign_ed25519_ref_sc25519_from_shortsc +#define crypto_sign_ed25519_ref_sc25519_isshort_vartime Fssh_crypto_sign_ed25519_ref_sc25519_isshort_vartime +#define crypto_sign_ed25519_ref_sc25519_iszero_vartime Fssh_crypto_sign_ed25519_ref_sc25519_iszero_vartime +#define crypto_sign_ed25519_ref_sc25519_lt_vartime Fssh_crypto_sign_ed25519_ref_sc25519_lt_vartime +#define crypto_sign_ed25519_ref_sc25519_mul Fssh_crypto_sign_ed25519_ref_sc25519_mul +#define crypto_sign_ed25519_ref_sc25519_mul_shortsc Fssh_crypto_sign_ed25519_ref_sc25519_mul_shortsc +#define crypto_sign_ed25519_ref_sc25519_sub_nored Fssh_crypto_sign_ed25519_ref_sc25519_sub_nored +#define crypto_sign_ed25519_ref_sc25519_to32bytes Fssh_crypto_sign_ed25519_ref_sc25519_to32bytes +#define crypto_sign_ed25519_ref_sc25519_window3 Fssh_crypto_sign_ed25519_ref_sc25519_window3 +#define crypto_sign_ed25519_ref_sc25519_window5 Fssh_crypto_sign_ed25519_ref_sc25519_window5 +#define crypto_sign_ed25519_ref_scalarmult_base Fssh_crypto_sign_ed25519_ref_scalarmult_base +#define crypto_sign_ed25519_ref_shortsc25519_from16bytes Fssh_crypto_sign_ed25519_ref_shortsc25519_from16bytes +#define crypto_sign_ed25519_ref_unpackneg_vartime Fssh_crypto_sign_ed25519_ref_unpackneg_vartime +#define crypto_verify_32 Fssh_crypto_verify_32 +#define dbl_p1p1 Fssh_dbl_p1p1 +#define deattack_init Fssh_deattack_init +#define debug Fssh_debug +#define debug2 Fssh_debug2 +#define debug3 Fssh_debug3 +#define deny_input_open Fssh_deny_input_open +#define derive_ssh1_session_id Fssh_derive_ssh1_session_id +#define detect_attack Fssh_detect_attack +#define dh_estimate Fssh_dh_estimate +#define dh_gen_key Fssh_dh_gen_key +#define dh_new_group Fssh_dh_new_group +#define dh_new_group1 Fssh_dh_new_group1 +#define dh_new_group14 Fssh_dh_new_group14 +#define dh_new_group_asc Fssh_dh_new_group_asc +#define dh_pub_is_valid Fssh_dh_pub_is_valid +#define dispatch_protocol_error Fssh_dispatch_protocol_error +#define dispatch_protocol_ignore Fssh_dispatch_protocol_ignore +#define dns_read_key Fssh_dns_read_key +#define do_log Fssh_do_log +#define do_log2 Fssh_do_log2 +#define dump_base64 Fssh_dump_base64 +#define enable_compat13 Fssh_enable_compat13 +#define enable_compat20 Fssh_enable_compat20 +#define error Fssh_error +#define evp_ssh1_3des Fssh_evp_ssh1_3des +#define evp_ssh1_bf Fssh_evp_ssh1_bf +#define export_dns_rr Fssh_export_dns_rr +#define fatal Fssh_fatal +#define filter_proposal Fssh_filter_proposal +#define fingerprint_b64 Fssh_fingerprint_b64 +#define fingerprint_hex Fssh_fingerprint_hex +#define fmt_scaled Fssh_fmt_scaled +#define free_hostkeys Fssh_free_hostkeys +#define freeargs Fssh_freeargs +#define freerrset Fssh_freerrset +#define gen_candidates Fssh_gen_candidates +#define get_canonical_hostname Fssh_get_canonical_hostname +#define get_local_ipaddr Fssh_get_local_ipaddr +#define get_local_name Fssh_get_local_name +#define get_local_port Fssh_get_local_port +#define get_peer_ipaddr Fssh_get_peer_ipaddr +#define get_peer_port Fssh_get_peer_port +#define get_remote_ipaddr Fssh_get_remote_ipaddr +#define get_remote_name_or_ip Fssh_get_remote_name_or_ip +#define get_remote_port Fssh_get_remote_port +#define get_sock_port Fssh_get_sock_port +#define get_socket_address Fssh_get_socket_address +#define get_u16 Fssh_get_u16 +#define get_u32 Fssh_get_u32 +#define get_u32_le Fssh_get_u32_le +#define get_u64 Fssh_get_u64 +#define getrrsetbyname Fssh_getrrsetbyname +#define glob Fssh_glob +#define glob0 Fssh_glob0 +#define glob2 Fssh_glob2 +#define globexp1 Fssh_globexp1 +#define globextend Fssh_globextend +#define globfree Fssh_globfree +#define host_delete Fssh_host_delete +#define host_hash Fssh_host_hash +#define hostfile_read_key Fssh_hostfile_read_key +#define hostfile_replace_entries Fssh_hostfile_replace_entries +#define hostkeys_foreach Fssh_hostkeys_foreach +#define hpdelim Fssh_hpdelim +#define init_hostkeys Fssh_init_hostkeys +#define input_kex_c25519_init Fssh_input_kex_c25519_init +#define input_kex_c25519_reply Fssh_input_kex_c25519_reply +#define input_kex_dh Fssh_input_kex_dh +#define input_kex_dh_gex_group Fssh_input_kex_dh_gex_group +#define input_kex_dh_gex_init Fssh_input_kex_dh_gex_init +#define input_kex_dh_gex_reply Fssh_input_kex_dh_gex_reply +#define input_kex_dh_gex_request Fssh_input_kex_dh_gex_request +#define input_kex_dh_init Fssh_input_kex_dh_init +#define input_kex_ecdh_init Fssh_input_kex_ecdh_init +#define input_kex_ecdh_reply Fssh_input_kex_ecdh_reply +#define iptos2str Fssh_iptos2str +#define ipv64_normalise_mapped Fssh_ipv64_normalise_mapped +#define is_cert_revoked Fssh_is_cert_revoked +#define is_key_revoked Fssh_is_key_revoked +#define kex_alg_by_name Fssh_kex_alg_by_name +#define kex_alg_list Fssh_kex_alg_list +#define kex_buf2prop Fssh_kex_buf2prop +#define kex_c25519_hash Fssh_kex_c25519_hash +#define kex_derive_keys Fssh_kex_derive_keys +#define kex_derive_keys_bn Fssh_kex_derive_keys_bn +#define kex_dh_hash Fssh_kex_dh_hash +#define kex_ecdh_hash Fssh_kex_ecdh_hash +#define kex_free Fssh_kex_free +#define kex_free_newkeys Fssh_kex_free_newkeys +#define kex_input_kexinit Fssh_kex_input_kexinit +#define kex_input_newkeys Fssh_kex_input_newkeys +#define kex_names_valid Fssh_kex_names_valid +#define kex_new Fssh_kex_new +#define kex_prop2buf Fssh_kex_prop2buf +#define kex_prop_free Fssh_kex_prop_free +#define kex_protocol_error Fssh_kex_protocol_error +#define kex_send_kexinit Fssh_kex_send_kexinit +#define kex_send_newkeys Fssh_kex_send_newkeys +#define kex_setup Fssh_kex_setup +#define kexc25519_client Fssh_kexc25519_client +#define kexc25519_keygen Fssh_kexc25519_keygen +#define kexc25519_server Fssh_kexc25519_server +#define kexc25519_shared_key Fssh_kexc25519_shared_key +#define kexdh_client Fssh_kexdh_client +#define kexdh_server Fssh_kexdh_server +#define kexecdh_client Fssh_kexecdh_client +#define kexecdh_server Fssh_kexecdh_server +#define kexgex_client Fssh_kexgex_client +#define kexgex_hash Fssh_kexgex_hash +#define kexgex_server Fssh_kexgex_server +#define key_add_private Fssh_key_add_private +#define key_alg_list Fssh_key_alg_list +#define key_cert_check_authority Fssh_key_cert_check_authority +#define key_cert_copy Fssh_key_cert_copy +#define key_certify Fssh_key_certify +#define key_demote Fssh_key_demote +#define key_drop_cert Fssh_key_drop_cert +#define key_ec_validate_private Fssh_key_ec_validate_private +#define key_ec_validate_public Fssh_key_ec_validate_public +#define key_from_blob Fssh_key_from_blob +#define key_from_private Fssh_key_from_private +#define key_generate Fssh_key_generate +#define key_load_cert Fssh_key_load_cert +#define key_load_file Fssh_key_load_file +#define key_load_private Fssh_key_load_private +#define key_load_private_cert Fssh_key_load_private_cert +#define key_load_private_type Fssh_key_load_private_type +#define key_load_public Fssh_key_load_public +#define key_new_private Fssh_key_new_private +#define key_perm_ok Fssh_key_perm_ok +#define key_private_deserialize Fssh_key_private_deserialize +#define key_private_serialize Fssh_key_private_serialize +#define key_read Fssh_key_read +#define key_save_private Fssh_key_save_private +#define key_sign Fssh_key_sign +#define key_to_blob Fssh_key_to_blob +#define key_to_certified Fssh_key_to_certified +#define key_verify Fssh_key_verify +#define key_write Fssh_key_write +#define load_hostkeys Fssh_load_hostkeys +#define log_change_level Fssh_log_change_level +#define log_facility_name Fssh_log_facility_name +#define log_facility_number Fssh_log_facility_number +#define log_init Fssh_log_init +#define log_is_on_stderr Fssh_log_is_on_stderr +#define log_level_name Fssh_log_level_name +#define log_level_number Fssh_log_level_number +#define log_redirect_stderr_to Fssh_log_redirect_stderr_to +#define logit Fssh_logit +#define lookup_key_in_hostkeys_by_type Fssh_lookup_key_in_hostkeys_by_type +#define lowercase Fssh_lowercase +#define mac_alg_list Fssh_mac_alg_list +#define mac_clear Fssh_mac_clear +#define mac_compute Fssh_mac_compute +#define mac_init Fssh_mac_init +#define mac_setup Fssh_mac_setup +#define mac_valid Fssh_mac_valid +#define match Fssh_match +#define match_host_and_ip Fssh_match_host_and_ip +#define match_hostname Fssh_match_hostname +#define match_list Fssh_match_list +#define match_maybe_hashed Fssh_match_maybe_hashed +#define match_pattern Fssh_match_pattern +#define match_pattern_list Fssh_match_pattern_list +#define match_user Fssh_match_user +#define mktemp_proto Fssh_mktemp_proto +#define mm_choose_dh Fssh_mm_choose_dh +#define mm_receive_fd Fssh_mm_receive_fd +#define mm_send_fd Fssh_mm_send_fd +#define mm_sshkey_sign Fssh_mm_sshkey_sign +#define monotime Fssh_monotime +#define ms_subtract_diff Fssh_ms_subtract_diff +#define ms_to_timeval Fssh_ms_to_timeval +#define mult Fssh_mult +#define mysignal Fssh_mysignal +#define newkeys_from_blob Fssh_newkeys_from_blob +#define newkeys_to_blob Fssh_newkeys_to_blob +#define nh_aux Fssh_nh_aux +#define nh_final Fssh_nh_final +#define packet_backup_state Fssh_packet_backup_state +#define packet_close Fssh_packet_close +#define packet_disconnect Fssh_packet_disconnect +#define packet_get_char Fssh_packet_get_char +#define packet_get_int Fssh_packet_get_int +#define packet_process_incoming Fssh_packet_process_incoming +#define packet_read_expect Fssh_packet_read_expect +#define packet_read_poll_seqnr Fssh_packet_read_poll_seqnr +#define packet_read_seqnr Fssh_packet_read_seqnr +#define packet_restore_state Fssh_packet_restore_state +#define packet_send_debug Fssh_packet_send_debug +#define packet_set_connection Fssh_packet_set_connection +#define packet_write_poll Fssh_packet_write_poll +#define packet_write_wait Fssh_packet_write_wait +#define parse_ipqos Fssh_parse_ipqos +#define parse_prime Fssh_parse_prime +#define percent_expand Fssh_percent_expand +#define permanently_drop_suid Fssh_permanently_drop_suid +#define permanently_set_uid Fssh_permanently_set_uid +#define permitopen_port Fssh_permitopen_port +#define pkcs11_add_provider Fssh_pkcs11_add_provider +#define pkcs11_del_provider Fssh_pkcs11_del_provider +#define pkcs11_fetch_keys_filter Fssh_pkcs11_fetch_keys_filter +#define pkcs11_find Fssh_pkcs11_find +#define pkcs11_init Fssh_pkcs11_init +#define pkcs11_provider_finalize Fssh_pkcs11_provider_finalize +#define pkcs11_provider_unref Fssh_pkcs11_provider_unref +#define pkcs11_rsa_finish Fssh_pkcs11_rsa_finish +#define pkcs11_rsa_private_decrypt Fssh_pkcs11_rsa_private_decrypt +#define pkcs11_rsa_private_encrypt Fssh_pkcs11_rsa_private_encrypt +#define pkcs11_terminate Fssh_pkcs11_terminate +#define plain_key_blob Fssh_plain_key_blob +#define poly1305_auth Fssh_poly1305_auth +#define poly64 Fssh_poly64 +#define poly_hash Fssh_poly_hash +#define port_open_helper Fssh_port_open_helper +#define prime_test Fssh_prime_test +#define proto_spec Fssh_proto_spec +#define put_bitmap Fssh_put_bitmap +#define put_host_port Fssh_put_host_port +#define put_u16 Fssh_put_u16 +#define put_u32 Fssh_put_u32 +#define put_u32_le Fssh_put_u32_le +#define put_u64 Fssh_put_u64 +#define pwcopy Fssh_pwcopy +#define qfileout Fssh_qfileout +#define read_keyfile_line Fssh_read_keyfile_line +#define read_mux Fssh_read_mux +#define read_passphrase Fssh_read_passphrase +#define record_hostkey Fssh_record_hostkey +#define reduce_add_sub Fssh_reduce_add_sub +#define refresh_progress_meter Fssh_refresh_progress_meter +#define replacearg Fssh_replacearg +#define restore_uid Fssh_restore_uid +#define revoke_blob Fssh_revoke_blob +#define revoked_blob_tree_RB_REMOVE Fssh_revoked_blob_tree_RB_REMOVE +#define revoked_certs_for_ca_key Fssh_revoked_certs_for_ca_key +#define revoked_serial_tree_RB_REMOVE Fssh_revoked_serial_tree_RB_REMOVE +#define rijndaelEncrypt Fssh_rijndaelEncrypt +#define rijndaelKeySetupEnc Fssh_rijndaelKeySetupEnc +#define rsa_generate_additional_parameters Fssh_rsa_generate_additional_parameters +#define rsa_private_decrypt Fssh_rsa_private_decrypt +#define rsa_public_encrypt Fssh_rsa_public_encrypt +#define sanitise_stdfd Fssh_sanitise_stdfd +#define scan_scaled Fssh_scan_scaled +#define seed_rng Fssh_seed_rng +#define set_log_handler Fssh_set_log_handler +#define set_nodelay Fssh_set_nodelay +#define set_nonblock Fssh_set_nonblock +#define shadow_pw Fssh_shadow_pw +#define sieve_large Fssh_sieve_large +#define sig_winch Fssh_sig_winch +#define sigdie Fssh_sigdie +#define sock_set_v6only Fssh_sock_set_v6only +#define square Fssh_square +#define ssh1_3des_cbc Fssh_ssh1_3des_cbc +#define ssh1_3des_cleanup Fssh_ssh1_3des_cleanup +#define ssh1_3des_init Fssh_ssh1_3des_init +#define ssh1_3des_iv Fssh_ssh1_3des_iv +#define ssh_OpenSSL_add_all_algorithms Fssh_ssh_OpenSSL_add_all_algorithms +#define ssh_add_hostkey Fssh_ssh_add_hostkey +#define ssh_add_identity_constrained Fssh_ssh_add_identity_constrained +#define ssh_agent_sign Fssh_ssh_agent_sign +#define ssh_alloc_session_state Fssh_ssh_alloc_session_state +#define ssh_close_authentication_socket Fssh_ssh_close_authentication_socket +#define ssh_compatible_openssl Fssh_ssh_compatible_openssl +#define ssh_crc32 Fssh_ssh_crc32 +#define ssh_decrypt_challenge Fssh_ssh_decrypt_challenge +#define ssh_digest_alg_by_name Fssh_ssh_digest_alg_by_name +#define ssh_digest_alg_name Fssh_ssh_digest_alg_name +#define ssh_digest_blocksize Fssh_ssh_digest_blocksize +#define ssh_digest_buffer Fssh_ssh_digest_buffer +#define ssh_digest_bytes Fssh_ssh_digest_bytes +#define ssh_digest_copy_state Fssh_ssh_digest_copy_state +#define ssh_digest_final Fssh_ssh_digest_final +#define ssh_digest_free Fssh_ssh_digest_free +#define ssh_digest_memory Fssh_ssh_digest_memory +#define ssh_digest_start Fssh_ssh_digest_start +#define ssh_digest_update Fssh_ssh_digest_update +#define ssh_digest_update_buffer Fssh_ssh_digest_update_buffer +#define ssh_dispatch_init Fssh_ssh_dispatch_init +#define ssh_dispatch_range Fssh_ssh_dispatch_range +#define ssh_dispatch_run Fssh_ssh_dispatch_run +#define ssh_dispatch_run_fatal Fssh_ssh_dispatch_run_fatal +#define ssh_dispatch_set Fssh_ssh_dispatch_set +#define ssh_dss_sign Fssh_ssh_dss_sign +#define ssh_dss_verify Fssh_ssh_dss_verify +#define ssh_ecdsa_sign Fssh_ssh_ecdsa_sign +#define ssh_ecdsa_verify Fssh_ssh_ecdsa_verify +#define ssh_ed25519_sign Fssh_ssh_ed25519_sign +#define ssh_ed25519_verify Fssh_ssh_ed25519_verify +#define ssh_err Fssh_ssh_err +#define ssh_fetch_identitylist Fssh_ssh_fetch_identitylist +#define ssh_free Fssh_ssh_free +#define ssh_free_identitylist Fssh_ssh_free_identitylist +#define ssh_gai_strerror Fssh_ssh_gai_strerror +#define ssh_get_app_data Fssh_ssh_get_app_data +#define ssh_get_authentication_socket Fssh_ssh_get_authentication_socket +#define ssh_get_progname Fssh_ssh_get_progname +#define ssh_gssapi_build_ctx Fssh_ssh_gssapi_build_ctx +#define ssh_gssapi_buildmic Fssh_ssh_gssapi_buildmic +#define ssh_gssapi_check_mechanism Fssh_ssh_gssapi_check_mechanism +#define ssh_gssapi_check_oid Fssh_ssh_gssapi_check_oid +#define ssh_gssapi_delete_ctx Fssh_ssh_gssapi_delete_ctx +#define ssh_gssapi_error Fssh_ssh_gssapi_error +#define ssh_gssapi_import_name Fssh_ssh_gssapi_import_name +#define ssh_gssapi_init_ctx Fssh_ssh_gssapi_init_ctx +#define ssh_gssapi_last_error Fssh_ssh_gssapi_last_error +#define ssh_gssapi_set_oid Fssh_ssh_gssapi_set_oid +#define ssh_gssapi_set_oid_data Fssh_ssh_gssapi_set_oid_data +#define ssh_gssapi_sign Fssh_ssh_gssapi_sign +#define ssh_hmac_bytes Fssh_ssh_hmac_bytes +#define ssh_hmac_final Fssh_ssh_hmac_final +#define ssh_hmac_free Fssh_ssh_hmac_free +#define ssh_hmac_init Fssh_ssh_hmac_init +#define ssh_hmac_start Fssh_ssh_hmac_start +#define ssh_hmac_update Fssh_ssh_hmac_update +#define ssh_hmac_update_buffer Fssh_ssh_hmac_update_buffer +#define ssh_init Fssh_ssh_init +#define ssh_input_append Fssh_ssh_input_append +#define ssh_input_space Fssh_ssh_input_space +#define ssh_krl_check_key Fssh_ssh_krl_check_key +#define ssh_krl_file_contains_key Fssh_ssh_krl_file_contains_key +#define ssh_krl_free Fssh_ssh_krl_free +#define ssh_krl_from_blob Fssh_ssh_krl_from_blob +#define ssh_krl_init Fssh_ssh_krl_init +#define ssh_krl_revoke_cert_by_key_id Fssh_ssh_krl_revoke_cert_by_key_id +#define ssh_krl_revoke_cert_by_serial Fssh_ssh_krl_revoke_cert_by_serial +#define ssh_krl_revoke_cert_by_serial_range Fssh_ssh_krl_revoke_cert_by_serial_range +#define ssh_krl_revoke_key Fssh_ssh_krl_revoke_key +#define ssh_krl_revoke_key_explicit Fssh_ssh_krl_revoke_key_explicit +#define ssh_krl_revoke_key_sha1 Fssh_ssh_krl_revoke_key_sha1 +#define ssh_krl_set_comment Fssh_ssh_krl_set_comment +#define ssh_krl_set_version Fssh_ssh_krl_set_version +#define ssh_krl_to_blob Fssh_ssh_krl_to_blob +#define ssh_lock_agent Fssh_ssh_lock_agent +#define ssh_msg_recv Fssh_ssh_msg_recv +#define ssh_msg_send Fssh_ssh_msg_send +#define ssh_output_consume Fssh_ssh_output_consume +#define ssh_output_ptr Fssh_ssh_output_ptr +#define ssh_output_space Fssh_ssh_output_space +#define ssh_packet_backup_state Fssh_ssh_packet_backup_state +#define ssh_packet_close Fssh_ssh_packet_close +#define ssh_packet_connection_af Fssh_ssh_packet_connection_af +#define ssh_packet_connection_is_on_socket Fssh_ssh_packet_connection_is_on_socket +#define ssh_packet_disconnect Fssh_ssh_packet_disconnect +#define ssh_packet_enable_delayed_compress Fssh_ssh_packet_enable_delayed_compress +#define ssh_packet_get_bignum Fssh_ssh_packet_get_bignum +#define ssh_packet_get_bignum2 Fssh_ssh_packet_get_bignum2 +#define ssh_packet_get_bytes Fssh_ssh_packet_get_bytes +#define ssh_packet_get_char Fssh_ssh_packet_get_char +#define ssh_packet_get_connection_in Fssh_ssh_packet_get_connection_in +#define ssh_packet_get_connection_out Fssh_ssh_packet_get_connection_out +#define ssh_packet_get_cstring Fssh_ssh_packet_get_cstring +#define ssh_packet_get_ecpoint Fssh_ssh_packet_get_ecpoint +#define ssh_packet_get_input Fssh_ssh_packet_get_input +#define ssh_packet_get_int Fssh_ssh_packet_get_int +#define ssh_packet_get_int64 Fssh_ssh_packet_get_int64 +#define ssh_packet_get_maxsize Fssh_ssh_packet_get_maxsize +#define ssh_packet_get_output Fssh_ssh_packet_get_output +#define ssh_packet_get_protocol_flags Fssh_ssh_packet_get_protocol_flags +#define ssh_packet_get_rekey_timeout Fssh_ssh_packet_get_rekey_timeout +#define ssh_packet_get_state Fssh_ssh_packet_get_state +#define ssh_packet_get_string Fssh_ssh_packet_get_string +#define ssh_packet_get_string_ptr Fssh_ssh_packet_get_string_ptr +#define ssh_packet_have_data_to_write Fssh_ssh_packet_have_data_to_write +#define ssh_packet_inc_alive_timeouts Fssh_ssh_packet_inc_alive_timeouts +#define ssh_packet_is_interactive Fssh_ssh_packet_is_interactive +#define ssh_packet_need_rekeying Fssh_ssh_packet_need_rekeying +#define ssh_packet_next Fssh_ssh_packet_next +#define ssh_packet_not_very_much_data_to_write Fssh_ssh_packet_not_very_much_data_to_write +#define ssh_packet_payload Fssh_ssh_packet_payload +#define ssh_packet_process_incoming Fssh_ssh_packet_process_incoming +#define ssh_packet_put Fssh_ssh_packet_put +#define ssh_packet_put_bignum Fssh_ssh_packet_put_bignum +#define ssh_packet_put_bignum2 Fssh_ssh_packet_put_bignum2 +#define ssh_packet_put_char Fssh_ssh_packet_put_char +#define ssh_packet_put_cstring Fssh_ssh_packet_put_cstring +#define ssh_packet_put_ecpoint Fssh_ssh_packet_put_ecpoint +#define ssh_packet_put_int Fssh_ssh_packet_put_int +#define ssh_packet_put_int64 Fssh_ssh_packet_put_int64 +#define ssh_packet_put_raw Fssh_ssh_packet_put_raw +#define ssh_packet_put_string Fssh_ssh_packet_put_string +#define ssh_packet_read Fssh_ssh_packet_read +#define ssh_packet_read_expect Fssh_ssh_packet_read_expect +#define ssh_packet_read_poll1 Fssh_ssh_packet_read_poll1 +#define ssh_packet_read_poll2 Fssh_ssh_packet_read_poll2 +#define ssh_packet_read_poll_seqnr Fssh_ssh_packet_read_poll_seqnr +#define ssh_packet_read_seqnr Fssh_ssh_packet_read_seqnr +#define ssh_packet_remaining Fssh_ssh_packet_remaining +#define ssh_packet_restore_state Fssh_ssh_packet_restore_state +#define ssh_packet_send Fssh_ssh_packet_send +#define ssh_packet_send1 Fssh_ssh_packet_send1 +#define ssh_packet_send2 Fssh_ssh_packet_send2 +#define ssh_packet_send2_wrapped Fssh_ssh_packet_send2_wrapped +#define ssh_packet_send_debug Fssh_ssh_packet_send_debug +#define ssh_packet_send_ignore Fssh_ssh_packet_send_ignore +#define ssh_packet_set_alive_timeouts Fssh_ssh_packet_set_alive_timeouts +#define ssh_packet_set_authenticated Fssh_ssh_packet_set_authenticated +#define ssh_packet_set_compress_hooks Fssh_ssh_packet_set_compress_hooks +#define ssh_packet_set_connection Fssh_ssh_packet_set_connection +#define ssh_packet_set_encryption_key Fssh_ssh_packet_set_encryption_key +#define ssh_packet_set_interactive Fssh_ssh_packet_set_interactive +#define ssh_packet_set_maxsize Fssh_ssh_packet_set_maxsize +#define ssh_packet_set_nonblocking Fssh_ssh_packet_set_nonblocking +#define ssh_packet_set_protocol_flags Fssh_ssh_packet_set_protocol_flags +#define ssh_packet_set_rekey_limits Fssh_ssh_packet_set_rekey_limits +#define ssh_packet_set_server Fssh_ssh_packet_set_server +#define ssh_packet_set_state Fssh_ssh_packet_set_state +#define ssh_packet_set_timeout Fssh_ssh_packet_set_timeout +#define ssh_packet_set_tos Fssh_ssh_packet_set_tos +#define ssh_packet_start Fssh_ssh_packet_start +#define ssh_packet_start_compression Fssh_ssh_packet_start_compression +#define ssh_packet_start_discard Fssh_ssh_packet_start_discard +#define ssh_packet_stop_discard Fssh_ssh_packet_stop_discard +#define ssh_packet_write_poll Fssh_ssh_packet_write_poll +#define ssh_packet_write_wait Fssh_ssh_packet_write_wait +#define ssh_remote_ipaddr Fssh_ssh_remote_ipaddr +#define ssh_remove_all_identities Fssh_ssh_remove_all_identities +#define ssh_remove_identity Fssh_ssh_remove_identity +#define ssh_request_reply Fssh_ssh_request_reply +#define ssh_rsa_sign Fssh_ssh_rsa_sign +#define ssh_rsa_verify Fssh_ssh_rsa_verify +#define ssh_set_app_data Fssh_ssh_set_app_data +#define ssh_set_newkeys Fssh_ssh_set_newkeys +#define ssh_set_verify_host_key_callback Fssh_ssh_set_verify_host_key_callback +#define ssh_update_card Fssh_ssh_update_card +#define sshbuf_alloc Fssh_sshbuf_alloc +#define sshbuf_avail Fssh_sshbuf_avail +#define sshbuf_b64tod Fssh_sshbuf_b64tod +#define sshbuf_check_reserve Fssh_sshbuf_check_reserve +#define sshbuf_consume Fssh_sshbuf_consume +#define sshbuf_consume_end Fssh_sshbuf_consume_end +#define sshbuf_dtob16 Fssh_sshbuf_dtob16 +#define sshbuf_dtob64 Fssh_sshbuf_dtob64 +#define sshbuf_dump Fssh_sshbuf_dump +#define sshbuf_dump_data Fssh_sshbuf_dump_data +#define sshbuf_free Fssh_sshbuf_free +#define sshbuf_from Fssh_sshbuf_from +#define sshbuf_fromb Fssh_sshbuf_fromb +#define sshbuf_froms Fssh_sshbuf_froms +#define sshbuf_get Fssh_sshbuf_get +#define sshbuf_get_bignum1 Fssh_sshbuf_get_bignum1 +#define sshbuf_get_bignum2 Fssh_sshbuf_get_bignum2 +#define sshbuf_get_bignum2_bytes_direct Fssh_sshbuf_get_bignum2_bytes_direct +#define sshbuf_get_cstring Fssh_sshbuf_get_cstring +#define sshbuf_get_ec Fssh_sshbuf_get_ec +#define sshbuf_get_eckey Fssh_sshbuf_get_eckey +#define sshbuf_get_string Fssh_sshbuf_get_string +#define sshbuf_get_string_direct Fssh_sshbuf_get_string_direct +#define sshbuf_get_stringb Fssh_sshbuf_get_stringb +#define sshbuf_get_u16 Fssh_sshbuf_get_u16 +#define sshbuf_get_u32 Fssh_sshbuf_get_u32 +#define sshbuf_get_u64 Fssh_sshbuf_get_u64 +#define sshbuf_get_u8 Fssh_sshbuf_get_u8 +#define sshbuf_init Fssh_sshbuf_init +#define sshbuf_len Fssh_sshbuf_len +#define sshbuf_max_size Fssh_sshbuf_max_size +#define sshbuf_mutable_ptr Fssh_sshbuf_mutable_ptr +#define sshbuf_new Fssh_sshbuf_new +#define sshbuf_parent Fssh_sshbuf_parent +#define sshbuf_peek_string_direct Fssh_sshbuf_peek_string_direct +#define sshbuf_ptr Fssh_sshbuf_ptr +#define sshbuf_put Fssh_sshbuf_put +#define sshbuf_put_bignum1 Fssh_sshbuf_put_bignum1 +#define sshbuf_put_bignum2 Fssh_sshbuf_put_bignum2 +#define sshbuf_put_bignum2_bytes Fssh_sshbuf_put_bignum2_bytes +#define sshbuf_put_cstring Fssh_sshbuf_put_cstring +#define sshbuf_put_ec Fssh_sshbuf_put_ec +#define sshbuf_put_eckey Fssh_sshbuf_put_eckey +#define sshbuf_put_string Fssh_sshbuf_put_string +#define sshbuf_put_stringb Fssh_sshbuf_put_stringb +#define sshbuf_put_u16 Fssh_sshbuf_put_u16 +#define sshbuf_put_u32 Fssh_sshbuf_put_u32 +#define sshbuf_put_u64 Fssh_sshbuf_put_u64 +#define sshbuf_put_u8 Fssh_sshbuf_put_u8 +#define sshbuf_putb Fssh_sshbuf_putb +#define sshbuf_putf Fssh_sshbuf_putf +#define sshbuf_putfv Fssh_sshbuf_putfv +#define sshbuf_refcount Fssh_sshbuf_refcount +#define sshbuf_reserve Fssh_sshbuf_reserve +#define sshbuf_reset Fssh_sshbuf_reset +#define sshbuf_set_max_size Fssh_sshbuf_set_max_size +#define sshbuf_set_parent Fssh_sshbuf_set_parent +#define sshkey_add_private Fssh_sshkey_add_private +#define sshkey_cert_check_authority Fssh_sshkey_cert_check_authority +#define sshkey_cert_copy Fssh_sshkey_cert_copy +#define sshkey_cert_is_legacy Fssh_sshkey_cert_is_legacy +#define sshkey_cert_type Fssh_sshkey_cert_type +#define sshkey_certify Fssh_sshkey_certify +#define sshkey_check_revoked Fssh_sshkey_check_revoked +#define sshkey_curve_name_to_nid Fssh_sshkey_curve_name_to_nid +#define sshkey_curve_nid_to_bits Fssh_sshkey_curve_nid_to_bits +#define sshkey_curve_nid_to_name Fssh_sshkey_curve_nid_to_name +#define sshkey_demote Fssh_sshkey_demote +#define sshkey_drop_cert Fssh_sshkey_drop_cert +#define sshkey_dump_ec_key Fssh_sshkey_dump_ec_key +#define sshkey_dump_ec_point Fssh_sshkey_dump_ec_point +#define sshkey_ec_nid_to_hash_alg Fssh_sshkey_ec_nid_to_hash_alg +#define sshkey_ec_validate_private Fssh_sshkey_ec_validate_private +#define sshkey_ec_validate_public Fssh_sshkey_ec_validate_public +#define sshkey_ecdsa_bits_to_nid Fssh_sshkey_ecdsa_bits_to_nid +#define sshkey_ecdsa_key_to_nid Fssh_sshkey_ecdsa_key_to_nid +#define sshkey_ecdsa_nid_from_name Fssh_sshkey_ecdsa_nid_from_name +#define sshkey_equal Fssh_sshkey_equal +#define sshkey_equal_public Fssh_sshkey_equal_public +#define sshkey_fingerprint Fssh_sshkey_fingerprint +#define sshkey_fingerprint_raw Fssh_sshkey_fingerprint_raw +#define sshkey_free Fssh_sshkey_free +#define sshkey_from_blob Fssh_sshkey_from_blob +#define sshkey_from_blob_internal Fssh_sshkey_from_blob_internal +#define sshkey_from_private Fssh_sshkey_from_private +#define sshkey_fromb Fssh_sshkey_fromb +#define sshkey_froms Fssh_sshkey_froms +#define sshkey_generate Fssh_sshkey_generate +#define sshkey_in_file Fssh_sshkey_in_file +#define sshkey_is_cert Fssh_sshkey_is_cert +#define sshkey_load_cert Fssh_sshkey_load_cert +#define sshkey_load_file Fssh_sshkey_load_file +#define sshkey_load_private Fssh_sshkey_load_private +#define sshkey_load_private_cert Fssh_sshkey_load_private_cert +#define sshkey_load_private_type Fssh_sshkey_load_private_type +#define sshkey_load_private_type_fd Fssh_sshkey_load_private_type_fd +#define sshkey_load_public Fssh_sshkey_load_public +#define sshkey_names_valid2 Fssh_sshkey_names_valid2 +#define sshkey_new Fssh_sshkey_new +#define sshkey_new_private Fssh_sshkey_new_private +#define sshkey_parse_private2 Fssh_sshkey_parse_private2 +#define sshkey_parse_private_fileblob Fssh_sshkey_parse_private_fileblob +#define sshkey_parse_private_fileblob_type Fssh_sshkey_parse_private_fileblob_type +#define sshkey_parse_private_pem_fileblob Fssh_sshkey_parse_private_pem_fileblob +#define sshkey_parse_public_rsa1_fileblob Fssh_sshkey_parse_public_rsa1_fileblob +#define sshkey_perm_ok Fssh_sshkey_perm_ok +#define sshkey_plain_to_blob Fssh_sshkey_plain_to_blob +#define sshkey_private_deserialize Fssh_sshkey_private_deserialize +#define sshkey_private_serialize Fssh_sshkey_private_serialize +#define sshkey_private_to_blob2 Fssh_sshkey_private_to_blob2 +#define sshkey_private_to_fileblob Fssh_sshkey_private_to_fileblob +#define sshkey_putb Fssh_sshkey_putb +#define sshkey_putb_plain Fssh_sshkey_putb_plain +#define sshkey_puts Fssh_sshkey_puts +#define sshkey_read Fssh_sshkey_read +#define sshkey_save_private Fssh_sshkey_save_private +#define sshkey_sign Fssh_sshkey_sign +#define sshkey_size Fssh_sshkey_size +#define sshkey_ssh_name Fssh_sshkey_ssh_name +#define sshkey_ssh_name_plain Fssh_sshkey_ssh_name_plain +#define sshkey_to_blob Fssh_sshkey_to_blob +#define sshkey_to_certified Fssh_sshkey_to_certified +#define sshkey_try_load_public Fssh_sshkey_try_load_public +#define sshkey_type Fssh_sshkey_type +#define sshkey_type_from_name Fssh_sshkey_type_from_name +#define sshkey_type_is_cert Fssh_sshkey_type_is_cert +#define sshkey_type_plain Fssh_sshkey_type_plain +#define sshkey_verify Fssh_sshkey_verify +#define sshkey_write Fssh_sshkey_write +#define sshpkt_add_padding Fssh_sshpkt_add_padding +#define sshpkt_disconnect Fssh_sshpkt_disconnect +#define sshpkt_fatal Fssh_sshpkt_fatal +#define sshpkt_get Fssh_sshpkt_get +#define sshpkt_get_bignum1 Fssh_sshpkt_get_bignum1 +#define sshpkt_get_bignum2 Fssh_sshpkt_get_bignum2 +#define sshpkt_get_cstring Fssh_sshpkt_get_cstring +#define sshpkt_get_ec Fssh_sshpkt_get_ec +#define sshpkt_get_end Fssh_sshpkt_get_end +#define sshpkt_get_string Fssh_sshpkt_get_string +#define sshpkt_get_string_direct Fssh_sshpkt_get_string_direct +#define sshpkt_get_u32 Fssh_sshpkt_get_u32 +#define sshpkt_get_u64 Fssh_sshpkt_get_u64 +#define sshpkt_get_u8 Fssh_sshpkt_get_u8 +#define sshpkt_ptr Fssh_sshpkt_ptr +#define sshpkt_put Fssh_sshpkt_put +#define sshpkt_put_bignum1 Fssh_sshpkt_put_bignum1 +#define sshpkt_put_bignum2 Fssh_sshpkt_put_bignum2 +#define sshpkt_put_cstring Fssh_sshpkt_put_cstring +#define sshpkt_put_ec Fssh_sshpkt_put_ec +#define sshpkt_put_string Fssh_sshpkt_put_string +#define sshpkt_put_stringb Fssh_sshpkt_put_stringb +#define sshpkt_put_u32 Fssh_sshpkt_put_u32 +#define sshpkt_put_u64 Fssh_sshpkt_put_u64 +#define sshpkt_put_u8 Fssh_sshpkt_put_u8 +#define sshpkt_putb Fssh_sshpkt_putb +#define sshpkt_send Fssh_sshpkt_send +#define sshpkt_start Fssh_sshpkt_start +#define start_progress_meter Fssh_start_progress_meter +#define stop_progress_meter Fssh_stop_progress_meter +#define strdelim Fssh_strdelim +#define strnvis Fssh_strnvis +#define strvis Fssh_strvis +#define strvisx Fssh_strvisx +#define sys_tun_open Fssh_sys_tun_open +#define temporarily_use_uid Fssh_temporarily_use_uid +#define tilde_expand_filename Fssh_tilde_expand_filename +#define timingsafe_bcmp Fssh_timingsafe_bcmp +#define to_blob Fssh_to_blob +#define to_blob_buf Fssh_to_blob_buf +#define tohex Fssh_tohex +#define tty_make_modes Fssh_tty_make_modes +#define tty_parse_modes Fssh_tty_parse_modes +#define tun_open Fssh_tun_open +#define umac128_delete Fssh_umac128_delete +#define umac128_final Fssh_umac128_final +#define umac128_new Fssh_umac128_new +#define umac128_update Fssh_umac128_update +#define umac_delete Fssh_umac_delete +#define umac_final Fssh_umac_final +#define umac_new Fssh_umac_new +#define umac_update Fssh_umac_update +#define uncompress_buffer Fssh_uncompress_buffer +#define unix_listener Fssh_unix_listener +#define unset_nonblock Fssh_unset_nonblock +#define update_progress_meter Fssh_update_progress_meter +#define uudecode Fssh_uudecode +#define uuencode Fssh_uuencode +#define verbose Fssh_verbose +#define verify_host_key_dns Fssh_verify_host_key_dns +#define vis Fssh_vis +#define write_host_entry Fssh_write_host_entry +#define x11_connect_display Fssh_x11_connect_display +#define x11_create_display_inet Fssh_x11_create_display_inet +#define x11_input_open Fssh_x11_input_open +#define x11_open_helper Fssh_x11_open_helper +#define x11_request_forwarding_with_spoofing Fssh_x11_request_forwarding_with_spoofing +#define xasprintf Fssh_xasprintf +#define xcalloc Fssh_xcalloc +#define xcrypt Fssh_xcrypt +#define xmalloc Fssh_xmalloc +#define xmmap Fssh_xmmap +#define xrealloc Fssh_xrealloc +#define xstrdup Fssh_xstrdup diff --git a/crypto/openssh/sshbuf-getput-basic.c b/crypto/openssh/sshbuf-getput-basic.c index b7d0758c2b45..8ff8a0a28893 100644 --- a/crypto/openssh/sshbuf-getput-basic.c +++ b/crypto/openssh/sshbuf-getput-basic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-getput-basic.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */ +/* $OpenBSD: sshbuf-getput-basic.c,v 1.4 2015/01/14 15:02:39 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -34,7 +34,7 @@ sshbuf_get(struct sshbuf *buf, void *v, size_t len) if ((r = sshbuf_consume(buf, len)) < 0) return r; - if (v != NULL) + if (v != NULL && len != 0) memcpy(v, p, len); return 0; } @@ -109,7 +109,8 @@ sshbuf_get_string(struct sshbuf *buf, u_char **valp, size_t *lenp) SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); return SSH_ERR_ALLOC_FAIL; } - memcpy(*valp, val, len); + if (len != 0) + memcpy(*valp, val, len); (*valp)[len] = '\0'; } if (lenp != NULL) @@ -200,7 +201,8 @@ sshbuf_get_cstring(struct sshbuf *buf, char **valp, size_t *lenp) SSHBUF_DBG(("SSH_ERR_ALLOC_FAIL")); return SSH_ERR_ALLOC_FAIL; } - memcpy(*valp, p, len); + if (len != 0) + memcpy(*valp, p, len); (*valp)[len] = '\0'; } if (lenp != NULL) @@ -236,7 +238,8 @@ sshbuf_put(struct sshbuf *buf, const void *v, size_t len) if ((r = sshbuf_reserve(buf, len, &p)) < 0) return r; - memcpy(p, v, len); + if (len != 0) + memcpy(p, v, len); return 0; } @@ -352,14 +355,15 @@ sshbuf_put_string(struct sshbuf *buf, const void *v, size_t len) if ((r = sshbuf_reserve(buf, len + 4, &d)) < 0) return r; POKE_U32(d, len); - memcpy(d + 4, v, len); + if (len != 0) + memcpy(d + 4, v, len); return 0; } int sshbuf_put_cstring(struct sshbuf *buf, const char *v) { - return sshbuf_put_string(buf, (u_char *)v, strlen(v)); + return sshbuf_put_string(buf, (u_char *)v, v == NULL ? 0 : strlen(v)); } int @@ -416,6 +420,43 @@ sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len) POKE_U32(d, len + prepend); if (prepend) d[4] = 0; - memcpy(d + 4 + prepend, s, len); + if (len != 0) + memcpy(d + 4 + prepend, s, len); + return 0; +} + +int +sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, + const u_char **valp, size_t *lenp) +{ + const u_char *d; + size_t len, olen; + int r; + + if ((r = sshbuf_peek_string_direct(buf, &d, &olen)) < 0) + return r; + len = olen; + /* Refuse negative (MSB set) bignums */ + if ((len != 0 && (*d & 0x80) != 0)) + return SSH_ERR_BIGNUM_IS_NEGATIVE; + /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */ + if (len > SSHBUF_MAX_BIGNUM + 1 || + (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0)) + return SSH_ERR_BIGNUM_TOO_LARGE; + /* Trim leading zeros */ + while (len > 0 && *d == 0x00) { + d++; + len--; + } + if (valp != 0) + *valp = d; + if (lenp != NULL) + *lenp = len; + if (sshbuf_consume(buf, olen + 4) != 0) { + /* Shouldn't happen */ + SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); + SSHBUF_ABORT(); + return SSH_ERR_INTERNAL_ERROR; + } return 0; } diff --git a/crypto/openssh/sshbuf-getput-crypto.c b/crypto/openssh/sshbuf-getput-crypto.c index 74351d3e5cab..e2e093c002f9 100644 --- a/crypto/openssh/sshbuf-getput-crypto.c +++ b/crypto/openssh/sshbuf-getput-crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-getput-crypto.c,v 1.2 2014/06/18 15:42:09 naddy Exp $ */ +/* $OpenBSD: sshbuf-getput-crypto.c,v 1.4 2015/01/14 15:02:39 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -38,24 +38,10 @@ sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v) size_t len; int r; - if ((r = sshbuf_peek_string_direct(buf, &d, &len)) < 0) + if ((r = sshbuf_get_bignum2_bytes_direct(buf, &d, &len)) != 0) return r; - /* Refuse negative (MSB set) bignums */ - if ((len != 0 && (*d & 0x80) != 0)) - return SSH_ERR_BIGNUM_IS_NEGATIVE; - /* Refuse overlong bignums, allow prepended \0 to avoid MSB set */ - if (len > SSHBUF_MAX_BIGNUM + 1 || - (len == SSHBUF_MAX_BIGNUM + 1 && *d != 0)) - return SSH_ERR_BIGNUM_TOO_LARGE; if (v != NULL && BN_bin2bn(d, len, v) == NULL) return SSH_ERR_ALLOC_FAIL; - /* Consume the string */ - if (sshbuf_get_string_direct(buf, NULL, NULL) != 0) { - /* Shouldn't happen */ - SSHBUF_DBG(("SSH_ERR_INTERNAL_ERROR")); - SSHBUF_ABORT(); - return SSH_ERR_INTERNAL_ERROR; - } return 0; } @@ -195,7 +181,8 @@ sshbuf_put_bignum1(struct sshbuf *buf, const BIGNUM *v) return r; } POKE_U16(dp, len_bits); - memcpy(dp + 2, d, len_bytes); + if (len_bytes != 0) + memcpy(dp + 2, d, len_bytes); bzero(d, sizeof(d)); return 0; } diff --git a/crypto/openssh/sshbuf-misc.c b/crypto/openssh/sshbuf-misc.c index bfeffe6749d9..f1c2d03c9eb6 100644 --- a/crypto/openssh/sshbuf-misc.c +++ b/crypto/openssh/sshbuf-misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-misc.c,v 1.2 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: sshbuf-misc.c,v 1.3 2015/02/05 12:59:57 millert Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -22,6 +22,9 @@ #include #include #include +#ifdef HAVE_STDINT_H +#include +#endif #include #include #include diff --git a/crypto/openssh/sshbuf.c b/crypto/openssh/sshbuf.c index 78f5340a185b..dbe0c9192e2f 100644 --- a/crypto/openssh/sshbuf.c +++ b/crypto/openssh/sshbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.c,v 1.2 2014/06/25 14:16:09 deraadt Exp $ */ +/* $OpenBSD: sshbuf.c,v 1.3 2015/01/20 23:14:00 deraadt Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -18,8 +18,8 @@ #define SSHBUF_INTERNAL #include "includes.h" +#include /* roundup */ #include -#include #include #include #include diff --git a/crypto/openssh/sshbuf.h b/crypto/openssh/sshbuf.h index 3602bc53f270..eb0d92e10211 100644 --- a/crypto/openssh/sshbuf.h +++ b/crypto/openssh/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.3 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.4 2015/01/14 15:02:39 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -209,6 +209,8 @@ int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, * curve points. */ int sshbuf_put_bignum2_bytes(struct sshbuf *buf, const void *v, size_t len); +int sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, + const u_char **valp, size_t *lenp); #ifdef WITH_OPENSSL int sshbuf_get_bignum2(struct sshbuf *buf, BIGNUM *v); int sshbuf_get_bignum1(struct sshbuf *buf, BIGNUM *v); diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index 88ea7be1e467..44bfa2de1ddd 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.251 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.259 2015/01/28 22:36:00 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -16,6 +16,7 @@ #include "includes.h" __RCSID("$FreeBSD$"); +#include /* roundup */ #include #include #include @@ -64,6 +65,8 @@ __RCSID("$FreeBSD$"); #include "monitor_fdpass.h" #include "ssh2.h" #include "version.h" +#include "authfile.h" +#include "ssherr.h" char *client_version_string = NULL; char *server_version_string = NULL; @@ -626,7 +629,7 @@ ssh_exchange_identification(int timeout_ms) debug("Remote protocol version %d.%d, remote software version %.100s", remote_major, remote_minor, remote_version); - compat_datafellows(remote_version); + active_state->compat = compat_datafellows(remote_version); mismatch = 0; switch (remote_major) { @@ -768,7 +771,7 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr, if (options.proxy_command == NULL) { if (getnameinfo(hostaddr, addrlen, ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) - fatal("check_host_key: getnameinfo failed"); + fatal("%s: getnameinfo failed", __func__); *hostfile_ipaddr = put_host_port(ntop, port); } else { *hostfile_ipaddr = xstrdup("key, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); + fp = sshkey_fingerprint(found->key, + options.fingerprint_hash, SSH_FP_DEFAULT); + ra = sshkey_fingerprint(found->key, + options.fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); logit("WARNING: %s key found for host %s\n" "in %s:%lu\n" "%s key fingerprint %s.", @@ -1379,7 +1430,10 @@ warn_changed_key(Key *host_key) { char *fp; - fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + fp = sshkey_fingerprint(host_key, options.fingerprint_hash, + SSH_FP_DEFAULT); + if (fp == NULL) + fatal("%s: sshkey_fingerprint fail", __func__); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); diff --git a/crypto/openssh/sshconnect1.c b/crypto/openssh/sshconnect1.c index dd12a3af2c72..016abbce5fbd 100644 --- a/crypto/openssh/sshconnect1.c +++ b/crypto/openssh/sshconnect1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect1.c,v 1.76 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: sshconnect1.c,v 1.77 2015/01/14 20:05:27 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -15,11 +15,14 @@ #include "includes.h" +#ifdef WITH_SSH1 + #include #include #include +#include #include #include #include @@ -47,6 +50,7 @@ #include "hostfile.h" #include "auth.h" #include "digest.h" +#include "ssherr.h" /* Session id for the current session. */ u_char session_id[16]; @@ -62,33 +66,38 @@ extern char *__progname; static int try_agent_authentication(void) { - int type; - char *comment; - AuthenticationConnection *auth; + int r, type, agent_fd, ret = 0; u_char response[16]; - u_int i; - Key *key; + size_t i; BIGNUM *challenge; + struct ssh_identitylist *idlist = NULL; /* Get connection to the agent. */ - auth = ssh_get_authentication_connection(); - if (!auth) + if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { + if (r != SSH_ERR_AGENT_NOT_PRESENT) + debug("%s: ssh_get_authentication_socket: %s", + __func__, ssh_err(r)); return 0; + } if ((challenge = BN_new()) == NULL) fatal("try_agent_authentication: BN_new failed"); - /* Loop through identities served by the agent. */ - for (key = ssh_get_first_identity(auth, &comment, 1); - key != NULL; - key = ssh_get_next_identity(auth, &comment, 1)) { + /* Loop through identities served by the agent. */ + if ((r = ssh_fetch_identitylist(agent_fd, 1, &idlist)) != 0) { + if (r != SSH_ERR_AGENT_NO_IDENTITIES) + debug("%s: ssh_fetch_identitylist: %s", + __func__, ssh_err(r)); + goto out; + } + for (i = 0; i < idlist->nkeys; i++) { /* Try this identity. */ - debug("Trying RSA authentication via agent with '%.100s'", comment); - free(comment); + debug("Trying RSA authentication via agent with '%.100s'", + idlist->comments[i]); /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RSA); - packet_put_bignum(key->rsa->n); + packet_put_bignum(idlist->keys[i]->rsa->n); packet_send(); packet_write_wait(); @@ -99,7 +108,6 @@ try_agent_authentication(void) does not support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); - key_free(key); continue; } /* Otherwise it should have sent a challenge. */ @@ -113,16 +121,17 @@ try_agent_authentication(void) debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ - if (!ssh_decrypt_challenge(auth, key, challenge, session_id, 1, response)) { + if ((r = ssh_decrypt_challenge(agent_fd, idlist->keys[i], + challenge, session_id, response)) != 0) { /* * The agent failed to authenticate this identifier * although it advertised it supports this. Just * return a wrong value. */ - logit("Authentication agent failed to decrypt challenge."); + logit("Authentication agent failed to decrypt " + "challenge: %s", ssh_err(r)); explicit_bzero(response, sizeof(response)); } - key_free(key); debug("Sending response to RSA challenge."); /* Send the decrypted challenge back to the server. */ @@ -135,22 +144,25 @@ try_agent_authentication(void) /* Wait for response from the server. */ type = packet_read(); - /* The server returns success if it accepted the authentication. */ + /* + * The server returns success if it accepted the + * authentication. + */ if (type == SSH_SMSG_SUCCESS) { - ssh_close_authentication_connection(auth); - BN_clear_free(challenge); debug("RSA authentication accepted by server."); - return 1; - } - /* Otherwise it should return failure. */ - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error waiting RSA auth response: %d", - type); + ret = 1; + break; + } else if (type != SSH_SMSG_FAILURE) + packet_disconnect("Protocol error waiting RSA auth " + "response: %d", type); } - ssh_close_authentication_connection(auth); + if (ret != 1) + debug("RSA authentication using agent refused."); + out: + ssh_free_identitylist(idlist); + ssh_close_authentication_socket(agent_fd); BN_clear_free(challenge); - debug("RSA authentication using agent refused."); - return 0; + return ret; } /* @@ -755,3 +767,5 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, success: return; /* need statement after label */ } + +#endif /* WITH_SSH1 */ diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 68f7f4fdd2c1..ba56f6433326 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.210 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.223 2015/01/30 11:43:14 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -70,6 +70,7 @@ #include "pathnames.h" #include "uidswap.h" #include "hostfile.h" +#include "ssherr.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -90,10 +91,8 @@ u_int session_id2_len = 0; char *xxx_host; struct sockaddr *xxx_hostaddr; -Kex *xxx_kex = NULL; - static int -verify_host_key_callback(Key *hostkey) +verify_host_key_callback(Key *hostkey, struct ssh *ssh) { if (verify_host_key(xxx_host, xxx_hostaddr, hostkey) == -1) fatal("Host key verification failed."); @@ -131,16 +130,17 @@ order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) } while (0) while ((alg = strsep(&avail, ",")) && *alg != '\0') { - if ((ktype = key_type_from_name(alg)) == KEY_UNSPEC) + if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) fatal("%s: unknown alg %s", __func__, alg); if (lookup_key_in_hostkeys_by_type(hostkeys, - key_type_plain(ktype), NULL)) + sshkey_type_plain(ktype), NULL)) ALG_APPEND(first, alg); else ALG_APPEND(last, alg); } #undef ALG_APPEND - xasprintf(&ret, "%s%s%s", first, *first == '\0' ? "" : ",", last); + xasprintf(&ret, "%s%s%s", first, + (*first == '\0' || *last == '\0') ? "" : ",", last); if (*first != '\0') debug3("%s: prefer hostkeyalgs: %s", __func__, first); @@ -157,7 +157,8 @@ void ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; - Kex *kex; + struct kex *kex; + int r; xxx_host = host; xxx_hostaddr = hostaddr; @@ -204,22 +205,24 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) (time_t)options.rekey_interval); /* start key exchange */ - kex = kex_setup(myproposal); + if ((r = kex_setup(active_state, myproposal)) != 0) + fatal("kex_setup: %s", ssh_err(r)); + kex = active_state->kex; #ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; +# ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kexecdh_client; +# endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; - xxx_kex = kex; - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); + dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); if (options.use_roaming && !kex->roaming) { debug("Roaming not allowed by server"); @@ -242,15 +245,15 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) * Authenticate user */ -typedef struct Authctxt Authctxt; -typedef struct Authmethod Authmethod; +typedef struct cauthctxt Authctxt; +typedef struct cauthmethod Authmethod; typedef struct identity Identity; typedef struct idlist Idlist; struct identity { TAILQ_ENTRY(identity) next; - AuthenticationConnection *ac; /* set if agent supports key */ - Key *key; /* public/private key */ + int agent_fd; /* >=0 if agent supports key */ + struct sshkey *key; /* public/private key */ char *filename; /* comment for agent-only keys */ int tried; int isprivate; /* key points to the private key */ @@ -258,25 +261,29 @@ struct identity { }; TAILQ_HEAD(idlist, identity); -struct Authctxt { +struct cauthctxt { const char *server_user; const char *local_user; const char *host; const char *service; - Authmethod *method; + struct cauthmethod *method; sig_atomic_t success; char *authlist; + int attempt; /* pubkey */ - Idlist keys; - AuthenticationConnection *agent; + struct idlist keys; + int agent_fd; /* hostbased */ Sensitive *sensitive; + char *oktypes, *ktypes; + const char *active_ktype; /* kbd-interactive */ int info_req_seen; /* generic */ void *methoddata; }; -struct Authmethod { + +struct cauthmethod { char *name; /* string to compare against server's list */ int (*userauth)(Authctxt *authctxt); void (*cleanup)(Authctxt *authctxt); @@ -284,14 +291,14 @@ struct Authmethod { int *batch_flag; /* flag in option struct that disables method */ }; -void input_userauth_success(int, u_int32_t, void *); -void input_userauth_success_unexpected(int, u_int32_t, void *); -void input_userauth_failure(int, u_int32_t, void *); -void input_userauth_banner(int, u_int32_t, void *); -void input_userauth_error(int, u_int32_t, void *); -void input_userauth_info_req(int, u_int32_t, void *); -void input_userauth_pk_ok(int, u_int32_t, void *); -void input_userauth_passwd_changereq(int, u_int32_t, void *); +int input_userauth_success(int, u_int32_t, void *); +int input_userauth_success_unexpected(int, u_int32_t, void *); +int input_userauth_failure(int, u_int32_t, void *); +int input_userauth_banner(int, u_int32_t, void *); +int input_userauth_error(int, u_int32_t, void *); +int input_userauth_info_req(int, u_int32_t, void *); +int input_userauth_pk_ok(int, u_int32_t, void *); +int input_userauth_passwd_changereq(int, u_int32_t, void *); int userauth_none(Authctxt *); int userauth_pubkey(Authctxt *); @@ -301,11 +308,11 @@ int userauth_hostbased(Authctxt *); #ifdef GSSAPI int userauth_gssapi(Authctxt *authctxt); -void input_gssapi_response(int type, u_int32_t, void *); -void input_gssapi_token(int type, u_int32_t, void *); -void input_gssapi_hash(int type, u_int32_t, void *); -void input_gssapi_error(int, u_int32_t, void *); -void input_gssapi_errtok(int, u_int32_t, void *); +int input_gssapi_response(int type, u_int32_t, void *); +int input_gssapi_token(int type, u_int32_t, void *); +int input_gssapi_hash(int type, u_int32_t, void *); +int input_gssapi_error(int, u_int32_t, void *); +int input_gssapi_errtok(int, u_int32_t, void *); #endif void userauth(Authctxt *, char *); @@ -398,7 +405,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, authctxt.authlist = NULL; authctxt.methoddata = NULL; authctxt.sensitive = sensitive; + authctxt.active_ktype = authctxt.oktypes = authctxt.ktypes = NULL; authctxt.info_req_seen = 0; + authctxt.agent_fd = -1; if (authctxt.method == NULL) fatal("ssh_userauth2: internal error: cannot send userauth none request"); @@ -453,15 +462,16 @@ userauth(Authctxt *authctxt, char *authlist) } /* ARGSUSED */ -void +int input_userauth_error(int type, u_int32_t seq, void *ctxt) { fatal("input_userauth_error: bad message during authentication: " "type %d", type); + return 0; } /* ARGSUSED */ -void +int input_userauth_banner(int type, u_int32_t seq, void *ctxt) { char *msg, *raw, *lang; @@ -480,10 +490,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt) } free(raw); free(lang); + return 0; } /* ARGSUSED */ -void +int input_userauth_success(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -497,9 +508,10 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt) free(authctxt->methoddata); authctxt->methoddata = NULL; authctxt->success = 1; /* break out */ + return 0; } -void +int input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -509,10 +521,11 @@ input_userauth_success_unexpected(int type, u_int32_t seq, void *ctxt) fatal("Unexpected authentication success during %s.", authctxt->method->name); + return 0; } /* ARGSUSED */ -void +int input_userauth_failure(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -535,10 +548,11 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt) debug("Authentications that can continue: %s", authlist); userauth(authctxt, authlist); + return 0; } /* ARGSUSED */ -void +int input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -582,7 +596,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) key->type, pktype); goto done; } - fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + goto done; debug2("input_userauth_pk_ok: fp %s", fp); free(fp); @@ -606,6 +622,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) /* try another method if we did not send a packet */ if (sent == 0) userauth(authctxt, NULL); + return 0; } #ifdef GSSAPI @@ -721,7 +738,7 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) } /* ARGSUSED */ -void +int input_gssapi_response(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -742,7 +759,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) free(oidv); debug("Badly encoded mechanism OID received"); userauth(authctxt, NULL); - return; + return 0; } if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2)) @@ -756,12 +773,13 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) /* Start again with next method on list */ debug("Trying to start again"); userauth(authctxt, NULL); - return; + return 0; } + return 0; } /* ARGSUSED */ -void +int input_gssapi_token(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -784,12 +802,13 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt) if (GSS_ERROR(status)) { /* Start again with the next method in the list */ userauth(authctxt, NULL); - return; + return 0; } + return 0; } /* ARGSUSED */ -void +int input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) { Authctxt *authctxt = ctxt; @@ -816,10 +835,11 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) gss_release_buffer(&ms, &send_tok); /* Server will be returning a failed packet after this one */ + return 0; } /* ARGSUSED */ -void +int input_gssapi_error(int type, u_int32_t plen, void *ctxt) { char *msg; @@ -835,6 +855,7 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) debug("Server GSSAPI Error:\n%s", msg); free(msg); free(lang); + return 0; } #endif /* GSSAPI */ @@ -889,7 +910,7 @@ userauth_passwd(Authctxt *authctxt) * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */ /* ARGSUSED */ -void +int input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) { Authctxt *authctxt = ctxt; @@ -930,7 +951,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) password = read_passphrase(prompt, RP_ALLOW_EOF); if (password == NULL) { /* bail out */ - return; + return 0; } snprintf(prompt, sizeof(prompt), "Retype %.30s@%.128s's new password: ", @@ -953,30 +974,33 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, &input_userauth_passwd_changereq); + return 0; } static int -identity_sign(Identity *id, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) +identity_sign(struct identity *id, u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen, u_int compat) { Key *prv; int ret; /* the agent supports this key */ - if (id->ac) - return (ssh_agent_sign(id->ac, id->key, sigp, lenp, - data, datalen)); + if (id->agent_fd) + return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, + data, datalen, compat); + /* * we have already loaded the private key or * the private key is stored in external hardware */ if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT)) - return (key_sign(id->key, sigp, lenp, data, datalen)); + return (sshkey_sign(id->key, sigp, lenp, data, datalen, + compat)); /* load the private key from the file */ if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL) - return (-1); - ret = key_sign(prv, sigp, lenp, data, datalen); - key_free(prv); + return (-1); /* XXX return decent error code */ + ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat); + sshkey_free(prv); return (ret); } @@ -985,13 +1009,16 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) { Buffer b; u_char *blob, *signature; - u_int bloblen, slen; + u_int bloblen; + size_t slen; u_int skip = 0; int ret = -1; int have_sig = 1; char *fp; - fp = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); + if ((fp = sshkey_fingerprint(id->key, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + return 0; debug3("sign_and_send_pubkey: %s %s", key_type(id->key), fp); free(fp); @@ -1026,8 +1053,8 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) /* generate signature */ ret = identity_sign(id, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - if (ret == -1) { + buffer_ptr(&b), buffer_len(&b), datafellows); + if (ret != 0) { free(blob); buffer_free(&b); return 0; @@ -1102,7 +1129,7 @@ load_identity_file(char *filename, int userprovided) { Key *private; char prompt[300], *passphrase; - int perm_ok = 0, quit, i; + int r, perm_ok = 0, quit = 0, i; struct stat st; if (stat(filename, &st) < 0) { @@ -1110,33 +1137,50 @@ load_identity_file(char *filename, int userprovided) filename, strerror(errno)); return NULL; } - private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok); - if (!perm_ok) { - if (private != NULL) - key_free(private); - return NULL; - } - if (private == NULL) { - if (options.batch_mode) - return NULL; - snprintf(prompt, sizeof prompt, - "Enter passphrase for key '%.100s': ", filename); - for (i = 0; i < options.number_of_password_prompts; i++) { + snprintf(prompt, sizeof prompt, + "Enter passphrase for key '%.100s': ", filename); + for (i = 0; i <= options.number_of_password_prompts; i++) { + if (i == 0) + passphrase = ""; + else { passphrase = read_passphrase(prompt, 0); - if (strcmp(passphrase, "") != 0) { - private = key_load_private_type(KEY_UNSPEC, - filename, passphrase, NULL, NULL); - quit = 0; - } else { + if (*passphrase == '\0') { debug2("no passphrase given, try next key"); - quit = 1; + free(passphrase); + break; } + } + switch ((r = sshkey_load_private_type(KEY_UNSPEC, filename, + passphrase, &private, NULL, &perm_ok))) { + case 0: + break; + case SSH_ERR_KEY_WRONG_PASSPHRASE: + if (options.batch_mode) { + quit = 1; + break; + } + if (i != 0) + debug2("bad passphrase given, try again..."); + break; + case SSH_ERR_SYSTEM_ERROR: + if (errno == ENOENT) { + debug2("Load key \"%s\": %s", + filename, ssh_err(r)); + quit = 1; + break; + } + /* FALLTHROUGH */ + default: + error("Load key \"%s\": %s", filename, ssh_err(r)); + quit = 1; + break; + } + if (i > 0) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); - if (private != NULL || quit) - break; - debug2("bad passphrase given, try again..."); } + if (private != NULL || quit) + break; } return private; } @@ -1150,12 +1194,12 @@ load_identity_file(char *filename, int userprovided) static void pubkey_prepare(Authctxt *authctxt) { - Identity *id, *id2, *tmp; - Idlist agent, files, *preferred; - Key *key; - AuthenticationConnection *ac; - char *comment; - int i, found; + struct identity *id, *id2, *tmp; + struct idlist agent, files, *preferred; + struct sshkey *key; + int agent_fd, i, r, found; + size_t j; + struct ssh_identitylist *idlist; TAILQ_INIT(&agent); /* keys from the agent */ TAILQ_INIT(&files); /* keys from the config file */ @@ -1185,7 +1229,7 @@ pubkey_prepare(Authctxt *authctxt) if (id2->key == NULL || (id2->key->flags & SSHKEY_FLAG_EXT) == 0) continue; - if (key_equal(id->key, id2->key)) { + if (sshkey_equal(id->key, id2->key)) { TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); found = 1; @@ -1200,37 +1244,48 @@ pubkey_prepare(Authctxt *authctxt) } } /* list of keys supported by the agent */ - if ((ac = ssh_get_authentication_connection())) { - for (key = ssh_get_first_identity(ac, &comment, 2); - key != NULL; - key = ssh_get_next_identity(ac, &comment, 2)) { + if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { + if (r != SSH_ERR_AGENT_NOT_PRESENT) + debug("%s: ssh_get_authentication_socket: %s", + __func__, ssh_err(r)); + } else if ((r = ssh_fetch_identitylist(agent_fd, 2, &idlist)) != 0) { + if (r != SSH_ERR_AGENT_NO_IDENTITIES) + debug("%s: ssh_fetch_identitylist: %s", + __func__, ssh_err(r)); + } else { + for (j = 0; j < idlist->nkeys; j++) { found = 0; TAILQ_FOREACH(id, &files, next) { - /* agent keys from the config file are preferred */ - if (key_equal(key, id->key)) { - key_free(key); - free(comment); + /* + * agent keys from the config file are + * preferred + */ + if (sshkey_equal(idlist->keys[j], id->key)) { TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); - id->ac = ac; + id->agent_fd = agent_fd; found = 1; break; } } if (!found && !options.identities_only) { id = xcalloc(1, sizeof(*id)); - id->key = key; - id->filename = comment; - id->ac = ac; + /* XXX "steals" key/comment from idlist */ + id->key = idlist->keys[j]; + id->filename = idlist->comments[j]; + idlist->keys[j] = NULL; + idlist->comments[j] = NULL; + id->agent_fd = agent_fd; TAILQ_INSERT_TAIL(&agent, id, next); } } + ssh_free_identitylist(idlist); /* append remaining agent keys */ for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) { TAILQ_REMOVE(&agent, id, next); TAILQ_INSERT_TAIL(preferred, id, next); } - authctxt->agent = ac; + authctxt->agent_fd = agent_fd; } /* append remaining keys from the config file */ for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { @@ -1248,13 +1303,13 @@ pubkey_cleanup(Authctxt *authctxt) { Identity *id; - if (authctxt->agent != NULL) - ssh_close_authentication_connection(authctxt->agent); + if (authctxt->agent_fd != -1) + ssh_close_authentication_socket(authctxt->agent_fd); for (id = TAILQ_FIRST(&authctxt->keys); id; id = TAILQ_FIRST(&authctxt->keys)) { TAILQ_REMOVE(&authctxt->keys, id, next); if (id->key) - key_free(id->key); + sshkey_free(id->key); free(id->filename); free(id); } @@ -1346,7 +1401,7 @@ userauth_kbdint(Authctxt *authctxt) /* * parse INFO_REQUEST, prompt user and send INFO_RESPONSE */ -void +int input_userauth_info_req(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; @@ -1398,81 +1453,120 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) packet_add_padding(64); packet_send(); + return 0; } static int -ssh_keysign(Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) +ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, + const u_char *data, size_t datalen) { - Buffer b; + struct sshbuf *b; struct stat st; pid_t pid; - int to[2], from[2], status, version = 2; + int i, r, to[2], from[2], status, sock = packet_get_connection_in(); + u_char rversion = 0, version = 2; + void (*osigchld)(int); - debug2("ssh_keysign called"); + *sigp = NULL; + *lenp = 0; if (stat(_PATH_SSH_KEY_SIGN, &st) < 0) { - error("ssh_keysign: not installed: %s", strerror(errno)); + error("%s: not installed: %s", __func__, strerror(errno)); + return -1; + } + if (fflush(stdout) != 0) { + error("%s: fflush: %s", __func__, strerror(errno)); return -1; } - if (fflush(stdout) != 0) - error("ssh_keysign: fflush: %s", strerror(errno)); if (pipe(to) < 0) { - error("ssh_keysign: pipe: %s", strerror(errno)); + error("%s: pipe: %s", __func__, strerror(errno)); return -1; } if (pipe(from) < 0) { - error("ssh_keysign: pipe: %s", strerror(errno)); + error("%s: pipe: %s", __func__, strerror(errno)); return -1; } if ((pid = fork()) < 0) { - error("ssh_keysign: fork: %s", strerror(errno)); + error("%s: fork: %s", __func__, strerror(errno)); return -1; } + osigchld = signal(SIGCHLD, SIG_DFL); if (pid == 0) { /* keep the socket on exec */ - fcntl(packet_get_connection_in(), F_SETFD, 0); + fcntl(sock, F_SETFD, 0); permanently_drop_suid(getuid()); close(from[0]); if (dup2(from[1], STDOUT_FILENO) < 0) - fatal("ssh_keysign: dup2: %s", strerror(errno)); + fatal("%s: dup2: %s", __func__, strerror(errno)); close(to[1]); if (dup2(to[0], STDIN_FILENO) < 0) - fatal("ssh_keysign: dup2: %s", strerror(errno)); + fatal("%s: dup2: %s", __func__, strerror(errno)); close(from[1]); close(to[0]); + /* Close everything but stdio and the socket */ + for (i = STDERR_FILENO + 1; i < sock; i++) + close(i); + closefrom(sock + 1); + debug3("%s: [child] pid=%ld, exec %s", + __func__, (long)getpid(), _PATH_SSH_KEY_SIGN); execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *) 0); - fatal("ssh_keysign: exec(%s): %s", _PATH_SSH_KEY_SIGN, + fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN, strerror(errno)); } close(from[1]); close(to[0]); - buffer_init(&b); - buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ - buffer_put_string(&b, data, datalen); - if (ssh_msg_send(to[1], version, &b) == -1) - fatal("ssh_keysign: couldn't send request"); - - if (ssh_msg_recv(from[0], &b) < 0) { - error("ssh_keysign: no reply"); - buffer_free(&b); - return -1; - } + if ((b = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + /* send # of sock, data to be signed */ + if ((r = sshbuf_put_u32(b, sock) != 0) || + (r = sshbuf_put_string(b, data, datalen)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + if (ssh_msg_send(to[1], version, b) == -1) + fatal("%s: couldn't send request", __func__); + sshbuf_reset(b); + r = ssh_msg_recv(from[0], b); close(from[0]); close(to[1]); + if (r < 0) { + error("%s: no reply", __func__); + goto fail; + } - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - - if (buffer_get_char(&b) != version) { - error("ssh_keysign: bad version"); - buffer_free(&b); + errno = 0; + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + error("%s: waitpid %ld: %s", + __func__, (long)pid, strerror(errno)); + goto fail; + } + } + if (!WIFEXITED(status)) { + error("%s: exited abnormally", __func__); + goto fail; + } + if (WEXITSTATUS(status) != 0) { + error("%s: exited with status %d", + __func__, WEXITSTATUS(status)); + goto fail; + } + if ((r = sshbuf_get_u8(b, &rversion)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + goto fail; + } + if (rversion != version) { + error("%s: bad version", __func__); + goto fail; + } + if ((r = sshbuf_get_string(b, sigp, lenp)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + fail: + signal(SIGCHLD, osigchld); + sshbuf_free(b); return -1; } - *sigp = buffer_get_string(&b, lenp); - buffer_free(&b); + signal(SIGCHLD, osigchld); + sshbuf_free(b); return 0; } @@ -1480,94 +1574,149 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, int userauth_hostbased(Authctxt *authctxt) { - Key *private = NULL; - Sensitive *sensitive = authctxt->sensitive; - Buffer b; - u_char *signature, *blob; - char *chost, *pkalg, *p; + struct ssh *ssh = active_state; + struct sshkey *private = NULL; + struct sshbuf *b = NULL; const char *service; - u_int blen, slen; - int ok, i, found = 0; + u_char *sig = NULL, *keyblob = NULL; + char *fp = NULL, *chost = NULL, *lname = NULL; + size_t siglen = 0, keylen = 0; + int i, r, success = 0; - /* check for a useful key */ - for (i = 0; i < sensitive->nkeys; i++) { - private = sensitive->keys[i]; - if (private && private->type != KEY_RSA1) { - found = 1; + if (authctxt->ktypes == NULL) { + authctxt->oktypes = xstrdup(options.hostbased_key_types); + authctxt->ktypes = authctxt->oktypes; + } + + /* + * Work through each listed type pattern in HostbasedKeyTypes, + * trying each hostkey that matches the type in turn. + */ + for (;;) { + if (authctxt->active_ktype == NULL) + authctxt->active_ktype = strsep(&authctxt->ktypes, ","); + if (authctxt->active_ktype == NULL || + *authctxt->active_ktype == '\0') + break; + debug3("%s: trying key type %s", __func__, + authctxt->active_ktype); + + /* check for a useful key */ + private = NULL; + for (i = 0; i < authctxt->sensitive->nkeys; i++) { + if (authctxt->sensitive->keys[i] == NULL || + authctxt->sensitive->keys[i]->type == KEY_RSA1 || + authctxt->sensitive->keys[i]->type == KEY_UNSPEC) + continue; + if (match_pattern_list( + sshkey_ssh_name(authctxt->sensitive->keys[i]), + authctxt->active_ktype, + strlen(authctxt->active_ktype), 0) != 1) + continue; /* we take and free the key */ - sensitive->keys[i] = NULL; + private = authctxt->sensitive->keys[i]; + authctxt->sensitive->keys[i] = NULL; break; } + /* Found one */ + if (private != NULL) + break; + /* No more keys of this type; advance */ + authctxt->active_ktype = NULL; } - if (!found) { + if (private == NULL) { + free(authctxt->oktypes); + authctxt->oktypes = authctxt->ktypes = NULL; + authctxt->active_ktype = NULL; debug("No more client hostkeys for hostbased authentication."); - return 0; + goto out; } - if (key_to_blob(private, &blob, &blen) == 0) { - key_free(private); - return 0; + + if ((fp = sshkey_fingerprint(private, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) { + error("%s: sshkey_fingerprint failed", __func__); + goto out; } + debug("%s: trying hostkey %s %s", + __func__, sshkey_ssh_name(private), fp); + /* figure out a name for the client host */ - p = get_local_name(packet_get_connection_in()); - if (p == NULL) { - error("userauth_hostbased: cannot get local ipaddr/name"); - key_free(private); - free(blob); - return 0; + if ((lname = get_local_name(packet_get_connection_in())) == NULL) { + error("%s: cannot get local ipaddr/name", __func__); + goto out; } - xasprintf(&chost, "%s.", p); - debug2("userauth_hostbased: chost %s", chost); - free(p); + + /* XXX sshbuf_put_stringf? */ + xasprintf(&chost, "%s.", lname); + debug2("%s: chost %s", __func__, chost); service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : authctxt->service; - pkalg = xstrdup(key_ssh_name(private)); - buffer_init(&b); - /* construct data */ - buffer_put_string(&b, session_id2, session_id2_len); - buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); - buffer_put_cstring(&b, authctxt->server_user); - buffer_put_cstring(&b, service); - buffer_put_cstring(&b, authctxt->method->name); - buffer_put_cstring(&b, pkalg); - buffer_put_string(&b, blob, blen); - buffer_put_cstring(&b, chost); - buffer_put_cstring(&b, authctxt->local_user); -#ifdef DEBUG_PK - buffer_dump(&b); -#endif - if (sensitive->external_keysign) - ok = ssh_keysign(private, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - else - ok = key_sign(private, &signature, &slen, - buffer_ptr(&b), buffer_len(&b)); - key_free(private); - buffer_free(&b); - if (ok != 0) { - error("key_sign failed"); - free(chost); - free(pkalg); - free(blob); - return 0; - } - packet_start(SSH2_MSG_USERAUTH_REQUEST); - packet_put_cstring(authctxt->server_user); - packet_put_cstring(authctxt->service); - packet_put_cstring(authctxt->method->name); - packet_put_cstring(pkalg); - packet_put_string(blob, blen); - packet_put_cstring(chost); - packet_put_cstring(authctxt->local_user); - packet_put_string(signature, slen); - explicit_bzero(signature, slen); - free(signature); - free(chost); - free(pkalg); - free(blob); - packet_send(); - return 1; + /* construct data */ + if ((b = sshbuf_new()) == NULL) { + error("%s: sshbuf_new failed", __func__); + goto out; + } + if ((r = sshkey_to_blob(private, &keyblob, &keylen)) != 0) { + error("%s: sshkey_to_blob: %s", __func__, ssh_err(r)); + goto out; + } + if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 || + (r = sshbuf_put_cstring(b, service)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->method->name)) != 0 || + (r = sshbuf_put_cstring(b, key_ssh_name(private))) != 0 || + (r = sshbuf_put_string(b, keyblob, keylen)) != 0 || + (r = sshbuf_put_cstring(b, chost)) != 0 || + (r = sshbuf_put_cstring(b, authctxt->local_user)) != 0) { + error("%s: buffer error: %s", __func__, ssh_err(r)); + goto out; + } + +#ifdef DEBUG_PK + sshbuf_dump(b, stderr); +#endif + if (authctxt->sensitive->external_keysign) + r = ssh_keysign(private, &sig, &siglen, + sshbuf_ptr(b), sshbuf_len(b)); + else if ((r = sshkey_sign(private, &sig, &siglen, + sshbuf_ptr(b), sshbuf_len(b), datafellows)) != 0) + debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); + if (r != 0) { + error("sign using hostkey %s %s failed", + sshkey_ssh_name(private), fp); + goto out; + } + if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || + (r = sshpkt_put_cstring(ssh, key_ssh_name(private))) != 0 || + (r = sshpkt_put_string(ssh, keyblob, keylen)) != 0 || + (r = sshpkt_put_cstring(ssh, chost)) != 0 || + (r = sshpkt_put_cstring(ssh, authctxt->local_user)) != 0 || + (r = sshpkt_put_string(ssh, sig, siglen)) != 0 || + (r = sshpkt_send(ssh)) != 0) { + error("%s: packet error: %s", __func__, ssh_err(r)); + goto out; + } + success = 1; + + out: + if (sig != NULL) { + explicit_bzero(sig, siglen); + free(sig); + } + free(keyblob); + free(lname); + free(fp); + free(chost); + sshkey_free(private); + sshbuf_free(b); + + return success; } /* find auth method */ diff --git a/crypto/openssh/sshd.0 b/crypto/openssh/sshd.0 index 7d007557067d..be6c98e98df9 100644 --- a/crypto/openssh/sshd.0 +++ b/crypto/openssh/sshd.0 @@ -1,7 +1,7 @@ SSHD(8) System Manager's Manual SSHD(8) NAME - sshd - OpenSSH SSH daemon + sshd M-bM-^@M-^S OpenSSH SSH daemon SYNOPSIS sshd [-46DdeiqTt] [-b bits] [-C connection_spec] @@ -41,10 +41,9 @@ DESCRIPTION file that would apply to the specified user, host, and address will be set before the configuration is written to standard output. The connection parameters are supplied as keyword=value - pairs. The keywords are ``user'', ``host'', ``laddr'', - ``lport'', and ``addr''. All are required and may be supplied in - any order, either with multiple -C options or as a comma- - separated list. + pairs. The keywords are M-bM-^@M-^\userM-bM-^@M-^], M-bM-^@M-^\hostM-bM-^@M-^], M-bM-^@M-^\laddrM-bM-^@M-^], M-bM-^@M-^\lportM-bM-^@M-^], and + M-bM-^@M-^\addrM-bM-^@M-^]. All are required and may be supplied in any order, + either with multiple -C options or as a comma-separated list. -c host_certificate_file Specifies a path to a certificate file to identify sshd during @@ -148,7 +147,7 @@ DESCRIPTION AUTHENTICATION The OpenSSH SSH daemon supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the Protocol option - in sshd_config(5). Protocol 2 supports DSA, ECDSA, ED25519 and RSA keys; + in sshd_config(5). Protocol 2 supports DSA, ECDSA, Ed25519 and RSA keys; protocol 1 only supports RSA keys. For both protocols, each host has a host-specific key, normally 2048 bits, used to identify the host. @@ -185,11 +184,11 @@ AUTHENTICATION listed in DenyUsers or its group is listed in DenyGroups . The definition of a locked account is system dependant. Some platforms have their own account database (eg AIX) and some modify the passwd field ( - `*LK*' on Solaris and UnixWare, `*' on HP-UX, containing `Nologin' on - Tru64, a leading `*LOCKED*' on FreeBSD and a leading `!' on most + M-bM-^@M-^X*LK*M-bM-^@M-^Y on Solaris and UnixWare, M-bM-^@M-^X*M-bM-^@M-^Y on HP-UX, containing M-bM-^@M-^XNologinM-bM-^@M-^Y on + Tru64, a leading M-bM-^@M-^X*LOCKED*M-bM-^@M-^Y on FreeBSD and a leading M-bM-^@M-^X!M-bM-^@M-^Y on most Linuxes). If there is a requirement to disable password authentication for the account while allowing still public-key, then the passwd field - should be set to something other than these values (eg `NP' or `*NP*' ). + should be set to something other than these values (eg M-bM-^@M-^XNPM-bM-^@M-^Y or M-bM-^@M-^X*NP*M-bM-^@M-^Y ). If the client successfully authenticates itself, a dialog for preparing the session is entered. At this time the client may request things like @@ -230,7 +229,7 @@ LOGIN PROCESS 8. If ~/.ssh/rc exists and the sshd_config(5) PermitUserRC option is set, runs it; else if /etc/ssh/sshrc exists, runs it; - otherwise runs xauth. The ``rc'' files are given the X11 + otherwise runs xauth. The M-bM-^@M-^\rcM-bM-^@M-^] files are given the X11 authentication protocol and cookie in standard input. See SSHRC, below. @@ -270,7 +269,7 @@ AUTHORIZED_KEYS FILE FORMAT AuthorizedKeysFile specifies the files containing public keys for public key authentication; if none is specified, the default is ~/.ssh/authorized_keys and ~/.ssh/authorized_keys2. Each line of the - file contains one key (empty lines and lines starting with a `#' are + file contains one key (empty lines and lines starting with a M-bM-^@M-^X#M-bM-^@M-^Y are ignored as comments). Protocol 1 public keys consist of the following space-separated fields: options, bits, exponent, modulus, comment. Protocol 2 public key consist of: options, keytype, base64-encoded key, @@ -279,9 +278,9 @@ AUTHORIZED_KEYS FILE FORMAT starts with a number). The bits, exponent, modulus, and comment fields give the RSA key for protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). - For protocol version 2 the keytype is ``ecdsa-sha2-nistp256'', - ``ecdsa-sha2-nistp384'', ``ecdsa-sha2-nistp521'', ``ssh-ed25519'', - ``ssh-dss'' or ``ssh-rsa''. + For protocol version 2 the keytype is M-bM-^@M-^\ecdsa-sha2-nistp256M-bM-^@M-^], + M-bM-^@M-^\ecdsa-sha2-nistp384M-bM-^@M-^], M-bM-^@M-^\ecdsa-sha2-nistp521M-bM-^@M-^], M-bM-^@M-^\ssh-ed25519M-bM-^@M-^], M-bM-^@M-^\ssh-dssM-bM-^@M-^] or + M-bM-^@M-^\ssh-rsaM-bM-^@M-^]. Note that lines in this file are usually several hundred bytes long (because of the size of the public key encoding) up to a limit of 8 @@ -370,7 +369,7 @@ AUTHORIZED_KEYS FILE FORMAT Any X11 forward requests by the client will return an error. permitopen="host:port" - Limit local ``ssh -L'' port forwarding such that it may only + Limit local port forwarding with ssh(1) -L such that it may only connect to the specified host and port. IPv6 addresses can be specified by enclosing the address in square brackets. Multiple permitopen options may be applied separated by commas. No @@ -416,23 +415,23 @@ SSH_KNOWN_HOSTS FILE FORMAT separated by spaces. The marker is optional, but if it is present then it must be one of - ``@cert-authority'', to indicate that the line contains a certification - authority (CA) key, or ``@revoked'', to indicate that the key contained - on the line is revoked and must not ever be accepted. Only one marker + M-bM-^@M-^\@cert-authorityM-bM-^@M-^], to indicate that the line contains a certification + authority (CA) key, or M-bM-^@M-^\@revokedM-bM-^@M-^], to indicate that the key contained on + the line is revoked and must not ever be accepted. Only one marker should be used on a key line. - Hostnames is a comma-separated list of patterns (`*' and `?' act as + Hostnames is a comma-separated list of patterns (M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y act as wildcards); each pattern in turn is matched against the canonical host name (when authenticating a client) or against the user-supplied name - (when authenticating a server). A pattern may also be preceded by `!' to + (when authenticating a server). A pattern may also be preceded by M-bM-^@M-^X!M-bM-^@M-^Y to indicate negation: if the host name matches a negated pattern, it is not accepted (by that line) even if it matched another pattern on the line. - A hostname or address may optionally be enclosed within `[' and `]' - brackets then followed by `:' and a non-standard port number. + A hostname or address may optionally be enclosed within M-bM-^@M-^X[M-bM-^@M-^Y and M-bM-^@M-^X]M-bM-^@M-^Y + brackets then followed by M-bM-^@M-^X:M-bM-^@M-^Y and a non-standard port number. Alternately, hostnames may be stored in a hashed form which hides host names and addresses should the file's contents be disclosed. Hashed - hostnames start with a `|' character. Only one hashed hostname may + hostnames start with a M-bM-^@M-^X|M-bM-^@M-^Y character. Only one hashed hostname may appear on a single line and none of the above negation or wildcard operators may be applied. @@ -440,21 +439,21 @@ SSH_KNOWN_HOSTS FILE FORMAT they can be obtained, for example, from /etc/ssh/ssh_host_key.pub. The optional comment field continues to the end of the line, and is not used. - Lines starting with `#' and empty lines are ignored as comments. + Lines starting with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines are ignored as comments. When performing host authentication, authentication is accepted if any matching line has the proper key; either one that matches exactly or, if the server has presented a certificate for authentication, the key of the certification authority that signed the certificate. For a key to be - trusted as a certification authority, it must use the ``@cert-authority'' + trusted as a certification authority, it must use the M-bM-^@M-^\@cert-authorityM-bM-^@M-^] marker described above. The known hosts file also provides a facility to mark keys as revoked, for example when it is known that the associated private key has been - stolen. Revoked keys are specified by including the ``@revoked'' marker - at the beginning of the key line, and are never accepted for - authentication or as certification authorities, but instead will produce - a warning from ssh(1) when they are encountered. + stolen. Revoked keys are specified by including the M-bM-^@M-^\@revokedM-bM-^@M-^] marker at + the beginning of the key line, and are never accepted for authentication + or as certification authorities, but instead will produce a warning from + ssh(1) when they are encountered. It is permissible (but not recommended) to have several lines or different host keys for the same names. This will inevitably happen when @@ -514,7 +513,7 @@ FILES for the user, and not accessible by others. ~/.ssh/authorized_keys - Lists the public keys (DSA, ECDSA, ED25519, RSA) that can be used + Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described above. The content of the file is not highly sensitive, but the recommended permissions are read/write for the @@ -524,12 +523,12 @@ FILES are writable by other users, then the file could be modified or replaced by unauthorized users. In this case, sshd will not allow it to be used unless the StrictModes option has been set to - ``no''. + M-bM-^@M-^\noM-bM-^@M-^]. ~/.ssh/environment This file is read into the environment at login (if it exists). It can only contain empty lines, comment lines (that start with - `#'), and assignment lines of the form name=value. The file + M-bM-^@M-^X#M-bM-^@M-^Y), and assignment lines of the form name=value. The file should be writable only by the user; it need not be readable by anyone else. Environment processing is disabled by default and is controlled via the PermitUserEnvironment option. @@ -637,4 +636,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 5.6 July 3, 2014 OpenBSD 5.6 +OpenBSD 5.7 November 15, 2014 OpenBSD 5.7 diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 index 87ee16af3824..affe25c0588b 100644 --- a/crypto/openssh/sshd.8 +++ b/crypto/openssh/sshd.8 @@ -33,9 +33,9 @@ .\" (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.276 2014/07/03 22:40:43 djm Exp $ +.\" $OpenBSD: sshd.8,v 1.278 2014/11/15 14:41:03 bentley Exp $ .\" $FreeBSD$ -.Dd $Mdocdate: July 3 2014 $ +.Dd $Mdocdate: November 15 2014 $ .Dt SSHD 8 .Os .Sh NAME @@ -279,7 +279,7 @@ though this can be changed via the .Cm Protocol option in .Xr sshd_config 5 . -Protocol 2 supports DSA, ECDSA, ED25519 and RSA keys; +Protocol 2 supports DSA, ECDSA, Ed25519 and RSA keys; protocol 1 only supports RSA keys. For both protocols, each host has a host-specific key, @@ -607,10 +607,10 @@ Disables execution of Forbids X11 forwarding when this key is used for authentication. Any X11 forward requests by the client will return an error. .It Cm permitopen="host:port" -Limit local -.Li ``ssh -L'' -port forwarding such that it may only connect to the specified host and -port. +Limit local port forwarding with +.Xr ssh 1 +.Fl L +such that it may only connect to the specified host and port. IPv6 addresses can be specified by enclosing the address in square brackets. Multiple .Cm permitopen @@ -811,7 +811,7 @@ secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp .It Pa ~/.ssh/authorized_keys -Lists the public keys (DSA, ECDSA, ED25519, RSA) +Lists the public keys (DSA, ECDSA, Ed25519, RSA) that can be used for logging in as this user. The format of this file is described above. The content of the file is not highly sensitive, but the recommended diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 65dfc220c8fc..7bdf84cc22b0 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.428 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: sshd.c,v 1.444 2015/02/20 22:17:21 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -73,6 +73,7 @@ __RCSID("$FreeBSD$"); #include #include #include +#include #ifdef WITH_OPENSSL #include @@ -133,6 +134,7 @@ __RCSID("$FreeBSD$"); #include "roaming.h" #include "ssh-sandbox.h" #include "version.h" +#include "ssherr.h" #ifdef LIBWRAP #include @@ -204,11 +206,8 @@ int num_listen_socks = 0; char *client_version_string = NULL; char *server_version_string = NULL; -/* for rekeying XXX fixme */ -Kex *xxx_kex; - /* Daemon's agent connection */ -AuthenticationConnection *auth_conn = NULL; +int auth_sock = -1; int have_agent = 0; /* @@ -248,7 +247,7 @@ u_char *session_id2 = NULL; u_int session_id2_len = 0; /* record remote hostname or ip */ -u_int utmp_len = MAXHOSTNAMELEN; +u_int utmp_len = HOST_NAME_MAX+1; /* options.max_startup sized array of fd ints */ int *startup_pipes = NULL; @@ -504,7 +503,7 @@ sshd_exchange_identification(int sock_in, int sock_out) debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version); - compat_datafellows(remote_version); + active_state->compat = compat_datafellows(remote_version); if ((datafellows & SSH_BUG_PROBE) != 0) { logit("probed from %s with %s. Don't panic.", @@ -640,7 +639,9 @@ privsep_preauth_child(void) arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); +#ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); +#endif explicit_bzero(rnd, sizeof(rnd)); /* Demote the private keys to public keys. */ @@ -670,14 +671,14 @@ privsep_preauth_child(void) static int privsep_preauth(Authctxt *authctxt) { - int status; + int status, r; pid_t pid; struct ssh_sandbox *box = NULL; /* Set up unprivileged child process to deal with network data */ pmonitor = monitor_init(); /* Store a pointer to the kex for later rekeying */ - pmonitor->m_pkex = &xxx_kex; + pmonitor->m_pkex = &active_state->kex; if (use_privsep == PRIVSEP_ON) box = ssh_sandbox_init(pmonitor); @@ -688,8 +689,14 @@ privsep_preauth(Authctxt *authctxt) debug2("Network child is on pid %ld", (long)pid); pmonitor->m_pid = pid; - if (have_agent) - auth_conn = ssh_get_authentication_connection(); + if (have_agent) { + r = ssh_get_authentication_socket(&auth_sock); + if (r != 0) { + error("Could not get agent socket: %s", + ssh_err(r)); + have_agent = 0; + } + } if (box != NULL) ssh_sandbox_parent_preauth(box, pid); monitor_child_preauth(authctxt, pmonitor); @@ -775,7 +782,9 @@ privsep_postauth(Authctxt *authctxt) arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); +#ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); +#endif explicit_bzero(rnd, sizeof(rnd)); /* Drop privileges */ @@ -845,7 +854,7 @@ list_hostkey_types(void) } static Key * -get_hostkey_by_type(int type, int need_private) +get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) { int i; Key *key; @@ -866,7 +875,8 @@ get_hostkey_by_type(int type, int need_private) key = sensitive_data.host_pubkeys[i]; break; } - if (key != NULL && key->type == type) + if (key != NULL && key->type == type && + (key->type != KEY_ECDSA || key->ecdsa_nid == nid)) return need_private ? sensitive_data.host_keys[i] : key; } @@ -874,15 +884,15 @@ get_hostkey_by_type(int type, int need_private) } Key * -get_hostkey_public_by_type(int type) +get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) { - return get_hostkey_by_type(type, 0); + return get_hostkey_by_type(type, nid, 0, ssh); } Key * -get_hostkey_private_by_type(int type) +get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) { - return get_hostkey_by_type(type, 1); + return get_hostkey_by_type(type, nid, 1, ssh); } Key * @@ -894,7 +904,7 @@ get_hostkey_by_index(int ind) } Key * -get_hostkey_public_by_index(int ind) +get_hostkey_public_by_index(int ind, struct ssh *ssh) { if (ind < 0 || ind >= options.num_host_key_files) return (NULL); @@ -902,24 +912,71 @@ get_hostkey_public_by_index(int ind) } int -get_hostkey_index(Key *key) +get_hostkey_index(Key *key, int compare, struct ssh *ssh) { int i; for (i = 0; i < options.num_host_key_files; i++) { if (key_is_cert(key)) { - if (key == sensitive_data.host_certificates[i]) + if (key == sensitive_data.host_certificates[i] || + (compare && sensitive_data.host_certificates[i] && + sshkey_equal(key, + sensitive_data.host_certificates[i]))) return (i); } else { - if (key == sensitive_data.host_keys[i]) + if (key == sensitive_data.host_keys[i] || + (compare && sensitive_data.host_keys[i] && + sshkey_equal(key, sensitive_data.host_keys[i]))) return (i); - if (key == sensitive_data.host_pubkeys[i]) + if (key == sensitive_data.host_pubkeys[i] || + (compare && sensitive_data.host_pubkeys[i] && + sshkey_equal(key, sensitive_data.host_pubkeys[i]))) return (i); } } return (-1); } +/* Inform the client of all hostkeys */ +static void +notify_hostkeys(struct ssh *ssh) +{ + struct sshbuf *buf; + struct sshkey *key; + int i, nkeys, r; + char *fp; + + if ((buf = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new", __func__); + for (i = nkeys = 0; i < options.num_host_key_files; i++) { + key = get_hostkey_public_by_index(i, ssh); + if (key == NULL || key->type == KEY_UNSPEC || + key->type == KEY_RSA1 || sshkey_is_cert(key)) + continue; + fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); + debug3("%s: key %d: %s %s", __func__, i, + sshkey_ssh_name(key), fp); + free(fp); + if (nkeys == 0) { + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("hostkeys-00@openssh.com"); + packet_put_char(0); /* want-reply */ + } + sshbuf_reset(buf); + if ((r = sshkey_putb(key, buf)) != 0) + fatal("%s: couldn't put hostkey %d: %s", + __func__, i, ssh_err(r)); + packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); + nkeys++; + } + debug3("%s: sent %d hostkeys", __func__, nkeys); + if (nkeys == 0) + fatal("%s: no hostkeys", __func__); + packet_send(); + sshbuf_free(buf); +} + /* * returns 1 if connection should be dropped, 0 otherwise. * dropping starts at connection #max_startups_begin with a probability @@ -1004,7 +1061,7 @@ send_rexec_state(int fd, Buffer *conf) #endif buffer_put_int(&m, 0); -#ifndef OPENSSL_PRNG_ONLY +#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) rexec_send_rng_seed(&m); #endif @@ -1057,7 +1114,7 @@ recv_rexec_state(int fd, Buffer *conf) #endif } -#ifndef OPENSSL_PRNG_ONLY +#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) rexec_recv_rng_seed(&m); #endif @@ -1230,7 +1287,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) logit("Received signal %d; terminating.", (int) received_sigterm); close_listen_socks(); - unlink(options.pid_file); + if (options.pid_file != NULL) + unlink(options.pid_file); exit(received_sigterm == SIGTERM ? 0 : 255); } if (key_used && key_do_regen) { @@ -1393,7 +1451,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) */ arc4random_stir(); arc4random_buf(rnd, sizeof(rnd)); +#ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); +#endif explicit_bzero(rnd, sizeof(rnd)); } @@ -1412,11 +1472,11 @@ main(int ac, char **av) { extern char *optarg; extern int optind; - int opt, i, j, on = 1; + int r, opt, i, j, on = 1; int sock_in = -1, sock_out = -1, newsock = -1; const char *remote_ip; int remote_port; - char *line, *logfile = NULL; + char *fp, *line, *logfile = NULL; int config_s[2] = { -1 , -1 }; u_int n; u_int64_t ibytes, obytes; @@ -1555,8 +1615,8 @@ main(int ac, char **av) exit(1); break; case 'u': - utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); - if (utmp_len > MAXHOSTNAMELEN) { + utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); + if (utmp_len > HOST_NAME_MAX+1) { fprintf(stderr, "Invalid utmp length.\n"); exit(1); } @@ -1716,21 +1776,25 @@ main(int ac, char **av) sizeof(Key *)); sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, sizeof(Key *)); - for (i = 0; i < options.num_host_key_files; i++) { - sensitive_data.host_keys[i] = NULL; - sensitive_data.host_pubkeys[i] = NULL; - } if (options.host_key_agent) { if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) setenv(SSH_AUTHSOCKET_ENV_NAME, options.host_key_agent, 1); - have_agent = ssh_agent_present(); + if ((r = ssh_get_authentication_socket(NULL)) == 0) + have_agent = 1; + else + error("Could not connect to agent \"%s\": %s", + options.host_key_agent, ssh_err(r)); } for (i = 0; i < options.num_host_key_files; i++) { + if (options.host_key_files[i] == NULL) + continue; key = key_load_private(options.host_key_files[i], "", NULL); pubkey = key_load_public(options.host_key_files[i], NULL); + if (pubkey == NULL && key != NULL) + pubkey = key_demote(key); sensitive_data.host_keys[i] = key; sensitive_data.host_pubkeys[i] = pubkey; @@ -1758,11 +1822,17 @@ main(int ac, char **av) case KEY_DSA: case KEY_ECDSA: case KEY_ED25519: - sensitive_data.have_ssh2_key = 1; + if (have_agent || key != NULL) + sensitive_data.have_ssh2_key = 1; break; } - debug("private host key: #%d type %d %s", i, keytype, - key_type(key ? key : pubkey)); + if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash, + SSH_FP_DEFAULT)) == NULL) + fatal("sshkey_fingerprint failed"); + debug("%s host key #%d: %s %s", + key ? "private" : "agent", i, keytype == KEY_RSA1 ? + sshkey_type(pubkey) : sshkey_ssh_name(pubkey), fp); + free(fp); } if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { logit("Disabling protocol version 1. Could not load host key"); @@ -1787,6 +1857,8 @@ main(int ac, char **av) sensitive_data.host_certificates[i] = NULL; for (i = 0; i < options.num_host_cert_files; i++) { + if (options.host_cert_files[i] == NULL) + continue; key = key_load_public(options.host_cert_files[i], NULL); if (key == NULL) { error("Could not load host certificate: %s", @@ -1958,7 +2030,7 @@ main(int ac, char **av) * Write out the pid file after the sigterm handler * is setup and the listen sockets are bound */ - if (!debug_flag) { + if (options.pid_file != NULL && !debug_flag) { FILE *f = fopen(options.pid_file, "w"); if (f == NULL) { @@ -2163,8 +2235,12 @@ main(int ac, char **av) if (use_privsep) { if (privsep_preauth(authctxt) == 1) goto authenticated; - } else if (compat20 && have_agent) - auth_conn = ssh_get_authentication_connection(); + } else if (compat20 && have_agent) { + if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { + error("Unable to get agent socket: %s", ssh_err(r)); + have_agent = 0; + } + } /* perform the key exchange */ /* authenticate user and start session */ @@ -2233,12 +2309,15 @@ main(int ac, char **av) packet_set_timeout(options.client_alive_interval, options.client_alive_count_max); + /* Try to send all our hostkeys to the client */ + if (compat20) + notify_hostkeys(active_state); + /* Start session. */ do_authenticated(authctxt); /* The connection has been terminated. */ - packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); - packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); + packet_get_bytes(&ibytes, &obytes); verbose("Transferred: sent %llu, received %llu bytes", (unsigned long long)obytes, (unsigned long long)ibytes); @@ -2320,8 +2399,10 @@ do_ssh1_kex(void) { int i, len; int rsafail = 0; - BIGNUM *session_key_int; + BIGNUM *session_key_int, *fake_key_int, *real_key_int; u_char session_key[SSH_SESSION_KEY_LENGTH]; + u_char fake_key_bytes[4096 / 8]; + size_t fake_key_len; u_char cookie[8]; u_int cipher_type, auth_mask, protocol_flags; @@ -2399,74 +2480,61 @@ do_ssh1_kex(void) debug("Encryption type: %.200s", cipher_name(cipher_type)); /* Get the encrypted integer. */ - if ((session_key_int = BN_new()) == NULL) + if ((real_key_int = BN_new()) == NULL) fatal("do_ssh1_kex: BN_new failed"); - packet_get_bignum(session_key_int); + packet_get_bignum(real_key_int); protocol_flags = packet_get_int(); packet_set_protocol_flags(protocol_flags); packet_check_eom(); - /* Decrypt session_key_int using host/server keys */ - rsafail = PRIVSEP(ssh1_session_key(session_key_int)); + /* Setup a fake key in case RSA decryption fails */ + if ((fake_key_int = BN_new()) == NULL) + fatal("do_ssh1_kex: BN_new failed"); + fake_key_len = BN_num_bytes(real_key_int); + if (fake_key_len > sizeof(fake_key_bytes)) + fake_key_len = sizeof(fake_key_bytes); + arc4random_buf(fake_key_bytes, fake_key_len); + if (BN_bin2bn(fake_key_bytes, fake_key_len, fake_key_int) == NULL) + fatal("do_ssh1_kex: BN_bin2bn failed"); + + /* Decrypt real_key_int using host/server keys */ + rsafail = PRIVSEP(ssh1_session_key(real_key_int)); + /* If decryption failed, use the fake key. Else, the real key. */ + if (rsafail) + session_key_int = fake_key_int; + else + session_key_int = real_key_int; /* * Extract session key from the decrypted integer. The key is in the * least significant 256 bits of the integer; the first byte of the * key is in the highest bits. */ - if (!rsafail) { - (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); - len = BN_num_bytes(session_key_int); - if (len < 0 || (u_int)len > sizeof(session_key)) { - error("do_ssh1_kex: bad session key len from %s: " - "session_key_int %d > sizeof(session_key) %lu", - get_remote_ipaddr(), len, (u_long)sizeof(session_key)); - rsafail++; - } else { - explicit_bzero(session_key, sizeof(session_key)); - BN_bn2bin(session_key_int, - session_key + sizeof(session_key) - len); + (void) BN_mask_bits(session_key_int, sizeof(session_key) * 8); + len = BN_num_bytes(session_key_int); + if (len < 0 || (u_int)len > sizeof(session_key)) { + error("do_ssh1_kex: bad session key len from %s: " + "session_key_int %d > sizeof(session_key) %lu", + get_remote_ipaddr(), len, (u_long)sizeof(session_key)); + rsafail++; + } else { + explicit_bzero(session_key, sizeof(session_key)); + BN_bn2bin(session_key_int, + session_key + sizeof(session_key) - len); - derive_ssh1_session_id( - sensitive_data.ssh1_host_key->rsa->n, - sensitive_data.server_key->rsa->n, - cookie, session_id); - /* - * Xor the first 16 bytes of the session key with the - * session id. - */ - for (i = 0; i < 16; i++) - session_key[i] ^= session_id[i]; - } - } - if (rsafail) { - int bytes = BN_num_bytes(session_key_int); - u_char *buf = xmalloc(bytes); - struct ssh_digest_ctx *md; - - logit("do_connection: generating a fake encryption key"); - BN_bn2bin(session_key_int, buf); - if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || - ssh_digest_update(md, buf, bytes) < 0 || - ssh_digest_update(md, sensitive_data.ssh1_cookie, - SSH_SESSION_KEY_LENGTH) < 0 || - ssh_digest_final(md, session_key, sizeof(session_key)) < 0) - fatal("%s: md5 failed", __func__); - ssh_digest_free(md); - if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL || - ssh_digest_update(md, session_key, 16) < 0 || - ssh_digest_update(md, sensitive_data.ssh1_cookie, - SSH_SESSION_KEY_LENGTH) < 0 || - ssh_digest_final(md, session_key + 16, - sizeof(session_key) - 16) < 0) - fatal("%s: md5 failed", __func__); - ssh_digest_free(md); - explicit_bzero(buf, bytes); - free(buf); + derive_ssh1_session_id( + sensitive_data.ssh1_host_key->rsa->n, + sensitive_data.server_key->rsa->n, + cookie, session_id); + /* + * Xor the first 16 bytes of the session key with the + * session id. + */ for (i = 0; i < 16; i++) - session_id[i] = session_key[i] ^ session_key[i + 16]; + session_key[i] ^= session_id[i]; } + /* Destroy the private and public keys. No longer. */ destroy_sensitive_data(); @@ -2474,7 +2542,8 @@ do_ssh1_kex(void) mm_ssh1_session_id(session_id); /* Destroy the decrypted integer. It is no longer needed. */ - BN_clear_free(session_key_int); + BN_clear_free(real_key_int); + BN_clear_free(fake_key_int); /* Set the session key. From this on all communications will be encrypted. */ packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); @@ -2491,21 +2560,30 @@ do_ssh1_kex(void) } #endif -void -sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, - u_char *data, u_int dlen) +int +sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, + const u_char *data, size_t dlen, u_int flag) { + int r; + u_int xxx_slen, xxx_dlen = dlen; + if (privkey) { - if (PRIVSEP(key_sign(privkey, signature, slen, data, dlen) < 0)) + if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen) < 0)) fatal("%s: key_sign failed", __func__); + if (slen) + *slen = xxx_slen; } else if (use_privsep) { - if (mm_key_sign(pubkey, signature, slen, data, dlen) < 0) + if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen) < 0) fatal("%s: pubkey_sign failed", __func__); + if (slen) + *slen = xxx_slen; } else { - if (ssh_agent_sign(auth_conn, pubkey, signature, slen, data, - dlen)) - fatal("%s: ssh_agent_sign failed", __func__); + if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen, + data, dlen, datafellows)) != 0) + fatal("%s: ssh_agent_sign failed: %s", + __func__, ssh_err(r)); } + return 0; } /* @@ -2515,7 +2593,8 @@ static void do_ssh2_kex(void) { char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; - Kex *kex; + struct kex *kex; + int r; if (options.ciphers != NULL) { myproposal[PROPOSAL_ENC_ALGS_CTOS] = @@ -2551,13 +2630,17 @@ do_ssh2_kex(void) list_hostkey_types()); /* start key exchange */ - kex = kex_setup(myproposal); + if ((r = kex_setup(active_state, myproposal)) != 0) + fatal("kex_setup: %s", ssh_err(r)); + kex = active_state->kex; #ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +# ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kexecdh_server; +# endif #endif kex->kex[KEX_C25519_SHA256] = kexc25519_server; kex->server = 1; @@ -2568,9 +2651,7 @@ do_ssh2_kex(void) kex->host_key_index=&get_hostkey_index; kex->sign = sshd_hostkey_sign; - xxx_kex = kex; - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); + dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); session_id2 = kex->session_id; session_id2_len = kex->session_id_len; diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index 6712744dc61e..49018cb4837e 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $ +# $OpenBSD: sshd_config,v 1.94 2015/02/02 01:57:44 deraadt Exp $ # $FreeBSD$ # This is the sshd server system-wide configuration file. See @@ -115,7 +115,7 @@ #Compression delayed #ClientAliveInterval 0 #ClientAliveCountMax 3 -#UseDNS yes +#UseDNS no #PidFile /var/run/sshd.pid #MaxStartups 10:30:100 #PermitTunnel no diff --git a/crypto/openssh/sshd_config.0 b/crypto/openssh/sshd_config.0 index 1c82d449fef6..be48e1364ed4 100644 --- a/crypto/openssh/sshd_config.0 +++ b/crypto/openssh/sshd_config.0 @@ -1,7 +1,7 @@ SSHD_CONFIG(5) File Formats Manual SSHD_CONFIG(5) NAME - sshd_config - OpenSSH SSH daemon configuration file + sshd_config M-bM-^@M-^S OpenSSH SSH daemon configuration file SYNOPSIS /etc/ssh/sshd_config @@ -9,7 +9,7 @@ SYNOPSIS DESCRIPTION sshd(8) reads configuration data from /etc/ssh/sshd_config (or the file specified with -f on the command line). The file contains keyword- - argument pairs, one per line. Lines starting with `#' and empty lines + argument pairs, one per line. Lines starting with M-bM-^@M-^X#M-bM-^@M-^Y and empty lines are interpreted as comments. Arguments may optionally be enclosed in double quotes (") in order to represent arguments containing spaces. @@ -22,7 +22,7 @@ DESCRIPTION ssh_config(5) for how to configure the client. Note that environment passing is only supported for protocol 2. Variables are specified by name, which may contain the wildcard characters - `*' and `?'. Multiple environment variables may be separated by + M-bM-^@M-^X*M-bM-^@M-^Y and M-bM-^@M-^X?M-bM-^@M-^Y. Multiple environment variables may be separated by whitespace or spread across multiple AcceptEnv directives. Be warned that some environment variables could be used to bypass restricted user environments. For this reason, care should be @@ -31,14 +31,14 @@ DESCRIPTION AddressFamily Specifies which address family should be used by sshd(8). Valid - arguments are ``any'', ``inet'' (use IPv4 only), or ``inet6'' - (use IPv6 only). The default is ``any''. + arguments are M-bM-^@M-^\anyM-bM-^@M-^], M-bM-^@M-^\inetM-bM-^@M-^] (use IPv4 only), or M-bM-^@M-^\inet6M-bM-^@M-^] (use IPv6 + only). The default is M-bM-^@M-^\anyM-bM-^@M-^]. AllowAgentForwarding Specifies whether ssh-agent(1) forwarding is permitted. The - default is ``yes''. Note that disabling agent forwarding does - not improve security unless users are also denied shell access, - as they can always install their own forwarders. + default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that disabling agent forwarding does not + improve security unless users are also denied shell access, as + they can always install their own forwarders. AllowGroups This keyword can be followed by a list of group name patterns, @@ -54,21 +54,21 @@ DESCRIPTION AllowTcpForwarding Specifies whether TCP forwarding is permitted. The available - options are ``yes'' or ``all'' to allow TCP forwarding, ``no'' to - prevent all TCP forwarding, ``local'' to allow local (from the - perspective of ssh(1)) forwarding only or ``remote'' to allow - remote forwarding only. The default is ``yes''. Note that + options are M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\allM-bM-^@M-^] to allow TCP forwarding, M-bM-^@M-^\noM-bM-^@M-^] to + prevent all TCP forwarding, M-bM-^@M-^\localM-bM-^@M-^] to allow local (from the + perspective of ssh(1)) forwarding only or M-bM-^@M-^\remoteM-bM-^@M-^] to allow + remote forwarding only. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that disabling TCP forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. AllowStreamLocalForwarding Specifies whether StreamLocal (Unix-domain socket) forwarding is - permitted. The available options are ``yes'' or ``all'' to allow - StreamLocal forwarding, ``no'' to prevent all StreamLocal - forwarding, ``local'' to allow local (from the perspective of - ssh(1)) forwarding only or ``remote'' to allow remote forwarding - only. The default is ``yes''. Note that disabling StreamLocal + permitted. The available options are M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\allM-bM-^@M-^] to allow + StreamLocal forwarding, M-bM-^@M-^\noM-bM-^@M-^] to prevent all StreamLocal + forwarding, M-bM-^@M-^\localM-bM-^@M-^] to allow local (from the perspective of + ssh(1)) forwarding only or M-bM-^@M-^\remoteM-bM-^@M-^] to allow remote forwarding + only. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that disabling StreamLocal forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. @@ -92,8 +92,8 @@ DESCRIPTION method names. Successful authentication requires completion of every method in at least one of these lists. - For example, an argument of ``publickey,password - publickey,keyboard-interactive'' would require the user to + For example, an argument of M-bM-^@M-^\publickey,password + publickey,keyboard-interactiveM-bM-^@M-^] would require the user to complete public key authentication, followed by either password or keyboard interactive authentication. Only methods that are next in one or more lists are offered at each stage, so for this @@ -102,10 +102,16 @@ DESCRIPTION For keyboard interactive authentication it is also possible to restrict authentication to a specific device by appending a colon - followed by the device identifier ``bsdauth'', ``pam'', or - ``skey'', depending on the server configuration. For example, - ``keyboard-interactive:bsdauth'' would restrict keyboard - interactive authentication to the ``bsdauth'' device. + followed by the device identifier M-bM-^@M-^\bsdauthM-bM-^@M-^], M-bM-^@M-^\pamM-bM-^@M-^], or M-bM-^@M-^\skeyM-bM-^@M-^], + depending on the server configuration. For example, + M-bM-^@M-^\keyboard-interactive:bsdauthM-bM-^@M-^] would restrict keyboard + interactive authentication to the M-bM-^@M-^\bsdauthM-bM-^@M-^] device. + + If the M-bM-^@M-^\publickeyM-bM-^@M-^] method is listed more than once, sshd(8) + verifies that keys that have been used successfully are not + reused for subsequent authentications. For example, an + AuthenticationMethods of M-bM-^@M-^\publickey,publickeyM-bM-^@M-^] will require + successful authentication using two different public keys. This option is only available for SSH protocol 2 and will yield a fatal error if enabled if protocol 1 is also enabled. Note that @@ -129,7 +135,9 @@ DESCRIPTION AuthorizedKeysCommandUser Specifies the user under whose account the AuthorizedKeysCommand is run. It is recommended to use a dedicated user that has no - other role on the host than running authorized keys commands. + other role on the host than running authorized keys commands. If + AuthorizedKeysCommand is specified but AuthorizedKeysCommandUser + is not, then sshd(8) will refuse to start. AuthorizedKeysFile Specifies the file that contains the public keys that can be used @@ -143,7 +151,7 @@ DESCRIPTION AuthorizedKeysFile is taken to be an absolute path or one relative to the user's home directory. Multiple files may be listed, separated by whitespace. The default is - ``.ssh/authorized_keys .ssh/authorized_keys2''. + M-bM-^@M-^\.ssh/authorized_keys .ssh/authorized_keys2M-bM-^@M-^]. AuthorizedPrincipalsFile Specifies a file that lists principal names that are accepted for @@ -152,7 +160,7 @@ DESCRIPTION which must appear in the certificate for it to be accepted for authentication. Names are listed one per line preceded by key options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)). - Empty lines and comments starting with `#' are ignored. + Empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are ignored. AuthorizedPrincipalsFile may contain tokens of the form %T which are substituted during connection setup. The following tokens @@ -162,7 +170,7 @@ DESCRIPTION AuthorizedPrincipalsFile is taken to be an absolute path or one relative to the user's home directory. - The default is ``none'', i.e. not to use a principals file - in + The default is M-bM-^@M-^\noneM-bM-^@M-^], i.e. not to use a principals file M-bM-^@M-^S in this case, the username of the user must appear in a certificate's principals list for it to be accepted. Note that AuthorizedPrincipalsFile is only used when authentication @@ -172,21 +180,22 @@ DESCRIPTION a similar facility (see sshd(8) for details). Banner The contents of the specified file are sent to the remote user - before authentication is allowed. If the argument is ``none'' - then no banner is displayed. This option is only available for + before authentication is allowed. If the argument is M-bM-^@M-^\noneM-bM-^@M-^] then + no banner is displayed. This option is only available for protocol version 2. By default, no banner is displayed. ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed (e.g. via PAM or through authentication styles supported in - login.conf(5)) The default is ``yes''. + login.conf(5)) The default is M-bM-^@M-^\yesM-bM-^@M-^]. ChrootDirectory Specifies the pathname of a directory to chroot(2) to after - authentication. All components of the pathname must be root- - owned directories that are not writable by any other user or - group. After the chroot, sshd(8) changes the working directory - to the user's home directory. + authentication. At session startup sshd(8) checks that all + components of the pathname are root-owned directories which are + not writable by any other user or group. After the chroot, + sshd(8) changes the working directory to the user's home + directory. The pathname may contain the following tokens that are expanded at runtime once the connecting user has been authenticated: %% is @@ -198,12 +207,17 @@ DESCRIPTION directories to support the user's session. For an interactive session this requires at least a shell, typically sh(1), and basic /dev nodes such as null(4), zero(4), stdin(4), stdout(4), - stderr(4), arandom(4) and tty(4) devices. For file transfer - sessions using ``sftp'', no additional configuration of the - environment is necessary if the in-process sftp server is used, - though sessions which use logging may require /dev/log inside the - chroot directory on some operating systems (see sftp-server(8) - for details). + stderr(4), and tty(4) devices. For file transfer sessions using + M-bM-^@M-^\sftpM-bM-^@M-^], no additional configuration of the environment is + necessary if the in-process sftp server is used, though sessions + which use logging may require /dev/log inside the chroot + directory on some operating systems (see sftp-server(8) for + details). + + For safety, it is very important that the directory hierarchy be + prevented from modification by other processes on the system + (especially those outside the jail). Misconfiguration can lead + to unsafe environments which sshd(8) cannot detect. The default is not to chroot(2). @@ -234,7 +248,7 @@ DESCRIPTION chacha20-poly1305@openssh.com The list of available ciphers may also be obtained using the -Q - option of ssh(1). + option of ssh(1) with an argument of M-bM-^@M-^\cipherM-bM-^@M-^]. ClientAliveCountMax Sets the number of client alive messages (see below) which may be @@ -264,8 +278,8 @@ DESCRIPTION Compression Specifies whether compression is allowed, or delayed until the - user has authenticated successfully. The argument must be - ``yes'', ``delayed'', or ``no''. The default is ``delayed''. + user has authenticated successfully. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], + M-bM-^@M-^\delayedM-bM-^@M-^], or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\delayedM-bM-^@M-^]. DenyGroups This keyword can be followed by a list of group name patterns, @@ -291,6 +305,10 @@ DESCRIPTION See PATTERNS in ssh_config(5) for more information on patterns. + FingerprintHash + Specifies the hash algorithm used when logging key fingerprints. + Valid options are: M-bM-^@M-^\md5M-bM-^@M-^] and M-bM-^@M-^\sha256M-bM-^@M-^]. The default is M-bM-^@M-^\sha256M-bM-^@M-^]. + ForceCommand Forces the execution of the command specified by ForceCommand, ignoring any command supplied by the client and ~/.ssh/rc if @@ -299,7 +317,7 @@ DESCRIPTION execution. It is most useful inside a Match block. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Specifying a command - of ``internal-sftp'' will force the use of an in-process sftp + of M-bM-^@M-^\internal-sftpM-bM-^@M-^] will force the use of an in-process sftp server that requires no support files when used with ChrootDirectory. @@ -310,37 +328,43 @@ DESCRIPTION hosts from connecting to forwarded ports. GatewayPorts can be used to specify that sshd should allow remote port forwardings to bind to non-loopback addresses, thus allowing other hosts to - connect. The argument may be ``no'' to force remote port - forwardings to be available to the local host only, ``yes'' to + connect. The argument may be M-bM-^@M-^\noM-bM-^@M-^] to force remote port + forwardings to be available to the local host only, M-bM-^@M-^\yesM-bM-^@M-^] to force remote port forwardings to bind to the wildcard address, or - ``clientspecified'' to allow the client to select the address to - which the forwarding is bound. The default is ``no''. + M-bM-^@M-^\clientspecifiedM-bM-^@M-^] to allow the client to select the address to + which the forwarding is bound. The default is M-bM-^@M-^\noM-bM-^@M-^]. GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. - The default is ``no''. Note that this option applies to protocol + The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 only. GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials - cache on logout. The default is ``yes''. Note that this option + cache on logout. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option applies to protocol version 2 only. + HostbasedAcceptedKeyTypes + Specifies the key types that will be accepted for hostbased + authentication as a comma-separated pattern list. The default + M-bM-^@M-^\*M-bM-^@M-^] will allow all key types. The -Q option of ssh(1) may be + used to list supported key types. + HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed (host-based authentication). This option is similar to RhostsRSAAuthentication and applies to protocol version 2 only. - The default is ``no''. + The default is M-bM-^@M-^\noM-bM-^@M-^]. HostbasedUsesNameFromPacketOnly Specifies whether or not the server will attempt to perform a reverse name lookup when matching the name in the ~/.shosts, ~/.rhosts, and /etc/hosts.equiv files during - HostbasedAuthentication. A setting of ``yes'' means that sshd(8) + HostbasedAuthentication. A setting of M-bM-^@M-^\yesM-bM-^@M-^] means that sshd(8) uses the name supplied by the client rather than attempting to resolve the name from the TCP connection itself. The default is - ``no''. + M-bM-^@M-^\noM-bM-^@M-^]. HostCertificate Specifies a file containing a public host certificate. The @@ -355,70 +379,69 @@ DESCRIPTION /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key for protocol version 2. Note that sshd(8) will refuse to use a file if it is group/world-accessible. It is possible to have multiple - host key files. ``rsa1'' keys are used for version 1 and - ``dsa'', ``ecdsa'', ``ed25519'' or ``rsa'' are used for version 2 - of the SSH protocol. It is also possible to specify public host - key files instead. In this case operations on the private key - will be delegated to an ssh-agent(1). + host key files. M-bM-^@M-^\rsa1M-bM-^@M-^] keys are used for version 1 and M-bM-^@M-^\dsaM-bM-^@M-^], + M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^] or M-bM-^@M-^\rsaM-bM-^@M-^] are used for version 2 of the SSH + protocol. It is also possible to specify public host key files + instead. In this case operations on the private key will be + delegated to an ssh-agent(1). HostKeyAgent Identifies the UNIX-domain socket used to communicate with an agent that has access to the private host keys. If - ``SSH_AUTH_SOCK'' is specified, the location of the socket will - be read from the SSH_AUTH_SOCK environment variable. + M-bM-^@M-^\SSH_AUTH_SOCKM-bM-^@M-^] is specified, the location of the socket will be + read from the SSH_AUTH_SOCK environment variable. IgnoreRhosts Specifies that .rhosts and .shosts files will not be used in RhostsRSAAuthentication or HostbasedAuthentication. /etc/hosts.equiv and /etc/shosts.equiv are still used. The - default is ``yes''. + default is M-bM-^@M-^\yesM-bM-^@M-^]. IgnoreUserKnownHosts Specifies whether sshd(8) should ignore the user's ~/.ssh/known_hosts during RhostsRSAAuthentication or - HostbasedAuthentication. The default is ``no''. + HostbasedAuthentication. The default is M-bM-^@M-^\noM-bM-^@M-^]. IPQoS Specifies the IPv4 type-of-service or DSCP class for the - connection. Accepted values are ``af11'', ``af12'', ``af13'', - ``af21'', ``af22'', ``af23'', ``af31'', ``af32'', ``af33'', - ``af41'', ``af42'', ``af43'', ``cs0'', ``cs1'', ``cs2'', ``cs3'', - ``cs4'', ``cs5'', ``cs6'', ``cs7'', ``ef'', ``lowdelay'', - ``throughput'', ``reliability'', or a numeric value. This option - may take one or two arguments, separated by whitespace. If one - argument is specified, it is used as the packet class - unconditionally. If two values are specified, the first is - automatically selected for interactive sessions and the second - for non-interactive sessions. The default is ``lowdelay'' for - interactive sessions and ``throughput'' for non-interactive + connection. Accepted values are M-bM-^@M-^\af11M-bM-^@M-^], M-bM-^@M-^\af12M-bM-^@M-^], M-bM-^@M-^\af13M-bM-^@M-^], M-bM-^@M-^\af21M-bM-^@M-^], + M-bM-^@M-^\af22M-bM-^@M-^], M-bM-^@M-^\af23M-bM-^@M-^], M-bM-^@M-^\af31M-bM-^@M-^], M-bM-^@M-^\af32M-bM-^@M-^], M-bM-^@M-^\af33M-bM-^@M-^], M-bM-^@M-^\af41M-bM-^@M-^], M-bM-^@M-^\af42M-bM-^@M-^], M-bM-^@M-^\af43M-bM-^@M-^], + M-bM-^@M-^\cs0M-bM-^@M-^], M-bM-^@M-^\cs1M-bM-^@M-^], M-bM-^@M-^\cs2M-bM-^@M-^], M-bM-^@M-^\cs3M-bM-^@M-^], M-bM-^@M-^\cs4M-bM-^@M-^], M-bM-^@M-^\cs5M-bM-^@M-^], M-bM-^@M-^\cs6M-bM-^@M-^], M-bM-^@M-^\cs7M-bM-^@M-^], M-bM-^@M-^\efM-bM-^@M-^], + M-bM-^@M-^\lowdelayM-bM-^@M-^], M-bM-^@M-^\throughputM-bM-^@M-^], M-bM-^@M-^\reliabilityM-bM-^@M-^], or a numeric value. + This option may take one or two arguments, separated by + whitespace. If one argument is specified, it is used as the + packet class unconditionally. If two values are specified, the + first is automatically selected for interactive sessions and the + second for non-interactive sessions. The default is M-bM-^@M-^\lowdelayM-bM-^@M-^] + for interactive sessions and M-bM-^@M-^\throughputM-bM-^@M-^] for non-interactive sessions. KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. - The argument to this keyword must be ``yes'' or ``no''. The - default is to use whatever value ChallengeResponseAuthentication - is set to (by default ``yes''). + The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default + is to use whatever value ChallengeResponseAuthentication is set + to (by default M-bM-^@M-^\yesM-bM-^@M-^]). KerberosAuthentication Specifies whether the password provided by the user for PasswordAuthentication will be validated through the Kerberos KDC. To use this option, the server needs a Kerberos servtab which allows the verification of the KDC's identity. The default - is ``no''. + is M-bM-^@M-^\noM-bM-^@M-^]. KerberosGetAFSToken If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire an AFS token before accessing the user's home directory. - The default is ``no''. + The default is M-bM-^@M-^\noM-bM-^@M-^]. KerberosOrLocalPasswd If password authentication through Kerberos fails then the password will be validated via any additional local mechanism - such as /etc/passwd. The default is ``yes''. + such as /etc/passwd. The default is M-bM-^@M-^\yesM-bM-^@M-^]. KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket - cache file on logout. The default is ``yes''. + cache file on logout. The default is M-bM-^@M-^\yesM-bM-^@M-^]. KexAlgorithms Specifies the available KEX (Key Exchange) algorithms. Multiple @@ -441,6 +464,9 @@ DESCRIPTION diffie-hellman-group-exchange-sha256, diffie-hellman-group14-sha1 + The list of available key exchange algorithms may also be + obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\kexM-bM-^@M-^]. + KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). The @@ -479,9 +505,9 @@ DESCRIPTION MACs Specifies the available MAC (message authentication code) algorithms. The MAC algorithm is used in protocol version 2 for data integrity protection. Multiple algorithms must be comma- - separated. The algorithms that contain ``-etm'' calculate the - MAC after encryption (encrypt-then-mac). These are considered - safer and their use recommended. The supported MACs are: + separated. The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC + after encryption (encrypt-then-mac). These are considered safer + and their use recommended. The supported MACs are: hmac-md5 hmac-md5-96 @@ -509,12 +535,15 @@ DESCRIPTION umac-64@openssh.com,umac-128@openssh.com, hmac-sha2-256,hmac-sha2-512 + The list of available MAC algorithms may also be obtained using + the -Q option of ssh(1) with an argument of M-bM-^@M-^\macM-bM-^@M-^]. + Match Introduces a conditional block. If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. If a - keyword appears in multiple Match blocks that are satisified, - only the first instance of the keyword is applied. + keyword appears in multiple Match blocks that are satisfied, only + the first instance of the keyword is applied. The arguments to Match are one or more criteria-pattern pairs or the single token All which matches all criteria. The available @@ -525,25 +554,28 @@ DESCRIPTION The patterns in an Address criteria may additionally contain addresses to match in CIDR address/masklen format, e.g. - ``192.0.2.0/24'' or ``3ffe:ffff::/32''. Note that the mask - length provided must be consistent with the address - it is an - error to specify a mask length that is too long for the address - or one with bits set in this host portion of the address. For - example, ``192.0.2.0/33'' and ``192.0.2.0/8'' respectively. + M-bM-^@M-^\192.0.2.0/24M-bM-^@M-^] or M-bM-^@M-^\3ffe:ffff::/32M-bM-^@M-^]. Note that the mask length + provided must be consistent with the address - it is an error to + specify a mask length that is too long for the address or one + with bits set in this host portion of the address. For example, + M-bM-^@M-^\192.0.2.0/33M-bM-^@M-^] and M-bM-^@M-^\192.0.2.0/8M-bM-^@M-^] respectively. Only a subset of keywords may be used on the lines following a Match keyword. Available keywords are AcceptEnv, - AllowAgentForwarding, AllowGroups, AllowTcpForwarding, - AllowUsers, AuthenticationMethods, AuthorizedKeysCommand, - AuthorizedKeysCommandUser, AuthorizedKeysFile, - AuthorizedPrincipalsFile, Banner, ChrootDirectory, DenyGroups, - DenyUsers, ForceCommand, GatewayPorts, GSSAPIAuthentication, - HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, + AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, + AllowTcpForwarding, AllowUsers, AuthenticationMethods, + AuthorizedKeysCommand, AuthorizedKeysCommandUser, + AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner, + ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, + GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes, + HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS, KbdInteractiveAuthentication, KerberosAuthentication, MaxAuthTries, MaxSessions, PasswordAuthentication, PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY, - PermitTunnel, PermitUserRC, PubkeyAuthentication, RekeyLimit, - RhostsRSAAuthentication, RSAAuthentication, X11DisplayOffset, + PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes, + PubkeyAuthentication, RekeyLimit, RevokedKeys, + RhostsRSAAuthentication, RSAAuthentication, StreamLocalBindMask, + StreamLocalBindUnlink, TrustedUserCAKeys, X11DisplayOffset, X11Forwarding and X11UseLocalHost. MaxAuthTries @@ -562,21 +594,21 @@ DESCRIPTION expires for a connection. The default is 10:30:100. Alternatively, random early drop can be enabled by specifying the - three colon separated values ``start:rate:full'' (e.g. - "10:30:60"). sshd(8) will refuse connection attempts with a - probability of ``rate/100'' (30%) if there are currently - ``start'' (10) unauthenticated connections. The probability - increases linearly and all connection attempts are refused if the - number of unauthenticated connections reaches ``full'' (60). + three colon separated values M-bM-^@M-^\start:rate:fullM-bM-^@M-^] (e.g. "10:30:60"). + sshd(8) will refuse connection attempts with a probability of + M-bM-^@M-^\rate/100M-bM-^@M-^] (30%) if there are currently M-bM-^@M-^\startM-bM-^@M-^] (10) + unauthenticated connections. The probability increases linearly + and all connection attempts are refused if the number of + unauthenticated connections reaches M-bM-^@M-^\fullM-bM-^@M-^] (60). PasswordAuthentication Specifies whether password authentication is allowed. The - default is ``yes''. + default is M-bM-^@M-^\yesM-bM-^@M-^]. PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The - default is ``no''. + default is M-bM-^@M-^\noM-bM-^@M-^]. PermitOpen Specifies the destinations to which TCP port forwarding is @@ -588,47 +620,50 @@ DESCRIPTION PermitOpen [IPv6_addr]:port Multiple forwards may be specified by separating them with - whitespace. An argument of ``any'' can be used to remove all + whitespace. An argument of M-bM-^@M-^\anyM-bM-^@M-^] can be used to remove all restrictions and permit any forwarding requests. An argument of - ``none'' can be used to prohibit all forwarding requests. By + M-bM-^@M-^\noneM-bM-^@M-^] can be used to prohibit all forwarding requests. By default all port forwarding requests are permitted. PermitRootLogin Specifies whether root can log in using ssh(1). The argument - must be ``yes'', ``without-password'', ``forced-commands-only'', - or ``no''. The default is ``yes''. + must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\without-passwordM-bM-^@M-^], M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^], or + M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\yesM-bM-^@M-^]. - If this option is set to ``without-password'', password + If this option is set to M-bM-^@M-^\without-passwordM-bM-^@M-^], password authentication is disabled for root. - If this option is set to ``forced-commands-only'', root login - with public key authentication will be allowed, but only if the + If this option is set to M-bM-^@M-^\forced-commands-onlyM-bM-^@M-^], root login with + public key authentication will be allowed, but only if the command option has been specified (which may be useful for taking remote backups even if root login is normally not allowed). All other authentication methods are disabled for root. - If this option is set to ``no'', root is not allowed to log in. + If this option is set to M-bM-^@M-^\noM-bM-^@M-^], root is not allowed to log in. PermitTunnel Specifies whether tun(4) device forwarding is allowed. The - argument must be ``yes'', ``point-to-point'' (layer 3), - ``ethernet'' (layer 2), or ``no''. Specifying ``yes'' permits - both ``point-to-point'' and ``ethernet''. The default is ``no''. + argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\point-to-pointM-bM-^@M-^] (layer 3), M-bM-^@M-^\ethernetM-bM-^@M-^] + (layer 2), or M-bM-^@M-^\noM-bM-^@M-^]. Specifying M-bM-^@M-^\yesM-bM-^@M-^] permits both + M-bM-^@M-^\point-to-pointM-bM-^@M-^] and M-bM-^@M-^\ethernetM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + + Independent of this setting, the permissions of the selected + tun(4) device must allow access to the user. PermitTTY Specifies whether pty(4) allocation is permitted. The default is - ``yes''. + M-bM-^@M-^\yesM-bM-^@M-^]. PermitUserEnvironment Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd(8). The default is - ``no''. Enabling environment processing may enable users to - bypass access restrictions in some configurations using - mechanisms such as LD_PRELOAD. + M-bM-^@M-^\noM-bM-^@M-^]. Enabling environment processing may enable users to bypass + access restrictions in some configurations using mechanisms such + as LD_PRELOAD. PermitUserRC Specifies whether any ~/.ssh/rc file is executed. The default is - ``yes''. + M-bM-^@M-^\yesM-bM-^@M-^]. PidFile Specifies the file that contains the process ID of the SSH @@ -641,24 +676,30 @@ DESCRIPTION PrintLastLog Specifies whether sshd(8) should print the date and time of the last user login when a user logs in interactively. The default - is ``yes''. + is M-bM-^@M-^\yesM-bM-^@M-^]. PrintMotd Specifies whether sshd(8) should print /etc/motd when a user logs in interactively. (On some systems it is also printed by the - shell, /etc/profile, or equivalent.) The default is ``yes''. + shell, /etc/profile, or equivalent.) The default is M-bM-^@M-^\yesM-bM-^@M-^]. Protocol Specifies the protocol versions sshd(8) supports. The possible - values are `1' and `2'. Multiple versions must be comma- - separated. The default is `2'. Note that the order of the + values are M-bM-^@M-^X1M-bM-^@M-^Y and M-bM-^@M-^X2M-bM-^@M-^Y. Multiple versions must be comma- + separated. The default is M-bM-^@M-^X2M-bM-^@M-^Y. Note that the order of the protocol list does not indicate preference, because the client selects among multiple protocol versions offered by the server. - Specifying ``2,1'' is identical to ``1,2''. + Specifying M-bM-^@M-^\2,1M-bM-^@M-^] is identical to M-bM-^@M-^\1,2M-bM-^@M-^]. + + PubkeyAcceptedKeyTypes + Specifies the key types that will be accepted for public key + authentication as a comma-separated pattern list. The default + M-bM-^@M-^\*M-bM-^@M-^] will allow all key types. The -Q option of ssh(1) may be + used to list supported key types. PubkeyAuthentication Specifies whether public key authentication is allowed. The - default is ``yes''. Note that this option applies to protocol + default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option applies to protocol version 2 only. RekeyLimit @@ -666,12 +707,12 @@ DESCRIPTION before the session key is renegotiated, optionally followed a maximum amount of time that may pass before the session key is renegotiated. The first argument is specified in bytes and may - have a suffix of `K', `M', or `G' to indicate Kilobytes, + have a suffix of M-bM-^@M-^XKM-bM-^@M-^Y, M-bM-^@M-^XMM-bM-^@M-^Y, or M-bM-^@M-^XGM-bM-^@M-^Y to indicate Kilobytes, Megabytes, or Gigabytes, respectively. The default is between - `1G' and `4G', depending on the cipher. The optional second + M-bM-^@M-^X1GM-bM-^@M-^Y and M-bM-^@M-^X4GM-bM-^@M-^Y, depending on the cipher. The optional second value is specified in seconds and may use any of the units documented in the TIME FORMATS section. The default value for - RekeyLimit is ``default none'', which means that rekeying is + RekeyLimit is M-bM-^@M-^\default noneM-bM-^@M-^], which means that rekeying is performed after the cipher's default amount of data has been sent or received and no time based rekeying is done. This option applies to protocol version 2 only. @@ -688,12 +729,11 @@ DESCRIPTION RhostsRSAAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful RSA host authentication is allowed. The - default is ``no''. This option applies to protocol version 1 - only. + default is M-bM-^@M-^\noM-bM-^@M-^]. This option applies to protocol version 1 only. RSAAuthentication Specifies whether pure RSA authentication is allowed. The - default is ``yes''. This option applies to protocol version 1 + default is M-bM-^@M-^\yesM-bM-^@M-^]. This option applies to protocol version 1 only. ServerKeyBits @@ -719,14 +759,14 @@ DESCRIPTION domain socket file. This option is only used for port forwarding to a Unix-domain socket file. - The argument must be ``yes'' or ``no''. The default is ``no''. + The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. StrictModes Specifies whether sshd(8) should check file modes and ownership of the user's files and home directory before accepting login. This is normally desirable because novices sometimes accidentally leave their directory or files world-writable. The default is - ``yes''. Note that this does not apply to ChrootDirectory, whose + M-bM-^@M-^\yesM-bM-^@M-^]. Note that this does not apply to ChrootDirectory, whose permissions and ownership are checked unconditionally. Subsystem @@ -734,11 +774,11 @@ DESCRIPTION Arguments should be a subsystem name and a command (with optional arguments) to execute upon subsystem request. - The command sftp-server(8) implements the ``sftp'' file transfer + The command sftp-server(8) implements the M-bM-^@M-^\sftpM-bM-^@M-^] file transfer subsystem. - Alternately the name ``internal-sftp'' implements an in-process - ``sftp'' server. This may simplify configurations using + Alternately the name M-bM-^@M-^\internal-sftpM-bM-^@M-^] implements an in-process + M-bM-^@M-^\sftpM-bM-^@M-^] server. This may simplify configurations using ChrootDirectory to force a different filesystem root on clients. By default no subsystems are defined. Note that this option @@ -757,21 +797,21 @@ DESCRIPTION this means that connections will die if the route is down temporarily, and some people find it annoying. On the other hand, if TCP keepalives are not sent, sessions may hang - indefinitely on the server, leaving ``ghost'' users and consuming + indefinitely on the server, leaving M-bM-^@M-^\ghostM-bM-^@M-^] users and consuming server resources. - The default is ``yes'' (to send TCP keepalive messages), and the + The default is M-bM-^@M-^\yesM-bM-^@M-^] (to send TCP keepalive messages), and the server will notice if the network goes down or the client host crashes. This avoids infinitely hanging sessions. To disable TCP keepalive messages, the value should be set to - ``no''. + M-bM-^@M-^\noM-bM-^@M-^]. TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication. Keys are listed one per line; empty lines and - comments starting with `#' are allowed. If a certificate is + comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are allowed. If a certificate is presented for authentication and has its signing CA key listed in this file, then it may be used for authentication for any user listed in the certificate's principals list. Note that @@ -781,18 +821,18 @@ DESCRIPTION UseDNS Specifies whether sshd(8) should look up the remote host name and check that the resolved host name for the remote IP address maps - back to the very same IP address. The default is ``yes''. + back to the very same IP address. The default is M-bM-^@M-^\noM-bM-^@M-^]. UseLogin Specifies whether login(1) is used for interactive login - sessions. The default is ``no''. Note that login(1) is never - used for remote command execution. Note also, that if this is + sessions. The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that login(1) is never used + for remote command execution. Note also, that if this is enabled, X11Forwarding will be disabled because login(1) does not know how to handle xauth(1) cookies. If UsePrivilegeSeparation is specified, it will be disabled after authentication. UsePAM Enables the Pluggable Authentication Module interface. If set to - ``yes'' this will enable PAM authentication using + M-bM-^@M-^\yesM-bM-^@M-^] this will enable PAM authentication using ChallengeResponseAuthentication and PasswordAuthentication in addition to PAM account and session module processing for all authentication types. @@ -802,7 +842,7 @@ DESCRIPTION either PasswordAuthentication or ChallengeResponseAuthentication. If UsePAM is enabled, you will not be able to run sshd(8) as a - non-root user. The default is ``no''. + non-root user. The default is M-bM-^@M-^\noM-bM-^@M-^]. UsePrivilegeSeparation Specifies whether sshd(8) separates privileges by creating an @@ -811,14 +851,14 @@ DESCRIPTION that has the privilege of the authenticated user. The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. The - default is ``yes''. If UsePrivilegeSeparation is set to - ``sandbox'' then the pre-authentication unprivileged process is - subject to additional restrictions. + default is M-bM-^@M-^\yesM-bM-^@M-^]. If UsePrivilegeSeparation is set to M-bM-^@M-^\sandboxM-bM-^@M-^] + then the pre-authentication unprivileged process is subject to + additional restrictions. VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default - is ``none''. + is M-bM-^@M-^\noneM-bM-^@M-^]. X11DisplayOffset Specifies the first display number available for sshd(8)'s X11 @@ -827,7 +867,7 @@ DESCRIPTION X11Forwarding Specifies whether X11 forwarding is permitted. The argument must - be ``yes'' or ``no''. The default is ``no''. + be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. When X11 forwarding is enabled, there may be additional exposure to the server and to client displays if the sshd(8) proxy display @@ -841,7 +881,7 @@ DESCRIPTION ssh_config(5)). A system administrator may have a stance in which they want to protect clients that may expose themselves to attack by unwittingly requesting X11 forwarding, which can - warrant a ``no'' setting. + warrant a M-bM-^@M-^\noM-bM-^@M-^] setting. Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users can always install their own @@ -853,12 +893,12 @@ DESCRIPTION to the loopback address or to the wildcard address. By default, sshd binds the forwarding server to the loopback address and sets the hostname part of the DISPLAY environment variable to - ``localhost''. This prevents remote hosts from connecting to the + M-bM-^@M-^\localhostM-bM-^@M-^]. This prevents remote hosts from connecting to the proxy display. However, some older X11 clients may not function - with this configuration. X11UseLocalhost may be set to ``no'' to + with this configuration. X11UseLocalhost may be set to M-bM-^@M-^\noM-bM-^@M-^] to specify that the forwarding server should be bound to the - wildcard address. The argument must be ``yes'' or ``no''. The - default is ``yes''. + wildcard address. The argument must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The + default is M-bM-^@M-^\yesM-bM-^@M-^]. XAuthLocation Specifies the full pathname of the xauth(1) program. The default @@ -870,7 +910,7 @@ TIME FORMATS time[qualifier], where time is a positive integer value and qualifier is one of the following: - seconds + M-bM-^_M-(noneM-bM-^_M-) seconds s | S seconds m | M minutes h | H hours @@ -903,4 +943,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 5.6 July 28, 2014 OpenBSD 5.6 +OpenBSD 5.7 February 20, 2015 OpenBSD 5.7 diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5 index 14ed45b2ced0..ca976e47f1c3 100644 --- a/crypto/openssh/sshd_config.5 +++ b/crypto/openssh/sshd_config.5 @@ -33,9 +33,9 @@ .\" (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_config.5,v 1.176 2014/07/28 15:40:08 schwarze Exp $ +.\" $OpenBSD: sshd_config.5,v 1.194 2015/02/20 23:46:01 djm Exp $ .\" $FreeBSD$ -.Dd $Mdocdate: July 28 2014 $ +.Dd $Mdocdate: February 20 2015 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -211,6 +211,18 @@ would restrict keyboard interactive authentication to the .Dq bsdauth device. .Pp +If the +.Dq publickey +method is listed more than once, +.Xr sshd 8 +verifies that keys that have been used successfully are not reused for +subsequent authentications. +For example, an +.Cm AuthenticationMethods +of +.Dq publickey,publickey +will require successful authentication using two different public keys. +.Pp This option is only available for SSH protocol 2 and will yield a fatal error if enabled if protocol 1 is also enabled. Note that each authentication method listed should also be explicitly enabled @@ -233,6 +245,13 @@ By default, no AuthorizedKeysCommand is run. Specifies the user under whose account the AuthorizedKeysCommand is run. It is recommended to use a dedicated user that has no other role on the host than running authorized keys commands. +If +.Cm AuthorizedKeysCommand +is specified but +.Cm AuthorizedKeysCommandUser +is not, then +.Xr sshd 8 +will refuse to start. .It Cm AuthorizedKeysFile Specifies the file that contains the public keys that can be used for user authentication. @@ -312,8 +331,10 @@ The default is Specifies the pathname of a directory to .Xr chroot 2 to after authentication. -All components of the pathname must be root-owned directories that are -not writable by any other user or group. +At session startup +.Xr sshd 8 +checks that all components of the pathname are root-owned directories +which are not writable by any other user or group. After the chroot, .Xr sshd 8 changes the working directory to the user's home directory. @@ -337,7 +358,6 @@ nodes such as .Xr stdin 4 , .Xr stdout 4 , .Xr stderr 4 , -.Xr arandom 4 and .Xr tty 4 devices. @@ -351,6 +371,13 @@ inside the chroot directory on some operating systems (see .Xr sftp-server 8 for details). .Pp +For safety, it is very important that the directory hierarchy be +prevented from modification by other processes on the system (especially +those outside the jail). +Misconfiguration can lead to unsafe environments which +.Xr sshd 8 +cannot detect. +.Pp The default is not to .Xr chroot 2 . .It Cm Ciphers @@ -401,7 +428,9 @@ chacha20-poly1305@openssh.com The list of available ciphers may also be obtained using the .Fl Q option of -.Xr ssh 1 . +.Xr ssh 1 +with an argument of +.Dq cipher . .It Cm ClientAliveCountMax Sets the number of client alive messages (see below) which may be sent without @@ -484,6 +513,14 @@ and finally See PATTERNS in .Xr ssh_config 5 for more information on patterns. +.It Cm FingerprintHash +Specifies the hash algorithm used when logging key fingerprints. +Valid options are: +.Dq md5 +and +.Dq sha256 . +The default is +.Dq sha256 . .It Cm ForceCommand Forces the execution of the command specified by .Cm ForceCommand , @@ -534,6 +571,17 @@ on logout. The default is .Dq yes . Note that this option applies to protocol version 2 only. +.It Cm HostbasedAcceptedKeyTypes +Specifies the key types that will be accepted for hostbased authentication +as a comma-separated pattern list. +The default +.Dq * +will allow all key types. +The +.Fl Q +option of +.Xr ssh 1 +may be used to list supported key types. .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed @@ -735,6 +783,13 @@ ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, diffie-hellman-group14-sha1 .Ed +.Pp +The list of available key exchange algorithms may also be obtained using the +.Fl Q +option of +.Xr ssh 1 +with an argument of +.Dq kex . .It Cm KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). @@ -754,18 +809,18 @@ The following forms may be used: .It .Cm ListenAddress .Sm off -.Ar host No | Ar IPv4_addr No | Ar IPv6_addr +.Ar host | Ar IPv4_addr | Ar IPv6_addr .Sm on .It .Cm ListenAddress .Sm off -.Ar host No | Ar IPv4_addr No : Ar port +.Ar host | Ar IPv4_addr : Ar port .Sm on .It .Cm ListenAddress .Sm off .Oo -.Ar host No | Ar IPv6_addr Oc : Ar port +.Ar host | Ar IPv6_addr Oc : Ar port .Sm on .El .Pp @@ -853,6 +908,13 @@ hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, hmac-sha2-256,hmac-sha2-512 .Ed +.Pp +The list of available MAC algorithms may also be obtained using the +.Fl Q +option of +.Xr ssh 1 +with an argument of +.Dq mac . .It Cm Match Introduces a conditional block. If all of the criteria on the @@ -863,7 +925,7 @@ set in the global section of the config file, until either another line or the end of the file. If a keyword appears in multiple .Cm Match -blocks that are satisified, only the first instance of the keyword is +blocks that are satisfied, only the first instance of the keyword is applied. .Pp The arguments to @@ -907,6 +969,7 @@ Available keywords are .Cm AcceptEnv , .Cm AllowAgentForwarding , .Cm AllowGroups , +.Cm AllowStreamLocalForwarding , .Cm AllowTcpForwarding , .Cm AllowUsers , .Cm AuthenticationMethods , @@ -921,8 +984,10 @@ Available keywords are .Cm ForceCommand , .Cm GatewayPorts , .Cm GSSAPIAuthentication , +.Cm HostbasedAcceptedKeyTypes , .Cm HostbasedAuthentication , .Cm HostbasedUsesNameFromPacketOnly , +.Cm IPQoS , .Cm KbdInteractiveAuthentication , .Cm KerberosAuthentication , .Cm MaxAuthTries , @@ -934,10 +999,15 @@ Available keywords are .Cm PermitTTY , .Cm PermitTunnel , .Cm PermitUserRC , +.Cm PubkeyAcceptedKeyTypes , .Cm PubkeyAuthentication , .Cm RekeyLimit , +.Cm RevokedKeys , .Cm RhostsRSAAuthentication , .Cm RSAAuthentication , +.Cm StreamLocalBindMask , +.Cm StreamLocalBindUnlink , +.Cm TrustedUserCAKeys , .Cm X11DisplayOffset , .Cm X11Forwarding and @@ -1071,6 +1141,10 @@ and .Dq ethernet . The default is .Dq no . +.Pp +Independent of this setting, the permissions of the selected +.Xr tun 4 +device must allow access to the user. .It Cm PermitTTY Specifies whether .Xr pty 4 @@ -1146,6 +1220,17 @@ Specifying .Dq 2,1 is identical to .Dq 1,2 . +.It Cm PubkeyAcceptedKeyTypes +Specifies the key types that will be accepted for public key authentication +as a comma-separated pattern list. +The default +.Dq * +will allow all key types. +The +.Fl Q +option of +.Xr ssh 1 +may be used to list supported key types. .It Cm PubkeyAuthentication Specifies whether public key authentication is allowed. The default is @@ -1312,7 +1397,7 @@ should look up the remote host name and check that the resolved host name for the remote IP address maps back to the very same IP address. The default is -.Dq yes . +.Dq no . .It Cm UseLogin Specifies whether .Xr login 1 diff --git a/crypto/openssh/ssherr.c b/crypto/openssh/ssherr.c index 49fbb71de755..4ca7939926c9 100644 --- a/crypto/openssh/ssherr.c +++ b/crypto/openssh/ssherr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */ +/* $OpenBSD: ssherr.c,v 1.4 2015/02/16 22:13:32 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -121,10 +121,20 @@ ssh_err(int n) return "agent not present"; case SSH_ERR_AGENT_NO_IDENTITIES: return "agent contains no identities"; + case SSH_ERR_BUFFER_READ_ONLY: + return "internal error: buffer is read-only"; case SSH_ERR_KRL_BAD_MAGIC: return "KRL file has invalid magic number"; case SSH_ERR_KEY_REVOKED: return "Key is revoked"; + case SSH_ERR_CONN_CLOSED: + return "Connection closed"; + case SSH_ERR_CONN_TIMEOUT: + return "Connection timed out"; + case SSH_ERR_CONN_CORRUPT: + return "Connection corrupted"; + case SSH_ERR_PROTOCOL_ERROR: + return "Protocol error"; default: return "unknown error"; } diff --git a/crypto/openssh/ssherr.h b/crypto/openssh/ssherr.h index 106f786ea4c4..6f771b4b78be 100644 --- a/crypto/openssh/ssherr.h +++ b/crypto/openssh/ssherr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.h,v 1.1 2014/04/30 05:29:56 djm Exp $ */ +/* $OpenBSD: ssherr.h,v 1.3 2015/01/30 01:13:33 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -73,6 +73,10 @@ #define SSH_ERR_BUFFER_READ_ONLY -49 #define SSH_ERR_KRL_BAD_MAGIC -50 #define SSH_ERR_KEY_REVOKED -51 +#define SSH_ERR_CONN_CLOSED -52 +#define SSH_ERR_CONN_TIMEOUT -53 +#define SSH_ERR_CONN_CORRUPT -54 +#define SSH_ERR_PROTOCOL_ERROR -55 /* Translate a numeric error code to a human-readable error string */ const char *ssh_err(int n); diff --git a/crypto/openssh/sshkey.c b/crypto/openssh/sshkey.c index fdd0c8a89ae2..476879033801 100644 --- a/crypto/openssh/sshkey.c +++ b/crypto/openssh/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.3 2014/07/03 01:45:38 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.15 2015/03/06 01:40:56 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -27,18 +27,23 @@ #include "includes.h" -#include +#include /* MIN MAX */ #include +#include +#ifdef WITH_OPENSSL #include #include #include +#endif #include "crypto_api.h" #include +#include #include #include +#include #ifdef HAVE_UTIL_H #include #endif /* HAVE_UTIL_H */ @@ -52,6 +57,7 @@ #include "digest.h" #define SSHKEY_INTERNAL #include "sshkey.h" +#include "match.h" /* openssh private key file format */ #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" @@ -67,7 +73,7 @@ /* Version identification string for SSH v1 identity files. */ #define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" -static int sshkey_from_blob_internal(const u_char *blob, size_t blen, +static int sshkey_from_blob_internal(struct sshbuf *buf, struct sshkey **keyp, int allow_cert); /* Supported key types */ @@ -181,12 +187,12 @@ sshkey_ecdsa_nid_from_name(const char *name) { const struct keytype *kt; - for (kt = keytypes; kt->type != -1; kt++) { - if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) - continue; - if (kt->name != NULL && strcmp(name, kt->name) == 0) - return kt->nid; - } + for (kt = keytypes; kt->type != -1; kt++) { + if (kt->type != KEY_ECDSA && kt->type != KEY_ECDSA_CERT) + continue; + if (kt->name != NULL && strcmp(name, kt->name) == 0) + return kt->nid; + } return -1; } @@ -217,9 +223,11 @@ key_alg_list(int certs_only, int plain_only) } int -sshkey_names_valid2(const char *names) +sshkey_names_valid2(const char *names, int allow_wildcard) { char *s, *cp, *p; + const struct keytype *kt; + int type; if (names == NULL || strcmp(names, "") == 0) return 0; @@ -227,9 +235,28 @@ sshkey_names_valid2(const char *names) return 0; for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { - switch (sshkey_type_from_name(p)) { - case KEY_RSA1: - case KEY_UNSPEC: + type = sshkey_type_from_name(p); + if (type == KEY_RSA1) { + free(s); + return 0; + } + if (type == KEY_UNSPEC) { + if (allow_wildcard) { + /* + * Try matching key types against the string. + * If any has a positive or negative match then + * the component is accepted. + */ + for (kt = keytypes; kt->type != -1; kt++) { + if (kt->type == KEY_RSA1) + continue; + if (match_pattern_list(kt->name, + p, strlen(p), 0) != 0) + break; + } + if (kt->type != -1) + continue; + } free(s); return 0; } @@ -797,13 +824,28 @@ to_blob_buf(const struct sshkey *key, struct sshbuf *b, int force_plain) } int -sshkey_to_blob_buf(const struct sshkey *key, struct sshbuf *b) +sshkey_putb(const struct sshkey *key, struct sshbuf *b) { return to_blob_buf(key, b, 0); } int -sshkey_plain_to_blob_buf(const struct sshkey *key, struct sshbuf *b) +sshkey_puts(const struct sshkey *key, struct sshbuf *b) +{ + struct sshbuf *tmp; + int r; + + if ((tmp = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + r = to_blob_buf(key, tmp, 0); + if (r == 0) + r = sshbuf_put_stringb(b, tmp); + sshbuf_free(tmp); + return r; +} + +int +sshkey_putb_plain(const struct sshkey *key, struct sshbuf *b) { return to_blob_buf(key, b, 1); } @@ -852,29 +894,18 @@ sshkey_plain_to_blob(const struct sshkey *key, u_char **blobp, size_t *lenp) } int -sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, +sshkey_fingerprint_raw(const struct sshkey *k, int dgst_alg, u_char **retp, size_t *lenp) { u_char *blob = NULL, *ret = NULL; size_t blob_len = 0; - int hash_alg = -1, r = SSH_ERR_INTERNAL_ERROR; + int r = SSH_ERR_INTERNAL_ERROR; if (retp != NULL) *retp = NULL; if (lenp != NULL) *lenp = 0; - - switch (dgst_type) { - case SSH_FP_MD5: - hash_alg = SSH_DIGEST_MD5; - break; - case SSH_FP_SHA1: - hash_alg = SSH_DIGEST_SHA1; - break; - case SSH_FP_SHA256: - hash_alg = SSH_DIGEST_SHA256; - break; - default: + if (ssh_digest_bytes(dgst_alg) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } @@ -899,7 +930,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, r = SSH_ERR_ALLOC_FAIL; goto out; } - if ((r = ssh_digest_memory(hash_alg, blob, blob_len, + if ((r = ssh_digest_memory(dgst_alg, blob, blob_len, ret, SSH_DIGEST_MAX_LENGTH)) != 0) goto out; /* success */ @@ -908,7 +939,7 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, ret = NULL; } if (lenp != NULL) - *lenp = ssh_digest_bytes(hash_alg); + *lenp = ssh_digest_bytes(dgst_alg); r = 0; out: free(ret); @@ -920,21 +951,45 @@ sshkey_fingerprint_raw(const struct sshkey *k, enum sshkey_fp_type dgst_type, } static char * -fingerprint_hex(u_char *dgst_raw, size_t dgst_raw_len) +fingerprint_b64(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) { - char *retval; - size_t i; + char *ret; + size_t plen = strlen(alg) + 1; + size_t rlen = ((dgst_raw_len + 2) / 3) * 4 + plen + 1; + int r; - if ((retval = calloc(1, dgst_raw_len * 3 + 1)) == NULL) + if (dgst_raw_len > 65536 || (ret = calloc(1, rlen)) == NULL) + return NULL; + strlcpy(ret, alg, rlen); + strlcat(ret, ":", rlen); + if (dgst_raw_len == 0) + return ret; + if ((r = b64_ntop(dgst_raw, dgst_raw_len, + ret + plen, rlen - plen)) == -1) { + explicit_bzero(ret, rlen); + free(ret); return NULL; - for (i = 0; i < dgst_raw_len; i++) { - char hex[4]; - snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); - strlcat(retval, hex, dgst_raw_len * 3 + 1); } + /* Trim padding characters from end */ + ret[strcspn(ret, "=")] = '\0'; + return ret; +} - /* Remove the trailing ':' character */ - retval[(dgst_raw_len * 3) - 1] = '\0'; +static char * +fingerprint_hex(const char *alg, u_char *dgst_raw, size_t dgst_raw_len) +{ + char *retval, hex[5]; + size_t i, rlen = dgst_raw_len * 3 + strlen(alg) + 2; + + if (dgst_raw_len > 65536 || (retval = calloc(1, rlen)) == NULL) + return NULL; + strlcpy(retval, alg, rlen); + strlcat(retval, ":", rlen); + for (i = 0; i < dgst_raw_len; i++) { + snprintf(hex, sizeof(hex), "%s%02x", + i > 0 ? ":" : "", dgst_raw[i]); + strlcat(retval, hex, rlen); + } return retval; } @@ -1020,7 +1075,7 @@ fingerprint_bubblebabble(u_char *dgst_raw, size_t dgst_raw_len) #define FLDSIZE_Y (FLDBASE + 1) #define FLDSIZE_X (FLDBASE * 2 + 1) static char * -fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, +fingerprint_randomart(const char *alg, u_char *dgst_raw, size_t dgst_raw_len, const struct sshkey *k) { /* @@ -1028,9 +1083,9 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, * intersects with itself. Matter of taste. */ char *augmentation_string = " .o+=*BOX@%&#/^SE"; - char *retval, *p, title[FLDSIZE_X]; + char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; u_char field[FLDSIZE_X][FLDSIZE_Y]; - size_t i, tlen; + size_t i, tlen, hlen; u_int b; int x, y, r; size_t len = strlen(augmentation_string) - 1; @@ -1075,8 +1130,12 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, sshkey_type(k), sshkey_size(k)); /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ if (r < 0 || r > (int)sizeof(title)) - snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); - tlen = strlen(title); + r = snprintf(title, sizeof(title), "[%s]", sshkey_type(k)); + tlen = (r <= 0) ? 0 : strlen(title); + + /* assemble hash ID. */ + r = snprintf(hash, sizeof(hash), "[%s]", alg); + hlen = (r <= 0) ? 0 : strlen(hash); /* output upper border */ p = retval; @@ -1085,7 +1144,7 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, *p++ = '-'; memcpy(p, title, tlen); p += tlen; - for (i = p - retval - 1; i < FLDSIZE_X; i++) + for (i += tlen; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; *p++ = '\n'; @@ -1101,7 +1160,11 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, /* output lower border */ *p++ = '+'; - for (i = 0; i < FLDSIZE_X; i++) + for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) + *p++ = '-'; + memcpy(p, hash, hlen); + p += hlen; + for (i += hlen; i < FLDSIZE_X; i++) *p++ = '-'; *p++ = '+'; @@ -1109,24 +1172,39 @@ fingerprint_randomart(u_char *dgst_raw, size_t dgst_raw_len, } char * -sshkey_fingerprint(const struct sshkey *k, enum sshkey_fp_type dgst_type, +sshkey_fingerprint(const struct sshkey *k, int dgst_alg, enum sshkey_fp_rep dgst_rep) { char *retval = NULL; u_char *dgst_raw; size_t dgst_raw_len; - if (sshkey_fingerprint_raw(k, dgst_type, &dgst_raw, &dgst_raw_len) != 0) + if (sshkey_fingerprint_raw(k, dgst_alg, &dgst_raw, &dgst_raw_len) != 0) return NULL; switch (dgst_rep) { + case SSH_FP_DEFAULT: + if (dgst_alg == SSH_DIGEST_MD5) { + retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); + } else { + retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); + } + break; case SSH_FP_HEX: - retval = fingerprint_hex(dgst_raw, dgst_raw_len); + retval = fingerprint_hex(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); + break; + case SSH_FP_BASE64: + retval = fingerprint_b64(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len); break; case SSH_FP_BUBBLEBABBLE: retval = fingerprint_bubblebabble(dgst_raw, dgst_raw_len); break; case SSH_FP_RANDOMART: - retval = fingerprint_randomart(dgst_raw, dgst_raw_len, k); + retval = fingerprint_randomart(ssh_digest_alg_name(dgst_alg), + dgst_raw, dgst_raw_len, k); break; default: explicit_bzero(dgst_raw, dgst_raw_len); @@ -1233,16 +1311,20 @@ sshkey_read(struct sshkey *ret, char **cpp) cp = space+1; if (*cp == '\0') return SSH_ERR_INVALID_FORMAT; - if (ret->type == KEY_UNSPEC) { - ret->type = type; - } else if (ret->type != type) + if (ret->type != KEY_UNSPEC && ret->type != type) return SSH_ERR_KEY_TYPE_MISMATCH; if ((blob = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; /* trim comment */ space = strchr(cp, ' '); - if (space) - *space = '\0'; + if (space) { + /* advance 'space': skip whitespace */ + *space++ = '\0'; + while (*space == ' ' || *space == '\t') + space++; + *cpp = space; + } else + *cpp = cp + strlen(cp); if ((r = sshbuf_b64tod(blob, cp)) != 0) { sshbuf_free(blob); return r; @@ -1262,7 +1344,7 @@ sshkey_read(struct sshkey *ret, char **cpp) sshkey_free(k); return SSH_ERR_EC_CURVE_MISMATCH; } -/*XXXX*/ + ret->type = type; if (sshkey_is_cert(ret)) { if (!sshkey_is_cert(k)) { sshkey_free(k); @@ -1319,12 +1401,6 @@ sshkey_read(struct sshkey *ret, char **cpp) sshkey_free(k); if (retval != 0) break; - /* advance cp: skip whitespace and data */ - while (*cp == ' ' || *cp == '\t') - cp++; - while (*cp != '\0' && *cp != ' ' && *cp != '\t') - cp++; - *cpp = cp; break; default: return SSH_ERR_INVALID_ARGUMENT; @@ -1389,7 +1465,7 @@ sshkey_write(const struct sshkey *key, FILE *f) ret = SSH_ERR_ALLOC_FAIL; goto out; } - if ((ret = sshkey_to_blob_buf(key, bb)) != 0) + if ((ret = sshkey_putb(key, bb)) != 0) goto out; if ((uu = sshbuf_dtob64(bb)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; @@ -1766,38 +1842,30 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) } static int -cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob, - size_t blen) +cert_parse(struct sshbuf *b, struct sshkey *key, struct sshbuf *certbuf) { - u_char *principals = NULL, *critical = NULL, *exts = NULL; - u_char *sig_key = NULL, *sig = NULL; - size_t signed_len, plen, clen, sklen, slen, kidlen, elen; - struct sshbuf *tmp; - char *principal; + struct sshbuf *principals = NULL, *crit = NULL; + struct sshbuf *exts = NULL, *ca = NULL; + u_char *sig = NULL; + size_t signed_len = 0, slen = 0, kidlen = 0; int ret = SSH_ERR_INTERNAL_ERROR; int v00 = sshkey_cert_is_legacy(key); - char **oprincipals; - - if ((tmp = sshbuf_new()) == NULL) - return SSH_ERR_ALLOC_FAIL; /* Copy the entire key blob for verification and later serialisation */ - if ((ret = sshbuf_put(key->cert->certblob, blob, blen)) != 0) + if ((ret = sshbuf_putb(key->cert->certblob, certbuf)) != 0) return ret; - elen = 0; /* Not touched for v00 certs */ - principals = exts = critical = sig_key = sig = NULL; if ((!v00 && (ret = sshbuf_get_u64(b, &key->cert->serial)) != 0) || (ret = sshbuf_get_u32(b, &key->cert->type)) != 0 || (ret = sshbuf_get_cstring(b, &key->cert->key_id, &kidlen)) != 0 || - (ret = sshbuf_get_string(b, &principals, &plen)) != 0 || + (ret = sshbuf_froms(b, &principals)) != 0 || (ret = sshbuf_get_u64(b, &key->cert->valid_after)) != 0 || (ret = sshbuf_get_u64(b, &key->cert->valid_before)) != 0 || - (ret = sshbuf_get_string(b, &critical, &clen)) != 0 || - (!v00 && (ret = sshbuf_get_string(b, &exts, &elen)) != 0) || + (ret = sshbuf_froms(b, &crit)) != 0 || + (!v00 && (ret = sshbuf_froms(b, &exts)) != 0) || (v00 && (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0) || (ret = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || - (ret = sshbuf_get_string(b, &sig_key, &sklen)) != 0) { + (ret = sshbuf_froms(b, &ca)) != 0) { /* XXX debug print error for ret */ ret = SSH_ERR_INVALID_FORMAT; goto out; @@ -1817,14 +1885,17 @@ cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob, goto out; } - if ((ret = sshbuf_put(tmp, principals, plen)) != 0) - goto out; - while (sshbuf_len(tmp) > 0) { + /* Parse principals section */ + while (sshbuf_len(principals) > 0) { + char *principal = NULL; + char **oprincipals = NULL; + if (key->cert->nprincipals >= SSHKEY_CERT_MAX_PRINCIPALS) { ret = SSH_ERR_INVALID_FORMAT; goto out; } - if ((ret = sshbuf_get_cstring(tmp, &principal, &plen)) != 0) { + if ((ret = sshbuf_get_cstring(principals, &principal, + NULL)) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } @@ -1841,38 +1912,38 @@ cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob, key->cert->principals[key->cert->nprincipals++] = principal; } - sshbuf_reset(tmp); - - if ((ret = sshbuf_put(key->cert->critical, critical, clen)) != 0 || - (ret = sshbuf_put(tmp, critical, clen)) != 0) + /* + * Stash a copies of the critical options and extensions sections + * for later use. + */ + if ((ret = sshbuf_putb(key->cert->critical, crit)) != 0 || + (exts != NULL && + (ret = sshbuf_putb(key->cert->extensions, exts)) != 0)) goto out; - /* validate structure */ - while (sshbuf_len(tmp) != 0) { - if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 || - (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) { + /* + * Validate critical options and extensions sections format. + * NB. extensions are not present in v00 certs. + */ + while (sshbuf_len(crit) != 0) { + if ((ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0 || + (ret = sshbuf_get_string_direct(crit, NULL, NULL)) != 0) { + sshbuf_reset(key->cert->critical); ret = SSH_ERR_INVALID_FORMAT; goto out; } } - sshbuf_reset(tmp); - - if ((ret = sshbuf_put(key->cert->extensions, exts, elen)) != 0 || - (ret = sshbuf_put(tmp, exts, elen)) != 0) - goto out; - - /* validate structure */ - while (sshbuf_len(tmp) != 0) { - if ((ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0 || - (ret = sshbuf_get_string_direct(tmp, NULL, NULL)) != 0) { + while (exts != NULL && sshbuf_len(exts) != 0) { + if ((ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0 || + (ret = sshbuf_get_string_direct(exts, NULL, NULL)) != 0) { + sshbuf_reset(key->cert->extensions); ret = SSH_ERR_INVALID_FORMAT; goto out; } } - sshbuf_reset(tmp); - if (sshkey_from_blob_internal(sig_key, sklen, - &key->cert->signature_key, 0) != 0) { + /* Parse CA key and check signature */ + if (sshkey_from_blob_internal(ca, &key->cert->signature_key, 0) != 0) { ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; goto out; } @@ -1880,50 +1951,49 @@ cert_parse(struct sshbuf *b, struct sshkey *key, const u_char *blob, ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; goto out; } - if ((ret = sshkey_verify(key->cert->signature_key, sig, slen, sshbuf_ptr(key->cert->certblob), signed_len, 0)) != 0) goto out; - ret = 0; + /* Success */ + ret = 0; out: - sshbuf_free(tmp); - free(principals); - free(critical); - free(exts); - free(sig_key); + sshbuf_free(ca); + sshbuf_free(crit); + sshbuf_free(exts); + sshbuf_free(principals); free(sig); return ret; } static int -sshkey_from_blob_internal(const u_char *blob, size_t blen, - struct sshkey **keyp, int allow_cert) +sshkey_from_blob_internal(struct sshbuf *b, struct sshkey **keyp, + int allow_cert) { - struct sshbuf *b = NULL; - int type, nid = -1, ret = SSH_ERR_INTERNAL_ERROR; + int type, ret = SSH_ERR_INTERNAL_ERROR; char *ktype = NULL, *curve = NULL; struct sshkey *key = NULL; size_t len; u_char *pk = NULL; + struct sshbuf *copy; #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) EC_POINT *q = NULL; #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ #ifdef DEBUG_PK /* XXX */ - dump_base64(stderr, blob, blen); + sshbuf_dump(b, stderr); #endif *keyp = NULL; - if ((b = sshbuf_from(blob, blen)) == NULL) - return SSH_ERR_ALLOC_FAIL; + if ((copy = sshbuf_fromb(b)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } type = sshkey_type_from_name(ktype); - if (sshkey_type_plain(type) == KEY_ECDSA) - nid = sshkey_ecdsa_nid_from_name(ktype); if (!allow_cert && sshkey_type_is_cert(type)) { ret = SSH_ERR_KEY_CERT_INVALID_SIGN_KEY; goto out; @@ -1931,6 +2001,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, switch (type) { #ifdef WITH_OPENSSL case KEY_RSA_CERT: + /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; @@ -1952,6 +2023,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, #endif break; case KEY_DSA_CERT: + /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; @@ -1975,6 +2047,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, #endif break; case KEY_ECDSA_CERT: + /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; @@ -1986,7 +2059,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, ret = SSH_ERR_ALLOC_FAIL; goto out; } - key->ecdsa_nid = nid; + key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype); if (sshbuf_get_cstring(b, &curve, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; @@ -2027,6 +2100,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ case KEY_ED25519_CERT: + /* Skip nonce */ if (sshbuf_get_string_direct(b, NULL, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; @@ -2058,8 +2132,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, } /* Parse certificate potion */ - if (sshkey_is_cert(key) && - (ret = cert_parse(b, key, blob, blen)) != 0) + if (sshkey_is_cert(key) && (ret = cert_parse(b, key, copy)) != 0) goto out; if (key != NULL && sshbuf_len(b) != 0) { @@ -2070,7 +2143,7 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, *keyp = key; key = NULL; out: - sshbuf_free(b); + sshbuf_free(copy); sshkey_free(key); free(ktype); free(curve); @@ -2085,7 +2158,33 @@ sshkey_from_blob_internal(const u_char *blob, size_t blen, int sshkey_from_blob(const u_char *blob, size_t blen, struct sshkey **keyp) { - return sshkey_from_blob_internal(blob, blen, keyp, 1); + struct sshbuf *b; + int r; + + if ((b = sshbuf_from(blob, blen)) == NULL) + return SSH_ERR_ALLOC_FAIL; + r = sshkey_from_blob_internal(b, keyp, 1); + sshbuf_free(b); + return r; +} + +int +sshkey_fromb(struct sshbuf *b, struct sshkey **keyp) +{ + return sshkey_from_blob_internal(b, keyp, 1); +} + +int +sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) +{ + struct sshbuf *b; + int r; + + if ((r = sshbuf_froms(buf, &b)) != 0) + return r; + r = sshkey_from_blob_internal(b, keyp, 1); + sshbuf_free(b); + return r; } int @@ -2131,10 +2230,7 @@ sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, const u_char *data, size_t dlen, u_int compat) { - if (siglen == 0) - return -1; - - if (dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) + if (siglen == 0 || dlen > SSH_KEY_MAX_SIGN_DATA_SIZE) return SSH_ERR_INVALID_ARGUMENT; switch (key->type) { #ifdef WITH_OPENSSL @@ -2368,6 +2464,7 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca) break; default: ret = SSH_ERR_INVALID_ARGUMENT; + goto out; } /* -v01 certs have a serial number next */ @@ -2593,8 +2690,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) { char *tname = NULL, *curve = NULL; struct sshkey *k = NULL; - const u_char *cert; - size_t len, pklen = 0, sklen = 0; + size_t pklen = 0, sklen = 0; int type, r = SSH_ERR_INTERNAL_ERROR; u_char *ed25519_pk = NULL, *ed25519_sk = NULL; #ifdef WITH_OPENSSL @@ -2622,8 +2718,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) break; case KEY_DSA_CERT_V00: case KEY_DSA_CERT: - if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || - (r = sshkey_from_blob(cert, len, &k)) != 0 || + if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_bignum2(buf, k->dsa->priv_key)) != 0) goto out; @@ -2666,8 +2761,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || - (r = sshkey_from_blob(cert, len, &k)) != 0 || + if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_bignum2(buf, exponent)) != 0) goto out; @@ -2697,8 +2791,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) break; case KEY_RSA_CERT_V00: case KEY_RSA_CERT: - if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || - (r = sshkey_from_blob(cert, len, &k)) != 0 || + if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_bignum2(buf, k->rsa->d) != 0) || (r = sshbuf_get_bignum2(buf, k->rsa->iqmp) != 0) || @@ -2725,8 +2818,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) ed25519_pk = ed25519_sk = NULL; break; case KEY_ED25519_CERT: - if ((r = sshbuf_get_string_direct(buf, &cert, &len)) != 0 || - (r = sshkey_from_blob(cert, len, &k)) != 0 || + if ((r = sshkey_froms(buf, &k)) != 0 || (r = sshkey_add_private(k)) != 0 || (r = sshbuf_get_string(buf, &ed25519_pk, &pklen)) != 0 || (r = sshbuf_get_string(buf, &ed25519_sk, &sklen)) != 0) @@ -2952,8 +3044,9 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, const char *passphrase, const char *comment, const char *ciphername, int rounds) { - u_char *cp, *b64 = NULL, *key = NULL, *pubkeyblob = NULL; + u_char *cp, *key = NULL, *pubkeyblob = NULL; u_char salt[SALT_LEN]; + char *b64 = NULL; size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; u_int check; int r = SSH_ERR_INTERNAL_ERROR; @@ -3165,7 +3258,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, } /* decode base64 */ - if ((r = sshbuf_b64tod(decoded, sshbuf_ptr(encoded))) != 0) + if ((r = sshbuf_b64tod(decoded, (char *)sshbuf_ptr(encoded))) != 0) goto out; /* check magic */ @@ -3481,10 +3574,12 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, int force_new_format, const char *new_format_cipher, int new_format_rounds) { switch (key->type) { -#ifdef WITH_OPENSSL +#ifdef WITH_SSH1 case KEY_RSA1: return sshkey_private_rsa1_to_blob(key, blob, passphrase, comment); +#endif /* WITH_SSH1 */ +#ifdef WITH_OPENSSL case KEY_DSA: case KEY_ECDSA: case KEY_RSA: @@ -3690,20 +3785,16 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, #endif /* WITH_SSH1 */ #ifdef WITH_OPENSSL -/* XXX make private once ssh-keysign.c fixed */ -int +static int sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, - const char *passphrase, struct sshkey **keyp, char **commentp) + const char *passphrase, struct sshkey **keyp) { EVP_PKEY *pk = NULL; struct sshkey *prv = NULL; - char *name = ""; BIO *bio = NULL; int r; *keyp = NULL; - if (commentp != NULL) - *commentp = NULL; if ((bio = BIO_new(BIO_s_mem())) == NULL || sshbuf_len(blob) > INT_MAX) return SSH_ERR_ALLOC_FAIL; @@ -3726,7 +3817,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, } prv->rsa = EVP_PKEY_get1_RSA(pk); prv->type = KEY_RSA; - name = "rsa w/o comment"; #ifdef DEBUG_PK RSA_print_fp(stderr, prv->rsa, 8); #endif @@ -3742,7 +3832,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, } prv->dsa = EVP_PKEY_get1_DSA(pk); prv->type = KEY_DSA; - name = "dsa w/o comment"; #ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8); #endif @@ -3764,7 +3853,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_INVALID_FORMAT; goto out; } - name = "ecdsa w/o comment"; # ifdef DEBUG_PK if (prv != NULL && prv->ecdsa != NULL) sshkey_dump_ec_key(prv->ecdsa); @@ -3774,11 +3862,6 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_INVALID_FORMAT; goto out; } - if (commentp != NULL && - (*commentp = strdup(name)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } r = 0; *keyp = prv; prv = NULL; @@ -3803,15 +3886,17 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, *commentp = NULL; switch (type) { -#ifdef WITH_OPENSSL +#ifdef WITH_SSH1 case KEY_RSA1: return sshkey_parse_private_rsa1(blob, passphrase, keyp, commentp); +#endif /* WITH_SSH1 */ +#ifdef WITH_OPENSSL case KEY_DSA: case KEY_ECDSA: case KEY_RSA: - return sshkey_parse_private_pem_fileblob(blob, type, passphrase, - keyp, commentp); + return sshkey_parse_private_pem_fileblob(blob, type, + passphrase, keyp); #endif /* WITH_OPENSSL */ case KEY_ED25519: return sshkey_parse_private2(blob, type, passphrase, @@ -3821,8 +3906,8 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, commentp)) == 0) return 0; #ifdef WITH_OPENSSL - return sshkey_parse_private_pem_fileblob(blob, type, passphrase, - keyp, commentp); + return sshkey_parse_private_pem_fileblob(blob, type, + passphrase, keyp); #else return SSH_ERR_INVALID_FORMAT; #endif /* WITH_OPENSSL */ diff --git a/crypto/openssh/sshkey.h b/crypto/openssh/sshkey.h index 450b30c1f379..62c1c3e2fdb1 100644 --- a/crypto/openssh/sshkey.h +++ b/crypto/openssh/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.1 2014/06/24 01:16:58 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.5 2015/01/26 02:59:11 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -67,16 +67,14 @@ enum sshkey_types { KEY_UNSPEC }; -/* Fingerprint hash algorithms */ -enum sshkey_fp_type { - SSH_FP_SHA1, - SSH_FP_MD5, - SSH_FP_SHA256 -}; +/* Default fingerprint hash */ +#define SSH_FP_HASH_DEFAULT SSH_DIGEST_SHA256 /* Fingerprint representation formats */ enum sshkey_fp_rep { + SSH_FP_DEFAULT = 0, SSH_FP_HEX, + SSH_FP_BASE64, SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART }; @@ -124,9 +122,9 @@ int sshkey_equal_public(const struct sshkey *, const struct sshkey *); int sshkey_equal(const struct sshkey *, const struct sshkey *); char *sshkey_fingerprint(const struct sshkey *, - enum sshkey_fp_type, enum sshkey_fp_rep); + int, enum sshkey_fp_rep); int sshkey_fingerprint_raw(const struct sshkey *k, - enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp); + int, u_char **retp, size_t *lenp); const char *sshkey_type(const struct sshkey *); const char *sshkey_cert_type(const struct sshkey *); int sshkey_write(const struct sshkey *, FILE *); @@ -158,14 +156,17 @@ int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); int sshkey_ec_validate_private(const EC_KEY *); const char *sshkey_ssh_name(const struct sshkey *); const char *sshkey_ssh_name_plain(const struct sshkey *); -int sshkey_names_valid2(const char *); +int sshkey_names_valid2(const char *, int); char *key_alg_list(int, int); int sshkey_from_blob(const u_char *, size_t, struct sshkey **); -int sshkey_to_blob_buf(const struct sshkey *, struct sshbuf *); +int sshkey_fromb(struct sshbuf *, struct sshkey **); +int sshkey_froms(struct sshbuf *, struct sshkey **); int sshkey_to_blob(const struct sshkey *, u_char **, size_t *); -int sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *); +int sshkey_putb(const struct sshkey *, struct sshbuf *); +int sshkey_puts(const struct sshkey *, struct sshbuf *); int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *); +int sshkey_putb_plain(const struct sshkey *, struct sshbuf *); int sshkey_sign(const struct sshkey *, u_char **, size_t *, const u_char *, size_t, u_int); @@ -186,8 +187,6 @@ int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, int force_new_format, const char *new_format_cipher, int new_format_rounds); int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, struct sshkey **keyp, char **commentp); -int sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, - const char *passphrase, struct sshkey **keyp, char **commentp); int sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, const char *filename, struct sshkey **keyp, char **commentp); diff --git a/crypto/openssh/sshlogin.c b/crypto/openssh/sshlogin.c index 7b951c844e8a..818312ff129b 100644 --- a/crypto/openssh/sshlogin.c +++ b/crypto/openssh/sshlogin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshlogin.c,v 1.29 2014/07/15 15:54:14 millert Exp $ */ +/* $OpenBSD: sshlogin.c,v 1.31 2015/01/20 23:14:00 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -42,7 +42,6 @@ #include "includes.h" #include -#include #include #include @@ -54,6 +53,7 @@ #include #include #include +#include #include "loginrec.h" #include "log.h" @@ -88,7 +88,7 @@ static void store_lastlog_message(const char *user, uid_t uid) { #ifndef NO_SSH_LASTLOG - char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512]; + char *time_string, hostname[HOST_NAME_MAX+1] = "", buf[512]; time_t last_login_time; if (!options.print_lastlog) diff --git a/crypto/openssh/sshpty.c b/crypto/openssh/sshpty.c index a2059b76d816..d2ff8c16a44a 100644 --- a/crypto/openssh/sshpty.c +++ b/crypto/openssh/sshpty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshpty.c,v 1.28 2007/09/11 23:49:09 stevesk Exp $ */ +/* $OpenBSD: sshpty.c,v 1.29 2014/09/03 18:55:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -196,13 +196,8 @@ pty_setowner(struct passwd *pw, const char *tty) /* Determine the group to make the owner of the tty. */ grp = getgrnam("tty"); - if (grp) { - gid = grp->gr_gid; - mode = S_IRUSR | S_IWUSR | S_IWGRP; - } else { - gid = pw->pw_gid; - mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; - } + gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid; + mode = (grp != NULL) ? 0622 : 0600; /* * Change owner and mode of the tty as required. diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c index 1f09d58876db..c339283af747 100644 --- a/crypto/openssh/uidswap.c +++ b/crypto/openssh/uidswap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uidswap.c,v 1.36 2013/11/08 11:15:19 dtucker Exp $ */ +/* $OpenBSD: uidswap.c,v 1.37 2015/01/16 06:40:12 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -14,11 +14,11 @@ #include "includes.h" -#include #include #include #include #include +#include #include #include diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index 809969e3fcdb..fe0609a12a7a 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -1,7 +1,7 @@ -/* $OpenBSD: version.h,v 1.71 2014/04/18 23:52:25 djm Exp $ */ +/* $OpenBSD: version.h,v 1.72 2015/03/04 18:53:53 djm Exp $ */ /* $FreeBSD$ */ -#define SSH_VERSION "OpenSSH_6.7" +#define SSH_VERSION "OpenSSH_6.8" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/crypto/openssh/xmalloc.c b/crypto/openssh/xmalloc.c index 2f1cd2306945..cd59dc2e5bef 100644 --- a/crypto/openssh/xmalloc.c +++ b/crypto/openssh/xmalloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.c,v 1.29 2014/01/04 17:50:55 tedu Exp $ */ +/* $OpenBSD: xmalloc.c,v 1.31 2015/02/06 23:21:59 millert Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -15,8 +15,10 @@ #include "includes.h" -#include #include +#ifdef HAVE_STDINT_H +#include +#endif #include #include #include @@ -44,8 +46,8 @@ xcalloc(size_t nmemb, size_t size) if (size == 0 || nmemb == 0) fatal("xcalloc: zero size"); - if (SIZE_T_MAX / nmemb < size) - fatal("xcalloc: nmemb * size > SIZE_T_MAX"); + if (SIZE_MAX / nmemb < size) + fatal("xcalloc: nmemb * size > SIZE_MAX"); ptr = calloc(nmemb, size); if (ptr == NULL) fatal("xcalloc: out of memory (allocating %zu bytes)", @@ -61,8 +63,8 @@ xrealloc(void *ptr, size_t nmemb, size_t size) if (new_size == 0) fatal("xrealloc: zero size"); - if (SIZE_T_MAX / nmemb < size) - fatal("xrealloc: nmemb * size > SIZE_T_MAX"); + if (SIZE_MAX / nmemb < size) + fatal("xrealloc: nmemb * size > SIZE_MAX"); if (ptr == NULL) new_ptr = malloc(new_size); else diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile index 203de26645c1..65bcdb054227 100644 --- a/secure/lib/libssh/Makefile +++ b/secure/lib/libssh/Makefile @@ -5,22 +5,24 @@ LIB= ssh PRIVATELIB= true SHLIB_MAJOR= 5 -SRCS= ssherr.c sshbuf.c sshkey.c sshbuf-getput-basic.c \ - sshbuf-misc.c sshbuf-getput-crypto.c -SRCS+= authfd.c authfile.c bufaux.c bufbn.c buffer.c \ - canohost.c channels.c cipher.c cipher-aes.c \ +SRCS= ssh_api.c ssherr.c sshbuf.c sshkey.c sshbuf-getput-basic.c \ + sshbuf-misc.c sshbuf-getput-crypto.c krl.o bitmap.o +SRCS+= authfd.c authfile.c bufaux.c bufbn.c bufec.c buffer.c \ + canohost.c channels.c cipher.c cipher-aes.c cipher-aesctr.c \ cipher-bf1.c cipher-ctr.c cipher-3des1.c cleanup.c \ - compat.c compress.c crc32.c deattack.c fatal.c hostfile.c \ - log.c match.c md-sha256.c moduli.c nchan.c packet.c \ + compat.c crc32.c deattack.c fatal.c hostfile.c \ + log.c match.c md-sha256.c moduli.c nchan.c packet.c opacket.c \ readpass.c rsa.c ttymodes.c xmalloc.c addrmatch.c \ - atomicio.c key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \ + atomicio.c key.c dispatch.c mac.c uidswap.c uuencode.c misc.c \ monitor_fdpass.c rijndael.c ssh-dss.c ssh-ecdsa.c ssh-rsa.c dh.c \ - kexdh.c kexgex.c kexdhc.c kexgexc.c bufec.c kexecdh.c kexecdhc.c \ msg.c progressmeter.c dns.c entropy.c umac.c umac128.c \ - ssh-pkcs11.c krl.c smult_curve25519_ref.c \ - kexc25519.c kexc25519c.c poly1305.c chacha.c cipher-chachapoly.c \ - ssh-ed25519.c digest-openssl.c hmac.c \ - sc25519.c ge25519.c fe25519.c ed25519.c verify.c hash.c blocks.c + ssh-pkcs11.c smult_curve25519_ref.c \ + poly1305.c chacha.c cipher-chachapoly.c \ + ssh-ed25519.c digest-openssl.c digest-libc.c hmac.c \ + sc25519.c ge25519.c fe25519.c ed25519.c verify.c hash.c blocks.c \ + kex.c kexdh.c kexgex.c kexecdh.c kexc25519.c \ + kexdhc.c kexgexc.c kexecdhc.c kexc25519c.c \ + kexdhs.c kexgexs.c kexecdhs.c kexc25519s.c # gss-genr.c should be in $SRCS but causes linking problems, so it is # compiled directly into sshd instead. diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile index 2974f6b9c114..debe2566bf47 100644 --- a/secure/usr.sbin/sshd/Makefile +++ b/secure/usr.sbin/sshd/Makefile @@ -10,8 +10,7 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ auth-chall.c auth2-chall.c groupaccess.c \ auth-skey.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \ auth2-none.c auth2-passwd.c auth2-pubkey.c \ - monitor_mm.c monitor.c monitor_wrap.c kexdhs.c kexgexs.c kexecdhs.c \ - kexc25519s.c auth-krb5.c \ + monitor_mm.c monitor.c monitor_wrap.c auth-krb5.c \ auth2-gss.c gss-serv.c gss-serv-krb5.c \ loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \ sftp-server.c sftp-common.c \