From 9169dee5c46ff1d9dfce5c97590347e20a54c84e Mon Sep 17 00:00:00 2001 From: des Date: Thu, 10 Mar 2016 20:10:25 +0000 Subject: [PATCH] Vendor import of OpenSSH 7.2p1. --- ChangeLog | 3206 +++++++++++++++++------- Makefile.in | 72 +- README | 2 +- README.platform | 3 + auth-bsdauth.c | 4 +- auth-krb5.c | 4 +- auth-options.c | 117 +- auth-pam.c | 3 +- auth.h | 4 +- auth2-pubkey.c | 36 +- authfd.c | 20 +- authfd.h | 6 +- authfile.c | 27 +- channels.c | 16 +- cipher.c | 5 +- clientloop.c | 195 +- clientloop.h | 4 +- config.h.in | 27 +- configure | 735 ++++-- configure.ac | 75 +- contrib/redhat/openssh.spec | 7 +- contrib/ssh-copy-id | 53 +- contrib/ssh-copy-id.1 | 5 + contrib/suse/openssh.spec | 2 +- defines.h | 7 + dh.h | 9 +- includes.h | 6 - kex.c | 168 +- kex.h | 13 +- kexc25519s.c | 6 +- kexdhs.c | 6 +- kexecdhs.c | 6 +- kexgexs.c | 6 +- key.c | 6 +- key.h | 5 +- krl.c | 23 +- krl.h | 3 +- loginrec.c | 3 + misc.c | 58 +- moduli.0 | 2 +- monitor.c | 39 +- monitor_wrap.c | 6 +- monitor_wrap.h | 4 +- mux.c | 34 +- myproposal.h | 23 +- opacket.c | 12 - opacket.h | 4 - openbsd-compat/bsd-misc.c | 8 + openbsd-compat/bsd-misc.h | 4 + openbsd-compat/bsd-poll.h | 4 +- openbsd-compat/glob.c | 1 + openbsd-compat/glob.h | 8 +- openbsd-compat/openbsd-compat.h | 1 - openbsd-compat/port-solaris.c | 136 + openbsd-compat/port-solaris.h | 6 + openbsd-compat/realpath.c | 61 +- packet.c | 366 +-- packet.h | 11 +- platform-pledge.c | 71 + platform.h | 5 + readconf.c | 110 +- readconf.h | 12 +- readpass.c | 4 +- regress/Makefile | 5 +- regress/agent-ptrace.sh | 5 + regress/cert-file.sh | 138 + regress/check-perm.c | 205 ++ regress/dhgex.sh | 6 +- regress/hostkey-rotate.sh | 20 +- regress/keys-command.sh | 6 + regress/keyscan.sh | 4 +- regress/limit-keytype.sh | 37 +- regress/principals-command.sh | 7 + regress/proxy-connect.sh | 5 +- regress/rekey.sh | 6 +- regress/setuid-allowed.c | 2 +- regress/sftp-chroot.sh | 5 + regress/unittests/sshkey/test_file.c | 42 +- regress/unittests/sshkey/test_fuzz.c | 102 +- regress/unittests/sshkey/test_sshkey.c | 46 +- roaming.h | 45 - roaming_client.c | 271 -- roaming_common.c | 241 -- roaming_dummy.c | 72 - roaming_serv.c | 31 - sandbox-pledge.c | 77 + sandbox-seccomp-filter.c | 3 + sandbox-solaris.c | 108 + sandbox-systrace.c | 36 +- scp.0 | 3 +- scp.1 | 5 +- scp.c | 14 +- servconf.c | 59 +- serverloop.c | 31 +- session.c | 52 +- sftp-client.c | 22 +- sftp-client.h | 6 + sftp-server-main.c | 4 +- sftp-server.0 | 2 +- sftp-server.c | 12 +- sftp.0 | 3 +- sftp.1 | 5 +- sftp.c | 3 +- ssh-add.0 | 2 +- ssh-add.c | 35 +- ssh-agent.0 | 14 +- ssh-agent.1 | 15 +- ssh-agent.c | 26 +- ssh-dss.c | 11 +- ssh-ecdsa.c | 14 +- ssh-keygen.0 | 23 +- ssh-keygen.1 | 18 +- ssh-keygen.c | 374 +-- ssh-keyscan.0 | 6 +- ssh-keyscan.1 | 8 +- ssh-keyscan.c | 71 +- ssh-keysign.0 | 5 +- ssh-keysign.8 | 6 +- ssh-keysign.c | 27 +- ssh-pkcs11-client.c | 4 +- ssh-pkcs11-helper.0 | 2 +- ssh-pkcs11-helper.c | 3 +- ssh-pkcs11.c | 8 +- ssh-rsa.c | 149 +- ssh.0 | 114 +- ssh.1 | 97 +- ssh.c | 148 +- ssh.h | 10 +- ssh2.h | 10 +- ssh_api.c | 16 +- ssh_config | 6 +- ssh_config.0 | 140 +- ssh_config.5 | 143 +- sshbuf-getput-basic.c | 8 +- sshbuf.c | 8 +- sshbuf.h | 65 +- sshconnect.c | 75 +- sshconnect.h | 4 +- sshconnect1.c | 15 +- sshconnect2.c | 265 +- sshd.0 | 44 +- sshd.8 | 55 +- sshd.c | 74 +- sshd_config | 4 +- sshd_config.0 | 128 +- sshd_config.5 | 64 +- ssherr.c | 4 +- sshkey.c | 210 +- sshkey.h | 17 +- sshlogin.c | 2 +- uidswap.c | 18 +- version.h | 6 +- xmalloc.c | 12 +- xmalloc.h | 3 +- 154 files changed, 6554 insertions(+), 3663 deletions(-) create mode 100644 platform-pledge.c create mode 100755 regress/cert-file.sh create mode 100644 regress/check-perm.c delete mode 100644 roaming_client.c delete mode 100644 roaming_common.c delete mode 100644 roaming_dummy.c delete mode 100644 roaming_serv.c create mode 100644 sandbox-pledge.c create mode 100644 sandbox-solaris.c diff --git a/ChangeLog b/ChangeLog index 35a1a76b146b..b01bb5642fb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,22 +1,1895 @@ -commit c88ac102f0eb89f2eaa314cb2e2e0ca3c890c443 +commit 72b061d4ba0f909501c595d709ea76e06b01e5c9 +Author: Darren Tucker +Date: Fri Feb 26 14:40:04 2016 +1100 + + Add a note about using xlc on AIX. + +commit fd4e4f2416baa2e6565ea49d52aade296bad3e28 +Author: Darren Tucker +Date: Wed Feb 24 10:44:25 2016 +1100 + + Skip PrintLastLog in config dump mode. + + When DISABLE_LASTLOG is set, do not try to include PrintLastLog in the + config dump since it'll be reported as UNKNOWN. + +commit 99135c764fa250801da5ec3b8d06cbd0111caae8 +Author: Damien Miller +Date: Tue Feb 23 20:17:23 2016 +1100 + + update spec/README versions ahead of release + +commit b86a334aaaa4d1e643eb1fd71f718573d6d948b5 +Author: Damien Miller +Date: Tue Feb 23 20:16:53 2016 +1100 + + put back portable patchlevel to p1 + +commit 555dd35ff176847e3c6bd068ba2e8db4022eb24f +Author: djm@openbsd.org +Date: Tue Feb 23 09:14:34 2016 +0000 + + upstream commit + + openssh-7.2 + + Upstream-ID: 9db776b26014147fc907ece8460ef2bcb0f11e78 + +commit 1acc058d0a7913838c830ed998a1a1fb5b7864bf +Author: Damien Miller +Date: Tue Feb 23 16:12:13 2016 +1100 + + Disable tests where fs perms are incorrect + + Some tests have strict requirements on the filesystem permissions + for certain files and directories. This adds a regress/check-perm + tool that copies the relevant logic from sshd to exactly test + the paths in question. This lets us skip tests when the local + filesystem doesn't conform to our expectations rather than + continuing and failing the test run. + + ok dtucker@ + +commit 39f303b1f36d934d8410b05625f25c7bcb75db4d +Author: Damien Miller +Date: Tue Feb 23 12:56:59 2016 +1100 + + fix sandbox on OSX Lion + + sshd was failing with: + + ssh_sandbox_child: sandbox_init: dlopen(/usr/lib/libsandbox.1.dylib, 261):cw + image not found [preauth] + + caused by chroot before sandboxing. Avoid by explicitly linking libsandbox + to sshd. Spotted by Darren. + +commit 0d1451a32c7436e6d3d482351e776bc5e7824ce4 +Author: djm@openbsd.org +Date: Tue Feb 23 01:34:14 2016 +0000 + + upstream commit + + fix spurious error message when incorrect passphrase + entered for keys; reported by espie@ ok deraadt@ + + Upstream-ID: 58b2e46e63ed6912ed1ee780bd3bd8560f9a5899 + +commit 09d87d79741beb85768b5e788d7dfdf4bc3543dc +Author: sobrado@openbsd.org +Date: Sat Feb 20 23:06:23 2016 +0000 + + upstream commit + + set ssh(1) protocol version to 2 only. + + ok djm@ + + Upstream-ID: e168daf9d27d7e392e3c9923826bd8e87b2b3a10 + +commit 9262e07826ba5eebf8423f7ac9e47ec488c47869 +Author: sobrado@openbsd.org +Date: Sat Feb 20 23:02:39 2016 +0000 + + upstream commit + + add missing ~/.ssh/id_ecdsa and ~/.ssh/id_ed25519 to + IdentityFile. + + ok djm@ + + Upstream-ID: 6ce99466312e4ae7708017c3665e3edb976f70cf + +commit c12f0fdce8f985fca8d71829fd64c5b89dc777f5 +Author: sobrado@openbsd.org +Date: Sat Feb 20 23:01:46 2016 +0000 + + upstream commit + + AddressFamily defaults to any. + + ok djm@ + + Upstream-ID: 0d94aa06a4b889bf57a7f631c45ba36d24c13e0c + +commit 907091acb188b1057d50c2158f74c3ecf1c2302b +Author: Darren Tucker +Date: Fri Feb 19 09:05:39 2016 +1100 + + Make Solaris privs code build on older systems. + + Not all systems with Solaris privs have priv_basicset so factor that + out and provide backward compatibility code. Similarly, not all have + PRIV_NET_ACCESS so wrap that in #ifdef. Based on code from + alex at cooperi.net and djm@ with help from carson at taltos.org and + wieland at purdue.edu. + +commit 292a8dee14e5e67dcd1b49ba5c7b9023e8420d59 +Author: djm@openbsd.org +Date: Wed Feb 17 22:20:14 2016 +0000 + + upstream commit + + rekey refactor broke SSH1; spotted by Tom G. Christensen + + Upstream-ID: 43f0d57928cc077c949af0bfa71ef574dcb58243 + +commit 3a13cb543df9919aec2fc6b75f3dd3802facaeca +Author: djm@openbsd.org +Date: Wed Feb 17 08:57:34 2016 +0000 + + upstream commit + + rsa-sha2-512,rsa-sha2-256 cannot be selected explicitly + in *KeyTypes options yet. Remove them from the lists of algorithms for now. + committing on behalf of markus@ ok djm@ + + Upstream-ID: c6e8820eb8e610ac21551832c0c89684a9a51bb7 + +commit a685ae8d1c24fb7c712c55a4f3280ee76f5f1e4b +Author: jmc@openbsd.org +Date: Wed Feb 17 07:38:19 2016 +0000 + + upstream commit + + since these pages now clearly tell folks to avoid v1, + normalise the docs from a v2 perspective (i.e. stop pointing out which bits + are v2 only); + + ok/tweaks djm ok markus + + Upstream-ID: eb474f8c36fb6a532dc05c282f7965e38dcfa129 + +commit c5c3f3279a0e4044b8de71b70d3570d692d0f29d +Author: djm@openbsd.org +Date: Wed Feb 17 05:29:04 2016 +0000 + + upstream commit + + make sandboxed privilege separation the default, not just + for new installs; "absolutely" deraadt@ + + Upstream-ID: 5221ef3b927d2df044e9aa3f5db74ae91743f69b + +commit eb3f7337a651aa01d5dec019025e6cdc124ed081 +Author: jmc@openbsd.org +Date: Tue Feb 16 07:47:54 2016 +0000 + + upstream commit + + no need to state that protocol 2 is the default twice; + + Upstream-ID: b1e4c36b0c2e12e338e5b66e2978f2ac953b95eb + +commit e7901efa9b24e5b0c7e74f2c5520d47eead4d005 +Author: djm@openbsd.org +Date: Tue Feb 16 05:11:04 2016 +0000 + + upstream commit + + Replace list of ciphers and MACs adjacent to -1/-2 flag + descriptions in ssh(1) with a strong recommendation not to use protocol 1. + Add a similar warning to the Protocol option descriptions in ssh_config(5) + and sshd_config(5); + + prompted by and ok mmcc@ + + Upstream-ID: 961f99e5437d50e636feca023978950a232ead5e + +commit 5a0fcb77287342e2fc2ba1cee79b6af108973dc2 +Author: djm@openbsd.org +Date: Tue Feb 16 03:37:48 2016 +0000 + + upstream commit + + add a "Close session" log entry (at loglevel=verbose) to + correspond to the existing "Starting session" one. Also include the session + id number to make multiplexed sessions more apparent. + + feedback and ok dtucker@ + + Upstream-ID: e72d2ac080e02774376325136e532cb24c2e617c + +commit 624fd395b559820705171f460dd33d67743d13d6 +Author: djm@openbsd.org +Date: Wed Feb 17 02:24:17 2016 +0000 + + upstream commit + + include bad $SSH_CONNECTION in failure output + + Upstream-Regress-ID: b22d72edfde78c403aaec2b9c9753ef633cc0529 + +commit 60d860e54b4f199e5e89963b1c086981309753cb +Author: Darren Tucker +Date: Wed Feb 17 13:37:09 2016 +1100 + + Rollback addition of va_start. + + va_start was added in 0f754e29dd3760fc0b172c1220f18b753fb0957e, however + it has the wrong number of args and it's not usable in non-variadic + functions anyway so it breaks things (for example Solaris 2.6 as + reported by Tom G. Christensen).i ok djm@ + +commit 2fee909c3cee2472a98b26eb82696297b81e0d38 +Author: Darren Tucker +Date: Wed Feb 17 09:48:15 2016 +1100 + + Look for gethostbyname in libresolv and libnsl. + + Should fix build problem on Solaris 2.6 reported by Tom G. Christensen. + +commit 5ac712d81a84396aab441a272ec429af5b738302 +Author: Damien Miller +Date: Tue Feb 16 10:45:02 2016 +1100 + + make existing ssh_malloc_init only for __OpenBSD__ + +commit 24c9bded569d9f2449ded73f92fb6d12db7a9eec +Author: djm@openbsd.org +Date: Mon Feb 15 23:32:37 2016 +0000 + + upstream commit + + memleak of algorithm name in mm_answer_sign; reported by + Jakub Jelen + + Upstream-ID: ccd742cd25952240ebd23d7d4d6b605862584d08 + +commit ffb1e7e896139a42ceb78676f637658f44612411 +Author: dtucker@openbsd.org +Date: Mon Feb 15 09:47:49 2016 +0000 + + upstream commit + + Add a function to enable security-related malloc_options. + With and ok deraadt@, something similar has been in the snaps for a while. + + Upstream-ID: 43a95523b832b7f3b943d2908662191110c380ed + +commit ef39e8c0497ff0564990a4f9e8b7338b3ba3507c +Author: Damien Miller +Date: Tue Feb 16 10:34:39 2016 +1100 + + sync ssh-copy-id with upstream 783ef08b0a75 + +commit d2d772f55b19bb0e8d03c2fe1b9bb176d9779efd +Author: djm@openbsd.org +Date: Fri Feb 12 00:20:30 2016 +0000 + + upstream commit + + avoid fatal() for PKCS11 tokens that present empty key IDs + bz#1773, ok markus@ + + Upstream-ID: 044a764fee526f2c4a9d530bd10695422d01fc54 + +commit e4c918a6c721410792b287c9fd21356a1bed5805 +Author: djm@openbsd.org +Date: Thu Feb 11 02:56:32 2016 +0000 + + upstream commit + + sync crypto algorithm lists in ssh_config(5) and + sshd_config(5) with current reality. bz#2527 + + Upstream-ID: d7fd1b6c1ed848d866236bcb1d7049d2bb9b2ff6 + +commit e30cabfa4ab456a30b3224f7f545f1bdfc4a2517 +Author: djm@openbsd.org +Date: Thu Feb 11 02:21:34 2016 +0000 + + upstream commit + + fix regression in openssh-6.8 sftp client: existing + destination directories would incorrectly terminate recursive uploads; + bz#2528 + + Upstream-ID: 3306be469f41f26758e3d447987ac6d662623e18 + +commit 714e367226ded4dc3897078be48b961637350b05 +Author: djm@openbsd.org +Date: Tue Feb 9 05:30:04 2016 +0000 + + upstream commit + + turn off more old crypto in the client: hmac-md5, ripemd, + truncated HMACs, RC4, blowfish. ok markus@ dtucker@ + + Upstream-ID: 96aa11c2c082be45267a690c12f1d2aae6acd46e + +commit 5a622844ff7f78dcb75e223399f9ef0977e8d0a3 +Author: djm@openbsd.org +Date: Mon Feb 8 23:40:12 2016 +0000 + + upstream commit + + don't attempt to percent_expand() already-canonicalised + addresses, avoiding unnecessary failures when attempting to connect to scoped + IPv6 addresses (that naturally contain '%' characters) + + Upstream-ID: f24569cffa1a7cbde5f08dc739a72f4d78aa5c6a + +commit 19bcf2ea2d17413f2d9730dd2a19575ff86b9b6a +Author: djm@openbsd.org +Date: Mon Feb 8 10:57:07 2016 +0000 + + upstream commit + + refactor activation of rekeying + + This makes automatic rekeying internal to the packet code (previously + the server and client loops needed to assist). In doing to it makes + application of rekey limits more accurate by accounting for packets + about to be sent as well as packets queued during rekeying events + themselves. + + Based on a patch from dtucker@ which was in turn based on a patch + Aleksander Adamowski in bz#2521; ok markus@ + + Upstream-ID: a441227fd64f9739850ca97b4cf794202860fcd8 + +commit 603ba41179e4b53951c7b90ee95b6ef3faa3f15d +Author: naddy@openbsd.org +Date: Fri Feb 5 13:28:19 2016 +0000 + + upstream commit + + Only check errno if read() has returned an error. EOF is + not an error. This fixes a problem where the mux master would sporadically + fail to notice that the client had exited. ok mikeb@ djm@ + + Upstream-ID: 3c2dadc21fac6ef64665688aac8a75fffd57ae53 + +commit 56d7dac790693ce420d225119283bc355cff9185 +Author: jsg@openbsd.org +Date: Fri Feb 5 04:31:21 2016 +0000 + + upstream commit + + avoid an uninitialised value when NumberOfPasswordPrompts + is 0 ok markus@ djm@ + + Upstream-ID: 11b068d83c2865343aeb46acf1e9eec00f829b6b + +commit deae7d52d59c5019c528f977360d87fdda15d20b +Author: djm@openbsd.org +Date: Fri Feb 5 03:07:06 2016 +0000 + + upstream commit + + mention internal DH-GEX fallback groups; bz#2302 + + Upstream-ID: e7b395fcca3122cd825515f45a2e41c9a157e09e + +commit cac3b6665f884d46192c0dc98a64112e8b11a766 +Author: djm@openbsd.org +Date: Fri Feb 5 02:37:56 2016 +0000 + + upstream commit + + better description for MaxSessions; bz#2531 + + Upstream-ID: e2c0d74ee185cd1a3e9d4ca1f1b939b745b354da + +commit 5ef4b0fdcc7a239577a754829b50022b91ab4712 +Author: Damien Miller +Date: Wed Jan 27 17:45:56 2016 +1100 + + avoid FreeBSD RCS Id in comment + + Change old $FreeBSD version string in comment so it doesn't + become an RCS ident downstream; requested by des AT des.no + +commit 696d12683c90d20a0a9c5f4275fc916b7011fb04 +Author: djm@openbsd.org +Date: Thu Feb 4 23:43:48 2016 +0000 + + upstream commit + + printf argument casts to avoid warnings on strict + compilers + + Upstream-ID: 7b9f6712cef01865ad29070262d366cf13587c9c + +commit 5658ef2501e785fbbdf5de2dc33b1ff7a4dca73a +Author: millert@openbsd.org +Date: Mon Feb 1 21:18:17 2016 +0000 + + upstream commit + + Avoid ugly "DISPLAY "(null)" invalid; disabling X11 + forwarding" message when DISPLAY is not set. This could also result in a + crash on systems with a printf that doesn't handle NULL. OK djm@ + + Upstream-ID: 20ee0cfbda678a247264c20ed75362042b90b412 + +commit 537f88ec7bcf40bd444ac5584c707c5588c55c43 +Author: dtucker@openbsd.org +Date: Fri Jan 29 05:18:15 2016 +0000 + + upstream commit + + Add regression test for RekeyLimit parsing of >32bit values + (4G and 8G). + + Upstream-Regress-ID: 548390350c62747b6234f522a99c319eee401328 + +commit 4c6cb8330460f94e6c7ae28a364236d4188156a3 +Author: dtucker@openbsd.org +Date: Fri Jan 29 23:04:46 2016 +0000 + + upstream commit + + Remove leftover roaming dead code. ok djm markus. + + Upstream-ID: 13d1f9c8b65a5109756bcfd3b74df949d53615be + +commit 28136471809806d6246ef41e4341467a39fe2f91 +Author: djm@openbsd.org +Date: Fri Jan 29 05:46:01 2016 +0000 + + upstream commit + + include packet type of non-data packets in debug3 output; + ok markus dtucker + + Upstream-ID: 034eaf639acc96459b9c5ce782db9fcd8bd02d41 + +commit 6fd6e28daccafaa35f02741036abe64534c361a1 +Author: dtucker@openbsd.org +Date: Fri Jan 29 03:31:03 2016 +0000 + + upstream commit + + Revert "account for packets buffered but not yet + processed" change as it breaks for very small RekeyLimit values due to + continuous rekeying. ok djm@ + + Upstream-ID: 7e03f636cb45ab60db18850236ccf19079182a19 + +commit 921ff00b0ac429666fb361d2d6cb1c8fff0006cb +Author: dtucker@openbsd.org +Date: Fri Jan 29 02:54:45 2016 +0000 + + upstream commit + + Allow RekeyLimits in excess of 4G up to 2**63 bits + (limited by the return type of scan_scaled). Part of bz#2521, ok djm. + + Upstream-ID: 13bea82be566b9704821b1ea05bf7804335c7979 + +commit c0060a65296f01d4634f274eee184c0e93ba0f23 +Author: dtucker@openbsd.org +Date: Fri Jan 29 02:42:46 2016 +0000 + + upstream commit + + Account for packets buffered but not yet processed when + computing whether or not it is time to perform rekeying. bz#2521, based + loosely on a patch from olo at fb.com, ok djm@ + + Upstream-ID: 67e268b547f990ed220f3cb70a5624d9bda12b8c + +commit 44cf930e670488c85c9efeb373fa5f4b455692ac +Author: djm@openbsd.org +Date: Wed Jan 27 06:44:58 2016 +0000 + + upstream commit + + change old $FreeBSD version string in comment so it doesn't + become an RCS ident downstream; requested by des AT des.no + + Upstream-ID: 8ca558c01f184e596b45e4fc8885534b2c864722 + +commit ebacd377769ac07d1bf3c75169644336056b7060 +Author: djm@openbsd.org +Date: Wed Jan 27 00:53:12 2016 +0000 + + upstream commit + + make the debug messages a bit more useful here + + Upstream-ID: 478ccd4e897e0af8486b294aa63aa3f90ab78d64 + +commit 458abc2934e82034c5c281336d8dc0f910aecad3 +Author: jsg@openbsd.org +Date: Sat Jan 23 05:31:35 2016 +0000 + + upstream commit + + Zero a stack buffer with explicit_bzero() instead of + memset() when returning from client_loop() for consistency with + buffer_free()/sshbuf_free(). + + ok dtucker@ deraadt@ djm@ + + Upstream-ID: bc9975b2095339811c3b954694d7d15ea5c58f66 + +commit 65a3c0dacbc7dbb75ddb6a70ebe22d8de084d0b0 +Author: dtucker@openbsd.org +Date: Wed Jan 20 09:22:39 2016 +0000 + + upstream commit + + Include sys/time.h for gettimeofday. From sortie at + maxsi.org. + + Upstream-ID: 6ed0c33b836d9de0a664cd091e86523ecaa2fb3b + +commit fc77ccdc2ce6d5d06628b8da5048a6a5f6ffca5a +Author: markus@openbsd.org +Date: Thu Jan 14 22:56:56 2016 +0000 + + upstream commit + + fd leaks; report Qualys Security Advisory team; ok + deraadt@ + + Upstream-ID: 4ec0f12b9d8fa202293c9effa115464185aa071d + +commit a306863831c57ec5fad918687cc5d289ee8e2635 +Author: markus@openbsd.org +Date: Thu Jan 14 16:17:39 2016 +0000 + + upstream commit + + remove roaming support; ok djm@ + + Upstream-ID: 2cab8f4b197bc95776fb1c8dc2859dad0c64dc56 + +commit 6ef49e83e30688504552ac10875feabd5521565f +Author: deraadt@openbsd.org +Date: Thu Jan 14 14:34:34 2016 +0000 + + upstream commit + + Disable experimental client-side roaming support. Server + side was disabled/gutted for years already, but this aspect was surprisingly + forgotten. Thanks for report from Qualys + + Upstream-ID: 2328004b58f431a554d4c1bf67f5407eae3389df + +commit 8d7b523b96d3be180572d9d338cedaafc0570f60 Author: Damien Miller Date: Thu Jan 14 11:08:19 2016 +1100 bump version numbers -commit 302bc21e6fadacb04b665868cd69b625ef69df90 +commit 8c3d512a1fac8b9c83b4d0c9c3f2376290bd84ca Author: Damien Miller Date: Thu Jan 14 11:04:04 2016 +1100 openssh-7.1p2 -commit 6b33763242c063e4e0593877e835eeb1fd1b60aa +commit e6c85f8889c5c9eb04796fdb76d2807636b9eef5 Author: Damien Miller -Date: Thu Jan 14 11:02:58 2016 +1100 +Date: Fri Jan 15 01:30:36 2016 +1100 forcibly disable roaming support in the client -commit 34d364f0d2e1e30a444009f0e04299bb7c94ba13 +commit ed4ce82dbfa8a3a3c8ea6fa0db113c71e234416c +Author: djm@openbsd.org +Date: Wed Jan 13 23:04:47 2016 +0000 + + upstream commit + + eliminate fallback from untrusted X11 forwarding to trusted + forwarding when the X server disables the SECURITY extension; Reported by + Thomas Hoger; ok deraadt@ + + Upstream-ID: f76195bd2064615a63ef9674a0e4096b0713f938 + +commit 9a728cc918fad67c8a9a71201088b1e150340ba4 +Author: djm@openbsd.org +Date: Tue Jan 12 23:42:54 2016 +0000 + + upstream commit + + use explicit_bzero() more liberally in the buffer code; ok + deraadt + + Upstream-ID: 0ece37069fd66bc6e4f55eb1321f93df372b65bf + +commit 4626cbaf78767fc8e9c86dd04785386c59ae0839 +Author: Damien Miller +Date: Fri Jan 8 14:24:56 2016 +1100 + + Support Illumos/Solaris fine-grained privileges + + Includes a pre-auth privsep sandbox and several pledge() + emulations. bz#2511, patch by Alex Wilson. + + ok dtucker@ + +commit 422d1b3ee977ff4c724b597fb2e437d38fc8de9d +Author: djm@openbsd.org +Date: Thu Dec 31 00:33:52 2015 +0000 + + upstream commit + + fix three bugs in KRL code related to (unused) signature + support: verification length was being incorrectly calculated, multiple + signatures were being incorrectly processed and a NULL dereference that + occurred when signatures were verified. Reported by Carl Jackson + + Upstream-ID: e705e97ad3ccce84291eaa651708dd1b9692576b + +commit 6074c84bf95d00f29cc7d5d3cd3798737851aa1a +Author: djm@openbsd.org +Date: Wed Dec 30 23:46:14 2015 +0000 + + upstream commit + + unused prototype + + Upstream-ID: f3eef4389d53ed6c0d5c77dcdcca3060c745da97 + +commit 6213f0e180e54122bb1ba928e11c784e2b4e5380 +Author: guenther@openbsd.org +Date: Sat Dec 26 20:51:35 2015 +0000 + + upstream commit + + Use pread/pwrite instead separate lseek+read/write for + lastlog. Cast to off_t before multiplication to avoid truncation on ILP32 + + ok kettenis@ mmcc@ + + Upstream-ID: fc40092568cd195719ddf1a00aa0742340d616cf + +commit d7d2bc95045a43dd56ea696cc1d030ac9d77e81f +Author: semarie@openbsd.org +Date: Sat Dec 26 07:46:03 2015 +0000 + + upstream commit + + adjust pledge promises for ControlMaster: when using + "ask" or "autoask", the process will use ssh-askpass for asking confirmation. + + problem found by halex@ + + ok halex@ + + Upstream-ID: 38a58b30ae3eef85051c74d3c247216ec0735f80 + +commit 271df8185d9689b3fb0523f58514481b858f6843 +Author: djm@openbsd.org +Date: Sun Dec 13 22:42:23 2015 +0000 + + upstream commit + + unbreak connections with peers that set + first_kex_follows; fix from Matt Johnston va bz#2515 + + Upstream-ID: decc88ec4fc7515594fdb42b04aa03189a44184b + +commit 43849a47c5f8687699eafbcb5604f6b9c395179f +Author: doug@openbsd.org +Date: Fri Dec 11 17:41:37 2015 +0000 + + upstream commit + + Add "id" to ssh-agent pledge for subprocess support. + + Found the hard way by Jan Johansson when using ssh-agent with X. Also, + rearranged proc/exec and retval to match other pledge calls in the tree. + + ok djm@ + + Upstream-ID: 914255f6850e5e7fa830a2de6c38605333b584db + +commit 52d7078421844b2f88329f5be3de370b0a938636 +Author: mmcc@openbsd.org +Date: Fri Dec 11 04:21:11 2015 +0000 + + upstream commit + + Remove NULL-checks before sshbuf_free(). + + ok djm@ + + Upstream-ID: 5ebed00ed5f9f03b119a345085e8774565466917 + +commit a4b9e0f4e4a6980a0eb8072f76ea611cab5b77e7 +Author: djm@openbsd.org +Date: Fri Dec 11 03:24:25 2015 +0000 + + upstream commit + + include remote port number in a few more messages; makes + tying log messages together into a session a bit easier; bz#2503 ok dtucker@ + + Upstream-ID: 9300dc354015f7a7368d94a8ff4a4266a69d237e + +commit 6091c362e89079397e68744ae30df121b0a72c07 +Author: djm@openbsd.org +Date: Fri Dec 11 03:20:09 2015 +0000 + + upstream commit + + don't try to load SSHv1 private key when compiled without + SSHv1 support. From Iain Morgan bz#2505 + + Upstream-ID: 8b8e7b02a448cf5e5635979df2d83028f58868a7 + +commit cce6a36bb95e81fa8bfb46daf22eabcf13afc352 +Author: djm@openbsd.org +Date: Fri Dec 11 03:19:09 2015 +0000 + + upstream commit + + use SSH_MAX_PUBKEY_BYTES consistently as buffer size when + reading key files. Increase it to match the size of the buffers already being + used. + + Upstream-ID: 1b60586b484b55a947d99a0b32bd25e0ced56fae + +commit 89540b6de025b80404a0cb8418c06377f3f98848 +Author: mmcc@openbsd.org +Date: Fri Dec 11 02:31:47 2015 +0000 + + upstream commit + + Remove NULL-checks before sshkey_free(). + + ok djm@ + + Upstream-ID: 3e35afe8a25e021216696b5d6cde7f5d2e5e3f52 + +commit 79394ed6d74572c2d2643d73937dad33727fc240 +Author: dtucker@openbsd.org +Date: Fri Dec 11 02:29:03 2015 +0000 + + upstream commit + + fflush stdout so that output is seen even when running in + debug mode when output may otherwise not be flushed. Patch from dustin at + null-ptr.net. + + Upstream-ID: b0c6b4cd2cdb01d7e9eefbffdc522e35b5bc4acc + +commit ee607cccb6636eb543282ba90e0677b0604d8b7a +Author: Darren Tucker +Date: Tue Dec 15 15:23:49 2015 +1100 + + Increase robustness of redhat/openssh.spec + + - remove configure --with-rsh, because this option isn't supported anymore + - replace last occurrence of BuildPreReq by BuildRequires + - update grep statement to query the krb5 include directory + + Patch from CarstenGrohmann via github, ok djm. + +commit b5fa0cd73555b991a543145603658d7088ec6b60 +Author: Darren Tucker +Date: Tue Dec 15 15:10:32 2015 +1100 + + Allow --without-ssl-engine with --without-openssl + + Patch from Mike Frysinger via github. + +commit c1d7e546f6029024f3257cc25c92f2bddf163125 +Author: Darren Tucker +Date: Tue Dec 15 14:27:09 2015 +1100 + + Include openssl crypto.h for SSLeay. + + Patch from doughdemon via github. + +commit c6f5f01651526e88c00d988ce59d71f481ebac62 +Author: Darren Tucker +Date: Tue Dec 15 13:59:12 2015 +1100 + + Add sys/time.h for gettimeofday. + + Should allow it it compile with MUSL libc. Based on patch from + doughdemon via github. + +commit 39736be06c7498ef57d6970f2d85cf066ae57c82 +Author: djm@openbsd.org +Date: Fri Dec 11 02:20:28 2015 +0000 + + upstream commit + + correct error messages; from Tomas Kuthan bz#2507 + + Upstream-ID: 7454a0affeab772398052954c79300aa82077093 + +commit 94141b7ade24afceeb6762a3f99e09e47a6c42b6 +Author: mmcc@openbsd.org +Date: Fri Dec 11 00:20:04 2015 +0000 + + upstream commit + + Pass (char *)NULL rather than (char *)0 to execl and + execlp. + + ok dtucker@ + + Upstream-ID: 56c955106cbddba86c3dd9bbf786ac0d1b361492 + +commit d59ce08811bf94111c2f442184cf7d1257ffae24 +Author: mmcc@openbsd.org +Date: Thu Dec 10 17:08:40 2015 +0000 + + upstream commit + + Remove NULL-checks before free(). + + ok dtucker@ + + Upstream-ID: e3d3cb1ce900179906af36517b5eea0fb15e6ef8 + +commit 8e56dd46cb37879c73bce2d6032cf5e7f82d5a71 +Author: mmcc@openbsd.org +Date: Thu Dec 10 07:01:35 2015 +0000 + + upstream commit + + Fix a couple "the the" typos. ok dtucker@ + + Upstream-ID: ec364c5af32031f013001fd28d1bd3dfacfe9a72 + +commit 6262a0522ddc2c0f2e9358dcb68d59b46e9c533e +Author: markus@openbsd.org +Date: Mon Dec 7 20:04:09 2015 +0000 + + upstream commit + + stricter encoding type checks for ssh-rsa; ok djm@ + + Upstream-ID: 8cca7c787599a5e8391e184d0b4f36fdc3665650 + +commit d86a3ba7af160c13496102aed861ae48a4297072 +Author: Damien Miller +Date: Wed Dec 9 09:18:45 2015 +1100 + + Don't set IPV6_V6ONLY on OpenBSD + + It isn't necessary and runs afoul of pledge(2) restrictions. + +commit da98c11d03d819a15429d8fff9688acd7505439f +Author: djm@openbsd.org +Date: Mon Dec 7 02:20:46 2015 +0000 + + upstream commit + + basic unit tests for rsa-sha2-* signature types + + Upstream-Regress-ID: 7dc4b9db809d578ff104d591b4d86560c3598d3c + +commit 3da893fdec9936dd2c23739cdb3c0c9d4c59fca0 +Author: markus@openbsd.org +Date: Sat Dec 5 20:53:21 2015 +0000 + + upstream commit + + prefer rsa-sha2-512 over -256 for hostkeys, too; noticed + by naddy@ + + Upstream-ID: 685f55f7ec566a8caca587750672723a0faf3ffe + +commit 8b56e59714d87181505e4678f0d6d39955caf10e +Author: tobias@openbsd.org +Date: Fri Dec 4 21:51:06 2015 +0000 + + upstream commit + + Properly handle invalid %-format by calling fatal. + + ok deraadt, djm + + Upstream-ID: 5692bce7d9f6eaa9c488cb93d3b55e758bef1eac + +commit 76c9fbbe35aabc1db977fb78e827644345e9442e +Author: markus@openbsd.org +Date: Fri Dec 4 16:41:28 2015 +0000 + + upstream commit + + implement SHA2-{256,512} for RSASSA-PKCS1-v1_5 signatures + (user and host auth) based on draft-rsa-dsa-sha2-256-03.txt and + draft-ssh-ext-info-04.txt; with & ok djm@ + + Upstream-ID: cf82ce532b2733e5c4b34bb7b7c94835632db309 + +commit 6064a8b8295cb5a17b5ebcfade53053377714f40 +Author: djm@openbsd.org +Date: Fri Dec 4 00:24:55 2015 +0000 + + upstream commit + + clean up agent_fd handling; properly initialise it to -1 + and make tests consistent + + ok markus@ + + Upstream-ID: ac9554323d5065745caf17b5e37cb0f0d4825707 + +commit b91926a97620f3e51761c271ba57aa5db790f48d +Author: semarie@openbsd.org +Date: Thu Dec 3 17:00:18 2015 +0000 + + upstream commit + + pledges ssh client: - mux client: which is used when + ControlMaster is in use. will end with "stdio proc tty" (proc is to + permit sending SIGWINCH to mux master on window resize) + + - client loop: several levels of pledging depending of your used options + + ok deraadt@ + + Upstream-ID: 21676155a700e51f2ce911e33538e92a2cd1d94b + +commit bcce47466bbc974636f588b5e4a9a18ae386f64a +Author: doug@openbsd.org +Date: Wed Dec 2 08:30:50 2015 +0000 + + upstream commit + + Add "cpath" to the ssh-agent pledge so the cleanup + handler can unlink(). + + ok djm@ + + Upstream-ID: 9e632991d48241d56db645602d381253a3d8c29d + +commit a90d001543f46716b6590c6dcc681d5f5322f8cf +Author: djm@openbsd.org +Date: Wed Dec 2 08:00:58 2015 +0000 + + upstream commit + + ssh-agent pledge needs proc for askpass; spotted by todd@ + + Upstream-ID: 349aa261b29cc0e7de47ef56167769c432630b2a + +commit d952162b3c158a8f23220587bb6c8fcda75da551 +Author: djm@openbsd.org +Date: Tue Dec 1 23:29:24 2015 +0000 + + upstream commit + + basic pledge() for ssh-agent, more refinement needed + + Upstream-ID: 5b5b03c88162fce549e45e1b6dd833f20bbb5e13 + +commit f0191d7c8e76e30551084b79341886d9bb38e453 +Author: Damien Miller +Date: Mon Nov 30 10:53:25 2015 +1100 + + Revert "stub for pledge(2) for systems that lack it" + + This reverts commit 14c887c8393adde2d9fd437d498be30f8c98535c. + + dtucker beat me to it :/ + +commit 6283cc72eb0e49a3470d30e07ca99a1ba9e89676 +Author: Damien Miller +Date: Mon Nov 30 10:37:03 2015 +1100 + + revert 7d4c7513: bring back S/Key prototypes + + (but leave RCSID changes) + +commit 14c887c8393adde2d9fd437d498be30f8c98535c +Author: Damien Miller +Date: Mon Nov 30 09:45:29 2015 +1100 + + stub for pledge(2) for systems that lack it + +commit 452c0b6af5d14c37553e30059bf74456012493f3 +Author: djm@openbsd.org +Date: Sun Nov 29 22:18:37 2015 +0000 + + upstream commit + + pledge, better fatal() messages; feedback deraadt@ + + Upstream-ID: 3e00f6ccfe2b9a7a2d1dbba5409586180801488f + +commit 6da413c085dba37127687b2617a415602505729b +Author: deraadt@openbsd.org +Date: Sat Nov 28 06:50:52 2015 +0000 + + upstream commit + + do not leak temp file if there is no known_hosts file + from craig leres, ok djm + + Upstream-ID: c820497fd5574844c782e79405c55860f170e426 + +commit 3ddd15e1b63a4d4f06c8ab16fbdd8a5a61764f16 +Author: Darren Tucker +Date: Mon Nov 30 07:23:53 2015 +1100 + + Add a null implementation of pledge. + + Fixes builds on almost everything. + +commit b1d6b3971ef256a08692efc409fc9ada719111cc +Author: djm@openbsd.org +Date: Sat Nov 28 06:41:03 2015 +0000 + + upstream commit + + don't include port number in tcpip-forward replies for + requests that don't allocate a port; bz#2509 diagnosed by Ron Frederick ok + markus + + Upstream-ID: 77efad818addb61ec638b5a2362f1554e21a970a + +commit 9080bd0b9cf10d0f13b1f642f20cb84285cb8d65 +Author: deraadt@openbsd.org +Date: Fri Nov 27 00:49:31 2015 +0000 + + upstream commit + + pledge "stdio rpath wpath cpath fattr tty proc exec" + except for the -p option (which sadly has insane semantics...) ok semarie + dtucker + + Upstream-ID: 8854bbd58279abe00f6c33f8094bdc02c8c65059 + +commit 4d90625b229cf6b3551d81550a9861897509a65f +Author: halex@openbsd.org +Date: Fri Nov 20 23:04:01 2015 +0000 + + upstream commit + + allow comment change for all supported formats + + ok djm@ + + Upstream-ID: 5fc477cf2f119b2d44aa9c683af16cb00bb3744b + +commit 8ca915fc761519dd1f7766a550ec597a81db5646 +Author: djm@openbsd.org +Date: Fri Nov 20 01:45:29 2015 +0000 + + upstream commit + + add cast to make -Werror clean + + Upstream-ID: 288db4f8f810bd475be01320c198250a04ff064d + +commit ac9473580dcd401f8281305af98635cdaae9bf96 +Author: Damien Miller +Date: Fri Nov 20 12:35:41 2015 +1100 + + fix multiple authentication using S/Key w/ privsep + + bz#2502, patch from Kevin Korb and feandil_ + +commit 88b6fcdeb87a2fb76767854d9eb15006662dca57 +Author: djm@openbsd.org +Date: Thu Nov 19 08:23:27 2015 +0000 + + upstream commit + + ban ConnectionAttempts=0, it makes no sense and would cause + ssh_connect_direct() to print an uninitialised stack variable; bz#2500 + reported by dvw AT phas.ubc.ca + + Upstream-ID: 32b5134c608270583a90b93a07b3feb3cbd5f7d5 + +commit 964ab3ee7a8f96bdbc963d5b5a91933d6045ebe7 +Author: djm@openbsd.org +Date: Thu Nov 19 01:12:32 2015 +0000 + + upstream commit + + trailing whitespace + + Upstream-ID: 31fe0ad7c4d08e87f1d69c79372f5e3c5cd79051 + +commit f96516d052dbe38561f6b92b0e4365d8e24bb686 +Author: djm@openbsd.org +Date: Thu Nov 19 01:09:38 2015 +0000 + + upstream commit + + print host certificate contents at debug level + + Upstream-ID: 39354cdd8a2b32b308fd03f98645f877f540f00d + +commit 499cf36fecd6040e30e2912dd25655bc574739a7 +Author: djm@openbsd.org +Date: Thu Nov 19 01:08:55 2015 +0000 + + upstream commit + + move the certificate validity formatting code to + sshkey.[ch] + + Upstream-ID: f05f7c78fab20d02ff1d5ceeda533ef52e8fe523 + +commit bcb7bc77bbb1535d1008c7714085556f3065d99d +Author: djm@openbsd.org +Date: Wed Nov 18 08:37:28 2015 +0000 + + upstream commit + + fix "ssh-keygen -l" of private key, broken in support for + multiple plain keys on stdin + + Upstream-ID: 6b3132d2c62d03d0bad6f2bcd7e2d8b7dab5cd9d + +commit 259adb6179e23195c8f6913635ea71040d1ccd63 +Author: millert@openbsd.org +Date: Mon Nov 16 23:47:52 2015 +0000 + + upstream commit + + Replace remaining calls to index(3) with strchr(3). OK + jca@ krw@ + + Upstream-ID: 33837d767a0cf1db1489b96055f9e330bc0bab6d + +commit c56a255162c2166884539c0a1f7511575325b477 +Author: djm@openbsd.org +Date: Mon Nov 16 22:53:07 2015 +0000 + + upstream commit + + Allow fingerprinting from standard input "ssh-keygen -lf + -" + + Support fingerprinting multiple plain keys in a file and authorized_keys + files too (bz#1319) + + ok markus@ + + Upstream-ID: 903f8b4502929d6ccf53509e4e07eae084574b77 + +commit 5b4010d9b923cf1b46c9c7b1887c013c2967e204 +Author: djm@openbsd.org +Date: Mon Nov 16 22:51:05 2015 +0000 + + upstream commit + + always call privsep_preauth_child() regardless of whether + sshd was started by root; it does important priming before sandboxing and + failing to call it could result in sandbox violations later; ok markus@ + + Upstream-ID: c8a6d0d56c42f3faab38460dc917ca0d1705d383 + +commit 3a9f84b58b0534bbb485f1eeab75665e2d03371f +Author: djm@openbsd.org +Date: Mon Nov 16 22:50:01 2015 +0000 + + upstream commit + + improve sshkey_read() semantics; only update *cpp when a + key is successfully read; ok markus@ + + Upstream-ID: f371e78e8f4fab366cf69a42bdecedaed5d1b089 + +commit db6f8dc5dd5655b59368efd074994d4568bc3556 +Author: logan@openbsd.org +Date: Mon Nov 16 06:13:04 2015 +0000 + + upstream commit + + 1) Use xcalloc() instead of xmalloc() to check for + potential overflow. (Feedback from both mmcc@ and djm@) 2) move set_size + just before the for loop. (suggested by djm@) + + OK djm@ + + Upstream-ID: 013534c308187284756c3141f11d2c0f33c47213 + +commit 383f10fb84a0fee3c01f9d97594f3e22aa3cd5e0 +Author: djm@openbsd.org +Date: Mon Nov 16 00:30:02 2015 +0000 + + upstream commit + + Add a new authorized_keys option "restrict" that + includes all current and future key restrictions (no-*-forwarding, etc). Also + add permissive versions of the existing restrictions, e.g. "no-pty" -> "pty". + This simplifies the task of setting up restricted keys and ensures they are + maximally-restricted, regardless of any permissions we might implement in the + future. + + Example: + + restrict,pty,command="nethack" ssh-ed25519 AAAAC3NzaC1lZDI1... + + Idea from Jann Horn; ok markus@ + + Upstream-ID: 04ceb9d448e46e67e13887a7ae5ea45b4f1719d0 + +commit e41a071f7bda6af1fb3f081bed0151235fa61f15 +Author: jmc@openbsd.org +Date: Sun Nov 15 23:58:04 2015 +0000 + + upstream commit + + correct section number for ssh-agent; + + Upstream-ID: 44be72fd8bcc167635c49b357b1beea8d5674bd6 + +commit 1a11670286acddcc19f5eff0966c380831fc4638 +Author: jmc@openbsd.org +Date: Sun Nov 15 23:54:15 2015 +0000 + + upstream commit + + do not confuse mandoc by presenting "Dd"; + + Upstream-ID: 1470fce171c47b60bbc7ecd0fc717a442c2cfe65 + +commit f361df474c49a097bfcf16d1b7b5c36fcd844b4b +Author: jcs@openbsd.org +Date: Sun Nov 15 22:26:49 2015 +0000 + + upstream commit + + Add an AddKeysToAgent client option which can be set to + 'yes', 'no', 'ask', or 'confirm', and defaults to 'no'. When enabled, a + private key that is used during authentication will be added to ssh-agent if + it is running (with confirmation enabled if set to 'confirm'). + + Initial version from Joachim Schipper many years ago. + + ok markus@ + + Upstream-ID: a680db2248e8064ec55f8be72d539458c987d5f4 + +commit d87063d9baf5479b6e813d47dfb694a97df6f6f5 +Author: djm@openbsd.org +Date: Fri Nov 13 04:39:35 2015 +0000 + + upstream commit + + send SSH2_MSG_UNIMPLEMENTED replies to unexpected + messages during KEX; bz#2949, ok dtucker@ + + Upstream-ID: 2b3abdff344d53c8d505f45c83a7b12e84935786 + +commit 9fd04681a1e9b0af21e08ff82eb674cf0a499bfc +Author: djm@openbsd.org +Date: Fri Nov 13 04:38:06 2015 +0000 + + upstream commit + + Support "none" as an argument for sshd_config + ForceCommand and ChrootDirectory. Useful inside Match blocks to override a + global default. bz#2486 ok dtucker@ + + Upstream-ID: 7ef478d6592bc7db5c7376fc33b4443e63dccfa5 + +commit 94bc0b72c29e511cbbc5772190d43282e5acfdfe +Author: djm@openbsd.org +Date: Fri Nov 13 04:34:15 2015 +0000 + + upstream commit + + support multiple certificates (one per line) and + reading from standard input (using "-f -") for "ssh-keygen -L"; ok dtucker@ + + Upstream-ID: ecbadeeef3926e5be6281689b7250a32a80e88db + +commit b6b9108f5b561c83612cb97ece4134eb59fde071 +Author: djm@openbsd.org +Date: Fri Nov 13 02:57:46 2015 +0000 + + upstream commit + + list a couple more options usable in Match blocks; + bz#2489 + + Upstream-ID: e4d03f39d254db4c0cc54101921bb89fbda19879 + +commit a7994b3f5a5a5a33b52b0a6065d08e888f0a99fb +Author: djm@openbsd.org +Date: Wed Nov 11 04:56:39 2015 +0000 + + upstream commit + + improve PEEK/POKE macros: better casts, don't multiply + evaluate arguments; ok deraadt@ + + Upstream-ID: 9a1889e19647615ededbbabab89064843ba92d3e + +commit 7d4c7513a7f209cb303a608ac6e46b3f1dfc11ec +Author: djm@openbsd.org +Date: Wed Nov 11 01:48:01 2015 +0000 + + upstream commit + + remove prototypes for long-gone s/key support; ok + dtucker@ + + Upstream-ID: db5bed3c57118af986490ab23d399df807359a79 + +commit 07889c75926c040b8e095949c724e66af26441cb +Author: Damien Miller +Date: Sat Nov 14 18:44:49 2015 +1100 + + read back from libcrypto RAND when privdropping + + makes certain libcrypto implementations cache a /dev/urandom fd + in preparation of sandboxing. Based on patch by Greg Hartman. + +commit 1560596f44c01bb0cef977816410950ed17b8ecd +Author: Darren Tucker +Date: Tue Nov 10 11:14:47 2015 +1100 + + Fix compiler warnings in the openssl header check. + + Noted by Austin English. + +commit e72a8575ffe1d8adff42c9abe9ca36938acc036b +Author: jmc@openbsd.org +Date: Sun Nov 8 23:24:03 2015 +0000 + + upstream commit + + -c before -H, in SYNOPSIS and usage(); + + Upstream-ID: 25e8c58a69e1f37fcd54ac2cd1699370acb5e404 + +commit 3a424cdd21db08c7b0ded902f97b8f02af5aa485 +Author: djm@openbsd.org +Date: Sun Nov 8 22:30:20 2015 +0000 + + upstream commit + + Add "ssh-keyscan -c ..." flag to allow fetching + certificates instead of plain keys; ok markus@ + + Upstream-ID: 0947e2177dba92339eced9e49d3c5bf7dda69f82 + +commit 69fead5d7cdaa73bdece9fcba80f8e8e70b90346 +Author: jmc@openbsd.org +Date: Sun Nov 8 22:08:38 2015 +0000 + + upstream commit + + remove slogin links; ok deraadt markus djm + + Upstream-ID: 39ba08548acde4c54f2d4520c202c2a863a3c730 + +commit 2fecfd486bdba9f51b3a789277bb0733ca36e1c0 +Author: djm@openbsd.org +Date: Sun Nov 8 21:59:11 2015 +0000 + + upstream commit + + fix OOB read in packet code caused by missing return + statement found by Ben Hawkes; ok markus@ deraadt@ + + Upstream-ID: a3e3a85434ebfa0690d4879091959591f30efc62 + +commit 5e288923a303ca672b686908320bc5368ebec6e6 +Author: mmcc@openbsd.org +Date: Fri Nov 6 00:31:41 2015 +0000 + + upstream commit + + 1. rlogin and rsh are long gone 2. protocol version isn't + of core relevance here, and v1 is going away + + ok markus@, deraadt@ + + Upstream-ID: 8b46bc94cf1ca7c8c1a75b1c958b2bb38d7579c8 + +commit 8b29008bbe97f33381d9b4b93fcfa304168d0286 +Author: jmc@openbsd.org +Date: Thu Nov 5 09:48:05 2015 +0000 + + upstream commit + + "commandline" -> "command line", since there are so few + examples of the former in the pages, so many of the latter, and in some of + these pages we had multiple spellings; + + prompted by tj + + Upstream-ID: 78459d59bff74223f8139d9001ccd56fc4310659 + +commit 996b24cebf20077fbe5db07b3a2c20c2d9db736e +Author: Darren Tucker +Date: Thu Oct 29 20:57:34 2015 +1100 + + (re)wrap SYS_sendsyslog in ifdef. + + Replace ifdef that went missing in commit + c61b42f2678f21f05653ac2d3d241b48ab5d59ac. Fixes build on older + OpenBSDs. + +commit b67e2e76fcf1ae7c802eb27ca927e16c91a513ff +Author: djm@openbsd.org +Date: Thu Oct 29 08:05:17 2015 +0000 + + upstream commit + + regress test for "PubkeyAcceptedKeyTypes +..." inside a + Match block + + Upstream-Regress-ID: 246c37ed64a2e5704d4c158ccdca1ff700e10647 + +commit abd9dbc3c0d8c8c7561347cfa22166156e78c077 +Author: dtucker@openbsd.org +Date: Mon Oct 26 02:50:58 2015 +0000 + + upstream commit + + Fix typo certopt->certopts in shell variable. This would + cause the test to hang at a host key prompt if you have an A or CNAME for + "proxy" in your local domain. + + Upstream-Regress-ID: 6ea03bcd39443a83c89e2c5606392ceb9585836a + +commit ed08510d38aef930a061ae30d10f2a9cf233bafa +Author: djm@openbsd.org +Date: Thu Oct 29 08:05:01 2015 +0000 + + upstream commit + + Fix "PubkeyAcceptedKeyTypes +..." inside a Match block; + ok dtucker@ + + Upstream-ID: 853662c4036730b966aab77684390c47b9738c69 + +commit a4aef3ed29071719b2af82fdf1ac3c2514f82bc5 +Author: djm@openbsd.org +Date: Tue Oct 27 08:54:52 2015 +0000 + + upstream commit + + fix execv arguments in a way less likely to cause grief + for -portable; ok dtucker@ + + Upstream-ID: 5902bf0ea0371f39f1300698dc3b8e4105fc0fc5 + +commit 63d188175accea83305e89fafa011136ff3d96ad +Author: djm@openbsd.org +Date: Tue Oct 27 01:44:45 2015 +0000 + + upstream commit + + log certificate serial in verbose() messages to match the + main auth success/fail message; ok dtucker@ + + Upstream-ID: dfc48b417c320b97c36ff351d303c142f2186288 + +commit 2aaba0cfd560ecfe92aa50c00750e6143842cf1f +Author: djm@openbsd.org +Date: Tue Oct 27 00:49:53 2015 +0000 + + upstream commit + + avoid de-const warning & shrink; ok dtucker@ + + Upstream-ID: 69a85ef94832378952a22c172009cbf52aaa11db + +commit 03239c18312b9bab7d1c3b03062c61e8bbc1ca6e +Author: dtucker@openbsd.org +Date: Sun Oct 25 23:42:00 2015 +0000 + + upstream commit + + Expand tildes in filenames passed to -i before checking + whether or not the identity file exists. This means that if the shell + doesn't do the expansion (eg because the option and filename were given as a + single argument) then we'll still add the key. bz#2481, ok markus@ + + Upstream-ID: db1757178a14ac519e9a3e1a2dbd21113cb3bfc6 + +commit 97e184e508dd33c37860c732c0eca3fc57698b40 +Author: dtucker@openbsd.org +Date: Sun Oct 25 23:14:03 2015 +0000 + + upstream commit + + Do not prepend "exec" to the shell command run by "Match + exec" in a config file. It's an unnecessary optimization from repurposed + ProxyCommand code and prevents some things working with some shells. + bz#2471, pointed out by res at qoxp.net. ok markus@ + + Upstream-ID: a1ead25ae336bfa15fb58d8c6b5589f85b4c33a3 + +commit 8db134e7f457bcb069ec72bc4ee722e2af557c69 +Author: Darren Tucker +Date: Thu Oct 29 10:48:23 2015 +1100 + + Prevent name collisions with system glob (bz#2463) + + Move glob.h from includes.h to the only caller (sftp) and override the + names for the symbols. This prevents name collisions with the system glob + in the case where something other than ssh uses it (eg kerberos). With + jjelen at redhat.com, ok djm@ + +commit 86c10dbbef6a5800d2431a66cf7f41a954bb62b5 +Author: dtucker@openbsd.org +Date: Fri Oct 23 02:22:01 2015 +0000 + + upstream commit + + Update expected group sizes to match recent code changes. + + Upstream-Regress-ID: 0004f0ea93428969fe75bcfff0d521c553977794 + +commit 9ada37d36003a77902e90a3214981e417457cf13 +Author: djm@openbsd.org +Date: Sat Oct 24 22:56:19 2015 +0000 + + upstream commit + + fix keyscan output for multiple hosts/addrs on one line + when host hashing or a non standard port is in use; bz#2479 ok dtucker@ + + Upstream-ID: 5321dabfaeceba343da3c8a8b5754c6f4a0a307b + +commit 44fc7cd7dcef6c52c6b7e9ff830dfa32879bd319 +Author: djm@openbsd.org +Date: Sat Oct 24 22:52:22 2015 +0000 + + upstream commit + + skip "Could not chdir to home directory" message when + chrooted + + patch from Christian Hesse in bz#2485 ok dtucker@ + + Upstream-ID: 86783c1953da426dff5b03b03ce46e699d9e5431 + +commit a820a8618ec44735dabc688fab96fba38ad66bb2 +Author: sthen@openbsd.org +Date: Sat Oct 24 08:34:09 2015 +0000 + + upstream commit + + Handle the split of tun(4) "link0" into tap(4) in ssh + tun-forwarding. Adapted from portable (using separate devices for this is the + normal case in most OS). ok djm@ + + Upstream-ID: 90facf4c59ce73d6741db1bc926e578ef465cd39 + +commit 66d2e229baa9fe57b868c373b05f7ff3bb20055b +Author: gsoares@openbsd.org +Date: Wed Oct 21 11:33:03 2015 +0000 + + upstream commit + + fix memory leak in error path ok djm@ + + Upstream-ID: dd2f402b0a0029b755df029fc7f0679e1365ce35 + +commit 7d6c0362039ceacdc1366b5df29ad5d2693c13e5 +Author: mmcc@openbsd.org +Date: Tue Oct 20 23:24:25 2015 +0000 + + upstream commit + + Compare pointers to NULL rather than 0. + + ok djm@ + + Upstream-ID: 21616cfea27eda65a06e772cc887530b9a1a27f8 + +commit f98a09cacff7baad8748c9aa217afd155a4d493f +Author: mmcc@openbsd.org +Date: Tue Oct 20 03:36:35 2015 +0000 + + upstream commit + + Replace a function-local allocation with stack memory. + + ok djm@ + + Upstream-ID: c09fbbab637053a2ab9f33ca142b4e20a4c5a17e + +commit ac908c1eeacccfa85659594d92428659320fd57e +Author: Damien Miller +Date: Thu Oct 22 09:35:24 2015 +1100 + + turn off PrintLastLog when --disable-lastlog + + bz#2278 from Brent Paulson + +commit b56deb847f4a0115a8bf488bf6ee8524658162fd +Author: djm@openbsd.org +Date: Fri Oct 16 22:32:22 2015 +0000 + + upstream commit + + increase the minimum modulus that we will send or accept in + diffie-hellman-group-exchange to 2048 bits; ok markus@ + + Upstream-ID: 06dce7a24c17b999a0f5fadfe95de1ed6a1a9b6a + +commit 5ee0063f024bf5b3f3ffb275b8cd20055d62b4b9 +Author: djm@openbsd.org +Date: Fri Oct 16 18:40:49 2015 +0000 + + upstream commit + + better handle anchored FQDNs (e.g. 'cvs.openbsd.org.') in + hostname canonicalisation - treat them as already canonical and remove the + trailing '.' before matching ssh_config; ok markus@ + + Upstream-ID: f7619652e074ac3febe8363f19622aa4853b679a + +commit e92c499a75477ecfe94dd7b4aed89f20b1fac5a7 +Author: mmcc@openbsd.org +Date: Fri Oct 16 17:07:24 2015 +0000 + + upstream commit + + 0 -> NULL when comparing with a char*. + + ok dtucker@, djm@. + + Upstream-ID: a928e9c21c0a9020727d99738ff64027c1272300 + +commit b1d38a3cc6fe349feb8d16a5f520ef12d1de7cb2 +Author: djm@openbsd.org +Date: Thu Oct 15 23:51:40 2015 +0000 + + upstream commit + + fix some signed/unsigned integer type mismatches in + format strings; reported by Nicholas Lemonias + + Upstream-ID: 78cd55420a0eef68c4095bdfddd1af84afe5f95c + +commit 1a2663a15d356bb188196b6414b4c50dc12fd42b +Author: djm@openbsd.org +Date: Thu Oct 15 23:08:23 2015 +0000 + + upstream commit + + argument to sshkey_from_private() and sshkey_demote() + can't be NULL + + Upstream-ID: 0111245b1641d387977a9b38da15916820a5fd1f + +commit 0f754e29dd3760fc0b172c1220f18b753fb0957e +Author: Damien Miller +Date: Fri Oct 16 10:53:14 2015 +1100 + + need va_copy before va_start + + reported by Nicholas Lemonias + +commit eb6c50d82aa1f0d3fc95f5630ea69761e918bfcd +Author: Damien Miller +Date: Thu Oct 15 15:48:28 2015 -0700 + + fix compilation on systems without SYMLOOP_MAX + +commit fafe1d84a210fb3dae7744f268059cc583db8c12 +Author: Damien Miller +Date: Wed Oct 14 09:22:15 2015 -0700 + + s/SANDBOX_TAME/SANDBOX_PLEDGE/g + +commit 8f22911027ff6c17d7226d232ccd20727f389310 +Author: Damien Miller +Date: Wed Oct 14 08:28:19 2015 +1100 + + upstream commit + + revision 1.20 + date: 2015/10/13 20:55:37; author: millert; state: Exp; lines: +2 -2; commitid: X39sl5ay1czgFIgp; + In rev 1.15 the sizeof argument was fixed in a strlcat() call but + the truncation check immediately following it was not updated to + match. Not an issue in practice since the buffers are the same + size. OK deraadt@ + +commit 23fa695bb735f54f04d46123662609edb6c76767 +Author: Damien Miller +Date: Wed Oct 14 08:27:51 2015 +1100 + + upstream commit + + revision 1.19 + date: 2015/01/16 16:48:51; author: deraadt; state: Exp; lines: +3 -3; commitid: 0DYulI8hhujBHMcR; + Move to the universe. + review by millert, binary checking process with doug, concept with guenther + +commit c71be375a69af00c2d0a0c24d8752bec12d8fd1b +Author: Damien Miller +Date: Wed Oct 14 08:27:08 2015 +1100 + + upstream commit + + revision 1.18 + date: 2014/10/19 03:56:28; author: doug; state: Exp; lines: +9 -9; commitid: U6QxmtbXrGoc02S5; + Revert last commit due to changed semantics found by make release. + +commit c39ad23b06e9aecc3ff788e92f787a08472905b1 +Author: Damien Miller +Date: Wed Oct 14 08:26:24 2015 +1100 + + upstream commit + + revision 1.17 + date: 2014/10/18 20:43:52; author: doug; state: Exp; lines: +10 -10; commitid: I74hI1tVZtsspKEt; + Better POSIX compliance in realpath(3). + + millert@ made changes to realpath.c based on FreeBSD's version. I merged + Todd's changes into dl_realpath.c. + + ok millert@, guenther@ + +commit e929a43f957dbd1254aca2aaf85c8c00cbfc25f4 +Author: Damien Miller +Date: Wed Oct 14 08:25:55 2015 +1100 + + upstream commit + + revision 1.16 + date: 2013/04/05 12:59:54; author: kurt; state: Exp; lines: +3 -1; + - Add comments regarding copies of these files also in libexec/ld.so + okay guenther@ + +commit 5225db68e58a1048cb17f0e36e0d33bc4a8fc410 +Author: Damien Miller +Date: Wed Oct 14 08:25:32 2015 +1100 + + upstream commit + + revision 1.15 + date: 2012/09/13 15:39:05; author: deraadt; state: Exp; lines: +2 -2; + specify the bounds of the dst to strlcat (both values were static and + equal, but it is more correct) + from Michal Mazurek + +commit 7365fe5b4859de2305e40ea132da3823830fa710 +Author: Damien Miller +Date: Wed Oct 14 08:25:09 2015 +1100 + + upstream commit + + revision 1.14 + date: 2011/07/24 21:03:00; author: miod; state: Exp; lines: +35 -13; + Recent Single Unix will malloc memory if the second argument of realpath() + is NULL, and third-party software is starting to rely upon this. + Adapted from FreeBSD via Jona Joachim (jaj ; hcl-club , .lu), with minor + tweaks from nicm@ and yours truly. + +commit e679c09cd1951f963793aa3d9748d1c3fdcf808f +Author: djm@openbsd.org +Date: Tue Oct 13 16:15:21 2015 +0000 + + upstream commit + + apply PubkeyAcceptedKeyTypes filtering earlier, so all + skipped keys are noted before pubkey authentication starts. ok dtucker@ + + Upstream-ID: ba4f52f54268a421a2a5f98bb375403f4cb044b8 + +commit 179c353f564ec7ada64b87730b25fb41107babd7 +Author: djm@openbsd.org +Date: Tue Oct 13 00:21:27 2015 +0000 + + upstream commit + + free the correct IV length, don't assume it's always the + cipher blocksize; ok dtucker@ + + Upstream-ID: c260d9e5ec73628d9ff4b067fbb060eff5a7d298 + +commit 2539dce2a049a8f6bb0d44cac51f07ad48e691d3 +Author: deraadt@openbsd.org +Date: Fri Oct 9 01:37:08 2015 +0000 + + upstream commit + + Change all tame callers to namechange to pledge(2). + + Upstream-ID: 17e654fc27ceaf523c60f4ffd9ec7ae4e7efc7f2 + +commit 9846a2f4067383bb76b4e31a9d2303e0a9c13a73 +Author: Damien Miller +Date: Thu Oct 8 04:30:48 2015 +1100 + + hook tame(2) sandbox up to build + + OpenBSD only for now + +commit 0c46bbe68b70bdf0d6d20588e5847e71f3739fe6 +Author: djm@openbsd.org +Date: Wed Oct 7 15:59:12 2015 +0000 + + upstream commit + + include PubkeyAcceptedKeyTypes in ssh -G config dump + + Upstream-ID: 6c097ce6ffebf6fe393fb7988b5d152a5d6b36bb + +commit bdcb73fb7641b1cf73c0065d1a0dd57b1e8b778e +Author: sobrado@openbsd.org +Date: Wed Oct 7 14:45:30 2015 +0000 + + upstream commit + + UsePrivilegeSeparation defaults to sandbox now. + + ok djm@ + + Upstream-ID: bff136c38bcae89df82e044d2f42de21e1ad914f + +commit 2905d6f99c837bb699b6ebc61711b19acd030709 +Author: djm@openbsd.org +Date: Wed Oct 7 00:54:06 2015 +0000 + + upstream commit + + don't try to change tun device flags if they are already + what we need; makes it possible to use tun/tap networking as non- root user + if device permissions and interface flags are pre-established; based on patch + by Ossi Herrala + + Upstream-ID: 89099ac4634cd477b066865acf54cb230780fd21 + +commit 0dc74512bdb105b048883f07de538b37e5e024d4 +Author: Damien Miller +Date: Mon Oct 5 18:33:05 2015 -0700 + + unbreak merge botch + +commit fdd020e86439afa7f537e2429d29d4b744c94331 +Author: djm@openbsd.org +Date: Tue Oct 6 01:20:59 2015 +0000 + + upstream commit + + adapt to recent sshkey_parse_private_fileblob() API + change + + Upstream-Regress-ID: 5c0d818da511e33e0abf6a92a31bd7163b7ad988 + +commit 21ae8ee3b630b0925f973db647a1b9aa5fcdd4c5 +Author: djm@openbsd.org +Date: Thu Sep 24 07:15:39 2015 +0000 + + upstream commit + + fix command-line option to match what was actually + committed + + Upstream-Regress-ID: 3e8c24a2044e8afd37e7ce17b69002ca817ac699 + +commit e14ac43b75e68f1ffbd3e1a5e44143c8ae578dcd +Author: djm@openbsd.org +Date: Thu Sep 24 06:16:53 2015 +0000 + + upstream commit + + regress test for CertificateFile; patch from Meghana Bhat + via bz#2436 + + Upstream-Regress-ID: e7a6e980cbe0f8081ba2e83de40d06c17be8bd25 + +commit 905b054ed24e0d5b4ef226ebf2c8bfc02ae6d4ad Author: djm@openbsd.org Date: Mon Oct 5 17:11:21 2015 +0000 @@ -26,7 +1899,129 @@ Date: Mon Oct 5 17:11:21 2015 +0000 Upstream-ID: 17f19545685c33327db2efdc357c1c9225ff00d0 -commit 8f5b93026797b9f7fba90d0c717570421ccebbd3 +commit b007159a0acdbcf65814b3ee05dbe2cf4ea46011 +Author: deraadt@openbsd.org +Date: Fri Oct 2 15:52:55 2015 +0000 + + upstream commit + + fix email + + Upstream-ID: 72150f2d54b94de14ebef1ea054ef974281bf834 + +commit b19e1b4ab11884c4f62aee9f8ab53127a4732658 +Author: deraadt@openbsd.org +Date: Fri Oct 2 01:39:52 2015 +0000 + + upstream commit + + a sandbox using tame ok djm + + Upstream-ID: 4ca24e47895e72f5daaa02f3e3d3e5ca2d820fa3 + +commit c61b42f2678f21f05653ac2d3d241b48ab5d59ac +Author: deraadt@openbsd.org +Date: Fri Oct 2 01:39:26 2015 +0000 + + upstream commit + + re-order system calls in order of risk, ok i'll be + honest, ordered this way they look like tame... ok djm + + Upstream-ID: 42a1e6d251fd8be13c8262bee026059ae6328813 + +commit c5f7c0843cb6e6074a93c8ac34e49ce33a6f5546 +Author: jmc@openbsd.org +Date: Fri Sep 25 18:19:54 2015 +0000 + + upstream commit + + some certificatefile tweaks; ok djm + + Upstream-ID: 0e5a7852c28c05fc193419cc7e50e64c1c535af0 + +commit 4e44a79a07d4b88b6a4e5e8c1bed5f58c841b1b8 +Author: djm@openbsd.org +Date: Thu Sep 24 06:15:11 2015 +0000 + + upstream commit + + add ssh_config CertificateFile option to explicitly list + a certificate; patch from Meghana Bhat on bz#2436; ok markus@ + + Upstream-ID: 58648ec53c510b41c1f46d8fe293aadc87229ab8 + +commit e3cbb06ade83c72b640a53728d362bbefa0008e2 +Author: sobrado@openbsd.org +Date: Tue Sep 22 08:33:23 2015 +0000 + + upstream commit + + fix two typos. + + Upstream-ID: 424402c0d8863a11b51749bacd7f8d932083b709 + +commit 8408218c1ca88cb17d15278174a24a94a6f65fe1 +Author: djm@openbsd.org +Date: Mon Sep 21 04:31:00 2015 +0000 + + upstream commit + + fix possible hang on closed output; bz#2469 reported by Tomas + Kuthan ok markus@ + + Upstream-ID: f7afd41810f8540f524284f1be6b970859f94fe3 + +commit 0097248f90a00865082e8c146b905a6555cc146f +Author: djm@openbsd.org +Date: Fri Sep 11 04:55:01 2015 +0000 + + upstream commit + + skip if running as root; many systems (inc OpenBSD) allow + root to ptrace arbitrary processes + + Upstream-Regress-ID: be2b925df89360dff36f972951fa0fa793769038 + +commit 9c06c814aff925e11a5cc592c06929c258a014f6 +Author: djm@openbsd.org +Date: Fri Sep 11 03:44:21 2015 +0000 + + upstream commit + + try all supported key types here; bz#2455 reported by + Jakub Jelen + + Upstream-Regress-ID: 188cb7d9031cdbac3a0fa58b428b8fa2b2482bba + +commit 3c019a936b43f3e2773f3edbde7c114d73caaa4c +Author: tim@openbsd.org +Date: Sun Sep 13 14:39:16 2015 +0000 + + upstream commit + + - Fix error message: passphrase needs to be at least 5 + characters, not 4. - Remove unused function argument. - Remove two + unnecessary variables. + + OK djm@ + + Upstream-ID: 13010c05bfa8b523da1c0dc19e81dd180662bc30 + +commit 2681cdb6e0de7c1af549dac37a9531af202b4434 +Author: tim@openbsd.org +Date: Sun Sep 13 13:48:19 2015 +0000 + + upstream commit + + When adding keys to the agent, don't ignore the comment + of keys for which the user is prompted for a passphrase. + + Tweak and OK djm@ + + Upstream-ID: dc737c620a5a8d282cc4f66e3b9b624e9abefbec + +commit 14692f7b8251cdda847e648a82735eef8a4d2a33 Author: guenther@openbsd.org Date: Fri Sep 11 08:50:04 2015 +0000 @@ -39,47 +2034,272 @@ Date: Fri Sep 11 08:50:04 2015 +0000 Upstream-ID: 2e3337db046c3fe70c7369ee31515ac73ec00f50 -commit d77148e3a3ef6c29b26ec74331455394581aa257 -Author: djm@openbsd.org -Date: Sun Nov 8 21:59:11 2015 +0000 +commit 846f6fa4cfa8483a9195971dbdd162220f199d85 +Author: jmc@openbsd.org +Date: Fri Sep 11 06:55:46 2015 +0000 upstream commit - fix OOB read in packet code caused by missing return - statement found by Ben Hawkes; ok markus@ deraadt@ + sync -Q in usage() to SYNOPSIS; since it's drastically + shorter, i've reformatted the block to sync with the man (80 cols) and saved + a line; - Upstream-ID: a3e3a85434ebfa0690d4879091959591f30efc62 + Upstream-ID: 86e2c65c3989a0777a6258a77e589b9f6f354abd -commit 076d849e17ab12603627f87b301e2dca71bae518 +commit 95923e0520a8647417ee6dcdff44694703dfeef0 +Author: jmc@openbsd.org +Date: Fri Sep 11 06:51:39 2015 +0000 + + upstream commit + + tweak previous; + + Upstream-ID: f29b3cfcfd9aa31fa140c393e7bd48c1c74139d6 + +commit 86ac462f833b05d8ed9de9c50ccb295d7faa79ff +Author: dtucker@openbsd.org +Date: Fri Sep 11 05:27:02 2015 +0000 + + upstream commit + + Update usage to match man page. + + Upstream-ID: 9e85aefaecfb6aaf34c7cfd0700cd21783a35675 + +commit 674b3b68c1d36b2562324927cd03857b565e05e8 +Author: djm@openbsd.org +Date: Fri Sep 11 03:47:28 2015 +0000 + + upstream commit + + expand %i in ControlPath to UID; bz#2449 + + patch from Christian Hesse w/ feedback from dtucker@ + + Upstream-ID: 2ba8d303e555a84e2f2165ab4b324b41e80ab925 + +commit c0f55db7ee00c8202b05cb4b9ad4ce72cc45df41 +Author: djm@openbsd.org +Date: Fri Sep 11 03:42:32 2015 +0000 + + upstream commit + + mention -Q key-plain and -Q key-cert; bz#2455 pointed out + by Jakub Jelen + + Upstream-ID: c8f1f8169332e4fa73ac96b0043e3b84e01d4896 + +commit cfffbdb10fdf0f02d3f4232232eef7ec3876c383 +Author: Darren Tucker +Date: Mon Sep 14 16:24:21 2015 +1000 + + Use ssh-keygen -A when generating host keys. + + Use ssh-keygen -A instead of per-keytype invocations when generating host + keys. Add tests when doing host-key-force since we can't use ssh-keygen -A + since it can't specify alternate locations. bz#2459, ok djm@ + +commit 366bada1e9e124654aac55b72b6ccf878755b0dc +Author: Darren Tucker +Date: Fri Sep 11 13:29:22 2015 +1000 + + Correct default value for --with-ssh1. + + bz#2457, from konto-mindrot.org at walimnieto.com. + +commit 2bca8a43e7dd9b04d7070824ffebb823c72587b2 +Author: djm@openbsd.org +Date: Fri Sep 11 03:13:36 2015 +0000 + + upstream commit + + more clarity on what AuthorizedKeysFile=none does; based + on diff by Thiebaud Weksteen + + Upstream-ID: 78ab87f069080f0cc3bc353bb04eddd9e8ad3704 + +commit 61942ea4a01e6db4fdf37ad61de81312ffe310e9 +Author: djm@openbsd.org +Date: Wed Sep 9 00:52:44 2015 +0000 + + upstream commit + + openssh_RSA_verify return type is int, so don't make it + size_t within the function itself with only negative numbers or zero assigned + to it. bz#2460 + + Upstream-ID: b6e794b0c7fc4f9f329509263c8668d35f83ea55 + +commit 4f7cc2f8cc861a21e6dbd7f6c25652afb38b9b96 +Author: dtucker@openbsd.org +Date: Fri Sep 4 08:21:47 2015 +0000 + + upstream commit + + Plug minor memory leaks when options are used more than + once. bz#2182, patch from Tiago Cunha, ok deraadt djm + + Upstream-ID: 5b84d0401e27fe1614c10997010cc55933adb48e + +commit 7ad8b287c8453a3e61dbc0d34d467632b8b06fc8 +Author: Darren Tucker +Date: Fri Sep 11 13:11:02 2015 +1000 + + Force resolution of _res for correct detection. + + bz#2259, from sconeu at yahoo.com. + +commit 26ad18247213ff72b4438abe7fc660c958810fa2 Author: Damien Miller -Date: Sat Nov 14 18:44:49 2015 +1100 +Date: Thu Sep 10 10:57:41 2015 +1000 - read back from libcrypto RAND when privdropping - - makes certain libcrypto implementations cache a /dev/urandom fd - in preparation of sandboxing. Based on patch by Greg Hartman. + allow getrandom syscall; from Felix von Leitner -commit f72adc0150011a28f177617a8456e1f83733099d -Author: djm@openbsd.org -Date: Sun Dec 13 22:42:23 2015 +0000 +commit 5245bc1e6b129a10a928f73f11c3aa32656c44b4 +Author: jmc@openbsd.org +Date: Fri Sep 4 06:40:45 2015 +0000 upstream commit - unbreak connections with peers that set - first_kex_follows; fix from Matt Johnston va bz#2515 + full stop belongs outside the brackets, not inside; - Upstream-ID: decc88ec4fc7515594fdb42b04aa03189a44184b + Upstream-ID: 99d098287767799ac33d2442a05b5053fa5a551a -commit 04bd8d019ccd906cac1a2b362517b8505f3759e6 +commit a85768a9321d74b41219eeb3c9be9f1702cbf6a5 Author: djm@openbsd.org -Date: Tue Jan 12 23:42:54 2016 +0000 +Date: Fri Sep 4 04:56:09 2015 +0000 upstream commit - use explicit_bzero() more liberally in the buffer code; ok - deraadt + add a debug2() right before DNS resolution; it's a place + where ssh could previously silently hang for a while. bz#2433 - Upstream-ID: 0ece37069fd66bc6e4f55eb1321f93df372b65bf + Upstream-ID: 52a1a3e0748db66518e7598352c427145692a6a0 + +commit 46152af8d27aa34d5d26ed1c371dc8aa142d4730 +Author: djm@openbsd.org +Date: Fri Sep 4 04:55:24 2015 +0000 + + upstream commit + + correct function name in error messages + + Upstream-ID: 92fb2798617ad9561370897f4ab60adef2ff4c0e + +commit a954cdb799a4d83c2d40fbf3e7b9f187fbfd72fc +Author: djm@openbsd.org +Date: Fri Sep 4 04:47:50 2015 +0000 + + upstream commit + + better document ExitOnForwardFailure; bz#2444, ok + dtucker@ + + Upstream-ID: a126209b5a6d9cb3117ac7ab5bc63d284538bfc2 + +commit f54d8ac2474b6fc3afa081cf759b48a6c89d3319 +Author: djm@openbsd.org +Date: Fri Sep 4 04:44:08 2015 +0000 + + upstream commit + + don't record hostbased authentication hostkeys as user + keys in test for multiple authentication with the same key + + Upstream-ID: 26b368fa2cff481f47f37e01b8da1ae5b57b1adc + +commit ac3451dd65f27ecf85dc045c46d49e2bbcb8dddd +Author: djm@openbsd.org +Date: Fri Sep 4 03:57:38 2015 +0000 + + upstream commit + + remove extra newline in nethack-mode hostkey; from + Christian Hesse bz#2686 + + Upstream-ID: 4f56368b1cc47baeea0531912186f66007fd5b92 + +commit 9e3ed9ebb1a7e47c155c28399ddf09b306ea05df +Author: djm@openbsd.org +Date: Fri Sep 4 04:23:10 2015 +0000 + + upstream commit + + trim junk from end of file; bz#2455 from Jakub Jelen + + Upstream-Regress-ID: a4e64e8931e40d23874b047074444eff919cdfe6 + +commit f3a3ea180afff080bab82087ee0b60db9fd84f6c +Author: jsg@openbsd.org +Date: Wed Sep 2 07:51:12 2015 +0000 + + upstream commit + + Fix occurrences of "r = func() != 0" which result in the + wrong error codes being returned due to != having higher precedence than =. + + ok deraadt@ markus@ + + Upstream-ID: 5fc35c9fc0319cc6fca243632662d2f06b5fd840 + +commit f498a98cf83feeb7ea01c15cd1c98b3111361f3a +Author: Damien Miller +Date: Thu Sep 3 09:11:22 2015 +1000 + + don't check for yp_match; ok tim@ + +commit 9690b78b7848b0b376980a61d51b1613e187ddb5 +Author: djm@openbsd.org +Date: Fri Aug 21 23:57:48 2015 +0000 + + upstream commit + + Improve printing of KEX offers and decisions + + The debug output now labels the client and server offers and the + negotiated options. ok markus@ + + Upstream-ID: 8db921b3f92a4565271b1c1fbce6e7f508e1a2cb + +commit 60a92470e21340e1a3fc10f9c7140d8e1519dc55 +Author: djm@openbsd.org +Date: Fri Aug 21 23:53:08 2015 +0000 + + upstream commit + + Fix printing (ssh -G ...) of HostKeyAlgorithms=+... + Reported by Bryan Drewery + + Upstream-ID: 19ad20c41bd5971e006289b6f9af829dd46c1293 + +commit 6310f60fffca2d1e464168e7d1f7e3b6b0268897 +Author: djm@openbsd.org +Date: Fri Aug 21 23:52:30 2015 +0000 + + upstream commit + + Fix expansion of HostkeyAlgorithms=+... + + Reported by Bryan Drewery + + Upstream-ID: 70ca1deea39d758ba36d36428ae832e28566f78d + +commit e774e5ea56237fd626a8161f9005023dff3e76c9 +Author: deraadt@openbsd.org +Date: Fri Aug 21 23:29:31 2015 +0000 + + upstream commit + + Improve size == 0, count == 0 checking in mm_zalloc, + which is "array" like. Discussed with tedu, millert, otto.... and ok djm + + Upstream-ID: 899b021be43b913fad3eca1aef44efe710c53e29 + +commit 189de02d9ad6f3645417c0ddf359b923aae5f926 +Author: Damien Miller +Date: Fri Aug 21 15:45:02 2015 +1000 + + expose POLLHUP and POLLNVAL for netcat.c commit e91346dc2bbf460246df2ab591b7613908c1b0ad Author: Damien Miller @@ -6685,931 +8905,3 @@ 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@ diff --git a/Makefile.in b/Makefile.in index 40cc7aae1ed0..d401787db0ae 100644 --- a/Makefile.in +++ b/Makefile.in @@ -91,11 +91,11 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ 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 + kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \ + platform-pledge.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ - sshconnect.o sshconnect1.o sshconnect2.o mux.o \ - roaming_common.o roaming_client.o + sshconnect.o sshconnect1.o sshconnect2.o mux.o SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ audit.o audit-bsm.o audit-linux.o platform.o \ @@ -108,9 +108,9 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.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 \ - roaming_common.o roaming_serv.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ + sandbox-solaris.o MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 sshd_config.5 ssh_config.5 @@ -178,14 +178,14 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o - $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o readconf.o + $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o - $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) +ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -327,10 +327,6 @@ install-files: $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 $(INSTALL) -m 644 ssh-pkcs11-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 - -rm -f $(DESTDIR)$(bindir)/slogin - ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 - ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 install-sysconf: if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ @@ -359,41 +355,19 @@ install-sysconf: host-key: ssh-keygen$(EXEEXT) @if [ -z "$(DESTDIR)" ] ; then \ - if [ -f "$(sysconfdir)/ssh_host_key" ] ; then \ - echo "$(sysconfdir)/ssh_host_key already exists, skipping." ; \ - else \ - ./ssh-keygen -t rsa1 -f $(sysconfdir)/ssh_host_key -N "" ; \ - fi ; \ - if [ -f $(sysconfdir)/ssh_host_dsa_key ] ; then \ - echo "$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ - else \ - ./ssh-keygen -t dsa -f $(sysconfdir)/ssh_host_dsa_key -N "" ; \ - fi ; \ - if [ -f $(sysconfdir)/ssh_host_rsa_key ] ; then \ - echo "$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \ - else \ - ./ssh-keygen -t rsa -f $(sysconfdir)/ssh_host_rsa_key -N "" ; \ - fi ; \ - if [ -f $(sysconfdir)/ssh_host_ed25519_key ] ; then \ - echo "$(sysconfdir)/ssh_host_ed25519_key already exists, skipping." ; \ - else \ - ./ssh-keygen -t ed25519 -f $(sysconfdir)/ssh_host_ed25519_key -N "" ; \ - fi ; \ - if [ -z "@COMMENT_OUT_ECC@" ] ; then \ - if [ -f $(sysconfdir)/ssh_host_ecdsa_key ] ; then \ - echo "$(sysconfdir)/ssh_host_ecdsa_key already exists, skipping." ; \ - else \ - ./ssh-keygen -t ecdsa -f $(sysconfdir)/ssh_host_ecdsa_key -N "" ; \ - fi ; \ - fi ; \ - fi ; + ./ssh-keygen -A; \ + fi -host-key-force: ssh-keygen$(EXEEXT) - ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" +host-key-force: ssh-keygen$(EXEEXT) ssh$(EXEEXT) + if ./ssh -Q protocol-version | grep '^1$$' >/dev/null; then \ + ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""; \ + fi ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ./ssh-keygen -t ed25519 -f $(DESTDIR)$(sysconfdir)/ssh_host_ed25519_key -N "" - test -z "@COMMENT_OUT_ECC@" && ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N "" + if ./ssh -Q key | grep ecdsa >/dev/null ; then \ + ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N ""; \ + fi uninstallall: uninstall -rm -f $(DESTDIR)$(sysconfdir)/ssh_config @@ -407,7 +381,6 @@ uninstallall: uninstall -rmdir $(DESTDIR)$(libexecdir) uninstall: - -rm -f $(DESTDIR)$(bindir)/slogin -rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT) -rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT) -rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT) @@ -430,7 +403,6 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 - -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 regress-prep: [ -d `pwd`/regress ] || mkdir -p `pwd`/regress @@ -462,6 +434,10 @@ regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) +regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.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 @@ -510,8 +486,7 @@ regress/unittests/bitmap/test_bitmap$(EXEEXT): ${UNITTESTS_TEST_BITMAP_OBJS} \ UNITTESTS_TEST_KEX_OBJS=\ regress/unittests/kex/tests.o \ - regress/unittests/kex/test_kex.o \ - roaming_dummy.o + regress/unittests/kex/test_kex.o regress/unittests/kex/test_kex$(EXEEXT): ${UNITTESTS_TEST_KEX_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a @@ -534,6 +509,7 @@ REGRESS_BINARIES=\ regress/modpipe$(EXEEXT) \ regress/setuid-allowed$(EXEEXT) \ regress/netcat$(EXEEXT) \ + regress/check-perm$(EXEEXT) \ regress/unittests/sshbuf/test_sshbuf$(EXEEXT) \ regress/unittests/sshkey/test_sshkey$(EXEEXT) \ regress/unittests/bitmap/test_bitmap$(EXEEXT) \ diff --git a/README b/README index ea6e228dda95..0dd047af34ff 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-7.1p2 for the release notes. +See http://www.openssh.com/txt/release-7.2p1 for the release notes. Please read http://www.openssh.com/report.html for bug reporting instructions and note that we do not use Github for bug reporting or diff --git a/README.platform b/README.platform index d1982321e3a9..8d75c16c1ca3 100644 --- a/README.platform +++ b/README.platform @@ -36,6 +36,9 @@ loginrestrictions() function, in particular that the user has the "rlogin" attribute set. This check is not done for the root account, instead the PermitRootLogin setting in sshd_config is used. +If you are using the IBM compiler you probably want to use CC=xlc rather +than the default of cc. + Cygwin ------ diff --git a/auth-bsdauth.c b/auth-bsdauth.c index 37ff893e6938..e00718f2ed3f 100644 --- a/auth-bsdauth.c +++ b/auth-bsdauth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-bsdauth.c,v 1.13 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: auth-bsdauth.c,v 1.14 2015/10/20 23:24:25 mmcc Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -103,7 +103,7 @@ bsdauth_respond(void *ctx, u_int numresponses, char **responses) if (!authctxt->valid) return -1; - if (authctxt->as == 0) + if (authctxt->as == NULL) error("bsdauth_respond: no bsd auth session"); if (numresponses != 1) diff --git a/auth-krb5.c b/auth-krb5.c index 0089b18440a9..d1c5a2f32898 100644 --- a/auth-krb5.c +++ b/auth-krb5.c @@ -1,8 +1,8 @@ -/* $OpenBSD: auth-krb5.c,v 1.20 2013/07/20 01:55:13 djm Exp $ */ +/* $OpenBSD: auth-krb5.c,v 1.21 2016/01/27 06:44:58 djm Exp $ */ /* * Kerberos v5 authentication and ticket-passing routines. * - * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $ + * From: FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar */ /* * Copyright (c) 2002 Daniel Kouril. All rights reserved. diff --git a/auth-options.c b/auth-options.c index e387697d36d0..edbaf80bbf09 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.68 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.70 2015/12/10 17:08:40 mmcc Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -75,18 +75,44 @@ auth_clear_options(void) free(ce->s); free(ce); } - if (forced_command) { - free(forced_command); - forced_command = NULL; - } - if (authorized_principals) { - free(authorized_principals); - authorized_principals = NULL; - } + free(forced_command); + forced_command = NULL; + free(authorized_principals); + authorized_principals = NULL; forced_tun_device = -1; channel_clear_permitted_opens(); } +/* + * Match flag 'opt' in *optsp, and if allow_negate is set then also match + * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0 + * if negated option matches. + * If the option or negated option matches, then *optsp is updated to + * point to the first character after the option and, if 'msg' is not NULL + * then a message based on it added via auth_debug_add(). + */ +static int +match_flag(const char *opt, int allow_negate, char **optsp, const char *msg) +{ + size_t opt_len = strlen(opt); + char *opts = *optsp; + int negate = 0; + + if (allow_negate && strncasecmp(opts, "no-", 3) == 0) { + opts += 3; + negate = 1; + } + if (strncasecmp(opts, opt, opt_len) == 0) { + *optsp = opts + opt_len; + if (msg != NULL) { + auth_debug_add("%s %s.", msg, + negate ? "disabled" : "enabled"); + } + return negate ? 0 : 1; + } + return -1; +} + /* * return 1 if access is granted, 0 if not. * side effect: sets key option flags @@ -95,7 +121,7 @@ int auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) { const char *cp; - int i; + int i, r; /* reset options */ auth_clear_options(); @@ -104,52 +130,48 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) return 1; while (*opts && *opts != ' ' && *opts != '\t') { - cp = "cert-authority"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - key_is_cert_authority = 1; - opts += strlen(cp); + if ((r = match_flag("cert-authority", 0, &opts, NULL)) != -1) { + key_is_cert_authority = r; goto next_option; } - cp = "no-port-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Port forwarding disabled."); + if ((r = match_flag("restrict", 0, &opts, NULL)) != -1) { + auth_debug_add("Key is restricted."); no_port_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-agent-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Agent forwarding disabled."); no_agent_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-X11-forwarding"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("X11 forwarding disabled."); no_x11_forwarding_flag = 1; - opts += strlen(cp); - goto next_option; - } - cp = "no-pty"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("Pty allocation disabled."); no_pty_flag = 1; - opts += strlen(cp); + no_user_rc = 1; goto next_option; } - cp = "no-user-rc"; - if (strncasecmp(opts, cp, strlen(cp)) == 0) { - auth_debug_add("User rc file execution disabled."); - no_user_rc = 1; - opts += strlen(cp); + if ((r = match_flag("port-forwarding", 1, &opts, + "Port forwarding")) != -1) { + no_port_forwarding_flag = r != 1; + goto next_option; + } + if ((r = match_flag("agent-forwarding", 1, &opts, + "Agent forwarding")) != -1) { + no_agent_forwarding_flag = r != 1; + goto next_option; + } + if ((r = match_flag("x11-forwarding", 1, &opts, + "X11 forwarding")) != -1) { + no_x11_forwarding_flag = r != 1; + goto next_option; + } + if ((r = match_flag("pty", 1, &opts, + "PTY allocation")) != -1) { + no_pty_flag = r != 1; + goto next_option; + } + if ((r = match_flag("user-rc", 1, &opts, + "User rc execution")) != -1) { + no_user_rc = r != 1; goto next_option; } cp = "command=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { opts += strlen(cp); - if (forced_command != NULL) - free(forced_command); + free(forced_command); forced_command = xmalloc(strlen(opts) + 1); i = 0; while (*opts) { @@ -179,8 +201,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) cp = "principals=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { opts += strlen(cp); - if (authorized_principals != NULL) - free(authorized_principals); + free(authorized_principals); authorized_principals = xmalloc(strlen(opts) + 1); i = 0; while (*opts) { @@ -566,8 +587,7 @@ parse_option_list(struct sshbuf *oblob, struct passwd *pw, free(*cert_forced_command); *cert_forced_command = NULL; } - if (name != NULL) - free(name); + free(name); sshbuf_free(data); sshbuf_free(c); return ret; @@ -611,8 +631,7 @@ auth_cert_options(struct sshkey *k, struct passwd *pw) no_user_rc |= cert_no_user_rc; /* CA-specified forced command supersedes key option */ if (cert_forced_command != NULL) { - if (forced_command != NULL) - free(forced_command); + free(forced_command); forced_command = cert_forced_command; } return 0; diff --git a/auth-pam.c b/auth-pam.c index d94c8285bba4..8425af1ea33a 100644 --- a/auth-pam.c +++ b/auth-pam.c @@ -45,7 +45,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ +/* Based on FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des */ + #include "includes.h" #include diff --git a/auth.h b/auth.h index 8b27575b071d..2160154f495c 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.84 2015/05/08 06:41:56 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.86 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -209,7 +209,7 @@ Key *get_hostkey_private_by_type(int, int, struct ssh *); int get_hostkey_index(Key *, int, struct ssh *); int ssh1_session_key(BIGNUM *); int sshd_hostkey_sign(Key *, Key *, u_char **, size_t *, - const u_char *, size_t, u_int); + const u_char *, size_t, const char *, u_int); /* debug messages during authentication */ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 5aa319ccc117..41b34aed2417 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.53 2015/06/15 18:44:22 jsing Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.55 2016/01/27 00:53:12 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -79,19 +79,19 @@ userauth_pubkey(Authctxt *authctxt) { Buffer b; Key *key = NULL; - char *pkalg, *userstyle; + char *pkalg, *userstyle, *fp = NULL; u_char *pkblob, *sig; u_int alen, blen, slen; int have_sig, pktype; int authenticated = 0; if (!authctxt->valid) { - debug2("userauth_pubkey: disabled because of invalid user"); + debug2("%s: disabled because of invalid user", __func__); return 0; } have_sig = packet_get_char(); if (datafellows & SSH_BUG_PKAUTH) { - debug2("userauth_pubkey: SSH_BUG_PKAUTH"); + debug2("%s: SSH_BUG_PKAUTH", __func__); /* no explicit pkalg given */ pkblob = packet_get_string(&blen); buffer_init(&b); @@ -106,18 +106,18 @@ userauth_pubkey(Authctxt *authctxt) pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ - logit("userauth_pubkey: unsupported public key algorithm: %s", - pkalg); + logit("%s: unsupported public key algorithm: %s", + __func__, pkalg); goto done; } key = key_from_blob(pkblob, blen); if (key == NULL) { - error("userauth_pubkey: cannot decode key: %s", pkalg); + error("%s: cannot decode key: %s", __func__, pkalg); goto done; } if (key->type != pktype) { - error("userauth_pubkey: type mismatch for decoded key " - "(received %d, expected %d)", key->type, pktype); + error("%s: type mismatch for decoded key " + "(received %d, expected %d)", __func__, key->type, pktype); goto done; } if (key_type_plain(key->type) == KEY_RSA && @@ -126,6 +126,7 @@ userauth_pubkey(Authctxt *authctxt) "signature scheme"); goto done; } + fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); if (auth2_userkey_already_used(authctxt, key)) { logit("refusing previously-used %s key", key_type(key)); goto done; @@ -138,6 +139,8 @@ userauth_pubkey(Authctxt *authctxt) } if (have_sig) { + debug3("%s: have signature for %s %s", + __func__, sshkey_type(key), fp); sig = packet_get_string(&slen); packet_check_eom(); buffer_init(&b); @@ -183,7 +186,8 @@ userauth_pubkey(Authctxt *authctxt) buffer_free(&b); free(sig); } else { - debug("test whether pkalg/pkblob are acceptable"); + debug("%s: test whether pkalg/pkblob are acceptable for %s %s", + __func__, sshkey_type(key), fp); packet_check_eom(); /* XXX fake reply and always send PK_OK ? */ @@ -206,11 +210,12 @@ userauth_pubkey(Authctxt *authctxt) if (authenticated != 1) auth_clear_options(); done: - debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); + debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); if (key != NULL) key_free(key); free(pkalg); free(pkblob); + free(fp); return authenticated; } @@ -796,8 +801,9 @@ check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw) free(fp); continue; } - verbose("Accepted certificate ID \"%s\" " + verbose("Accepted certificate ID \"%s\" (serial %llu) " "signed by %s CA %s via %s", key->cert->key_id, + (unsigned long long)key->cert->serial, key_type(found), fp, file); free(fp); found_key = 1; @@ -875,8 +881,10 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) if (auth_cert_options(key, pw) != 0) goto out; - verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s", - key->cert->key_id, key_type(key->cert->signature_key), ca_fp, + verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " + "%s CA %s via %s", key->cert->key_id, + (unsigned long long)key->cert->serial, + key_type(key->cert->signature_key), ca_fp, options.trusted_user_ca_keys); ret = 1; diff --git a/authfd.c b/authfd.c index eaa1426485d0..a634bcb81c58 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.98 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -426,11 +426,24 @@ ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, } #endif +/* encode signature algoritm in flag bits, so we can keep the msg format */ +static u_int +agent_encode_alg(struct sshkey *key, const char *alg) +{ + if (alg != NULL && key->type == KEY_RSA) { + if (strcmp(alg, "rsa-sha2-256") == 0) + return SSH_AGENT_RSA_SHA2_256; + else if (strcmp(alg, "rsa-sha2-512") == 0) + return SSH_AGENT_RSA_SHA2_512; + } + return 0; +} + /* ask agent to sign data, returns err.h code on error, 0 on success */ 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) + const u_char *data, size_t datalen, const char *alg, u_int compat) { struct sshbuf *msg; u_char *blob = NULL, type; @@ -449,12 +462,13 @@ ssh_agent_sign(int sock, struct sshkey *key, return SSH_ERR_ALLOC_FAIL; if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) goto out; + flags |= agent_encode_alg(key, alg); 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)) + if ((r = ssh_request_reply(sock, msg, msg)) != 0) goto out; if ((r = sshbuf_get_u8(msg, &type)) != 0) goto out; diff --git a/authfd.h b/authfd.h index bea20c26bc96..4b417e3f4a22 100644 --- a/authfd.h +++ b/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.38 2015/01/14 20:05:27 djm Exp $ */ +/* $OpenBSD: authfd.h,v 1.39 2015/12/04 16:41:28 markus Exp $ */ /* * Author: Tatu Ylonen @@ -41,7 +41,7 @@ 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); + const u_char *data, size_t datalen, const char *alg, u_int compat); /* Messages for the authentication agent connection. */ #define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 @@ -86,5 +86,7 @@ int ssh_agent_sign(int sock, struct sshkey *key, #define SSH_COM_AGENT2_FAILURE 102 #define SSH_AGENT_OLD_SIGNATURE 0x01 +#define SSH_AGENT_RSA_SHA2_256 0x02 +#define SSH_AGENT_RSA_SHA2_512 0x04 #endif /* AUTHFD_H */ diff --git a/authfile.c b/authfile.c index 58f589a4745d..d67042411cca 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.116 2015/07/09 09:49:46 markus Exp $ */ +/* $OpenBSD: authfile.c,v 1.120 2015/12/11 04:21:11 mmcc Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * @@ -243,8 +243,7 @@ sshkey_load_private_type_fd(int fd, int type, const char *passphrase, /* success */ r = 0; out: - if (buffer != NULL) - sshbuf_free(buffer); + sshbuf_free(buffer); return r; } @@ -272,14 +271,13 @@ sshkey_load_private(const char *filename, const char *passphrase, goto out; } if ((r = sshkey_load_file(fd, buffer)) != 0 || - (r = sshkey_parse_private_fileblob(buffer, passphrase, filename, - keyp, commentp)) != 0) + (r = sshkey_parse_private_fileblob(buffer, passphrase, keyp, + commentp)) != 0) goto out; r = 0; out: close(fd); - if (buffer != NULL) - sshbuf_free(buffer); + sshbuf_free(buffer); return r; } @@ -426,10 +424,8 @@ sshkey_load_cert(const char *filename, struct sshkey **keyp) r = 0; out: - if (file != NULL) - free(file); - if (pub != NULL) - sshkey_free(pub); + free(file); + sshkey_free(pub); return r; } @@ -474,10 +470,8 @@ sshkey_load_private_cert(int type, const char *filename, const char *passphrase, *keyp = key; key = NULL; out: - if (key != NULL) - sshkey_free(key); - if (cert != NULL) - sshkey_free(cert); + sshkey_free(key); + sshkey_free(cert); return r; } @@ -538,8 +532,7 @@ sshkey_in_file(struct sshkey *key, const char *filename, int strict_type, } r = SSH_ERR_KEY_NOT_FOUND; out: - if (pub != NULL) - sshkey_free(pub); + sshkey_free(pub); fclose(f); return r; } diff --git a/channels.c b/channels.c index a84b487e57b2..c9d2015eea39 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.347 2015/07/01 02:26:31 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.349 2016/02/05 13:28:19 naddy Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -662,7 +662,7 @@ channel_open_message(void) case SSH_CHANNEL_INPUT_DRAINING: case SSH_CHANNEL_OUTPUT_DRAINING: snprintf(buf, sizeof buf, - " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d cc %d)\r\n", + " #%d %.300s (t%d r%d i%u/%d o%u/%d fd %d/%d cc %d)\r\n", c->self, c->remote_name, c->type, c->remote_id, c->istate, buffer_len(&c->input), @@ -1896,13 +1896,13 @@ read_mux(Channel *c, u_int need) if (buffer_len(&c->input) < need) { rlen = need - buffer_len(&c->input); len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF)); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return buffer_len(&c->input); if (len <= 0) { - if (errno != EINTR && errno != EAGAIN) { - debug2("channel %d: ctl read<=0 rfd %d len %d", - c->self, c->rfd, len); - chan_read_failed(c); - return 0; - } + debug2("channel %d: ctl read<=0 rfd %d len %d", + c->self, c->rfd, len); + chan_read_failed(c); + return 0; } else buffer_append(&c->input, buf, len); } diff --git a/cipher.c b/cipher.c index 02dae6f9fa1f..13847e5bd7b6 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.100 2015/01/14 10:29:45 djm Exp $ */ +/* $OpenBSD: cipher.c,v 1.101 2015/12/10 17:08:40 mmcc Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -353,8 +353,7 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, if (cipher->discard_len > 0) { if ((junk = malloc(cipher->discard_len)) == NULL || (discard = malloc(cipher->discard_len)) == NULL) { - if (junk != NULL) - free(junk); + free(junk); ret = SSH_ERR_ALLOC_FAIL; goto bad; } diff --git a/clientloop.c b/clientloop.c index 87ceb3dab9e6..9820455c4293 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.275 2015/07/10 06:21:53 markus Exp $ */ +/* $OpenBSD: clientloop.c,v 1.284 2016/02/08 10:57:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -111,7 +111,6 @@ #include "sshpty.h" #include "match.h" #include "msg.h" -#include "roaming.h" #include "ssherr.h" #include "hostfile.h" @@ -169,8 +168,6 @@ static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ static void client_init_dispatch(void); int session_ident = -1; -int session_resumed = 0; - /* Track escape per proto2 channel */ struct escape_filter_ctx { int escape_pending; @@ -288,6 +285,9 @@ client_x11_display_valid(const char *display) { size_t i, dlen; + if (display == NULL) + return 0; + dlen = strlen(display); for (i = 0; i < dlen; i++) { if (!isalnum((u_char)display[i]) && @@ -301,35 +301,34 @@ client_x11_display_valid(const char *display) #define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1" #define X11_TIMEOUT_SLACK 60 -void +int client_x11_get_proto(const char *display, const char *xauth_path, u_int trusted, u_int timeout, char **_proto, char **_data) { - char cmd[1024]; - char line[512]; - char xdisplay[512]; + char cmd[1024], line[512], xdisplay[512]; + char xauthfile[PATH_MAX], xauthdir[PATH_MAX]; static char proto[512], data[512]; FILE *f; - int got_data = 0, generated = 0, do_unlink = 0, i; - char *xauthdir, *xauthfile; + int got_data = 0, generated = 0, do_unlink = 0, i, r; struct stat st; u_int now, x11_timeout_real; - xauthdir = xauthfile = NULL; *_proto = proto; *_data = data; - proto[0] = data[0] = '\0'; + proto[0] = data[0] = xauthfile[0] = xauthdir[0] = '\0'; - if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { + if (!client_x11_display_valid(display)) { + if (display != NULL) + logit("DISPLAY \"%s\" invalid; disabling X11 forwarding", + display); + return -1; + } + if (xauth_path != NULL && stat(xauth_path, &st) == -1) { debug("No xauth program."); - } else if (!client_x11_display_valid(display)) { - logit("DISPLAY '%s' invalid, falling back to fake xauth data", - display); - } else { - if (display == NULL) { - debug("x11_get_proto: DISPLAY not set"); - return; - } + xauth_path = NULL; + } + + if (xauth_path != NULL) { /* * Handle FamilyLocal case where $DISPLAY does * not match an authorization entry. For this we @@ -338,45 +337,60 @@ client_x11_get_proto(const char *display, const char *xauth_path, * is not perfect. */ if (strncmp(display, "localhost:", 10) == 0) { - snprintf(xdisplay, sizeof(xdisplay), "unix:%s", - display + 10); + if ((r = snprintf(xdisplay, sizeof(xdisplay), "unix:%s", + display + 10)) < 0 || + (size_t)r >= sizeof(xdisplay)) { + error("%s: display name too long", __func__); + return -1; + } display = xdisplay; } if (trusted == 0) { - xauthdir = xmalloc(PATH_MAX); - xauthfile = xmalloc(PATH_MAX); - mktemp_proto(xauthdir, PATH_MAX); /* + * Generate an untrusted X11 auth cookie. + * * The authentication cookie should briefly outlive * ssh's willingness to forward X11 connections to * avoid nasty fail-open behaviour in the X server. */ + mktemp_proto(xauthdir, sizeof(xauthdir)); + if (mkdtemp(xauthdir) == NULL) { + error("%s: mkdtemp: %s", + __func__, strerror(errno)); + return -1; + } + do_unlink = 1; + if ((r = snprintf(xauthfile, sizeof(xauthfile), + "%s/xauthfile", xauthdir)) < 0 || + (size_t)r >= sizeof(xauthfile)) { + error("%s: xauthfile path too long", __func__); + unlink(xauthfile); + rmdir(xauthdir); + return -1; + } + if (timeout >= UINT_MAX - X11_TIMEOUT_SLACK) x11_timeout_real = UINT_MAX; else x11_timeout_real = timeout + X11_TIMEOUT_SLACK; - if (mkdtemp(xauthdir) != NULL) { - do_unlink = 1; - snprintf(xauthfile, PATH_MAX, "%s/xauthfile", - xauthdir); - snprintf(cmd, sizeof(cmd), - "%s -f %s generate %s " SSH_X11_PROTO - " untrusted timeout %u 2>" _PATH_DEVNULL, - xauth_path, xauthfile, display, - x11_timeout_real); - debug2("x11_get_proto: %s", cmd); - if (x11_refuse_time == 0) { - now = monotime() + 1; - if (UINT_MAX - timeout < now) - x11_refuse_time = UINT_MAX; - else - x11_refuse_time = now + timeout; - channel_set_x11_refuse_time( - x11_refuse_time); - } - if (system(cmd) == 0) - generated = 1; + if ((r = snprintf(cmd, sizeof(cmd), + "%s -f %s generate %s " SSH_X11_PROTO + " untrusted timeout %u 2>" _PATH_DEVNULL, + xauth_path, xauthfile, display, + x11_timeout_real)) < 0 || + (size_t)r >= sizeof(cmd)) + fatal("%s: cmd too long", __func__); + debug2("%s: %s", __func__, cmd); + if (x11_refuse_time == 0) { + now = monotime() + 1; + if (UINT_MAX - timeout < now) + x11_refuse_time = UINT_MAX; + else + x11_refuse_time = now + timeout; + channel_set_x11_refuse_time(x11_refuse_time); } + if (system(cmd) == 0) + generated = 1; } /* @@ -398,17 +412,20 @@ client_x11_get_proto(const char *display, const char *xauth_path, got_data = 1; if (f) pclose(f); - } else - error("Warning: untrusted X11 forwarding setup failed: " - "xauth key data not generated"); + } } if (do_unlink) { unlink(xauthfile); rmdir(xauthdir); } - free(xauthdir); - free(xauthfile); + + /* Don't fall back to fake X11 data for untrusted forwarding */ + if (!trusted && !got_data) { + error("Warning: untrusted X11 forwarding setup failed: " + "xauth key data not generated"); + return -1; + } /* * If we didn't get authentication data, just make up some @@ -432,6 +449,8 @@ client_x11_get_proto(const char *display, const char *xauth_path, rnd >>= 8; } } + + return 0; } /* @@ -735,7 +754,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) static void client_process_net_input(fd_set *readset) { - int len, cont = 0; + int len; char buf[SSH_IOBUFSZ]; /* @@ -744,8 +763,8 @@ client_process_net_input(fd_set *readset) */ if (FD_ISSET(connection_in, readset)) { /* Read as much as possible. */ - len = roaming_read(connection_in, buf, sizeof(buf), &cont); - if (len == 0 && cont == 0) { + len = read(connection_in, buf, sizeof(buf)); + if (len == 0) { /* * Received EOF. The remote host has closed the * connection. @@ -1483,13 +1502,43 @@ 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 r, max_fd = 0, max_fd2 = 0, len, rekeying = 0; + int r, max_fd = 0, max_fd2 = 0, len; u_int64_t ibytes, obytes; u_int nalloc = 0; char buf[100]; debug("Entering interactive session."); + if (options.control_master && + ! option_clear_or_none(options.control_path)) { + debug("pledge: id"); + if (pledge("stdio rpath wpath cpath unix inet dns proc exec id tty", + NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + + } else if (options.forward_x11 || options.permit_local_command) { + debug("pledge: exec"); + if (pledge("stdio rpath wpath cpath unix inet dns proc exec tty", + NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + + } else if (options.update_hostkeys) { + debug("pledge: filesystem full"); + if (pledge("stdio rpath wpath cpath unix inet dns proc tty", + NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + + } else if (! option_clear_or_none(options.proxy_command)) { + debug("pledge: proc"); + if (pledge("stdio cpath unix inet dns proc tty", NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + + } else { + debug("pledge: network"); + if (pledge("stdio unix inet dns tty", NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + } + start_time = get_current_time(); /* Initialize variables. */ @@ -1568,10 +1617,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) if (compat20 && session_closed && !channel_still_open()) break; - rekeying = (active_state->kex != NULL && !active_state->kex->done); - - if (rekeying) { + if (ssh_packet_is_rekeying(active_state)) { debug("rekeying in progress"); + } else if (need_rekeying) { + /* manual rekey request */ + debug("need rekeying"); + if ((r = kex_start_rekex(active_state)) != 0) + fatal("%s: kex_start_rekex: %s", __func__, + ssh_err(r)); + need_rekeying = 0; } else { /* * Make packets of buffered stdin data, and buffer @@ -1602,23 +1656,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) */ max_fd2 = max_fd; client_wait_until_can_do_something(&readset, &writeset, - &max_fd2, &nalloc, rekeying); + &max_fd2, &nalloc, ssh_packet_is_rekeying(active_state)); if (quit_pending) break; /* Do channel operations unless rekeying in progress. */ - if (!rekeying) { + if (!ssh_packet_is_rekeying(active_state)) channel_after_select(readset, writeset); - if (need_rekeying || packet_need_rekeying()) { - debug("need rekeying"); - 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; - } - } /* Buffer input from the connection. */ client_process_net_input(readset); @@ -1636,14 +1681,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) client_process_output(writeset); } - if (session_resumed) { - connection_in = packet_get_connection_in(); - connection_out = packet_get_connection_out(); - max_fd = MAX(max_fd, connection_out); - max_fd = MAX(max_fd, connection_in); - session_resumed = 0; - } - /* * Send as much buffered packet data as possible to the * sender. @@ -1737,7 +1774,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) } /* Clear and free any buffers. */ - memset(buf, 0, sizeof(buf)); + explicit_bzero(buf, sizeof(buf)); buffer_free(&stdin_buffer); buffer_free(&stdout_buffer); buffer_free(&stderr_buffer); diff --git a/clientloop.h b/clientloop.h index 338d45186f8b..f4d4c69b73a0 100644 --- a/clientloop.h +++ b/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.31 2013/06/02 23:36:29 dtucker Exp $ */ +/* $OpenBSD: clientloop.h,v 1.32 2016/01/13 23:04:47 djm Exp $ */ /* * Author: Tatu Ylonen @@ -39,7 +39,7 @@ /* Client side main loop for the interactive session. */ int client_loop(int, int, int); -void client_x11_get_proto(const char *, const char *, u_int, u_int, +int client_x11_get_proto(const char *, const char *, u_int, u_int, char **, char **); void client_global_request_reply_fwd(int, u_int32_t, void *); void client_session2_setup(int, int, int, const char *, struct termios *, diff --git a/config.h.in b/config.h.in index 7500df532618..89bf1b0ff6a0 100644 --- a/config.h.in +++ b/config.h.in @@ -694,9 +694,6 @@ /* Define to 1 if you have the `network' library (-lnetwork). */ #undef HAVE_LIBNETWORK -/* Define to 1 if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - /* Define to 1 if you have the `pam' library (-lpam). */ #undef HAVE_LIBPAM @@ -845,6 +842,9 @@ /* define if you have pid_t data type */ #undef HAVE_PID_T +/* Define to 1 if you have the `pledge' function. */ +#undef HAVE_PLEDGE + /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL @@ -854,6 +854,12 @@ /* Define to 1 if you have the `prctl' function. */ #undef HAVE_PRCTL +/* Define to 1 if you have the `priv_basicset' function. */ +#undef HAVE_PRIV_BASICSET + +/* Define to 1 if you have the header file. */ +#undef HAVE_PRIV_H + /* Define if you have /proc/$pid/fd */ #undef HAVE_PROC_PID @@ -956,6 +962,9 @@ /* Define to 1 if you have the `setpcred' function. */ #undef HAVE_SETPCRED +/* Define to 1 if you have the `setppriv' function. */ +#undef HAVE_SETPPRIV + /* Define to 1 if you have the `setproctitle' function. */ #undef HAVE_SETPROCTITLE @@ -1444,6 +1453,9 @@ /* Define if you don't want to use lastlog in session.c */ #undef NO_SSH_LASTLOG +/* Define to disable UID restoration test */ +#undef NO_UID_RESTORATION_TEST + /* Define if X11 doesn't support AF_UNIX sockets on that system */ #undef NO_X11_UNIX_SOCKETS @@ -1520,6 +1532,9 @@ /* no privsep sandboxing */ #undef SANDBOX_NULL +/* Sandbox using pledge(2) */ +#undef SANDBOX_PLEDGE + /* Sandbox using setrlimit(2) */ #undef SANDBOX_RLIMIT @@ -1532,6 +1547,9 @@ /* define if setrlimit RLIMIT_NOFILE breaks things */ #undef SANDBOX_SKIP_RLIMIT_NOFILE +/* Sandbox using Solaris/Illumos privileges */ +#undef SANDBOX_SOLARIS + /* Sandbox using systrace(4) */ #undef SANDBOX_SYSTRACE @@ -1638,6 +1656,9 @@ /* Use PIPES instead of a socketpair() */ #undef USE_PIPES +/* Define if you have Solaris privileges */ +#undef USE_SOLARIS_PRIVS + /* Define if you have Solaris process contracts */ #undef USE_SOLARIS_PROCESS_CONTRACTS diff --git a/configure b/configure index 0d7a5b97eaa4..2a46ba9665fb 100755 --- a/configure +++ b/configure @@ -1320,7 +1320,7 @@ 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 Enable support for SSH protocol 1 + --with-ssh1 Enable 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 @@ -1331,6 +1331,7 @@ Optional Packages: --with-Werror Build main code with -Werror --with-solaris-contracts Enable Solaris process contracts (experimental) --with-solaris-projects Enable Solaris projects (experimental) + --with-solaris-privs Enable Solaris/Illumos privileges (experimental) --with-osfsia Enable Digital Unix SIA --with-zlib=PATH Use zlib in PATH --without-zlib-version-check Disable zlib version check @@ -1346,7 +1347,7 @@ Optional Packages: --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool) --with-pam Enable PAM support --with-privsep-user=user Specify non-privileged user for privilege separation - --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum) + --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) @@ -7972,6 +7973,11 @@ done SIA_MSG="no" SPC_MSG="no" SP_MSG="no" +SPP_MSG="no" + +# Support for Solaris/Illumos privileges (this test is used by both +# the --with-solaris-privs option and --with-sandbox=solaris). +SOLARIS_PRIVS="no" # Check for some target-specific stuff case "$host" in @@ -8959,6 +8965,11 @@ cat >>confdefs.h <<\_ACEOF _ACEOF +cat >>confdefs.h <<\_ACEOF +#define NO_UID_RESTORATION_TEST 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF #define DISABLE_SHADOW 1 _ACEOF @@ -9491,6 +9502,73 @@ fi done + { echo "$as_me:$LINENO: checking for sandbox_apply in -lsandbox" >&5 +echo $ECHO_N "checking for sandbox_apply in -lsandbox... $ECHO_C" >&6; } +if test "${ac_cv_lib_sandbox_sandbox_apply+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsandbox $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 sandbox_apply (); +int +main () +{ +return sandbox_apply (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_sandbox_sandbox_apply=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_sandbox_sandbox_apply=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_sandbox_sandbox_apply" >&5 +echo "${ECHO_T}$ac_cv_lib_sandbox_sandbox_apply" >&6; } +if test $ac_cv_lib_sandbox_sandbox_apply = yes; then + + SSHDLIBS="$SSHDLIBS -lsandbox" + +fi + ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" @@ -10789,6 +10867,339 @@ _ACEOF echo "${ECHO_T}no" >&6; } fi +for ac_func in setppriv +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_func in priv_basicset +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* 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 $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +for ac_header in priv.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ------------------------------------------- ## +## Report this to openssh-unix-dev@mindrot.org ## +## ------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + # Check whether --with-solaris-contracts was given. if test "${with_solaris_contracts+set}" = set; then withval=$with_solaris_contracts; @@ -10859,7 +11270,7 @@ cat >>confdefs.h <<\_ACEOF #define USE_SOLARIS_PROCESS_CONTRACTS 1 _ACEOF - SSHDLIBS="$SSHDLIBS -lcontract" + LIBS="$LIBS -lcontract" SPC_MSG="yes" fi @@ -10937,11 +11348,43 @@ cat >>confdefs.h <<\_ACEOF #define USE_SOLARIS_PROJECTS 1 _ACEOF - SSHDLIBS="$SSHDLIBS -lproject" + LIBS="$LIBS -lproject" SP_MSG="yes" fi +fi + + +# Check whether --with-solaris-privs was given. +if test "${with_solaris_privs+set}" = set; then + withval=$with_solaris_privs; + { echo "$as_me:$LINENO: checking for Solaris/Illumos privilege support" >&5 +echo $ECHO_N "checking for Solaris/Illumos privilege support... $ECHO_C" >&6; } + if test "x$ac_cv_func_setppriv" = "xyes" -a \ + "x$ac_cv_header_priv_h" = "xyes" ; then + SOLARIS_PRIVS=yes + { echo "$as_me:$LINENO: result: found" >&5 +echo "${ECHO_T}found" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define NO_UID_RESTORATION_TEST 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define USE_SOLARIS_PRIVS 1 +_ACEOF + + SPP_MSG="yes" + else + { echo "$as_me:$LINENO: result: not found" >&5 +echo "${ECHO_T}not found" >&6; } + { { echo "$as_me:$LINENO: error: *** must have support for Solaris privileges to use --with-solaris-privs" >&5 +echo "$as_me: error: *** must have support for Solaris privileges to use --with-solaris-privs" >&2;} + { (exit 1); exit 1; }; } + fi + fi TEST_SHELL=$SHELL # let configure find us a capable shell @@ -11942,163 +12385,6 @@ fi # Checks for libraries. -{ echo "$as_me:$LINENO: checking for yp_match" >&5 -echo $ECHO_N "checking for yp_match... $ECHO_C" >&6; } -if test "${ac_cv_func_yp_match+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define yp_match to an innocuous variant, in case declares yp_match. - For example, HP-UX 11i declares gettimeofday. */ -#define yp_match innocuous_yp_match - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char yp_match (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef yp_match - -/* 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 yp_match (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_yp_match || defined __stub___yp_match -choke me -#endif - -int -main () -{ -return yp_match (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_func_yp_match=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_yp_match=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_yp_match" >&5 -echo "${ECHO_T}$ac_cv_func_yp_match" >&6; } -if test $ac_cv_func_yp_match = yes; then - : -else - -{ echo "$as_me:$LINENO: checking for yp_match in -lnsl" >&5 -echo $ECHO_N "checking for yp_match in -lnsl... $ECHO_C" >&6; } -if test "${ac_cv_lib_nsl_yp_match+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* 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 yp_match (); -int -main () -{ -return yp_match (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_nsl_yp_match=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_nsl_yp_match=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_yp_match" >&5 -echo "${ECHO_T}$ac_cv_lib_nsl_yp_match" >&6; } -if test $ac_cv_lib_nsl_yp_match = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNSL 1 -_ACEOF - - LIBS="-lnsl $LIBS" - -fi - -fi - { echo "$as_me:$LINENO: checking for setsockopt" >&5 echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6; } if test "${ac_cv_func_setsockopt+set}" = set; then @@ -14599,7 +14885,8 @@ fi done -# On some platforms, inet_ntop may be found in libresolv or libnsl. +# On some platforms, inet_ntop and gethostbyname may be found in libresolv +# or libnsl. { echo "$as_me:$LINENO: checking for library containing inet_ntop" >&5 echo $ECHO_N "checking for library containing inet_ntop... $ECHO_C" >&6; } if test "${ac_cv_search_inet_ntop+set}" = set; then @@ -14683,6 +14970,89 @@ if test "$ac_res" != no; then fi +{ echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 +echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6; } +if test "${ac_cv_search_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* 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 gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +for ac_lib in '' resolv nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_gethostbyname=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_gethostbyname+set}" = set; then + break +fi +done +if test "${ac_cv_search_gethostbyname+set}" = set; then + : +else + ac_cv_search_gethostbyname=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6; } +ac_res=$ac_cv_search_gethostbyname +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + for ac_func in strftime @@ -16522,6 +16892,7 @@ fi + for ac_func in \ @@ -16579,6 +16950,7 @@ for ac_func in \ nsleep \ ogetaddrinfo \ openlog_r \ + pledge \ poll \ prctl \ pstat \ @@ -20707,12 +21079,12 @@ 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 - { { echo "$as_me:$LINENO: error: cannot use --with-ssl-engine when OpenSSL disabled" >&5 + if test "x$withval" != "xno" ; then + if test "x$openssl" = "xno" ; then + { { echo "$as_me:$LINENO: error: cannot use --with-ssl-engine when OpenSSL disabled" >&5 echo "$as_me: error: cannot use --with-ssl-engine when OpenSSL disabled" >&2;} { (exit 1); exit 1; }; } - fi - if test "x$withval" != "xno" ; then + fi openssl_engine=yes fi @@ -20999,6 +21371,7 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ + #include #include #include #include @@ -21015,7 +21388,8 @@ main () if(fd == NULL) exit(1); - if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) + if ((rc = fprintf(fd ,"%08lx (%s)\n", + (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) exit(1); exit(0); @@ -21184,6 +21558,7 @@ cat >>conftest.$ac_ext <<_ACEOF #include #include + #include int main () @@ -24145,7 +24520,19 @@ fi -if test "x$sandbox_arg" = "xsystrace" || \ +if test "x$sandbox_arg" = "xpledge" || \ + ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then + test "x$ac_cv_func_pledge" != "xyes" && \ + { { echo "$as_me:$LINENO: error: pledge sandbox requires pledge(2) support" >&5 +echo "$as_me: error: pledge sandbox requires pledge(2) support" >&2;} + { (exit 1); exit 1; }; } + SANDBOX_STYLE="pledge" + +cat >>confdefs.h <<\_ACEOF +#define SANDBOX_PLEDGE 1 +_ACEOF + +elif test "x$sandbox_arg" = "xsystrace" || \ ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then test "x$have_systr_policy_kill" != "x1" && \ { { echo "$as_me:$LINENO: error: systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" >&5 @@ -24238,6 +24625,14 @@ cat >>confdefs.h <<\_ACEOF #define SANDBOX_RLIMIT 1 _ACEOF +elif test "x$sandbox_arg" = "xsolaris" || \ + ( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then + SANDBOX_STYLE="solaris" + +cat >>confdefs.h <<\_ACEOF +#define SANDBOX_SOLARIS 1 +_ACEOF + elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then SANDBOX_STYLE="none" @@ -31719,6 +32114,9 @@ int main () { +struct __res_state *volatile p = &_res; /* force resolution of _res */ +return 0; + ; return 0; } @@ -36811,6 +37209,7 @@ echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" +echo " Solaris privilege support: $SPP_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" diff --git a/configure.ac b/configure.ac index 9b05c30f897a..7258cc0e5397 100644 --- a/configure.ac +++ b/configure.ac @@ -140,7 +140,7 @@ else fi AC_ARG_WITH([ssh1], - [ --without-ssh1 Enable support for SSH protocol 1], + [ --with-ssh1 Enable support for SSH protocol 1], [ if test "x$withval" = "xyes" ; then if test "x$openssl" = "xno" ; then @@ -469,6 +469,11 @@ AC_CHECK_HEADERS([sys/un.h], [], [], [ SIA_MSG="no" SPC_MSG="no" SP_MSG="no" +SPP_MSG="no" + +# Support for Solaris/Illumos privileges (this test is used by both +# the --with-solaris-privs option and --with-sandbox=solaris). +SOLARIS_PRIVS="no" # Check for some target-specific stuff case "$host" in @@ -575,6 +580,8 @@ case "$host" in LIBS="$LIBS /usr/lib/textreadmode.o" AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin]) AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()]) + AC_DEFINE([NO_UID_RESTORATION_TEST], [1], + [Define to disable UID restoration test]) AC_DEFINE([DISABLE_SHADOW], [1], [Define if you want to disable shadow passwords]) AC_DEFINE([NO_X11_UNIX_SOCKETS], [1], @@ -637,6 +644,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) supported by bsd-setproctitle.c]) AC_CHECK_FUNCS([sandbox_init]) AC_CHECK_HEADERS([sandbox.h]) + AC_CHECK_LIB([sandbox], [sandbox_apply], [ + SSHDLIBS="$SSHDLIBS -lsandbox" + ]) ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" @@ -889,13 +899,16 @@ mips-sony-bsd|mips-sony-newsos4) else AC_MSG_RESULT([no]) fi + AC_CHECK_FUNCS([setppriv]) + AC_CHECK_FUNCS([priv_basicset]) + AC_CHECK_HEADERS([priv.h]) AC_ARG_WITH([solaris-contracts], [ --with-solaris-contracts Enable Solaris process contracts (experimental)], [ AC_CHECK_LIB([contract], [ct_tmpl_activate], [ AC_DEFINE([USE_SOLARIS_PROCESS_CONTRACTS], [1], [Define if you have Solaris process contracts]) - SSHDLIBS="$SSHDLIBS -lcontract" + LIBS="$LIBS -lcontract" SPC_MSG="yes" ], ) ], ) @@ -905,10 +918,29 @@ mips-sony-bsd|mips-sony-newsos4) AC_CHECK_LIB([project], [setproject], [ AC_DEFINE([USE_SOLARIS_PROJECTS], [1], [Define if you have Solaris projects]) - SSHDLIBS="$SSHDLIBS -lproject" + LIBS="$LIBS -lproject" SP_MSG="yes" ], ) ], ) + AC_ARG_WITH([solaris-privs], + [ --with-solaris-privs Enable Solaris/Illumos privileges (experimental)], + [ + AC_MSG_CHECKING([for Solaris/Illumos privilege support]) + if test "x$ac_cv_func_setppriv" = "xyes" -a \ + "x$ac_cv_header_priv_h" = "xyes" ; then + SOLARIS_PRIVS=yes + AC_MSG_RESULT([found]) + AC_DEFINE([NO_UID_RESTORATION_TEST], [1], + [Define to disable UID restoration test]) + AC_DEFINE([USE_SOLARIS_PRIVS], [1], + [Define if you have Solaris privileges]) + SPP_MSG="yes" + else + AC_MSG_RESULT([not found]) + AC_MSG_ERROR([*** must have support for Solaris privileges to use --with-solaris-privs]) + fi + ], + ) TEST_SHELL=$SHELL # let configure find us a capable shell ;; *-*-sunos4*) @@ -1122,7 +1154,6 @@ AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ exit(0); ]])], dnl Checks for header files. # Checks for libraries. -AC_CHECK_FUNC([yp_match], , [AC_CHECK_LIB([nsl], [yp_match])]) AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])]) dnl IRIX and Solaris 2.5.1 have dirname() in libgen @@ -1286,8 +1317,10 @@ AC_SEARCH_LIBS([openpty], [util bsd]) AC_SEARCH_LIBS([updwtmp], [util bsd]) AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp]) -# On some platforms, inet_ntop may be found in libresolv or libnsl. +# On some platforms, inet_ntop and gethostbyname may be found in libresolv +# or libnsl. AC_SEARCH_LIBS([inet_ntop], [resolv nsl]) +AC_SEARCH_LIBS([gethostbyname], [resolv nsl]) AC_FUNC_STRFTIME @@ -1669,6 +1702,7 @@ AC_CHECK_FUNCS([ \ nsleep \ ogetaddrinfo \ openlog_r \ + pledge \ poll \ prctl \ pstat \ @@ -2309,10 +2343,10 @@ openssl_engine=no AC_ARG_WITH([ssl-engine], [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], [ - if test "x$openssl" = "xno" ; then - AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled]) - fi if test "x$withval" != "xno" ; then + if test "x$openssl" = "xno" ; then + AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled]) + fi openssl_engine=yes fi ] @@ -2345,6 +2379,7 @@ if test "x$openssl" = "xyes" ; then AC_MSG_CHECKING([OpenSSL header version]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ + #include #include #include #include @@ -2357,7 +2392,8 @@ if test "x$openssl" = "xyes" ; then if(fd == NULL) exit(1); - if ((rc = fprintf(fd ,"%08x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) + if ((rc = fprintf(fd ,"%08lx (%s)\n", + (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) exit(1); exit(0); @@ -2424,6 +2460,7 @@ if test "x$openssl" = "xyes" ; then [AC_LANG_PROGRAM([[ #include #include + #include ]], [[ exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); ]])], @@ -2998,7 +3035,7 @@ fi # Decide which sandbox style to use sandbox_arg="" AC_ARG_WITH([sandbox], - [ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter, capsicum)], + [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)], [ if test "x$withval" = "xyes" ; then sandbox_arg="" @@ -3094,7 +3131,13 @@ AC_RUN_IFELSE( [AC_MSG_WARN([cross compiling: assuming yes])] ) -if test "x$sandbox_arg" = "xsystrace" || \ +if test "x$sandbox_arg" = "xpledge" || \ + ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then + test "x$ac_cv_func_pledge" != "xyes" && \ + AC_MSG_ERROR([pledge sandbox requires pledge(2) support]) + SANDBOX_STYLE="pledge" + AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)]) +elif test "x$sandbox_arg" = "xsystrace" || \ ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then test "x$have_systr_policy_kill" != "x1" && \ AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support]) @@ -3147,6 +3190,10 @@ elif test "x$sandbox_arg" = "xrlimit" || \ AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit]) SANDBOX_STYLE="rlimit" AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)]) +elif test "x$sandbox_arg" = "xsolaris" || \ + ( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then + SANDBOX_STYLE="solaris" + AC_DEFINE([SANDBOX_SOLARIS], [1], [Sandbox using Solaris/Illumos privileges]) elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then SANDBOX_STYLE="none" @@ -3970,7 +4017,10 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include extern struct __res_state _res; - ]], [[ ]])], + ]], [[ +struct __res_state *volatile p = &_res; /* force resolution of _res */ +return 0; + ]],)], [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE__RES_EXTERN], [1], [Define if you have struct __res_state _res as an extern]) @@ -4933,6 +4983,7 @@ echo " MD5 password support: $MD5_MSG" echo " libedit support: $LIBEDIT_MSG" echo " Solaris process contract support: $SPC_MSG" echo " Solaris project support: $SP_MSG" +echo " Solaris privilege support: $SPP_MSG" echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG" echo " BSD Auth support: $BSD_AUTH_MSG" diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 4c55227e5e9e..2a55f454e26b 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 7.1p2 +%define ver 7.2p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID @@ -89,7 +89,7 @@ Requires: initscripts >= 5.20 BuildRequires: perl, openssl-devel BuildRequires: /bin/login %if ! %{build6x} -BuildPreReq: glibc-devel, pam +BuildRequires: glibc-devel, pam %else BuildRequires: /usr/include/security/pam_appl.h %endif @@ -184,7 +184,7 @@ CFLAGS="$RPM_OPT_FLAGS -Os"; export CFLAGS %endif %if %{kerberos5} -K5DIR=`rpm -ql krb5-devel | grep include/krb5.h | sed 's,\/include\/krb5.h,,'` +K5DIR=`rpm -ql krb5-devel | grep 'include/krb5\.h' | sed 's,\/include\/krb5.h,,'` echo K5DIR=$K5DIR %endif @@ -192,7 +192,6 @@ echo K5DIR=$K5DIR --sysconfdir=%{_sysconfdir}/ssh \ --libexecdir=%{_libexecdir}/openssh \ --datadir=%{_datadir}/openssh \ - --with-rsh=%{_bindir}/rsh \ --with-default-path=/usr/local/bin:/bin:/usr/bin \ --with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \ --with-privsep-path=%{_var}/empty/sshd \ diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id index ae88e9958d69..afde8b1703c9 100644 --- a/contrib/ssh-copy-id +++ b/contrib/ssh-copy-id @@ -56,10 +56,13 @@ then fi fi -DEFAULT_PUB_ID_FILE=$(ls -t ${HOME}/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) +DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)" usage () { - printf 'Usage: %s [-h|-?|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 + printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o ] ...] [user@]hostname\n' "$0" >&2 + printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2 + printf '\t-n: dry run -- no keys are actually copied\n' >&2 + printf '\t-h|-?: print this help\n' >&2 exit 1 } @@ -77,15 +80,18 @@ use_id_file() { PUB_ID_FILE="$L_ID_FILE.pub" fi - PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) + [ "$FORCED" ] || PRIV_ID_FILE=$(dirname "$PUB_ID_FILE")/$(basename "$PUB_ID_FILE" .pub) # check that the files are readable - for f in $PUB_ID_FILE $PRIV_ID_FILE ; do - ErrMSG=$( { : < $f ; } 2>&1 ) || { - printf "\n%s: ERROR: failed to open ID file '%s': %s\n\n" "$0" "$f" "$(printf "%s\n" "$ErrMSG" | sed -e 's/.*: *//')" + for f in "$PUB_ID_FILE" ${PRIV_ID_FILE:+"$PRIV_ID_FILE"} ; do + ErrMSG=$( { : < "$f" ; } 2>&1 ) || { + local L_PRIVMSG="" + [ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)" + printf "\n%s: ERROR: failed to open ID file '%s': %s\n" "$0" "$f" "$(printf "%s\n%s\n" "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')" exit 1 } done + printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2 GET_ID="cat \"$PUB_ID_FILE\"" } @@ -121,7 +127,7 @@ do } shift ;; - -n|-h|-\?) + -f|-n|-h|-\?) OPT="$1" OPTARG= shift @@ -154,6 +160,9 @@ do -o|-p) SSH_OPTS="${SSH_OPTS:+$SSH_OPTS }$OPT '$(quote "$OPTARG")'" ;; + -f) + FORCED=1 + ;; -n) DRY_RUN=1 ;; @@ -194,27 +203,35 @@ fi populate_new_ids() { local L_SUCCESS="$1" + if [ "$FORCED" ] ; then + NEW_IDS=$(eval $GET_ID) + return + fi + # repopulate "$@" inside this function eval set -- "$SSH_OPTS" umask 0177 local L_TMP_ID_FILE=$(mktemp ~/.ssh/ssh-copy-id_id.XXXXXXXXXX) if test $? -ne 0 || test "x$L_TMP_ID_FILE" = "x" ; then - echo "mktemp failed" 1>&2 + printf '%s: ERROR: mktemp failed\n' "$0" >&2 exit 1 fi - trap "rm -f $L_TMP_ID_FILE ${L_TMP_ID_FILE}.pub" EXIT TERM INT QUIT + local L_CLEANUP="rm -f \"$L_TMP_ID_FILE\" \"${L_TMP_ID_FILE}.stderr\"" + trap "$L_CLEANUP" EXIT TERM INT QUIT printf '%s: INFO: attempting to log in with the new key(s), to filter out any that are already installed\n' "$0" >&2 NEW_IDS=$( eval $GET_ID | { - while read ID ; do - printf '%s\n' "$ID" > $L_TMP_ID_FILE + while read ID || [ "$ID" ] ; do + printf '%s\n' "$ID" > "$L_TMP_ID_FILE" # the next line assumes $PRIV_ID_FILE only set if using a single id file - this # assumption will break if we implement the possibility of multiple -i options. # The point being that if file based, ssh needs the private key, which it cannot # find if only given the contents of the .pub file in an unrelated tmpfile ssh -i "${PRIV_ID_FILE:-$L_TMP_ID_FILE}" \ + -o ControlPath=none \ + -o LogLevel=INFO \ -o PreferredAuthentications=publickey \ -o IdentitiesOnly=yes "$@" exit 2>$L_TMP_ID_FILE.stderr /dev/null ; then printf '\n%s: %s\n\n' "$0" "$NEW_IDS" >&2 exit 1 fi if [ -z "$NEW_IDS" ] ; then - printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n\n' "$0" >&2 + printf '\n%s: WARNING: All keys were skipped because they already exist on the remote system.\n' "$0" >&2 + printf '\t\t(if you think this is a mistake, you may want to use -f option)\n\n' "$0" >&2 exit 0 fi printf '%s: INFO: %d key(s) remain to be installed -- if you are prompted now it is to install the new keys\n' "$0" "$(printf '%s\n' "$NEW_IDS" | wc -l)" >&2 } -REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' "$@" 2>&1 | +REMOTE_VERSION=$(ssh -v -o PreferredAuthentications=',' -o ControlPath=none "$@" 2>&1 | sed -ne 's/.*remote software version //p') case "$REMOTE_VERSION" in @@ -269,10 +287,9 @@ case "$REMOTE_VERSION" in *) # Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect populate_new_ids 0 - [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | ssh "$@" " - umask 077 ; - mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; - if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi" \ + # in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh. + [ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \ + ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \ || exit 1 ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l) ;; diff --git a/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1 index 67a59e492a92..8850cceda0a9 100644 --- a/contrib/ssh-copy-id.1 +++ b/contrib/ssh-copy-id.1 @@ -29,6 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .Nd use locally available keys to authorise logins on a remote machine .Sh SYNOPSIS .Nm +.Op Fl f .Op Fl n .Op Fl i Op Ar identity_file .Op Fl p Ar port @@ -76,6 +77,10 @@ is used. Note that this can be used to ensure that the keys copied have the comment one prefers and/or extra options applied, by ensuring that the key file has these set as preferred before the copy is attempted. +.It Fl f +Forced mode: doesn't check if the keys are present on the remote server. +This means that it does not need the private key. Of course, this can result +in more than one copy of the key being installed on the remote system. .It Fl n do a dry-run. Instead of installing keys on the remote system simply prints the key(s) that would have been installed. diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 3ee526805d83..53264c1fbc6d 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 7.1p2 +Version: 7.2p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/defines.h b/defines.h index fa0ccba7c018..a438ddd742f7 100644 --- a/defines.h +++ b/defines.h @@ -850,4 +850,11 @@ struct winsize { # endif /* gcc version */ #endif /* __predict_true */ +#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ + defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \ + defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \ + !defined(BROKEN_GLOB) +# define USE_SYSTEM_GLOB +#endif + #endif /* _DEFINES_H */ diff --git a/dh.h b/dh.h index 654695315e0f..e191cfd8a25e 100644 --- a/dh.h +++ b/dh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.h,v 1.13 2015/05/27 23:39:18 dtucker Exp $ */ +/* $OpenBSD: dh.h,v 1.14 2015/10/16 22:32:22 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. @@ -44,8 +44,11 @@ int dh_pub_is_valid(DH *, BIGNUM *); u_int dh_estimate(int); -/* Min and max values from RFC4419. */ -#define DH_GRP_MIN 1024 +/* + * Max value from RFC4419. + * Miniumum increased in light of DH precomputation attacks. + */ +#define DH_GRP_MIN 2048 #define DH_GRP_MAX 8192 /* diff --git a/includes.h b/includes.h index 2893a54cdc6b..497a038b2373 100644 --- a/includes.h +++ b/includes.h @@ -32,12 +32,6 @@ #ifdef HAVE_BSTRING_H # include #endif -#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ - defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \ - defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \ - !defined(BROKEN_GLOB) -# include -#endif #ifdef HAVE_ENDIAN_H # include #endif diff --git a/kex.c b/kex.c index b777b7d50f80..d371f47c48dd 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.109 2015/07/30 00:01:34 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.117 2016/02/08 10:57:07 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -49,7 +49,6 @@ #include "misc.h" #include "dispatch.h" #include "monitor.h" -#include "roaming.h" #include "ssherr.h" #include "sshbuf.h" @@ -67,6 +66,19 @@ extern const EVP_MD *evp_ssh_sha256(void); static int kex_choose_conf(struct ssh *); static int kex_input_newkeys(int, u_int32_t, void *); +static const char *proposal_names[PROPOSAL_MAX] = { + "KEX algorithms", + "host key algorithms", + "ciphers ctos", + "ciphers stoc", + "MACs ctos", + "MACs stoc", + "compression ctos", + "compression stoc", + "languages ctos", + "languages stoc", +}; + struct kexalg { char *name; u_int type; @@ -267,7 +279,7 @@ kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp) for (i = 0; i < PROPOSAL_MAX; i++) { if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0) goto out; - debug2("kex_parse_kexinit: %s", proposal[i]); + debug2("%s: %s", proposal_names[i], proposal[i]); } /* first kex follows / reserved */ if ((r = sshbuf_get_u8(b, &v)) != 0 || /* first_kex_follows */ @@ -302,7 +314,14 @@ kex_prop_free(char **proposal) static int kex_protocol_error(int type, u_int32_t seq, void *ctxt) { - error("Hm, kex protocol error: type %d seq %u", type, seq); + struct ssh *ssh = active_state; /* XXX */ + int r; + + error("kex protocol error: type %d seq %u", type, seq); + if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 || + (r = sshpkt_put_u32(ssh, seq)) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; return 0; } @@ -314,6 +333,20 @@ kex_reset_dispatch(struct ssh *ssh) ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); } +static int +kex_send_ext_info(struct ssh *ssh) +{ + int r; + + if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || + (r = sshpkt_put_u32(ssh, 1)) != 0 || + (r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || + (r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 || + (r = sshpkt_send(ssh)) != 0) + return r; + return 0; +} + int kex_send_newkeys(struct ssh *ssh) { @@ -326,9 +359,51 @@ kex_send_newkeys(struct ssh *ssh) debug("SSH2_MSG_NEWKEYS sent"); debug("expecting SSH2_MSG_NEWKEYS"); ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); + if (ssh->kex->ext_info_c) + if ((r = kex_send_ext_info(ssh)) != 0) + return r; return 0; } +int +kex_input_ext_info(int type, u_int32_t seq, void *ctxt) +{ + struct ssh *ssh = ctxt; + struct kex *kex = ssh->kex; + u_int32_t i, ninfo; + char *name, *val, *found; + int r; + + debug("SSH2_MSG_EXT_INFO received"); + ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error); + if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0) + return r; + for (i = 0; i < ninfo; i++) { + if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) + return r; + if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) { + free(name); + return r; + } + debug("%s: %s=<%s>", __func__, name, val); + if (strcmp(name, "server-sig-algs") == 0) { + found = match_list("rsa-sha2-256", val, NULL); + if (found) { + kex->rsa_sha2 = 256; + free(found); + } + found = match_list("rsa-sha2-512", val, NULL); + if (found) { + kex->rsa_sha2 = 512; + free(found); + } + } + free(name); + free(val); + } + return sshpkt_get_end(ssh); +} + static int kex_input_newkeys(int type, u_int32_t seq, void *ctxt) { @@ -468,7 +543,7 @@ kex_free_newkeys(struct newkeys *newkeys) newkeys->enc.key = NULL; } if (newkeys->enc.iv) { - explicit_bzero(newkeys->enc.iv, newkeys->enc.block_size); + explicit_bzero(newkeys->enc.iv, newkeys->enc.iv_len); free(newkeys->enc.iv); newkeys->enc.iv = NULL; } @@ -511,6 +586,8 @@ kex_free(struct kex *kex) free(kex->client_version_string); free(kex->server_version_string); free(kex->failed_choice); + free(kex->hostkey_alg); + free(kex->name); free(kex); } @@ -529,6 +606,25 @@ kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) return 0; } +/* + * Request key re-exchange, returns 0 on success or a ssherr.h error + * code otherwise. Must not be called if KEX is incomplete or in-progress. + */ +int +kex_start_rekex(struct ssh *ssh) +{ + if (ssh->kex == NULL) { + error("%s: no kex", __func__); + return SSH_ERR_INTERNAL_ERROR; + } + if (ssh->kex->done == 0) { + error("%s: requested twice", __func__); + return SSH_ERR_INTERNAL_ERROR; + } + ssh->kex->done = 0; + return kex_send_kexinit(ssh); +} + static int choose_enc(struct sshenc *enc, char *client, char *server) { @@ -593,6 +689,7 @@ choose_kex(struct kex *k, char *client, char *server) k->name = match_list(client, server, NULL); + debug("kex: algorithm: %s", k->name ? k->name : "(no match)"); if (k->name == NULL) return SSH_ERR_NO_KEX_ALG_MATCH; if ((kexalg = kex_alg_by_name(k->name)) == NULL) @@ -606,15 +703,16 @@ choose_kex(struct kex *k, char *client, char *server) static int choose_hostkeyalg(struct kex *k, char *client, char *server) { - char *hostkeyalg = match_list(client, server, NULL); + k->hostkey_alg = match_list(client, server, NULL); - if (hostkeyalg == NULL) + debug("kex: host key algorithm: %s", + k->hostkey_alg ? k->hostkey_alg : "(no match)"); + if (k->hostkey_alg == NULL) return SSH_ERR_NO_HOSTKEY_ALG_MATCH; - k->hostkey_type = sshkey_type_from_name(hostkeyalg); + k->hostkey_type = sshkey_type_from_name(k->hostkey_alg); if (k->hostkey_type == KEY_UNSPEC) return SSH_ERR_INTERNAL_ERROR; - k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg); - free(hostkeyalg); + k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg); return 0; } @@ -653,8 +751,11 @@ kex_choose_conf(struct ssh *ssh) u_int mode, ctos, need, dh_need, authlen; int r, first_kex_follows; - if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0 || - (r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) + debug2("local %s KEXINIT proposal", kex->server ? "server" : "client"); + if ((r = kex_buf2prop(kex->my, NULL, &my)) != 0) + goto out; + debug2("peer %s KEXINIT proposal", kex->server ? "client" : "server"); + if ((r = kex_buf2prop(kex->peer, &first_kex_follows, &peer)) != 0) goto out; if (kex->server) { @@ -665,18 +766,30 @@ kex_choose_conf(struct ssh *ssh) sprop=peer; } - /* Check whether server offers roaming */ - if (!kex->server) { - char *roaming = match_list(KEX_RESUME, - peer[PROPOSAL_KEX_ALGS], NULL); + /* Check whether client supports ext_info_c */ + if (kex->server) { + char *ext; - if (roaming) { - kex->roaming = 1; - free(roaming); + ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL); + if (ext) { + kex->ext_info_c = 1; + free(ext); } } /* Algorithm Negotiation */ + if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], + sprop[PROPOSAL_KEX_ALGS])) != 0) { + kex->failed_choice = peer[PROPOSAL_KEX_ALGS]; + peer[PROPOSAL_KEX_ALGS] = NULL; + goto out; + } + if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) { + kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS]; + peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL; + goto out; + } for (mode = 0; mode < MODE_MAX; mode++) { if ((newkeys = calloc(1, sizeof(*newkeys))) == NULL) { r = SSH_ERR_ALLOC_FAIL; @@ -709,24 +822,12 @@ kex_choose_conf(struct ssh *ssh) peer[ncomp] = NULL; goto out; } - debug("kex: %s %s %s %s", + debug("kex: %s cipher: %s MAC: %s compression: %s", ctos ? "client->server" : "server->client", newkeys->enc.name, authlen == 0 ? newkeys->mac.name : "", newkeys->comp.name); } - if ((r = choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], - sprop[PROPOSAL_KEX_ALGS])) != 0) { - kex->failed_choice = peer[PROPOSAL_KEX_ALGS]; - peer[PROPOSAL_KEX_ALGS] = NULL; - goto out; - } - if ((r = choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], - sprop[PROPOSAL_SERVER_HOST_KEY_ALGS])) != 0) { - kex->failed_choice = peer[PROPOSAL_SERVER_HOST_KEY_ALGS]; - peer[PROPOSAL_SERVER_HOST_KEY_ALGS] = NULL; - goto out; - } need = dh_need = 0; for (mode = 0; mode < MODE_MAX; mode++) { newkeys = kex->newkeys[mode]; @@ -812,8 +913,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen, digest = NULL; r = 0; out: - if (digest) - free(digest); + free(digest); ssh_digest_free(hashctx); return r; } diff --git a/kex.h b/kex.h index d71b53293d8d..1c5896605059 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.73 2015/07/30 00:01:34 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.76 2016/02/08 10:57:07 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -54,7 +54,6 @@ #define KEX_DH14 "diffie-hellman-group14-sha1" #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" -#define KEX_RESUME "resume@appgate.com" #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" @@ -129,10 +128,12 @@ struct kex { u_int dh_need; int server; char *name; + char *hostkey_alg; int hostkey_type; int hostkey_nid; u_int kex_type; - int roaming; + int rsa_sha2; + int ext_info_c; struct sshbuf *my; struct sshbuf *peer; sig_atomic_t done; @@ -146,8 +147,8 @@ struct kex { 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 (*sign)(struct sshkey *, struct sshkey *, u_char **, size_t *, + const u_char *, size_t, const char *, u_int); int (*kex[KEX_MAX])(struct ssh *); /* kex specific state */ DH *dh; /* DH */ @@ -174,9 +175,11 @@ void kex_prop_free(char **); int kex_send_kexinit(struct ssh *); int kex_input_kexinit(int, u_int32_t, void *); +int kex_input_ext_info(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 *); +int kex_start_rekex(struct ssh *); int kexdh_client(struct ssh *); int kexdh_server(struct ssh *); diff --git a/kexc25519s.c b/kexc25519s.c index 24027253363e..4e77622b0b2f 100644 --- a/kexc25519s.c +++ b/kexc25519s.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexc25519s.c,v 1.9 2015/04/27 00:37:53 dtucker Exp $ */ +/* $OpenBSD: kexc25519s.c,v 1.10 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -134,8 +134,8 @@ input_kex_c25519_init(int type, u_int32_t seq, void *ctxt) } /* sign H */ - if ((r = kex->sign(server_host_private, server_host_public, - &signature, &slen, hash, hashlen, ssh->compat)) < 0) + if ((r = kex->sign(server_host_private, server_host_public, &signature, + &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ diff --git a/kexdhs.c b/kexdhs.c index de7c05b17249..bf933e4c9013 100644 --- a/kexdhs.c +++ b/kexdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhs.c,v 1.22 2015/01/26 06:10:03 djm Exp $ */ +/* $OpenBSD: kexdhs.c,v 1.23 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -181,8 +181,8 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt) } /* sign H */ - if ((r = kex->sign(server_host_private, server_host_public, - &signature, &slen, hash, hashlen, ssh->compat)) < 0) + if ((r = kex->sign(server_host_private, server_host_public, &signature, + &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ diff --git a/kexecdhs.c b/kexecdhs.c index 0adb80e6addf..ccdbf70b1cf6 100644 --- a/kexecdhs.c +++ b/kexecdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdhs.c,v 1.14 2015/01/26 06:10:03 djm Exp $ */ +/* $OpenBSD: kexecdhs.c,v 1.15 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -169,8 +169,8 @@ input_kex_ecdh_init(int type, u_int32_t seq, void *ctxt) } /* sign H */ - if ((r = kex->sign(server_host_private, server_host_public, - &signature, &slen, hash, hashlen, ssh->compat)) < 0) + if ((r = kex->sign(server_host_private, server_host_public, &signature, + &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ diff --git a/kexgexs.c b/kexgexs.c index ff6c6879e73a..8c5adf7e4305 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.25 2015/04/13 02:04:08 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.26 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -220,8 +220,8 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) } /* sign H */ - if ((r = kex->sign(server_host_private, server_host_public, - &signature, &slen, hash, hashlen, ssh->compat)) < 0) + if ((r = kex->sign(server_host_private, server_host_public, &signature, + &slen, hash, hashlen, kex->hostkey_alg, ssh->compat)) < 0) goto out; /* destroy_sensitive_data(); */ diff --git a/key.c b/key.c index 0ba98b6f35bd..28d7c6207145 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.128 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: key.c,v 1.129 2015/12/04 16:41:28 markus Exp $ */ /* * placed in the public domain */ @@ -132,7 +132,7 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) int key_sign(const Key *key, u_char **sigp, u_int *lenp, - const u_char *data, u_int datalen) + const u_char *data, u_int datalen, const char *alg) { int r; u_char *sig; @@ -143,7 +143,7 @@ key_sign(const Key *key, u_char **sigp, u_int *lenp, if (lenp != NULL) *lenp = 0; if ((r = sshkey_sign(key, &sig, &siglen, - data, datalen, datafellows)) != 0) { + data, datalen, alg, datafellows)) != 0) { fatal_on_fatal_errors(r, __func__, 0); error("%s: %s", __func__, ssh_err(r)); return -1; diff --git a/key.h b/key.h index 903bdf6730de..34c992bd300b 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.48 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: key.h,v 1.49 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -84,7 +84,8 @@ int key_ec_validate_private(const EC_KEY *); Key *key_from_blob(const u_char *, u_int); int key_to_blob(const Key *, u_char **, u_int *); -int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int, + const char *); int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); void key_private_serialize(const Key *, struct sshbuf *); diff --git a/krl.c b/krl.c index 4075df853fff..fff1a3f7cbaf 100644 --- a/krl.c +++ b/krl.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.c,v 1.33 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: krl.c,v 1.37 2015/12/31 00:33:52 djm Exp $ */ #include "includes.h" @@ -723,7 +723,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, 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->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) @@ -772,7 +772,7 @@ ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf, goto out; if ((r = sshkey_sign(sign_keys[i], &sblob, &slen, - sshbuf_ptr(buf), sshbuf_len(buf), 0)) != 0) + sshbuf_ptr(buf), sshbuf_len(buf), NULL, 0)) != 0) goto out; KRL_DBG(("%s: signature sig len %zu", __func__, slen)); if ((r = sshbuf_put_string(buf, sblob, slen)) != 0) @@ -826,10 +826,8 @@ parse_revoked_certs(struct sshbuf *buf, struct ssh_krl *krl) goto out; while (sshbuf_len(buf) > 0) { - if (subsect != NULL) { - sshbuf_free(subsect); - subsect = NULL; - } + sshbuf_free(subsect); + subsect = NULL; if ((r = sshbuf_get_u8(buf, &type)) != 0 || (r = sshbuf_froms(buf, &subsect)) != 0) goto out; @@ -1017,7 +1015,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, } /* Check signature over entire KRL up to this point */ if ((r = sshkey_verify(key, blob, blen, - sshbuf_ptr(buf), sshbuf_len(buf) - sig_off, 0)) != 0) + sshbuf_ptr(buf), sig_off, 0)) != 0) goto out; /* Check if this key has already signed this KRL */ for (i = 0; i < nca_used; i++) { @@ -1038,7 +1036,6 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, ca_used = tmp_ca_used; ca_used[nca_used++] = key; key = NULL; - break; } if (sshbuf_len(copy) != 0) { @@ -1059,10 +1056,8 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, if ((r = sshbuf_consume(copy, sects_off)) != 0) goto out; while (sshbuf_len(copy) > 0) { - if (sect != NULL) { - sshbuf_free(sect); - sect = NULL; - } + sshbuf_free(sect); + sect = NULL; if ((r = sshbuf_get_u8(copy, &type)) != 0 || (r = sshbuf_froms(copy, §)) != 0) goto out; @@ -1105,7 +1100,7 @@ ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp, r = SSH_ERR_INVALID_FORMAT; goto out; } - if (sshbuf_len(sect) > 0) { + if (sect != NULL && sshbuf_len(sect) > 0) { error("KRL section contains unparsed data"); r = SSH_ERR_INVALID_FORMAT; goto out; diff --git a/krl.h b/krl.h index 4e12befc3c13..675496cc48a2 100644 --- a/krl.h +++ b/krl.h @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $OpenBSD: krl.h,v 1.4 2015/01/13 19:06:49 djm Exp $ */ +/* $OpenBSD: krl.h,v 1.5 2015/12/30 23:46:14 djm Exp $ */ #ifndef _KRL_H #define _KRL_H @@ -43,7 +43,6 @@ 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 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); diff --git a/loginrec.c b/loginrec.c index 94ae81dc6088..788553e9204d 100644 --- a/loginrec.c +++ b/loginrec.c @@ -150,6 +150,9 @@ #include #include #include +#ifdef HAVE_SYS_TIME_H +# include +#endif #include diff --git a/misc.c b/misc.c index ddd2b2db452f..de7e1facd68b 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.97 2015/04/24 01:36:00 deraadt Exp $ */ +/* $OpenBSD: misc.c,v 1.101 2016/01/20 09:22:39 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -604,6 +605,8 @@ percent_expand(const char *string, ...) /* %% case */ if (*string == '%') goto append; + if (*string == '\0') + fatal("%s: invalid format", __func__); for (j = 0; j < num_keys; j++) { if (strchr(keys[j].key, *string) != NULL) { i = strlcat(buf, keys[j].repl, sizeof(buf)); @@ -653,62 +656,63 @@ tun_open(int tun, int mode) struct ifreq ifr; char name[100]; int fd = -1, sock; + const char *tunbase = "tun"; + + if (mode == SSH_TUNMODE_ETHERNET) + tunbase = "tap"; /* Open the tunnel device */ if (tun <= SSH_TUNID_MAX) { - snprintf(name, sizeof(name), "/dev/tun%d", tun); + snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); fd = open(name, O_RDWR); } else if (tun == SSH_TUNID_ANY) { for (tun = 100; tun >= 0; tun--) { - snprintf(name, sizeof(name), "/dev/tun%d", tun); + snprintf(name, sizeof(name), "/dev/%s%d", + tunbase, tun); if ((fd = open(name, O_RDWR)) >= 0) break; } } else { debug("%s: invalid tunnel %u", __func__, tun); - return (-1); + return -1; } if (fd < 0) { - debug("%s: %s open failed: %s", __func__, name, strerror(errno)); - return (-1); + debug("%s: %s open: %s", __func__, name, strerror(errno)); + return -1; } debug("%s: %s mode %d fd %d", __func__, name, mode, fd); - /* Set the tunnel device operation mode */ - snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); + /* Bring interface up if it is not already */ + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) goto failed; - if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { + debug("%s: get interface %s flags: %s", __func__, + ifr.ifr_name, strerror(errno)); goto failed; + } - /* Set interface mode */ - ifr.ifr_flags &= ~IFF_UP; - if (mode == SSH_TUNMODE_ETHERNET) - ifr.ifr_flags |= IFF_LINK0; - else - ifr.ifr_flags &= ~IFF_LINK0; - if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) - goto failed; - - /* Bring interface up */ - ifr.ifr_flags |= IFF_UP; - if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) - goto failed; + if (!(ifr.ifr_flags & IFF_UP)) { + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { + debug("%s: activate interface %s: %s", __func__, + ifr.ifr_name, strerror(errno)); + goto failed; + } + } close(sock); - return (fd); + return fd; failed: if (fd >= 0) close(fd); if (sock >= 0) close(sock); - debug("%s: failed to set %s mode %d: %s", __func__, name, - mode, strerror(errno)); - return (-1); + return -1; #else error("Tunnel interfaces are not supported on this platform"); return (-1); @@ -1107,7 +1111,7 @@ unix_listener(const char *path, int backlog, int unlink_first) void sock_set_v6only(int s) { -#ifdef IPV6_V6ONLY +#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) int on = 1; debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); diff --git a/moduli.0 b/moduli.0 index 087e5963e4de..a74279b21d5d 100644 --- a/moduli.0 +++ b/moduli.0 @@ -71,4 +71,4 @@ STANDARDS the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006, 2006. -OpenBSD 5.8 September 26, 2012 OpenBSD 5.8 +OpenBSD 5.9 September 26, 2012 OpenBSD 5.9 diff --git a/monitor.c b/monitor.c index a91420983ba8..ac7dd309974c 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.150 2015/06/22 23:42:16 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.157 2016/02/15 23:32:37 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -100,7 +100,6 @@ #include "monitor_fdpass.h" #include "compat.h" #include "ssh2.h" -#include "roaming.h" #include "authfd.h" #include "match.h" #include "ssherr.h" @@ -487,15 +486,10 @@ monitor_sync(struct monitor *pmonitor) 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) + if (size == 0 || ncount == 0 || ncount > SIZE_MAX / size) fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); - address = mm_malloc(mm, len); - - return (address); + return mm_malloc(mm, size * ncount); } static void @@ -690,17 +684,18 @@ mm_answer_sign(int sock, Buffer *m) 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; - size_t datlen, siglen; + struct sshbuf *sigbuf = NULL; + u_char *p = NULL, *signature = NULL; + char *alg = NULL; + size_t datlen, siglen, alglen; int r, keyid, is_proof = 0; const char proof_req[] = "hostkeys-prove-00@openssh.com"; debug3("%s", __func__); if ((r = sshbuf_get_u32(m, &keyid)) != 0 || - (r = sshbuf_get_string(m, &p, &datlen)) != 0) + (r = sshbuf_get_string(m, &p, &datlen)) != 0 || + (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* @@ -727,7 +722,7 @@ mm_answer_sign(int sock, Buffer *m) 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) || + session_id2_len)) != 0 || (r = sshkey_puts(key, sigbuf)) != 0) fatal("%s: couldn't prepare private key " "proof buffer: %s", __func__, ssh_err(r)); @@ -747,14 +742,14 @@ mm_answer_sign(int sock, Buffer *m) } if ((key = get_hostkey_by_index(keyid)) != NULL) { - if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, + if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, 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) { + p, datlen, alg, datafellows)) != 0) { fatal("%s: ssh_agent_sign failed: %s", __func__, ssh_err(r)); } @@ -768,6 +763,7 @@ mm_answer_sign(int sock, Buffer *m) if ((r = sshbuf_put_string(m, signature, siglen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); + free(alg); free(p); free(signature); @@ -971,7 +967,7 @@ mm_answer_bsdauthrespond(int sock, Buffer *m) char *response; int authok; - if (authctxt->as == 0) + if (authctxt->as == NULL) fatal("%s: no bsd auth session", __func__); response = buffer_get_string(m, NULL); @@ -1040,7 +1036,8 @@ mm_answer_skeyrespond(int sock, Buffer *m) debug3("%s: sending authenticated: %d", __func__, authok); mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); - auth_method = "skey"; + auth_method = "keyboard-interactive"; + auth_submethod = "skey"; return (authok != 0); } @@ -1449,7 +1446,7 @@ mm_answer_keyverify(int sock, Buffer *m) __func__, key, (verified == 1) ? "verified" : "unverified"); /* If auth was successful then record key to ensure it isn't reused */ - if (verified == 1) + if (verified == 1 && key_blobtype == MM_USERKEY) auth2_record_userkey(authctxt, key); else key_free(key); @@ -1852,7 +1849,7 @@ monitor_apply_keystate(struct monitor *pmonitor) sshbuf_free(child_state); child_state = NULL; - if ((kex = ssh->kex) != 0) { + if ((kex = ssh->kex) != NULL) { /* XXX set callbacks */ #ifdef WITH_OPENSSL kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; diff --git a/monitor_wrap.c b/monitor_wrap.c index eac421ba145b..c5db6df483b7 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.85 2015/05/01 03:23:51 djm Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.87 2016/01/14 16:17:40 markus Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -80,7 +80,6 @@ #include "channels.h" #include "session.h" #include "servconf.h" -#include "roaming.h" #include "ssherr.h" @@ -218,7 +217,7 @@ mm_choose_dh(int min, int nbits, int max) int mm_key_sign(Key *key, u_char **sigp, u_int *lenp, - const u_char *data, u_int datalen) + const u_char *data, u_int datalen, const char *hostkey_alg) { struct kex *kex = *pmonitor->m_pkex; Buffer m; @@ -228,6 +227,7 @@ mm_key_sign(Key *key, u_char **sigp, u_int *lenp, buffer_init(&m); buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); buffer_put_string(&m, data, datalen); + buffer_put_cstring(&m, hostkey_alg); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); diff --git a/monitor_wrap.h b/monitor_wrap.h index de4a08f99ff3..eb820aeea743 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.27 2015/05/01 03:23:51 djm Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.29 2015/12/04 16:41:28 markus 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 *, const u_char *, u_int); +int mm_key_sign(Key *, u_char **, u_int *, const u_char *, u_int, const char *); void mm_inform_authserv(char *, char *); struct passwd *mm_getpwnamallow(const char *); char *mm_auth2_read_banner(void); diff --git a/mux.c b/mux.c index e6136fd28c28..6bf53ebd9a32 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.54 2015/08/19 23:18:26 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.58 2016/01/13 23:04:47 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -1354,16 +1354,18 @@ mux_session_confirm(int id, int success, void *arg) char *proto, *data; /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, + if (client_x11_get_proto(display, options.xauth_location, options.forward_x11_trusted, options.forward_x11_timeout, - &proto, &data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication " - "spoofing."); - x11_request_forwarding_with_spoofing(id, display, proto, - data, 1); - client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN); - /* XXX exit_on_forward_failure */ + &proto, &data) == 0) { + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication " + "spoofing."); + x11_request_forwarding_with_spoofing(id, display, proto, + data, 1); + /* XXX exit_on_forward_failure */ + client_expect_confirm(id, "X11 forwarding", + CONFIRM_WARN); + } } if (cctx->want_agent_fwd && options.forward_agent) { @@ -1744,7 +1746,7 @@ mux_client_forward(int fd, int cancel_flag, u_int ftype, struct Forward *fwd) fwd->connect_host ? fwd->connect_host : "", fwd->connect_port); if (muxclient_command == SSHMUX_COMMAND_FORWARD) - fprintf(stdout, "%u\n", fwd->allocated_port); + fprintf(stdout, "%i\n", fwd->allocated_port); break; case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); @@ -1889,6 +1891,10 @@ mux_client_request_session(int fd) } muxclient_request_id++; + if (pledge("stdio proc tty", NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + platform_pledge_mux(); + signal(SIGHUP, control_client_sighandler); signal(SIGINT, control_client_sighandler); signal(SIGTERM, control_client_sighandler); @@ -1996,6 +2002,10 @@ mux_client_request_stdio_fwd(int fd) mm_send_fd(fd, STDOUT_FILENO) == -1) fatal("%s: send fds failed", __func__); + if (pledge("stdio proc tty", NULL) == -1) + fatal("%s pledge(): %s", __func__, strerror(errno)); + platform_pledge_mux(); + debug3("%s: stdio forward request sent", __func__); /* Read their reply */ @@ -2169,7 +2179,7 @@ muxclient(const char *path) case SSHMUX_COMMAND_ALIVE_CHECK: if ((pid = mux_client_request_alive(sock)) == 0) fatal("%s: master alive check failed", __func__); - fprintf(stderr, "Master running (pid=%d)\r\n", pid); + fprintf(stderr, "Master running (pid=%u)\r\n", pid); exit(0); case SSHMUX_COMMAND_TERMINATE: mux_client_request_terminate(sock); diff --git a/myproposal.h b/myproposal.h index 46e5b988d463..bdd05966f0ab 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.47 2015/07/10 06:21:53 markus Exp $ */ +/* $OpenBSD: myproposal.h,v 1.50 2016/02/09 05:30:04 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -101,7 +101,9 @@ "ssh-rsa-cert-v01@openssh.com," \ HOSTKEY_ECDSA_METHODS \ "ssh-ed25519," \ - "ssh-rsa" \ + "rsa-sha2-512," \ + "rsa-sha2-256," \ + "ssh-rsa" /* the actual algorithms */ @@ -111,9 +113,7 @@ AESGCM_CIPHER_MODES #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \ - "arcfour256,arcfour128," \ - "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ - "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se" + "aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc" #define KEX_SERVER_MAC \ "umac-64-etm@openssh.com," \ @@ -127,18 +127,9 @@ "hmac-sha2-512," \ "hmac-sha1" -#define KEX_CLIENT_MAC KEX_SERVER_MAC "," \ - "hmac-md5-etm@openssh.com," \ - "hmac-ripemd160-etm@openssh.com," \ - "hmac-sha1-96-etm@openssh.com," \ - "hmac-md5-96-etm@openssh.com," \ - "hmac-md5," \ - "hmac-ripemd160," \ - "hmac-ripemd160@openssh.com," \ - "hmac-sha1-96," \ - "hmac-md5-96" +#define KEX_CLIENT_MAC KEX_SERVER_MAC -#else +#else /* WITH_OPENSSL */ #define KEX_SERVER_KEX \ "curve25519-sha256@libssh.org" diff --git a/opacket.c b/opacket.c index b9160d59def8..5970dd3771cc 100644 --- a/opacket.c +++ b/opacket.c @@ -235,18 +235,6 @@ packet_set_connection(int fd_in, int fd_out) 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) { diff --git a/opacket.h b/opacket.h index a0a60e5507e1..c26ade44c7f2 100644 --- a/opacket.h +++ b/opacket.h @@ -39,8 +39,6 @@ do { \ 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 *); @@ -127,8 +125,6 @@ void packet_disconnect(const char *, ...) 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() \ diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index f7be415ec226..2a788e47f7dd 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -276,3 +276,11 @@ getpgid(pid_t pid) return -1; } #endif + +#ifndef HAVE_PLEDGE +int +pledge(const char *promises, const char *paths[]) +{ + return 0; +} +#endif diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index ff347a24b0eb..0d81d17352ea 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -122,4 +122,8 @@ pid_t getpgid(pid_t); # define krb5_free_error_message(a,b) do { } while(0) #endif +#ifndef HAVE_PLEDGE +int pledge(const char *promises, const char *paths[]); +#endif + #endif /* _BSD_MISC_H */ diff --git a/openbsd-compat/bsd-poll.h b/openbsd-compat/bsd-poll.h index dcbb9ca40236..17945f5b46f5 100644 --- a/openbsd-compat/bsd-poll.h +++ b/openbsd-compat/bsd-poll.h @@ -42,11 +42,11 @@ typedef unsigned int nfds_t; #define POLLIN 0x0001 #define POLLOUT 0x0004 #define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 #if 0 /* the following are currently not implemented */ #define POLLPRI 0x0002 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 #define POLLRDNORM 0x0040 #define POLLNORM POLLRDNORM #define POLLWRNORM POLLOUT diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index 742b4b954a32..7c97e67f557c 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c @@ -59,6 +59,7 @@ */ #include "includes.h" +#include "glob.h" #include #include diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h index f8a7fa5ffe3e..f069a05dc656 100644 --- a/openbsd-compat/glob.h +++ b/openbsd-compat/glob.h @@ -42,11 +42,15 @@ !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ defined(BROKEN_GLOB) -#ifndef _GLOB_H_ -#define _GLOB_H_ +#ifndef _COMPAT_GLOB_H_ +#define _COMPAT_GLOB_H_ #include +# define glob_t _ssh_compat_glob_t +# define glob(a, b, c, d) _ssh__compat_glob(a, b, c, d) +# define globfree(a) _ssh__compat_globfree(a) + struct stat; typedef struct { int gl_pathc; /* Count of total paths so far. */ diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index 1ff7114ef3da..8cc8a11b7617 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -39,7 +39,6 @@ /* OpenBSD function replacements */ #include "base64.h" #include "sigact.h" -#include "glob.h" #include "readpassphrase.h" #include "vis.h" #include "getrrsetbyname.h" diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c index 25382f1c907c..e36e412d7325 100644 --- a/openbsd-compat/port-solaris.c +++ b/openbsd-compat/port-solaris.c @@ -227,3 +227,139 @@ solaris_set_default_project(struct passwd *pw) } } #endif /* USE_SOLARIS_PROJECTS */ + +#ifdef USE_SOLARIS_PRIVS +# ifdef HAVE_PRIV_H +# include +# endif + +priv_set_t * +solaris_basic_privset(void) +{ + priv_set_t *pset; + +#ifdef HAVE_PRIV_BASICSET + if ((pset = priv_allocset()) == NULL) { + error("priv_allocset: %s", strerror(errno)); + return NULL; + } + priv_basicset(pset); +#else + if ((pset = priv_str_to_set("basic", ",", NULL)) == NULL) { + error("priv_str_to_set: %s", strerror(errno)); + return NULL; + } +#endif + return pset; +} + +void +solaris_drop_privs_pinfo_net_fork_exec(void) +{ + priv_set_t *pset = NULL, *npset = NULL; + + /* + * Note: this variant avoids dropping DAC filesystem rights, in case + * the process calling it is running as root and should have the + * ability to read/write/chown any file on the system. + * + * We start with the basic set, then *add* the DAC rights to it while + * taking away other parts of BASIC we don't need. Then we intersect + * this with our existing PERMITTED set. In this way we keep any + * DAC rights we had before, while otherwise reducing ourselves to + * the minimum set of privileges we need to proceed. + * + * This also means we drop any other parts of "root" that we don't + * need (e.g. the ability to kill any process, create new device nodes + * etc etc). + */ + + if ((pset = priv_allocset()) == NULL) + fatal("priv_allocset: %s", strerror(errno)); + if ((npset = solaris_basic_privset()) == NULL) + fatal("solaris_basic_privset: %s", strerror(errno)); + + if (priv_addset(npset, PRIV_FILE_CHOWN) != 0 || + priv_addset(npset, PRIV_FILE_DAC_READ) != 0 || + priv_addset(npset, PRIV_FILE_DAC_SEARCH) != 0 || + priv_addset(npset, PRIV_FILE_DAC_WRITE) != 0 || + priv_addset(npset, PRIV_FILE_OWNER) != 0) + fatal("priv_addset: %s", strerror(errno)); + + if (priv_delset(npset, PRIV_FILE_LINK_ANY) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(npset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(npset, PRIV_PROC_EXEC) != 0 || + priv_delset(npset, PRIV_PROC_FORK) != 0 || + priv_delset(npset, PRIV_PROC_INFO) != 0 || + priv_delset(npset, PRIV_PROC_SESSION) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (getppriv(PRIV_PERMITTED, pset) != 0) + fatal("getppriv: %s", strerror(errno)); + + priv_intersect(pset, npset); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, npset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, npset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, npset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); + priv_freeset(npset); +} + +void +solaris_drop_privs_root_pinfo_net(void) +{ + priv_set_t *pset = NULL; + + /* Start with "basic" and drop everything we don't need. */ + if ((pset = solaris_basic_privset()) == NULL) + fatal("solaris_basic_privset: %s", strerror(errno)); + + if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(pset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(pset, PRIV_PROC_INFO) != 0 || + priv_delset(pset, PRIV_PROC_SESSION) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); +} + +void +solaris_drop_privs_root_pinfo_net_exec(void) +{ + priv_set_t *pset = NULL; + + + /* Start with "basic" and drop everything we don't need. */ + if ((pset = solaris_basic_privset()) == NULL) + fatal("solaris_basic_privset: %s", strerror(errno)); + + if (priv_delset(pset, PRIV_FILE_LINK_ANY) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(pset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(pset, PRIV_PROC_EXEC) != 0 || + priv_delset(pset, PRIV_PROC_INFO) != 0 || + priv_delset(pset, PRIV_PROC_SESSION) != 0) + fatal("priv_delset: %s", strerror(errno)); + + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, pset) != 0) + fatal("setppriv: %s", strerror(errno)); + + priv_freeset(pset); +} + +#endif diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h index cd442e78b10e..3a41ea8cdccd 100644 --- a/openbsd-compat/port-solaris.h +++ b/openbsd-compat/port-solaris.h @@ -26,5 +26,11 @@ void solaris_contract_pre_fork(void); void solaris_contract_post_fork_child(void); void solaris_contract_post_fork_parent(pid_t pid); void solaris_set_default_project(struct passwd *); +# ifdef USE_SOLARIS_PRIVS +priv_set_t *solaris_basic_privset(void); +void solaris_drop_privs_pinfo_net_fork_exec(void); +void solaris_drop_privs_root_pinfo_net(void); +void solaris_drop_privs_root_pinfo_net_exec(void); +# endif /* USE_SOLARIS_PRIVS */ #endif diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c index ba4cea93894f..a2f090e5512f 100644 --- a/openbsd-compat/realpath.c +++ b/openbsd-compat/realpath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: realpath.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ +/* $OpenBSD: realpath.c,v 1.20 2015/10/13 20:55:37 millert Exp $ */ /* * Copyright (c) 2003 Constantin S. Svintsoff * @@ -42,6 +42,13 @@ #include #include #include +#include + +#ifndef SYMLOOP_MAX +# define SYMLOOP_MAX 32 +#endif + +/* A slightly modified copy of this file exists in libexec/ld.so */ /* * char *realpath(const char *path, char resolved[PATH_MAX]); @@ -51,16 +58,30 @@ * in which case the path which caused trouble is left in (resolved). */ char * -realpath(const char *path, char resolved[PATH_MAX]) +realpath(const char *path, char *resolved) { struct stat sb; char *p, *q, *s; size_t left_len, resolved_len; unsigned symlinks; - int serrno, slen; + int serrno, slen, mem_allocated; char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; + if (path[0] == '\0') { + errno = ENOENT; + return (NULL); + } + serrno = errno; + + if (resolved == NULL) { + resolved = malloc(PATH_MAX); + if (resolved == NULL) + return (NULL); + mem_allocated = 1; + } else + mem_allocated = 0; + symlinks = 0; if (path[0] == '/') { resolved[0] = '/'; @@ -71,7 +92,10 @@ realpath(const char *path, char resolved[PATH_MAX]) left_len = strlcpy(left, path + 1, sizeof(left)); } else { if (getcwd(resolved, PATH_MAX) == NULL) { - strlcpy(resolved, ".", PATH_MAX); + if (mem_allocated) + free(resolved); + else + strlcpy(resolved, ".", PATH_MAX); return (NULL); } resolved_len = strlen(resolved); @@ -79,7 +103,7 @@ realpath(const char *path, char resolved[PATH_MAX]) } if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto err; } /* @@ -94,7 +118,7 @@ realpath(const char *path, char resolved[PATH_MAX]) s = p ? p : left + left_len; if (s - left >= (ptrdiff_t)sizeof(next_token)) { errno = ENAMETOOLONG; - return (NULL); + goto err; } memcpy(next_token, left, s - left); next_token[s - left] = '\0'; @@ -104,7 +128,7 @@ realpath(const char *path, char resolved[PATH_MAX]) if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto err; } resolved[resolved_len++] = '/'; resolved[resolved_len] = '\0'; @@ -135,23 +159,23 @@ realpath(const char *path, char resolved[PATH_MAX]) resolved_len = strlcat(resolved, next_token, PATH_MAX); if (resolved_len >= PATH_MAX) { errno = ENAMETOOLONG; - return (NULL); + goto err; } if (lstat(resolved, &sb) != 0) { if (errno == ENOENT && p == NULL) { errno = serrno; return (resolved); } - return (NULL); + goto err; } if (S_ISLNK(sb.st_mode)) { - if (symlinks++ > MAXSYMLINKS) { + if (symlinks++ > SYMLOOP_MAX) { errno = ELOOP; - return (NULL); + goto err; } slen = readlink(resolved, symlink, sizeof(symlink) - 1); if (slen < 0) - return (NULL); + goto err; symlink[slen] = '\0'; if (symlink[0] == '/') { resolved[1] = 0; @@ -174,15 +198,15 @@ realpath(const char *path, char resolved[PATH_MAX]) if (slen + 1 >= (ptrdiff_t)sizeof(symlink)) { errno = ENAMETOOLONG; - return (NULL); + goto err; } symlink[slen] = '/'; symlink[slen + 1] = 0; } - left_len = strlcat(symlink, left, sizeof(left)); - if (left_len >= sizeof(left)) { + left_len = strlcat(symlink, left, sizeof(symlink)); + if (left_len >= sizeof(symlink)) { errno = ENAMETOOLONG; - return (NULL); + goto err; } } left_len = strlcpy(left, symlink, sizeof(left)); @@ -196,5 +220,10 @@ realpath(const char *path, char resolved[PATH_MAX]) if (resolved_len > 1 && resolved[resolved_len - 1] == '/') resolved[resolved_len - 1] = '\0'; return (resolved); + +err: + if (mem_allocated) + free(resolved); + return (NULL); } #endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ diff --git a/packet.c b/packet.c index 7b5c419eb152..f406c0755a54 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.214 2015/08/20 22:32:42 deraadt Exp $ */ +/* $OpenBSD: packet.c,v 1.229 2016/02/17 22:20:14 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -83,7 +83,6 @@ #include "channels.h" #include "ssh.h" #include "packet.h" -#include "roaming.h" #include "ssherr.h" #include "sshbuf.h" @@ -181,8 +180,7 @@ struct session_state { struct packet_state p_read, p_send; /* Volume-based rekeying */ - u_int64_t max_blocks_in, max_blocks_out; - u_int32_t rekey_limit; + u_int64_t max_blocks_in, max_blocks_out, rekey_limit; /* Time-based rekeying */ u_int32_t rekey_interval; /* how often in seconds */ @@ -261,6 +259,14 @@ ssh_alloc_session_state(void) return NULL; } +/* Returns nonzero if rekeying is in progress */ +int +ssh_packet_is_rekeying(struct ssh *ssh) +{ + return compat20 && + (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0)); +} + /* * Sets the descriptors used for communication. Disables encryption until * packet_set_encryption_key is called. @@ -338,7 +344,8 @@ ssh_packet_stop_discard(struct ssh *ssh) sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE, NULL, 0); } - logit("Finished discarding for %.200s", ssh_remote_ipaddr(ssh)); + logit("Finished discarding for %.200s port %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); return SSH_ERR_MAC_INVALID; } @@ -455,16 +462,30 @@ ssh_packet_get_connection_out(struct ssh *ssh) const char * ssh_remote_ipaddr(struct ssh *ssh) { + const int sock = ssh->state->connection_in; + /* 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"; + if (ssh->remote_ipaddr == NULL) { + if (ssh_packet_connection_is_on_socket(ssh)) { + ssh->remote_ipaddr = get_peer_ipaddr(sock); + ssh->remote_port = get_sock_port(sock, 0); + } else { + ssh->remote_ipaddr = strdup("UNKNOWN"); + ssh->remote_port = 0; + } + } return ssh->remote_ipaddr; } +/* Returns the port number of the remote host. */ + +int +ssh_remote_port(struct ssh *ssh) +{ + (void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */ + return ssh->remote_port; +} + /* Closes the connection and clears and frees internal data structures. */ void @@ -519,10 +540,8 @@ ssh_packet_close(struct ssh *ssh) 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->remote_ipaddr); + ssh->remote_ipaddr = NULL; free(ssh->state); ssh->state = NULL; } @@ -941,7 +960,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode) max_blocks = &state->max_blocks_in; } if (state->newkeys[mode] != NULL) { - debug("set_newkeys: rekeying"); + debug("set_newkeys: rekeying, input %llu bytes %llu blocks, " + "output %llu bytes %llu blocks", + (unsigned long long)state->p_read.bytes, + (unsigned long long)state->p_read.blocks, + (unsigned long long)state->p_send.bytes, + (unsigned long long)state->p_send.blocks); if ((r = cipher_cleanup(cc)) != 0) return r; enc = &state->newkeys[mode]->enc; @@ -1009,9 +1033,55 @@ ssh_set_newkeys(struct ssh *ssh, int mode) if (state->rekey_limit) *max_blocks = MIN(*max_blocks, state->rekey_limit / enc->block_size); + debug("rekey after %llu blocks", (unsigned long long)*max_blocks); return 0; } +#define MAX_PACKETS (1U<<31) +static int +ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) +{ + struct session_state *state = ssh->state; + u_int32_t out_blocks; + + /* XXX client can't cope with rekeying pre-auth */ + if (!state->after_authentication) + return 0; + + /* Haven't keyed yet or KEX in progress. */ + if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh)) + return 0; + + /* Peer can't rekey */ + if (ssh->compat & SSH_BUG_NOREKEY) + return 0; + + /* + * Permit one packet in or out per rekey - this allows us to + * make progress when rekey limits are very small. + */ + if (state->p_send.packets == 0 && state->p_read.packets == 0) + return 0; + + /* Time-based rekeying */ + if (state->rekey_interval != 0 && + state->rekey_time + state->rekey_interval <= monotime()) + return 1; + + /* Always rekey when MAX_PACKETS sent in either direction */ + if (state->p_send.packets > MAX_PACKETS || + state->p_read.packets > MAX_PACKETS) + return 1; + + /* Rekey after (cipher-specific) maxiumum blocks */ + out_blocks = roundup(outbound_packet_len, + state->newkeys[MODE_OUT]->enc.block_size); + return (state->max_blocks_out && + (state->p_send.blocks + out_blocks > state->max_blocks_out)) || + (state->max_blocks_in && + (state->p_read.blocks > state->max_blocks_in)); +} + /* * Delayed compression for SSH2 is enabled after authentication: * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, @@ -1050,6 +1120,20 @@ ssh_packet_enable_delayed_compress(struct ssh *ssh) return 0; } +/* Used to mute debug logging for noisy packet types */ +static int +ssh_packet_log_type(u_char type) +{ + switch (type) { + case SSH2_MSG_CHANNEL_DATA: + case SSH2_MSG_CHANNEL_EXTENDED_DATA: + case SSH2_MSG_CHANNEL_WINDOW_ADJUST: + return 0; + default: + return 1; + } +} + /* * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) */ @@ -1078,7 +1162,8 @@ ssh_packet_send2_wrapped(struct ssh *ssh) aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; type = (sshbuf_ptr(state->outgoing_packet))[5]; - + if (ssh_packet_log_type(type)) + debug3("send packet: type %u", type); #ifdef PACKET_DEBUG fprintf(stderr, "plain: "); sshbuf_dump(state->outgoing_packet, stderr); @@ -1200,34 +1285,58 @@ ssh_packet_send2_wrapped(struct ssh *ssh) return r; } +/* returns non-zero if the specified packet type is usec by KEX */ +static int +ssh_packet_type_is_kex(u_char type) +{ + return + type >= SSH2_MSG_TRANSPORT_MIN && + type <= SSH2_MSG_TRANSPORT_MAX && + type != SSH2_MSG_SERVICE_REQUEST && + type != SSH2_MSG_SERVICE_ACCEPT && + type != SSH2_MSG_EXT_INFO; +} + int ssh_packet_send2(struct ssh *ssh) { struct session_state *state = ssh->state; struct packet *p; u_char type; - int r; + int r, need_rekey; + if (sshbuf_len(state->outgoing_packet) < 6) + return SSH_ERR_INTERNAL_ERROR; type = sshbuf_ptr(state->outgoing_packet)[5]; + need_rekey = !ssh_packet_type_is_kex(type) && + ssh_packet_need_rekeying(ssh, sshbuf_len(state->outgoing_packet)); - /* during rekeying we can only send key exchange messages */ - 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 = calloc(1, sizeof(*p)); - if (p == NULL) - return SSH_ERR_ALLOC_FAIL; - p->type = type; - 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; + /* + * During rekeying we can only send key exchange messages. + * Queue everything else. + */ + if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) { + if (need_rekey) + debug3("%s: rekex triggered", __func__); + debug("enqueue packet: %u", type); + p = calloc(1, sizeof(*p)); + if (p == NULL) + return SSH_ERR_ALLOC_FAIL; + p->type = type; + 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; + if (need_rekey) { + /* + * This packet triggered a rekey, so send the + * KEXINIT now. + * NB. reenters this function via kex_start_rekex(). + */ + return kex_start_rekex(ssh); } + return 0; } /* rekeying starts with sending KEXINIT */ @@ -1243,10 +1352,22 @@ ssh_packet_send2(struct ssh *ssh) state->rekey_time = monotime(); while ((p = TAILQ_FIRST(&state->outgoing))) { type = p->type; + /* + * If this packet triggers a rekex, then skip the + * remaining packets in the queue for now. + * NB. re-enters this function via kex_start_rekex. + */ + if (ssh_packet_need_rekeying(ssh, + sshbuf_len(p->payload))) { + debug3("%s: queued packet triggered rekex", + __func__); + return kex_start_rekex(ssh); + } debug("dequeue packet: %u", type); sshbuf_free(state->outgoing_packet); state->outgoing_packet = p->payload; TAILQ_REMOVE(&state->outgoing, p, next); + memset(p, 0, sizeof(*p)); free(p); if ((r = ssh_packet_send2_wrapped(ssh)) != 0) return r; @@ -1265,7 +1386,7 @@ int ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { struct session_state *state = ssh->state; - int len, r, ms_remain, cont; + int len, r, ms_remain; fd_set *setp; char buf[8192]; struct timeval timeout, start, *timeoutp = NULL; @@ -1335,11 +1456,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) if (r == 0) return SSH_ERR_CONN_TIMEOUT; /* Read data from the socket. */ - do { - cont = 0; - len = roaming_read(state->connection_in, buf, - sizeof(buf), &cont); - } while (len == 0 && cont); + len = read(state->connection_in, buf, sizeof(buf)); if (len == 0) { r = SSH_ERR_CONN_CLOSED; goto out; @@ -1734,6 +1851,8 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) */ if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) goto out; + if (ssh_packet_log_type(*typep)) + debug3("receive packet: type %u", *typep); if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { if ((r = sshpkt_disconnect(ssh, "Invalid ssh2 packet type: %d", *typep)) != 0 || @@ -1753,6 +1872,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) #endif /* reset for next packet */ state->packlen = 0; + + /* do we need to rekey? */ + if (ssh_packet_need_rekeying(ssh, 0)) { + debug3("%s: rekex triggered", __func__); + if ((r = kex_start_rekex(ssh)) != 0) + return r; + } out: return r; } @@ -1783,8 +1909,7 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) 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); + free(msg); return r; } debug("Remote: %.900s", msg); @@ -1798,8 +1923,9 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) do_log2(ssh->state->server_side && reason == SSH2_DISCONNECT_BY_APPLICATION ? SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, - "Received disconnect from %s: %u: %.400s", - ssh_remote_ipaddr(ssh), reason, msg); + "Received disconnect from %s port %d:" + "%u: %.400s", ssh_remote_ipaddr(ssh), + ssh_remote_port(ssh), reason, msg); free(msg); return SSH_ERR_DISCONNECTED; case SSH2_MSG_UNIMPLEMENTED: @@ -1827,8 +1953,9 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) case SSH_MSG_DISCONNECT: if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) return r; - error("Received disconnect from %s: %.400s", - ssh_remote_ipaddr(ssh), msg); + error("Received disconnect from %s port %d: " + "%.400s", ssh_remote_ipaddr(ssh), + ssh_remote_port(ssh), msg); free(msg); return SSH_ERR_DISCONNECTED; default: @@ -1918,19 +2045,22 @@ 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)); + logit("Connection closed by %.200s port %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); case SSH_ERR_CONN_TIMEOUT: - logit("Connection to %.200s timed out", ssh_remote_ipaddr(ssh)); + logit("Connection %s %.200s port %d timed out", + ssh->state->server_side ? "from" : "to", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); case SSH_ERR_DISCONNECTED: - logit("Disconnected from %.200s", - ssh_remote_ipaddr(ssh)); + logit("Disconnected from %.200s port %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); case SSH_ERR_SYSTEM_ERROR: if (errno == ECONNRESET) { - logit("Connection reset by %.200s", - ssh_remote_ipaddr(ssh)); + logit("Connection reset by %.200s port %d", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); cleanup_exit(255); } /* FALLTHROUGH */ @@ -1940,15 +2070,17 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r) case SSH_ERR_NO_KEX_ALG_MATCH: case SSH_ERR_NO_HOSTKEY_ALG_MATCH: if (ssh && ssh->kex && ssh->kex->failed_choice) { - fatal("Unable to negotiate with %.200s: %s. " + fatal("Unable to negotiate with %.200s port %d: %s. " "Their offer: %s", ssh_remote_ipaddr(ssh), - ssh_err(r), ssh->kex->failed_choice); + ssh_remote_port(ssh), ssh_err(r), + ssh->kex->failed_choice); } /* FALLTHROUGH */ default: - fatal("%s%sConnection to %.200s: %s", + fatal("%s%sConnection %s %.200s port %d: %s", tag != NULL ? tag : "", tag != NULL ? ": " : "", - ssh_remote_ipaddr(ssh), ssh_err(r)); + ssh->state->server_side ? "from" : "to", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_err(r)); } } @@ -2005,19 +2137,18 @@ ssh_packet_write_poll(struct ssh *ssh) { struct session_state *state = ssh->state; int len = sshbuf_len(state->output); - int cont, r; + int r; if (len > 0) { - cont = 0; - len = roaming_write(state->connection_out, - sshbuf_ptr(state->output), len, &cont); + len = write(state->connection_out, + sshbuf_ptr(state->output), len); if (len == -1) { if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) return 0; return SSH_ERR_SYSTEM_ERROR; } - if (len == 0 && !cont) + if (len == 0) return SSH_ERR_CONN_CLOSED; if ((r = sshbuf_consume(state->output, len)) != 0) return r; @@ -2041,7 +2172,10 @@ ssh_packet_write_wait(struct ssh *ssh) NFDBITS), sizeof(fd_mask)); if (setp == NULL) return SSH_ERR_ALLOC_FAIL; - ssh_packet_write_poll(ssh); + if ((r = ssh_packet_write_poll(ssh)) != 0) { + free(setp); + return r; + } while (ssh_packet_have_data_to_write(ssh)) { memset(setp, 0, howmany(state->connection_out + 1, NFDBITS) * sizeof(fd_mask)); @@ -2229,29 +2363,10 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes) } } -#define MAX_PACKETS (1U<<31) -int -ssh_packet_need_rekeying(struct ssh *ssh) -{ - struct session_state *state = ssh->state; - - if (ssh->compat & SSH_BUG_NOREKEY) - return 0; - return - (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 -ssh_packet_set_rekey_limits(struct ssh *ssh, u_int32_t bytes, time_t seconds) +ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, time_t seconds) { - debug3("rekey after %lld bytes, %d seconds", (long long)bytes, + debug3("rekey after %llu bytes, %d seconds", (unsigned long long)bytes, (int)seconds); ssh->state->rekey_limit = bytes; ssh->state->rekey_interval = seconds; @@ -2291,58 +2406,6 @@ ssh_packet_get_output(struct ssh *ssh) 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 -ssh_packet_backup_state(struct ssh *ssh, - struct ssh *backup_state) -{ - struct ssh *tmp; - - 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 = ssh_alloc_session_state(); - backup_state = ssh; - ssh = tmp; -} - -/* XXX FIXME FIXME FIXME */ -/* - * Swap in the old state when resuming a connecion. - */ -void -ssh_packet_restore_state(struct ssh *ssh, - struct ssh *backup_state) -{ - struct ssh *tmp; - u_int len; - int r; - - tmp = backup_state; - 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) { - 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 */ static int ssh_packet_set_postauth(struct ssh *ssh) @@ -2430,8 +2493,7 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) goto out; r = sshbuf_put_stringb(m, b); out: - if (b != NULL) - sshbuf_free(b); + sshbuf_free(b); return r; } @@ -2462,7 +2524,7 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) 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_u64(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 || @@ -2493,11 +2555,6 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) (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; } @@ -2566,10 +2623,8 @@ newkeys_from_blob(struct sshbuf *m, struct ssh *ssh, int mode) newkey = NULL; r = 0; out: - if (newkey != NULL) - free(newkey); - if (b != NULL) - sshbuf_free(b); + free(newkey); + sshbuf_free(b); return r; } @@ -2602,10 +2657,8 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp) 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); + sshbuf_free(kex->my); + sshbuf_free(kex->peer); free(kex); } if (kexp != NULL) @@ -2628,7 +2681,6 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) 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 || @@ -2651,7 +2703,7 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) 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_u64(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 || @@ -2693,12 +2745,6 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) (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__); diff --git a/packet.h b/packet.h index 7b06544e8370..28516a553a20 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.66 2015/01/30 01:13:33 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.70 2016/02/08 10:57:07 djm Exp $ */ /* * Author: Tatu Ylonen @@ -86,6 +86,7 @@ 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); +int ssh_packet_is_rekeying(struct ssh *); 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); @@ -143,15 +144,11 @@ int ssh_packet_get_state(struct ssh *, struct sshbuf *); int ssh_packet_set_state(struct ssh *, struct sshbuf *); const char *ssh_remote_ipaddr(struct ssh *); +int ssh_remote_port(struct ssh *); -int ssh_packet_need_rekeying(struct ssh *); -void ssh_packet_set_rekey_limits(struct ssh *, u_int32_t, time_t); +void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, time_t); time_t ssh_packet_get_rekey_timeout(struct ssh *); -/* 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 *); diff --git a/platform-pledge.c b/platform-pledge.c new file mode 100644 index 000000000000..4a6ec15e1b2d --- /dev/null +++ b/platform-pledge.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 Joyent, Inc + * Author: Alex Wilson + * + * 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 "platform.h" + +#include "openbsd-compat/openbsd-compat.h" + +/* + * Drop any fine-grained privileges that are not needed for post-startup + * operation of ssh-agent + * + * Should be as close as possible to pledge("stdio cpath unix id proc exec", ...) + */ +void +platform_pledge_agent(void) +{ +#ifdef USE_SOLARIS_PRIVS + /* + * Note: Solaris priv dropping is closer to tame() than pledge(), but + * we will use what we have. + */ + solaris_drop_privs_root_pinfo_net(); +#endif +} + +/* + * Drop any fine-grained privileges that are not needed for post-startup + * operation of sftp-server + */ +void +platform_pledge_sftp_server(void) +{ +#ifdef USE_SOLARIS_PRIVS + solaris_drop_privs_pinfo_net_fork_exec(); +#endif +} + +/* + * Drop any fine-grained privileges that are not needed for the post-startup + * operation of the SSH client mux + * + * Should be as close as possible to pledge("stdio proc tty", ...) + */ +void +platform_pledge_mux(void) +{ +#ifdef USE_SOLARIS_PRIVS + solaris_drop_privs_root_pinfo_net_exec(); +#endif +} diff --git a/platform.h b/platform.h index 1c7a45d8fc29..e687c99b6e55 100644 --- a/platform.h +++ b/platform.h @@ -31,3 +31,8 @@ void platform_setusercontext_post_groups(struct passwd *); char *platform_get_krb5_client(const char *); char *platform_krb5_get_principal_name(const char *); int platform_sys_dir_uid(uid_t); + +/* in platform-pledge.c */ +void platform_pledge_agent(void); +void platform_pledge_sftp_server(void); +void platform_pledge_mux(void); diff --git a/readconf.c b/readconf.c index cd014821aefe..69d4553af217 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -135,6 +135,7 @@ typedef enum { oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, + oCertificateFile, oAddKeysToAgent, oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, @@ -151,7 +152,7 @@ typedef enum { oSendEnv, oControlPath, oControlMaster, oControlPersist, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, - oVisualHostKey, oUseRoaming, + oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, @@ -202,6 +203,8 @@ static struct { { "identityfile", oIdentityFile }, { "identityfile2", oIdentityFile }, /* obsolete */ { "identitiesonly", oIdentitiesOnly }, + { "certificatefile", oCertificateFile }, + { "addkeystoagent", oAddKeysToAgent }, { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, { "proxycommand", oProxyCommand }, @@ -260,7 +263,7 @@ static struct { { "localcommand", oLocalCommand }, { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, - { "useroaming", oUseRoaming }, + { "useroaming", oDeprecated }, { "kexalgorithms", oKexAlgorithms }, { "ipqos", oIPQoS }, { "requesttty", oRequestTTY }, @@ -365,6 +368,30 @@ clear_forwardings(Options *options) options->tun_open = SSH_TUNMODE_NO; } +void +add_certificate_file(Options *options, const char *path, int userprovided) +{ + int i; + + if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES) + fatal("Too many certificate files specified (max %d)", + SSH_MAX_CERTIFICATE_FILES); + + /* Avoid registering duplicates */ + for (i = 0; i < options->num_certificate_files; i++) { + if (options->certificate_file_userprovided[i] == userprovided && + strcmp(options->certificate_files[i], path) == 0) { + debug2("%s: ignoring duplicate key %s", __func__, path); + return; + } + } + + options->certificate_file_userprovided[options->num_certificate_files] = + userprovided; + options->certificate_files[options->num_certificate_files++] = + xstrdup(path); +} + void add_identity_file(Options *options, const char *dir, const char *filename, int userprovided) @@ -416,7 +443,7 @@ default_ssh_port(void) static int execute_in_shell(const char *cmd) { - char *shell, *command_string; + char *shell; pid_t pid; int devnull, status; extern uid_t original_real_uid; @@ -424,12 +451,6 @@ execute_in_shell(const char *cmd) if ((shell = getenv("SHELL")) == NULL) shell = _PATH_BSHELL; - /* - * Use "exec" to avoid "sh -c" processes on some platforms - * (e.g. Solaris) - */ - xasprintf(&command_string, "exec %s", cmd); - /* Need this to redirect subprocess stdin/out */ if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) fatal("open(/dev/null): %s", strerror(errno)); @@ -454,7 +475,7 @@ execute_in_shell(const char *cmd) argv[0] = shell; argv[1] = "-c"; - argv[2] = command_string; + argv[2] = xstrdup(cmd); argv[3] = NULL; execv(argv[0], argv); @@ -469,7 +490,6 @@ execute_in_shell(const char *cmd) fatal("%s: fork: %.100s", __func__, strerror(errno)); close(devnull); - free(command_string); while (waitpid(pid, &status, 0) == -1) { if (errno != EINTR && errno != EAGAIN) @@ -502,12 +522,15 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, */ port = options->port <= 0 ? default_ssh_port() : options->port; ruser = options->user == NULL ? pw->pw_name : options->user; - if (options->hostname != NULL) { + if (post_canon) { + host = xstrdup(options->hostname); + } else if (options->hostname != NULL) { /* NB. Please keep in sync with ssh.c:main() */ host = percent_expand(options->hostname, "h", host_arg, (char *)NULL); - } else + } else { host = xstrdup(host_arg); + } debug2("checking match for '%s' host %s originally %s", cp, host, original_host); @@ -693,6 +716,15 @@ static const struct multistate multistate_yesnoask[] = { { "ask", 2 }, { NULL, -1 } }; +static const struct multistate multistate_yesnoaskconfirm[] = { + { "true", 1 }, + { "false", 0 }, + { "yes", 1 }, + { "no", 0 }, + { "ask", 2 }, + { "confirm", 3 }, + { NULL, -1 } +}; static const struct multistate multistate_addressfamily[] = { { "inet", AF_INET }, { "inet6", AF_INET6 }, @@ -947,16 +979,12 @@ process_config_line(Options *options, struct passwd *pw, const char *host, if (scan_scaled(arg, &val64) == -1) fatal("%.200s line %d: Bad number '%s': %s", filename, linenum, arg, strerror(errno)); - /* check for too-large or too-small limits */ - if (val64 > UINT_MAX) - fatal("%.200s line %d: RekeyLimit too large", - filename, linenum); if (val64 != 0 && val64 < 16) fatal("%.200s line %d: RekeyLimit too small", filename, linenum); } if (*activep && options->rekey_limit == -1) - options->rekey_limit = (u_int32_t)val64; + options->rekey_limit = val64; if (s != NULL) { /* optional rekey interval present */ if (strcmp(s, "none") == 0) { (void)strdelim(&s); /* discard */ @@ -981,6 +1009,24 @@ process_config_line(Options *options, struct passwd *pw, const char *host, } break; + case oCertificateFile: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if (*activep) { + intptr = &options->num_certificate_files; + if (*intptr >= SSH_MAX_CERTIFICATE_FILES) { + fatal("%.200s line %d: Too many certificate " + "files specified (max %d).", + filename, linenum, + SSH_MAX_CERTIFICATE_FILES); + } + add_certificate_file(options, arg, + flags & SSHCONF_USERCONF); + } + break; + case oXAuthLocation: charptr=&options->xauth_location; goto parse_string; @@ -1378,10 +1424,6 @@ process_config_line(Options *options, struct passwd *pw, const char *host, } break; - case oUseRoaming: - intptr = &options->use_roaming; - goto parse_flag; - case oRequestTTY: intptr = &options->request_tty; multistate_ptr = multistate_requesttty; @@ -1496,6 +1538,11 @@ process_config_line(Options *options, struct passwd *pw, const char *host, charptr = &options->pubkey_key_types; goto parse_keytypes; + case oAddKeysToAgent: + intptr = &options->add_keys_to_agent; + multistate_ptr = multistate_yesnoaskconfirm; + goto parse_multistate; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -1625,6 +1672,7 @@ initialize_options(Options * options) options->hostkeyalgorithms = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->num_identity_files = 0; + options->num_certificate_files = 0; options->hostname = NULL; options->host_key_alias = NULL; options->proxy_command = NULL; @@ -1660,7 +1708,7 @@ initialize_options(Options * options) options->tun_remote = -1; options->local_command = NULL; options->permit_local_command = -1; - options->use_roaming = 0; + options->add_keys_to_agent = -1; options->visual_host_key = -1; options->ip_qos_interactive = -1; options->ip_qos_bulk = -1; @@ -1765,6 +1813,8 @@ fill_default_options(Options * options) /* options->hostkeyalgorithms, default set in myproposals.h */ if (options->protocol == SSH_PROTO_UNKNOWN) options->protocol = SSH_PROTO_2; + if (options->add_keys_to_agent == -1) + options->add_keys_to_agent = 0; if (options->num_identity_files == 0) { if (options->protocol & SSH_PROTO_1) { add_identity_file(options, "~/", @@ -1833,7 +1883,6 @@ fill_default_options(Options * options) options->tun_remote = SSH_TUNID_ANY; if (options->permit_local_command == -1) options->permit_local_command = 0; - options->use_roaming = 0; if (options->visual_host_key == -1) options->visual_host_key = 0; if (options->ip_qos_interactive == -1) @@ -2242,6 +2291,10 @@ dump_client_config(Options *o, const char *host) int i; char vbuf[5]; + /* This is normally prepared in ssh_kex2 */ + if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0) + fatal("%s: kex_assemble_names failed", __func__); + /* Most interesting options first: user, host, port */ dump_cfg_string(oUser, o->user); dump_cfg_string(oHostName, host); @@ -2302,7 +2355,7 @@ dump_client_config(Options *o, const char *host) 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(oHostKeyAlgorithms, o->hostkeyalgorithms); dump_cfg_string(oHostKeyAlias, o->host_key_alias); dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); @@ -2313,6 +2366,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); dump_cfg_string(oProxyCommand, o->proxy_command); + dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types); dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); dump_cfg_string(oXAuthLocation, o->xauth_location); @@ -2381,8 +2435,8 @@ dump_client_config(Options *o, const char *host) printf("%s\n", iptos2str(o->ip_qos_bulk)); /* oRekeyLimit */ - printf("rekeylimit %lld %d\n", - (long long)o->rekey_limit, o->rekey_interval); + printf("rekeylimit %llu %d\n", + (unsigned long long)o->rekey_limit, o->rekey_interval); /* oStreamLocalBindMask */ printf("streamlocalbindmask 0%o\n", diff --git a/readconf.h b/readconf.h index bb2d55283dd0..c84d068bd0cc 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.110 2015/07/10 06:21:53 markus Exp $ */ +/* $OpenBSD: readconf.h,v 1.113 2016/01/14 16:17:40 markus Exp $ */ /* * Author: Tatu Ylonen @@ -95,6 +95,13 @@ typedef struct { int identity_file_userprovided[SSH_MAX_IDENTITY_FILES]; struct sshkey *identity_keys[SSH_MAX_IDENTITY_FILES]; + int num_certificate_files; /* Number of extra certificates for ssh. */ + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; + + int add_keys_to_agent; + /* Local TCP/IP forward requests. */ int num_local_forwards; struct Forward *local_forwards; @@ -130,8 +137,6 @@ typedef struct { int permit_local_command; int visual_host_key; - int use_roaming; - int request_tty; int proxy_use_fdpass; @@ -194,5 +199,6 @@ 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 *); void add_identity_file(Options *, const char *, const char *, int); +void add_certificate_file(Options *, const char *, int); #endif /* READCONF_H */ diff --git a/readpass.c b/readpass.c index 869d86425c02..05c8cac1cc03 100644 --- a/readpass.c +++ b/readpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readpass.c,v 1.50 2014/02/02 03:44:31 djm Exp $ */ +/* $OpenBSD: readpass.c,v 1.51 2015/12/11 00:20:04 mmcc Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -76,7 +76,7 @@ ssh_askpass(char *askpass, const char *msg) close(p[0]); if (dup2(p[1], STDOUT_FILENO) < 0) fatal("ssh_askpass: dup2: %s", strerror(errno)); - execlp(askpass, askpass, msg, (char *) 0); + execlp(askpass, askpass, msg, (char *)NULL); fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); } close(p[1]); diff --git a/regress/Makefile b/regress/Makefile index cba83f4d6b06..451909c1a4b1 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.81 2015/05/21 06:44:25 djm Exp $ +# $OpenBSD: Makefile,v 1.82 2015/09/24 06:16:53 djm Exp $ REGRESS_TARGETS= unit t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t-exec tests: prep $(REGRESS_TARGETS) @@ -74,7 +74,8 @@ LTESTS= connect \ hostkey-agent \ keygen-knownhosts \ hostkey-rotate \ - principals-command + principals-command \ + cert-file # dhgex \ diff --git a/regress/agent-ptrace.sh b/regress/agent-ptrace.sh index 1912ca8f9bb0..bb676d631574 100644 --- a/regress/agent-ptrace.sh +++ b/regress/agent-ptrace.sh @@ -12,6 +12,11 @@ if have_prog uname ; then esac fi +if [ "x$USER" = "xroot" ]; then + echo "Skipped: running as root" + exit 0 +fi + if have_prog gdb ; then : ok else diff --git a/regress/cert-file.sh b/regress/cert-file.sh new file mode 100755 index 000000000000..bad923ad0ac7 --- /dev/null +++ b/regress/cert-file.sh @@ -0,0 +1,138 @@ +# $OpenBSD: cert-file.sh,v 1.2 2015/09/24 07:15:39 djm Exp $ +# Placed in the Public Domain. + +tid="ssh with certificates" + +rm -f $OBJ/user_ca_key* $OBJ/user_key* +rm -f $OBJ/cert_user_key* + +# Create a CA key +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key1 ||\ + fatal "ssh-keygen failed" +${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key2 ||\ + fatal "ssh-keygen failed" + +# Make some keys and certificates. +${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" +# Move the certificate to a different address to better control +# when it is offered. +${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \ + -z $$ -n ${USER} $OBJ/user_key1 || + fail "couldn't sign user_key1 with user_ca_key1" +mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_1.pub +${SSHKEYGEN} -q -s $OBJ/user_ca_key2 -I "regress user key for $USER" \ + -z $$ -n ${USER} $OBJ/user_key1 || + fail "couldn't sign user_key1 with user_ca_key2" +mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub + +trace 'try with identity files' +opts="-F $OBJ/ssh_proxy -oIdentitiesOnly=yes" +opts2="$opts -i $OBJ/user_key1 -i $OBJ/user_key2" +echo "cert-authority $(cat $OBJ/user_ca_key1.pub)" > $OBJ/authorized_keys_$USER + +for p in ${SSH_PROTOCOLS}; do + # Just keys should fail + ${SSH} $opts2 somehost exit 5$p + r=$? + if [ $r -eq 5$p ]; then + fail "ssh succeeded with no certs in protocol $p" + fi + + # Keys with untrusted cert should fail. + opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" + ${SSH} $opts3 somehost exit 5$p + r=$? + if [ $r -eq 5$p ]; then + fail "ssh succeeded with bad cert in protocol $p" + fi + + # Good cert with bad key should fail. + opts3="$opts -i $OBJ/user_key2" + opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" + ${SSH} $opts3 somehost exit 5$p + r=$? + if [ $r -eq 5$p ]; then + fail "ssh succeeded with no matching key in protocol $p" + fi + + # Keys with one trusted cert, should succeed. + opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" + ${SSH} $opts3 somehost exit 5$p + r=$? + if [ $r -ne 5$p ]; then + fail "ssh failed with trusted cert and key in protocol $p" + fi + + # Multiple certs and keys, with one trusted cert, should succeed. + opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub" + opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub" + ${SSH} $opts3 somehost exit 5$p + r=$? + if [ $r -ne 5$p ]; then + fail "ssh failed with multiple certs in protocol $p" + fi + + #Keys with trusted certificate specified in config options, should succeed. + opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub" + ${SSH} $opts3 somehost exit 5$p + r=$? + if [ $r -ne 5$p ]; then + fail "ssh failed with trusted cert in config in protocol $p" + fi +done + +#next, using an agent in combination with the keys +SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1 +if [ $? -ne 2 ]; then + fatal "ssh-add -l did not fail with exit code 2" +fi + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fatal "could not start ssh-agent: exit code $r" +fi + +# add private keys to agent +${SSHADD} -k $OBJ/user_key2 > /dev/null 2>&1 +if [ $? -ne 0 ]; then + fatal "ssh-add did not succeed with exit code 0" +fi +${SSHADD} -k $OBJ/user_key1 > /dev/null 2>&1 +if [ $? -ne 0 ]; then + fatal "ssh-add did not succeed with exit code 0" +fi + +# try ssh with the agent and certificates +# note: ssh agent only uses certificates in protocol 2 +opts="-F $OBJ/ssh_proxy" +# with no certificates, shoud fail +${SSH} -2 $opts somehost exit 52 +if [ $? -eq 52 ]; then + fail "ssh connect with agent in protocol 2 succeeded with no cert" +fi + +#with an untrusted certificate, should fail +opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub" +${SSH} -2 $opts somehost exit 52 +if [ $? -eq 52 ]; then + fail "ssh connect with agent in protocol 2 succeeded with bad cert" +fi + +#with an additional trusted certificate, should succeed +opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub" +${SSH} -2 $opts somehost exit 52 +if [ $? -ne 52 ]; then + fail "ssh connect with agent in protocol 2 failed with good cert" +fi + +trace "kill agent" +${SSHAGENT} -k > /dev/null + +#cleanup +rm -f $OBJ/user_ca_key* $OBJ/user_key* +rm -f $OBJ/cert_user_key* diff --git a/regress/check-perm.c b/regress/check-perm.c new file mode 100644 index 000000000000..dac307d24464 --- /dev/null +++ b/regress/check-perm.c @@ -0,0 +1,205 @@ +/* + * Placed in the public domain + */ + +/* $OpenBSD: modpipe.c,v 1.6 2013/11/21 03:16:47 djm Exp $ */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LIBGEN_H +#include +#endif + +static void +fatal(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + exit(1); +} +/* Based on session.c. NB. keep tests in sync */ +static void +safely_chroot(const char *path, uid_t uid) +{ + const char *cp; + char component[PATH_MAX]; + struct stat st; + + if (*path != '/') + fatal("chroot path does not begin at root"); + if (strlen(path) >= sizeof(component)) + fatal("chroot path too long"); + + /* + * Descend the path, checking that each component is a + * root-owned directory with strict permissions. + */ + for (cp = path; cp != NULL;) { + if ((cp = strchr(cp, '/')) == NULL) + strlcpy(component, path, sizeof(component)); + else { + cp++; + memcpy(component, path, cp - path); + component[cp - path] = '\0'; + } + + /* debug3("%s: checking '%s'", __func__, component); */ + + if (stat(component, &st) != 0) + fatal("%s: stat(\"%s\"): %s", __func__, + component, strerror(errno)); + if (st.st_uid != 0 || (st.st_mode & 022) != 0) + fatal("bad ownership or modes for chroot " + "directory %s\"%s\"", + cp == NULL ? "" : "component ", component); + if (!S_ISDIR(st.st_mode)) + fatal("chroot path %s\"%s\" is not a directory", + cp == NULL ? "" : "component ", component); + + } + + if (chdir(path) == -1) + fatal("Unable to chdir to chroot path \"%s\": " + "%s", path, strerror(errno)); +} + +/* from platform.c */ +int +platform_sys_dir_uid(uid_t uid) +{ + if (uid == 0) + return 1; +#ifdef PLATFORM_SYS_DIR_UID + if (uid == PLATFORM_SYS_DIR_UID) + return 1; +#endif + return 0; +} + +/* from auth.c */ +int +auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, + uid_t uid, char *err, size_t errlen) +{ + char buf[PATH_MAX], homedir[PATH_MAX]; + char *cp; + int comparehome = 0; + struct stat st; + + if (realpath(name, buf) == NULL) { + snprintf(err, errlen, "realpath %s failed: %s", name, + strerror(errno)); + return -1; + } + if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) + comparehome = 1; + + if (!S_ISREG(stp->st_mode)) { + snprintf(err, errlen, "%s is not a regular file", buf); + return -1; + } + if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || + (stp->st_mode & 022) != 0) { + snprintf(err, errlen, "bad ownership or modes for file %s", + buf); + return -1; + } + + /* for each component of the canonical path, walking upwards */ + for (;;) { + if ((cp = dirname(buf)) == NULL) { + snprintf(err, errlen, "dirname() failed"); + return -1; + } + strlcpy(buf, cp, sizeof(buf)); + + if (stat(buf, &st) < 0 || + (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || + (st.st_mode & 022) != 0) { + snprintf(err, errlen, + "bad ownership or modes for directory %s", buf); + return -1; + } + + /* If are past the homedir then we can stop */ + if (comparehome && strcmp(homedir, buf) == 0) + break; + + /* + * dirname should always complete with a "/" path, + * but we can be paranoid and check for "." too + */ + if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) + break; + } + return 0; +} + +static void +usage(void) +{ + fprintf(stderr, "check-perm -m [chroot | keys-command] [path]\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *path = "."; + char errmsg[256]; + int ch, mode = -1; + extern char *optarg; + extern int optind; + struct stat st; + + while ((ch = getopt(argc, argv, "hm:")) != -1) { + switch (ch) { + case 'm': + if (strcasecmp(optarg, "chroot") == 0) + mode = 1; + else if (strcasecmp(optarg, "keys-command") == 0) + mode = 2; + else { + fprintf(stderr, "Invalid -m option\n"), + usage(); + } + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc > 1) + usage(); + else if (argc == 1) + path = argv[0]; + + if (mode == 1) + safely_chroot(path, getuid()); + else if (mode == 2) { + if (stat(path, &st) < 0) + fatal("Could not stat %s: %s", path, strerror(errno)); + if (auth_secure_path(path, &st, NULL, 0, + errmsg, sizeof(errmsg)) != 0) + fatal("Unsafe %s: %s", path, errmsg); + } else { + fprintf(stderr, "Invalid mode\n"); + usage(); + } + return 0; +} diff --git a/regress/dhgex.sh b/regress/dhgex.sh index 57fca4a32e94..e7c5733974a7 100755 --- a/regress/dhgex.sh +++ b/regress/dhgex.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dhgex.sh,v 1.2 2014/04/21 22:15:37 djm Exp $ +# $OpenBSD: dhgex.sh,v 1.3 2015/10/23 02:22:01 dtucker Exp $ # Placed in the Public Domain. tid="dhgex" @@ -20,7 +20,9 @@ ssh_test_dhgex() echo "Ciphers=$cipher" >> $OBJ/sshd_proxy rm -f ${LOG} opts="-oKexAlgorithms=$kex -oCiphers=$cipher" - groupsz="1024<$bits<8192" + min=2048 + max=8192 + groupsz="$min<$bits<$max" verbose "$tid bits $bits $kex $cipher" ${SSH} ${opts} $@ -vvv -F ${OBJ}/ssh_proxy somehost true if [ $? -ne 0 ]; then diff --git a/regress/hostkey-rotate.sh b/regress/hostkey-rotate.sh index 3aa8c40c0adf..d69de32557a6 100755 --- a/regress/hostkey-rotate.sh +++ b/regress/hostkey-rotate.sh @@ -1,4 +1,4 @@ -# $OpenBSD: hostkey-rotate.sh,v 1.4 2015/07/10 06:23:25 markus Exp $ +# $OpenBSD: hostkey-rotate.sh,v 1.5 2015/09/04 04:23:10 djm Exp $ # Placed in the Public Domain. tid="hostkey rotate" @@ -108,21 +108,3 @@ 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.4 2015/07/10 06:23:25 markus 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/regress/keys-command.sh b/regress/keys-command.sh index 700273b66642..af68cf15c7a5 100755 --- a/regress/keys-command.sh +++ b/regress/keys-command.sh @@ -36,6 +36,12 @@ exec cat "$OBJ/authorized_keys_${LOGNAME}" _EOF $SUDO chmod 0755 "$KEY_COMMAND" +if ! $OBJ/check-perm -m keys-command $KEY_COMMAND ; then + echo "skipping: $KEY_COMMAND is unsuitable as AuthorizedKeysCommand" + $SUDO rm -f $KEY_COMMAND + exit 0 +fi + if [ -x $KEY_COMMAND ]; then cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak diff --git a/regress/keyscan.sh b/regress/keyscan.sh index 886f3295ae7c..f97364b76e7d 100644 --- a/regress/keyscan.sh +++ b/regress/keyscan.sh @@ -1,4 +1,4 @@ -# $OpenBSD: keyscan.sh,v 1.4 2015/03/03 22:35:19 markus Exp $ +# $OpenBSD: keyscan.sh,v 1.5 2015/09/11 03:44:21 djm Exp $ # Placed in the Public Domain. tid="keyscan" @@ -8,7 +8,7 @@ rm -f ${OBJ}/host.dsa start_sshd -KEYTYPES="rsa dsa" +KEYTYPES=`${SSH} -Q key-plain` if ssh_version 1; then KEYTYPES="${KEYTYPES} rsa1" fi diff --git a/regress/limit-keytype.sh b/regress/limit-keytype.sh index 2de037bd1edb..c0cf2fed6d86 100755 --- a/regress/limit-keytype.sh +++ b/regress/limit-keytype.sh @@ -1,4 +1,4 @@ -# $OpenBSD: limit-keytype.sh,v 1.1 2015/01/13 07:49:49 djm Exp $ +# $OpenBSD: limit-keytype.sh,v 1.4 2015/10/29 08:05:17 djm Exp $ # Placed in the Public Domain. tid="restrict pubkey type" @@ -20,18 +20,19 @@ ${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 -N '' -t dsa -f $OBJ/user_key4 || \ + 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" +certopts="$opts -i $OBJ/user_key3 -oCertificateFile=$OBJ/cert_user_key3.pub" echo mekmitasdigoat > $OBJ/authorized_principals_$USER cat $OBJ/user_key1.pub > $OBJ/authorized_keys_$USER @@ -53,28 +54,44 @@ prepare_config() { prepare_config # Check we can log in with all key types. -${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" +${SSH} $certopts 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" +verbose "allow rsa,ed25519" prepare_config "PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519" -${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" +${SSH} $certopts 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" +verbose "allow ed25519" prepare_config "PubkeyAcceptedKeyTypes ssh-ed25519" -${SSH} $opts -i $OBJ/cert_user_key3 proxy true && fatal "cert succeeded" +${SSH} $certopts 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" +verbose "allow cert only" prepare_config "PubkeyAcceptedKeyTypes ssh-*-cert-v01@openssh.com" -${SSH} $opts -i $OBJ/cert_user_key3 proxy true || fatal "cert failed" +${SSH} $certopts 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" +# Allow RSA in main config, Ed25519 for non-existent user. +verbose "match w/ no match" +prepare_config "PubkeyAcceptedKeyTypes ssh-rsa" \ + "Match user x$USER" "PubkeyAcceptedKeyTypes +ssh-ed25519" +${SSH} $certopts proxy true && fatal "cert succeeded" +${SSH} $opts -i $OBJ/user_key1 proxy true && fatal "key1 succeeded" +${SSH} $opts -i $OBJ/user_key2 proxy true || fatal "key2 failed" + +# Allow only DSA in main config, Ed25519 for user. +verbose "match w/ matching" +prepare_config "PubkeyAcceptedKeyTypes ssh-dss" \ + "Match user $USER" "PubkeyAcceptedKeyTypes +ssh-ed25519" +${SSH} $certopts proxy true || fatal "cert failed" +${SSH} $opts -i $OBJ/user_key1 proxy true || fatal "key1 failed" +${SSH} $opts -i $OBJ/user_key4 proxy true && fatal "key4 succeeded" + diff --git a/regress/principals-command.sh b/regress/principals-command.sh index b90a8cf2cb44..c0be7e747761 100755 --- a/regress/principals-command.sh +++ b/regress/principals-command.sh @@ -24,6 +24,13 @@ _EOF test $? -eq 0 || fatal "couldn't prepare principals command" $SUDO chmod 0755 "$PRINCIPALS_CMD" +if ! $OBJ/check-perm -m keys-command $PRINCIPALS_CMD ; then + echo "skipping: $PRINCIPALS_CMD is unsuitable as " \ + "AuthorizedPrincipalsCommand" + $SUDO rm -f $PRINCIPALS_CMD + exit 0 +fi + # Create a CA key and a user certificate. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_ca_key || \ fatal "ssh-keygen of user_ca_key failed" diff --git a/regress/proxy-connect.sh b/regress/proxy-connect.sh index f816962b592a..b7a43fabe782 100644 --- a/regress/proxy-connect.sh +++ b/regress/proxy-connect.sh @@ -1,4 +1,4 @@ -# $OpenBSD: proxy-connect.sh,v 1.8 2015/03/03 22:35:19 markus Exp $ +# $OpenBSD: proxy-connect.sh,v 1.9 2016/02/17 02:24:17 djm Exp $ # Placed in the Public Domain. tid="proxy connect" @@ -18,7 +18,8 @@ for ps in no yes; do fail "ssh proxyconnect protocol $p privsep=$ps comp=$c failed" fi if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then - fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c" + fail "bad SSH_CONNECTION protocol $p privsep=$ps comp=$c: " \ + "$SSH_CONNECTION" fi done done diff --git a/regress/rekey.sh b/regress/rekey.sh index 0d4444d03fed..ae145bc8b92e 100644 --- a/regress/rekey.sh +++ b/regress/rekey.sh @@ -1,4 +1,4 @@ -# $OpenBSD: rekey.sh,v 1.16 2015/02/14 12:43:16 markus Exp $ +# $OpenBSD: rekey.sh,v 1.17 2016/01/29 05:18:15 dtucker Exp $ # Placed in the Public Domain. tid="rekey" @@ -137,13 +137,15 @@ for s in 5 10; do done verbose "rekeylimit parsing" -for size in 16 1k 1K 1m 1M 1g 1G; do +for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do case $size in 16) bytes=16 ;; 1k|1K) bytes=1024 ;; 1m|1M) bytes=1048576 ;; 1g|1G) bytes=1073741824 ;; + 4g|4G) bytes=4294967296 ;; + 8g|8G) bytes=8589934592 ;; esac case $time in 1) seconds=1 ;; diff --git a/regress/setuid-allowed.c b/regress/setuid-allowed.c index 676d2661c044..7a0527fd064c 100644 --- a/regress/setuid-allowed.c +++ b/regress/setuid-allowed.c @@ -26,7 +26,7 @@ #include #include -void +static void usage(void) { fprintf(stderr, "check-setuid [path]\n"); diff --git a/regress/sftp-chroot.sh b/regress/sftp-chroot.sh index 23f7456e8e61..9c26eb6807f0 100755 --- a/regress/sftp-chroot.sh +++ b/regress/sftp-chroot.sh @@ -12,6 +12,11 @@ if [ -z "$SUDO" ]; then exit 0 fi +if ! $OBJ/check-perm -m chroot "$CHROOT" ; then + echo "skipped: $CHROOT is unsuitable as ChrootDirectory" + exit 0 +fi + $SUDO sh -c "echo mekmitastdigoat > $PRIVDATA" || \ fatal "create $PRIVDATA failed" diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c index c8a2369373b4..906491f2bc31 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_file.c,v 1.4 2015/07/07 14:53:30 markus Exp $ */ +/* $OpenBSD: test_file.c,v 1.5 2015/10/06 01:20:59 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -54,8 +54,7 @@ sshkey_file_tests(void) #ifdef WITH_SSH1 TEST_START("parse RSA1 from private"); buf = load_file("rsa1_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa1_1", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("rsa1_1.param.n"); @@ -66,7 +65,7 @@ sshkey_file_tests(void) TEST_START("parse RSA1 from private w/ passphrase"); buf = load_file("rsa1_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "rsa1_1_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -104,8 +103,7 @@ sshkey_file_tests(void) TEST_START("parse RSA from private"); buf = load_file("rsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "rsa_1", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("rsa_1.param.n"); @@ -122,7 +120,7 @@ sshkey_file_tests(void) TEST_START("parse RSA from private w/ passphrase"); buf = load_file("rsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "rsa_1_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -131,8 +129,7 @@ sshkey_file_tests(void) TEST_START("parse RSA from new-format"); buf = load_file("rsa_n"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - "", "rsa_n", &k2, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -142,7 +139,7 @@ sshkey_file_tests(void) TEST_START("parse RSA from new-format w/ passphrase"); buf = load_file("rsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "rsa_n_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -197,8 +194,7 @@ sshkey_file_tests(void) TEST_START("parse DSA from private"); buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "dsa_1", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); a = load_bignum("dsa_1.param.g"); @@ -215,7 +211,7 @@ sshkey_file_tests(void) TEST_START("parse DSA from private w/ passphrase"); buf = load_file("dsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "dsa_1_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -224,8 +220,7 @@ sshkey_file_tests(void) TEST_START("parse DSA from new-format"); buf = load_file("dsa_n"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - "", "dsa_n", &k2, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -235,7 +230,7 @@ sshkey_file_tests(void) TEST_START("parse DSA from new-format w/ passphrase"); buf = load_file("dsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "dsa_n_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -291,8 +286,7 @@ sshkey_file_tests(void) #ifdef OPENSSL_HAS_ECC TEST_START("parse ECDSA from private"); buf = load_file("ecdsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ecdsa_1", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); buf = load_text_file("ecdsa_1.param.curve"); @@ -315,7 +309,7 @@ sshkey_file_tests(void) TEST_START("parse ECDSA from private w/ passphrase"); buf = load_file("ecdsa_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "ecdsa_1_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -324,8 +318,7 @@ sshkey_file_tests(void) TEST_START("parse ECDSA from new-format"); buf = load_file("ecdsa_n"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - "", "ecdsa_n", &k2, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -335,7 +328,7 @@ sshkey_file_tests(void) TEST_START("parse ECDSA from new-format w/ passphrase"); buf = load_file("ecdsa_n_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "ecdsa_n_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); @@ -391,8 +384,7 @@ sshkey_file_tests(void) TEST_START("parse Ed25519 from private"); buf = load_file("ed25519_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "ed25519_1", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k1, NULL); ASSERT_INT_EQ(k1->type, KEY_ED25519); @@ -402,7 +394,7 @@ sshkey_file_tests(void) TEST_START("parse Ed25519 from private w/ passphrase"); buf = load_file("ed25519_1_pw"); ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, - (const char *)sshbuf_ptr(pw), "ed25519_1_pw", &k2, NULL), 0); + (const char *)sshbuf_ptr(pw), &k2, NULL), 0); sshbuf_free(buf); ASSERT_PTR_NE(k2, NULL); ASSERT_INT_EQ(sshkey_equal(k1, k2), 1); diff --git a/regress/unittests/sshkey/test_fuzz.c b/regress/unittests/sshkey/test_fuzz.c index 1f08a2e432bb..1f414e0acaa2 100644 --- a/regress/unittests/sshkey/test_fuzz.c +++ b/regress/unittests/sshkey/test_fuzz.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_fuzz.c,v 1.4 2015/03/04 23:22:35 djm Exp $ */ +/* $OpenBSD: test_fuzz.c,v 1.6 2015/12/07 02:20:46 djm Exp $ */ /* * Fuzz tests for key parsing * @@ -72,13 +72,13 @@ public_fuzz(struct sshkey *k) } static void -sig_fuzz(struct sshkey *k) +sig_fuzz(struct sshkey *k, const char *sig_alg) { struct fuzz *fuzz; u_char *sig, c[] = "some junk to be signed"; size_t l; - ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), 0), 0); + ASSERT_INT_EQ(sshkey_sign(k, &sig, &l, c, sizeof(c), sig_alg, 0), 0); ASSERT_SIZE_T_GT(l, 0); fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | /* too slow FUZZ_2_BIT_FLIP | */ FUZZ_1_BYTE_FLIP | FUZZ_2_BYTE_FLIP | @@ -110,8 +110,7 @@ sshkey_fuzz_tests(void) fuzz = fuzz_begin(FUZZ_1_BIT_FLIP | FUZZ_1_BYTE_FLIP | FUZZ_TRUNCATE_START | FUZZ_TRUNCATE_END, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -119,8 +118,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -154,8 +152,7 @@ sshkey_fuzz_tests(void) buf = load_file("rsa_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -163,8 +160,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -176,8 +172,7 @@ sshkey_fuzz_tests(void) buf = load_file("rsa_n"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -185,8 +180,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -198,8 +192,7 @@ sshkey_fuzz_tests(void) buf = load_file("dsa_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -207,8 +200,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -220,8 +212,7 @@ sshkey_fuzz_tests(void) buf = load_file("dsa_n"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -229,8 +220,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -243,8 +233,7 @@ sshkey_fuzz_tests(void) buf = load_file("ecdsa_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -252,8 +241,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -265,8 +253,7 @@ sshkey_fuzz_tests(void) buf = load_file("ecdsa_n"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -274,8 +261,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -288,8 +274,7 @@ sshkey_fuzz_tests(void) buf = load_file("ed25519_1"); fuzz = fuzz_begin(FUZZ_BASE64, sshbuf_mutable_ptr(buf), sshbuf_len(buf)); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshkey_free(k1); sshbuf_free(buf); ASSERT_PTR_NE(fuzzed = sshbuf_new(), NULL); @@ -297,8 +282,7 @@ sshkey_fuzz_tests(void) for(; !fuzz_done(fuzz); fuzz_next(fuzz)) { r = sshbuf_put(fuzzed, fuzz_ptr(fuzz), fuzz_len(fuzz)); ASSERT_INT_EQ(r, 0); - if (sshkey_parse_private_fileblob(fuzzed, "", "key", - &k1, NULL) == 0) + if (sshkey_parse_private_fileblob(fuzzed, "", &k1, NULL) == 0) sshkey_free(k1); sshbuf_reset(fuzzed); } @@ -308,8 +292,7 @@ sshkey_fuzz_tests(void) TEST_START("fuzz RSA public"); buf = load_file("rsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); @@ -323,8 +306,7 @@ sshkey_fuzz_tests(void) TEST_START("fuzz DSA public"); buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); @@ -339,8 +321,7 @@ sshkey_fuzz_tests(void) #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA public"); buf = load_file("ecdsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); @@ -355,8 +336,7 @@ sshkey_fuzz_tests(void) TEST_START("fuzz Ed25519 public"); buf = load_file("ed25519_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); public_fuzz(k1); sshkey_free(k1); @@ -370,39 +350,51 @@ sshkey_fuzz_tests(void) TEST_START("fuzz RSA sig"); buf = load_file("rsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); - sig_fuzz(k1); + sig_fuzz(k1, "ssh-rsa"); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz RSA SHA256 sig"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1, "rsa-sha2-256"); + sshkey_free(k1); + TEST_DONE(); + + TEST_START("fuzz RSA SHA512 sig"); + buf = load_file("rsa_1"); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); + sshbuf_free(buf); + sig_fuzz(k1, "rsa-sha2-512"); sshkey_free(k1); TEST_DONE(); TEST_START("fuzz DSA sig"); buf = load_file("dsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); - sig_fuzz(k1); + sig_fuzz(k1, NULL); sshkey_free(k1); TEST_DONE(); #ifdef OPENSSL_HAS_ECC TEST_START("fuzz ECDSA sig"); buf = load_file("ecdsa_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); - sig_fuzz(k1); + sig_fuzz(k1, NULL); sshkey_free(k1); TEST_DONE(); #endif TEST_START("fuzz Ed25519 sig"); buf = load_file("ed25519_1"); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", "key", - &k1, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(buf, "", &k1, NULL), 0); sshbuf_free(buf); - sig_fuzz(k1); + sig_fuzz(k1, NULL); sshkey_free(k1); TEST_DONE(); diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c index 9b3ce7ee43bb..1f160d1a7917 100644 --- a/regress/unittests/sshkey/test_sshkey.c +++ b/regress/unittests/sshkey/test_sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshkey.c,v 1.7 2015/08/05 05:27:33 djm Exp $ */ +/* $OpenBSD: test_sshkey.c,v 1.9 2015/12/07 02:20:46 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -52,7 +52,8 @@ put_opt(struct sshbuf *b, const char *name, const char *value) static void build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, - const struct sshkey *sign_key, const struct sshkey *ca_key) + const struct sshkey *sign_key, const struct sshkey *ca_key, + const char *sig_alg) { struct sshbuf *ca_buf, *pk, *principals, *critopts, *exts; u_char *sigblob; @@ -99,7 +100,7 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, ASSERT_INT_EQ(sshbuf_put_string(b, NULL, 0), 0); /* reserved */ ASSERT_INT_EQ(sshbuf_put_stringb(b, ca_buf), 0); /* signature key */ ASSERT_INT_EQ(sshkey_sign(sign_key, &sigblob, &siglen, - sshbuf_ptr(b), sshbuf_len(b), 0), 0); + sshbuf_ptr(b), sshbuf_len(b), sig_alg, 0), 0); ASSERT_INT_EQ(sshbuf_put_string(b, sigblob, siglen), 0); /* signature */ free(sigblob); @@ -111,12 +112,13 @@ build_cert(struct sshbuf *b, const struct sshkey *k, const char *type, } static void -signature_test(struct sshkey *k, struct sshkey *bad, const u_char *d, size_t l) +signature_test(struct sshkey *k, struct sshkey *bad, const char *sig_alg, + 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_INT_EQ(sshkey_sign(k, &sig, &len, d, l, sig_alg, 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); @@ -143,7 +145,7 @@ banana(u_char *s, size_t l) } static void -signature_tests(struct sshkey *k, struct sshkey *bad) +signature_tests(struct sshkey *k, struct sshkey *bad, const char *sig_alg) { u_char i, buf[2049]; size_t lens[] = { @@ -155,7 +157,7 @@ signature_tests(struct sshkey *k, struct sshkey *bad) test_subtest_info("%s key, banana length %zu", sshkey_type(k), lens[i]); banana(buf, lens[i]); - signature_test(k, bad, buf, lens[i]); + signature_test(k, bad, sig_alg, buf, lens[i]); } } @@ -166,7 +168,7 @@ get_private(const char *n) struct sshkey *ret; b = load_file(n); - ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", n, &ret, NULL), 0); + ASSERT_INT_EQ(sshkey_parse_private_fileblob(b, "", &ret, NULL), 0); sshbuf_free(b); return ret; } @@ -469,7 +471,25 @@ sshkey_tests(void) k1 = get_private("rsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, NULL), 0); - signature_tests(k1, k2); + signature_tests(k1, k2, "ssh-rsa"); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("sign and verify RSA-SHA256"); + k1 = get_private("rsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2, "rsa-sha2-256"); + sshkey_free(k1); + sshkey_free(k2); + TEST_DONE(); + + TEST_START("sign and verify RSA-SHA512"); + k1 = get_private("rsa_1"); + ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_2.pub"), &k2, + NULL), 0); + signature_tests(k1, k2, "rsa-sha2-512"); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); @@ -478,7 +498,7 @@ sshkey_tests(void) k1 = get_private("dsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("dsa_2.pub"), &k2, NULL), 0); - signature_tests(k1, k2); + signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); @@ -488,7 +508,7 @@ sshkey_tests(void) k1 = get_private("ecdsa_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ecdsa_2.pub"), &k2, NULL), 0); - signature_tests(k1, k2); + signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); @@ -498,7 +518,7 @@ sshkey_tests(void) k1 = get_private("ed25519_1"); ASSERT_INT_EQ(sshkey_load_public(test_data_file("ed25519_2.pub"), &k2, NULL), 0); - signature_tests(k1, k2); + signature_tests(k1, k2, NULL); sshkey_free(k1); sshkey_free(k2); TEST_DONE(); @@ -508,7 +528,7 @@ sshkey_tests(void) ASSERT_INT_EQ(sshkey_load_public(test_data_file("rsa_1.pub"), &k2, NULL), 0); k3 = get_private("rsa_1"); - build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1); + build_cert(b, k2, "ssh-rsa-cert-v01@openssh.com", k3, k1, NULL); 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); diff --git a/roaming.h b/roaming.h index da069f878736..e69de29bb2d1 100644 --- a/roaming.h +++ b/roaming.h @@ -1,45 +0,0 @@ -/* $OpenBSD: roaming.h,v 1.6 2011/12/07 05:44:38 djm Exp $ */ -/* - * Copyright (c) 2004-2009 AppGate Network Security AB - * - * 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 ROAMING_H -#define ROAMING_H - -#define DEFAULT_ROAMBUF 65536 -#define MAX_ROAMBUF (2*1024*1024) /* XXX arbitrary */ -#define ROAMING_REQUEST "roaming@appgate.com" - -extern int roaming_enabled; -extern int resume_in_progress; - -void request_roaming(void); -int get_snd_buf_size(void); -int get_recv_buf_size(void); -void add_recv_bytes(u_int64_t); -int wait_for_roaming_reconnect(void); -void roaming_reply(int, u_int32_t, void *); -void set_out_buffer_size(size_t); -ssize_t roaming_write(int, const void *, size_t, int *); -ssize_t roaming_read(int, void *, size_t, int *); -size_t roaming_atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); -u_int64_t get_recv_bytes(void); -u_int64_t get_sent_bytes(void); -void roam_set_bytes(u_int64_t, u_int64_t); -void resend_bytes(int, u_int64_t *); -void calculate_new_key(u_int64_t *, u_int64_t, u_int64_t); -int resume_kex(void); - -#endif /* ROAMING */ diff --git a/roaming_client.c b/roaming_client.c deleted file mode 100644 index cb1328574140..000000000000 --- a/roaming_client.c +++ /dev/null @@ -1,271 +0,0 @@ -/* $OpenBSD: roaming_client.c,v 1.9 2015/01/27 12:54:06 okan Exp $ */ -/* - * Copyright (c) 2004-2009 AppGate Network Security AB - * - * 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 "openbsd-compat/sys-queue.h" -#include -#include - -#include -#include -#include - -#include "xmalloc.h" -#include "buffer.h" -#include "channels.h" -#include "cipher.h" -#include "dispatch.h" -#include "clientloop.h" -#include "log.h" -#include "match.h" -#include "misc.h" -#include "packet.h" -#include "ssh.h" -#include "key.h" -#include "kex.h" -#include "readconf.h" -#include "roaming.h" -#include "ssh2.h" -#include "sshconnect.h" -#include "digest.h" - -/* import */ -extern Options options; -extern char *host; -extern struct sockaddr_storage hostaddr; -extern int session_resumed; - -static u_int32_t roaming_id; -static u_int64_t cookie; -static u_int64_t lastseenchall; -static u_int64_t key1, key2, oldkey1, oldkey2; - -void -roaming_reply(int type, u_int32_t seq, void *ctxt) -{ - if (type == SSH2_MSG_REQUEST_FAILURE) { - logit("Server denied roaming"); - return; - } - verbose("Roaming enabled"); - roaming_id = packet_get_int(); - cookie = packet_get_int64(); - key1 = oldkey1 = packet_get_int64(); - key2 = oldkey2 = packet_get_int64(); - set_out_buffer_size(packet_get_int() + get_snd_buf_size()); - roaming_enabled = 1; -} - -void -request_roaming(void) -{ - packet_start(SSH2_MSG_GLOBAL_REQUEST); - packet_put_cstring(ROAMING_REQUEST); - packet_put_char(1); - packet_put_int(get_recv_buf_size()); - packet_send(); - client_register_global_confirm(roaming_reply, NULL); -} - -static void -roaming_auth_required(void) -{ - u_char digest[SSH_DIGEST_MAX_LENGTH]; - Buffer b; - u_int64_t chall, oldchall; - - chall = packet_get_int64(); - oldchall = packet_get_int64(); - if (oldchall != lastseenchall) { - key1 = oldkey1; - key2 = oldkey2; - } - lastseenchall = chall; - - buffer_init(&b); - buffer_put_int64(&b, cookie); - buffer_put_int64(&b, chall); - if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, digest, sizeof(digest)) != 0) - fatal("%s: ssh_digest_buffer failed", __func__); - buffer_free(&b); - - packet_start(SSH2_MSG_KEX_ROAMING_AUTH); - packet_put_int64(key1 ^ get_recv_bytes()); - packet_put_raw(digest, ssh_digest_bytes(SSH_DIGEST_SHA1)); - packet_send(); - - oldkey1 = key1; - oldkey2 = key2; - calculate_new_key(&key1, cookie, chall); - calculate_new_key(&key2, cookie, chall); - - debug("Received %llu bytes", (unsigned long long)get_recv_bytes()); - debug("Sent roaming_auth packet"); -} - -int -resume_kex(void) -{ - /* - * This should not happen - if the client sends the kex method - * resume@appgate.com then the kex is done in roaming_resume(). - */ - return 1; -} - -static int -roaming_resume(void) -{ - u_int64_t recv_bytes; - char *str = NULL, *kexlist = NULL, *c; - int i, type; - int timeout_ms = options.connection_timeout * 1000; - u_int len; - u_int32_t rnd = 0; - - resume_in_progress = 1; - - /* Exchange banners */ - ssh_exchange_identification(timeout_ms); - packet_set_nonblocking(); - - /* Send a kexinit message with resume@appgate.com as only kex algo */ - packet_start(SSH2_MSG_KEXINIT); - for (i = 0; i < KEX_COOKIE_LEN; i++) { - if (i % 4 == 0) - rnd = arc4random(); - packet_put_char(rnd & 0xff); - rnd >>= 8; - } - packet_put_cstring(KEX_RESUME); - for (i = 1; i < PROPOSAL_MAX; i++) { - /* kex algorithm added so start with i=1 and not 0 */ - packet_put_cstring(""); /* Not used when we resume */ - } - packet_put_char(1); /* first kex_packet follows */ - packet_put_int(0); /* reserved */ - packet_send(); - - /* Assume that resume@appgate.com will be accepted */ - packet_start(SSH2_MSG_KEX_ROAMING_RESUME); - packet_put_int(roaming_id); - packet_send(); - - /* Read the server's kexinit and check for resume@appgate.com */ - if ((type = packet_read()) != SSH2_MSG_KEXINIT) { - debug("expected kexinit on resume, got %d", type); - goto fail; - } - for (i = 0; i < KEX_COOKIE_LEN; i++) - (void)packet_get_char(); - kexlist = packet_get_string(&len); - if (!kexlist - || (str = match_list(KEX_RESUME, kexlist, NULL)) == NULL) { - debug("server doesn't allow resume"); - goto fail; - } - free(str); - for (i = 1; i < PROPOSAL_MAX; i++) { - /* kex algorithm taken care of so start with i=1 and not 0 */ - free(packet_get_string(&len)); - } - i = packet_get_char(); /* first_kex_packet_follows */ - if (i && (c = strchr(kexlist, ','))) - *c = 0; - if (i && strcmp(kexlist, KEX_RESUME)) { - debug("server's kex guess (%s) was wrong, skipping", kexlist); - (void)packet_read(); /* Wrong guess - discard packet */ - } - - /* - * Read the ROAMING_AUTH_REQUIRED challenge from the server and - * send ROAMING_AUTH - */ - if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED) { - debug("expected roaming_auth_required, got %d", type); - goto fail; - } - roaming_auth_required(); - - /* Read ROAMING_AUTH_OK from the server */ - if ((type = packet_read()) != SSH2_MSG_KEX_ROAMING_AUTH_OK) { - debug("expected roaming_auth_ok, got %d", type); - goto fail; - } - recv_bytes = packet_get_int64() ^ oldkey2; - debug("Peer received %llu bytes", (unsigned long long)recv_bytes); - resend_bytes(packet_get_connection_out(), &recv_bytes); - - resume_in_progress = 0; - - session_resumed = 1; /* Tell clientloop */ - - return 0; - -fail: - free(kexlist); - if (packet_get_connection_in() == packet_get_connection_out()) - close(packet_get_connection_in()); - else { - close(packet_get_connection_in()); - close(packet_get_connection_out()); - } - return 1; -} - -int -wait_for_roaming_reconnect(void) -{ - static int reenter_guard = 0; - int timeout_ms = options.connection_timeout * 1000; - int c; - - if (reenter_guard != 0) - fatal("Server refused resume, roaming timeout may be exceeded"); - reenter_guard = 1; - - fprintf(stderr, "[connection suspended, press return to resume]"); - fflush(stderr); - packet_backup_state(); - /* TODO Perhaps we should read from tty here */ - while ((c = fgetc(stdin)) != EOF) { - if (c == 'Z' - 64) { - kill(getpid(), SIGTSTP); - continue; - } - if (c != '\n' && c != '\r') - continue; - - if (ssh_connect(host, NULL, &hostaddr, options.port, - options.address_family, 1, &timeout_ms, - options.tcp_keep_alive, options.use_privileged_port) == 0 && - roaming_resume() == 0) { - packet_restore_state(); - reenter_guard = 0; - fprintf(stderr, "[connection resumed]\n"); - fflush(stderr); - return 0; - } - - fprintf(stderr, "[reconnect failed, press return to retry]"); - fflush(stderr); - } - fprintf(stderr, "[exiting]\n"); - fflush(stderr); - exit(0); -} diff --git a/roaming_common.c b/roaming_common.c deleted file mode 100644 index ea064605cec4..000000000000 --- a/roaming_common.c +++ /dev/null @@ -1,241 +0,0 @@ -/* $OpenBSD: roaming_common.c,v 1.13 2015/01/27 12:54:06 okan Exp $ */ -/* - * Copyright (c) 2004-2009 AppGate Network Security AB - * - * 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 -#include -#include -#include - -#include "atomicio.h" -#include "log.h" -#include "packet.h" -#include "xmalloc.h" -#include "cipher.h" -#include "buffer.h" -#include "roaming.h" -#include "digest.h" - -static size_t out_buf_size = 0; -static char *out_buf = NULL; -static size_t out_start; -static size_t out_last; - -static u_int64_t write_bytes = 0; -static u_int64_t read_bytes = 0; - -int roaming_enabled = 0; -int resume_in_progress = 0; - -int -get_snd_buf_size(void) -{ - int fd = packet_get_connection_out(); - int optval; - socklen_t optvallen = sizeof(optval); - - if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0) - optval = DEFAULT_ROAMBUF; - return optval; -} - -int -get_recv_buf_size(void) -{ - int fd = packet_get_connection_in(); - int optval; - socklen_t optvallen = sizeof(optval); - - if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0) - optval = DEFAULT_ROAMBUF; - return optval; -} - -void -set_out_buffer_size(size_t size) -{ - if (size == 0 || size > MAX_ROAMBUF) - fatal("%s: bad buffer size %lu", __func__, (u_long)size); - /* - * The buffer size can only be set once and the buffer will live - * as long as the session lives. - */ - if (out_buf == NULL) { - out_buf_size = size; - out_buf = xmalloc(size); - out_start = 0; - out_last = 0; - } -} - -u_int64_t -get_recv_bytes(void) -{ - return read_bytes; -} - -void -add_recv_bytes(u_int64_t num) -{ - read_bytes += num; -} - -u_int64_t -get_sent_bytes(void) -{ - return write_bytes; -} - -void -roam_set_bytes(u_int64_t sent, u_int64_t recvd) -{ - read_bytes = recvd; - write_bytes = sent; -} - -static void -buf_append(const char *buf, size_t count) -{ - if (count > out_buf_size) { - buf += count - out_buf_size; - count = out_buf_size; - } - if (count < out_buf_size - out_last) { - memcpy(out_buf + out_last, buf, count); - if (out_start > out_last) - out_start += count; - out_last += count; - } else { - /* data will wrap */ - size_t chunk = out_buf_size - out_last; - memcpy(out_buf + out_last, buf, chunk); - memcpy(out_buf, buf + chunk, count - chunk); - out_last = count - chunk; - out_start = out_last + 1; - } -} - -ssize_t -roaming_write(int fd, const void *buf, size_t count, int *cont) -{ - ssize_t ret; - - ret = write(fd, buf, count); - if (ret > 0 && !resume_in_progress) { - write_bytes += ret; - if (out_buf_size > 0) - buf_append(buf, ret); - } - if (out_buf_size > 0 && - (ret == 0 || (ret == -1 && errno == EPIPE))) { - if (wait_for_roaming_reconnect() != 0) { - ret = 0; - *cont = 1; - } else { - ret = -1; - errno = EAGAIN; - } - } - return ret; -} - -ssize_t -roaming_read(int fd, void *buf, size_t count, int *cont) -{ - ssize_t ret = read(fd, buf, count); - if (ret > 0) { - if (!resume_in_progress) { - read_bytes += ret; - } - } else if (out_buf_size > 0 && - (ret == 0 || (ret == -1 && (errno == ECONNRESET - || errno == ECONNABORTED || errno == ETIMEDOUT - || errno == EHOSTUNREACH)))) { - debug("roaming_read failed for %d ret=%ld errno=%d", - fd, (long)ret, errno); - ret = 0; - if (wait_for_roaming_reconnect() == 0) - *cont = 1; - } - return ret; -} - -size_t -roaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf, - size_t count) -{ - size_t ret = atomicio(f, fd, buf, count); - - if (f == vwrite && ret > 0 && !resume_in_progress) { - write_bytes += ret; - } else if (f == read && ret > 0 && !resume_in_progress) { - read_bytes += ret; - } - return ret; -} - -void -resend_bytes(int fd, u_int64_t *offset) -{ - size_t available, needed; - - if (out_start < out_last) - available = out_last - out_start; - else - available = out_buf_size; - needed = write_bytes - *offset; - debug3("resend_bytes: resend %lu bytes from %llu", - (unsigned long)needed, (unsigned long long)*offset); - if (needed > available) - fatal("Needed to resend more data than in the cache"); - if (out_last < needed) { - int chunkend = needed - out_last; - atomicio(vwrite, fd, out_buf + out_buf_size - chunkend, - chunkend); - atomicio(vwrite, fd, out_buf, out_last); - } else { - atomicio(vwrite, fd, out_buf + (out_last - needed), needed); - } -} - -/* - * Caclulate a new key after a reconnect - */ -void -calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) -{ - u_char hash[SSH_DIGEST_MAX_LENGTH]; - Buffer b; - - buffer_init(&b); - buffer_put_int64(&b, *key); - buffer_put_int64(&b, cookie); - buffer_put_int64(&b, challenge); - - if (ssh_digest_buffer(SSH_DIGEST_SHA1, &b, hash, sizeof(hash)) != 0) - fatal("%s: digest_buffer failed", __func__); - - buffer_clear(&b); - buffer_append(&b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1)); - *key = buffer_get_int64(&b); - buffer_free(&b); -} diff --git a/roaming_dummy.c b/roaming_dummy.c deleted file mode 100644 index 837de695ddf1..000000000000 --- a/roaming_dummy.c +++ /dev/null @@ -1,72 +0,0 @@ -/* $OpenBSD: roaming_dummy.c,v 1.4 2015/01/19 19:52:16 markus Exp $ */ -/* - * Copyright (c) 2004-2009 AppGate Network Security AB - * - * 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. - */ - -/* - * This file is included in the client programs which should not - * support roaming. - */ - -#include "includes.h" - -#include -#include - -#include "roaming.h" - -int resume_in_progress = 0; - -u_int64_t -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) -{ - return write(fd, buf, count); -} - -ssize_t -roaming_read(int fd, void *buf, size_t count, int *cont) -{ - if (cont) - *cont = 0; - return read(fd, buf, count); -} - -void -add_recv_bytes(u_int64_t num) -{ -} - -int -resume_kex(void) -{ - return 1; -} diff --git a/roaming_serv.c b/roaming_serv.c deleted file mode 100644 index 511ca846101b..000000000000 --- a/roaming_serv.c +++ /dev/null @@ -1,31 +0,0 @@ -/* $OpenBSD: roaming_serv.c,v 1.1 2009/10/24 11:18:23 andreas Exp $ */ -/* - * Copyright (c) 2004-2009 AppGate Network Security AB - * - * 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 "roaming.h" - -/* - * Wait for the roaming client to reconnect. Returns 0 if a connect ocurred. - */ -int -wait_for_roaming_reconnect(void) -{ - return 1; -} diff --git a/sandbox-pledge.c b/sandbox-pledge.c new file mode 100644 index 000000000000..d28fc27274e2 --- /dev/null +++ b/sandbox-pledge.c @@ -0,0 +1,77 @@ +/* $OpenBSD: sandbox-pledge.c,v 1.1 2015/10/09 01:37:08 deraadt Exp $ */ +/* + * Copyright (c) 2015 Theo de Raadt + * + * 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" + +#ifdef SANDBOX_PLEDGE + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +struct ssh_sandbox { + pid_t child_pid; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *m) +{ + struct ssh_sandbox *box; + + debug3("%s: preparing pledge sandbox", __func__); + box = xcalloc(1, sizeof(*box)); + box->child_pid = 0; + + return box; +} + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + if (pledge("stdio", NULL) == -1) + fatal("%s: pledge()", __func__); +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + free(box); + debug3("%s: finished", __func__); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + box->child_pid = child_pid; + /* Nothing to do here */ +} + +#endif /* SANDBOX_PLEDGE */ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index 2462bcc88f32..d132e26460de 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c @@ -147,6 +147,9 @@ static const struct sock_filter preauth_insns[] = { #ifdef __NR_getpid SC_ALLOW(getpid), #endif +#ifdef __NR_getrandom + SC_ALLOW(getrandom), +#endif #ifdef __NR_gettimeofday SC_ALLOW(gettimeofday), #endif diff --git a/sandbox-solaris.c b/sandbox-solaris.c new file mode 100644 index 000000000000..343a01022850 --- /dev/null +++ b/sandbox-solaris.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015 Joyent, Inc + * Author: Alex Wilson + * + * 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" + +#ifdef SANDBOX_SOLARIS +#ifndef USE_SOLARIS_PRIVS +# error "--with-solaris-privs must be used with the Solaris sandbox" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_PRIV_H +# include +#endif + +#include "log.h" +#include "ssh-sandbox.h" +#include "xmalloc.h" + +struct ssh_sandbox { + priv_set_t *pset; +}; + +struct ssh_sandbox * +ssh_sandbox_init(struct monitor *monitor) +{ + struct ssh_sandbox *box = NULL; + + box = xcalloc(1, sizeof(*box)); + + /* Start with "basic" and drop everything we don't need. */ + box->pset = solaris_basic_privset(); + + if (box->pset == NULL) { + free(box); + return NULL; + } + + /* Drop everything except the ability to use already-opened files */ + if (priv_delset(box->pset, PRIV_FILE_LINK_ANY) != 0 || +#ifdef PRIV_NET_ACCESS + priv_delset(box->pset, PRIV_NET_ACCESS) != 0 || +#endif + priv_delset(box->pset, PRIV_PROC_EXEC) != 0 || + priv_delset(box->pset, PRIV_PROC_FORK) != 0 || + priv_delset(box->pset, PRIV_PROC_INFO) != 0 || + priv_delset(box->pset, PRIV_PROC_SESSION) != 0) { + free(box); + return NULL; + } + + /* These may not be available on older Solaris-es */ +# if defined(PRIV_FILE_READ) && defined(PRIV_FILE_WRITE) + if (priv_delset(box->pset, PRIV_FILE_READ) != 0 || + priv_delset(box->pset, PRIV_FILE_WRITE) != 0) { + free(box); + return NULL; + } +# endif + + return box; +} + +void +ssh_sandbox_child(struct ssh_sandbox *box) +{ + if (setppriv(PRIV_SET, PRIV_PERMITTED, box->pset) != 0 || + setppriv(PRIV_SET, PRIV_LIMIT, box->pset) != 0 || + setppriv(PRIV_SET, PRIV_INHERITABLE, box->pset) != 0) + fatal("setppriv: %s", strerror(errno)); +} + +void +ssh_sandbox_parent_finish(struct ssh_sandbox *box) +{ + priv_freeset(box->pset); + box->pset = NULL; + free(box); +} + +void +ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) +{ + /* Nothing to do here */ +} + +#endif /* SANDBOX_SOLARIS */ diff --git a/sandbox-systrace.c b/sandbox-systrace.c index 3830ed16c63e..b4d8d04cae3a 100644 --- a/sandbox-systrace.c +++ b/sandbox-systrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sandbox-systrace.c,v 1.17 2015/07/27 16:29:23 guenther Exp $ */ +/* $OpenBSD: sandbox-systrace.c,v 1.18 2015/10/02 01:39:26 deraadt Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -50,9 +50,17 @@ struct sandbox_policy { /* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ static const struct sandbox_policy preauth_policy[] = { - { SYS_clock_gettime, SYSTR_POLICY_PERMIT }, - { SYS_close, SYSTR_POLICY_PERMIT }, { SYS_exit, SYSTR_POLICY_PERMIT }, +#ifdef SYS_kbind + { SYS_kbind, SYSTR_POLICY_PERMIT }, +#endif + + { SYS_getpid, SYSTR_POLICY_PERMIT }, + { SYS_getpgid, SYSTR_POLICY_PERMIT }, + { SYS_clock_gettime, SYSTR_POLICY_PERMIT }, + { SYS_gettimeofday, SYSTR_POLICY_PERMIT }, + { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, + #ifdef SYS_getentropy /* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */ { SYS_getentropy, SYSTR_POLICY_PERMIT }, @@ -60,27 +68,25 @@ static const struct sandbox_policy preauth_policy[] = { /* Previous releases used sysctl(3)'s kern.arnd variable. */ { SYS___sysctl, SYSTR_POLICY_PERMIT }, #endif - { SYS_getpid, SYSTR_POLICY_PERMIT }, - { SYS_getpgid, SYSTR_POLICY_PERMIT }, - { SYS_gettimeofday, SYSTR_POLICY_PERMIT }, -#ifdef SYS_kbind - { SYS_kbind, SYSTR_POLICY_PERMIT }, +#ifdef SYS_sendsyslog + { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, #endif + { SYS_madvise, SYSTR_POLICY_PERMIT }, { SYS_mmap, SYSTR_POLICY_PERMIT }, { SYS_mprotect, SYSTR_POLICY_PERMIT }, { SYS_mquery, SYSTR_POLICY_PERMIT }, { SYS_munmap, SYSTR_POLICY_PERMIT }, - { SYS_open, SYSTR_POLICY_NEVER }, + { SYS_poll, SYSTR_POLICY_PERMIT }, - { SYS_read, SYSTR_POLICY_PERMIT }, { SYS_select, SYSTR_POLICY_PERMIT }, -#ifdef SYS_sendsyslog - { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, -#endif - { SYS_shutdown, SYSTR_POLICY_PERMIT }, - { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, + { SYS_read, SYSTR_POLICY_PERMIT }, { SYS_write, SYSTR_POLICY_PERMIT }, + { SYS_shutdown, SYSTR_POLICY_PERMIT }, + { SYS_close, SYSTR_POLICY_PERMIT }, + + { SYS_open, SYSTR_POLICY_NEVER }, + { -1, -1 } }; diff --git a/scp.0 b/scp.0 index 8f41f6140404..6b70e4ed41c8 100644 --- a/scp.0 +++ b/scp.0 @@ -72,6 +72,7 @@ DESCRIPTION CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs + CertificateFile ChallengeResponseAuthentication CheckHostIP Cipher @@ -162,4 +163,4 @@ AUTHORS Timo Rinne Tatu Ylonen -OpenBSD 5.8 July 10, 2015 OpenBSD 5.8 +OpenBSD 5.9 September 25, 2015 OpenBSD 5.9 diff --git a/scp.1 b/scp.1 index 279b0d70b7be..54ea352ce1ae 100644 --- a/scp.1 +++ b/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.67 2015/07/10 06:21:53 markus Exp $ +.\" $OpenBSD: scp.1,v 1.68 2015/09/25 18:19:54 jmc Exp $ .\" -.Dd $Mdocdate: July 10 2015 $ +.Dd $Mdocdate: September 25 2015 $ .Dt SCP 1 .Os .Sh NAME @@ -133,6 +133,7 @@ For full details of the options listed below, and their possible values, see .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs +.It CertificateFile .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher diff --git a/scp.c b/scp.c index 593fe89bded2..0bdd7cb0b29d 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.182 2015/04/24 01:36:00 deraadt Exp $ */ +/* $OpenBSD: scp.c,v 1.184 2015/11/27 00:49:31 deraadt Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -484,6 +484,16 @@ main(int argc, char **argv) if (!isatty(STDOUT_FILENO)) showprogress = 0; + if (pflag) { + /* Cannot pledge: -p allows setuid/setgid files... */ + } else { + if (pledge("stdio rpath wpath cpath fattr tty proc exec", + NULL) == -1) { + perror("pledge"); + exit(1); + } + } + remin = STDIN_FILENO; remout = STDOUT_FILENO; @@ -866,7 +876,7 @@ rsource(char *name, struct stat *statp) return; } last = strrchr(name, '/'); - if (last == 0) + if (last == NULL) last = name; else last++; diff --git a/servconf.c b/servconf.c index 6c7a91e6b22f..b19d30e18303 100644 --- a/servconf.c +++ b/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.280 2015/08/06 14:53:21 deraadt Exp $ */ +/* $OpenBSD: servconf.c,v 1.285 2016/02/17 05:29:04 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -178,6 +178,20 @@ option_clear_or_none(const char *o) return o == NULL || strcasecmp(o, "none") == 0; } +static void +assemble_algorithms(ServerOptions *o) +{ + if (kex_assemble_names(KEX_SERVER_ENCRYPT, &o->ciphers) != 0 || + kex_assemble_names(KEX_SERVER_MAC, &o->macs) != 0 || + kex_assemble_names(KEX_SERVER_KEX, &o->kex_algorithms) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, + &o->hostkeyalgorithms) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, + &o->hostbased_key_types) != 0 || + kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->pubkey_key_types) != 0) + fatal("kex_assemble_names failed"); +} + void fill_default_server_options(ServerOptions *options) { @@ -259,8 +273,6 @@ 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->hostkeyalgorithms == NULL) - options->hostkeyalgorithms = xstrdup(KEX_DEFAULT_PK_ALG); if (options->rsa_authentication == -1) options->rsa_authentication = 1; if (options->pubkey_authentication == -1) @@ -342,18 +354,11 @@ fill_default_server_options(ServerOptions *options) if (options->fingerprint_hash == -1) options->fingerprint_hash = SSH_FP_HASH_DEFAULT; - if (kex_assemble_names(KEX_SERVER_ENCRYPT, &options->ciphers) != 0 || - kex_assemble_names(KEX_SERVER_MAC, &options->macs) != 0 || - kex_assemble_names(KEX_SERVER_KEX, &options->kex_algorithms) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, - &options->hostbased_key_types) != 0 || - kex_assemble_names(KEX_DEFAULT_PK_ALG, - &options->pubkey_key_types) != 0) - fatal("%s: kex_assemble_names failed", __func__); + assemble_algorithms(options); - /* Turn privilege separation on by default */ + /* Turn privilege separation and sandboxing on by default */ if (use_privsep == -1) - use_privsep = PRIVSEP_NOSANDBOX; + use_privsep = PRIVSEP_ON; #define CLEAR_ON_NONE(v) \ do { \ @@ -368,6 +373,8 @@ fill_default_server_options(ServerOptions *options) CLEAR_ON_NONE(options->trusted_user_ca_keys); CLEAR_ON_NONE(options->revoked_keys_file); CLEAR_ON_NONE(options->authorized_principals_file); + CLEAR_ON_NONE(options->adm_forced_command); + CLEAR_ON_NONE(options->chroot_directory); 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++) @@ -499,7 +506,11 @@ static struct { { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, { "printmotd", sPrintMotd, SSHCFG_GLOBAL }, +#ifdef DISABLE_LASTLOG + { "printlastlog", sUnsupported, SSHCFG_GLOBAL }, +#else { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL }, +#endif { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL }, { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL }, { "x11forwarding", sX11Forwarding, SSHCFG_ALL }, @@ -1319,16 +1330,12 @@ process_server_config_line(ServerOptions *options, char *line, if (scan_scaled(arg, &val64) == -1) fatal("%.200s line %d: Bad number '%s': %s", filename, linenum, arg, strerror(errno)); - /* check for too-large or too-small limits */ - if (val64 > UINT_MAX) - fatal("%.200s line %d: RekeyLimit too large", - filename, linenum); if (val64 != 0 && val64 < 16) fatal("%.200s line %d: RekeyLimit too small", filename, linenum); } if (*activep && options->rekey_limit == -1) - options->rekey_limit = (u_int32_t)val64; + options->rekey_limit = val64; if (cp != NULL) { /* optional rekey interval present */ if (strcmp(cp, "none") == 0) { (void)strdelim(&cp); /* discard */ @@ -2015,6 +2022,9 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) /* See comment in servconf.h */ COPY_MATCH_STRING_OPTS(); + /* Arguments that accept '+...' need to be expanded */ + assemble_algorithms(dst); + /* * The only things that should be below this point are string options * which are only used after authentication. @@ -2022,8 +2032,17 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) if (preauth) return; + /* These options may be "none" to clear a global setting */ M_CP_STROPT(adm_forced_command); + if (option_clear_or_none(dst->adm_forced_command)) { + free(dst->adm_forced_command); + dst->adm_forced_command = NULL; + } M_CP_STROPT(chroot_directory); + if (option_clear_or_none(dst->chroot_directory)) { + free(dst->chroot_directory); + dst->chroot_directory = NULL; + } } #undef M_CP_INTOPT @@ -2254,7 +2273,9 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sChallengeResponseAuthentication, o->challenge_response_authentication); dump_cfg_fmtint(sPrintMotd, o->print_motd); +#ifndef DISABLE_LASTLOG dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); +#endif dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); dump_cfg_fmtint(sPermitTTY, o->permit_tty); @@ -2338,7 +2359,7 @@ dump_config(ServerOptions *o) printf("ipqos %s ", iptos2str(o->ip_qos_interactive)); printf("%s\n", iptos2str(o->ip_qos_bulk)); - printf("rekeylimit %lld %d\n", (long long)o->rekey_limit, + printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit, o->rekey_interval); channel_print_adm_permitted_opens(); diff --git a/serverloop.c b/serverloop.c index 306ac36be670..80d1db5490bc 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.178 2015/02/20 22:17:21 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.182 2016/02/08 10:57:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -78,7 +78,6 @@ #include "dispatch.h" #include "auth-options.h" #include "serverloop.h" -#include "roaming.h" #include "ssherr.h" extern ServerOptions options; @@ -399,11 +398,8 @@ process_input(fd_set *readset) /* Read and buffer any input data from the client. */ if (FD_ISSET(connection_in, readset)) { - int cont = 0; - len = roaming_read(connection_in, buf, sizeof(buf), &cont); + len = read(connection_in, buf, sizeof(buf)); if (len == 0) { - if (cont) - return; verbose("Connection closed by %.100s", get_remote_ipaddr()); connection_closed = 1; @@ -824,7 +820,7 @@ void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; - int rekeying = 0, max_fd; + int max_fd; u_int nalloc = 0; u_int64_t rekey_timeout_ms = 0; @@ -851,11 +847,11 @@ server_loop2(Authctxt *authctxt) for (;;) { process_buffered_input_packets(); - rekeying = (active_state->kex != NULL && !active_state->kex->done); - - if (!rekeying && packet_not_very_much_data_to_write()) + if (!ssh_packet_is_rekeying(active_state) && + packet_not_very_much_data_to_write()) channel_output_poll(); - if (options.rekey_interval > 0 && compat20 && !rekeying) + if (options.rekey_interval > 0 && compat20 && + !ssh_packet_is_rekeying(active_state)) rekey_timeout_ms = packet_get_rekey_timeout() * 1000; else rekey_timeout_ms = 0; @@ -870,14 +866,8 @@ server_loop2(Authctxt *authctxt) } collect_children(); - if (!rekeying) { + if (!ssh_packet_is_rekeying(active_state)) channel_after_select(readset, writeset); - if (packet_need_rekeying()) { - debug("need rekeying"); - active_state->kex->done = 0; - kex_send_kexinit(active_state); - } - } process_input(readset); if (connection_closed) break; @@ -1201,7 +1191,7 @@ server_input_hostkeys_prove(struct sshbuf **respp) 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 || + sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), NULL, 0)) != 0 || (r = sshbuf_put_string(resp, sig, slen)) != 0) { error("%s: couldn't prepare signature: %s", __func__, ssh_err(r)); @@ -1265,7 +1255,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) free(fwd.listen_host); if ((resp = sshbuf_new()) == NULL) fatal("%s: sshbuf_new", __func__); - if ((r = sshbuf_put_u32(resp, allocated_listen_port)) != 0) + if (allocated_listen_port != 0 && + (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; diff --git a/session.c b/session.c index 5a64715e2cfd..7a02500ab68f 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.278 2015/04/24 01:36:00 deraadt Exp $ */ +/* $OpenBSD: session.c,v 1.280 2016/02/16 03:37:48 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -160,6 +160,7 @@ login_cap_t *lc; #endif static int is_child = 0; +static int in_chroot = 0; /* Name and directory of socket for authentication agent forwarding. */ static char *auth_sock_name = NULL; @@ -778,8 +779,8 @@ int do_exec(Session *s, const char *command) { int ret; - const char *forced = NULL; - char session_type[1024], *tty = NULL; + const char *forced = NULL, *tty = NULL; + char session_type[1024]; if (options.adm_forced_command) { original_command = command; @@ -814,13 +815,14 @@ do_exec(Session *s, const char *command) tty += 5; } - verbose("Starting session: %s%s%s for %s from %.200s port %d", + verbose("Starting session: %s%s%s for %s from %.200s port %d id %d", session_type, tty == NULL ? "" : " on ", tty == NULL ? "" : tty, s->pw->pw_name, get_remote_ipaddr(), - get_remote_port()); + get_remote_port(), + s->self); #ifdef SSH_AUDIT_EVENTS if (command != NULL) @@ -1490,9 +1492,6 @@ void do_setusercontext(struct passwd *pw) { char *chroot_path, *tmp; -#ifdef USE_LIBIAF - int doing_chroot = 0; -#endif platform_setusercontext(pw); @@ -1520,7 +1519,7 @@ do_setusercontext(struct passwd *pw) platform_setusercontext_post_groups(pw); - if (options.chroot_directory != NULL && + if (!in_chroot && options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { tmp = tilde_expand_filename(options.chroot_directory, pw->pw_uid); @@ -1532,9 +1531,7 @@ do_setusercontext(struct passwd *pw) /* Make sure we don't attempt to chroot again */ free(options.chroot_directory); options.chroot_directory = NULL; -#ifdef USE_LIBIAF - doing_chroot = 1; -#endif + in_chroot = 1; } #ifdef HAVE_LOGIN_CAP @@ -1549,16 +1546,16 @@ do_setusercontext(struct passwd *pw) (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUMASK); #else # ifdef USE_LIBIAF -/* In a chroot environment, the set_id() will always fail; typically - * because of the lack of necessary authentication services and runtime - * such as ./usr/lib/libiaf.so, ./usr/lib/libpam.so.1, and ./etc/passwd - * We skip it in the internal sftp chroot case. - * We'll lose auditing and ACLs but permanently_set_uid will - * take care of the rest. - */ - if ((doing_chroot == 0) && set_id(pw->pw_name) != 0) { - fatal("set_id(%s) Failed", pw->pw_name); - } + /* + * In a chroot environment, the set_id() will always fail; + * typically because of the lack of necessary authentication + * services and runtime such as ./usr/lib/libiaf.so, + * ./usr/lib/libpam.so.1, and ./etc/passwd We skip it in the + * internal sftp chroot case. We'll lose auditing and ACLs but + * permanently_set_uid will take care of the rest. + */ + if (!in_chroot && set_id(pw->pw_name) != 0) + fatal("set_id(%s) Failed", pw->pw_name); # endif /* USE_LIBIAF */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); @@ -1790,11 +1787,11 @@ do_child(Session *s, const char *command) #ifdef HAVE_LOGIN_CAP r = login_getcapbool(lc, "requirehome", 0); #endif - if (r || options.chroot_directory == NULL || - strcasecmp(options.chroot_directory, "none") == 0) + if (r || !in_chroot) { fprintf(stderr, "Could not chdir to home " "directory %s: %s\n", pw->pw_dir, strerror(errno)); + } if (r) exit(1); } @@ -2503,7 +2500,12 @@ session_close(Session *s) { u_int i; - debug("session_close: session %d pid %ld", s->self, (long)s->pid); + verbose("Close session: user %s from %.200s port %d id %d", + s->pw->pw_name, + get_remote_ipaddr(), + get_remote_port(), + s->self); + if (s->ttyfd != -1) session_pty_cleanup(s); free(s->term); diff --git a/sftp-client.c b/sftp-client.c index 5dbeb47c0624..d49bfaabac90 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.120 2015/05/28 04:50:53 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.121 2016/02/11 02:21:34 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -1760,7 +1760,7 @@ do_upload(struct sftp_conn *conn, const char *local_path, if (fsync_flag) (void)do_fsync(conn, handle, handle_len); - if (do_close(conn, handle, handle_len) != SSH2_FX_OK) + if (do_close(conn, handle, handle_len) != 0) status = SSH2_FX_FAILURE; free(handle); @@ -1773,12 +1773,11 @@ 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; - u_int status; DIR *dirp; struct dirent *dp; char *filename, *new_src, *new_dst; struct stat sb; - Attrib a; + Attrib a, *dirattrib; if (depth >= MAX_DIR_DEPTH) { error("Maximum directory depth exceeded: %d levels", depth); @@ -1805,17 +1804,18 @@ upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst, if (!preserve_flag) a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME; - status = do_mkdir(conn, dst, &a, 0); /* - * we lack a portable status for errno EEXIST, - * so if we get a SSH2_FX_FAILURE back we must check - * if it was created successfully. + * sftp lacks a portable status value to match errno EEXIST, + * so if we get a failure back then we must check whether + * the path already existed and is a directory. */ - if (status != SSH2_FX_OK) { - if (status != SSH2_FX_FAILURE) + if (do_mkdir(conn, dst, &a, 0) != 0) { + if ((dirattrib = do_stat(conn, dst, 0)) == NULL) return -1; - if (do_stat(conn, dst, 0) == NULL) + if (!S_ISDIR(dirattrib->perm)) { + error("\"%s\" exists but is not a directory", dst); return -1; + } } if ((dirp = opendir(src)) == NULL) { diff --git a/sftp-client.h b/sftp-client.h index f814b07d6c88..14a3b8182c49 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -21,6 +21,12 @@ #ifndef _SFTP_CLIENT_H #define _SFTP_CLIENT_H +#ifdef USE_SYSTEM_GLOB +# include +#else +# include "openbsd-compat/glob.h" +#endif + typedef struct SFTP_DIRENT SFTP_DIRENT; struct SFTP_DIRENT { diff --git a/sftp-server-main.c b/sftp-server-main.c index 7e644ab8982b..c6ccd623eab9 100644 --- a/sftp-server-main.c +++ b/sftp-server-main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server-main.c,v 1.4 2009/02/21 19:32:04 tobias Exp $ */ +/* $OpenBSD: sftp-server-main.c,v 1.5 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2008 Markus Friedl. All rights reserved. * @@ -26,6 +26,7 @@ #include "log.h" #include "sftp.h" #include "misc.h" +#include "xmalloc.h" void cleanup_exit(int i) @@ -38,6 +39,7 @@ main(int argc, char **argv) { struct passwd *user_pw; + ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); diff --git a/sftp-server.0 b/sftp-server.0 index b971cef4039c..3b22ed2a022d 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -93,4 +93,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.8 December 11, 2014 OpenBSD 5.8 +OpenBSD 5.9 December 11, 2014 OpenBSD 5.9 diff --git a/sftp-server.c b/sftp-server.c index eac11d7e695d..e11a1b89bdb6 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.107 2015/08/20 22:32:42 deraadt Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.109 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1513,6 +1513,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) extern char *optarg; extern char *__progname; + ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); @@ -1598,6 +1599,9 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) fatal("unable to make the process undumpable"); #endif /* defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) */ + /* Drop any fine-grained privileges we don't need */ + platform_pledge_sftp_server(); + if ((cp = getenv("SSH_CONNECTION")) != NULL) { client_addr = xstrdup(cp); if ((cp = strchr(client_addr, ' ')) == NULL) { @@ -1631,9 +1635,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) if ((oqueue = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); - set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); - rset = xmalloc(set_size); - wset = xmalloc(set_size); + rset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask)); + wset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask)); if (homedir != NULL) { if (chdir(homedir) != 0) { @@ -1642,6 +1645,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) } } + set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); for (;;) { memset(rset, 0, set_size); memset(wset, 0, set_size); diff --git a/sftp.0 b/sftp.0 index 550f27648c8a..ce48de9ca138 100644 --- a/sftp.0 +++ b/sftp.0 @@ -108,6 +108,7 @@ DESCRIPTION CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs + CertificateFile ChallengeResponseAuthentication CheckHostIP Cipher @@ -380,4 +381,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.8 January 30, 2015 OpenBSD 5.8 +OpenBSD 5.9 September 25, 2015 OpenBSD 5.9 diff --git a/sftp.1 b/sftp.1 index 214f0118c0bb..edc5a85e6be5 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.101 2015/01/30 11:43:14 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.102 2015/09/25 18:19:54 jmc 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: January 30 2015 $ +.Dd $Mdocdate: September 25 2015 $ .Dt SFTP 1 .Os .Sh NAME @@ -198,6 +198,7 @@ For full details of the options listed below, and their possible values, see .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs +.It CertificateFile .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher diff --git a/sftp.c b/sftp.c index 788601a8d7fd..2077219fa4e8 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.171 2015/08/20 22:32:42 deraadt Exp $ */ +/* $OpenBSD: sftp.c,v 1.172 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2248,6 +2248,7 @@ main(int argc, char **argv) size_t num_requests = DEFAULT_NUM_REQUESTS; long long limit_kbps = 0; + ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); setlocale(LC_CTYPE, ""); diff --git a/ssh-add.0 b/ssh-add.0 index 29db710abcc1..cc56b00353ee 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -126,4 +126,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.8 March 30, 2015 OpenBSD 5.8 +OpenBSD 5.9 March 30, 2015 OpenBSD 5.9 diff --git a/ssh-add.c b/ssh-add.c index d6271d78ef79..fb9a53e64cfe 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.123 2015/07/03 03:43:18 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.128 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -93,7 +93,7 @@ static int lifetime = 0; /* User has to confirm key use */ static int confirm = 0; -/* we keep a cache of one passphrases */ +/* we keep a cache of one passphrase */ static char *pass = NULL; static void clear_pass(void) @@ -150,10 +150,8 @@ delete_file(int agent_fd, const char *filename, int key_only) certpath, ssh_err(r)); out: - if (cert != NULL) - sshkey_free(cert); - if (public != NULL) - sshkey_free(public); + sshkey_free(cert); + sshkey_free(public); free(certpath); free(comment); @@ -218,35 +216,32 @@ add_file(int agent_fd, const char *filename, int key_only) close(fd); /* At first, try empty passphrase */ - if ((r = sshkey_parse_private_fileblob(keyblob, "", filename, - &private, &comment)) != 0 && r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + if ((r = sshkey_parse_private_fileblob(keyblob, "", &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, - &private, &comment)) != 0 && - r != SSH_ERR_KEY_WRONG_PASSPHRASE) { + if ((r = sshkey_parse_private_fileblob(keyblob, pass, &private, + &comment)) != 0 && 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%s: ", - comment, confirm ? " (will confirm each use)" : ""); + snprintf(msg, sizeof msg, "Enter passphrase for %s%s: ", + filename, confirm ? " (will confirm each use)" : ""); for (;;) { pass = read_passphrase(msg, RP_ALLOW_STDIN); if (strcmp(pass, "") == 0) goto fail_load; if ((r = sshkey_parse_private_fileblob(keyblob, pass, - filename, &private, NULL)) == 0) + &private, &comment)) == 0) break; else if (r != SSH_ERR_KEY_WRONG_PASSPHRASE) { fprintf(stderr, @@ -254,16 +249,17 @@ add_file(int agent_fd, const char *filename, int key_only) filename, ssh_err(r)); fail_load: clear_pass(); - free(comment); sshbuf_free(keyblob); return -1; } clear_pass(); snprintf(msg, sizeof msg, - "Bad passphrase, try again for %.200s%s: ", comment, + "Bad passphrase, try again for %s%s: ", filename, confirm ? " (will confirm each use)" : ""); } } + if (comment == NULL || *comment == '\0') + comment = xstrdup(filename); sshbuf_free(keyblob); if ((r = ssh_add_identity_constrained(agent_fd, private, comment, @@ -386,7 +382,7 @@ list_identities(int agent_fd, int do_fp) if (do_fp) { fp = sshkey_fingerprint(idlist->keys[i], fingerprint_hash, SSH_FP_DEFAULT); - printf("%d %s %s (%s)\n", + printf("%u %s %s (%s)\n", sshkey_size(idlist->keys[i]), fp == NULL ? "(null)" : fp, idlist->comments[i], @@ -485,6 +481,7 @@ main(int argc, char **argv) int r, i, ch, deleting = 0, ret = 0, key_only = 0; int xflag = 0, lflag = 0, Dflag = 0; + ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); diff --git a/ssh-agent.0 b/ssh-agent.0 index 65bf6e70fd8e..2cc5ac6e0156 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -18,10 +18,10 @@ DESCRIPTION using ssh(1). The agent initially does not have any private keys. Keys are added using - ssh-add(1). Multiple identities may be stored in ssh-agent concurrently - and ssh(1) will automatically use them if present. ssh-add(1) is also - used to remove keys from ssh-agent and to query the keys that are held in - one. + ssh(1) (see AddKeysToAgent in ssh_config(5) for details) or ssh-add(1). + Multiple identities may be stored in ssh-agent concurrently and ssh(1) + will automatically use them if present. ssh-add(1) is also used to + remove keys from ssh-agent and to query the keys that are held in one. The options are as follows: @@ -56,8 +56,8 @@ DESCRIPTION for an identity with ssh-add(1) overrides this value. Without this option the default maximum lifetime is forever. - If a commandline is given, this is executed as a subprocess of the agent. - When the command dies, so does the agent. + If a command line is given, this is executed as a subprocess of the + agent. When the command dies, so does the agent. The idea is that the agent is run in the user's local PC, laptop, or terminal. Authentication data need not be stored on any other machine, @@ -109,4 +109,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.8 April 24, 2015 OpenBSD 5.8 +OpenBSD 5.9 November 15, 2015 OpenBSD 5.9 diff --git a/ssh-agent.1 b/ssh-agent.1 index d0aa712f1c69..c4b50bbdfe74 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.59 2015/04/24 06:26:49 jmc Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.62 2015/11/15 23:54:15 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: April 24 2015 $ +.Dd $Mdocdate: November 15 2015 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -43,7 +43,7 @@ .Sh SYNOPSIS .Nm ssh-agent .Op Fl c | s -.Op Fl Dd +.Op Fl \&Dd .Op Fl a Ar bind_address .Op Fl E Ar fingerprint_hash .Op Fl t Ar life @@ -66,6 +66,13 @@ machines using .Pp The agent initially does not have any private keys. Keys are added using +.Xr ssh 1 +(see +.Cm AddKeysToAgent +in +.Xr ssh_config 5 +for details) +or .Xr ssh-add 1 . Multiple identities may be stored in .Nm @@ -130,7 +137,7 @@ overrides this value. Without this option the default maximum lifetime is forever. .El .Pp -If a commandline is given, this is executed as a subprocess of the agent. +If a command line is given, this is executed as a subprocess of the agent. When the command dies, so does the agent. .Pp The idea is that the agent is run in the user's local PC, laptop, or diff --git a/ssh-agent.c b/ssh-agent.c index a335ea33d76f..c38906d94278 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.204 2015/07/08 20:24:02 markus Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.212 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -368,6 +368,18 @@ process_authentication_challenge1(SocketEntry *e) } #endif +static char * +agent_decode_alg(struct sshkey *key, u_int flags) +{ + if (key->type == KEY_RSA) { + if (flags & SSH_AGENT_RSA_SHA2_256) + return "rsa-sha2-256"; + else if (flags & SSH_AGENT_RSA_SHA2_512) + return "rsa-sha2-512"; + } + return NULL; +} + /* ssh2 only */ static void process_sign_request2(SocketEntry *e) @@ -389,7 +401,7 @@ process_sign_request2(SocketEntry *e) if (flags & SSH_AGENT_OLD_SIGNATURE) compat = SSH_BUG_SIGBLOB; if ((r = sshkey_from_blob(blob, blen, &key)) != 0) { - error("%s: cannot parse key blob: %s", __func__, ssh_err(ok)); + error("%s: cannot parse key blob: %s", __func__, ssh_err(r)); goto send; } if ((id = lookup_identity(key, 2)) == NULL) { @@ -401,8 +413,8 @@ process_sign_request2(SocketEntry *e) goto send; } if ((r = sshkey_sign(id->key, &signature, &slen, - data, dlen, compat)) != 0) { - error("%s: sshkey_sign: %s", __func__, ssh_err(ok)); + data, dlen, agent_decode_alg(key, flags), compat)) != 0) { + error("%s: sshkey_sign: %s", __func__, ssh_err(r)); goto send; } /* Success */ @@ -1188,6 +1200,7 @@ main(int ac, char **av) size_t len; mode_t prev_mask; + ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -1330,6 +1343,7 @@ main(int ac, char **av) printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, SSH_AUTHSOCKET_ENV_NAME); printf("echo Agent pid %ld;\n", (long)parent_pid); + fflush(stdout); goto skip; } pid = fork(); @@ -1402,6 +1416,10 @@ main(int ac, char **av) signal(SIGTERM, cleanup_handler); nalloc = 0; + if (pledge("stdio cpath unix id proc exec", NULL) == -1) + fatal("%s: pledge: %s", __progname, strerror(errno)); + platform_pledge_agent(); + while (1) { prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); diff --git a/ssh-dss.c b/ssh-dss.c index 8ed19d84977f..cc47dcf5f14f 100644 --- a/ssh-dss.c +++ b/ssh-dss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-dss.c,v 1.32 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-dss.c,v 1.34 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -122,8 +122,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, explicit_bzero(digest, sizeof(digest)); if (sig != NULL) DSA_SIG_free(sig); - if (b != NULL) - sshbuf_free(b); + sshbuf_free(b); return ret; } @@ -209,10 +208,8 @@ ssh_dss_verify(const struct sshkey *key, explicit_bzero(digest, sizeof(digest)); if (sig != NULL) DSA_SIG_free(sig); - if (b != NULL) - sshbuf_free(b); - if (ktype != NULL) - free(ktype); + sshbuf_free(b); + free(ktype); if (sigblob != NULL) { explicit_bzero(sigblob, len); free(sigblob); diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 2c76f8b43793..74912dfd906c 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.11 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.12 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -99,10 +99,8 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ret = 0; out: explicit_bzero(digest, sizeof(digest)); - if (b != NULL) - sshbuf_free(b); - if (bb != NULL) - sshbuf_free(bb); + sshbuf_free(b); + sshbuf_free(bb); if (sig != NULL) ECDSA_SIG_free(sig); return ret; @@ -179,10 +177,8 @@ ssh_ecdsa_verify(const struct sshkey *key, out: explicit_bzero(digest, sizeof(digest)); - if (sigbuf != NULL) - sshbuf_free(sigbuf); - if (b != NULL) - sshbuf_free(b); + sshbuf_free(sigbuf); + sshbuf_free(b); if (sig != NULL) ECDSA_SIG_free(sig); free(ktype); diff --git a/ssh-keygen.0 b/ssh-keygen.0 index 07a45b36b9b9..2b749ae9f9b2 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -31,8 +31,11 @@ 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. + ssh(1). ssh-keygen can create keys for use by SSH protocol versions 1 + and 2. Protocol 1 should not be used and is only offered to support + legacy devices. It suffers from a number of cryptographic weaknesses and + doesn't support many of the advanced features available for protocol 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. @@ -194,7 +197,7 @@ DESCRIPTION file or using the format described in the KEY REVOCATION LISTS section. - -L Prints the contents of a certificate. + -L Prints the contents of one or more certificates. -l Show fingerprint of specified public key file. Private RSA1 keys are also supported. For RSA and DSA keys ssh-keygen tries to @@ -275,11 +278,11 @@ DESCRIPTION At present, no options are valid for host keys. - -o Causes ssh-keygen to save SSH protocol 2 private keys using the - new OpenSSH format rather than the more compatible PEM format. - The new format has increased resistance to brute-force password - cracking but is not supported by versions of OpenSSH prior to - 6.5. Ed25519 keys always use the new private key format. + -o Causes ssh-keygen to save private keys using the new OpenSSH + format rather than the more compatible PEM format. The new + format has increased resistance to brute-force password cracking + but is not supported by versions of OpenSSH prior to 6.5. + Ed25519 keys always use the new private key format. -P passphrase Provides the (old) passphrase. @@ -502,7 +505,7 @@ KEY REVOCATION LISTS It is also possible, given a KRL, to test whether it revokes a particular key (or keys). The -Q flag will query an existing KRL, testing each key - specified on the commandline. If any key listed on the command line has + specified on the command line. If any key listed on the command line has been revoked (or an error encountered) then ssh-keygen will exit with a non-zero exit status. A zero exit status will only be returned if no key was revoked. @@ -563,4 +566,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.8 August 20, 2015 OpenBSD 5.8 +OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index ed17a08fab28..37a4fc2b226d 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.127 2015/08/20 19:20:06 naddy Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.130 2016/02/17 07:38:19 jmc 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: August 20 2015 $ +.Dd $Mdocdate: February 17 2016 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -141,8 +141,12 @@ 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. +can create keys for use by SSH protocol versions 1 and 2. +Protocol 1 should not be used +and is only offered to support legacy devices. +It suffers from a number of cryptographic weaknesses +and doesn't support many of the advanced features available for protocol 2. +.Pp The type of key to be generated is specified with the .Fl t option. @@ -376,7 +380,7 @@ using the format described in the .Sx KEY REVOCATION LISTS section. .It Fl L -Prints the contents of a certificate. +Prints the contents of one or more certificates. .It Fl l Show fingerprint of specified public key file. Private RSA1 keys are also supported. @@ -474,7 +478,7 @@ At present, no options are valid for host keys. .It Fl o Causes .Nm -to save SSH protocol 2 private keys using the new OpenSSH format rather than +to save private keys using the new OpenSSH format rather than the more compatible PEM format. The new format has increased resistance to brute-force password cracking but is not supported by versions of OpenSSH prior to 6.5. @@ -781,7 +785,7 @@ It is also possible, given a KRL, to test whether it revokes a particular key (or keys). The .Fl Q -flag will query an existing KRL, testing each key specified on the commandline. +flag will query an existing KRL, testing each key specified on the command line. If any key listed on the command line has been revoked (or an error encountered) then .Nm diff --git a/ssh-keygen.c b/ssh-keygen.c index 4e0a8555434c..478520123e10 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.277 2015/08/19 23:17:51 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.288 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -523,7 +523,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) sshbuf_free(b); /* try the key */ - if (sshkey_sign(key, &sig, &slen, data, sizeof(data), 0) != 0 || + if (sshkey_sign(key, &sig, &slen, data, sizeof(data), NULL, 0) != 0 || sshkey_verify(key, sig, slen, data, sizeof(data), 0) != 0) { sshkey_free(key); free(sig); @@ -808,116 +808,162 @@ do_download(struct passwd *pw) #endif /* ENABLE_PKCS11 */ } +static struct sshkey * +try_read_key(char **cpp) +{ + struct sshkey *ret; + int r; + + if ((ret = sshkey_new(KEY_RSA1)) == NULL) + fatal("sshkey_new failed"); + /* Try RSA1 */ + if ((r = sshkey_read(ret, cpp)) == 0) + return ret; + /* Try modern */ + sshkey_free(ret); + if ((ret = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("sshkey_new failed"); + if ((r = sshkey_read(ret, cpp)) == 0) + return ret; + /* Not a key */ + sshkey_free(ret); + return NULL; +} + +static void +fingerprint_one_key(const struct sshkey *public, const char *comment) +{ + char *fp = NULL, *ra = NULL; + enum sshkey_fp_rep rep; + int fptype; + + fptype = print_bubblebabble ? SSH_DIGEST_SHA1 : fingerprint_hash; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_DEFAULT; + fp = sshkey_fingerprint(public, fptype, rep); + ra = sshkey_fingerprint(public, fingerprint_hash, SSH_FP_RANDOMART); + if (fp == NULL || ra == NULL) + fatal("%s: sshkey_fingerprint failed", __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); +} + +static void +fingerprint_private(const char *path) +{ + struct stat st; + char *comment = NULL; + struct sshkey *public = NULL; + int r; + + if (stat(identity_file, &st) < 0) + fatal("%s: %s", path, strerror(errno)); + if ((r = sshkey_load_public(path, &public, &comment)) != 0) { + debug("load public \"%s\": %s", path, ssh_err(r)); + if ((r = sshkey_load_private(path, NULL, + &public, &comment)) != 0) { + debug("load private \"%s\": %s", path, ssh_err(r)); + fatal("%s is not a key file.", path); + } + } + + fingerprint_one_key(public, comment); + sshkey_free(public); + free(comment); +} + static void do_fingerprint(struct passwd *pw) { FILE *f; - struct sshkey *public; - char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; - int r, i, skip = 0, num = 0, invalid = 1; - enum sshkey_fp_rep rep; - int fptype; - struct stat st; + struct sshkey *public = NULL; + char *comment = NULL, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES]; + int i, invalid = 1; + const char *path; + long int lnum = 0; - 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) - fatal("%s: %s", identity_file, strerror(errno)); - 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); - sshkey_free(public); - free(comment); - free(ra); - free(fp); - exit(0); - } - if (comment) { - free(comment); - comment = NULL; - } + path = identity_file; - if ((f = fopen(identity_file, "r")) == NULL) - fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); + if (strcmp(identity_file, "-") == 0) { + f = stdin; + path = "(stdin)"; + } else if ((f = fopen(path, "r")) == NULL) + fatal("%s: %s: %s", __progname, path, strerror(errno)); - while (fgets(line, sizeof(line), f)) { - if ((cp = strchr(line, '\n')) == NULL) { - error("line %d too long: %.40s...", - num + 1, line); - skip = 1; + while (read_keyfile_line(f, path, line, sizeof(line), &lnum) == 0) { + cp = line; + cp[strcspn(cp, "\n")] = '\0'; + /* Trim leading space and comments */ + cp = line + strspn(line, " \t"); + if (*cp == '#' || *cp == '\0') + continue; + + /* + * Input may be plain keys, private keys, authorized_keys + * or known_hosts. + */ + + /* + * Try private keys first. Assume a key is private if + * "SSH PRIVATE KEY" appears on the first line and we're + * not reading from stdin (XXX support private keys on stdin). + */ + if (lnum == 1 && strcmp(identity_file, "-") != 0 && + strstr(cp, "PRIVATE KEY") != NULL) { + fclose(f); + fingerprint_private(path); + exit(0); + } + + /* + * If it's not a private key, then this must be prepared to + * accept a public key prefixed with a hostname or options. + * Try a bare key first, otherwise skip the leading stuff. + */ + if ((public = try_read_key(&cp)) == NULL) { + i = strtol(cp, &ep, 10); + if (i == 0 || ep == NULL || + (*ep != ' ' && *ep != '\t')) { + int quoted = 0; + + comment = cp; + for (; *cp && (quoted || (*cp != ' ' && + *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + if (!*cp) + continue; + *cp++ = '\0'; + } + } + /* Retry after parsing leading hostname/key options */ + if (public == NULL && (public = try_read_key(&cp)) == NULL) { + debug("%s:%ld: not a public key", path, lnum); continue; } - num++; - if (skip) { - skip = 0; - continue; - } - *cp = '\0'; - /* Skip leading whitespace, empty and comment lines. */ - for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + /* Find trailing comment, if any */ + for (; *cp == ' ' || *cp == '\t'; cp++) ; - if (!*cp || *cp == '\n' || *cp == '#') - continue; - i = strtol(cp, &ep, 10); - if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { - int quoted = 0; + if (*cp != '\0' && *cp != '#') comment = cp; - for (; *cp && (quoted || (*cp != ' ' && - *cp != '\t')); cp++) { - if (*cp == '\\' && cp[1] == '"') - cp++; /* Skip both */ - else if (*cp == '"') - quoted = !quoted; - } - if (!*cp) - continue; - *cp++ = '\0'; - } - ep = cp; - if ((public = sshkey_new(KEY_RSA1)) == NULL) - fatal("sshkey_new failed"); - if ((r = sshkey_read(public, &cp)) != 0) { - cp = ep; - 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 = 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); + + fingerprint_one_key(public, comment); sshkey_free(public); - invalid = 0; + invalid = 0; /* One good key in the file is sufficient */ } fclose(f); if (invalid) - fatal("%s is not a public key file.", identity_file); + fatal("%s is not a public key file.", path); exit(0); } @@ -1185,8 +1231,11 @@ do_known_hosts(struct passwd *pw, const char *name) foreach_options |= print_fingerprint ? HKF_WANT_PARSE_KEY : 0; if ((r = hostkeys_foreach(identity_file, hash_hosts ? known_hosts_hash : known_hosts_find_delete, &ctx, - name, NULL, foreach_options)) != 0) + name, NULL, foreach_options)) != 0) { + if (inplace) + unlink(tmp); fatal("%s: hostkeys_foreach failed: %s", __func__, ssh_err(r)); + } if (inplace) fclose(ctx.out); @@ -1383,9 +1432,11 @@ do_change_comment(struct passwd *pw) identity_file, ssh_err(r)); } } - /* XXX what about new-format keys? */ - if (private->type != KEY_RSA1) { - error("Comments are only supported for RSA1 keys."); + + if (private->type != KEY_RSA1 && private->type != KEY_ED25519 && + !use_new_format) { + error("Comments are only supported for RSA1 or keys stored in " + "the new format (-o)."); explicit_bzero(passphrase, strlen(passphrase)); sshkey_free(private); exit(1); @@ -1441,44 +1492,6 @@ do_change_comment(struct passwd *pw) exit(0); } -static const char * -fmt_validity(u_int64_t valid_from, u_int64_t valid_to) -{ - char from[32], to[32]; - static char ret[64]; - time_t tt; - struct tm *tm; - - *from = *to = '\0'; - if (valid_from == 0 && valid_to == 0xffffffffffffffffULL) - return "forever"; - - if (valid_from != 0) { - /* XXX revisit INT_MAX in 2038 :) */ - tt = valid_from > INT_MAX ? INT_MAX : valid_from; - tm = localtime(&tt); - strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); - } - if (valid_to != 0xffffffffffffffffULL) { - /* XXX revisit INT_MAX in 2038 :) */ - tt = valid_to > INT_MAX ? INT_MAX : valid_to; - tm = localtime(&tt); - strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); - } - - if (valid_from == 0) { - snprintf(ret, sizeof(ret), "before %s", to); - return ret; - } - if (valid_to == 0xffffffffffffffffULL) { - snprintf(ret, sizeof(ret), "after %s", from); - return ret; - } - - snprintf(ret, sizeof(ret), "from %s to %s", from, to); - return ret; -} - static void add_flag_option(struct sshbuf *c, const char *name) { @@ -1572,7 +1585,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) int r, i, fd; u_int n; struct sshkey *ca, *public; - char *otmp, *tmp, *cp, *out, *comment, **plist = NULL; + char valid[64], *otmp, *tmp, *cp, *out, *comment, **plist = NULL; FILE *f; #ifdef ENABLE_PKCS11 @@ -1647,13 +1660,15 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) fclose(f); if (!quiet) { + sshkey_format_cert_validity(public->cert, + valid, sizeof(valid)); logit("Signed %s key %s: id \"%s\" serial %llu%s%s " - "valid %s", sshkey_cert_type(public), + "valid %s", sshkey_cert_type(public), out, public->cert->key_id, (unsigned long long)public->cert->serial, cert_principals != NULL ? " for " : "", cert_principals != NULL ? cert_principals : "", - fmt_validity(cert_valid_from, cert_valid_to)); + valid); } sshkey_free(public); @@ -1687,7 +1702,7 @@ parse_absolute_time(const char *s) char buf[32], *fmt; /* - * POSIX strptime says "The application shall ensure that there + * POSIX strptime says "The application shall ensure that there * is white-space or other non-alphanumeric characters between * any two conversion specifications" so arrange things this way. */ @@ -1851,31 +1866,18 @@ show_options(struct sshbuf *optbuf, int in_critical) } static void -do_show_cert(struct passwd *pw) +print_cert(struct sshkey *key) { - struct sshkey *key; - struct stat st; - char *key_fp, *ca_fp; + char valid[64], *key_fp, *ca_fp; u_int i; - 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 ((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); 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__); + sshkey_format_cert_validity(key->cert, valid, sizeof(valid)); - printf("%s:\n", identity_file); 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); @@ -1883,8 +1885,7 @@ do_show_cert(struct passwd *pw) sshkey_type(key->cert->signature_key), ca_fp); printf(" Key ID: \"%s\"\n", key->cert->key_id); printf(" Serial: %llu\n", (unsigned long long)key->cert->serial); - printf(" Valid: %s\n", - fmt_validity(key->cert->valid_after, key->cert->valid_before)); + printf(" Valid: %s\n", valid); printf(" Principals: "); if (key->cert->nprincipals == 0) printf("(none)\n"); @@ -1908,7 +1909,60 @@ do_show_cert(struct passwd *pw) printf("\n"); show_options(key->cert->extensions, 0); } - exit(0); +} + +static void +do_show_cert(struct passwd *pw) +{ + struct sshkey *key = NULL; + struct stat st; + int r, is_stdin = 0, ok = 0; + FILE *f; + char *cp, line[SSH_MAX_PUBKEY_BYTES]; + const char *path; + long int lnum = 0; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (strcmp(identity_file, "-") != 0 && stat(identity_file, &st) < 0) + fatal("%s: %s: %s", __progname, identity_file, strerror(errno)); + + path = identity_file; + if (strcmp(path, "-") == 0) { + f = stdin; + path = "(stdin)"; + is_stdin = 1; + } else if ((f = fopen(identity_file, "r")) == NULL) + fatal("fopen %s: %s", identity_file, strerror(errno)); + + while (read_keyfile_line(f, path, line, sizeof(line), &lnum) == 0) { + sshkey_free(key); + key = NULL; + /* Trim leading space and comments */ + cp = line + strspn(line, " \t"); + if (*cp == '#' || *cp == '\0') + continue; + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) + fatal("key_new"); + if ((r = sshkey_read(key, &cp)) != 0) { + error("%s:%lu: invalid key: %s", path, + lnum, ssh_err(r)); + continue; + } + if (!sshkey_is_cert(key)) { + error("%s:%lu is not a certificate", path, lnum); + continue; + } + ok = 1; + if (!is_stdin && lnum == 1) + printf("%s:\n", path); + else + printf("%s:%lu:\n", path, lnum); + print_cert(key); + } + sshkey_free(key); + fclose(f); + exit(ok ? 0 : 1); } static void @@ -2112,8 +2166,7 @@ do_gen_krl(struct passwd *pw, int updating, int argc, char **argv) close(fd); sshbuf_free(kbuf); ssh_krl_free(krl); - if (ca != NULL) - sshkey_free(ca); + sshkey_free(ca); } static void @@ -2208,6 +2261,7 @@ main(int argc, char **argv) extern int optind; extern char *optarg; + ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 500c1dd30798..5578cc504cb3 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -4,7 +4,7 @@ NAME ssh-keyscan M-bM-^@M-^S gather ssh public keys SYNOPSIS - ssh-keyscan [-46Hv] [-f file] [-p port] [-T timeout] [-t type] + ssh-keyscan [-46cHv] [-f file] [-p port] [-T timeout] [-t type] [host | addrlist namelist] ... DESCRIPTION @@ -26,6 +26,8 @@ DESCRIPTION -6 Forces ssh-keyscan to use IPv6 addresses only. + -c Request certificates from target hosts instead of plain keys. + -f file 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 @@ -106,4 +108,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.8 August 30, 2014 OpenBSD 5.8 +OpenBSD 5.9 November 8, 2015 OpenBSD 5.9 diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 6bbc480cd5c6..d29d9d906479 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.36 2014/08/30 15:33:50 sobrado Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.38 2015/11/08 23:24:03 jmc 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: August 30 2014 $ +.Dd $Mdocdate: November 8 2015 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -15,7 +15,7 @@ .Sh SYNOPSIS .Nm ssh-keyscan .Bk -words -.Op Fl 46Hv +.Op Fl 46cHv .Op Fl f Ar file .Op Fl p Ar port .Op Fl T Ar timeout @@ -54,6 +54,8 @@ to use IPv4 addresses only. Forces .Nm to use IPv6 addresses only. +.It Fl c +Request certificates from target hosts instead of plain keys. .It Fl f Ar file Read hosts or .Dq addrlist namelist diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 57d88429b059..7fe61e4e1a0e 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.101 2015/04/10 00:08:55 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.105 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -60,6 +60,7 @@ int ssh_port = SSH_DEFAULT_PORT; #define KT_ECDSA 8 #define KT_ED25519 16 +int get_cert = 0; int get_keytypes = KT_RSA|KT_ECDSA|KT_ED25519; int hash_hosts = 0; /* Hash hostname on output */ @@ -267,11 +268,32 @@ keygrab_ssh2(con *c) int r; 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")); + switch (c->c_keytype) { + case KT_DSA: + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? + "ssh-dss-cert-v01@openssh.com" : "ssh-dss"; + break; + case KT_RSA: + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? + "ssh-rsa-cert-v01@openssh.com" : "ssh-rsa"; + break; + case KT_ED25519: + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? + "ssh-ed25519-cert-v01@openssh.com" : "ssh-ed25519"; + break; + case KT_ECDSA: + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = get_cert ? + "ecdsa-sha2-nistp256-cert-v01@openssh.com," + "ecdsa-sha2-nistp384-cert-v01@openssh.com," + "ecdsa-sha2-nistp521-cert-v01@openssh.com" : + "ecdsa-sha2-nistp256," + "ecdsa-sha2-nistp384," + "ecdsa-sha2-nistp521"; + break; + default: + fatal("unknown key type %d", c->c_keytype); + break; + } if ((r = kex_setup(c->c_ssh, myproposal)) != 0) { free(c->c_ssh); fprintf(stderr, "kex_setup: %s\n", ssh_err(r)); @@ -296,23 +318,39 @@ keygrab_ssh2(con *c) } static void -keyprint(con *c, struct sshkey *key) +keyprint_one(char *host, struct sshkey *key) { - char *host = c->c_output_name ? c->c_output_name : c->c_name; - char *hostport = NULL; + char *hostport; - if (!key) - return; if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL) fatal("host_hash failed"); hostport = put_host_port(host, ssh_port); - fprintf(stdout, "%s ", hostport); + if (!get_cert) + fprintf(stdout, "%s ", hostport); sshkey_write(key, stdout); fputs("\n", stdout); free(hostport); } +static void +keyprint(con *c, struct sshkey *key) +{ + char *hosts = c->c_output_name ? c->c_output_name : c->c_name; + char *host, *ohosts; + + if (key == NULL) + return; + if (get_cert || (!hash_hosts && ssh_port == SSH_DEFAULT_PORT)) { + keyprint_one(hosts, key); + return; + } + ohosts = hosts = xstrdup(hosts); + while ((host = strsep(&hosts, ",")) != NULL) + keyprint_one(host, key); + free(ohosts); +} + static int tcpconnect(char *host) { @@ -369,6 +407,7 @@ conalloc(char *iname, char *oname, int keytype) if (fdcon[s].c_status) fatal("conalloc: attempt to reuse fdno %d", s); + debug3("%s: oname %s kt %d", __func__, oname, keytype); fdcon[s].c_fd = s; fdcon[s].c_status = CS_CON; fdcon[s].c_namebase = namebase; @@ -639,7 +678,7 @@ static void usage(void) { fprintf(stderr, - "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" + "usage: %s [-46cHv] [-f file] [-p port] [-T timeout] [-t type]\n" "\t\t [host | addrlist namelist] ...\n", __progname); exit(1); @@ -657,6 +696,7 @@ main(int argc, char **argv) extern int optind; extern char *optarg; + ssh_malloc_init(); /* must be called before any mallocs */ __progname = ssh_get_progname(argv[0]); seed_rng(); TAILQ_INIT(&tq); @@ -667,11 +707,14 @@ main(int argc, char **argv) if (argc <= 1) usage(); - while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) { + while ((opt = getopt(argc, argv, "cHv46p:T:t:f:")) != -1) { switch (opt) { case 'H': hash_hosts = 1; break; + case 'c': + get_cert = 1; + break; case 'p': ssh_port = a2port(optarg); if (ssh_port <= 0) { diff --git a/ssh-keysign.0 b/ssh-keysign.0 index 7db72c714adf..65d75f313ffc 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -8,8 +8,7 @@ SYNOPSIS DESCRIPTION ssh-keysign is used by ssh(1) to access the local host keys and generate - the digital signature required during host-based authentication with SSH - protocol version 2. + the digital signature required during host-based authentication. ssh-keysign is disabled by default and can only be enabled in the global client configuration file /etc/ssh/ssh_config by setting EnableSSHKeysign @@ -50,4 +49,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.8 December 7, 2013 OpenBSD 5.8 +OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 diff --git a/ssh-keysign.8 b/ssh-keysign.8 index 69d082954df6..19b0dbc533c8 100644 --- a/ssh-keysign.8 +++ b/ssh-keysign.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keysign.8,v 1.14 2013/12/07 11:58:46 naddy Exp $ +.\" $OpenBSD: ssh-keysign.8,v 1.15 2016/02/17 07:38:19 jmc Exp $ .\" .\" Copyright (c) 2002 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: December 7 2013 $ +.Dd $Mdocdate: February 17 2016 $ .Dt SSH-KEYSIGN 8 .Os .Sh NAME @@ -35,7 +35,7 @@ is used by .Xr ssh 1 to access the local host keys and generate the digital signature -required during host-based authentication with SSH protocol version 2. +required during host-based authentication. .Pp .Nm is disabled by default and can only be enabled in the diff --git a/ssh-keysign.c b/ssh-keysign.c index 1dca3e289f1e..ac5034de860f 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.49 2015/07/03 03:56:25 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.52 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef WITH_OPENSSL #include @@ -59,6 +60,8 @@ struct ssh *active_state = NULL; /* XXX needed for linking */ +extern char *__progname; + /* XXX readconf.c needs these */ uid_t original_real_uid; @@ -179,6 +182,10 @@ main(int argc, char **argv) u_int32_t rnd[256]; #endif + ssh_malloc_init(); /* must be called before any mallocs */ + if (pledge("stdio rpath getpw dns id", NULL) != 0) + fatal("%s: pledge: %s", __progname, strerror(errno)); + /* Ensure that stdin and stdout are connected */ if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) exit(1); @@ -245,23 +252,26 @@ main(int argc, char **argv) if (!found) fatal("no hostkey found"); + if (pledge("stdio dns", NULL) != 0) + fatal("%s: pledge: %s", __progname, strerror(errno)); + if ((b = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); + fatal("%s: sshbuf_new failed", __progname); if (ssh_msg_recv(STDIN_FILENO, b) < 0) fatal("ssh_msg_recv failed"); if ((r = sshbuf_get_u8(b, &rver)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal("%s: buffer error: %s", __progname, 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)); + fatal("%s: buffer error: %s", __progname, 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"); if ((r = sshbuf_get_string(b, &data, &dlen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal("%s: buffer error: %s", __progname, ssh_err(r)); if (valid_request(pw, host, &key, data, dlen) < 0) fatal("not a valid request"); free(host); @@ -277,19 +287,20 @@ main(int argc, char **argv) if (!found) { if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) - fatal("%s: sshkey_fingerprint failed", __func__); + fatal("%s: sshkey_fingerprint failed", __progname); fatal("no matching hostkey found for key %s %s", sshkey_type(key), fp ? fp : ""); } - if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, 0)) != 0) + if ((r = sshkey_sign(keys[i], &signature, &slen, data, dlen, NULL, 0)) + != 0) fatal("sshkey_sign failed: %s", ssh_err(r)); free(data); /* send reply */ sshbuf_reset(b); if ((r = sshbuf_put_string(b, signature, slen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); + fatal("%s: buffer error: %s", __progname, ssh_err(r)); if (ssh_msg_send(STDOUT_FILENO, version, b) == -1) fatal("ssh_msg_send failed"); diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 8c74864aa362..fac0167e6f14 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.5 2014/06/24 01:13:21 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.6 2015/12/11 00:20:04 mmcc Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -173,7 +173,7 @@ pkcs11_start_helper(void) close(pair[0]); close(pair[1]); execlp(_PATH_SSH_PKCS11_HELPER, _PATH_SSH_PKCS11_HELPER, - (char *) 0); + (char *)NULL); fprintf(stderr, "exec: %s: %s\n", _PATH_SSH_PKCS11_HELPER, strerror(errno)); _exit(1); diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0 index 7fac805ffb95..47aa7bdcdb9c 100644 --- a/ssh-pkcs11-helper.0 +++ b/ssh-pkcs11-helper.0 @@ -22,4 +22,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 5.8 July 16, 2013 OpenBSD 5.8 +OpenBSD 5.9 July 16, 2013 OpenBSD 5.9 diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index f2d586395472..53f41c555f40 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.11 2015/08/20 22:32:42 deraadt Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.12 2016/02/15 09:47:49 dtucker Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -280,6 +280,7 @@ main(int argc, char **argv) extern char *__progname; + ssh_malloc_init(); /* must be called before any mallocs */ TAILQ_INIT(&pkcs11_keylist); pkcs11_init(0); diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 92614a52d64d..d1f750db0410 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.21 2015/07/18 08:02:17 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.22 2016/02/12 00:20:30 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -322,8 +322,10 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, k11->slotidx = slotidx; /* identify key object on smartcard */ k11->keyid_len = keyid_attrib->ulValueLen; - k11->keyid = xmalloc(k11->keyid_len); - memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + if (k11->keyid_len > 0) { + k11->keyid = xmalloc(k11->keyid_len); + memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); + } k11->orig_finish = def->finish; memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); k11->rsa_method.name = "pkcs11"; diff --git a/ssh-rsa.c b/ssh-rsa.c index cdc18a4162c7..53d44d1f31a2 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.53 2015/06/15 01:32:50 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.58 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -36,16 +36,56 @@ static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); +static const char * +rsa_hash_alg_ident(int hash_alg) +{ + switch (hash_alg) { + case SSH_DIGEST_SHA1: + return "ssh-rsa"; + case SSH_DIGEST_SHA256: + return "rsa-sha2-256"; + case SSH_DIGEST_SHA512: + return "rsa-sha2-512"; + } + return NULL; +} + +static int +rsa_hash_alg_from_ident(const char *ident) +{ + if (strcmp(ident, "ssh-rsa") == 0) + return SSH_DIGEST_SHA1; + if (strcmp(ident, "rsa-sha2-256") == 0) + return SSH_DIGEST_SHA256; + if (strcmp(ident, "rsa-sha2-512") == 0) + return SSH_DIGEST_SHA512; + return -1; +} + +static int +rsa_hash_alg_nid(int type) +{ + switch (type) { + case SSH_DIGEST_SHA1: + return NID_sha1; + case SSH_DIGEST_SHA256: + return NID_sha256; + case SSH_DIGEST_SHA512: + return NID_sha512; + default: + return -1; + } +} + /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */ int ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, - const u_char *data, size_t datalen, u_int compat) + const u_char *data, size_t datalen, const char *alg_ident) { - int hash_alg; u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; size_t slen; u_int dlen, len; - int nid, ret = SSH_ERR_INTERNAL_ERROR; + int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; if (lenp != NULL) @@ -53,16 +93,21 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, if (sigp != NULL) *sigp = NULL; - if (key == NULL || key->rsa == NULL || - sshkey_type_plain(key->type) != KEY_RSA) + if (alg_ident == NULL || strlen(alg_ident) == 0 || + strncmp(alg_ident, "ssh-rsa-cert", strlen("ssh-rsa-cert")) == 0) + hash_alg = SSH_DIGEST_SHA1; + else + hash_alg = rsa_hash_alg_from_ident(alg_ident); + if (key == NULL || key->rsa == NULL || hash_alg == -1 || + sshkey_type_plain(key->type) != KEY_RSA || + BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_INVALID_ARGUMENT; slen = RSA_size(key->rsa); if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; /* hash the data */ - hash_alg = SSH_DIGEST_SHA1; - nid = NID_sha1; + nid = rsa_hash_alg_nid(hash_alg); if ((dlen = ssh_digest_bytes(hash_alg)) == 0) return SSH_ERR_INTERNAL_ERROR; if ((ret = ssh_digest_memory(hash_alg, data, datalen, @@ -91,7 +136,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ret = SSH_ERR_ALLOC_FAIL; goto out; } - if ((ret = sshbuf_put_cstring(b, "ssh-rsa")) != 0 || + if ((ret = sshbuf_put_cstring(b, rsa_hash_alg_ident(hash_alg))) != 0 || (ret = sshbuf_put_string(b, sig, slen)) != 0) goto out; len = sshbuf_len(b); @@ -111,15 +156,13 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, explicit_bzero(sig, slen); free(sig); } - if (b != NULL) - sshbuf_free(b); + sshbuf_free(b); return ret; } int ssh_rsa_verify(const struct sshkey *key, - const u_char *signature, size_t signaturelen, - const u_char *data, size_t datalen, u_int compat) + const u_char *sig, size_t siglen, const u_char *data, size_t datalen) { char *ktype = NULL; int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; @@ -132,13 +175,13 @@ ssh_rsa_verify(const struct sshkey *key, BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_INVALID_ARGUMENT; - if ((b = sshbuf_from(signature, signaturelen)) == NULL) + if ((b = sshbuf_from(sig, siglen)) == NULL) return SSH_ERR_ALLOC_FAIL; if (sshbuf_get_cstring(b, &ktype, NULL) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } - if (strcmp("ssh-rsa", ktype) != 0) { + if ((hash_alg = rsa_hash_alg_from_ident(ktype)) == -1) { ret = SSH_ERR_KEY_TYPE_MISMATCH; goto out; } @@ -167,7 +210,6 @@ ssh_rsa_verify(const struct sshkey *key, explicit_bzero(sigblob, diff); len = modlen; } - hash_alg = SSH_DIGEST_SHA1; if ((dlen = ssh_digest_bytes(hash_alg)) == 0) { ret = SSH_ERR_INTERNAL_ERROR; goto out; @@ -183,10 +225,8 @@ ssh_rsa_verify(const struct sshkey *key, explicit_bzero(sigblob, len); free(sigblob); } - if (ktype != NULL) - free(ktype); - if (b != NULL) - sshbuf_free(b); + free(ktype); + sshbuf_free(b); explicit_bzero(digest, sizeof(digest)); return ret; } @@ -196,6 +236,7 @@ ssh_rsa_verify(const struct sshkey *key, * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn */ + /* * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) * oiw(14) secsig(3) algorithms(2) 26 } @@ -209,25 +250,71 @@ static const u_char id_sha1[] = { 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ }; +/* + * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html + * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) + * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) + * id-sha256(1) } + */ +static const u_char id_sha256[] = { + 0x30, 0x31, /* type Sequence, length 0x31 (49) */ + 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ + 0x06, 0x09, /* type OID, length 0x09 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ + 0x05, 0x00, /* NULL */ + 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ +}; + +/* + * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html + * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) + * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) + * id-sha256(3) } + */ +static const u_char id_sha512[] = { + 0x30, 0x51, /* type Sequence, length 0x51 (81) */ + 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ + 0x06, 0x09, /* type OID, length 0x09 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */ + 0x05, 0x00, /* NULL */ + 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */ +}; + +static int +rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) +{ + switch (hash_alg) { + case SSH_DIGEST_SHA1: + *oidp = id_sha1; + *oidlenp = sizeof(id_sha1); + break; + case SSH_DIGEST_SHA256: + *oidp = id_sha256; + *oidlenp = sizeof(id_sha256); + break; + case SSH_DIGEST_SHA512: + *oidp = id_sha512; + *oidlenp = sizeof(id_sha512); + break; + default: + return SSH_ERR_INVALID_ARGUMENT; + } + return 0; +} + static int openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, u_char *sigbuf, size_t siglen, RSA *rsa) { - size_t ret, rsasize = 0, oidlen = 0, hlen = 0; - int len, oidmatch, hashmatch; + size_t rsasize = 0, oidlen = 0, hlen = 0; + int ret, len, oidmatch, hashmatch; const u_char *oid = NULL; u_char *decrypted = NULL; + if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0) + return ret; ret = SSH_ERR_INTERNAL_ERROR; - switch (hash_alg) { - case SSH_DIGEST_SHA1: - oid = id_sha1; - oidlen = sizeof(id_sha1); - hlen = 20; - break; - default: - goto done; - } + hlen = ssh_digest_bytes(hash_alg); if (hashlen != hlen) { ret = SSH_ERR_INVALID_ARGUMENT; goto done; diff --git a/ssh.0 b/ssh.0 index ad4817aff0fd..9aaf4367d0e2 100644 --- a/ssh.0 +++ b/ssh.0 @@ -8,22 +8,19 @@ SYNOPSIS [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] - [-Q cipher | cipher-auth | mac | kex | key | protocol-version] - [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] - [user@]hostname [command] + [-Q query_option] [-R address] [-S ctl_path] [-W host:port] + [-w local_tun[:remote_tun]] [user@]hostname [command] DESCRIPTION ssh (SSH client) is a program for logging into a remote machine and for - executing commands on a remote machine. It is intended to replace rlogin - and rsh, and provide secure encrypted communications between two - untrusted hosts over an insecure network. X11 connections, arbitrary TCP - ports and UNIX-domain sockets can also be forwarded over the secure - channel. + executing commands on a remote machine. It is intended to provide secure + encrypted communications between two untrusted hosts over an insecure + network. X11 connections, arbitrary TCP ports and UNIX-domain sockets + can also be forwarded over the secure channel. ssh connects and logs into the specified hostname (with optional user name). The user must prove his/her identity to the remote machine using - one of several methods depending on the protocol version used (see - below). + one of several methods (see below). If command is specified, it is executed on the remote host instead of a login shell. @@ -144,9 +141,11 @@ DESCRIPTION ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file. It is possible to have multiple -i options - (and multiple identities specified in configuration files). ssh - will also try to load certificate information from the filename - obtained by appending -cert.pub to identity filenames. + (and multiple identities specified in configuration files). If + no certificates have been explicitly specified by the + CertificateFile directive, ssh will also try to load certificate + information from the filename obtained by appending -cert.pub to + identity filenames. -K Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server. @@ -190,12 +189,12 @@ DESCRIPTION details. -m mac_spec - Additionally, for protocol version 2 a comma-separated list of - MAC (message authentication code) algorithms can be specified in - order of preference. See the MACs keyword for more information. + A comma-separated list of MAC (message authentication code) + algorithms, specified in order of preference. See the MACs + keyword for more information. -N Do not execute a remote command. This is useful for just - forwarding ports (protocol version 2 only). + forwarding ports. -n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background. A @@ -224,6 +223,7 @@ DESCRIPTION of the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress @@ -232,6 +232,7 @@ DESCRIPTION CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs + CertificateFile ChallengeResponseAuthentication CheckHostIP Cipher @@ -312,13 +313,14 @@ 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 | protocol-version + -Q query_option 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) - and protocol-version (supported SSH protocol versions). + integrity codes), kex (key exchange algorithms), key (key types), + key-cert (certificate key types), key-plain (non-certificate key + types), and protocol-version (supported SSH protocol versions). -q Quiet mode. Causes most warning and diagnostic messages to be suppressed. @@ -361,10 +363,9 @@ DESCRIPTION ssh_config(5) for details. -s May be used to request invocation of a subsystem on the remote - system. Subsystems are a feature of the SSH2 protocol which - facilitate the use of SSH as a secure transport for other - applications (eg. sftp(1)). The subsystem is specified as the - remote command. + system. Subsystems facilitate the use of SSH as a secure + transport for other applications (e.g. sftp(1)). The subsystem + is specified as the remote command. -T Disable pseudo-terminal allocation. @@ -383,8 +384,7 @@ DESCRIPTION -W host:port Requests that standard input and output on the client be forwarded to host on port over the secure channel. Implies -N, - -T, ExitOnForwardFailure and ClearAllForwardings. Works with - Protocol version 2 only. + -T, ExitOnForwardFailure and ClearAllForwardings. -w local_tun[:remote_tun] Requests tunnel device forwarding with the specified tun(4) @@ -427,20 +427,16 @@ DESCRIPTION AUTHENTICATION The OpenSSH SSH client supports SSH protocols 1 and 2. The default is to use protocol 2 only, though this can be changed via the Protocol option - in ssh_config(5) or the -1 and -2 options (see above). Both protocols - support similar authentication methods, but protocol 2 is the default - since it provides additional mechanisms for confidentiality (the traffic - is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) and - integrity (hmac-md5, hmac-sha1, hmac-sha2-256, hmac-sha2-512, umac-64, - umac-128, hmac-ripemd160). Protocol 1 lacks a strong mechanism for - ensuring the integrity of the connection. + in ssh_config(5) or the -1 and -2 options (see above). Protocol 1 should + not be used and is only offered to support legacy devices. It suffers + from a number of cryptographic weaknesses and doesn't support many of the + advanced features available for protocol 2. The methods available for authentication are: GSSAPI-based authentication, host-based authentication, public key authentication, challenge-response authentication, and password authentication. Authentication methods are tried in the order specified above, though - protocol 2 has a configuration option to change the default order: - PreferredAuthentications. + PreferredAuthentications can be used to change the default order. Host-based authentication works as follows: If the machine the user logs in from is listed in /etc/hosts.equiv or /etc/shosts.equiv on the remote @@ -463,10 +459,8 @@ 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 - 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. + one of the DSA, ECDSA, Ed25519 or RSA algorithms. The HISTORY section of + ssl(8) contains a brief discussion of the DSA and RSA algorithms. The file ~/.ssh/authorized_keys lists the public keys that are permitted for logging in. When the user logs in, the ssh program tells the server @@ -475,13 +469,12 @@ AUTHENTICATION the corresponding public key is authorized to accept the account. 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 - ~/.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 - directory. The user should then copy the public key to + the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (DSA), + ~/.ssh/id_ecdsa (ECDSA), ~/.ssh/id_ed25519 (Ed25519), or ~/.ssh/id_rsa + (RSA) and stores the public key in ~/.ssh/identity.pub (protocol 1), + ~/.ssh/id_dsa.pub (DSA), ~/.ssh/id_ecdsa.pub (ECDSA), + ~/.ssh/id_ed25519.pub (Ed25519), or ~/.ssh/id_rsa.pub (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, and has one key per line, though the lines can be very long. After this, @@ -495,15 +488,13 @@ AUTHENTICATION more information. The most convenient way to use public key or certificate authentication - may be with an authentication agent. See ssh-agent(1) for more - information. + may be with an authentication agent. See ssh-agent(1) and (optionally) + the AddKeysToAgent directive in ssh_config(5) for more information. Challenge-response authentication works as follows: The server sends an - arbitrary "challenge" text, and prompts for a response. Protocol 2 - allows multiple challenges and responses; protocol 1 is restricted to - just one challenge/response. Examples of challenge-response - authentication include BSD Authentication (see login.conf(5)) and PAM - (some non-OpenBSD systems). + arbitrary "challenge" text, and prompts for a response. Examples of + challenge-response authentication include BSD Authentication (see + login.conf(5)) and PAM (some non-OpenBSD systems). Finally, if other authentication methods fail, ssh prompts the user for a password. The password is sent to the remote host for checking; however, @@ -565,8 +556,8 @@ ESCAPE CHARACTERS ~? Display a list of escape characters. - ~B Send a BREAK to the remote system (only useful for SSH protocol - version 2 and if the peer supports it). + ~B Send a BREAK to the remote system (only useful if the peer + supports it). ~C Open command line. Currently this allows the addition of port forwardings using the -L, -R and -D options (see above). It also @@ -577,8 +568,8 @@ ESCAPE CHARACTERS PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option. - ~R Request rekeying of the connection (only useful for SSH protocol - version 2 and if the peer supports it). + ~R Request rekeying of the connection (only useful if the peer + supports it). ~V Decrease the verbosity (LogLevel) when errors are being written to stderr. @@ -892,12 +883,7 @@ FILES /etc/ssh/ssh_host_ed25519_key /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys and are - used for host-based authentication. If protocol version 1 is - used, ssh must be setuid root, since the host key is readable - only by root. For protocol version 2, ssh uses ssh-keysign(8) to - access the host keys, eliminating the requirement that ssh be - setuid root when host-based authentication is used. By default - ssh is not setuid root. + used for host-based authentication. /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared @@ -969,4 +955,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.8 July 20, 2015 OpenBSD 5.8 +OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 diff --git a/ssh.1 b/ssh.1 index 2ea0a2058d17..cc5334338fd9 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.361 2015/07/20 18:44:12 millert Exp $ -.Dd $Mdocdate: July 20 2015 $ +.\" $OpenBSD: ssh.1,v 1.369 2016/02/17 07:38:19 jmc Exp $ +.Dd $Mdocdate: February 17 2016 $ .Dt SSH 1 .Os .Sh NAME @@ -58,7 +58,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 | protocol-version +.Op Fl Q Ar query_option .Op Fl R Ar address .Op Fl S Ar ctl_path .Op Fl W Ar host : Ns Ar port @@ -70,8 +70,7 @@ .Nm (SSH client) is a program for logging into a remote machine and for executing commands on a remote machine. -It is intended to replace rlogin and rsh, -and provide secure encrypted communications between +It is intended to provide secure encrypted communications between two untrusted hosts over an insecure network. X11 connections, arbitrary TCP ports and .Ux Ns -domain @@ -85,7 +84,7 @@ connects and logs into the specified name). The user must prove his/her identity to the remote machine using one of several methods -depending on the protocol version used (see below). +(see below). .Pp If .Ar command @@ -304,6 +303,9 @@ It is possible to have multiple .Fl i options (and multiple identities specified in configuration files). +If no certificates have been explicitly specified by the +.Cm CertificateFile +directive, .Nm will also try to load certificate information from the filename obtained by appending @@ -400,17 +402,15 @@ in for details. .Pp .It Fl m Ar mac_spec -Additionally, for protocol version 2 a comma-separated list of MAC -(message authentication code) algorithms can -be specified in order of preference. +A comma-separated list of MAC (message authentication code) algorithms, +specified in order of preference. See the .Cm MACs keyword for more information. .Pp .It Fl N Do not execute a remote command. -This is useful for just forwarding ports -(protocol version 2 only). +This is useful for just forwarding ports. .Pp .It Fl n Redirects stdin from @@ -460,6 +460,7 @@ For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact +.It AddKeysToAgent .It AddressFamily .It BatchMode .It BindAddress @@ -468,6 +469,7 @@ For full details of the options listed below, and their possible values, see .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs +.It CertificateFile .It ChallengeResponseAuthentication .It CheckHostIP .It Cipher @@ -550,7 +552,7 @@ Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. .Pp -.It Fl Q Cm cipher | cipher-auth | mac | kex | key | protocol-version +.It Fl Q Ar query_option Queries .Nm for the algorithms supported for the specified version 2. @@ -564,7 +566,11 @@ The available features are: .Ar kex (key exchange algorithms), .Ar key -(key types) and +(key types), +.Ar key-cert +(certificate key types), +.Ar key-plain +(non-certificate key types), and .Ar protocol-version (supported SSH protocol versions). .Pp @@ -656,8 +662,8 @@ for details. .Pp .It Fl s May be used to request invocation of a subsystem on the remote system. -Subsystems are a feature of the SSH2 protocol which facilitate the use -of SSH as a secure transport for other applications (eg.\& +Subsystems facilitate the use of SSH +as a secure transport for other applications (e.g.\& .Xr sftp 1 ) . The subsystem is specified as the remote command. .Pp @@ -702,7 +708,6 @@ Implies .Cm ExitOnForwardFailure and .Cm ClearAllForwardings . -Works with Protocol version 2 only. .Pp .It Fl w Xo .Ar local_tun Ns Op : Ns Ar remote_tun @@ -787,15 +792,10 @@ or the and .Fl 2 options (see above). -Both protocols support similar authentication methods, -but protocol 2 is the default since -it provides additional mechanisms for confidentiality -(the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) -and integrity (hmac-md5, hmac-sha1, -hmac-sha2-256, hmac-sha2-512, -umac-64, umac-128, hmac-ripemd160). -Protocol 1 lacks a strong mechanism for ensuring the -integrity of the connection. +Protocol 1 should not be used +and is only offered to support legacy devices. +It suffers from a number of cryptographic weaknesses +and doesn't support many of the advanced features available for protocol 2. .Pp The methods available for authentication are: GSSAPI-based authentication, @@ -804,8 +804,9 @@ public key authentication, challenge-response authentication, and password authentication. Authentication methods are tried in the order specified above, -though protocol 2 has a configuration option to change the default order: -.Cm PreferredAuthentications . +though +.Cm PreferredAuthentications +can be used to change the default order. .Pp Host-based authentication works as follows: If the machine the user logs in from is listed in @@ -849,8 +850,6 @@ 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. -Protocol 1 is restricted to using only RSA keys, -but protocol 2 may use any. The HISTORY section of .Xr ssl 8 contains a brief discussion of the DSA and RSA algorithms. @@ -872,26 +871,26 @@ This stores the private key in .Pa ~/.ssh/identity (protocol 1), .Pa ~/.ssh/id_dsa -(protocol 2 DSA), +(DSA), .Pa ~/.ssh/id_ecdsa -(protocol 2 ECDSA), +(ECDSA), .Pa ~/.ssh/id_ed25519 -(protocol 2 Ed25519), +(Ed25519), or .Pa ~/.ssh/id_rsa -(protocol 2 RSA) +(RSA) and stores the public key in .Pa ~/.ssh/identity.pub (protocol 1), .Pa ~/.ssh/id_dsa.pub -(protocol 2 DSA), +(DSA), .Pa ~/.ssh/id_ecdsa.pub -(protocol 2 ECDSA), +(ECDSA), .Pa ~/.ssh/id_ed25519.pub -(protocol 2 Ed25519), +(Ed25519), or .Pa ~/.ssh/id_rsa.pub -(protocol 2 RSA) +(RSA) in the user's home directory. The user should then copy the public key to @@ -919,14 +918,16 @@ The most convenient way to use public key or certificate authentication may be with an authentication agent. See .Xr ssh-agent 1 +and (optionally) the +.Cm AddKeysToAgent +directive in +.Xr ssh_config 5 for more information. .Pp Challenge-response authentication works as follows: The server sends an arbitrary .Qq challenge text, and prompts for a response. -Protocol 2 allows multiple challenges and responses; -protocol 1 is restricted to just one challenge/response. Examples of challenge-response authentication include .Bx Authentication (see @@ -1025,7 +1026,7 @@ at logout when waiting for forwarded connection / X11 sessions to terminate. Display a list of escape characters. .It Cm ~B Send a BREAK to the remote system -(only useful for SSH protocol version 2 and if the peer supports it). +(only useful if the peer supports it). .It Cm ~C Open command line. Currently this allows the addition of port forwardings using the @@ -1058,7 +1059,7 @@ Basic help is available, using the option. .It Cm ~R Request rekeying of the connection -(only useful for SSH protocol version 2 and if the peer supports it). +(only useful if the peer supports it). .It Cm ~V Decrease the verbosity .Pq Ic LogLevel @@ -1526,20 +1527,6 @@ The file format and configuration options are described in .It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys and are used for host-based authentication. -If protocol version 1 is used, -.Nm -must be setuid root, since the host key is readable only by root. -For protocol version 2, -.Nm -uses -.Xr ssh-keysign 8 -to access the host keys, -eliminating the requirement that -.Nm -be setuid root when host-based authentication is used. -By default -.Nm -is not setuid root. .Pp .It Pa /etc/ssh/ssh_known_hosts Systemwide list of known host keys. diff --git a/ssh.c b/ssh.c index 67c1ebfa2e07..f9ff91f049d5 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.420 2015/07/30 00:01:34 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.436 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -105,7 +105,6 @@ #include "match.h" #include "msg.h" #include "uidswap.h" -#include "roaming.h" #include "version.h" #include "ssherr.h" #include "myproposal.h" @@ -203,11 +202,9 @@ usage(void) fprintf(stderr, "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 address] [-l login_name] [-m mac_spec]\n" -" [-O ctl_cmd] [-o option] [-p port]\n" -" [-Q cipher | cipher-auth | mac | kex | key]\n" -" [-R address] [-S ctl_path] [-W host:port]\n" +" [-F configfile] [-I pkcs11] [-i identity_file] [-L address]\n" +" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" +" [-Q query_option] [-R address] [-S ctl_path] [-W host:port]\n" " [-w local_tun[:remote_tun]] [user@]hostname [command]\n" ); exit(255); @@ -252,7 +249,7 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) if (port <= 0) port = default_ssh_port(); - snprintf(strport, sizeof strport, "%u", port); + snprintf(strport, sizeof strport, "%d", port); memset(&hints, 0, sizeof(hints)); hints.ai_family = options.address_family == -1 ? AF_UNSPEC : options.address_family; @@ -406,6 +403,17 @@ resolve_canonicalize(char **hostp, int port) return addrs; } + /* If domain name is anchored, then resolve it now */ + if ((*hostp)[strlen(*hostp) - 1] == '.') { + debug3("%s: name is fully qualified", __func__); + fullhost = xstrdup(*hostp); + if ((addrs = resolve_host(fullhost, port, 0, + newname, sizeof(newname))) != NULL) + goto found; + free(fullhost); + goto notfound; + } + /* Don't apply canonicalization to sufficiently-qualified hostnames */ ndots = 0; for (cp = *hostp; *cp != '\0'; cp++) { @@ -429,6 +437,7 @@ resolve_canonicalize(char **hostp, int port) free(fullhost); continue; } + found: /* Remove trailing '.' */ fullhost[strlen(fullhost) - 1] = '\0'; /* Follow CNAME if requested */ @@ -440,6 +449,7 @@ resolve_canonicalize(char **hostp, int port) *hostp = fullhost; return addrs; } + notfound: if (!options.canonicalize_fallback_local) fatal("%s: Could not resolve host \"%s\"", __progname, *hostp); debug2("%s: host %s not found in any suffix", __func__, *hostp); @@ -506,7 +516,7 @@ main(int ac, char **av) 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]; + char cname[NI_MAXHOST], uidstr[32], *conn_hash_hex; struct stat st; struct passwd *pw; int timeout_ms; @@ -516,8 +526,8 @@ main(int ac, char **av) struct addrinfo *addrs = NULL; struct ssh_digest_ctx *md; u_char conn_hash[SSH_DIGEST_MAX_LENGTH]; - char *conn_hash_hex; + ssh_malloc_init(); /* must be called before any mallocs */ /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -627,7 +637,7 @@ main(int ac, char **av) use_syslog = 1; break; case 'E': - logfile = xstrdup(optarg); + logfile = optarg; break; case 'G': config_test = 1; @@ -704,16 +714,18 @@ main(int ac, char **av) options.gss_deleg_creds = 1; break; case 'i': - if (stat(optarg, &st) < 0) { + p = tilde_expand_filename(optarg, original_real_uid); + if (stat(p, &st) < 0) fprintf(stderr, "Warning: Identity file %s " - "not accessible: %s.\n", optarg, + "not accessible: %s.\n", p, strerror(errno)); - break; - } - add_identity_file(&options, NULL, optarg, 1); + else + add_identity_file(&options, NULL, p, 1); + free(p); break; case 'I': #ifdef ENABLE_PKCS11 + free(options.pkcs11_provider); options.pkcs11_provider = xstrdup(optarg); #else fprintf(stderr, "no support for PKCS#11.\n"); @@ -798,6 +810,7 @@ main(int ac, char **av) if (ciphers_valid(*optarg == '+' ? optarg + 1 : optarg)) { /* SSH2 only */ + free(options.ciphers); options.ciphers = xstrdup(optarg); options.cipher = SSH_CIPHER_INVALID; break; @@ -817,9 +830,10 @@ main(int ac, char **av) options.ciphers = xstrdup(KEX_CLIENT_ENCRYPT); break; case 'm': - if (mac_valid(optarg)) + if (mac_valid(optarg)) { + free(options.macs); options.macs = xstrdup(optarg); - else { + } else { fprintf(stderr, "Unknown mac type '%s'\n", optarg); exit(255); @@ -897,8 +911,7 @@ main(int ac, char **av) subsystem_flag = 1; break; case 'S': - if (options.control_path != NULL) - free(options.control_path); + free(options.control_path); options.control_path = xstrdup(optarg); break; case 'b': @@ -980,10 +993,8 @@ main(int ac, char **av) */ if (use_syslog && logfile != NULL) fatal("Can't specify both -y and -E"); - if (logfile != NULL) { + if (logfile != NULL) log_redirect_stderr_to(logfile); - free(logfile); - } log_init(argv0, options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, !use_syslog); @@ -1084,6 +1095,8 @@ main(int ac, char **av) "disabling"); options.update_hostkeys = 0; } + if (options.connection_attempts <= 0) + fatal("Invalid number of ConnectionAttempts"); #ifndef HAVE_CYGWIN if (original_effective_uid != 0) options.use_privileged_port = 0; @@ -1122,6 +1135,7 @@ main(int ac, char **av) strlcpy(shorthost, thishost, sizeof(shorthost)); shorthost[strcspn(thishost, ".")] = '\0'; snprintf(portstr, sizeof(portstr), "%d", options.port); + snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid); if ((md = ssh_digest_start(SSH_DIGEST_SHA1)) == NULL || ssh_digest_update(md, thishost, strlen(thishost)) < 0 || @@ -1164,6 +1178,7 @@ main(int ac, char **av) "p", portstr, "r", options.user, "u", pw->pw_name, + "i", uidstr, (char *)NULL); free(cp); } @@ -1184,6 +1199,7 @@ main(int ac, char **av) * have yet resolved the hostname. Do so now. */ if (addrs == NULL && options.proxy_command == NULL) { + debug2("resolving \"%s\" port %d", host, options.port); if ((addrs = resolve_host(host, options.port, 1, cname, sizeof(cname))) == NULL) cleanup_exit(255); /* resolve_host logs the error */ @@ -1227,8 +1243,10 @@ main(int ac, char **av) sensitive_data.keys[i] = NULL; PRIV_START; +#if WITH_SSH1 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, _PATH_HOST_KEY_FILE, "", NULL, NULL); +#endif #ifdef OPENSSL_HAS_ECC sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, _PATH_HOST_ECDSA_KEY_FILE, "", NULL); @@ -1353,6 +1371,10 @@ main(int ac, char **av) options.identity_keys[i] = NULL; } } + for (i = 0; i < options.num_certificate_files; i++) { + free(options.certificate_files[i]); + options.certificate_files[i] = NULL; + } exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); @@ -1604,6 +1626,7 @@ ssh_session(void) struct winsize ws; char *cp; const char *display; + char *proto = NULL, *data = NULL; /* Enable compression if requested. */ if (options.compression) { @@ -1674,13 +1697,9 @@ ssh_session(void) display = getenv("DISPLAY"); if (display == NULL && options.forward_x11) debug("X11 forwarding requested but DISPLAY not set"); - if (options.forward_x11 && display != NULL) { - char *proto, *data; - /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, - options.forward_x11_timeout, - &proto, &data); + if (options.forward_x11 && client_x11_get_proto(display, + options.xauth_location, options.forward_x11_trusted, + options.forward_x11_timeout, &proto, &data) == 0) { /* Request forwarding with authentication spoofing. */ debug("Requesting X11 forwarding with authentication " "spoofing."); @@ -1770,6 +1789,7 @@ ssh_session2_setup(int id, int success, void *arg) extern char **environ; const char *display; int interactive = tty_flag; + char *proto = NULL, *data = NULL; if (!success) return; /* No need for error message, channels code sens one */ @@ -1777,12 +1797,9 @@ ssh_session2_setup(int id, int success, void *arg) display = getenv("DISPLAY"); if (display == NULL && options.forward_x11) debug("X11 forwarding requested but DISPLAY not set"); - if (options.forward_x11 && display != NULL) { - char *proto, *data; - /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, - options.forward_x11_timeout, &proto, &data); + if (options.forward_x11 && client_x11_get_proto(display, + options.xauth_location, options.forward_x11_trusted, + options.forward_x11_timeout, &proto, &data) == 0) { /* Request forwarding with authentication spoofing. */ debug("Requesting X11 forwarding with authentication " "spoofing."); @@ -1936,25 +1953,30 @@ ssh_session2(void) options.escape_char : SSH_ESCAPECHAR_NONE, id); } +/* Loads all IdentityFile and CertificateFile keys */ static void load_public_identity_files(void) { char *filename, *cp, thishost[NI_MAXHOST]; char *pwdir = NULL, *pwname = NULL; - int i = 0; Key *public; struct passwd *pw; - u_int n_ids; + int i; + u_int n_ids, n_certs; char *identity_files[SSH_MAX_IDENTITY_FILES]; Key *identity_keys[SSH_MAX_IDENTITY_FILES]; + char *certificate_files[SSH_MAX_CERTIFICATE_FILES]; + struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; #ifdef ENABLE_PKCS11 Key **keys; int nkeys; #endif /* PKCS11 */ - n_ids = 0; + n_ids = n_certs = 0; memset(identity_files, 0, sizeof(identity_files)); memset(identity_keys, 0, sizeof(identity_keys)); + memset(certificate_files, 0, sizeof(certificate_files)); + memset(certificates, 0, sizeof(certificates)); #ifdef ENABLE_PKCS11 if (options.pkcs11_provider != NULL && @@ -1986,6 +2008,7 @@ load_public_identity_files(void) if (n_ids >= SSH_MAX_IDENTITY_FILES || strcasecmp(options.identity_files[i], "none") == 0) { free(options.identity_files[i]); + options.identity_files[i] = NULL; continue; } cp = tilde_expand_filename(options.identity_files[i], @@ -2004,7 +2027,12 @@ load_public_identity_files(void) if (++n_ids >= SSH_MAX_IDENTITY_FILES) continue; - /* Try to add the certificate variant too */ + /* + * If no certificates have been explicitly listed then try + * to add the default certificate variant too. + */ + if (options.num_certificate_files != 0) + continue; xasprintf(&cp, "%s-cert", filename); public = key_load_public(cp, NULL); debug("identity file %s type %d", cp, @@ -2021,14 +2049,50 @@ load_public_identity_files(void) continue; } identity_keys[n_ids] = public; - /* point to the original path, most likely the private key */ - identity_files[n_ids] = xstrdup(filename); + identity_files[n_ids] = cp; n_ids++; } + + if (options.num_certificate_files > SSH_MAX_CERTIFICATE_FILES) + fatal("%s: too many certificates", __func__); + for (i = 0; i < options.num_certificate_files; i++) { + cp = tilde_expand_filename(options.certificate_files[i], + original_real_uid); + filename = percent_expand(cp, "d", pwdir, + "u", pwname, "l", thishost, "h", host, + "r", options.user, (char *)NULL); + free(cp); + + public = key_load_public(filename, NULL); + debug("certificate file %s type %d", filename, + public ? public->type : -1); + free(options.certificate_files[i]); + options.certificate_files[i] = NULL; + if (public == NULL) { + free(filename); + continue; + } + if (!key_is_cert(public)) { + debug("%s: key %s type %s is not a certificate", + __func__, filename, key_type(public)); + key_free(public); + free(filename); + continue; + } + certificate_files[n_certs] = filename; + certificates[n_certs] = public; + ++n_certs; + } + options.num_identity_files = n_ids; memcpy(options.identity_files, identity_files, sizeof(identity_files)); memcpy(options.identity_keys, identity_keys, sizeof(identity_keys)); + options.num_certificate_files = n_certs; + memcpy(options.certificate_files, + certificate_files, sizeof(certificate_files)); + memcpy(options.certificates, certificates, sizeof(certificates)); + explicit_bzero(pwname, strlen(pwname)); free(pwname); explicit_bzero(pwdir, strlen(pwdir)); diff --git a/ssh.h b/ssh.h index 39c7e18af10f..50467a792bdf 100644 --- a/ssh.h +++ b/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.81 2015/08/04 05:23:06 djm Exp $ */ +/* $OpenBSD: ssh.h,v 1.83 2015/12/11 03:19:09 djm Exp $ */ /* * Author: Tatu Ylonen @@ -18,6 +18,12 @@ /* Default port number. */ #define SSH_DEFAULT_PORT 22 +/* + * Maximum number of certificate files that can be specified + * in configuration files or on the command line. + */ +#define SSH_MAX_CERTIFICATE_FILES 100 + /* * Maximum number of RSA authentication identity files that can be specified * in configuration files or on the command line. @@ -29,7 +35,7 @@ * Current value permits 16kbit RSA and RSA1 keys and 8kbit DSA keys, with * some room for options and comments. */ -#define SSH_MAX_PUBKEY_BYTES 8192 +#define SSH_MAX_PUBKEY_BYTES 16384 /* * Major protocol version. Different version indicates major incompatibility diff --git a/ssh2.h b/ssh2.h index 59417e6121d1..5d1918bf8012 100644 --- a/ssh2.h +++ b/ssh2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh2.h,v 1.15 2014/01/29 06:18:35 djm Exp $ */ +/* $OpenBSD: ssh2.h,v 1.17 2016/01/14 16:17:40 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -80,6 +80,7 @@ #define SSH2_MSG_DEBUG 4 #define SSH2_MSG_SERVICE_REQUEST 5 #define SSH2_MSG_SERVICE_ACCEPT 6 +#define SSH2_MSG_EXT_INFO 7 /* transport layer: alg negotiation */ @@ -164,13 +165,6 @@ #define SSH2_EXTENDED_DATA_STDERR 1 -/* kex messages for resume@appgate.com */ -#define SSH2_MSG_KEX_ROAMING_RESUME 30 -#define SSH2_MSG_KEX_ROAMING_AUTH_REQUIRED 31 -#define SSH2_MSG_KEX_ROAMING_AUTH 32 -#define SSH2_MSG_KEX_ROAMING_AUTH_OK 33 -#define SSH2_MSG_KEX_ROAMING_AUTH_FAIL 34 - /* Certificate types for OpenSSH certificate keys extension */ #define SSH2_CERT_TYPE_USER 1 #define SSH2_CERT_TYPE_HOST 2 diff --git a/ssh_api.c b/ssh_api.c index 6c712584f49e..f544f006b20f 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh_api.c,v 1.4 2015/02/16 22:13:32 djm Exp $ */ +/* $OpenBSD: ssh_api.c,v 1.5 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * @@ -40,8 +40,8 @@ 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); +int _ssh_host_key_sign(struct sshkey *, struct sshkey *, + u_char **, size_t *, const u_char *, size_t, const char *, u_int); /* * stubs for the server side implementation of kex. @@ -49,7 +49,7 @@ int _ssh_host_key_sign(struct sshkey *, struct sshkey *, u_char **, */ int use_privsep = 0; int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, - u_char *, u_int, u_int); + u_char *, u_int, char *, u_int); DH *mm_choose_dh(int, int, int); /* Define these two variables here so that they are part of the library */ @@ -58,7 +58,7 @@ 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) + u_char *data, u_int datalen, char *alg, u_int compat) { return (-1); } @@ -530,8 +530,8 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) 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) + u_char **signature, size_t *slen, const u_char *data, size_t dlen, + const char *alg, u_int compat) { - return sshkey_sign(privkey, signature, slen, data, dlen, compat); + return sshkey_sign(privkey, signature, slen, data, dlen, alg, compat); } diff --git a/ssh_config b/ssh_config index 03a228fbd483..90fb63f0bf43 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.28 2013/09/16 11:35:43 sthen Exp $ +# $OpenBSD: ssh_config,v 1.30 2016/02/20 23:06:23 sobrado Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -34,8 +34,10 @@ # IdentityFile ~/.ssh/identity # IdentityFile ~/.ssh/id_rsa # IdentityFile ~/.ssh/id_dsa +# IdentityFile ~/.ssh/id_ecdsa +# IdentityFile ~/.ssh/id_ed25519 # Port 22 -# Protocol 2,1 +# Protocol 2 # Cipher 3des # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc # MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 diff --git a/ssh_config.0 b/ssh_config.0 index 67133cd4d49b..b823c021cbd1 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -59,7 +59,7 @@ 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 critera or the single token all which always + using one or more criteria 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 @@ -94,10 +94,23 @@ DESCRIPTION matches against the name of the local user running ssh(1) (this keyword may be useful in system-wide ssh_config files). + AddKeysToAgent + Specifies whether keys should be automatically added to a running + ssh-agent(1). If this option is set to M-bM-^@M-^\yesM-bM-^@M-^] and a key is loaded + from a file, the key and its passphrase are added to the agent + with the default lifetime, as if by ssh-add(1). If this option + is set to M-bM-^@M-^\askM-bM-^@M-^], ssh will require confirmation using the + SSH_ASKPASS program before adding a key (see ssh-add(1) for + details). If this option is set to M-bM-^@M-^\confirmM-bM-^@M-^], each use of the + key must be confirmed, as if the -c option was specified to + ssh-add(1). If this option is set to M-bM-^@M-^\noM-bM-^@M-^], no keys are added to + the agent. The argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\confirmM-bM-^@M-^], M-bM-^@M-^\askM-bM-^@M-^], or + M-bM-^@M-^\noM-bM-^@M-^]. The default is M-bM-^@M-^\noM-bM-^@M-^]. + AddressFamily Specifies which address family to use when connecting. Valid 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). + only). The default is M-bM-^@M-^\anyM-bM-^@M-^]. BatchMode If set to M-bM-^@M-^\yesM-bM-^@M-^], passphrase/password querying will be disabled. @@ -157,6 +170,22 @@ DESCRIPTION canonicalized to names in the M-bM-^@M-^\*.b.example.comM-bM-^@M-^] or M-bM-^@M-^\*.c.example.comM-bM-^@M-^] domains. + CertificateFile + Specifies a file from which the user's certificate is read. A + corresponding private key must be provided separately in order to + use this certificate either from an IdentityFile directive or -i + flag to ssh(1), via ssh-agent(1), or via a PKCS11Provider. + + The file name may use the tilde syntax to refer to a user's home + 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 certificate files specified in + configuration files; these certificates will be tried in + sequence. Multiple CertificateFile directives will add to the + list of certificates used for authentication. + ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The argument to this keyword must be M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The default is @@ -208,9 +237,7 @@ DESCRIPTION chacha20-poly1305@openssh.com, aes128-ctr,aes192-ctr,aes256-ctr, aes128-gcm@openssh.com,aes256-gcm@openssh.com, - arcfour256,arcfour128, - aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc, - aes192-cbc,aes256-cbc,arcfour + aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc The list of available ciphers may also be obtained using the -Q option of ssh(1) with an argument of M-bM-^@M-^\cipherM-bM-^@M-^]. @@ -282,13 +309,13 @@ DESCRIPTION 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) and be placed in a directory that is not - writable by other users. This ensures that shared connections - are uniquely identified. + the remote login username, M-bM-^@M-^X%uM-bM-^@M-^Y by the username and M-bM-^@M-^X%iM-bM-^@M-^Y by the + numeric user ID (uid) 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) 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 @@ -342,8 +369,12 @@ DESCRIPTION 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 M-bM-^@M-^\yesM-bM-^@M-^] or M-bM-^@M-^\noM-bM-^@M-^]. The - default is M-bM-^@M-^\noM-bM-^@M-^]. + port forwardings, (e.g. if either end is unable to bind and + listen on a specified port). Note that ExitOnForwardFailure does + not apply to connections made over port forwardings and will not, + for example, cause ssh(1) to exit if TCP connections to the + ultimate forwarding destination fail. 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 @@ -415,12 +446,11 @@ DESCRIPTION GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. - The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol - version 2 only. + The default is M-bM-^@M-^\noM-bM-^@M-^]. GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is - M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol version 2 only. + M-bM-^@M-^\noM-bM-^@M-^]. HashKnownHosts Indicates that ssh(1) should hash host names and addresses when @@ -434,8 +464,7 @@ DESCRIPTION HostbasedAuthentication Specifies whether to try rhosts based authentication with public 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. + default is M-bM-^@M-^\noM-bM-^@M-^]. HostbasedKeyTypes Specifies the key types that will be used for hostbased @@ -455,11 +484,11 @@ DESCRIPTION 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 - client wants to use in order of preference. Alternately if the - specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified - key types will be appended to the default set instead of - replacing them. The default for this option is: + Specifies the host key algorithms that the client wants to use in + order of preference. Alternately if the specified value begins + with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified key types will be + appended to the default set instead of replacing them. The + default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, @@ -496,8 +525,9 @@ DESCRIPTION IdentitiesOnly 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 + and certificate files explicitly configured in the ssh_config + files or passed on the ssh(1) command-line, even if ssh-agent(1) + or a PKCS11Provider offers more identities. The argument to this 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 M-bM-^@M-^\noM-bM-^@M-^]. @@ -509,9 +539,10 @@ DESCRIPTION ~/.ssh/id_ed25519 and ~/.ssh/id_rsa for protocol version 2. Additionally, any identities represented by the authentication agent will be used for authentication unless IdentitiesOnly is - set. ssh(1) will try to load certificate information from the - filename obtained by appending -cert.pub to the path of a - specified IdentityFile. + set. If no certificates have been explicitly specified by + CertificateFile, ssh(1) will try to load certificate information + from the filename obtained by appending -cert.pub to the path of + a 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: M-bM-^@M-^X%dM-bM-^@M-^Y (local @@ -526,7 +557,9 @@ DESCRIPTION IdentityFile may be used in conjunction with IdentitiesOnly to select which identities in an agent are offered during - authentication. + authentication. IdentityFile may also be used in conjunction + with CertificateFile in order to provide any certificate also + needed for authentication with the identity. IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they @@ -620,11 +653,11 @@ DESCRIPTION higher levels of verbose output. 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. If the specified value begins with a - M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified algorithms will be appended to - the default set instead of replacing them. + order of preference. The MAC algorithm is used for data + integrity protection. Multiple algorithms must be comma- + separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, + then the specified algorithms will be appended to the default set + instead of replacing them. The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC after encryption (encrypt-then-mac). These are considered safer and @@ -634,13 +667,9 @@ DESCRIPTION umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, + hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, - hmac-sha2-256,hmac-sha2-512, - hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com, - hmac-ripemd160-etm@openssh.com, - hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com, - hmac-md5,hmac-sha1,hmac-ripemd160, - hmac-sha1-96,hmac-md5-96 + hmac-sha2-256,hmac-sha2-512,hmac-sha1 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-^]. @@ -677,10 +706,10 @@ DESCRIPTION default is 22. PreferredAuthentications - Specifies the order in which the client should try protocol 2 - authentication methods. This allows a client to prefer one - method (e.g. keyboard-interactive) over another method (e.g. - password). The default is: + Specifies the order in which the client should try authentication + methods. This allows a client to prefer one method (e.g. + keyboard-interactive) over another method (e.g. password). The + default is: gssapi-with-mic,hostbased,publickey, keyboard-interactive,password @@ -690,7 +719,9 @@ DESCRIPTION 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 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. + version 2 is not available. The default is M-bM-^@M-^X2M-bM-^@M-^Y. Protocol 1 + suffers from a number of cryptographic weaknesses and should not + be used. It is only offered to support legacy devices. ProxyCommand Specifies the command to use to connect to the server. The @@ -740,7 +771,6 @@ DESCRIPTION PubkeyAuthentication Specifies whether to try public key authentication. 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-^]. - This option applies to protocol version 2 only. RekeyLimit Specifies the maximum amount of data that may be transmitted @@ -755,7 +785,6 @@ DESCRIPTION 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 @@ -808,8 +837,7 @@ DESCRIPTION SendEnv Specifies what variables from the local environ(7) should be sent - to the server. Note that environment passing is only supported - for protocol 2. The server must also support it, and the server + to the server. The server must also support it, and the server must be configured to accept these environment variables. Note that the TERM environment variable is always sent whenever a pseudo-terminal is requested as it is required by the protocol. @@ -838,15 +866,14 @@ DESCRIPTION The default value is 3. If, for example, ServerAliveInterval (see below) is set to 15 and ServerAliveCountMax is left at the default, if the server becomes unresponsive, ssh will disconnect - after approximately 45 seconds. This option applies to protocol - version 2 only. + after approximately 45 seconds. ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, ssh(1) will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to - the server. This option applies to protocol version 2 only. + the server. StreamLocalBindMask Sets the octal file creation mode mask (umask) used when creating @@ -924,7 +951,7 @@ DESCRIPTION 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 + already trusted or explicitly 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 @@ -960,8 +987,7 @@ DESCRIPTION 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 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. + is M-bM-^@M-^\noM-bM-^@M-^]. See also VERIFYING HOST KEYS in ssh(1). @@ -1023,4 +1049,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 5.8 August 14, 2015 OpenBSD 5.8 +OpenBSD 5.9 February 20, 2016 OpenBSD 5.9 diff --git a/ssh_config.5 b/ssh_config.5 index a47f3ca9e3e2..caf13a62d09f 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.215 2015/08/14 15:32:41 jmc Exp $ -.Dd $Mdocdate: August 14 2015 $ +.\" $OpenBSD: ssh_config.5,v 1.228 2016/02/20 23:01:46 sobrado Exp $ +.Dd $Mdocdate: February 20 2016 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -139,7 +139,7 @@ or keyword) to be used only when the conditions following the .Cm Match keyword are satisfied. -Match conditions are specified using one or more critera +Match conditions are specified using one or more criteria or the single token .Cm all which always matches. @@ -221,6 +221,39 @@ keyword matches against the name of the local user running (this keyword may be useful in system-wide .Nm files). +.It Cm AddKeysToAgent +Specifies whether keys should be automatically added to a running +.Xr ssh-agent 1 . +If this option is set to +.Dq yes +and a key is loaded from a file, the key and its passphrase are added to +the agent with the default lifetime, as if by +.Xr ssh-add 1 . +If this option is set to +.Dq ask , +.Nm ssh +will require confirmation using the +.Ev SSH_ASKPASS +program before adding a key (see +.Xr ssh-add 1 +for details). +If this option is set to +.Dq confirm , +each use of the key must be confirmed, as if the +.Fl c +option was specified to +.Xr ssh-add 1 . +If this option is set to +.Dq no , +no keys are added to the agent. +The argument must be +.Dq yes , +.Dq confirm , +.Dq ask , +or +.Dq no . +The default is +.Dq no . .It Cm AddressFamily Specifies which address family to use when connecting. Valid arguments are @@ -229,6 +262,8 @@ Valid arguments are (use IPv4 only), or .Dq inet6 (use IPv6 only). +The default is +.Dq any . .It Cm BatchMode If set to .Dq yes , @@ -325,6 +360,41 @@ to be canonicalized to names in the or .Dq *.c.example.com domains. +.It Cm CertificateFile +Specifies a file from which the user's certificate is read. +A corresponding private key must be provided separately in order +to use this certificate either +from an +.Cm IdentityFile +directive or +.Fl i +flag to +.Xr ssh 1 , +via +.Xr ssh-agent 1 , +or via a +.Cm PKCS11Provider . +.Pp +The file name may use the tilde +syntax to refer to a user's home directory or one of the following +escape characters: +.Ql %d +(local user's home directory), +.Ql %u +(local user name), +.Ql %l +(local host name), +.Ql %h +(remote host name) or +.Ql %r +(remote user name). +.Pp +It is possible to have multiple certificate files specified in +configuration files; these certificates will be tried in sequence. +Multiple +.Cm CertificateFile +directives will add to the list of certificates used for +authentication. .It Cm ChallengeResponseAuthentication Specifies whether to use challenge-response authentication. The argument to this keyword must be @@ -418,9 +488,7 @@ The default is: chacha20-poly1305@openssh.com, aes128-ctr,aes192-ctr,aes256-ctr, aes128-gcm@openssh.com,aes256-gcm@openssh.com, -arcfour256,arcfour128, -aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc, -aes192-cbc,aes256-cbc,arcfour +aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc .Ed .Pp The list of available ciphers may also be obtained using the @@ -538,8 +606,11 @@ the destination port, .Ql %r by the remote login username, .Ql %u -by the username of the user running -.Xr ssh 1 , and +by the username and +.Ql %i +by the numeric user ID (uid) of the user running +.Xr ssh 1 , +and .Ql \&%C by a hash of the concatenation: %l%h%p%r. It is recommended that any @@ -639,7 +710,14 @@ data). Specifies whether .Xr ssh 1 should terminate the connection if it cannot set up all requested -dynamic, tunnel, local, and remote port forwardings. +dynamic, tunnel, local, and remote port forwardings, (e.g.\& +if either end is unable to bind and listen on a specified port). +Note that +.Cm ExitOnForwardFailure +does not apply to connections made over port forwardings and will not, +for example, cause +.Xr ssh 1 +to exit if TCP connections to the ultimate forwarding destination fail. The argument must be .Dq yes or @@ -748,12 +826,10 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . -Note that this option applies to protocol version 2 only. .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is .Dq no . -Note that this option applies to protocol version 2 only. .It Cm HashKnownHosts Indicates that .Xr ssh 1 @@ -780,9 +856,6 @@ or .Dq no . The default is .Dq no . -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. @@ -807,7 +880,7 @@ option of .Xr ssh 1 may be used to list supported key types. .It Cm HostKeyAlgorithms -Specifies the protocol version 2 host key algorithms +Specifies the host key algorithms that the client wants to use in order of preference. Alternately if the specified value begins with a .Sq + @@ -859,9 +932,13 @@ specifications). .It Cm IdentitiesOnly Specifies that .Xr ssh 1 -should only use the authentication identity files configured in the +should only use the authentication identity and certificate files explicitly +configured in the .Nm -files, +files +or passed on the +.Xr ssh 1 +command-line, even if .Xr ssh-agent 1 or a @@ -891,6 +968,8 @@ Additionally, any identities represented by the authentication agent will be used for authentication unless .Cm IdentitiesOnly is set. +If no certificates have been explicitly specified by +.Cm CertificateFile , .Xr ssh 1 will try to load certificate information from the filename obtained by appending @@ -924,6 +1003,11 @@ differs from that of other configuration directives). may be used in conjunction with .Cm IdentitiesOnly to select which identities in an agent are offered during authentication. +.Cm IdentityFile +may also be used in conjunction with +.Cm CertificateFile +in order to provide any certificate also needed for authentication with +the identity. .It Cm IgnoreUnknown Specifies a pattern-list of unknown options to be ignored if they are encountered in configuration parsing. @@ -1083,8 +1167,7 @@ DEBUG2 and DEBUG3 each specify higher levels of verbose output. .It Cm 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. +The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma-separated. If the specified value begins with a .Sq + @@ -1100,13 +1183,9 @@ The default is: .Bd -literal -offset indent umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, +hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, -hmac-sha2-256,hmac-sha2-512, -hmac-md5-etm@openssh.com,hmac-sha1-etm@openssh.com, -hmac-ripemd160-etm@openssh.com, -hmac-sha1-96-etm@openssh.com,hmac-md5-96-etm@openssh.com, -hmac-md5,hmac-sha1,hmac-ripemd160, -hmac-sha1-96,hmac-md5-96 +hmac-sha2-256,hmac-sha2-512,hmac-sha1 .Ed .Pp The list of available MAC algorithms may also be obtained using the @@ -1160,8 +1239,7 @@ private RSA key. Specifies the port number to connect on the remote host. The default is 22. .It Cm PreferredAuthentications -Specifies the order in which the client should try protocol 2 -authentication methods. +Specifies the order in which the client should try authentication methods. This allows a client to prefer one method (e.g.\& .Cm keyboard-interactive ) over another method (e.g.\& @@ -1187,6 +1265,9 @@ will try version 2 and fall back to version 1 if version 2 is not available. The default is .Sq 2 . +Protocol 1 suffers from a number of cryptographic weaknesses and should +not be used. +It is only offered to support legacy devices. .It Cm ProxyCommand Specifies the command to use to connect to the server. The command @@ -1267,7 +1348,6 @@ or .Dq no . The default is .Dq yes . -This option applies to protocol version 2 only. .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of @@ -1293,7 +1373,6 @@ is .Dq 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. .It Cm RemoteForward Specifies that a TCP port on the remote machine be forwarded over the secure channel to the specified host and port from the local machine. @@ -1386,7 +1465,6 @@ Note that this option applies to protocol version 1 only. Specifies what variables from the local .Xr environ 7 should be sent to the server. -Note that environment passing is only supported for protocol 2. The server must also support it, and the server must be configured to accept these environment variables. Note that the @@ -1434,7 +1512,6 @@ If, for example, .Cm ServerAliveCountMax is left at the default, if the server becomes unresponsive, ssh will disconnect after approximately 45 seconds. -This option applies to protocol version 2 only. .It Cm ServerAliveInterval Sets a timeout interval in seconds after which if no data has been received from the server, @@ -1443,7 +1520,6 @@ will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server. -This option applies to protocol version 2 only. .It Cm StreamLocalBindMask Sets the octal file creation mode mask .Pq umask @@ -1575,7 +1651,7 @@ 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. +host was already trusted or explicitly accepted by the user. If .Cm UpdateHostKeys is set to @@ -1640,7 +1716,6 @@ or .Dq ask . The default is .Dq no . -Note that this option applies to protocol version 2 only. .Pp See also VERIFYING HOST KEYS in .Xr ssh 1 . diff --git a/sshbuf-getput-basic.c b/sshbuf-getput-basic.c index 8ff8a0a28893..23e0fd7c1cf4 100644 --- a/sshbuf-getput-basic.c +++ b/sshbuf-getput-basic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-getput-basic.c,v 1.4 2015/01/14 15:02:39 djm Exp $ */ +/* $OpenBSD: sshbuf-getput-basic.c,v 1.5 2015/10/20 23:24:25 mmcc Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -131,7 +131,7 @@ sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp, size_t *lenp) *lenp = 0; if ((r = sshbuf_peek_string_direct(buf, &p, &len)) < 0) return r; - if (valp != 0) + if (valp != NULL) *valp = p; if (lenp != NULL) *lenp = len; @@ -168,7 +168,7 @@ sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp, SSHBUF_DBG(("SSH_ERR_MESSAGE_INCOMPLETE")); return SSH_ERR_MESSAGE_INCOMPLETE; } - if (valp != 0) + if (valp != NULL) *valp = p + 4; if (lenp != NULL) *lenp = len; @@ -448,7 +448,7 @@ sshbuf_get_bignum2_bytes_direct(struct sshbuf *buf, d++; len--; } - if (valp != 0) + if (valp != NULL) *valp = d; if (lenp != NULL) *lenp = len; diff --git a/sshbuf.c b/sshbuf.c index 19e162c0748e..4d6e0ea0acb0 100644 --- a/sshbuf.c +++ b/sshbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.c,v 1.4 2015/10/05 17:11:21 djm Exp $ */ +/* $OpenBSD: sshbuf.c,v 1.6 2016/01/12 23:42:54 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -163,10 +163,8 @@ sshbuf_free(struct sshbuf *buf) * If we are a child, the free our parent to decrement its reference * count and possibly free it. */ - if (buf->parent != NULL) { - sshbuf_free(buf->parent); - buf->parent = NULL; - } + sshbuf_free(buf->parent); + buf->parent = NULL; /* * If we are a parent with still-extant children, then don't free just * yet. The last child's call to sshbuf_free should decrement our diff --git a/sshbuf.h b/sshbuf.h index eb0d92e10211..63495fbb075a 100644 --- a/sshbuf.h +++ b/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.4 2015/01/14 15:02:39 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.6 2015/12/10 07:01:35 mmcc Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -120,12 +120,12 @@ size_t sshbuf_len(const struct sshbuf *buf); size_t sshbuf_avail(const struct sshbuf *buf); /* - * Returns a read-only pointer to the start of the the data in buf + * Returns a read-only pointer to the start of the data in buf */ const u_char *sshbuf_ptr(const struct sshbuf *buf); /* - * Returns a mutable pointer to the start of the the data in buf, or + * Returns a mutable pointer to the start of the data in buf, or * NULL if the buffer is read-only. */ u_char *sshbuf_mutable_ptr(const struct sshbuf *buf); @@ -241,45 +241,48 @@ int sshbuf_b64tod(struct sshbuf *buf, const char *b64); /* Macros for decoding/encoding integers */ #define PEEK_U64(p) \ - (((u_int64_t)(((u_char *)(p))[0]) << 56) | \ - ((u_int64_t)(((u_char *)(p))[1]) << 48) | \ - ((u_int64_t)(((u_char *)(p))[2]) << 40) | \ - ((u_int64_t)(((u_char *)(p))[3]) << 32) | \ - ((u_int64_t)(((u_char *)(p))[4]) << 24) | \ - ((u_int64_t)(((u_char *)(p))[5]) << 16) | \ - ((u_int64_t)(((u_char *)(p))[6]) << 8) | \ - (u_int64_t)(((u_char *)(p))[7])) + (((u_int64_t)(((const u_char *)(p))[0]) << 56) | \ + ((u_int64_t)(((const u_char *)(p))[1]) << 48) | \ + ((u_int64_t)(((const u_char *)(p))[2]) << 40) | \ + ((u_int64_t)(((const u_char *)(p))[3]) << 32) | \ + ((u_int64_t)(((const u_char *)(p))[4]) << 24) | \ + ((u_int64_t)(((const u_char *)(p))[5]) << 16) | \ + ((u_int64_t)(((const u_char *)(p))[6]) << 8) | \ + (u_int64_t)(((const u_char *)(p))[7])) #define PEEK_U32(p) \ - (((u_int32_t)(((u_char *)(p))[0]) << 24) | \ - ((u_int32_t)(((u_char *)(p))[1]) << 16) | \ - ((u_int32_t)(((u_char *)(p))[2]) << 8) | \ - (u_int32_t)(((u_char *)(p))[3])) + (((u_int32_t)(((const u_char *)(p))[0]) << 24) | \ + ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \ + ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \ + (u_int32_t)(((const u_char *)(p))[3])) #define PEEK_U16(p) \ - (((u_int16_t)(((u_char *)(p))[0]) << 8) | \ - (u_int16_t)(((u_char *)(p))[1])) + (((u_int16_t)(((const u_char *)(p))[0]) << 8) | \ + (u_int16_t)(((const u_char *)(p))[1])) #define POKE_U64(p, v) \ do { \ - ((u_char *)(p))[0] = (((u_int64_t)(v)) >> 56) & 0xff; \ - ((u_char *)(p))[1] = (((u_int64_t)(v)) >> 48) & 0xff; \ - ((u_char *)(p))[2] = (((u_int64_t)(v)) >> 40) & 0xff; \ - ((u_char *)(p))[3] = (((u_int64_t)(v)) >> 32) & 0xff; \ - ((u_char *)(p))[4] = (((u_int64_t)(v)) >> 24) & 0xff; \ - ((u_char *)(p))[5] = (((u_int64_t)(v)) >> 16) & 0xff; \ - ((u_char *)(p))[6] = (((u_int64_t)(v)) >> 8) & 0xff; \ - ((u_char *)(p))[7] = ((u_int64_t)(v)) & 0xff; \ + const u_int64_t __v = (v); \ + ((u_char *)(p))[0] = (__v >> 56) & 0xff; \ + ((u_char *)(p))[1] = (__v >> 48) & 0xff; \ + ((u_char *)(p))[2] = (__v >> 40) & 0xff; \ + ((u_char *)(p))[3] = (__v >> 32) & 0xff; \ + ((u_char *)(p))[4] = (__v >> 24) & 0xff; \ + ((u_char *)(p))[5] = (__v >> 16) & 0xff; \ + ((u_char *)(p))[6] = (__v >> 8) & 0xff; \ + ((u_char *)(p))[7] = __v & 0xff; \ } while (0) #define POKE_U32(p, v) \ do { \ - ((u_char *)(p))[0] = (((u_int64_t)(v)) >> 24) & 0xff; \ - ((u_char *)(p))[1] = (((u_int64_t)(v)) >> 16) & 0xff; \ - ((u_char *)(p))[2] = (((u_int64_t)(v)) >> 8) & 0xff; \ - ((u_char *)(p))[3] = ((u_int64_t)(v)) & 0xff; \ + const u_int32_t __v = (v); \ + ((u_char *)(p))[0] = (__v >> 24) & 0xff; \ + ((u_char *)(p))[1] = (__v >> 16) & 0xff; \ + ((u_char *)(p))[2] = (__v >> 8) & 0xff; \ + ((u_char *)(p))[3] = __v & 0xff; \ } while (0) #define POKE_U16(p, v) \ do { \ - ((u_char *)(p))[0] = (((u_int64_t)(v)) >> 8) & 0xff; \ - ((u_char *)(p))[1] = ((u_int64_t)(v)) & 0xff; \ + const u_int16_t __v = (v); \ + ((u_char *)(p))[0] = (__v >> 8) & 0xff; \ + ((u_char *)(p))[1] = __v & 0xff; \ } while (0) /* Internal definitions follow. Exposed for regress tests */ diff --git a/sshconnect.c b/sshconnect.c index 17fbe39b007a..356ec79f0a0e 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.263 2015/08/20 22:32:42 deraadt Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.271 2016/01/14 22:56:56 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -59,12 +59,12 @@ #include "readconf.h" #include "atomicio.h" #include "dns.h" -#include "roaming.h" #include "monitor_fdpass.h" #include "ssh2.h" #include "version.h" #include "authfile.h" #include "ssherr.h" +#include "authfd.h" char *client_version_string = NULL; char *server_version_string = NULL; @@ -167,6 +167,7 @@ ssh_proxy_fdpass_connect(const char *host, u_short port, if ((sock = mm_receive_fd(sp[1])) == -1) fatal("proxy dialer did not pass back a connection"); + close(sp[1]); while (waitpid(pid, NULL, 0) == -1) if (errno != EINTR) @@ -432,7 +433,9 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, char ntop[NI_MAXHOST], strport[NI_MAXSERV]; struct addrinfo *ai; - debug2("ssh_connect: needpriv %d", needpriv); + debug2("%s: needpriv %d", __func__, needpriv); + memset(ntop, 0, sizeof(ntop)); + memset(strport, 0, sizeof(strport)); for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { @@ -451,7 +454,7 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop, if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("ssh_connect: getnameinfo failed"); + error("%s: getnameinfo failed", __func__); continue; } debug("Connecting to %.200s [%.100s] port %s.", @@ -529,7 +532,7 @@ send_client_banner(int connection_out, int minor1) xasprintf(&client_version_string, "SSH-%d.%d-%.100s\n", PROTOCOL_MAJOR_1, minor1, SSH_VERSION); } - if (roaming_atomicio(vwrite, connection_out, client_version_string, + if (atomicio(vwrite, connection_out, client_version_string, strlen(client_version_string)) != strlen(client_version_string)) fatal("write: %.100s", strerror(errno)); chop(client_version_string); @@ -589,7 +592,7 @@ ssh_exchange_identification(int timeout_ms) } } - len = roaming_atomicio(read, connection_in, &buf[i], 1); + len = atomicio(read, connection_in, &buf[i], 1); if (len != 1 && errno == EPIPE) fatal("ssh_exchange_identification: " @@ -925,7 +928,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, options.fingerprint_hash, SSH_FP_RANDOMART); if (fp == NULL || ra == NULL) fatal("%s: sshkey_fingerprint fail", __func__); - logit("Host key fingerprint is %s\n%s\n", fp, ra); + logit("Host key fingerprint is %s\n%s", fp, ra); free(ra); free(fp); } @@ -1236,8 +1239,9 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, int verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { + u_int i; int r = -1, flags = 0; - char *fp = NULL; + char valid[64], *fp = NULL, *cafp = NULL; struct sshkey *plain = NULL; if ((fp = sshkey_fingerprint(host_key, @@ -1247,8 +1251,31 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) goto out; } - debug("Server host key: %s %s", - compat20 ? sshkey_ssh_name(host_key) : sshkey_type(host_key), fp); + if (sshkey_is_cert(host_key)) { + if ((cafp = sshkey_fingerprint(host_key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { + error("%s: fingerprint CA key: %s", + __func__, ssh_err(r)); + r = -1; + goto out; + } + sshkey_format_cert_validity(host_key->cert, + valid, sizeof(valid)); + debug("Server host certificate: %s %s, serial %llu " + "ID \"%s\" CA %s %s valid %s", + sshkey_ssh_name(host_key), fp, + (unsigned long long)host_key->cert->serial, + host_key->cert->key_id, + sshkey_ssh_name(host_key->cert->signature_key), cafp, + valid); + for (i = 0; i < host_key->cert->nprincipals; i++) { + debug2("Server host certificate hostname: %s", + host_key->cert->principals[i]); + } + } else { + debug("Server host key: %s %s", compat20 ? + sshkey_ssh_name(host_key) : sshkey_type(host_key), fp); + } if (sshkey_equal(previous_host_key, host_key)) { debug2("%s: server host key %s %s matches cached key", @@ -1313,6 +1340,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) out: sshkey_free(plain); free(fp); + free(cafp); if (r == 0 && host_key != NULL) { key_free(previous_host_key); previous_host_key = key_from_private(host_key); @@ -1487,3 +1515,30 @@ ssh_local_cmd(const char *args) return (WEXITSTATUS(status)); } + +void +maybe_add_key_to_agent(char *authfile, Key *private, char *comment, + char *passphrase) +{ + int auth_sock = -1, r; + + if (options.add_keys_to_agent == 0) + return; + + if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { + debug3("no authentication agent, not adding key"); + return; + } + + if (options.add_keys_to_agent == 2 && + !ask_permission("Add key %s (%s) to agent?", authfile, comment)) { + debug3("user denied adding this key"); + return; + } + + if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0, + (options.add_keys_to_agent == 3))) == 0) + debug("identity added to agent: %s", authfile); + else + debug("could not add identity to agent: %s (%d)", authfile, r); +} diff --git a/sshconnect.h b/sshconnect.h index 0ea6e99f6171..cf1851a959b7 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.28 2013/10/16 02:31:47 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.29 2015/11/15 22:26:49 jcs Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -55,6 +55,8 @@ void ssh_userauth2(const char *, const char *, char *, Sensitive *); void ssh_put_password(char *); int ssh_local_cmd(const char *); +void maybe_add_key_to_agent(char *, Key *, char *, char *); + /* * Macros to raise/lower permissions. */ diff --git a/sshconnect1.c b/sshconnect1.c index 016abbce5fbd..bfc523bde317 100644 --- a/sshconnect1.c +++ b/sshconnect1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect1.c,v 1.77 2015/01/14 20:05:27 djm Exp $ */ +/* $OpenBSD: sshconnect1.c,v 1.78 2015/11/15 22:26:49 jcs Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -221,7 +221,7 @@ try_rsa_authentication(int idx) { BIGNUM *challenge; Key *public, *private; - char buf[300], *passphrase, *comment, *authfile; + char buf[300], *passphrase = NULL, *comment, *authfile; int i, perm_ok = 1, type, quit; public = options.identity_keys[idx]; @@ -283,13 +283,20 @@ try_rsa_authentication(int idx) debug2("no passphrase given, try next key"); quit = 1; } - explicit_bzero(passphrase, strlen(passphrase)); - free(passphrase); if (private != NULL || quit) break; debug2("bad passphrase given, try again..."); } } + + if (private != NULL) + maybe_add_key_to_agent(authfile, private, comment, passphrase); + + if (passphrase != NULL) { + explicit_bzero(passphrase, strlen(passphrase)); + free(passphrase); + } + /* We no longer need the comment. */ free(comment); diff --git a/sshconnect2.c b/sshconnect2.c index 775103185edd..f79c96beb243 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.226 2015/07/30 00:01:34 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.239 2016/02/23 01:34:14 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -157,14 +157,16 @@ void ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; + char *s; struct kex *kex; int r; xxx_host = host; xxx_hostaddr = hostaddr; - myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal( - options.kex_algorithms); + if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL) + fatal("%s: kex_names_cat", __func__); + myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s); myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(options.ciphers); myproposal[PROPOSAL_ENC_ALGS_STOC] = @@ -217,10 +219,11 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) dispatch_run(DISPATCH_BLOCK, &kex->done, active_state); - if (options.use_roaming && !kex->roaming) { - debug("Roaming not allowed by server"); - options.use_roaming = 0; - } + /* remove ext-info from the KEX proposals for rekeying */ + myproposal[PROPOSAL_KEX_ALGS] = + compat_kex_proposal(options.kex_algorithms); + if ((r = kex_prop2buf(kex->my, myproposal)) != 0) + fatal("kex_prop2buf: %s", ssh_err(r)); session_id2 = kex->session_id; session_id2_len = kex->session_id_len; @@ -284,6 +287,8 @@ struct cauthmethod { int *batch_flag; /* flag in option struct that disables method */ }; +int input_userauth_service_accept(int, u_int32_t, void *); +int input_userauth_ext_info(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 *); @@ -313,7 +318,7 @@ void userauth(Authctxt *, char *); static int sign_and_send_pubkey(Authctxt *, Identity *); static void pubkey_prepare(Authctxt *); static void pubkey_cleanup(Authctxt *); -static Key *load_identity_file(char *, int); +static Key *load_identity_file(Identity *); static Authmethod *authmethod_get(char *authlist); static Authmethod *authmethod_lookup(const char *name); @@ -359,30 +364,12 @@ void ssh_userauth2(const char *local_user, const char *server_user, char *host, Sensitive *sensitive) { + struct ssh *ssh = active_state; Authctxt authctxt; - int type; + int r; if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; - - packet_start(SSH2_MSG_SERVICE_REQUEST); - packet_put_cstring("ssh-userauth"); - packet_send(); - debug("SSH2_MSG_SERVICE_REQUEST sent"); - packet_write_wait(); - type = packet_read(); - if (type != SSH2_MSG_SERVICE_ACCEPT) - fatal("Server denied authentication request: %d", type); - if (packet_remaining() > 0) { - char *reply = packet_get_string(NULL); - debug2("service_accept: %s", reply); - free(reply); - } else { - debug2("buggy server: service_accept w/o service"); - } - packet_check_eom(); - debug("SSH2_MSG_SERVICE_ACCEPT received"); - if (options.preferred_authentications == NULL) options.preferred_authentications = authmethods_get(); @@ -404,21 +391,63 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, if (authctxt.method == NULL) fatal("ssh_userauth2: internal error: cannot send userauth none request"); - /* initial userauth request */ - userauth_none(&authctxt); + if ((r = sshpkt_start(ssh, SSH2_MSG_SERVICE_REQUEST)) != 0 || + (r = sshpkt_put_cstring(ssh, "ssh-userauth")) != 0 || + (r = sshpkt_send(ssh)) != 0) + fatal("%s: %s", __func__, ssh_err(r)); - dispatch_init(&input_userauth_error); - dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); - dispatch_set(SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); - dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); - dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ + ssh_dispatch_init(ssh, &input_userauth_error); + ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info); + ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept); + ssh_dispatch_run(ssh, DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ pubkey_cleanup(&authctxt); - dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); + ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); debug("Authentication succeeded (%s).", authctxt.method->name); } +/* ARGSUSED */ +int +input_userauth_service_accept(int type, u_int32_t seqnr, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct ssh *ssh = active_state; + int r; + + if (ssh_packet_remaining(ssh) > 0) { + char *reply; + + if ((r = sshpkt_get_cstring(ssh, &reply, NULL)) != 0) + goto out; + debug2("service_accept: %s", reply); + free(reply); + } else { + debug2("buggy server: service_accept w/o service"); + } + if ((r = sshpkt_get_end(ssh)) != 0) + goto out; + debug("SSH2_MSG_SERVICE_ACCEPT received"); + + /* initial userauth request */ + userauth_none(authctxt); + + ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error); + ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); + ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_FAILURE, &input_userauth_failure); + ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); + r = 0; + out: + return r; +} + +/* ARGSUSED */ +int +input_userauth_ext_info(int type, u_int32_t seqnr, void *ctxt) +{ + return kex_input_ext_info(type, seqnr, active_state); +} + void userauth(Authctxt *authctxt, char *authlist) { @@ -970,29 +999,48 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) return 0; } +static const char * +identity_sign_encode(struct identity *id) +{ + struct ssh *ssh = active_state; + + if (id->key->type == KEY_RSA) { + switch (ssh->kex->rsa_sha2) { + case 256: + return "rsa-sha2-256"; + case 512: + return "rsa-sha2-512"; + } + } + return key_ssh_name(id->key); +} + static int 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; + const char *alg; + + alg = identity_sign_encode(id); /* the agent supports this key */ - if (id->agent_fd) + if (id->agent_fd != -1) return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, - data, datalen, compat); + data, datalen, alg, 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 (sshkey_sign(id->key, sigp, lenp, data, datalen, + return (sshkey_sign(id->key, sigp, lenp, data, datalen, alg, compat)); /* load the private key from the file */ - if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL) - return (-1); /* XXX return decent error code */ - ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat); + if ((prv = load_identity_file(id)) == NULL) + return SSH_ERR_KEY_NOT_FOUND; + ret = sshkey_sign(prv, sigp, lenp, data, datalen, alg, compat); sshkey_free(prv); return (ret); } @@ -1001,18 +1049,17 @@ static int sign_and_send_pubkey(Authctxt *authctxt, Identity *id) { Buffer b; + Identity *private_id; u_char *blob, *signature; - u_int bloblen; size_t slen; - u_int skip = 0; - int ret = -1; - int have_sig = 1; + u_int bloblen, skip = 0; + int matched, ret = -1, have_sig = 1; char *fp; 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); + debug3("%s: %s %s", __func__, key_type(id->key), fp); free(fp); if (key_to_blob(id->key, &blob, &bloblen) == 0) { @@ -1040,14 +1087,46 @@ sign_and_send_pubkey(Authctxt *authctxt, Identity *id) } else { buffer_put_cstring(&b, authctxt->method->name); buffer_put_char(&b, have_sig); - buffer_put_cstring(&b, key_ssh_name(id->key)); + buffer_put_cstring(&b, identity_sign_encode(id)); } buffer_put_string(&b, blob, bloblen); + /* + * If the key is an certificate, try to find a matching private key + * and use it to complete the signature. + * If no such private key exists, return failure and continue with + * other methods of authentication. + */ + if (key_is_cert(id->key)) { + matched = 0; + TAILQ_FOREACH(private_id, &authctxt->keys, next) { + if (sshkey_equal_public(id->key, private_id->key) && + id->key->type != private_id->key->type) { + id = private_id; + matched = 1; + break; + } + } + if (matched) { + debug2("%s: using private key \"%s\"%s for " + "certificate", __func__, id->filename, + id->agent_fd != -1 ? " from agent" : ""); + } else { + /* XXX maybe verbose/error? */ + debug("%s: no private key for certificate " + "\"%s\"", __func__, id->filename); + free(blob); + buffer_free(&b); + return 0; + } + } + /* generate signature */ ret = identity_sign(id, &signature, &slen, buffer_ptr(&b), buffer_len(&b), datafellows); if (ret != 0) { + if (ret != SSH_ERR_KEY_NOT_FOUND) + error("%s: signing failed: %s", __func__, ssh_err(ret)); free(blob); buffer_free(&b); return 0; @@ -1110,7 +1189,7 @@ send_pubkey_test(Authctxt *authctxt, Identity *id) packet_put_cstring(authctxt->method->name); packet_put_char(have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) - packet_put_cstring(key_ssh_name(id->key)); + packet_put_cstring(identity_sign_encode(id)); packet_put_string(blob, bloblen); free(blob); packet_send(); @@ -1118,20 +1197,20 @@ send_pubkey_test(Authctxt *authctxt, Identity *id) } static Key * -load_identity_file(char *filename, int userprovided) +load_identity_file(Identity *id) { - Key *private; - char prompt[300], *passphrase; + Key *private = NULL; + char prompt[300], *passphrase, *comment; int r, perm_ok = 0, quit = 0, i; struct stat st; - if (stat(filename, &st) < 0) { - (userprovided ? logit : debug3)("no such identity: %s: %s", - filename, strerror(errno)); + if (stat(id->filename, &st) < 0) { + (id->userprovided ? logit : debug3)("no such identity: %s: %s", + id->filename, strerror(errno)); return NULL; } snprintf(prompt, sizeof prompt, - "Enter passphrase for key '%.100s': ", filename); + "Enter passphrase for key '%.100s': ", id->filename); for (i = 0; i <= options.number_of_password_prompts; i++) { if (i == 0) passphrase = ""; @@ -1143,8 +1222,8 @@ load_identity_file(char *filename, int userprovided) break; } } - switch ((r = sshkey_load_private_type(KEY_UNSPEC, filename, - passphrase, &private, NULL, &perm_ok))) { + switch ((r = sshkey_load_private_type(KEY_UNSPEC, id->filename, + passphrase, &private, &comment, &perm_ok))) { case 0: break; case SSH_ERR_KEY_WRONG_PASSPHRASE: @@ -1158,20 +1237,25 @@ load_identity_file(char *filename, int userprovided) case SSH_ERR_SYSTEM_ERROR: if (errno == ENOENT) { debug2("Load key \"%s\": %s", - filename, ssh_err(r)); + id->filename, ssh_err(r)); quit = 1; break; } /* FALLTHROUGH */ default: - error("Load key \"%s\": %s", filename, ssh_err(r)); + error("Load key \"%s\": %s", id->filename, ssh_err(r)); quit = 1; break; } + if (!quit && private != NULL && id->agent_fd == -1 && + !(id->key && id->isprivate)) + maybe_add_key_to_agent(id->filename, private, comment, + passphrase); if (i > 0) { explicit_bzero(passphrase, strlen(passphrase)); free(passphrase); } + free(comment); if (private != NULL || quit) break; } @@ -1180,9 +1264,11 @@ load_identity_file(char *filename, int userprovided) /* * try keys in the following order: - * 1. agent keys that are found in the config file - * 2. other agent keys - * 3. keys that are only listed in the config file + * 1. certificates listed in the config file + * 2. other input certificates + * 3. agent keys that are found in the config file + * 4. other agent keys + * 5. keys that are only listed in the config file */ static void pubkey_prepare(Authctxt *authctxt) @@ -1190,7 +1276,7 @@ pubkey_prepare(Authctxt *authctxt) struct identity *id, *id2, *tmp; struct idlist agent, files, *preferred; struct sshkey *key; - int agent_fd, i, r, found; + int agent_fd = -1, i, r, found; size_t j; struct ssh_identitylist *idlist; @@ -1208,6 +1294,7 @@ pubkey_prepare(Authctxt *authctxt) continue; options.identity_keys[i] = NULL; id = xcalloc(1, sizeof(*id)); + id->agent_fd = -1; id->key = key; id->filename = xstrdup(options.identity_files[i]); id->userprovided = options.identity_file_userprovided[i]; @@ -1236,6 +1323,19 @@ pubkey_prepare(Authctxt *authctxt) free(id); } } + /* list of certificates specified by user */ + for (i = 0; i < options.num_certificate_files; i++) { + key = options.certificates[i]; + if (!key_is_cert(key) || key->cert == NULL || + key->cert->type != SSH2_CERT_TYPE_USER) + continue; + id = xcalloc(1, sizeof(*id)); + id->agent_fd = -1; + id->key = key; + id->filename = xstrdup(options.certificate_files[i]); + id->userprovided = options.certificate_file_userprovided[i]; + TAILQ_INSERT_TAIL(preferred, id, next); + } /* list of keys supported by the agent */ if ((r = ssh_get_authentication_socket(&agent_fd)) != 0) { if (r != SSH_ERR_AGENT_NOT_PRESENT) @@ -1245,6 +1345,7 @@ pubkey_prepare(Authctxt *authctxt) if (r != SSH_ERR_AGENT_NO_IDENTITIES) debug("%s: ssh_fetch_identitylist: %s", __func__, ssh_err(r)); + close(agent_fd); } else { for (j = 0; j < idlist->nkeys; j++) { found = 0; @@ -1285,9 +1386,23 @@ pubkey_prepare(Authctxt *authctxt) TAILQ_REMOVE(&files, id, next); TAILQ_INSERT_TAIL(preferred, id, next); } - TAILQ_FOREACH(id, preferred, next) { - debug2("key: %s (%p),%s", id->filename, id->key, - id->userprovided ? " explicit" : ""); + /* finally, filter by PubkeyAcceptedKeyTypes */ + TAILQ_FOREACH_SAFE(id, preferred, next, id2) { + if (id->key != NULL && + match_pattern_list(sshkey_ssh_name(id->key), + options.pubkey_key_types, 0) != 1) { + debug("Skipping %s key %s - " + "not in PubkeyAcceptedKeyTypes", + sshkey_ssh_name(id->key), id->filename); + TAILQ_REMOVE(preferred, id, next); + sshkey_free(id->key); + free(id->filename); + memset(id, 0, sizeof(*id)); + continue; + } + debug2("key: %s (%p)%s%s", id->filename, id->key, + id->userprovided ? ", explicit" : "", + id->agent_fd != -1 ? ", agent" : ""); } } @@ -1301,8 +1416,7 @@ pubkey_cleanup(Authctxt *authctxt) for (id = TAILQ_FIRST(&authctxt->keys); id; id = TAILQ_FIRST(&authctxt->keys)) { TAILQ_REMOVE(&authctxt->keys, id, next); - if (id->key) - sshkey_free(id->key); + sshkey_free(id->key); free(id->filename); free(id); } @@ -1313,12 +1427,6 @@ try_identity(Identity *id) { if (!id->key) return (0); - if (match_pattern_list(sshkey_ssh_name(id->key), - options.pubkey_key_types, 0) != 1) { - debug("Skipping %s key %s for not in PubkeyAcceptedKeyTypes", - sshkey_ssh_name(id->key), id->filename); - return (0); - } if (key_type_plain(id->key->type) == KEY_RSA && (datafellows & SSH_BUG_RSASIGMD5) != 0) { debug("Skipped %s key %s for RSA/MD5 server", @@ -1353,8 +1461,7 @@ userauth_pubkey(Authctxt *authctxt) } } else { debug("Trying private key: %s", id->filename); - id->key = load_identity_file(id->filename, - id->userprovided); + id->key = load_identity_file(id); if (id->key != NULL) { if (try_identity(id)) { id->isprivate = 1; @@ -1513,7 +1620,7 @@ ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp, 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); + execl(_PATH_SSH_KEY_SIGN, _PATH_SSH_KEY_SIGN, (char *)NULL); fatal("%s: exec(%s): %s", __func__, _PATH_SSH_KEY_SIGN, strerror(errno)); } @@ -1685,7 +1792,7 @@ userauth_hostbased(Authctxt *authctxt) 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) + sshbuf_ptr(b), sshbuf_len(b), NULL, datafellows)) != 0) debug("%s: sshkey_sign: %s", __func__, ssh_err(r)); if (r != 0) { error("sign using hostkey %s %s failed", diff --git a/sshd.0 b/sshd.0 index 7980225686ff..7eb05312f3d5 100644 --- a/sshd.0 +++ b/sshd.0 @@ -146,11 +146,11 @@ 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; - protocol 1 only supports RSA keys. For both protocols, each host has a - host-specific key, normally 2048 bits, used to identify the host. + in sshd_config(5). Protocol 1 should not be used and is only offered to + support legacy devices. - Forward security for protocol 1 is provided through an additional server + Each host has a host-specific key, used to identify the host. Partial + forward security for protocol 1 is provided through an additional server key, normally 1024 bits, generated when the server starts. This key is normally regenerated every hour if it has been used, and is never stored on disk. Whenever a client connects, the daemon responds with its public @@ -268,7 +268,7 @@ SSHRC AUTHORIZED_KEYS FILE FORMAT AuthorizedKeysFile specifies the files containing public keys for public - key authentication; if none is specified, the default is + key authentication; if this option is not 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 M-bM-^@M-^X#M-bM-^@M-^Y are ignored as comments). Protocol 1 public keys consist of the following @@ -298,6 +298,10 @@ AUTHORIZED_KEYS FILE FORMAT The following option specifications are supported (note that option keywords are case-insensitive): + agent-forwarding + Enable authentication agent forwarding previously disabled by the + restrict option. + cert-authority Specifies that the listed key is a certification authority (CA) that is trusted to validate signed certificates for user @@ -378,6 +382,9 @@ AUTHORIZED_KEYS FILE FORMAT must be literal domains or addresses. A port specification of * matches any port. + port-forwarding + Enable port forwarding previously disabled by the restrict + principals="principals" On a cert-authority line, specifies allowed principals for certificate authentication as a comma-separated list. At least @@ -386,11 +393,28 @@ AUTHORIZED_KEYS FILE FORMAT ignored for keys that are not marked as trusted certificate signers using the cert-authority option. + pty Permits tty allocation previously disabled by the restrict + option. + + restrict + Enable all restrictions, i.e. disable port, agent and X11 + forwarding, as well as disabling PTY allocation and execution of + ~/.ssh/rc. If any future restriction capabilities are added to + authorized_keys files they will be included in this set. + tunnel="n" Force a tun(4) device on the server. Without this option, the next available device will be used if the client requests a tunnel. + user-rc + Enables execution of ~/.ssh/rc previously disabled by the + restrict option. + + X11-forwarding + Permits X11 forwarding previously disabled by the restrict + option. + An example authorized_keys file: # Comments allowed at start of line @@ -403,6 +427,10 @@ AUTHORIZED_KEYS FILE FORMAT AAAAB5...21S== tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== jane@example.net + restrict,command="uptime" ssh-rsa AAAA1C8...32Tv== + user@example.net + restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5== + user@example.net SSH_KNOWN_HOSTS FILE FORMAT The /etc/ssh/ssh_known_hosts and ~/.ssh/known_hosts files contain host @@ -552,7 +580,9 @@ FILES /etc/moduli Contains Diffie-Hellman groups used for the "Diffie-Hellman Group - Exchange". The file format is described in moduli(5). + Exchange" key exchange method. The file format is described in + moduli(5). If no usable groups are found in this file then fixed + internal groups will be used. /etc/motd See motd(5). @@ -632,4 +662,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 5.8 July 3, 2015 OpenBSD 5.8 +OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 diff --git a/sshd.8 b/sshd.8 index 213b5fc4315a..6c521f23e2ea 100644 --- a/sshd.8 +++ b/sshd.8 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.280 2015/07/03 03:49:45 djm Exp $ -.Dd $Mdocdate: July 3 2015 $ +.\" $OpenBSD: sshd.8,v 1.284 2016/02/17 07:38:19 jmc Exp $ +.Dd $Mdocdate: February 17 2016 $ .Dt SSHD 8 .Os .Sh NAME @@ -275,14 +275,12 @@ 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 1 only supports RSA keys. -For both protocols, -each host has a host-specific key, -normally 2048 bits, -used to identify the host. +Protocol 1 should not be used +and is only offered to support legacy devices. .Pp -Forward security for protocol 1 is provided through +Each host has a host-specific key, +used to identify the host. +Partial forward security for protocol 1 is provided through an additional server key, normally 1024 bits, generated when the server starts. @@ -470,7 +468,7 @@ does not exist either, xauth is used to add the cookie. .Cm AuthorizedKeysFile specifies the files containing public keys for public key authentication; -if none is specified, the default is +if this option is not specified, the default is .Pa ~/.ssh/authorized_keys and .Pa ~/.ssh/authorized_keys2 . @@ -522,6 +520,10 @@ No spaces are permitted, except within double quotes. The following option specifications are supported (note that option keywords are case-insensitive): .Bl -tag -width Ds +.It Cm agent-forwarding +Enable authentication agent forwarding previously disabled by the +.Cm restrict +option. .It Cm cert-authority Specifies that the listed key is a certification authority (CA) that is trusted to validate signed certificates for user authentication. @@ -616,6 +618,9 @@ they must be literal domains or addresses. A port specification of .Cm * matches any port. +.It Cm port-forwarding +Enable port forwarding previously disabled by the +.Cm restrict .It Cm principals="principals" On a .Cm cert-authority @@ -627,12 +632,33 @@ This option is ignored for keys that are not marked as trusted certificate signers using the .Cm cert-authority option. +.It Cm pty +Permits tty allocation previously disabled by the +.Cm restrict +option. +.It Cm restrict +Enable all restrictions, i.e. disable port, agent and X11 forwarding, +as well as disabling PTY allocation +and execution of +.Pa ~/.ssh/rc . +If any future restriction capabilities are added to authorized_keys files +they will be included in this set. .It Cm tunnel="n" Force a .Xr tun 4 device on the server. Without this option, the next available device will be used if the client requests a tunnel. +.It Cm user-rc +Enables execution of +.Pa ~/.ssh/rc +previously disabled by the +.Cm restrict +option. +.It Cm X11-forwarding +Permits X11 forwarding previously disabled by the +.Cm restrict +option. .El .Pp An example authorized_keys file: @@ -647,6 +673,10 @@ permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss AAAAB5...21S== tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== jane@example.net +restrict,command="uptime" ssh-rsa AAAA1C8...32Tv== +user@example.net +restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5== +user@example.net .Ed .Sh SSH_KNOWN_HOSTS FILE FORMAT The @@ -856,9 +886,12 @@ This file is for host-based authentication (see It should only be writable by root. .Pp .It Pa /etc/moduli -Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange". +Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange" +key exchange method. The file format is described in .Xr moduli 5 . +If no usable groups are found in this file then fixed internal groups will +be used. .Pp .It Pa /etc/motd See diff --git a/sshd.c b/sshd.c index 43d46508526b..430569c46081 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.458 2015/08/20 22:32:42 deraadt Exp $ */ +/* $OpenBSD: sshd.c,v 1.465 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -121,7 +121,6 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" -#include "roaming.h" #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" @@ -437,7 +436,7 @@ sshd_exchange_identification(int sock_in, int sock_out) options.version_addendum, newline); /* Send our protocol version identification. */ - if (roaming_atomicio(vwrite, sock_out, server_version_string, + if (atomicio(vwrite, sock_out, server_version_string, strlen(server_version_string)) != strlen(server_version_string)) { logit("Could not write ident string to %s", get_remote_ipaddr()); @@ -447,7 +446,7 @@ sshd_exchange_identification(int sock_in, int sock_out) /* Read other sides version identification. */ memset(buf, 0, sizeof(buf)); for (i = 0; i < sizeof(buf) - 1; i++) { - if (roaming_atomicio(read, sock_in, &buf[i], 1) != 1) { + if (atomicio(read, sock_in, &buf[i], 1) != 1) { logit("Did not receive identification string from %s", get_remote_ipaddr()); cleanup_exit(255); @@ -632,25 +631,23 @@ privsep_preauth_child(void) /* Demote the private keys to public keys. */ demote_sensitive_data(); - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, - strerror(errno)); - if (chdir("/") == -1) - fatal("chdir(\"/\"): %s", strerror(errno)); + /* Demote the child */ + if (getuid() == 0 || geteuid() == 0) { + /* Change our root directory */ + if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) + fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, + strerror(errno)); + if (chdir("/") == -1) + fatal("chdir(\"/\"): %s", strerror(errno)); - /* Drop our privileges */ - debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, - (u_int)privsep_pw->pw_gid); -#if 0 - /* XXX not ready, too heavy after chroot */ - do_setusercontext(privsep_pw); -#else - gidset[0] = privsep_pw->pw_gid; - if (setgroups(1, gidset) < 0) - fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(privsep_pw); -#endif + /* Drop our privileges */ + debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, + (u_int)privsep_pw->pw_gid); + gidset[0] = privsep_pw->pw_gid; + if (setgroups(1, gidset) < 0) + fatal("setgroups: %.100s", strerror(errno)); + permanently_set_uid(privsep_pw); + } } static int @@ -716,9 +713,7 @@ privsep_preauth(Authctxt *authctxt) /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); - /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); + privsep_preauth_child(); setproctitle("%s", "[net]"); if (box != NULL) ssh_sandbox_child(box); @@ -820,6 +815,12 @@ list_hostkey_types(void) buffer_append(&b, ",", 1); p = key_ssh_name(key); buffer_append(&b, p, strlen(p)); + + /* for RSA we also support SHA2 signatures */ + if (key->type == KEY_RSA) { + p = ",rsa-sha2-512,rsa-sha2-256"; + buffer_append(&b, p, strlen(p)); + } break; } /* If the private key has a cert peer, then list that too */ @@ -1255,8 +1256,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) for (;;) { if (received_sighup) sighup_restart(); - if (fdset != NULL) - free(fdset); + free(fdset); fdset = xcalloc(howmany(maxfd + 1, NFDBITS), sizeof(fd_mask)); @@ -1476,6 +1476,8 @@ main(int ac, char **av) Authctxt *authctxt; struct connection_info *connection_info = get_connection_info(0, 0); + ssh_malloc_init(); /* must be called before any mallocs */ + #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); #endif @@ -1536,7 +1538,7 @@ main(int ac, char **av) no_daemon_flag = 1; break; case 'E': - logfile = xstrdup(optarg); + logfile = optarg; /* FALLTHROUGH */ case 'e': log_stderr = 1; @@ -1638,10 +1640,8 @@ main(int ac, char **av) #endif /* If requested, redirect the logs to the specified logfile. */ - if (logfile != NULL) { + if (logfile != NULL) log_redirect_stderr_to(logfile); - free(logfile); - } /* * Force logging to stderr until we have loaded the private host * key (unless started from inetd) @@ -2513,24 +2513,26 @@ do_ssh1_kex(void) int sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, size_t *slen, - const u_char *data, size_t dlen, u_int flag) + const u_char *data, size_t dlen, const char *alg, u_int flag) { int r; u_int xxx_slen, xxx_dlen = dlen; if (privkey) { - if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen) < 0)) + if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen, + alg) < 0)) fatal("%s: key_sign failed", __func__); if (slen) *slen = xxx_slen; } else if (use_privsep) { - if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen) < 0) + if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen, + alg) < 0) fatal("%s: pubkey_sign failed", __func__); if (slen) *slen = xxx_slen; } else { if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen, - data, dlen, datafellows)) != 0) + data, dlen, alg, datafellows)) != 0) fatal("%s: ssh_agent_sign failed: %s", __func__, ssh_err(r)); } @@ -2563,7 +2565,7 @@ do_ssh2_kex(void) } if (options.rekey_limit || options.rekey_interval) - packet_set_rekey_limits((u_int32_t)options.rekey_limit, + packet_set_rekey_limits(options.rekey_limit, (time_t)options.rekey_interval); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( diff --git a/sshd_config b/sshd_config index 4d77f05aa2dd..a848d73e4430 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.97 2015/08/06 14:53:21 deraadt Exp $ +# $OpenBSD: sshd_config,v 1.98 2016/02/17 05:29:04 djm Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -107,7 +107,7 @@ AuthorizedKeysFile .ssh/authorized_keys #PrintLastLog yes #TCPKeepAlive yes #UseLogin no -UsePrivilegeSeparation sandbox # Default for new installations. +#UsePrivilegeSeparation sandbox #PermitUserEnvironment no #Compression delayed #ClientAliveInterval 0 diff --git a/sshd_config.0 b/sshd_config.0 index aae7fb6afaea..8bda6a39f042 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -19,17 +19,16 @@ DESCRIPTION AcceptEnv Specifies what environment variables sent by the client will be copied into the session's environ(7). See SendEnv in - ssh_config(5) for how to configure the client. Note that - environment passing is only supported for protocol 2, and that - the TERM environment variable is always sent whenever the client - requests a pseudo-terminal as it is required by the protocol. - Variables are specified by name, which may contain the wildcard - characters 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 taken in the use of this directive. The default - is not to accept any environment variables. + ssh_config(5) for how to configure the client. The TERM + environment variable is always sent whenever the client requests + a pseudo-terminal as it is required by the protocol. Variables + are specified by name, which may contain the wildcard characters + 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 + taken in the use of this directive. The default is not to accept + any environment variables. AddressFamily Specifies which address family should be used by sshd(8). Valid @@ -115,12 +114,11 @@ DESCRIPTION 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 - each authentication method listed should also be explicitly - enabled in the configuration. The default is not to require - multiple authentication; successful completion of a single - authentication method is sufficient. + This option will yield a fatal error if enabled if protocol 1 is + also enabled. Note that each authentication method listed should + also be explicitly enabled in the configuration. The default is + not to require multiple authentication; successful completion of + a single authentication method is sufficient. AuthorizedKeysCommand Specifies a program to be used to look up the user's public keys. @@ -162,8 +160,9 @@ DESCRIPTION replaced by the username of that user. After expansion, 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 - M-bM-^@M-^\.ssh/authorized_keys .ssh/authorized_keys2M-bM-^@M-^]. + listed, separated by whitespace. Alternately this option may be + set to M-bM-^@M-^\noneM-bM-^@M-^] to skip checking for user keys in files. The + default is M-bM-^@M-^\.ssh/authorized_keys .ssh/authorized_keys2M-bM-^@M-^]. AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed @@ -220,8 +219,7 @@ DESCRIPTION Banner The contents of the specified file are sent to the remote user 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. + no banner is displayed. By default, no banner is displayed. ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed @@ -258,13 +256,13 @@ DESCRIPTION (especially those outside the jail). Misconfiguration can lead to unsafe environments which sshd(8) cannot detect. - The default is not to chroot(2). + The default is M-bM-^@M-^\noneM-bM-^@M-^], indicating not to chroot(2). Ciphers - Specifies the ciphers allowed for protocol version 2. Multiple - ciphers must be comma-separated. If the specified value begins - with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified ciphers will be appended - to the default set instead of replacing them. + Specifies the ciphers allowed. Multiple ciphers must be comma- + separated. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, + then the specified ciphers will be appended to the default set + instead of replacing them. The supported ciphers are: @@ -309,15 +307,14 @@ DESCRIPTION The default value is 3. If ClientAliveInterval (see below) is set to 15, and ClientAliveCountMax is left at the default, unresponsive SSH clients will be disconnected after approximately - 45 seconds. This option applies to protocol version 2 only. + 45 seconds. ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, sshd(8) will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will - not be sent to the client. This option applies to protocol - version 2 only. + not be sent to the client. Compression Specifies whether compression is allowed, or delayed until the @@ -362,7 +359,7 @@ DESCRIPTION SSH_ORIGINAL_COMMAND environment variable. Specifying a command 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. + ChrootDirectory. The default is M-bM-^@M-^\noneM-bM-^@M-^]. GatewayPorts Specifies whether remote hosts are allowed to connect to ports @@ -379,13 +376,11 @@ DESCRIPTION GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. - The default is M-bM-^@M-^\noM-bM-^@M-^]. Note that this option applies to protocol - version 2 only. + The default is M-bM-^@M-^\noM-bM-^@M-^]. GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials - cache on logout. The default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option - applies to protocol version 2 only. + cache on logout. The default is M-bM-^@M-^\yesM-bM-^@M-^]. GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI @@ -416,9 +411,7 @@ DESCRIPTION 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 M-bM-^@M-^\noM-bM-^@M-^]. + allowed (host-based authentication). The default is M-bM-^@M-^\noM-bM-^@M-^]. HostbasedUsesNameFromPacketOnly Specifies whether or not the server will attempt to perform a @@ -459,8 +452,8 @@ DESCRIPTION read from the SSH_AUTH_SOCK environment variable. HostKeyAlgorithms - Specifies the protocol version 2 host key algorithms that the - server offers. The default for this option is: + Specifies the host key algorithms that the server offers. The + default for this option is: ecdsa-sha2-nistp256-cert-v01@openssh.com, ecdsa-sha2-nistp384-cert-v01@openssh.com, @@ -585,11 +578,11 @@ DESCRIPTION violates the privacy of users and is not recommended. 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. If the specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, - then the specified algorithms will be appended to the default set - instead of replacing them. + algorithms. The MAC algorithm is used for data integrity + protection. Multiple algorithms must be comma-separated. If the + specified value begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the specified + algorithms will be appended to the default set instead of + replacing them. The algorithms that contain M-bM-^@M-^\-etmM-bM-^@M-^] calculate the MAC after encryption (encrypt-then-mac). These are considered safer and @@ -618,8 +611,9 @@ DESCRIPTION umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, + hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, - hmac-sha2-256,hmac-sha2-512 + hmac-sha2-256,hmac-sha2-512,hmac-sha1 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-^]. @@ -651,8 +645,9 @@ DESCRIPTION AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, AllowTcpForwarding, AllowUsers, AuthenticationMethods, AuthorizedKeysCommand, AuthorizedKeysCommandUser, - AuthorizedKeysFile, AuthorizedPrincipalsFile, Banner, - ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, + AuthorizedKeysFile, AuthorizedPrincipalsCommand, + AuthorizedPrincipalsCommandUser, AuthorizedPrincipalsFile, + Banner, ChrootDirectory, DenyGroups, DenyUsers, ForceCommand, GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes, HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS, KbdInteractiveAuthentication, KerberosAuthentication, @@ -670,8 +665,13 @@ DESCRIPTION value, additional failures are logged. The default is 6. MaxSessions - Specifies the maximum number of open sessions permitted per - network connection. The default is 10. + Specifies the maximum number of open shell, login or subsystem + (e.g. sftp) sessions permitted per network connection. Multiple + sessions may be established by clients that support connection + multiplexing. Setting MaxSessions to 1 will effectively disable + session multiplexing, whereas setting it to 0 will prevent all + shell, login and subsystem sessions while still permitting + forwarding. The default is 10. MaxStartups Specifies the maximum number of concurrent unauthenticated @@ -775,10 +775,14 @@ DESCRIPTION Protocol Specifies the protocol versions sshd(8) supports. 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. 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 M-bM-^@M-^\2,1M-bM-^@M-^] is identical to M-bM-^@M-^\1,2M-bM-^@M-^]. + separated. The default is M-bM-^@M-^X2M-bM-^@M-^Y. Protocol 1 suffers from a number + of cryptographic weaknesses and should not be used. It is only + offered to support legacy devices. + + 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 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 @@ -799,8 +803,7 @@ DESCRIPTION PubkeyAuthentication Specifies whether public key authentication is allowed. The - default is M-bM-^@M-^\yesM-bM-^@M-^]. Note that this option applies to protocol - version 2 only. + default is M-bM-^@M-^\yesM-bM-^@M-^]. RekeyLimit Specifies the maximum amount of data that may be transmitted @@ -814,8 +817,7 @@ DESCRIPTION documented in the TIME FORMATS section. The 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. + or received and no time based rekeying is done. RevokedKeys Specifies revoked public keys file, or M-bM-^@M-^\noneM-bM-^@M-^] to not use one. @@ -882,8 +884,7 @@ DESCRIPTION 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 - applies to protocol version 2 only. + By default no subsystems are defined. SyslogFacility Gives the facility code that is used when logging messages from @@ -957,9 +958,10 @@ 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 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. + argument must be M-bM-^@M-^\yesM-bM-^@M-^], M-bM-^@M-^\noM-bM-^@M-^], or M-bM-^@M-^\sandboxM-bM-^@M-^]. If + UsePrivilegeSeparation is set to M-bM-^@M-^\sandboxM-bM-^@M-^] then the pre- + authentication unprivileged process is subject to additional + restrictions. The default is M-bM-^@M-^\sandboxM-bM-^@M-^]. VersionAddendum Optionally specifies additional text to append to the SSH @@ -1049,4 +1051,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 5.8 August 14, 2015 OpenBSD 5.8 +OpenBSD 5.9 February 17, 2016 OpenBSD 5.9 diff --git a/sshd_config.5 b/sshd_config.5 index b18d340af67b..a37a3aca3add 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.211 2015/08/14 15:32:41 jmc Exp $ -.Dd $Mdocdate: August 14 2015 $ +.\" $OpenBSD: sshd_config.5,v 1.220 2016/02/17 08:57:34 djm Exp $ +.Dd $Mdocdate: February 17 2016 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -70,8 +70,7 @@ See in .Xr ssh_config 5 for how to configure the client. -Note that environment passing is only supported for protocol 2, and -that the +The .Ev TERM environment variable is always sent whenever the client requests a pseudo-terminal as it is required by the protocol. @@ -226,7 +225,7 @@ 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 +This option will yield a fatal error if enabled if protocol 1 is also enabled. Note that each authentication method listed should also be explicitly enabled in the configuration. @@ -285,6 +284,9 @@ After expansion, is taken to be an absolute path or one relative to the user's home directory. Multiple files may be listed, separated by whitespace. +Alternately this option may be set to +.Dq none +to skip checking for user keys in files. The default is .Dq .ssh/authorized_keys .ssh/authorized_keys2 . .It Cm AuthorizedPrincipalsCommand @@ -370,7 +372,6 @@ authentication is allowed. If the argument is .Dq none then no banner is displayed. -This option is only available for protocol version 2. By default, no banner is displayed. .It Cm ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed (e.g. via @@ -429,10 +430,12 @@ Misconfiguration can lead to unsafe environments which .Xr sshd 8 cannot detect. .Pp -The default is not to +The default is +.Dq none , +indicating not to .Xr chroot 2 . .It Cm Ciphers -Specifies the ciphers allowed for protocol version 2. +Specifies the ciphers allowed. Multiple ciphers must be comma-separated. If the specified value begins with a .Sq + @@ -513,7 +516,6 @@ If .Cm ClientAliveCountMax is left at the default, unresponsive SSH clients will be disconnected after approximately 45 seconds. -This option applies to protocol version 2 only. .It Cm ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received from the client, @@ -522,7 +524,6 @@ will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client. -This option applies to protocol version 2 only. .It Cm Compression Specifies whether compression is allowed, or delayed until the user has authenticated successfully. @@ -596,6 +597,8 @@ Specifying a command of will force the use of an in-process sftp server that requires no support files when used with .Cm ChrootDirectory . +The default is +.Dq none . .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to ports forwarded for the client. @@ -620,13 +623,11 @@ The default is Specifies whether user authentication based on GSSAPI is allowed. The default is .Dq no . -Note that this option applies to protocol version 2 only. .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Dq yes . -Note that this option applies to protocol version 2 only. .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. @@ -669,9 +670,6 @@ may be used to list supported key types. 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 -.Cm RhostsRSAAuthentication -and applies to protocol version 2 only. The default is .Dq no . .It Cm HostbasedUsesNameFromPacketOnly @@ -742,7 +740,7 @@ is specified, the location of the socket will be read from the .Ev SSH_AUTH_SOCK environment variable. .It Cm HostKeyAlgorithms -Specifies the protocol version 2 host key algorithms +Specifies the host key algorithms that the server offers. The default for this option is: .Bd -literal -offset 3n @@ -963,8 +961,7 @@ DEBUG2 and DEBUG3 each specify higher levels of debugging output. Logging with a DEBUG level violates the privacy of users and is not recommended. .It Cm MACs Specifies the available MAC (message authentication code) algorithms. -The MAC algorithm is used in protocol version 2 -for data integrity protection. +The MAC algorithm is used for data integrity protection. Multiple algorithms must be comma-separated. If the specified value begins with a .Sq + @@ -1020,8 +1017,9 @@ The default is: .Bd -literal -offset indent umac-64-etm@openssh.com,umac-128-etm@openssh.com, hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com, +hmac-sha1-etm@openssh.com, umac-64@openssh.com,umac-128@openssh.com, -hmac-sha2-256,hmac-sha2-512 +hmac-sha2-256,hmac-sha2-512,hmac-sha1 .Ed .Pp The list of available MAC algorithms may also be obtained using the @@ -1091,6 +1089,8 @@ Available keywords are .Cm AuthorizedKeysCommand , .Cm AuthorizedKeysCommandUser , .Cm AuthorizedKeysFile , +.Cm AuthorizedPrincipalsCommand , +.Cm AuthorizedPrincipalsCommandUser , .Cm AuthorizedPrincipalsFile , .Cm Banner , .Cm ChrootDirectory , @@ -1134,7 +1134,15 @@ Once the number of failures reaches half this value, additional failures are logged. The default is 6. .It Cm MaxSessions -Specifies the maximum number of open sessions permitted per network connection. +Specifies the maximum number of open shell, login or subsystem (e.g. sftp) +sessions permitted per network connection. +Multiple sessions may be established by clients that support connection +multiplexing. +Setting +.Cm MaxSessions +to 1 will effectively disable session multiplexing, whereas setting it to 0 +will prevent all shell, login and subsystem sessions while still permitting +forwarding. The default is 10. .It Cm MaxStartups Specifies the maximum number of concurrent unauthenticated connections to the @@ -1324,6 +1332,10 @@ and Multiple versions must be comma-separated. The default is .Sq 2 . +Protocol 1 suffers from a number of cryptographic weaknesses and should +not be used. +It is only offered to support legacy devices. +.Pp Note that the order of the protocol list does not indicate preference, because the client selects among multiple protocol versions offered by the server. @@ -1358,7 +1370,6 @@ may be used to list supported key types. Specifies whether public key authentication is allowed. The default is .Dq yes . -Note that this option applies to protocol version 2 only. .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted before the session key is renegotiated, optionally followed a maximum amount of @@ -1384,7 +1395,6 @@ is .Dq 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. .It Cm RevokedKeys Specifies revoked public keys file, or .Dq none @@ -1471,7 +1481,6 @@ This may simplify configurations using to force a different filesystem root on clients. .Pp By default no subsystems are defined. -Note that this option applies to protocol version 2 only. .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Xr sshd 8 . @@ -1584,14 +1593,19 @@ After successful authentication, another process will be created 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 -.Dq yes . +The argument must be +.Dq yes , +.Dq no , +or +.Dq sandbox . If .Cm UsePrivilegeSeparation is set to .Dq sandbox then the pre-authentication unprivileged process is subject to additional restrictions. +The default is +.Dq sandbox . .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. diff --git a/ssherr.c b/ssherr.c index 4ca7939926c9..68020706381c 100644 --- a/ssherr.c +++ b/ssherr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssherr.c,v 1.4 2015/02/16 22:13:32 djm Exp $ */ +/* $OpenBSD: ssherr.c,v 1.5 2015/09/13 14:39:16 tim Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -104,7 +104,7 @@ ssh_err(int n) case SSH_ERR_NEED_REKEY: return "rekeying not supported by peer"; case SSH_ERR_PASSPHRASE_TOO_SHORT: - return "passphrase is too short (minimum four characters)"; + return "passphrase is too short (minimum five characters)"; case SSH_ERR_FILE_CHANGED: return "file changed while reading"; case SSH_ERR_KEY_UNKNOWN_CIPHER: diff --git a/sshkey.c b/sshkey.c index 32dd8f2254a2..87b093e91d26 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.21 2015/08/19 23:19:01 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.31 2015/12/11 04:21:12 mmcc Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -83,36 +83,39 @@ struct keytype { int type; int nid; int cert; + int sigonly; }; static const struct keytype keytypes[] = { - { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0 }, + { "ssh-ed25519", "ED25519", KEY_ED25519, 0, 0, 0 }, { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", - KEY_ED25519_CERT, 0, 1 }, + KEY_ED25519_CERT, 0, 1, 0 }, #ifdef WITH_OPENSSL - { NULL, "RSA1", KEY_RSA1, 0, 0 }, - { "ssh-rsa", "RSA", KEY_RSA, 0, 0 }, - { "ssh-dss", "DSA", KEY_DSA, 0, 0 }, + { NULL, "RSA1", KEY_RSA1, 0, 0, 0 }, + { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, + { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, + { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, + { "ssh-dss", "DSA", KEY_DSA, 0, 0, 0 }, # ifdef OPENSSL_HAS_ECC - { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0 }, - { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0 }, + { "ecdsa-sha2-nistp256", "ECDSA", KEY_ECDSA, NID_X9_62_prime256v1, 0, 0 }, + { "ecdsa-sha2-nistp384", "ECDSA", KEY_ECDSA, NID_secp384r1, 0, 0 }, # ifdef OPENSSL_HAS_NISTP521 - { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0 }, + { "ecdsa-sha2-nistp521", "ECDSA", KEY_ECDSA, NID_secp521r1, 0, 0 }, # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ - { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1 }, - { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1 }, + { "ssh-rsa-cert-v01@openssh.com", "RSA-CERT", KEY_RSA_CERT, 0, 1, 0 }, + { "ssh-dss-cert-v01@openssh.com", "DSA-CERT", KEY_DSA_CERT, 0, 1, 0 }, # ifdef OPENSSL_HAS_ECC { "ecdsa-sha2-nistp256-cert-v01@openssh.com", "ECDSA-CERT", - KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1 }, + KEY_ECDSA_CERT, NID_X9_62_prime256v1, 1, 0 }, { "ecdsa-sha2-nistp384-cert-v01@openssh.com", "ECDSA-CERT", - KEY_ECDSA_CERT, NID_secp384r1, 1 }, + KEY_ECDSA_CERT, NID_secp384r1, 1, 0 }, # ifdef OPENSSL_HAS_NISTP521 { "ecdsa-sha2-nistp521-cert-v01@openssh.com", "ECDSA-CERT", - KEY_ECDSA_CERT, NID_secp521r1, 1 }, + KEY_ECDSA_CERT, NID_secp521r1, 1, 0 }, # endif /* OPENSSL_HAS_NISTP521 */ # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ - { NULL, NULL, -1, -1, 0 } + { NULL, NULL, -1, -1, 0, 0 } }; const char * @@ -200,7 +203,7 @@ key_alg_list(int certs_only, int plain_only) const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { - if (kt->name == NULL) + if (kt->name == NULL || kt->sigonly) continue; if ((certs_only && !kt->cert) || (plain_only && kt->cert)) continue; @@ -417,20 +420,14 @@ cert_free(struct sshkey_cert *cert) if (cert == NULL) return; - if (cert->certblob != NULL) - sshbuf_free(cert->certblob); - if (cert->critical != NULL) - sshbuf_free(cert->critical); - if (cert->extensions != NULL) - sshbuf_free(cert->extensions); - if (cert->key_id != NULL) - free(cert->key_id); + sshbuf_free(cert->certblob); + sshbuf_free(cert->critical); + sshbuf_free(cert->extensions); + free(cert->key_id); for (i = 0; i < cert->nprincipals; i++) free(cert->principals[i]); - if (cert->principals != NULL) - free(cert->principals); - if (cert->signature_key != NULL) - sshkey_free(cert->signature_key); + free(cert->principals); + sshkey_free(cert->signature_key); explicit_bzero(cert, sizeof(*cert)); free(cert); } @@ -1216,7 +1213,7 @@ read_decimal_bignum(char **cpp, BIGNUM *v) return SSH_ERR_BIGNUM_TOO_LARGE; if (cp[e] == '\0') skip = 0; - else if (index(" \t\r\n", cp[e]) == NULL) + else if (strchr(" \t\r\n", cp[e]) == NULL) return SSH_ERR_INVALID_FORMAT; cp[e] = '\0'; if (BN_dec2bn(&v, cp) <= 0) @@ -1232,11 +1229,10 @@ sshkey_read(struct sshkey *ret, char **cpp) { struct sshkey *k; int retval = SSH_ERR_INVALID_FORMAT; - char *cp, *space; + char *ep, *cp, *space; int r, type, curve_nid = -1; struct sshbuf *blob; #ifdef WITH_SSH1 - char *ep; u_long bits; #endif /* WITH_SSH1 */ @@ -1247,7 +1243,7 @@ sshkey_read(struct sshkey *ret, char **cpp) #ifdef WITH_SSH1 /* Get number of bits. */ bits = strtoul(cp, &ep, 10); - if (*cp == '\0' || index(" \t\r\n", *ep) == NULL || + if (*cp == '\0' || strchr(" \t\r\n", *ep) == NULL || bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */ /* Get public exponent, public modulus. */ @@ -1255,10 +1251,10 @@ sshkey_read(struct sshkey *ret, char **cpp) return r; if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0) return r; - *cpp = ep; /* validate the claimed number of bits */ if (BN_num_bits(ret->rsa->n) != (int)bits) return SSH_ERR_KEY_BITS_MISMATCH; + *cpp = ep; retval = 0; #endif /* WITH_SSH1 */ break; @@ -1296,9 +1292,9 @@ sshkey_read(struct sshkey *ret, char **cpp) *space++ = '\0'; while (*space == ' ' || *space == '\t') space++; - *cpp = space; + ep = space; } else - *cpp = cp + strlen(cp); + ep = cp + strlen(cp); if ((r = sshbuf_b64tod(blob, cp)) != 0) { sshbuf_free(blob); return r; @@ -1329,8 +1325,9 @@ sshkey_read(struct sshkey *ret, char **cpp) ret->cert = k->cert; k->cert = NULL; } + switch (sshkey_type_plain(ret->type)) { #ifdef WITH_OPENSSL - if (sshkey_type_plain(ret->type) == KEY_RSA) { + case KEY_RSA: if (ret->rsa != NULL) RSA_free(ret->rsa); ret->rsa = k->rsa; @@ -1338,8 +1335,8 @@ sshkey_read(struct sshkey *ret, char **cpp) #ifdef DEBUG_PK RSA_print_fp(stderr, ret->rsa, 8); #endif - } - if (sshkey_type_plain(ret->type) == KEY_DSA) { + break; + case KEY_DSA: if (ret->dsa != NULL) DSA_free(ret->dsa); ret->dsa = k->dsa; @@ -1347,9 +1344,9 @@ sshkey_read(struct sshkey *ret, char **cpp) #ifdef DEBUG_PK DSA_print_fp(stderr, ret->dsa, 8); #endif - } + break; # ifdef OPENSSL_HAS_ECC - if (sshkey_type_plain(ret->type) == KEY_ECDSA) { + case KEY_ECDSA: if (ret->ecdsa != NULL) EC_KEY_free(ret->ecdsa); ret->ecdsa = k->ecdsa; @@ -1359,17 +1356,19 @@ sshkey_read(struct sshkey *ret, char **cpp) #ifdef DEBUG_PK sshkey_dump_ec_key(ret->ecdsa); #endif - } + break; # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ - if (sshkey_type_plain(ret->type) == KEY_ED25519) { + case KEY_ED25519: free(ret->ed25519_pk); ret->ed25519_pk = k->ed25519_pk; k->ed25519_pk = NULL; #ifdef DEBUG_PK /* XXX */ #endif + break; } + *cpp = ep; retval = 0; /*XXXX*/ sshkey_free(k); @@ -1717,7 +1716,7 @@ sshkey_cert_copy(const struct sshkey *from_key, struct sshkey *to_key) if ((ret = sshbuf_putb(to->certblob, from->certblob)) != 0 || (ret = sshbuf_putb(to->critical, from->critical)) != 0 || - (ret = sshbuf_putb(to->extensions, from->extensions) != 0)) + (ret = sshbuf_putb(to->extensions, from->extensions)) != 0) return ret; to->serial = from->serial; @@ -1758,9 +1757,7 @@ sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) struct sshkey *n = NULL; int ret = SSH_ERR_INTERNAL_ERROR; - if (pkp != NULL) - *pkp = NULL; - + *pkp = NULL; switch (k->type) { #ifdef WITH_OPENSSL case KEY_DSA: @@ -2174,7 +2171,7 @@ sshkey_froms(struct sshbuf *buf, struct sshkey **keyp) int sshkey_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, - const u_char *data, size_t datalen, u_int compat) + const u_char *data, size_t datalen, const char *alg, u_int compat) { if (sigp != NULL) *sigp = NULL; @@ -2194,7 +2191,7 @@ sshkey_sign(const struct sshkey *key, # endif /* OPENSSL_HAS_ECC */ case KEY_RSA_CERT: case KEY_RSA: - return ssh_rsa_sign(key, sigp, lenp, data, datalen, compat); + return ssh_rsa_sign(key, sigp, lenp, data, datalen, alg); #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: @@ -2226,7 +2223,7 @@ sshkey_verify(const struct sshkey *key, # endif /* OPENSSL_HAS_ECC */ case KEY_RSA_CERT: case KEY_RSA: - return ssh_rsa_verify(key, sig, siglen, data, dlen, compat); + return ssh_rsa_verify(key, sig, siglen, data, dlen); #endif /* WITH_OPENSSL */ case KEY_ED25519: case KEY_ED25519_CERT: @@ -2243,9 +2240,7 @@ sshkey_demote(const struct sshkey *k, struct sshkey **dkp) struct sshkey *pk; int ret = SSH_ERR_INTERNAL_ERROR; - if (dkp != NULL) - *dkp = NULL; - + *dkp = NULL; if ((pk = calloc(1, sizeof(*pk))) == NULL) return SSH_ERR_ALLOC_FAIL; pk->type = k->type; @@ -2462,7 +2457,7 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca) /* Sign the whole mess */ if ((ret = sshkey_sign(ca, &sig_blob, &sig_len, sshbuf_ptr(cert), - sshbuf_len(cert), 0)) != 0) + sshbuf_len(cert), NULL, 0)) != 0) goto out; /* Append signature and we are done */ @@ -2472,12 +2467,9 @@ sshkey_certify(struct sshkey *k, struct sshkey *ca) out: if (ret != 0) sshbuf_reset(cert); - if (sig_blob != NULL) - free(sig_blob); - if (ca_blob != NULL) - free(ca_blob); - if (principals != NULL) - sshbuf_free(principals); + free(sig_blob); + free(ca_blob); + sshbuf_free(principals); return ret; } @@ -2538,6 +2530,43 @@ sshkey_cert_check_authority(const struct sshkey *k, return 0; } +size_t +sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l) +{ + char from[32], to[32], ret[64]; + time_t tt; + struct tm *tm; + + *from = *to = '\0'; + if (cert->valid_after == 0 && + cert->valid_before == 0xffffffffffffffffULL) + return strlcpy(s, "forever", l); + + if (cert->valid_after != 0) { + /* XXX revisit INT_MAX in 2038 :) */ + tt = cert->valid_after > INT_MAX ? + INT_MAX : cert->valid_after; + tm = localtime(&tt); + strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); + } + if (cert->valid_before != 0xffffffffffffffffULL) { + /* XXX revisit INT_MAX in 2038 :) */ + tt = cert->valid_before > INT_MAX ? + INT_MAX : cert->valid_before; + tm = localtime(&tt); + strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); + } + + if (cert->valid_after == 0) + snprintf(ret, sizeof(ret), "before %s", to); + else if (cert->valid_before == 0xffffffffffffffffULL) + snprintf(ret, sizeof(ret), "after %s", from); + else + snprintf(ret, sizeof(ret), "from %s to %s", from, to); + + return strlcpy(s, ret, l); +} + int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *b) { @@ -2701,7 +2730,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) goto out; } if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), - EC_KEY_get0_public_key(k->ecdsa)) != 0) || + EC_KEY_get0_public_key(k->ecdsa))) != 0 || (r = sshkey_ec_validate_private(k->ecdsa)) != 0) goto out; break; @@ -2719,7 +2748,7 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) goto out; } if ((r = sshkey_ec_validate_public(EC_KEY_get0_group(k->ecdsa), - EC_KEY_get0_public_key(k->ecdsa)) != 0) || + EC_KEY_get0_public_key(k->ecdsa))) != 0 || (r = sshkey_ec_validate_private(k->ecdsa)) != 0) goto out; break; @@ -2741,10 +2770,10 @@ sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **kp) case KEY_RSA_CERT: 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) || - (r = sshbuf_get_bignum2(buf, k->rsa->p) != 0) || - (r = sshbuf_get_bignum2(buf, k->rsa->q) != 0) || + (r = sshbuf_get_bignum2(buf, k->rsa->d)) != 0 || + (r = sshbuf_get_bignum2(buf, k->rsa->iqmp)) != 0 || + (r = sshbuf_get_bignum2(buf, k->rsa->p)) != 0 || + (r = sshbuf_get_bignum2(buf, k->rsa->q)) != 0 || (r = rsa_generate_additional_parameters(k->rsa)) != 0) goto out; break; @@ -3431,9 +3460,9 @@ sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, /* Store public key. This will be in plain text. */ if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 || - (r = sshbuf_put_bignum1(encrypted, key->rsa->n) != 0) || - (r = sshbuf_put_bignum1(encrypted, key->rsa->e) != 0) || - (r = sshbuf_put_cstring(encrypted, comment) != 0)) + (r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 || + (r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 || + (r = sshbuf_put_cstring(encrypted, comment)) != 0) goto out; /* Allocate space for the private part of the key in the buffer. */ @@ -3454,10 +3483,8 @@ sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, out: explicit_bzero(&ciphercontext, sizeof(ciphercontext)); explicit_bzero(buf, sizeof(buf)); - if (buffer != NULL) - sshbuf_free(buffer); - if (encrypted != NULL) - sshbuf_free(encrypted); + sshbuf_free(buffer); + sshbuf_free(encrypted); return r; } @@ -3611,10 +3638,8 @@ sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, pub = NULL; out: - if (copy != NULL) - sshbuf_free(copy); - if (pub != NULL) - sshkey_free(pub); + sshbuf_free(copy); + sshkey_free(pub); return r; } @@ -3726,14 +3751,10 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, } out: explicit_bzero(&ciphercontext, sizeof(ciphercontext)); - if (comment != NULL) - free(comment); - if (prv != NULL) - sshkey_free(prv); - if (copy != NULL) - sshbuf_free(copy); - if (decrypted != NULL) - sshbuf_free(decrypted); + free(comment); + sshkey_free(prv); + sshbuf_free(copy); + sshbuf_free(decrypted); return r; } #endif /* WITH_SSH1 */ @@ -3823,8 +3844,7 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, BIO_free(bio); if (pk != NULL) EVP_PKEY_free(pk); - if (prv != NULL) - sshkey_free(prv); + sshkey_free(prv); return r; } #endif /* WITH_OPENSSL */ @@ -3833,8 +3853,6 @@ int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp) { - int r; - *keyp = NULL; if (commentp != NULL) *commentp = NULL; @@ -3856,8 +3874,8 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, return sshkey_parse_private2(blob, type, passphrase, keyp, commentp); case KEY_UNSPEC: - if ((r = sshkey_parse_private2(blob, type, passphrase, keyp, - commentp)) == 0) + if (sshkey_parse_private2(blob, type, passphrase, keyp, + commentp) == 0) return 0; #ifdef WITH_OPENSSL return sshkey_parse_private_pem_fileblob(blob, type, @@ -3872,10 +3890,8 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, int sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, - const char *filename, struct sshkey **keyp, char **commentp) + struct sshkey **keyp, char **commentp) { - int r; - if (keyp != NULL) *keyp = NULL; if (commentp != NULL) @@ -3883,13 +3899,11 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase, #ifdef WITH_SSH1 /* it's a SSH v1 key if the public key part is readable */ - if ((r = sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL)) == 0) { + if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) { return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1, passphrase, keyp, commentp); } #endif /* WITH_SSH1 */ - if ((r = sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, - passphrase, keyp, commentp)) == 0) - return 0; - return r; + return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, + passphrase, keyp, commentp); } diff --git a/sshkey.h b/sshkey.h index c8d3cddca595..a20a14f9e74b 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.9 2015/08/04 05:23:06 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.12 2015/12/04 16:41:28 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -141,6 +141,8 @@ int sshkey_certify(struct sshkey *, struct sshkey *); int sshkey_cert_copy(const struct sshkey *, struct sshkey *); int sshkey_cert_check_authority(const struct sshkey *, int, int, const char *, const char **); +size_t sshkey_format_cert_validity(const struct sshkey_cert *, + char *, size_t) __attribute__((__bounded__(__string__, 2, 3))); int sshkey_ecdsa_nid_from_name(const char *); int sshkey_curve_name_to_nid(const char *); @@ -167,7 +169,7 @@ 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); + const u_char *, size_t, const char *, u_int); int sshkey_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, u_int); @@ -186,17 +188,16 @@ int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob, int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob, struct sshkey **keyp, char **commentp); int sshkey_parse_private_fileblob(struct sshbuf *buffer, - const char *passphrase, const char *filename, struct sshkey **keyp, - char **commentp); + const char *passphrase, struct sshkey **keyp, char **commentp); int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type, const char *passphrase, struct sshkey **keyp, char **commentp); #ifdef SSHKEY_INTERNAL -int ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, - const u_char *data, size_t datalen, u_int compat); +int ssh_rsa_sign(const struct sshkey *key, + u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, + const char *ident); int ssh_rsa_verify(const struct sshkey *key, - const u_char *signature, size_t signaturelen, - const u_char *data, size_t datalen, u_int compat); + const u_char *sig, size_t siglen, const u_char *data, size_t datalen); int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, u_int compat); int ssh_dss_verify(const struct sshkey *key, diff --git a/sshlogin.c b/sshlogin.c index 818312ff129b..cea3e7697401 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshlogin.c,v 1.31 2015/01/20 23:14:00 deraadt Exp $ */ +/* $OpenBSD: sshlogin.c,v 1.32 2015/12/26 20:51:35 guenther Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland diff --git a/uidswap.c b/uidswap.c index 0702e1d9e1b8..8bf6b244e5c7 100644 --- a/uidswap.c +++ b/uidswap.c @@ -134,7 +134,7 @@ temporarily_use_uid(struct passwd *pw) void permanently_drop_suid(uid_t uid) { -#ifndef HAVE_CYGWIN +#ifndef NO_UID_RESTORATION_TEST uid_t old_uid = getuid(); #endif @@ -142,8 +142,14 @@ permanently_drop_suid(uid_t uid) if (setresuid(uid, uid, uid) < 0) fatal("setresuid %u: %.100s", (u_int)uid, strerror(errno)); -#ifndef HAVE_CYGWIN - /* Try restoration of UID if changed (test clearing of saved uid) */ +#ifndef NO_UID_RESTORATION_TEST + /* + * Try restoration of UID if changed (test clearing of saved uid). + * + * Note that we don't do this on Cygwin, or on Solaris-based platforms + * where fine-grained privileges are available (the user might be + * deliberately allowed the right to setuid back to root). + */ if (old_uid != uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) fatal("%s: was able to restore old [e]uid", __func__); @@ -199,7 +205,7 @@ restore_uid(void) void permanently_set_uid(struct passwd *pw) { -#ifndef HAVE_CYGWIN +#ifndef NO_UID_RESTORATION_TEST uid_t old_uid = getuid(); gid_t old_gid = getgid(); #endif @@ -227,7 +233,7 @@ permanently_set_uid(struct passwd *pw) if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); -#ifndef HAVE_CYGWIN +#ifndef NO_UID_RESTORATION_TEST /* Try restoration of GID if changed (test clearing of saved gid) */ if (old_gid != pw->pw_gid && pw->pw_uid != 0 && (setgid(old_gid) != -1 || setegid(old_gid) != -1)) @@ -241,7 +247,7 @@ permanently_set_uid(struct passwd *pw) (u_int)pw->pw_gid); } -#ifndef HAVE_CYGWIN +#ifndef NO_UID_RESTORATION_TEST /* Try restoration of UID if changed (test clearing of saved uid) */ if (old_uid != pw->pw_uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) diff --git a/version.h b/version.h index 41e1ea931b71..4189982a98b1 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.75 2015/08/21 03:45:26 djm Exp $ */ +/* $OpenBSD: version.h,v 1.76 2016/02/23 09:14:34 djm Exp $ */ -#define SSH_VERSION "OpenSSH_7.1" +#define SSH_VERSION "OpenSSH_7.2" -#define SSH_PORTABLE "p2" +#define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE diff --git a/xmalloc.c b/xmalloc.c index 98cbf8776bd6..b58323677ee7 100644 --- a/xmalloc.c +++ b/xmalloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.c,v 1.32 2015/04/24 01:36:01 deraadt Exp $ */ +/* $OpenBSD: xmalloc.c,v 1.33 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -26,6 +26,16 @@ #include "xmalloc.h" #include "log.h" +void +ssh_malloc_init(void) +{ +#if defined(__OpenBSD__) + extern char *malloc_options; + + malloc_options = "S"; +#endif /* __OpenBSD__ */ +} + void * xmalloc(size_t size) { diff --git a/xmalloc.h b/xmalloc.h index 2bec77ba8d3b..e4992893276d 100644 --- a/xmalloc.h +++ b/xmalloc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xmalloc.h,v 1.15 2015/04/24 01:36:01 deraadt Exp $ */ +/* $OpenBSD: xmalloc.h,v 1.16 2016/02/15 09:47:49 dtucker Exp $ */ /* * Author: Tatu Ylonen @@ -16,6 +16,7 @@ * called by a name other than "ssh" or "Secure Shell". */ +void ssh_malloc_init(void); void *xmalloc(size_t); void *xcalloc(size_t, size_t); void *xreallocarray(void *, size_t, size_t);