From 9f6de2d748109e4e479c9259468a79973631e7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 17 Feb 2011 11:47:40 +0000 Subject: [PATCH] Vendor import of OpenSSH 5.7p1 --- ChangeLog | 3428 ++++++------------------------ LICENCE | 1 + Makefile.in | 51 +- PROTOCOL | 61 +- PROTOCOL.agent | 44 +- PROTOCOL.certkeys | 89 +- PROTOCOL.mux | 26 +- README | 4 +- atomicio.c | 33 +- atomicio.h | 8 +- audit-bsm.c | 6 +- audit-linux.c | 126 ++ audit.c | 10 +- audit.h | 9 +- auth-options.c | 10 +- auth-rsa.c | 9 +- auth.c | 32 +- auth1.c | 6 +- auth2-jpake.c | 7 +- auth2-pubkey.c | 4 +- auth2.c | 10 +- authfd.c | 22 +- authfile.c | 492 +++-- bufaux.c | 35 +- bufec.c | 146 ++ buffer.h | 13 +- canohost.c | 2 +- channels.c | 5 +- cipher-3des1.c | 5 +- cipher-acss.c | 3 +- cipher-aes.c | 2 +- cipher-bf1.c | 8 +- cipher-ctr.c | 12 +- clientloop.c | 40 +- compress.c | 5 +- config.h.in | 36 + configure | 1088 +++++++++- configure.ac | 153 +- contrib/caldera/openssh.spec | 12 +- contrib/redhat/openssh.spec | 2 +- contrib/redhat/sshd.init | 2 +- contrib/suse/openssh.spec | 2 +- defines.h | 48 +- dns.c | 3 +- entropy.c | 2 +- hostfile.c | 306 +-- hostfile.h | 30 +- includes.h | 2 +- jpake.c | 9 +- kex.c | 40 +- kex.h | 25 +- kexdhc.c | 4 +- kexdhs.c | 4 +- kexecdh.c | 117 + kexecdhc.c | 168 ++ kexecdhs.c | 173 ++ kexgexc.c | 4 +- kexgexs.c | 4 +- key.c | 673 +++++- key.h | 33 +- loginrec.c | 28 +- loginrec.h | 12 +- misc.c | 141 +- misc.h | 14 +- moduli.0 | 1 - moduli.c | 10 +- monitor.c | 9 +- monitor_wrap.c | 3 +- mux.c | 60 +- myproposal.h | 57 +- openbsd-compat/Makefile.in | 4 +- openbsd-compat/bindresvport.c | 2 +- openbsd-compat/bsd-misc.c | 7 + openbsd-compat/bsd-misc.h | 6 +- openbsd-compat/charclass.h | 31 + openbsd-compat/glob.c | 304 ++- openbsd-compat/glob.h | 13 +- openbsd-compat/openbsd-compat.h | 6 +- openbsd-compat/openssl-compat.c | 76 +- openbsd-compat/openssl-compat.h | 26 +- openbsd-compat/port-linux.c | 57 +- openbsd-compat/port-solaris.c | 32 +- openbsd-compat/port-solaris.h | 5 +- openbsd-compat/timingsafe_bcmp.c | 34 + opensshd.init.in | 4 + packet.c | 53 +- packet.h | 14 +- pathnames.h | 4 +- platform.c | 132 +- platform.h | 7 +- readconf.c | 51 +- readconf.h | 5 +- readpass.c | 27 +- regress/Makefile | 69 +- regress/agent-getpeereid.sh | 9 +- regress/agent-ptrace.sh | 2 +- regress/cert-hostkey.sh | 31 +- regress/cert-userkey.sh | 25 +- regress/host-expand.sh | 18 + regress/kextype.sh | 30 + regress/keytype.sh | 55 + regress/multiplex.sh | 3 +- regress/sftp-cmds.sh | 10 +- regress/sftp-glob.sh | 23 +- regress/test-exec.sh | 11 + schnorr.c | 38 +- scp.0 | 12 +- scp.1 | 16 +- scp.c | 239 ++- servconf.c | 61 +- servconf.h | 5 +- session.c | 80 +- sftp-client.c | 259 ++- sftp-client.h | 7 +- sftp-server.0 | 2 +- sftp-server.c | 42 +- sftp.0 | 23 +- sftp.1 | 29 +- sftp.c | 141 +- ssh-add.0 | 16 +- ssh-add.1 | 17 +- ssh-add.c | 7 +- ssh-agent.0 | 35 +- ssh-agent.1 | 19 +- ssh-agent.c | 67 +- ssh-dss.c | 4 +- ssh-ecdsa.c | 168 ++ ssh-keygen.0 | 65 +- ssh-keygen.1 | 48 +- ssh-keygen.c | 62 +- ssh-keyscan.0 | 15 +- ssh-keyscan.1 | 20 +- ssh-keyscan.c | 18 +- ssh-keysign.0 | 10 +- ssh-keysign.8 | 16 +- ssh-keysign.c | 4 +- ssh-rsa.c | 4 +- ssh.0 | 68 +- ssh.1 | 85 +- ssh.c | 96 +- ssh2.h | 6 +- ssh_config.0 | 58 +- ssh_config.5 | 77 +- sshconnect.c | 322 +-- sshconnect.h | 12 +- sshconnect2.c | 65 +- sshd.0 | 32 +- sshd.8 | 73 +- sshd.c | 14 +- sshd_config | 3 +- sshd_config.0 | 47 +- sshd_config.5 | 61 +- sshlogin.c | 2 +- uuencode.c | 4 +- uuencode.h | 4 +- version.h | 4 +- 156 files changed, 7327 insertions(+), 4480 deletions(-) create mode 100644 audit-linux.c create mode 100644 bufec.c create mode 100644 kexecdh.c create mode 100644 kexecdhc.c create mode 100644 kexecdhs.c create mode 100644 openbsd-compat/charclass.h create mode 100644 openbsd-compat/timingsafe_bcmp.c create mode 100755 regress/host-expand.sh create mode 100755 regress/kextype.sh create mode 100755 regress/keytype.sh create mode 100644 ssh-ecdsa.c diff --git a/ChangeLog b/ChangeLog index e3ac6a9258dc..0356a33c5d11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,688 @@ +20110122 + - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add + RSA_get_default_method() for the benefit of openssl versions that don't + have it (at least openssl-engine-0.9.6b). Found and tested by Kevin Brott, + ok djm@. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/22 09:18:53 + [version.h] + crank to OpenSSH-5.7 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] update versions in docs and spec files. + - (djm) Release 5.7p1 + +20110119 + - (tim) [contrib/caldera/openssh.spec] Use CFLAGS from Makefile instead + of RPM so build completes. Signatures were changed to .asc since 4.1p1. + - (djm) [configure.ac] Disable ECC on OpenSSL <0.9.8g. Releases prior to + 0.9.8 lacked it, and 0.9.8a through 0.9.8d have proven buggy in pre- + release testing (random crashes and failure to load ECC keys). + ok dtucker@ + +20110117 + - (djm) [regress/Makefile] use $TEST_SSH_KEYGEN instead of the one in + $PATH, fix cleanup of droppings; reported by openssh AT + roumenpetrov.info; ok dtucker@ + - (djm) [regress/agent-ptrace.sh] Fix false failure on OS X by adding + its unique snowflake of a gdb error to the ones we look for. + - (djm) [regress/agent-getpeereid.sh] leave stdout attached when running + ssh-add to avoid $SUDO failures on Linux + - (dtucker) [openbsd-compat/port-linux.c] Bug #1838: Add support for the new + Linux OOM-killer magic values that changed in 2.6.36 kernels, with fallback + to the old values. Feedback from vapier at gentoo org and djm, ok djm. + - (djm) [configure.ac regress/agent-getpeereid.sh regress/multiplex.sh] + [regress/sftp-glob.sh regress/test-exec.sh] Rework how feature tests are + disabled on platforms that do not support them; add a "config_defined()" + shell function that greps for defines in config.h and use them to decide + on feature tests. + Convert a couple of existing grep's over config.h to use the new function + Add a define "FILESYSTEM_NO_BACKSLASH" for filesystem that can't represent + backslash characters in filenames, enable it for Cygwin and use it to turn + of tests for quotes backslashes in sftp-glob.sh. + based on discussion with vinschen AT redhat.com and dtucker@; ok dtucker@ + - (tim) [regress/agent-getpeereid.sh] shell portability fix. + - (dtucker) [openbsd-compat/port-linux.c] Fix minor bug caught by -Werror on + the tinderbox. + - (dtucker) [LICENCE Makefile.in audit-bsm.c audit-linux.c audit.c audit.h + configure.ac defines.h loginrec.c] Bug #1402: add linux audit subsystem + support, based on patches from Tomas Mraz and jchadima at redhat. + +20110116 + - (dtucker) [Makefile.in configure.ac regress/kextype.sh] Skip sha256-based + on configurations that don't have it. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/16 11:50:05 + [clientloop.c] + Use atomicio when flushing protocol 1 std{out,err} buffers at + session close. This was a latent bug exposed by setting a SIGCHLD + handler and spotted by kevin.brott AT gmail.com; ok dtucker@ + - djm@cvs.openbsd.org 2011/01/16 11:50:36 + [sshconnect.c] + reset the SIGPIPE handler when forking to execute child processes; + ok dtucker@ + - djm@cvs.openbsd.org 2011/01/16 12:05:59 + [clientloop.c] + a couple more tweaks to the post-close protocol 1 stderr/stdout flush: + now that we use atomicio(), convert them from while loops to if statements + add test and cast to compile cleanly with -Wsigned + +20110114 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/13 21:54:53 + [mux.c] + correct error messages; patch from bert.wesarg AT googlemail.com + - djm@cvs.openbsd.org 2011/01/13 21:55:25 + [PROTOCOL.mux] + correct protocol names and add a couple of missing protocol number + defines; patch from bert.wesarg AT googlemail.com + - (djm) [Makefile.in] Use shell test to disable ecdsa key generating in + host-key-force target rather than a substitution that is replaced with a + comment so that the Makefile.in is still a syntactically valid Makefile + (useful to run the distprep target) + - (tim) [regress/cert-hostkey.sh] Typo. Missing $ on variable name. + - (tim) [regress/cert-hostkey.sh] Add missing TEST_SSH_ECC guard around some + ecdsa bits. + +20110113 + - (djm) [misc.c] include time.h for nanosleep() prototype + - (tim) [Makefile.in] test the ECC bits if we have the capability. ok djm + - (tim) [Makefile.in configure.ac opensshd.init.in] Add support for generating + ecdsa keys. ok djm. + - (djm) [entropy.c] cast OPENSSL_VERSION_NUMBER to u_long to avoid + gcc warning on platforms where it defaults to int + - (djm) [regress/Makefile] add a few more generated files to the clean + target + - (djm) [myproposal.h] Fix reversed OPENSSL_VERSION_NUMBER test and bad + #define that was causing diffie-hellman-group-exchange-sha256 to be + incorrectly disabled + - (djm) [regress/kextype.sh] Testing diffie-hellman-group-exchange-sha256 + should not depend on ECC support + +20110112 + - OpenBSD CVS Sync + - nicm@cvs.openbsd.org 2010/10/08 21:48:42 + [openbsd-compat/glob.c] + Extend GLOB_LIMIT to cover readdir and stat and bump the malloc limit + from ARG_MAX to 64K. + Fixes glob-using programs (notably ftp) able to be triggered to hit + resource limits. + Idea from a similar NetBSD change, original problem reported by jasper@. + ok millert tedu jasper + - djm@cvs.openbsd.org 2011/01/12 01:53:14 + avoid some integer overflows mostly with GLOB_APPEND and GLOB_DOOFFS + and sanity check arguments (these will be unnecessary when we switch + struct glob members from being type into to size_t in the future); + "looks ok" tedu@ feedback guenther@ + - (djm) [configure.ac] Turn on -Wno-unused-result for gcc >= 4.4 to avoid + silly warnings on write() calls we don't care succeed or not. + - (djm) [configure.ac] Fix broken test for gcc >= 4.4 with per-compiler + flag tests that don't depend on gcc version at all; suggested by and + ok dtucker@ + +20110111 + - (tim) [regress/host-expand.sh] Fix for building outside of read only + source tree. + - (djm) [platform.c] Some missing includes that show up under -Werror + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/08 10:51:51 + [clientloop.c] + use host and not options.hostname, as the latter may have unescaped + substitution characters + - djm@cvs.openbsd.org 2011/01/11 06:06:09 + [sshlogin.c] + fd leak on error paths; from zinovik@ + NB. Id sync only; we use loginrec.c that was also audited and fixed + recently + - djm@cvs.openbsd.org 2011/01/11 06:13:10 + [clientloop.c ssh-keygen.c sshd.c] + some unsigned long long casts that make things a bit easier for + portable without resorting to dropping PRIu64 formats everywhere + +20110109 + - (djm) [Makefile.in] list ssh_host_ecdsa key in PATHSUBS; spotted by + openssh AT roumenpetrov.info + +20110108 + - (djm) [regress/keytype.sh] s/echo -n/echon/ to repair failing regress + test on OSX and others. Reported by imorgan AT nas.nasa.gov + +20110107 + - (djm) [regress/cert-hostkey.sh regress/cert-userkey.sh] fix shell test + for no-ECC case. Patch from cristian.ionescu-idbohrn AT axis.com + - djm@cvs.openbsd.org 2011/01/06 22:23:53 + [ssh.c] + unbreak %n expansion in LocalCommand; patch from bert.wesarg AT + googlemail.com; ok markus@ + - djm@cvs.openbsd.org 2011/01/06 22:23:02 + [clientloop.c] + when exiting due to ServerAliveTimeout, mention the hostname that caused + it (useful with backgrounded controlmaster) + - djm@cvs.openbsd.org 2011/01/06 22:46:21 + [regress/Makefile regress/host-expand.sh] + regress test for LocalCommand %n expansion from bert.wesarg AT + googlemail.com; ok markus@ + - djm@cvs.openbsd.org 2011/01/06 23:01:35 + [sshconnect.c] + reset SIGCHLD handler to SIG_DFL when execuring LocalCommand; + ok markus@ + +20110106 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2010/12/08 22:46:03 + [scp.1 scp.c] + add a new -3 option to scp: Copies between two remote hosts are + transferred through the local host. Without this option the data + is copied directly between the two remote hosts. ok djm@ (bugzilla #1837) + - jmc@cvs.openbsd.org 2010/12/09 14:13:33 + [scp.1 scp.c] + scp.1: grammer fix + scp.c: add -3 to usage() + - markus@cvs.openbsd.org 2010/12/14 11:59:06 + [sshconnect.c] + don't mention key type in key-changed-warning, since we also print + this warning if a new key type appears. ok djm@ + - djm@cvs.openbsd.org 2010/12/15 00:49:27 + [readpass.c] + fix ControlMaster=ask regression + reset SIGCHLD handler before fork (and restore it after) so we don't miss + the the askpass child's exit status. Correct test for exit status/signal to + account for waitpid() failure; with claudio@ ok claudio@ markus@ + - djm@cvs.openbsd.org 2010/12/24 21:41:48 + [auth-options.c] + don't send the actual forced command in a debug message; ok markus deraadt + - otto@cvs.openbsd.org 2011/01/04 20:44:13 + [ssh-keyscan.c] + handle ecdsa-sha2 with various key lengths; hint and ok djm@ + +20110104 + - (djm) [configure.ac Makefile.in] Use mandoc as preferred manpage + formatter if it is present, followed by nroff and groff respectively. + Fixes distprep target on OpenBSD (which has bumped groff/nroff to ports + in favour of mandoc). feedback and ok tim + +20110103 + - (djm) [Makefile.in] revert local hack I didn't intend to commit + +20110102 + - (djm) [loginrec.c] Fix some fd leaks on error paths. ok dtucker + - (djm) [configure.ac] Check whether libdes is needed when building + with Heimdal krb5 support. On OpenBSD this library no longer exists, + so linking it unconditionally causes a build failure; ok dtucker + +20101226 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/12/08 04:02:47 + [ssh_config.5 sshd_config.5] + explain that IPQoS arguments are separated by whitespace; iirc requested + by jmc@ a while back + +20101205 + - (dtucker) openbsd-compat/openssl-compat.c] remove sleep leftover from + debugging. Spotted by djm. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/12/03 23:49:26 + [schnorr.c] + check that g^x^q === 1 mod p; recommended by JPAKE author Feng Hao + (this code is still disabled, but apprently people are treating it as + a reference implementation) + - djm@cvs.openbsd.org 2010/12/03 23:55:27 + [auth-rsa.c] + move check for revoked keys to run earlier (in auth_rsa_key_allowed) + bz#1829; patch from ldv AT altlinux.org; ok markus@ + - djm@cvs.openbsd.org 2010/12/04 00:18:01 + [sftp-server.c sftp.1 sftp-client.h sftp.c PROTOCOL sftp-client.c] + add a protocol extension to support a hard link operation. It is + available through the "ln" command in the client. The old "ln" + behaviour of creating a symlink is available using its "-s" option + or through the preexisting "symlink" command; based on a patch from + miklos AT szeredi.hu in bz#1555; ok markus@ + - djm@cvs.openbsd.org 2010/12/04 13:31:37 + [hostfile.c] + fix fd leak; spotted and ok dtucker + - djm@cvs.openbsd.org 2010/12/04 00:21:19 + [regress/sftp-cmds.sh] + adjust for hard-link support + - (dtucker) [regress/Makefile] Id sync. + +20101204 + - (djm) [openbsd-compat/bindresvport.c] Use arc4random_uniform(range) + instead of (arc4random() % range) + - (dtucker) [configure.ac moduli.c openbsd-compat/openssl-compat.{c,h}] Add + shims for the new, non-deprecated OpenSSL key generation functions for + platforms that don't have the new interfaces. + +20101201 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2010/11/20 05:12:38 + [auth2-pubkey.c] + clean up cases of ;; + - djm@cvs.openbsd.org 2010/11/21 01:01:13 + [clientloop.c misc.c misc.h ssh-agent.1 ssh-agent.c] + honour $TMPDIR for client xauth and ssh-agent temporary directories; + feedback and ok markus@ + - djm@cvs.openbsd.org 2010/11/21 10:57:07 + [authfile.c] + Refactor internals of private key loading and saving to work on memory + buffers rather than directly on files. This will make a few things + easier to do in the future; ok markus@ + - djm@cvs.openbsd.org 2010/11/23 02:35:50 + [auth.c] + use strict_modes already passed as function argument over referencing + global options.strict_modes + - djm@cvs.openbsd.org 2010/11/23 23:57:24 + [clientloop.c] + avoid NULL deref on receiving a channel request on an unknown or invalid + channel; report bz#1842 from jchadima AT redhat.com; ok dtucker@ + - djm@cvs.openbsd.org 2010/11/24 01:24:14 + [channels.c] + remove a debug() that pollutes stderr on client connecting to a server + in debug mode (channel_close_fds is called transitively from the session + code post-fork); bz#1719, ok dtucker + - djm@cvs.openbsd.org 2010/11/25 04:10:09 + [session.c] + replace close() loop for fds 3->64 with closefrom(); + ok markus deraadt dtucker + - djm@cvs.openbsd.org 2010/11/26 05:52:49 + [scp.c] + Pass through ssh command-line flags and options when doing remote-remote + transfers, e.g. to enable agent forwarding which is particularly useful + in this case; bz#1837 ok dtucker@ + - markus@cvs.openbsd.org 2010/11/29 18:57:04 + [authfile.c] + correctly load comment for encrypted rsa1 keys; + report/fix Joachim Schipper; ok djm@ + - djm@cvs.openbsd.org 2010/11/29 23:45:51 + [auth.c hostfile.c hostfile.h ssh.c ssh_config.5 sshconnect.c] + [sshconnect.h sshconnect2.c] + automatically order the hostkeys requested by the client based on + which hostkeys are already recorded in known_hosts. This avoids + hostkey warnings when connecting to servers with new ECDSA keys + that are preferred by default; with markus@ + +20101124 + - (dtucker) [platform.c session.c] Move the getluid call out of session.c and + into the platform-specific code Only affects SCO, tested by and ok tim@. + - (djm) [loginrec.c] Relax permission requirement on btmp logs to allow + group read/write. ok dtucker@ + - (dtucker) [packet.c] Remove redundant local declaration of "int tos". + - (djm) [defines.h] Add IP DSCP defines + +20101122 + - (dtucker) Bug #1840: fix warning when configuring --with-ssl-engine, patch + from vapier at gentoo org. + +20101120 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/11/05 02:46:47 + [packet.c] + whitespace KNF + - djm@cvs.openbsd.org 2010/11/10 01:33:07 + [kexdhc.c kexdhs.c kexgexc.c kexgexs.c key.c moduli.c] + use only libcrypto APIs that are retained with OPENSSL_NO_DEPRECATED. + these have been around for years by this time. ok markus + - djm@cvs.openbsd.org 2010/11/13 23:27:51 + [clientloop.c misc.c misc.h packet.c packet.h readconf.c readconf.h] + [servconf.c servconf.h session.c ssh.c ssh_config.5 sshd_config.5] + allow ssh and sshd to set arbitrary TOS/DSCP/QoS values instead of + hardcoding lowdelay/throughput. + + bz#1733 patch from philipp AT redfish-solutions.com; ok markus@ deraadt@ + - jmc@cvs.openbsd.org 2010/11/15 07:40:14 + [ssh_config.5] + libary -> library; + - jmc@cvs.openbsd.org 2010/11/18 15:01:00 + [scp.1 sftp.1 ssh.1 sshd_config.5] + add IPQoS to the various -o lists, and zap some trailing whitespace; + +20101111 + - (djm) [servconf.c ssh-add.c ssh-keygen.c] don't look for ECDSA keys on + platforms that don't support ECC. Fixes some spurious warnings reported + by tim@ + +20101109 + - (tim) [regress/kextype.sh] Not all platforms have time in /usr/bin. + Feedback from dtucker@ + - (tim) [configure.ac openbsd-compat/bsd-misc.h openbsd-compat/bsd-misc.c] Add + support for platforms missing isblank(). ok djm@ + +20101108 + - (tim) [regress/Makefile] Fixes to allow building/testing outside source + tree. + - (tim) [regress/kextype.sh] Shell portability fix. + +20101107 + - (dtucker) [platform.c] includes.h instead of defines.h so that we get + the correct typedefs. + +20101105 + - (djm) [loginrec.c loginrec.h] Use correct uid_t/pid_t types instead of + int. Should fix bz#1817 cleanly; ok dtucker@ + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/09/22 12:26:05 + [regress/Makefile regress/kextype.sh] + regress test for each of the key exchange algorithms that we support + - djm@cvs.openbsd.org 2010/10/28 11:22:09 + [authfile.c key.c key.h ssh-keygen.c] + fix a possible NULL deref on loading a corrupt ECDH key + + store ECDH group information in private keys files as "named groups" + rather than as a set of explicit group parameters (by setting + the OPENSSL_EC_NAMED_CURVE flag). This makes for shorter key files and + retrieves the group's OpenSSL NID that we need for various things. + - jmc@cvs.openbsd.org 2010/10/28 18:33:28 + [scp.1 ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5 sshd.8 sshd_config.5] + knock out some "-*- nroff -*-" lines; + - djm@cvs.openbsd.org 2010/11/04 02:45:34 + [sftp-server.c] + umask should be parsed as octal. reported by candland AT xmission.com; + ok markus@ + - (dtucker) [configure.ac platform.{c,h} session.c + openbsd-compat/port-solaris.{c,h}] Bug #1824: Add Solaris Project support. + Patch from cory.erickson at csu mnscu edu with a bit of rework from me. + ok djm@ + - (dtucker) [platform.c platform.h session.c] Add a platform hook to run + after the user's groups are established and move the selinux calls into it. + - (dtucker) [platform.c session.c] Move the AIX setpcred+chroot hack into + platform.c + - (dtucker) [platform.c session.c] Move the BSDI setpgrp into platform.c. + - (dtucker) [platform.c] Only call setpgrp on BSDI if running as root to + retain previous behavior. + - (dtucker) [platform.c session.c] Move the PAM credential establishment for + the LOGIN_CAP case into platform.c. + - (dtucker) platform.c session.c] Move the USE_LIBIAF fragment into + platform.c + - (dtucker) [platform.c session.c] Move aix_usrinfo frament into platform.c. + - (dtucker) [platform.c session.c] Move irix setusercontext fragment into + platform.c. + - (dtucker) [platform.c session.c] Move PAM credential establishment for the + non-LOGIN_CAP case into platform.c. + - (dtucker) [platform.c platform.h session.c] Move the Cygwin special-case + check into platform.c + - (dtucker) [regress/keytype.sh] Import new test. + - (dtucker) [Makefile configure.ac regress/Makefile regress/keytype.sh] + Import recent changes to regress/Makefile, pass a flag to enable ECC tests + from configure through to regress/Makefile and use it in the tests. + - (dtucker) [regress/kextype.sh] Add missing "test". + - (dtucker) [regress/kextype.sh] Make sha256 test depend on ECC. This is not + strictly correct since while ECC requires sha256 the reverse is not true + however it does prevent spurious test failures. + - (dtucker) [platform.c] Need servconf.h and extern options. + +20101025 + - (tim) [openbsd-compat/glob.h] Remove sys/cdefs.h include that came with + 1.12 to unbreak Solaris build. + ok djm@ + - (dtucker) [defines.h] Use SIZE_T_MAX for SIZE_MAX for platforms that have a + native one. + +20101024 + - (dtucker) [includes.h] Add missing ifdef GLOB_HAS_GL_STATV to fix build. + - (dtucker) [regress/cert-hostkey.sh] Disable ECC-based tests on platforms + which don't have ECC support in libcrypto. + - (dtucker) [regress/cert-userkey.sh] Disable ECC-based tests on platforms + which don't have ECC support in libcrypto. + - (dtucker) [defines.h] Add SIZE_MAX for the benefit of platforms that don't + have it. + - (dtucker) OpenBSD CVS Sync + - sthen@cvs.openbsd.org 2010/10/23 22:06:12 + [sftp.c] + escape '[' in filename tab-completion; fix a type while there. + ok djm@ + +20101021 + - OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2010/10/12 02:22:24 + [mux.c] + Typo in confirmation message. bz#1827, patch from imorgan at + nas nasa gov + - djm@cvs.openbsd.org 2010/08/31 12:24:09 + [regress/cert-hostkey.sh regress/cert-userkey.sh] + tests for ECDSA certificates + +20101011 + - (djm) [canohost.c] Zero a4 instead of addr to better match type. + bz#1825, reported by foo AT mailinator.com + - (djm) [sshconnect.c] Need signal.h for prototype for kill(2) + +20101011 + - (djm) [configure.ac] Use = instead of == in shell tests. Patch from + dr AT vasco.com + +20101007 + - (djm) [ssh-agent.c] Fix type for curve name. + - (djm) OpenBSD CVS Sync + - matthew@cvs.openbsd.org 2010/09/24 13:33:00 + [misc.c misc.h configure.ac openbsd-compat/openbsd-compat.h] + [openbsd-compat/timingsafe_bcmp.c] + Add timingsafe_bcmp(3) to libc, mention that it's already in the + kernel in kern(9), and remove it from OpenSSH. + ok deraadt@, djm@ + NB. re-added under openbsd-compat/ for portable OpenSSH + - djm@cvs.openbsd.org 2010/09/25 09:30:16 + [sftp.c configure.ac openbsd-compat/glob.c openbsd-compat/glob.h] + make use of new glob(3) GLOB_KEEPSTAT extension to save extra server + rountrips to fetch per-file stat(2) information. + NB. update openbsd-compat/ glob(3) implementation from OpenBSD libc to + match. + - djm@cvs.openbsd.org 2010/09/26 22:26:33 + [sftp.c] + when performing an "ls" in columnated (short) mode, only call + ioctl(TIOCGWINSZ) once to get the window width instead of per- + filename + - djm@cvs.openbsd.org 2010/09/30 11:04:51 + [servconf.c] + prevent free() of string in .rodata when overriding AuthorizedKeys in + a Match block; patch from rein AT basefarm.no + - djm@cvs.openbsd.org 2010/10/01 23:05:32 + [cipher-3des1.c cipher-bf1.c cipher-ctr.c openbsd-compat/openssl-compat.h] + adapt to API changes in openssl-1.0.0a + NB. contains compat code to select correct API for older OpenSSL + - djm@cvs.openbsd.org 2010/10/05 05:13:18 + [sftp.c sshconnect.c] + use default shell /bin/sh if $SHELL is ""; ok markus@ + - djm@cvs.openbsd.org 2010/10/06 06:39:28 + [clientloop.c ssh.c sshconnect.c sshconnect.h] + kill proxy command on fatal() (we already kill it on clean exit); + ok markus@ + - djm@cvs.openbsd.org 2010/10/06 21:10:21 + [sshconnect.c] + swapped args to kill(2) + - (djm) [openbsd-compat/glob.c] restore ARG_MAX compat code. + - (djm) [cipher-acss.c] Add missing header. + - (djm) [openbsd-compat/Makefile.in] Actually link timingsafe_bcmp + +20100924 + - (djm) OpenBSD CVS Sync + - naddy@cvs.openbsd.org 2010/09/10 15:19:29 + [ssh-keygen.1] + * mention ECDSA in more places + * less repetition in FILES section + * SSHv1 keys are still encrypted with 3DES + help and ok jmc@ + - djm@cvs.openbsd.org 2010/09/11 21:44:20 + [ssh.1] + mention RFC 5656 for ECC stuff + - jmc@cvs.openbsd.org 2010/09/19 21:30:05 + [sftp.1] + more wacky macro fixing; + - djm@cvs.openbsd.org 2010/09/20 04:41:47 + [ssh.c] + install a SIGCHLD handler to reap expiried child process; ok markus@ + - djm@cvs.openbsd.org 2010/09/20 04:50:53 + [jpake.c schnorr.c] + check that received values are smaller than the group size in the + disabled and unfinished J-PAKE code. + avoids catastrophic security failure found by Sebastien Martini + - djm@cvs.openbsd.org 2010/09/20 04:54:07 + [jpake.c] + missing #include + - djm@cvs.openbsd.org 2010/09/20 07:19:27 + [mux.c] + "atomically" create the listening mux socket by binding it on a temorary + name and then linking it into position after listen() has succeeded. + this allows the mux clients to determine that the server socket is + either ready or stale without races. stale server sockets are now + automatically removed + ok deraadt + - djm@cvs.openbsd.org 2010/09/22 05:01:30 + [kex.c kex.h kexecdh.c kexecdhc.c kexecdhs.c readconf.c readconf.h] + [servconf.c servconf.h ssh_config.5 sshconnect2.c sshd.c sshd_config.5] + add a KexAlgorithms knob to the client and server configuration to allow + selection of which key exchange methods are used by ssh(1) and sshd(8) + and their order of preference. + ok markus@ + - jmc@cvs.openbsd.org 2010/09/22 08:30:08 + [ssh.1 ssh_config.5] + ssh.1: add kexalgorithms to the -o list + ssh_config.5: format the kexalgorithms in a more consistent + (prettier!) way + ok djm + - djm@cvs.openbsd.org 2010/09/22 22:58:51 + [atomicio.c atomicio.h misc.c misc.h scp.c sftp-client.c] + [sftp-client.h sftp.1 sftp.c] + add an option per-read/write callback to atomicio + + factor out bandwidth limiting code from scp(1) into a generic bandwidth + limiter that can be attached using the atomicio callback mechanism + + add a bandwidth limit option to sftp(1) using the above + "very nice" markus@ + - jmc@cvs.openbsd.org 2010/09/23 13:34:43 + [sftp.c] + add [-l limit] to usage(); + - jmc@cvs.openbsd.org 2010/09/23 13:36:46 + [scp.1 sftp.1] + add KexAlgorithms to the -o list; + +20100910 + - (dtucker) [openbsd-compat/port-linux.c] Check is_selinux_enabled for exact + return code since it can apparently return -1 under some conditions. From + openssh bugs werbittewas de, ok djm@ + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/08/31 12:33:38 + [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] + reintroduce commit from tedu@, which I pulled out for release + engineering: + OpenSSL_add_all_algorithms is the name of the function we have a + man page for, so use that. ok djm + - jmc@cvs.openbsd.org 2010/08/31 17:40:54 + [ssh-agent.1] + fix some macro abuse; + - jmc@cvs.openbsd.org 2010/08/31 21:14:58 + [ssh.1] + small text tweak to accommodate previous; + - naddy@cvs.openbsd.org 2010/09/01 15:21:35 + [servconf.c] + pick up ECDSA host key by default; ok djm@ + - markus@cvs.openbsd.org 2010/09/02 16:07:25 + [ssh-keygen.c] + permit -b 256, 384 or 521 as key size for ECDSA; ok djm@ + - markus@cvs.openbsd.org 2010/09/02 16:08:39 + [ssh.c] + unbreak ControlPersist=yes for ControlMaster=yes; ok djm@ + - naddy@cvs.openbsd.org 2010/09/02 17:21:50 + [ssh-keygen.c] + Switch ECDSA default key size to 256 bits, which according to RFC5656 + should still be better than our current RSA-2048 default. + ok djm@, markus@ + - jmc@cvs.openbsd.org 2010/09/03 11:09:29 + [scp.1] + add an EXIT STATUS section for /usr/bin; + - jmc@cvs.openbsd.org 2010/09/04 09:38:34 + [ssh-add.1 ssh.1] + two more EXIT STATUS sections; + - naddy@cvs.openbsd.org 2010/09/06 17:10:19 + [sshd_config] + add ssh_host_ecdsa_key to /etc; from Mattieu Baptiste + + ok deraadt@ + - djm@cvs.openbsd.org 2010/09/08 03:54:36 + [authfile.c] + typo + - deraadt@cvs.openbsd.org 2010/09/08 04:13:31 + [compress.c] + work around name-space collisions some buggy compilers (looking at you + gcc, at least in earlier versions, but this does not forgive your current + transgressions) seen between zlib and openssl + ok djm + - djm@cvs.openbsd.org 2010/09/09 10:45:45 + [kex.c kex.h kexecdh.c key.c key.h monitor.c ssh-ecdsa.c] + ECDH/ECDSA compliance fix: these methods vary the hash function they use + (SHA256/384/512) depending on the length of the curve in use. The previous + code incorrectly used SHA256 in all cases. + + This fix will cause authentication failure when using 384 or 521-bit curve + keys if one peer hasn't been upgraded and the other has. (256-bit curve + keys work ok). In particular you may need to specify HostkeyAlgorithms + when connecting to a server that has not been upgraded from an upgraded + client. + + ok naddy@ + - (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c] + [kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c] + [ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on + platforms that don't have the requisite OpenSSL support. ok dtucker@ + - (dtucker) [kex.h key.c packet.h ssh-agent.c ssh.c] A few more ECC ifdefs + for missing headers and compiler warnings. + +20100831 + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/08/08 19:36:30 + [ssh-keysign.8 ssh.1 sshd.8] + use the same template for all FILES sections; i.e. -compact/.Pp where we + have multiple items, and .Pa for path names; + - tedu@cvs.openbsd.org 2010/08/12 23:34:39 + [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] + OpenSSL_add_all_algorithms is the name of the function we have a man page + for, so use that. ok djm + - djm@cvs.openbsd.org 2010/08/16 04:06:06 + [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] + backout previous temporarily; discussed with deraadt@ + - djm@cvs.openbsd.org 2010/08/31 09:58:37 + [auth-options.c auth1.c auth2.c bufaux.c buffer.h kex.c key.c packet.c] + [packet.h ssh-dss.c ssh-rsa.c] + Add buffer_get_cstring() and related functions that verify that the + string extracted from the buffer contains no embedded \0 characters* + This prevents random (possibly malicious) crap from being appended to + strings where it would not be noticed if the string is used with + a string(3) function. + + Use the new API in a few sensitive places. + + * actually, we allow a single one at the end of the string for now because + we don't know how many deployed implementations get this wrong, but don't + count on this to remain indefinitely. + - djm@cvs.openbsd.org 2010/08/31 11:54:45 + [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys auth2-jpake.c authfd.c] + [authfile.c buffer.h dns.c kex.c kex.h key.c key.h monitor.c] + [monitor_wrap.c myproposal.h packet.c packet.h pathnames.h readconf.c] + [ssh-add.1 ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh-keygen.c] + [ssh-keyscan.1 ssh-keyscan.c ssh-keysign.8 ssh.1 ssh.c ssh2.h] + [ssh_config.5 sshconnect.c sshconnect2.c sshd.8 sshd.c sshd_config.5] + [uuencode.c uuencode.h bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] + Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and + host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer + better performance than plain DH and DSA at the same equivalent symmetric + key length, as well as much shorter keys. + + Only the mandatory sections of RFC5656 are implemented, specifically the + three REQUIRED curves nistp256, nistp384 and nistp521 and only ECDH and + ECDSA. Point compression (optional in RFC5656 is NOT implemented). + + Certificate host and user keys using the new ECDSA key types are supported. + + Note that this code has not been tested for interoperability and may be + subject to change. + + feedback and ok markus@ + - (djm) [Makefile.in] Add new ECC files + - (djm) [bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] include + includes.h + +20100827 + - (dtucker) [contrib/redhat/sshd.init] Bug #1810: initlog is deprecated, + remove. Patch from martynas at venck us + 20100823 - (djm) Release OpenSSH-5.6p1 @@ -517,2746 +1202,3 @@ ok markus@ -20100410 - - (dtucker) [configure.ac] Put the check for the existence of getaddrinfo - back so we disable the IPv6 tests if we don't have it. - -20100409 - - (dtucker) [contrib/cygwin/Makefile] Don't overwrite files with the wrong - ones. Based on a patch from Roumen Petrov. - - (dtucker) [configure.ac] Bug #1744: use pkg-config for libedit flags if we - have it and the path is not provided to --with-libedit. Based on a patch - from Iain Morgan. - - (dtucker) [configure.ac defines.h loginrec.c logintest.c] Bug #1732: enable - utmpx support on FreeBSD where possible. Patch from Ed Schouten, ok djm@ - -20100326 - - (djm) [openbsd-compat/bsd-arc4random.c] Fix preprocessor detection - for arc4random_buf() and arc4random_uniform(); from Josh Gilkerson - - (dtucker) [configure.ac] Bug #1741: Add section for Haiku, patch originally - by Ingo Weinhold via Scott McCreary, ok djm@ - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/03/25 23:38:28 - [servconf.c] - from portable: getcwd(NULL, 0) doesn't work on all platforms, so - use a stack buffer; ok dtucker@ - - djm@cvs.openbsd.org 2010/03/26 00:26:58 - [ssh.1] - mention that -S none disables connection sharing; from Colin Watson - - (djm) [session.c] Allow ChrootDirectory to work on SELinux platforms - - set up SELinux execution context before chroot() call. From Russell - Coker via Colin watson; bz#1726 ok dtucker@ - - (djm) [channels.c] Check for EPFNOSUPPORT as a socket() errno; bz#1721 - ok dtucker@ - - (dtucker) Bug #1725: explicitly link libX11 into gnome-ssh-askpass2 using - pkg-config, patch from Colin Watson. Needed for newer linkers (ie gold). - - (djm) [contrib/ssh-copy-id] Don't blow up when the agent has no keys; - bz#1723 patch from Adeodato Simóvia Colin Watson; ok dtucker@ - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2010/03/26 01:06:13 - [ssh_config.5] - Reformat default value of PreferredAuthentications entry (current - formatting implies ", " is acceptable as a separator, which it's not. - ok djm@ - -20100324 - - (dtucker) [contrib/cygwin/ssh-host-config] Mount the Windows directory - containing the services file explicitely case-insensitive. This allows to - tweak the Windows services file reliably. Patch from vinschen at redhat. - -20100321 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/03/08 09:41:27 - [ssh-keygen.1] - sort the list of constraints (to -O); ok djm - - jmc@cvs.openbsd.org 2010/03/10 07:40:35 - [ssh-keygen.1] - typos; from Ross Richardson - closes prs 6334 and 6335 - - djm@cvs.openbsd.org 2010/03/10 23:27:17 - [auth2-pubkey.c] - correct certificate logging and make it more consistent between - authorized_keys and TrustedCAKeys; ok markus@ - - djm@cvs.openbsd.org 2010/03/12 01:06:25 - [servconf.c] - unbreak AuthorizedKeys option with a $HOME-relative path; reported by - vinschen AT redhat.com, ok dtucker@ - - markus@cvs.openbsd.org 2010/03/12 11:37:40 - [servconf.c] - do not prepend AuthorizedKeysFile with getcwd(), unbreaks relative paths - free() (not xfree()) the buffer returned by getcwd() - - djm@cvs.openbsd.org 2010/03/13 21:10:38 - [clientloop.c] - protocol conformance fix: send language tag when disconnecting normally; - spotted by 1.41421 AT gmail.com, ok markus@ deraadt@ - - djm@cvs.openbsd.org 2010/03/13 21:45:46 - [ssh-keygen.1] - Certificates are named *-cert.pub, not *_cert.pub; committing a diff - from stevesk@ ok me - - jmc@cvs.openbsd.org 2010/03/13 23:38:13 - [ssh-keygen.1] - fix a formatting error (args need quoted); noted by stevesk - - stevesk@cvs.openbsd.org 2010/03/15 19:40:02 - [key.c key.h ssh-keygen.c] - also print certificate type (user or host) for ssh-keygen -L - ok djm kettenis - - stevesk@cvs.openbsd.org 2010/03/16 15:46:52 - [auth-options.c] - spelling in error message. ok djm kettenis - - djm@cvs.openbsd.org 2010/03/16 16:36:49 - [version.h] - crank version to openssh-5.5 since we have a few fixes since 5.4; - requested deraadt@ kettenis@ - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank version numbers - -20100314 - - (djm) [ssh-pkcs11-helper.c] Move #ifdef to after #defines to fix - compilation failure when !HAVE_DLOPEN. Reported by felix-mindrot - AT fefe.de - - (djm) [Makefile.in] Respecify -lssh after -lopenbsd-compat for - ssh-pkcs11-helper to repair static builds (we do the same for - ssh-keyscan). Reported by felix-mindrot AT fefe.de - -20100312 - - (tim) [Makefile.in] Now that scard is gone, no need to make $(datadir) - - (tim) [Makefile.in] Add missing $(EXEEXT) to install targets. - Patch from Corinna Vinschen. - - (tim) [contrib/cygwin/Makefile] Fix list of documentation files to install - on a Cygwin installation. Patch from Corinna Vinschen. - -20100311 - - (tim) [contrib/suse/openssh.spec] crank version number here too. - report by imorgan AT nas.nasa.gov - -20100309 - - (dtucker) [configure.ac] Use a proper AC_CHECK_DECL for BROKEN_GETADDRINFO - so setting it in CFLAGS correctly skips IPv6 tests. - -20100308 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/03/07 22:16:01 - [ssh-keygen.c] - make internal strptime string match strftime format; - suggested by vinschen AT redhat.com and markus@ - - djm@cvs.openbsd.org 2010/03/08 00:28:55 - [ssh-keygen.1] - document permit-agent-forwarding certificate constraint; patch from - stevesk@ - - djm@cvs.openbsd.org 2010/03/07 22:01:32 - [version.h] - openssh-5.4 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - crank version numbers - - (djm) Release OpenSSH-5.4p1 - -20100307 - - (dtucker) [auth.c] Bug #1710: call setauthdb on AIX before getpwuid so that - it gets the passwd struct from the LAM that knows about the user which is - not necessarily the default. Patch from Alexandre Letourneau. - - (dtucker) [session.c] Bug #1567: move setpcred call to before chroot and - do not set real uid, since that's needed for the chroot, and will be set - by permanently_set_uid. - - (dtucker) [session.c] Also initialize creds to NULL for handing to - setpcred. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2010/03/07 11:57:13 - [auth-rhosts.c monitor.c monitor_wrap.c session.c auth-options.c sshd.c] - Hold authentication debug messages until after successful authentication. - Fixes an info leak of environment variables specified in authorized_keys, - reported by Jacob Appelbaum. ok djm@ - -20100305 - - OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/03/04 12:51:25 - [ssh.1 sshd_config.5] - tweak previous; - - djm@cvs.openbsd.org 2010/03/04 20:35:08 - [ssh-keygen.1 ssh-keygen.c] - Add a -L flag to print the contents of a certificate; ok markus@ - - jmc@cvs.openbsd.org 2010/03/04 22:52:40 - [ssh-keygen.1] - fix Bk/Ek; - - djm@cvs.openbsd.org 2010/03/04 23:17:25 - [sshd_config.5] - missing word; spotted by jmc@ - - djm@cvs.openbsd.org 2010/03/04 23:19:29 - [ssh.1 sshd.8] - move section on CA and revoked keys from ssh.1 to sshd.8's known hosts - format section and rework it a bit; requested by jmc@ - - djm@cvs.openbsd.org 2010/03/04 23:27:25 - [auth-options.c ssh-keygen.c] - "force-command" is not spelled "forced-command"; spotted by - imorgan AT nas.nasa.gov - - djm@cvs.openbsd.org 2010/03/05 02:58:11 - [auth.c] - make the warning for a revoked key louder and more noticable - - jmc@cvs.openbsd.org 2010/03/05 06:50:35 - [ssh.1 sshd.8] - tweak previous; - - jmc@cvs.openbsd.org 2010/03/05 08:31:20 - [ssh.1] - document certificate authentication; help/ok djm - - djm@cvs.openbsd.org 2010/03/05 10:28:21 - [ssh-add.1 ssh.1 ssh_config.5] - mention loading of certificate files from [private]-cert.pub when - they are present; feedback and ok jmc@ - - (tim) [ssh-pkcs11.c] Fix "non-constant initializer" errors in older - compilers. OK djm@ - - (djm) [ssh-rand-helper.c] declare optind, avoiding compilation failure - on some platforms - - (djm) [configure.ac] set -fno-strict-aliasing for gcc4; ok dtucker@ - -20100304 - - (djm) [ssh-keygen.c] Use correct local variable, instead of - maybe-undefined global "optarg" - - (djm) [contrib/redhat/openssh.spec] Replace obsolete BuildPreReq - on XFree86-devel with neutral /usr/include/X11/Xlib.h; - imorgan AT nas.nasa.gov in bz#1731 - - (djm) [.cvsignore] Ignore ssh-pkcs11-helper - - (djm) [regress/Makefile] Cleanup sshd_proxy_orig - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/03/03 01:44:36 - [auth-options.c key.c] - reject strings with embedded ASCII nul chars in certificate key IDs, - principal names and constraints - - djm@cvs.openbsd.org 2010/03/03 22:49:50 - [sshd.8] - the authorized_keys option for CA keys is "cert-authority", not - "from=cert-authority". spotted by imorgan AT nas.nasa.gov - - djm@cvs.openbsd.org 2010/03/03 22:50:40 - [PROTOCOL.certkeys] - s/similar same/similar/; from imorgan AT nas.nasa.gov - - djm@cvs.openbsd.org 2010/03/04 01:44:57 - [key.c] - use buffer_get_string_ptr_ret() where we are checking the return - value explicitly instead of the fatal()-causing buffer_get_string_ptr() - - djm@cvs.openbsd.org 2010/03/04 10:36:03 - [auth-rh-rsa.c auth-rsa.c auth.c auth.h auth2-hostbased.c auth2-pubkey.c] - [authfile.c authfile.h hostfile.c hostfile.h servconf.c servconf.h] - [ssh-keygen.c ssh.1 sshconnect.c sshd_config.5] - Add a TrustedUserCAKeys option to sshd_config to specify CA keys that - are trusted to authenticate users (in addition than doing it per-user - in authorized_keys). - - Add a RevokedKeys option to sshd_config and a @revoked marker to - known_hosts to allow keys to me revoked and banned for user or host - authentication. - - feedback and ok markus@ - - djm@cvs.openbsd.org 2010/03/03 00:47:23 - [regress/cert-hostkey.sh regress/cert-userkey.sh] - add an extra test to ensure that authentication with the wrong - certificate fails as it should (and it does) - - djm@cvs.openbsd.org 2010/03/04 10:38:23 - [regress/cert-hostkey.sh regress/cert-userkey.sh] - additional regression tests for revoked keys and TrustedUserCAKeys - -20100303 - - (djm) [PROTOCOL.certkeys] Add RCS Ident - - OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/02/26 22:09:28 - [ssh-keygen.1 ssh.1 sshd.8] - tweak previous; - - otto@cvs.openbsd.org 2010/03/01 11:07:06 - [ssh-add.c] - zap what seems to be a left-over debug message; ok markus@ - - djm@cvs.openbsd.org 2010/03/02 23:20:57 - [ssh-keygen.c] - POSIX strptime is stricter than OpenBSD's so do a little dance to - appease it. - - (djm) [regress/cert-userkey.sh] s/echo -n/echon/ here too - -20100302 - - (tim) [config.guess config.sub] Bug 1722: Update to latest versions from - http://git.savannah.gnu.org/gitweb/ (2009-12-30 and 2010-01-22 - respectively). - -20100301 - - (dtucker) [regress/{cert-hostkey,cfgmatch,cipher-speed}.sh} Replace - "echo -n" with "echon" for portability. - - (dtucker) [openbsd-compat/port-linux.c] Make failure to write to the OOM - adjust log at verbose only, since according to cjwatson in bug #1470 - some virtualization platforms don't allow writes. - -20100228 - - (djm) [auth.c] On Cygwin, refuse usernames that have differences in - case from that matched in the system password database. On this - platform, passwords are stored case-insensitively, but sshd requires - exact case matching for Match blocks in sshd_config(5). Based on - a patch from vinschen AT redhat.com. - - (tim) [ssh-pkcs11-helper.c] Move declarations before calling functions - to make older compilers (gcc 2.95) happy. - -20100227 - - (djm) [ssh-pkcs11-helper.c ] Ensure RNG is initialised and seeded - - (djm) [openbsd-compat/bsd-cygwin_util.c] Reduce the set of environment - variables copied into sshd child processes. From vinschen AT redhat.com - -20100226 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/02/26 20:29:54 - [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys addrmatch.c auth-options.c] - [auth-options.h auth.h auth2-pubkey.c authfd.c dns.c dns.h hostfile.c] - [hostfile.h kex.h kexdhs.c kexgexs.c key.c key.h match.h monitor.c] - [myproposal.h servconf.c servconf.h ssh-add.c ssh-agent.c ssh-dss.c] - [ssh-keygen.1 ssh-keygen.c ssh-rsa.c ssh.1 ssh.c ssh2.h sshconnect.c] - [sshconnect2.c sshd.8 sshd.c sshd_config.5] - Add support for certificate key types for users and hosts. - - OpenSSH certificate key types are not X.509 certificates, but a much - simpler format that encodes a public key, identity information and - some validity constraints and signs it with a CA key. CA keys are - regular SSH keys. This certificate style avoids the attack surface - of X.509 certificates and is very easy to deploy. - - Certified host keys allow automatic acceptance of new host keys - when a CA certificate is marked as trusted in ~/.ssh/known_hosts. - see VERIFYING HOST KEYS in ssh(1) for details. - - Certified user keys allow authentication of users when the signing - CA key is marked as trusted in authorized_keys. See "AUTHORIZED_KEYS - FILE FORMAT" in sshd(8) for details. - - Certificates are minted using ssh-keygen(1), documentation is in - the "CERTIFICATES" section of that manpage. - - Documentation on the format of certificates is in the file - PROTOCOL.certkeys - - feedback and ok markus@ - - djm@cvs.openbsd.org 2010/02/26 20:33:21 - [Makefile regress/cert-hostkey.sh regress/cert-userkey.sh] - regression tests for certified keys - -20100224 - - (djm) [pkcs11.h ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] - [ssh-pkcs11.h] Add $OpenBSD$ RCS idents so we can sync portable - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/02/11 20:37:47 - [pathnames.h] - correct comment - - dtucker@cvs.openbsd.org 2009/11/09 04:20:04 - [regress/Makefile] - add regression test for ssh-keygen pubkey conversions - - dtucker@cvs.openbsd.org 2010/01/11 02:53:44 - [regress/forwarding.sh] - regress test for stdio forwarding - - djm@cvs.openbsd.org 2010/02/09 04:57:36 - [regress/addrmatch.sh] - clean up droppings - - djm@cvs.openbsd.org 2010/02/09 06:29:02 - [regress/Makefile] - turn on all the malloc(3) checking options when running regression - tests. this has caught a few bugs for me in the past; ok dtucker@ - - djm@cvs.openbsd.org 2010/02/24 06:21:56 - [regress/test-exec.sh] - wait for sshd to fully stop in cleanup() function; avoids races in tests - that do multiple start_sshd/cleanup cycles; "I hate pidfiles" deraadt@ - - markus@cvs.openbsd.org 2010/02/08 10:52:47 - [regress/agent-pkcs11.sh] - test for PKCS#11 support (currently disabled) - - (djm) [Makefile.in ssh-pkcs11-helper.8] Add manpage for PKCS#11 helper - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Add PKCS#11 helper binary and manpage - -20100212 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/02/02 22:49:34 - [bufaux.c] - make buffer_get_string_ret() really non-fatal in all cases (it was - using buffer_get_int(), which could fatal() on buffer empty); - ok markus dtucker - - markus@cvs.openbsd.org 2010/02/08 10:50:20 - [pathnames.h readconf.c readconf.h scp.1 sftp.1 ssh-add.1 ssh-add.c] - [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config.5] - replace our obsolete smartcard code with PKCS#11. - ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf - ssh(1) and ssh-keygen(1) use dlopen(3) directly to talk to a PKCS#11 - provider (shared library) while ssh-agent(1) delegates PKCS#11 to - a forked a ssh-pkcs11-helper process. - PKCS#11 is currently a compile time option. - feedback and ok djm@; inspired by patches from Alon Bar-Lev - - jmc@cvs.openbsd.org 2010/02/08 22:03:05 - [ssh-add.1 ssh-keygen.1 ssh.1 ssh.c] - tweak previous; ok markus - - djm@cvs.openbsd.org 2010/02/09 00:50:36 - [ssh-agent.c] - fallout from PKCS#11: unbreak -D - - djm@cvs.openbsd.org 2010/02/09 00:50:59 - [ssh-keygen.c] - fix -Wall - - djm@cvs.openbsd.org 2010/02/09 03:56:28 - [buffer.c buffer.h] - constify the arguments to buffer_len, buffer_ptr and buffer_dump - - djm@cvs.openbsd.org 2010/02/09 06:18:46 - [auth.c] - unbreak ChrootDirectory+internal-sftp by skipping check for executable - shell when chrooting; reported by danh AT wzrd.com; ok dtucker@ - - markus@cvs.openbsd.org 2010/02/10 23:20:38 - [ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5] - pkcs#11 is no longer optional; improve wording; ok jmc@ - - jmc@cvs.openbsd.org 2010/02/11 13:23:29 - [ssh.1] - libarary -> library; - - (djm) [INSTALL Makefile.in README.smartcard configure.ac scard-opensc.c] - [scard.c scard.h pkcs11.h scard/Makefile.in scard/Ssh.bin.uu scard/Ssh.java] - Remove obsolete smartcard support - - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] - Make it compile on OSX - - (djm) [ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c] - Use ssh_get_progname to fill __progname - - (djm) [configure.ac] Enable PKCS#11 support only when we find a working - dlopen() - -20100210 - - (djm) add -lselinux to LIBS before calling AC_CHECK_FUNCS for - getseuserbyname; patch from calebcase AT gmail.com via - cjwatson AT debian.org - -20100202 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/01/30 21:08:33 - [sshd.8] - debug output goes to stderr, not "the system log"; ok markus dtucker - - djm@cvs.openbsd.org 2010/01/30 21:12:08 - [channels.c] - fake local addr:port when stdio fowarding as some servers (Tectia at - least) validate that they are well-formed; - reported by imorgan AT nas.nasa.gov - ok dtucker - -20100130 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/01/28 00:21:18 - [clientloop.c] - downgrade an error() to a debug() - this particular case can be hit in - normal operation for certain sequences of mux slave vs session closure - and is harmless - - djm@cvs.openbsd.org 2010/01/29 00:20:41 - [sshd.c] - set FD_CLOEXEC on sock_in/sock_out; bz#1706 from jchadima AT redhat.com - ok dtucker@ - - djm@cvs.openbsd.org 2010/01/29 20:16:17 - [mux.c] - kill correct channel (was killing already-dead mux channel, not - its session channel) - - djm@cvs.openbsd.org 2010/01/30 02:54:53 - [mux.c] - don't mark channel as read failed if it is already closing; suppresses - harmless error messages when connecting to SSH.COM Tectia server - report by imorgan AT nas.nasa.gov - -20100129 - - (dtucker) [openbsd-compat/openssl-compat.c] Bug #1707: Call OPENSSL_config() - after registering the hardware engines, which causes the openssl.cnf file to - be processed. See OpenSSL's man page for OPENSSL_config(3) for details. - Patch from Solomon Peachy, ok djm@. - -20100128 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/01/26 02:15:20 - [mux.c] - -Wuninitialized and remove a // comment; from portable - (Id sync only) - - djm@cvs.openbsd.org 2010/01/27 13:26:17 - [mux.c] - fix bug introduced in mux rewrite: - - In a mux master, when a socket to a mux slave closes before its server - session (as may occur when the slave has been signalled), gracefully - close the server session rather than deleting its channel immediately. - A server may have more messages on that channel to send (e.g. an exit - message) that will fatal() the client if they are sent to a channel that - has been prematurely deleted. - - spotted by imorgan AT nas.nasa.gov - - djm@cvs.openbsd.org 2010/01/27 19:21:39 - [sftp.c] - add missing "p" flag to getopt optstring; - bz#1704 from imorgan AT nas.nasa.gov - -20100126 - - (djm) OpenBSD CVS Sync - - tedu@cvs.openbsd.org 2010/01/17 21:49:09 - [ssh-agent.1] - Correct and clarify ssh-add's password asking behavior. - Improved text dtucker and ok jmc - - dtucker@cvs.openbsd.org 2010/01/18 01:50:27 - [roaming_client.c] - s/long long unsigned/unsigned long long/, from tim via portable - (Id sync only, change already in portable) - - djm@cvs.openbsd.org 2010/01/26 01:28:35 - [channels.c channels.h clientloop.c clientloop.h mux.c nchan.c ssh.c] - rewrite ssh(1) multiplexing code to a more sensible protocol. - - The new multiplexing code uses channels for the listener and - accepted control sockets to make the mux master non-blocking, so - no stalls when processing messages from a slave. - - avoid use of fatal() in mux master protocol parsing so an errant slave - process cannot take down a running master. - - implement requesting of port-forwards over multiplexed sessions. Any - port forwards requested by the slave are added to those the master has - established. - - add support for stdio forwarding ("ssh -W host:port ...") in mux slaves. - - document master/slave mux protocol so that other tools can use it to - control a running ssh(1). Note: there are no guarantees that this - protocol won't be incompatibly changed (though it is versioned). - - feedback Salvador Fandino, dtucker@ - channel changes ok markus@ - -20100122 - - (tim) [configure.ac] Due to constraints in Windows Sockets in terms of - socket inheritance, reduce the default SO_RCVBUF/SO_SNDBUF buffer size - in Cygwin to 65535. Patch from Corinna Vinschen. - -20100117 - - (tim) [configure.ac] OpenServer 5 needs BROKEN_GETADDRINFO too. - - (tim) [configure.ac] On SVR5 systems, use the C99-conforming functions - snprintf() and vsnprintf() named _xsnprintf() and _xvsnprintf(). - -20100116 - - (dtucker) [openbsd-compat/pwcache.c] Pull in includes.h and thus defines.h - so we correctly detect whether or not we have a native user_from_uid. - - (dtucker) [openbsd-compat/openbsd-compat.h] Prototypes for user_from_uid - and group_from_gid. - - (dtucker) [openbsd-compat/openbsd-compat.h] Fix prototypes, spotted by - Tim. - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2010/01/15 09:24:23 - [sftp-common.c] - unused - - (dtucker) [openbsd-compat/pwcache.c] Shrink ifdef area to prevent unused - variable warnings. - - (dtucker) [openbsd-compat/openbsd-compat.h] Typo. - - (tim) [regress/portnum.sh] Shell portability fix. - - (tim) [configure.ac] Define BROKEN_GETADDRINFO on SVR5 systems. The native - getaddrinfo() is too old and limited for addr_pton() in addrmatch.c. - - (tim) [roaming_client.c] Use of is not really portable so we - use "openbsd-compat/sys-queue.h". s/long long unsigned/unsigned long long/ - to keep USL compilers happy. - -20100115 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2010/01/13 12:48:34 - [sftp.1 sftp.c] - sftp.1: put ls -h in the right place - sftp.c: as above, plus add -p to get/put, and shorten their arg names - to keep the help usage nicely aligned - ok djm - - djm@cvs.openbsd.org 2010/01/13 23:47:26 - [auth.c] - when using ChrootDirectory, make sure we test for the existence of the - user's shell inside the chroot; bz #1679, patch from alex AT rtfs.hu; - ok dtucker - - dtucker@cvs.openbsd.org 2010/01/14 23:41:49 - [sftp-common.c] - use user_from{uid,gid} to lookup up ids since it keeps a small cache. - ok djm - - guenther@cvs.openbsd.org 2010/01/15 00:05:22 - [sftp.c] - Reset SIGTERM to SIG_DFL before executing ssh, so that even if sftp - inherited SIGTERM as ignored it will still be able to kill the ssh it - starts. - ok dtucker@ - - (dtucker) [openbsd-compat/pwcache.c] Pull in pwcache.c from OpenBSD (no - changes yet but there will be some to come). - - (dtucker) [configure.ac openbsd-compat/{Makefile.in,pwcache.c} Portability - for pwcache. Also, added caching of negative hits. - -20100114 - - (djm) [platform.h] Add missing prototype for - platform_krb5_get_principal_name - -20100113 - - (dtucker) [monitor_fdpass.c] Wrap poll.h include in ifdefs. - - (dtucker) [openbsd-compat/readpassphrase.c] Resync against OpenBSD's r1.18: - missing restore of SIGTTOU and some whitespace. - - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.21. - - (dtucker) [openbsd-compat/readpassphrase.c] Update to OpenBSD's r1.22. - Fixes bz #1590, where sometimes you could not interrupt a connection while - ssh was prompting for a passphrase or password. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2010/01/13 00:19:04 - [sshconnect.c auth.c] - Fix a couple of typos/mispellings in comments - - dtucker@cvs.openbsd.org 2010/01/13 01:10:56 - [key.c] - Ignore and log any Protocol 1 keys where the claimed size is not equal to - the actual size. Noted by Derek Martin, ok djm@ - - dtucker@cvs.openbsd.org 2010/01/13 01:20:20 - [canohost.c ssh-keysign.c sshconnect2.c] - Make HostBased authentication work with a ProxyCommand. bz #1569, patch - from imorgan at nas nasa gov, ok djm@ - - djm@cvs.openbsd.org 2010/01/13 01:40:16 - [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h] - support '-h' (human-readable units) for sftp's ls command, just like - ls(1); ok dtucker@ - - djm@cvs.openbsd.org 2010/01/13 03:48:13 - [servconf.c servconf.h sshd.c] - avoid run-time failures when specifying hostkeys via a relative - path by prepending the cwd in these cases; bz#1290; ok dtucker@ - - djm@cvs.openbsd.org 2010/01/13 04:10:50 - [sftp.c] - don't append a space after inserting a completion of a directory (i.e. - a path ending in '/') for a slightly better user experience; ok dtucker@ - - (dtucker) [sftp-common.c] Wrap include of util.h in an ifdef. - - (tim) [defines.h] openbsd-compat/readpassphrase.c now needs _NSIG. - feedback and ok dtucker@ - -20100112 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2010/01/11 01:39:46 - [ssh_config channels.c ssh.1 channels.h ssh.c] - Add a 'netcat mode' (ssh -W). This connects stdio on the client to a - single port forward on the server. This allows, for example, using ssh as - a ProxyCommand to route connections via intermediate servers. - bz #1618, man page help from jmc@, ok markus@ - - dtucker@cvs.openbsd.org 2010/01/11 04:46:45 - [authfile.c sshconnect2.c] - Do not prompt for a passphrase if we fail to open a keyfile, and log the - reason the open failed to debug. - bz #1693, found by tj AT castaglia org, ok djm@ - - djm@cvs.openbsd.org 2010/01/11 10:51:07 - [ssh-keygen.c] - when converting keys, truncate key comments at 72 chars as per RFC4716; - bz#1630 reported by tj AT castaglia.org; ok markus@ - - dtucker@cvs.openbsd.org 2010/01/12 00:16:47 - [authfile.c] - Fix bug introduced in r1.78 (incorrect brace location) that broke key auth. - Patch from joachim joachimschipper nl. - - djm@cvs.openbsd.org 2010/01/12 00:58:25 - [monitor_fdpass.c] - avoid spinning when fd passing on nonblocking sockets by calling poll() - in the EINTR/EAGAIN path, much like we do in atomicio; ok dtucker@ - - djm@cvs.openbsd.org 2010/01/12 00:59:29 - [roaming_common.c] - delete with extreme prejudice a debug() that fired with every keypress; - ok dtucker deraadt - - dtucker@cvs.openbsd.org 2010/01/12 01:31:05 - [session.c] - Do not allow logins if /etc/nologin exists but is not readable by the user - logging in. Noted by Jan.Pechanec at Sun, ok djm@ deraadt@ - - djm@cvs.openbsd.org 2010/01/12 01:36:08 - [buffer.h bufaux.c] - add a buffer_get_string_ptr_ret() that does the same as - buffer_get_string_ptr() but does not fatal() on error; ok dtucker@ - - dtucker@cvs.openbsd.org 2010/01/12 08:33:17 - [session.c] - Add explicit stat so we reliably detect nologin with bad perms. - ok djm markus - -20100110 - - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] - Remove hacks add for RoutingDomain in preparation for its removal. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2010/01/09 23:04:13 - [channels.c ssh.1 servconf.c sshd_config.5 sshd.c channels.h servconf.h - ssh-keyscan.1 ssh-keyscan.c readconf.c sshconnect.c misc.c ssh.c - readconf.h scp.1 sftp.1 ssh_config.5 misc.h] - Remove RoutingDomain from ssh since it's now not needed. It can be - replaced with "route exec" or "nc -V" as a proxycommand. "route exec" - also ensures that trafic such as DNS lookups stays withing the specified - routingdomain. For example (from reyk): - # route -T 2 exec /usr/sbin/sshd - or inherited from the parent process - $ route -T 2 exec sh - $ ssh 10.1.2.3 - ok deraadt@ markus@ stevesk@ reyk@ - - dtucker@cvs.openbsd.org 2010/01/10 03:51:17 - [servconf.c] - Add ChrootDirectory to sshd.c test-mode output - - dtucker@cvs.openbsd.org 2010/01/10 07:15:56 - [auth.c] - Output a debug if we can't open an existing keyfile. bz#1694, ok djm@ - -20100109 - - (dtucker) Wrap use of IPPROTO_IPV6 in an ifdef for platforms that don't - have it. - - (dtucker) [defines.h] define PRIu64 for platforms that don't have it. - - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. - - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name - when using utmpx. Patch from Ed Schouten. - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2010/01/09 00:20:26 - [sftp-server.c sftp-server.8] - add a 'read-only' mode to sftp-server(8) that disables open in write mode - and all other fs-modifying protocol methods. bz#430 ok dtucker@ - - djm@cvs.openbsd.org 2010/01/09 00:57:10 - [PROTOCOL] - tweak language - - jmc@cvs.openbsd.org 2010/01/09 03:36:00 - [sftp-server.8] - bad place to forget a comma... - - djm@cvs.openbsd.org 2010/01/09 05:04:24 - [mux.c sshpty.h clientloop.c sshtty.c] - quell tc[gs]etattr warnings when forcing a tty (ssh -tt), since we - usually don't actually have a tty to read/set; bz#1686 ok dtucker@ - - dtucker@cvs.openbsd.org 2010/01/09 05:17:00 - [roaming_client.c] - Remove a PRIu64 format string that snuck in with roaming. ok djm@ - - dtucker@cvs.openbsd.org 2010/01/09 11:13:02 - [sftp.c] - Prevent sftp from derefing a null pointer when given a "-" without a - command. Also, allow whitespace to follow a "-". bz#1691, path from - Colin Watson via Debian. ok djm@ deraadt@ - - dtucker@cvs.openbsd.org 2010/01/09 11:17:56 - [sshd.c] - Afer sshd receives a SIGHUP, ignore subsequent HUPs while sshd re-execs - itself. Prevents two HUPs in quick succession from resulting in sshd - dying. bz#1692, patch from Colin Watson via Ubuntu. - - (dtucker) [defines.h] Remove now-undeeded PRIu64 define. - -20100108 - - (dtucker) OpenBSD CVS Sync - - andreas@cvs.openbsd.org 2009/10/24 11:11:58 - [roaming.h] - Declarations needed for upcoming changes. - ok markus@ - - andreas@cvs.openbsd.org 2009/10/24 11:13:54 - [sshconnect2.c kex.h kex.c] - Let the client detect if the server supports roaming by looking - for the resume@appgate.com kex algorithm. - ok markus@ - - andreas@cvs.openbsd.org 2009/10/24 11:15:29 - [clientloop.c] - client_loop() must detect if the session has been suspended and resumed, - and take appropriate action in that case. - From Martin Forssen, maf at appgate dot com - - andreas@cvs.openbsd.org 2009/10/24 11:19:17 - [ssh2.h] - Define the KEX messages used when resuming a suspended connection. - ok markus@ - - andreas@cvs.openbsd.org 2009/10/24 11:22:37 - [roaming_common.c] - Do the actual suspend/resume in the client. This won't be useful until - the server side supports roaming. - Most code from Martin Forssen, maf at appgate dot com. Some changes by - me and markus@ - ok markus@ - - andreas@cvs.openbsd.org 2009/10/24 11:23:42 - [ssh.c] - Request roaming to be enabled if UseRoaming is true and the server - supports it. - ok markus@ - - reyk@cvs.openbsd.org 2009/10/28 16:38:18 - [ssh_config.5 sshd.c misc.h ssh-keyscan.1 readconf.h sshconnect.c - channels.c channels.h servconf.h servconf.c ssh.1 ssh-keyscan.c scp.1 - sftp.1 sshd_config.5 readconf.c ssh.c misc.c] - Allow to set the rdomain in ssh/sftp/scp/sshd and ssh-keyscan. - ok markus@ - - jmc@cvs.openbsd.org 2009/10/28 21:45:08 - [sshd_config.5 sftp.1] - tweak previous; - - djm@cvs.openbsd.org 2009/11/10 02:56:22 - [ssh_config.5] - explain the constraints on LocalCommand some more so people don't - try to abuse it. - - djm@cvs.openbsd.org 2009/11/10 02:58:56 - [sshd_config.5] - clarify that StrictModes does not apply to ChrootDirectory. Permissions - and ownership are always checked when chrooting. bz#1532 - - dtucker@cvs.openbsd.org 2009/11/10 04:30:45 - [sshconnect2.c channels.c sshconnect.c] - Set close-on-exec on various descriptors so they don't get leaked to - child processes. bz #1643, patch from jchadima at redhat, ok deraadt. - - markus@cvs.openbsd.org 2009/11/11 21:37:03 - [channels.c channels.h] - fix race condition in x11/agent channel allocation: don't read after - the end of the select read/write fdset and make sure a reused FD - is not touched before the pre-handlers are called. - with and ok djm@ - - djm@cvs.openbsd.org 2009/11/17 05:31:44 - [clientloop.c] - fix incorrect exit status when multiplexing and channel ID 0 is recycled - bz#1570 reported by peter.oliver AT eon-is.co.uk; ok dtucker - - djm@cvs.openbsd.org 2009/11/19 23:39:50 - [session.c] - bz#1606: error when an attempt is made to connect to a server - with ForceCommand=internal-sftp with a shell session (i.e. not a - subsystem session). Avoids stuck client when attempting to ssh to such a - service. ok dtucker@ - - dtucker@cvs.openbsd.org 2009/11/20 00:15:41 - [session.c] - Warn but do not fail if stat()ing the subsystem binary fails. This helps - with chrootdirectory+forcecommand=sftp-server and restricted shells. - bz #1599, ok djm. - - djm@cvs.openbsd.org 2009/11/20 00:54:01 - [sftp.c] - bz#1588 change "Connecting to host..." message to "Connected to host." - and delay it until after the sftp protocol connection has been established. - Avoids confusing sequence of messages when the underlying ssh connection - experiences problems. ok dtucker@ - - dtucker@cvs.openbsd.org 2009/11/20 00:59:36 - [sshconnect2.c] - Use the HostKeyAlias when prompting for passwords. bz#1039, ok djm@ - - djm@cvs.openbsd.org 2009/11/20 03:24:07 - [misc.c] - correct off-by-one in percent_expand(): we would fatal() when trying - to expand EXPAND_MAX_KEYS, allowing only EXPAND_MAX_KEYS-1 to actually - work. Note that nothing in OpenSSH actually uses close to this limit at - present. bz#1607 from Jan.Pechanec AT Sun.COM - - halex@cvs.openbsd.org 2009/11/22 13:18:00 - [sftp.c] - make passing of zero-length arguments to ssh safe by - passing "-" "" rather than "-" - ok dtucker@, guenther@, djm@ - - dtucker@cvs.openbsd.org 2009/12/06 23:41:15 - [sshconnect2.c] - zap unused variable and strlen; from Steve McClellan, ok djm - - djm@cvs.openbsd.org 2009/12/06 23:53:45 - [roaming_common.c] - use socklen_t for getsockopt optlen parameter; reported by - Steve.McClellan AT radisys.com, ok dtucker@ - - dtucker@cvs.openbsd.org 2009/12/06 23:53:54 - [sftp.c] - fix potential divide-by-zero in sftp's "df" output when talking to a server - that reports zero files on the filesystem (Unix filesystems always have at - least the root inode). From Steve McClellan at radisys, ok djm@ - - markus@cvs.openbsd.org 2009/12/11 18:16:33 - [key.c] - switch from 35 to the more common value of RSA_F4 == (2**16)+1 == 65537 - for the RSA public exponent; discussed with provos; ok djm@ - - guenther@cvs.openbsd.org 2009/12/20 07:28:36 - [ssh.c sftp.c scp.c] - When passing user-controlled options with arguments to other programs, - pass the option and option argument as separate argv entries and - not smashed into one (e.g., as -l foo and not -lfoo). Also, always - pass a "--" argument to stop option parsing, so that a positional - argument that starts with a '-' isn't treated as an option. This - fixes some error cases as well as the handling of hostnames and - filenames that start with a '-'. - Based on a diff by halex@ - ok halex@ djm@ deraadt@ - - djm@cvs.openbsd.org 2009/12/20 23:20:40 - [PROTOCOL] - fix an incorrect magic number and typo in PROTOCOL; bz#1688 - report and fix from ueno AT unixuser.org - - stevesk@cvs.openbsd.org 2009/12/25 19:40:21 - [readconf.c servconf.c misc.h ssh-keyscan.c misc.c] - validate routing domain is in range 0-RT_TABLEID_MAX. - 'Looks right' deraadt@ - - stevesk@cvs.openbsd.org 2009/12/29 16:38:41 - [sshd_config.5 readconf.c ssh_config.5 scp.1 servconf.c sftp.1 ssh.1] - Rename RDomain config option to RoutingDomain to be more clear and - consistent with other options. - NOTE: if you currently use RDomain in the ssh client or server config, - or ssh/sshd -o, you must update to use RoutingDomain. - ok markus@ djm@ - - jmc@cvs.openbsd.org 2009/12/29 18:03:32 - [sshd_config.5 ssh_config.5] - sort previous; - - dtucker@cvs.openbsd.org 2010/01/04 01:45:30 - [sshconnect2.c] - Don't escape backslashes in the SSH2 banner. bz#1533, patch from - Michal Gorny via Gentoo. - - djm@cvs.openbsd.org 2010/01/04 02:03:57 - [sftp.c] - Implement tab-completion of commands, local and remote filenames for sftp. - Hacked on and off for some time by myself, mouring, Carlos Silva (via 2009 - Google Summer of Code) and polished to a fine sheen by myself again. - It should deal more-or-less correctly with the ikky corner-cases presented - by quoted filenames, but the UI could still be slightly improved. - In particular, it is quite slow for remote completion on large directories. - bz#200; ok markus@ - - djm@cvs.openbsd.org 2010/01/04 02:25:15 - [sftp-server.c] - bz#1566 don't unnecessarily dup() in and out fds for sftp-server; - ok markus@ - - dtucker@cvs.openbsd.org 2010/01/08 21:50:49 - [sftp.c] - Fix two warnings: possibly used unitialized and use a nul byte instead of - NULL pointer. ok djm@ - - (dtucker) [Makefile.in added roaming_client.c roaming_serv.c] Import new - files for roaming and add to Makefile. - - (dtucker) [Makefile.in] .c files do not belong in the OBJ lines. - - (dtucker) [sftp.c] ifdef out the sftp completion bits for platforms that - don't have libedit. - - (dtucker) [configure.ac misc.c readconf.c servconf.c ssh-keyscan.c] Make - RoutingDomain an unsupported option on platforms that don't have it. - - (dtucker) [sftp.c] Expand ifdef for libedit to cover complete_is_remote - too. - - (dtucker) [misc.c] Move the routingdomain ifdef to allow the socket to - be created. - - (dtucker] [misc.c] Shrink the area covered by USE_ROUTINGDOMAIN more - to eliminate an unused variable warning. - - (dtucker) [roaming_serv.c] Include includes.h for u_intXX_t types. - -20091226 - - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 - Gzip all man pages. Patch from Corinna Vinschen. - -20091221 - - (dtucker) [auth-krb5.c platform.{c,h} openbsd-compat/port-aix.{c,h}] - Bug #1583: Use system's kerberos principal name on AIX if it's available. - Based on a patch from and tested by Miguel Sanders - -20091208 - - (dtucker) Bug #1470: Disable OOM-killing of the listening sshd on Linux, - based on a patch from Vaclav Ovsik and Colin Watson. ok djm. - -20091207 - - (dtucker) Bug #1160: use pkg-config for opensc config if it's available. - Tested by Martin Paljak. - - (dtucker) Bug #1677: add conditionals around the source for ssh-askpass. - -20091121 - - (tim) [opensshd.init.in] If PidFile is set in sshd_config, use it. - Bug 1628. OK dtucker@ - -20091120 - - (djm) [ssh-rand-helper.c] Print error and usage() when passed command- - line arguments as none are supported. Exit when passed unrecognised - commandline flags. bz#1568 from gson AT araneus.fi - -20091118 - - (djm) [channels.c misc.c misc.h sshd.c] add missing setsockopt() to - set IPV6_V6ONLY for local forwarding with GatwayPorts=yes. Unify - setting IPV6_V6ONLY behind a new function misc.c:sock_set_v6only() - bz#1648, report and fix from jan.kratochvil AT redhat.com - - (djm) [contrib/gnome-ssh-askpass2.c] Make askpass dialog desktop-modal. - bz#1645, patch from jchadima AT redhat.com - -20091107 - - (dtucker) [authfile.c] Fall back to 3DES for the encryption of private - keys when built with OpenSSL versions that don't do AES. - -20091105 - - (dtucker) [authfile.c] Add OpenSSL compat header so this still builds with - older versions of OpenSSL. - -20091024 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2009/10/11 23:03:15 - [hostfile.c] - mention the host name that we are looking for in check_host_in_hostfile() - - sobrado@cvs.openbsd.org 2009/10/17 12:10:39 - [sftp-server.c] - sort flags. - - sobrado@cvs.openbsd.org 2009/10/22 12:35:53 - [ssh.1 ssh-agent.1 ssh-add.1] - use the UNIX-related macros (.At and .Ux) where appropriate. - ok jmc@ - - sobrado@cvs.openbsd.org 2009/10/22 15:02:12 - [ssh-agent.1 ssh-add.1 ssh.1] - write UNIX-domain in a more consistent way; while here, replace a - few remaining ".Tn UNIX" macros with ".Ux" ones. - pointed out by ratchov@, thanks! - ok jmc@ - - djm@cvs.openbsd.org 2009/10/22 22:26:13 - [authfile.c] - switch from 3DES to AES-128 for encryption of passphrase-protected - SSH protocol 2 private keys; ok several - - djm@cvs.openbsd.org 2009/10/23 01:57:11 - [sshconnect2.c] - disallow a hostile server from checking jpake auth by sending an - out-of-sequence success message. (doesn't affect code enabled by default) - - dtucker@cvs.openbsd.org 2009/10/24 00:48:34 - [ssh-keygen.1] - ssh-keygen now uses AES-128 for private keys - - (dtucker) [mdoc2man.awk] Teach it to understand the .Ux macro. - - (dtucker) [session.c openbsd-compat/port-linux.{c,h}] Bug #1637: if selinux - is enabled set the security context to "sftpd_t" before running the - internal sftp server Based on a patch from jchadima at redhat. - -20091011 - - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for - dirent d_type and DTTOIF as we've switched OpenBSD to the more portable - lstat. - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2009/10/08 14:03:41 - [sshd_config readconf.c ssh_config.5 servconf.c sshd_config.5] - disable protocol 1 by default (after a transition period of about 10 years) - ok deraadt - - jmc@cvs.openbsd.org 2009/10/08 20:42:12 - [sshd_config.5 ssh_config.5 sshd.8 ssh.1] - some tweaks now that protocol 1 is not offered by default; ok markus - - dtucker@cvs.openbsd.org 2009/10/11 10:41:26 - [sftp-client.c] - d_type isn't portable so use lstat to get dirent modes. Suggested by and - "looks sane" deraadt@ - - markus@cvs.openbsd.org 2009/10/08 18:04:27 - [regress/test-exec.sh] - re-enable protocol v1 for the tests. - -20091007 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2009/08/12 00:13:00 - [sftp.c sftp.1] - support most of scp(1)'s commandline arguments in sftp(1), as a first - step towards making sftp(1) a drop-in replacement for scp(1). - One conflicting option (-P) has not been changed, pending further - discussion. - Patch from carlosvsilvapt@gmail.com as part of his work in the - Google Summer of Code - - jmc@cvs.openbsd.org 2009/08/12 06:31:42 - [sftp.1] - sort options; - - djm@cvs.openbsd.org 2009/08/13 01:11:19 - [sftp.1 sftp.c] - Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", - add "-P port" to match scp(1). Fortunately, the -P option is only really - used by our regression scripts. - part of larger patch from carlosvsilvapt@gmail.com for his Google Summer - of Code work; ok deraadt markus - - jmc@cvs.openbsd.org 2009/08/13 13:39:54 - [sftp.1 sftp.c] - sync synopsis and usage(); - - djm@cvs.openbsd.org 2009/08/14 18:17:49 - [sftp-client.c] - make the "get_handle: ..." error messages vaguely useful by allowing - callers to specify their own error message strings. - - fgsch@cvs.openbsd.org 2009/08/15 18:56:34 - [auth.h] - remove unused define. markus@ ok. - (Id sync only, Portable still uses this.) - - dtucker@cvs.openbsd.org 2009/08/16 23:29:26 - [sshd_config.5] - Add PubkeyAuthentication to the list allowed in a Match block (bz #1577) - - djm@cvs.openbsd.org 2009/08/18 18:36:21 - [sftp-client.h sftp.1 sftp-client.c sftp.c] - recursive transfer support for get/put and on the commandline - work mostly by carlosvsilvapt@gmail.com for the Google Summer of Code - with some tweaks by me; "go for it" deraadt@ - - djm@cvs.openbsd.org 2009/08/18 21:15:59 - [sftp.1] - fix "get" command usage, spotted by jmc@ - - jmc@cvs.openbsd.org 2009/08/19 04:56:03 - [sftp.1] - ether -> either; - - dtucker@cvs.openbsd.org 2009/08/20 23:54:28 - [mux.c] - subsystem_flag is defined in ssh.c so it's extern; ok djm - - djm@cvs.openbsd.org 2009/08/27 17:28:52 - [sftp-server.c] - allow setting an explicit umask on the commandline to override whatever - default the user has. bz#1229; ok dtucker@ deraadt@ markus@ - - djm@cvs.openbsd.org 2009/08/27 17:33:49 - [ssh-keygen.c] - force use of correct hash function for random-art signature display - as it was inheriting the wrong one when bubblebabble signatures were - activated; bz#1611 report and patch from fwojcik+openssh AT besh.com; - ok markus@ - - djm@cvs.openbsd.org 2009/08/27 17:43:00 - [sftp-server.8] - allow setting an explicit umask on the commandline to override whatever - default the user has. bz#1229; ok dtucker@ deraadt@ markus@ - - djm@cvs.openbsd.org 2009/08/27 17:44:52 - [authfd.c ssh-add.c authfd.h] - Do not fall back to adding keys without contraints (ssh-add -c / -t ...) - when the agent refuses the constrained add request. This was a useful - migration measure back in 2002 when constraints were new, but just - adds risk now. - bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@ - - djm@cvs.openbsd.org 2009/08/31 20:56:02 - [sftp-server.c] - check correct variable for error message, spotted by martynas@ - - djm@cvs.openbsd.org 2009/08/31 21:01:29 - [sftp-server.8] - document -e and -h; prodded by jmc@ - - djm@cvs.openbsd.org 2009/09/01 14:43:17 - [ssh-agent.c] - fix a race condition in ssh-agent that could result in a wedged or - spinning agent: don't read off the end of the allocated fd_sets, and - don't issue blocking read/write on agent sockets - just fall back to - select() on retriable read/write errors. bz#1633 reported and tested - by "noodle10000 AT googlemail.com"; ok dtucker@ markus@ - - grunk@cvs.openbsd.org 2009/10/01 11:37:33 - [dh.c] - fix a cast - ok djm@ markus@ - - djm@cvs.openbsd.org 2009/10/06 04:46:40 - [session.c] - bz#1596: fflush(NULL) before exec() to ensure that everying (motd - in particular) has made it out before the streams go away. - - djm@cvs.openbsd.org 2008/12/07 22:17:48 - [regress/addrmatch.sh] - match string "passwordauthentication" only at start of line, not anywhere - in sshd -T output - - dtucker@cvs.openbsd.org 2009/05/05 07:51:36 - [regress/multiplex.sh] - Always specify ssh_config for multiplex tests: prevents breakage caused - by options in ~/.ssh/config. From Dan Peterson. - - djm@cvs.openbsd.org 2009/08/13 00:57:17 - [regress/Makefile] - regression test for port number parsing. written as part of the a2port - change that went into 5.2 but I forgot to commit it at the time... - - djm@cvs.openbsd.org 2009/08/13 01:11:55 - [regress/sftp-batch.sh regress/sftp-badcmds.sh regress/sftp.sh - regress/sftp-cmds.sh regres/sftp-glob.sh] - date: 2009/08/13 01:11:19; author: djm; state: Exp; lines: +10 -7 - Swizzle options: "-P sftp_server_path" moves to "-D sftp_server_path", - add "-P port" to match scp(1). Fortunately, the -P option is only really - used by our regression scripts. - part of larger patch from carlosvsilvapt@gmail.com for his Google Summer - of Code work; ok deraadt markus - - djm@cvs.openbsd.org 2009/08/20 18:43:07 - [regress/ssh-com-sftp.sh] - fix one sftp -D ... => sftp -P ... conversion that I missed; from Carlos - Silva for Google Summer of Code - - dtucker@cvs.openbsd.org 2009/10/06 23:51:49 - [regress/ssh2putty.sh] - Add OpenBSD tag to make syncs easier - - (dtucker) [regress/portnum.sh] Import new test. - - (dtucker) [configure.ac sftp-client.c] DTOTIF is in fs/ffs/dir.h on at - least dragonflybsd. - - (dtucker) d_type is not mandated by POSIX, so add fallback code using - stat(), needed on at least cygwin. - -20091002 - - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. - spotted by des AT des.no - -20090926 - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update for release - - (djm) [README] update relnotes URL - - (djm) [packet.c] Restore EWOULDBLOCK handling that got lost somewhere - - (djm) Release 5.3p1 - -20090911 - - (dtucker) [configure.ac] Change the -lresolv check so it works on Mac OS X - 10.6 (which doesn't have BIND8_COMPAT and thus uses res_9_query). Patch - from jbasney at ncsa uiuc edu. - -20090908 - - (djm) [serverloop.c] Fix test for server-assigned remote forwarding port - (-R 0:...); bz#1578, spotted and fix by gavin AT emf.net; ok dtucker@ - -20090901 - - (dtucker) [configure.ac] Bug #1639: use AC_PATH_PROG to search the path for - krb5-config if it's not in the location specified by --with-kerberos5. - Patch from jchadima at redhat. - -20090829 - - (dtucker) [README.platform] Add text about development packages, based on - text from Chris Pepper in bug #1631. - -20090828 - - dtucker [auth-sia.c] Roll back the change for bug #1241 as it apparently - causes problems in some Tru64 configurations. - - (djm) [sshd_config.5] downgrade mention of login.conf to be an example - and mention PAM as another provider for ChallengeResponseAuthentication; - bz#1408; ok dtucker@ - - (djm) [sftp-server.c] bz#1535: accept ENOSYS as a fallback error when - attempting atomic rename(); ok dtucker@ - - (djm) [Makefile.in] bz#1505: Solaris make(1) doesn't accept make variables - in argv, so pass them in the environment; ok dtucker@ - - (dtucker) [channels.c configure.ac] Bug #1528: skip the tcgetattr call on - the pty master on Solaris, since it never succeeds and can hang if large - amounts of data is sent to the slave (eg a copy-paste). Based on a patch - originally from Doke Scott, ok djm@ - - (dtucker) [clientloop.c configure.ac defines.h] Make the client's IO buffer - size a compile-time option and set it to 64k on Cygwin, since Corinna - reports that it makes a significant difference to performance. ok djm@ - - (dtucker) [configure.ac] Fix the syntax of the Solaris tcgetattr entry. - -20090820 - - (dtucker) [includes.h] Bug #1634: do not include system glob.h if we're not - using it since the type conflicts can cause problems on FreeBSD. Patch - from Jonathan Chen. - - (dtucker) [session.c openbsd-compat/port-aix.h] Bugs #1249 and #1567: move - the setpcred call on AIX to immediately before the permanently_set_uid(). - Ensures that we still have privileges when we call chroot and - pam_open_sesson. Based on a patch from David Leonard. - -20090817 - - (dtucker) [configure.ac] Check for headers before libraries for openssl an - zlib, which should make the errors slightly more meaningful on platforms - where there's separate "-devel" packages for those. - - (dtucker) [sshlogin.c openbsd-compat/port-aix.{c,h}] Bug #1595: make - PrintLastLog work on AIX. Based in part on a patch from Miguel Sanders. - -20090729 - - (tim) [contrib/cygwin/ssh-user-config] Change script to call correct error - function. Patch from Corinna Vinschen. - -20090713 - - (dtucker) [openbsd-compat/getrrsetbyname.c] Reduce answer buffer size so it - fits into 16 bits to work around a bug in glibc's resolver where it masks - off the buffer size at 16 bits. Patch from Hauke Lampe, ok djm jakob. - -20090712 - - (dtucker) [configure.ac] Include sys/param.h for the sys/mount.h test, - prevents configure complaining on older BSDs. - - (dtucker [contrib/cygwin/ssh-{host,user}-config] Add license text. Patch - from Corinna Vinschen. - - (dtucker) [auth-pam.c] Bug #1534: move the deletion of PAM credentials on - logout to after the session close. Patch from Anicka Bernathova, - originally from Andreas Schwab via Novelll ok djm. - -20090707 - - (dtucker) [contrib/cygwin/ssh-host-config] better support for automated - scripts and fix usage of eval. Patch from Corinna Vinschen. - -20090705 - - (dtucker) OpenBSD CVS Sync - - andreas@cvs.openbsd.org 2009/06/27 09:29:06 - [packet.h packet.c] - packet_bacup_state() and packet_restore_state() will be used to - temporarily save the current state ren resuming a suspended connection. - ok markus@ - - andreas@cvs.openbsd.org 2009/06/27 09:32:43 - [roaming_common.c roaming.h] - It may be necessary to retransmit some data when resuming, so add it - to a buffer when roaming is enabled. - Most of this code was written by Martin Forssen, maf at appgate dot com. - ok markus@ - - andreas@cvs.openbsd.org 2009/06/27 09:35:06 - [readconf.h readconf.c] - Add client option UseRoaming. It doesn't do anything yet but will - control whether the client tries to use roaming if enabled on the - server. From Martin Forssen. - ok markus@ - - markus@cvs.openbsd.org 2009/06/30 14:54:40 - [version.h] - crank version; ok deraadt - - dtucker@cvs.openbsd.org 2009/07/02 02:11:47 - [ssh.c] - allow for long home dir paths (bz #1615). ok deraadt - (based in part on a patch from jchadima at redhat) - - stevesk@cvs.openbsd.org 2009/07/05 19:28:33 - [clientloop.c] - only send SSH2_MSG_DISCONNECT if we're in compat20; from dtucker@ - ok deraadt@ markus@ - -20090622 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2009/06/22 05:39:28 - [monitor_wrap.c monitor_mm.c ssh-keygen.c auth2.c gss-genr.c sftp-client.c] - alphabetize includes; reduces diff vs portable and style(9). - ok stevesk djm - (Id sync only; these were already in order in -portable) - -20090621 - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2009/03/17 21:37:00 - [ssh.c] - pass correct argv[0] to openlog(); ok djm@ - - jmc@cvs.openbsd.org 2009/03/19 15:15:09 - [ssh.1] - for "Ciphers", just point the reader to the keyword in ssh_config(5), just - as we do for "MACs": this stops us getting out of sync when the lists - change; - fixes documentation/6102, submitted by Peter J. Philipp - alternative fix proposed by djm - ok markus - - tobias@cvs.openbsd.org 2009/03/23 08:31:19 - [ssh-agent.c] - Fixed a possible out-of-bounds memory access if the environment variable - SHELL is shorter than 3 characters. - with input by and ok dtucker - - tobias@cvs.openbsd.org 2009/03/23 19:38:04 - [ssh-agent.c] - My previous commit didn't fix the problem at all, so stick at my first - version of the fix presented to dtucker. - Issue notified by Matthias Barkhoff (matthias dot barkhoff at gmx dot de). - ok dtucker - - sobrado@cvs.openbsd.org 2009/03/26 08:38:39 - [sftp-server.8 sshd.8 ssh-agent.1] - fix a few typographical errors found by spell(1). - ok dtucker@, jmc@ - - stevesk@cvs.openbsd.org 2009/04/13 19:07:44 - [sshd_config.5] - fix possessive; ok djm@ - - stevesk@cvs.openbsd.org 2009/04/14 16:33:42 - [sftp-server.c] - remove unused option character from getopt() optstring; ok markus@ - - jj@cvs.openbsd.org 2009/04/14 21:10:54 - [servconf.c] - Fixed a few the-the misspellings in comments. Skipped a bunch in - binutils,gcc and so on. ok jmc@ - - stevesk@cvs.openbsd.org 2009/04/17 19:23:06 - [session.c] - use INTERNAL_SFTP_NAME for setproctitle() of in-process sftp-server; - ok djm@ markus@ - - stevesk@cvs.openbsd.org 2009/04/17 19:40:17 - [sshd_config.5] - clarify that even internal-sftp needs /dev/log for logging to work; ok - markus@ - - jmc@cvs.openbsd.org 2009/04/18 18:39:10 - [sshd_config.5] - tweak previous; ok stevesk - - stevesk@cvs.openbsd.org 2009/04/21 15:13:17 - [sshd_config.5] - clarify we cd to user's home after chroot; ok markus@ on - earlier version; tweaks and ok jmc@ - - andreas@cvs.openbsd.org 2009/05/25 06:48:01 - [channels.c packet.c clientloop.c packet.h serverloop.c monitor_wrap.c - monitor.c] - Put the globals in packet.c into a struct and don't access it directly - from other files. No functional changes. - ok markus@ djm@ - - andreas@cvs.openbsd.org 2009/05/27 06:31:25 - [canohost.h canohost.c] - Add clear_cached_addr(), needed for upcoming changes allowing the peer - address to change. - ok markus@ - - andreas@cvs.openbsd.org 2009/05/27 06:33:39 - [clientloop.c] - Send SSH2_MSG_DISCONNECT when the client disconnects. From a larger - change from Martin Forssen, maf at appgate dot com. - ok markus@ - - andreas@cvs.openbsd.org 2009/05/27 06:34:36 - [kex.c kex.h] - Move the KEX_COOKIE_LEN define to kex.h - ok markus@ - - andreas@cvs.openbsd.org 2009/05/27 06:36:07 - [packet.h packet.c] - Add packet_put_int64() and packet_get_int64(), part of a larger change - from Martin Forssen. - ok markus@ - - andreas@cvs.openbsd.org 2009/05/27 06:38:16 - [sshconnect.h sshconnect.c] - Un-static ssh_exchange_identification(), part of a larger change from - Martin Forssen and needed for upcoming changes. - ok markus@ - - andreas@cvs.openbsd.org 2009/05/28 16:50:16 - [sshd.c packet.c serverloop.c monitor_wrap.c clientloop.c sshconnect.c - monitor.c Added roaming.h roaming_common.c roaming_dummy.c] - Keep track of number of bytes read and written. Needed for upcoming - changes. Most code from Martin Forssen, maf at appgate dot com. - ok markus@ - Also, applied appropriate changes to Makefile.in - - andreas@cvs.openbsd.org 2009/06/12 20:43:22 - [monitor.c packet.c] - Fix warnings found by chl@ and djm@ and change roaming_atomicio's - return type to match atomicio's - Diff from djm@, ok markus@ - - andreas@cvs.openbsd.org 2009/06/12 20:58:32 - [packet.c] - Move some more statics into session_state - ok markus@ djm@ - - dtucker@cvs.openbsd.org 2009/06/21 07:37:15 - [kexdhs.c kexgexs.c] - abort if key_sign fails, preventing possible null deref. Based on report - from Paolo Ganci, ok markus@ djm@ - - dtucker@cvs.openbsd.org 2009/06/21 09:04:03 - [roaming.h roaming_common.c roaming_dummy.c] - Add tags for the benefit of the sync scripts - Also: pull in the changes for 1.1->1.2 missed in the previous sync. - - (dtucker) [auth2-jpake.c auth2.c canohost.h session.c] Whitespace and - header-order changes to reduce diff vs OpenBSD. - - (dtucker) [servconf.c sshd.c] More whitespace sync. - - (dtucker) [roaming_common.c roaming_dummy.c] Wrap #include in - ifdef. - -20090616 - - (dtucker) [configure.ac defines.h] Bug #1607: handle the case where fsid_t - is a struct with a __val member. Fixes build on, eg, Redhat 6.2. - -20090504 - - (dtucker) [sshlogin.c] Move the NO_SSH_LASTLOG #ifndef line to include - variable declarations. Should prevent unused warnings anywhere it's set - (only Crays as far as I can tell) and be a no-op everywhere else. - -20090318 - - (tim) [configure.ac] Remove setting IP_TOS_IS_BROKEN for Cygwin. The problem - that setsockopt(IP_TOS) doesn't work on Cygwin has been fixed since 2005. - Based on patch from vinschen at redhat com. - -20090308 - - (dtucker) [auth-passwd.c auth1.c auth2-kbdint.c auth2-none.c auth2-passwd.c - auth2-pubkey.c session.c openbsd-compat/bsd-cygwin_util.{c,h} - openbsd-compat/daemon.c] Remove support for Windows 95/98/ME and very old - version of Cygwin. Patch from vinschen at redhat com. - -20090307 - - (dtucker) [contrib/aix/buildbff.sh] Only try to rename ssh_prng_cmds if it - exists (it's not created if OpenSSL's PRNG is self-seeded, eg if the OS - has a /dev/random). - - (dtucker) [schnorr.c openbsd-compat/openssl-compat.{c,h}] Add - EVP_DigestUpdate to the OLD_EVP compatibility functions and tell schnorr.c - to use them. Allows building with older OpenSSL versions. - - (dtucker) [configure.ac defines.h] Check for in_port_t and typedef if needed. - - (dtucker) [configure.ac] Missing comma in type list. - - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] - EVP_DigestUpdate does not exactly match the other OLD_EVP functions (eg - in openssl 0.9.6) so add an explicit test for it. - -20090306 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2009/03/05 07:18:19 - [auth2-jpake.c jpake.c jpake.h monitor_wrap.c monitor_wrap.h schnorr.c] - [sshconnect2.c] - refactor the (disabled) Schnorr proof code to make it a little more - generally useful - - djm@cvs.openbsd.org 2009/03/05 11:30:50 - [uuencode.c] - document what these functions do so I don't ever have to recuse into - b64_pton/ntop to remember their return values - -20090223 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2009/02/22 23:50:57 - [ssh_config.5 sshd_config.5] - don't advertise experimental options - - djm@cvs.openbsd.org 2009/02/22 23:59:25 - [sshd_config.5] - missing period - - djm@cvs.openbsd.org 2009/02/23 00:06:15 - [version.h] - openssh-5.2 - - (djm) [README] update for 5.2 - - (djm) Release openssh-5.2p1 - -20090222 - - (djm) OpenBSD CVS Sync - - tobias@cvs.openbsd.org 2009/02/21 19:32:04 - [misc.c sftp-server-main.c ssh-keygen.c] - Added missing newlines in error messages. - ok dtucker - -20090221 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2009/02/17 01:28:32 - [ssh_config] - sync with revised default ciphers; pointed out by dkrause@ - - djm@cvs.openbsd.org 2009/02/18 04:31:21 - [schnorr.c] - signature should hash over the entire group, not just the generator - (this is still disabled code) - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Prepare for 5.2p1 - -20090216 - - (djm) [regress/conch-ciphers.sh regress/putty-ciphers.sh] - [regress/putty-kex.sh regress/putty-transfer.sh] Downgrade disabled - interop tests from FATAL error to a warning. Allows some interop - tests to proceed if others are missing necessary prerequisites. - - (djm) [configure.ac] support GNU/kFreeBSD and GNU/kOpensolaris - systems; patch from Aurelien Jarno via rmh AT aybabtu.com - -20090214 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2009/02/02 11:15:14 - [sftp.c] - Initialize a few variables to prevent spurious "may be used - uninitialized" warnings from newer gcc's. ok djm@ - - djm@cvs.openbsd.org 2009/02/12 03:00:56 - [canohost.c canohost.h channels.c channels.h clientloop.c readconf.c] - [readconf.h serverloop.c ssh.c] - support remote port forwarding with a zero listen port (-R0:...) to - dyamically allocate a listen port at runtime (this is actually - specified in rfc4254); bz#1003 ok markus@ - - djm@cvs.openbsd.org 2009/02/12 03:16:01 - [serverloop.c] - tighten check for -R0:... forwarding: only allow dynamic allocation - if want_reply is set in the packet - - djm@cvs.openbsd.org 2009/02/12 03:26:22 - [monitor.c] - some paranoia: check that the serialised key is really KEY_RSA before - diddling its internals - - djm@cvs.openbsd.org 2009/02/12 03:42:09 - [ssh.1] - document -R0:... usage - - djm@cvs.openbsd.org 2009/02/12 03:44:25 - [ssh.1] - consistency: Dq => Ql - - djm@cvs.openbsd.org 2009/02/12 03:46:17 - [ssh_config.5] - document RemoteForward usage with 0 listen port - - jmc@cvs.openbsd.org 2009/02/12 07:34:20 - [ssh_config.5] - kill trailing whitespace; - - markus@cvs.openbsd.org 2009/02/13 11:50:21 - [packet.c] - check for enc !=NULL in packet_start_discard - - djm@cvs.openbsd.org 2009/02/14 06:35:49 - [PROTOCOL] - mention that eow and no-more-sessions extensions are sent only to - OpenSSH peers - -20090212 - - (djm) [sshpty.c] bz#1419: OSX uses cloning ptys that automagically - set ownership and modes, so avoid explicitly setting them - - (djm) [configure.ac loginrec.c] bz#1421: fix lastlog support for OSX. - OSX provides a getlastlogxbyname function that automates the reading of - a lastlog file. Also, the pututxline function will update lastlog so - there is no need for loginrec.c to do it explicitly. Collapse some - overly verbose code while I'm in there. - -20090201 - - (dtucker) [defines.h sshconnect.c] INET6_ADDRSTRLEN is now needed in - channels.c too, so move the definition for non-IP6 platforms to defines.h - where it can be shared. - -20090129 - - (tim) [contrib/cygwin/ssh-host-config] Patch from Corinna Vinschen. - If the CYGWIN environment variable is empty, the installer script - should not install the service with an empty CYGWIN variable, but - rather without setting CYGWNI entirely. - - (tim) [contrib/cygwin/ssh-host-config] Whitespace cleanup. No code changes. - -20090128 - - (tim) [contrib/cygwin/ssh-host-config] Patch from Corinna Vinschen. - Changes to work on Cygwin 1.5.x as well as on the new Cygwin 1.7.x. - The information given for the setting of the CYGWIN environment variable - is wrong for both releases so I just removed it, together with the - unnecessary (Cygwin 1.5.x) or wrong (Cygwin 1.7.x) default setting. - -20081228 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2008/12/09 03:20:42 - [channels.c servconf.c] - channel_print_adm_permitted_opens() should deal with all the printing - for that config option. suggested by markus@; ok markus@ djm@ - dtucker@ - - djm@cvs.openbsd.org 2008/12/09 04:32:22 - [auth2-chall.c] - replace by-hand string building with xasprinf(); ok deraadt@ - - sobrado@cvs.openbsd.org 2008/12/09 15:35:00 - [sftp.1 sftp.c] - update for the synopses displayed by the 'help' command, there are a - few missing flags; add 'bye' to the output of 'help'; sorting and spacing. - jmc@ suggested replacing .Oo/.Oc with a single .Op macro. - ok jmc@ - - stevesk@cvs.openbsd.org 2008/12/09 22:37:33 - [clientloop.c] - fix typo in error message - - stevesk@cvs.openbsd.org 2008/12/10 03:55:20 - [addrmatch.c] - o cannot be NULL here but use xfree() to be consistent; ok djm@ - - stevesk@cvs.openbsd.org 2008/12/29 01:12:36 - [ssh-keyscan.1] - fix example, default key type is rsa for 3+ years; from - frederic.perrin@resel.fr - - stevesk@cvs.openbsd.org 2008/12/29 02:23:26 - [pathnames.h] - no need to escape single quotes in comments - - okan@cvs.openbsd.org 2008/12/30 00:46:56 - [sshd_config.5] - add AllowAgentForwarding to available Match keywords list - ok djm - - djm@cvs.openbsd.org 2009/01/01 21:14:35 - [channels.c] - call channel destroy callbacks on receipt of open failure messages. - fixes client hangs when connecting to a server that has MaxSessions=0 - set spotted by imorgan AT nas.nasa.gov; ok markus@ - - djm@cvs.openbsd.org 2009/01/01 21:17:36 - [kexgexs.c] - fix hash calculation for KEXGEX: hash over the original client-supplied - values and not the sanity checked versions that we acutally use; - bz#1540 reported by john.smith AT arrows.demon.co.uk - ok markus@ - - djm@cvs.openbsd.org 2009/01/14 01:38:06 - [channels.c] - support SOCKS4A protocol, from dwmw2 AT infradead.org via bz#1482; - "looks ok" markus@ - - stevesk@cvs.openbsd.org 2009/01/15 17:38:43 - [readconf.c] - 1) use obsolete instead of alias for consistency - 2) oUserKnownHostsFile not obsolete but oGlobalKnownHostsFile2 is - so move the comment. - 3) reorder so like options are together - ok djm@ - - djm@cvs.openbsd.org 2009/01/22 09:46:01 - [channels.c channels.h session.c] - make Channel->path an allocated string, saving a few bytes here and - there and fixing bz#1380 in the process; ok markus@ - - djm@cvs.openbsd.org 2009/01/22 09:49:57 - [channels.c] - oops! I committed the wrong version of the Channel->path diff, - it was missing some tweaks suggested by stevesk@ - - djm@cvs.openbsd.org 2009/01/22 10:02:34 - [clientloop.c misc.c readconf.c readconf.h servconf.c servconf.h] - [serverloop.c ssh-keyscan.c ssh.c sshd.c] - make a2port() return -1 when it encounters an invalid port number - rather than 0, which it will now treat as valid (needed for future work) - adjust current consumers of a2port() to check its return value is <= 0, - which in turn required some things to be converted from u_short => int - make use of int vs. u_short consistent in some other places too - feedback & ok markus@ - - djm@cvs.openbsd.org 2009/01/22 10:09:16 - [auth-options.c] - another chunk of a2port() diff that got away. wtfdjm?? - - djm@cvs.openbsd.org 2009/01/23 07:58:11 - [myproposal.h] - prefer CTR modes and revised arcfour (i.e w/ discard) modes to CBC - modes; ok markus@ - - naddy@cvs.openbsd.org 2009/01/24 17:10:22 - [ssh_config.5 sshd_config.5] - sync list of preferred ciphers; ok djm@ - - markus@cvs.openbsd.org 2009/01/26 09:58:15 - [cipher.c cipher.h packet.c] - Work around the CPNI-957037 Plaintext Recovery Attack by always - reading 256K of data on packet size or HMAC errors (in CBC mode only). - Help, feedback and ok djm@ - Feedback from Martin Albrecht and Paterson Kenny - -20090107 - - (djm) [uidswap.c] bz#1412: Support >16 supplemental groups in OS X. - Patch based on one from vgiffin AT apple.com; ok dtucker@ - - (djm) [channels.c] bz#1419: support "on demand" X11 forwarding via - launchd on OS X; patch from vgiffin AT apple.com, slightly tweaked; - ok dtucker@ - - (djm) [contrib/ssh-copy-id.1 contrib/ssh-copy-id] bz#1492: Make - ssh-copy-id copy id_rsa.pub by default (instead of the legacy "identity" - key). Patch from cjwatson AT debian.org - -20090107 - - (tim) [configure.ac defines.h openbsd-compat/port-uw.c - openbsd-compat/xcrypt.c] Add SECUREWARE support to OpenServer 6 SVR5 ABI. - OK djm@ dtucker@ - - (tim) [configure.ac] Move check_for_libcrypt_later=1 in *-*-sysv5*) section. - OpenServer 6 doesn't need libcrypt. - -20081209 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/12/09 02:38:18 - [clientloop.c] - The ~C escape handler does not work correctly for multiplexed sessions - - it opens a commandline on the master session, instead of on the slave - that requested it. Disable it on slave sessions until such time as it - is fixed; bz#1543 report from Adrian Bridgett via Colin Watson - ok markus@ - - djm@cvs.openbsd.org 2008/12/09 02:39:59 - [sftp.c] - Deal correctly with failures in remote stat() operation in sftp, - correcting fail-on-error behaviour in batchmode. bz#1541 report and - fix from anedvedicky AT gmail.com; ok markus@ - - djm@cvs.openbsd.org 2008/12/09 02:58:16 - [readconf.c] - don't leave junk (free'd) pointers around in Forward *fwd argument on - failure; avoids double-free in ~C -L handler when given an invalid - forwarding specification; bz#1539 report from adejong AT debian.org - via Colin Watson; ok markus@ dtucker@ - - djm@cvs.openbsd.org 2008/12/09 03:02:37 - [sftp.1 sftp.c] - correct sftp(1) and corresponding usage syntax; - bz#1518 patch from imorgan AT nas.nasa.gov; ok deraadt@ improved diff jmc@ - -20081208 - - (djm) [configure.ac] bz#1538: better test for ProPolice/SSP: actually - use some stack in main(). - Report and suggested fix from vapier AT gentoo.org - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2008/12/02 19:01:07 - [clientloop.c] - we have to use the recipient's channel number (RFC 4254) for - SSH2_MSG_CHANNEL_SUCCESS/SSH2_MSG_CHANNEL_FAILURE messages, - otherwise we trigger 'Non-public channel' error messages on sshd - systems with clientkeepalive enabled; noticed by sturm; ok djm; - - markus@cvs.openbsd.org 2008/12/02 19:08:59 - [serverloop.c] - backout 1.149, since it's not necessary and openssh clients send - broken CHANNEL_FAILURE/SUCCESS messages since about 2004; ok djm@ - - markus@cvs.openbsd.org 2008/12/02 19:09:38 - [channels.c] - s/remote_id/id/ to be more consistent with other code; ok djm@ - -20081201 - - (dtucker) [contrib/cygwin/{Makefile,ssh-host-config}] Add new doc files - and tweak the is-sshd-running check in ssh-host-config. Patch from - vinschen at redhat com. - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2008/11/21 15:47:38 - [packet.c] - packet_disconnect() on padding error, too. should reduce the success - probability for the CPNI-957037 Plaintext Recovery Attack to 2^-18 - ok djm@ - - dtucker@cvs.openbsd.org 2008/11/30 11:59:26 - [monitor_fdpass.c] - Retry sendmsg/recvmsg on EAGAIN and EINTR; ok djm@ - -20081123 - - (dtucker) [monitor_fdpass.c] Reduce diff vs OpenBSD by moving some - declarations, removing an unnecessary union member and adding whitespace. - cmsgbuf.tmp thing spotted by des at des no, ok djm some time ago. - -20081118 - - (tim) [addrmatch.c configure.ac] Some platforms do not have sin6_scope_id - member of sockaddr_in6. Also reported in Bug 1491 by David Leonard. OK and - feedback by djm@ - -20081111 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2008/11/05 11:22:54 - [servconf.c] - passord -> password; - fixes user/5975 from Rene Maroufi - - stevesk@cvs.openbsd.org 2008/11/07 00:42:12 - [ssh-keygen.c] - spelling/typo in comment - - stevesk@cvs.openbsd.org 2008/11/07 18:50:18 - [nchan.c] - add space to some log/debug messages for readability; ok djm@ markus@ - - dtucker@cvs.openbsd.org 2008/11/07 23:34:48 - [auth2-jpake.c] - Move JPAKE define to make life easier for portable. ok djm@ - - tobias@cvs.openbsd.org 2008/11/09 12:34:47 - [session.c ssh.1] - typo fixed (overriden -> overridden) - ok espie, jmc - - stevesk@cvs.openbsd.org 2008/11/11 02:58:09 - [servconf.c] - USE_AFS not referenced so remove #ifdef. fixes sshd -T not printing - kerberosgetafstoken. ok dtucker@ - (Id sync only, we still want the ifdef in portable) - - stevesk@cvs.openbsd.org 2008/11/11 03:55:11 - [channels.c] - for sshd -T print 'permitopen any' vs. 'permitopen' for case of no - permitopen's; ok and input dtucker@ - - djm@cvs.openbsd.org 2008/11/10 02:06:35 - [regress/putty-ciphers.sh] - PuTTY supports AES CTR modes, so interop test against them too - -20081105 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/11/03 08:59:41 - [servconf.c] - include MaxSessions in sshd -T output; patch from imorgan AT nas.nasa.gov - - djm@cvs.openbsd.org 2008/11/04 07:58:09 - [auth.c] - need unistd.h for close() prototype - (ID sync only) - - djm@cvs.openbsd.org 2008/11/04 08:22:13 - [auth.h auth2.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h] - [readconf.c readconf.h servconf.c servconf.h ssh2.h ssh_config.5] - [sshconnect2.c sshd_config.5 jpake.c jpake.h schnorr.c auth2-jpake.c] - [Makefile.in] - Add support for an experimental zero-knowledge password authentication - method using the J-PAKE protocol described in F. Hao, P. Ryan, - "Password Authenticated Key Exchange by Juggling", 16th Workshop on - Security Protocols, Cambridge, April 2008. - - This method allows password-based authentication without exposing - the password to the server. Instead, the client and server exchange - cryptographic proofs to demonstrate of knowledge of the password while - revealing nothing useful to an attacker or compromised endpoint. - - This is experimental, work-in-progress code and is presently - compiled-time disabled (turn on -DJPAKE in Makefile.inc). - - "just commit it. It isn't too intrusive." deraadt@ - - stevesk@cvs.openbsd.org 2008/11/04 19:18:00 - [readconf.c] - because parse_forward() is now used to parse all forward types (DLR), - and it malloc's space for host variables, we don't need to malloc - here. fixes small memory leaks. - - previously dynamic forwards were not parsed in parse_forward() and - space was not malloc'd in that case. - - ok djm@ - - stevesk@cvs.openbsd.org 2008/11/05 03:23:09 - [clientloop.c ssh.1] - add dynamic forward escape command line; ok djm@ - -20081103 - - OpenBSD CVS Sync - - sthen@cvs.openbsd.org 2008/07/24 23:55:30 - [ssh-keygen.1] - Add "ssh-keygen -F -l" to synopsis (displays fingerprint from - known_hosts). ok djm@ - - grunk@cvs.openbsd.org 2008/07/25 06:56:35 - [ssh_config] - Add VisualHostKey to example file, ok djm@ - - grunk@cvs.openbsd.org 2008/07/25 07:05:16 - [key.c] - In random art visualization, make sure to use the end marker only at the - end. Initial diff by Dirk Loss, tweaks and ok djm@ - - markus@cvs.openbsd.org 2008/07/31 14:48:28 - [sshconnect2.c] - don't allocate space for empty banners; report t8m at centrum.cz; - ok deraadt - - krw@cvs.openbsd.org 2008/08/02 04:29:51 - [ssh_config.5] - whitepsace -> whitespace. From Matthew Clarke via bugs@. - - djm@cvs.openbsd.org 2008/08/21 04:09:57 - [session.c] - allow ForceCommand internal-sftp with arguments. based on patch from - michael.barabanov AT gmail.com; ok markus@ - - djm@cvs.openbsd.org 2008/09/06 12:24:13 - [kex.c] - OpenSSL 0.9.8h supplies a real EVP_sha256 so we do not need our - replacement anymore - (ID sync only for portable - we still need this) - - markus@cvs.openbsd.org 2008/09/11 14:22:37 - [compat.c compat.h nchan.c ssh.c] - only send eow and no-more-sessions requests to openssh 5 and newer; - fixes interop problems with broken ssh v2 implementations; ok djm@ - - millert@cvs.openbsd.org 2008/10/02 14:39:35 - [session.c] - Convert an unchecked strdup to xstrdup. OK deraadt@ - - jmc@cvs.openbsd.org 2008/10/03 13:08:12 - [sshd.8] - do not give an example of how to chmod files: we can presume the user - knows that. removes an ambiguity in the permission of authorized_keys; - ok deraadt - - deraadt@cvs.openbsd.org 2008/10/03 23:56:28 - [sshconnect2.c] - Repair strnvis() buffersize of 4*n+1, with termination gauranteed by the - function. - spotted by des@freebsd, who commited an incorrect fix to the freebsd tree - and (as is fairly typical) did not report the problem to us. But this fix - is correct. - ok djm - - djm@cvs.openbsd.org 2008/10/08 23:34:03 - [ssh.1 ssh.c] - Add -y option to force logging via syslog rather than stderr. - Useful for daemonised ssh connection (ssh -f). Patch originally from - and ok'd by markus@ - - djm@cvs.openbsd.org 2008/10/09 03:50:54 - [servconf.c sshd_config.5] - support setting PermitEmptyPasswords in a Match block - requested in PR3891; ok dtucker@ - - jmc@cvs.openbsd.org 2008/10/09 06:54:22 - [ssh.c] - add -y to usage(); - - stevesk@cvs.openbsd.org 2008/10/10 04:55:16 - [scp.c] - spelling in comment; ok djm@ - - stevesk@cvs.openbsd.org 2008/10/10 05:00:12 - [key.c] - typo in error message; ok djm@ - - stevesk@cvs.openbsd.org 2008/10/10 16:43:27 - [ssh_config.5] - use 'Privileged ports can be forwarded only when logging in as root on - the remote machine.' for RemoteForward just like ssh.1 -R. - ok djm@ jmc@ - - stevesk@cvs.openbsd.org 2008/10/14 18:11:33 - [sshconnect.c] - use #define ROQUIET here; no binary change. ok dtucker@ - - stevesk@cvs.openbsd.org 2008/10/17 18:36:24 - [ssh_config.5] - correct and clarify VisualHostKey; ok jmc@ - - stevesk@cvs.openbsd.org 2008/10/30 19:31:16 - [clientloop.c sshd.c] - don't need to #include "monitor_fdpass.h" - - stevesk@cvs.openbsd.org 2008/10/31 15:05:34 - [dispatch.c] - remove unused #define DISPATCH_MIN; ok markus@ - - djm@cvs.openbsd.org 2008/11/01 04:50:08 - [sshconnect2.c] - sprinkle ARGSUSED on dispatch handlers - nuke stale unusued prototype - - stevesk@cvs.openbsd.org 2008/11/01 06:43:33 - [channels.c] - fix some typos in log messages; ok djm@ - - sobrado@cvs.openbsd.org 2008/11/01 11:14:36 - [ssh-keyscan.1 ssh-keyscan.c] - the ellipsis is not an optional argument; while here, improve spacing. - - stevesk@cvs.openbsd.org 2008/11/01 17:40:33 - [clientloop.c readconf.c readconf.h ssh.c] - merge dynamic forward parsing into parse_forward(); - 'i think this is OK' djm@ - - stevesk@cvs.openbsd.org 2008/11/02 00:16:16 - [ttymodes.c] - protocol 2 tty modes support is now 7.5 years old so remove these - debug3()s; ok deraadt@ - - stevesk@cvs.openbsd.org 2008/11/03 01:07:02 - [readconf.c] - remove valueless comment - - stevesk@cvs.openbsd.org 2008/11/03 02:44:41 - [readconf.c] - fix comment - - (djm) [contrib/caldera/ssh-host-keygen contrib/suse/rc.sshd] - Make example scripts generate keys with default sizes rather than fixed, - non-default 1024 bits; patch from imorgan AT nas.nasa.gov - - (djm) [contrib/sshd.pam.generic contrib/caldera/sshd.pam] - [contrib/redhat/sshd.pam] Move pam_nologin to account group from - incorrect auth group in example files; - patch from imorgan AT nas.nasa.gov - -20080906 - - (dtucker) [config.guess config.sub] Update to latest versions from - http://git.savannah.gnu.org/gitweb/ (2008-04-14 and 2008-06-16 - respectively). - -20080830 - - (dtucker) [openbsd-compat/bsd-poll.c] correctly check for number of FDs - larger than FD_SETSIZE (OpenSSH only ever uses poll with one fd). Patch - from Nicholas Marriott. - -20080721 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/07/23 07:36:55 - [servconf.c] - do not try to print options that have been compile-time disabled - in config test mode (sshd -T); report from nix-corp AT esperi.org.uk - ok dtucker@ - - (djm) [servconf.c] Print UsePAM option in config test mode (when it - has been compiled in); report from nix-corp AT esperi.org.uk - ok dtucker@ - -20080721 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2008/07/18 22:51:01 - [sftp-server.8] - no need for .Pp before or after .Sh; - - djm@cvs.openbsd.org 2008/07/21 08:19:07 - [version.h] - openssh-5.1 - - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update version number in README and RPM specs - - (djm) Release OpenSSH-5.1 - -20080717 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/07/17 08:48:00 - [sshconnect2.c] - strnvis preauth banner; pointed out by mpf@ ok markus@ - - djm@cvs.openbsd.org 2008/07/17 08:51:07 - [auth2-hostbased.c] - strip trailing '.' from hostname when HostbasedUsesNameFromPacketOnly=yes - report and patch from res AT qoxp.net (bz#1200); ok markus@ - - (dtucker) [openbsd-compat/bsd-cygwin_util.c] Remove long-unneeded compat - code, replace with equivalent cygwin library call. Patch from vinschen - at redhat.com, ok djm@. - - (djm) [sshconnect2.c] vis.h isn't available everywhere - -20080716 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/07/15 02:23:14 - [sftp.1] - number of pipelined requests is now 64; - prodded by Iain.Morgan AT nasa.gov - - djm@cvs.openbsd.org 2008/07/16 11:51:14 - [clientloop.c] - rename variable first_gc -> last_gc (since it is actually the last - in the list). - - djm@cvs.openbsd.org 2008/07/16 11:52:19 - [channels.c] - this loop index should be automatic, not static - -20080714 - - (djm) OpenBSD CVS Sync - - sthen@cvs.openbsd.org 2008/07/13 21:22:52 - [ssh-keygen.c] - Change "ssh-keygen -F [host] -l" to not display random art unless - -v is also specified, making it consistent with the manual and other - uses of -l. - ok grunk@ - - djm@cvs.openbsd.org 2008/07/13 22:13:07 - [channels.c] - use struct sockaddr_storage instead of struct sockaddr for accept(2) - address argument. from visibilis AT yahoo.com in bz#1485; ok markus@ - - djm@cvs.openbsd.org 2008/07/13 22:16:03 - [sftp.c] - increase number of piplelined requests so they properly fill the - (recently increased) channel window. prompted by rapier AT psc.edu; - ok markus@ - - djm@cvs.openbsd.org 2008/07/14 01:55:56 - [sftp-server.8] - mention requirement for /dev/log inside chroot when using sftp-server - with ChrootDirectory - - (djm) [openbsd-compat/bindresvport.c] Rename variables s/sin/in/ to - avoid clash with sin(3) function; reported by - cristian.ionescu-idbohrn AT axis.com - - (djm) [openbsd-compat/rresvport.c] Add unistd.h for missing close() - prototype; reported by cristian.ionescu-idbohrn AT axis.com - - (djm) [umac.c] Rename variable s/buffer_ptr/bufp/ to avoid clash; - reported by cristian.ionescu-idbohrn AT axis.com - - (djm) [contrib/cygwin/Makefile contrib/cygwin/ssh-host-config] - [contrib/cygwin/ssh-user-config contrib/cygwin/sshd-inetd] - Revamped and simplified Cygwin ssh-host-config script that uses - unified csih configuration tool. Requires recent Cygwin. - Patch from vinschen AT redhat.com - -20080712 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/07/12 04:52:50 - [channels.c] - unbreak; move clearing of cctx struct to before first use - reported by dkrause@ - - djm@cvs.openbsd.org 2008/07/12 05:33:41 - [scp.1] - better description for -i flag: - s/RSA authentication/public key authentication/ - - (djm) [openbsd-compat/fake-rfc2553.c openbsd-compat/fake-rfc2553.h] - return EAI_FAMILY when trying to lookup unsupported address family; - from vinschen AT redhat.com - -20080711 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2008/07/07 00:31:41 - [ttymodes.c] - we don't need arg after the debug3() was removed. from lint. - ok djm@ - - stevesk@cvs.openbsd.org 2008/07/07 23:32:51 - [key.c] - /*NOTREACHED*/ for lint warning: - warning: function key_equal falls off bottom without returning value - ok djm@ - - markus@cvs.openbsd.org 2008/07/10 18:05:58 - [channels.c] - missing bzero; from mickey; ok djm@ - - markus@cvs.openbsd.org 2008/07/10 18:08:11 - [clientloop.c monitor.c monitor_wrap.c packet.c packet.h sshd.c] - sync v1 and v2 traffic accounting; add it to sshd, too; - ok djm@, dtucker@ - -20080709 - - (djm) [Makefile.in] Print "all tests passed" when all regress tests pass - - (djm) [auth1.c] Fix format string vulnerability in protocol 1 PAM - account check failure path. The vulnerable format buffer is supplied - from PAM and should not contain attacker-supplied data. - - (djm) [auth.c] Missing unistd.h for close() - - (djm) [configure.ac] Add -Wformat-security to CFLAGS for gcc 3.x and 4.x - -20080705 - - (djm) [auth.c] Fixed test for locked account on HP/UX with shadowed - passwords disabled. bz#1083 report & patch from senthilkumar_sen AT - hotpop.com, w/ dtucker@ - - (djm) [atomicio.c configure.ac] Disable poll() fallback in atomiciov for - Tru64. readv doesn't seem to be a comparable object there. - bz#1386, patch from dtucker@ ok me - - (djm) [Makefile.in] Pass though pass to conch for interop tests - - (djm) [configure.ac] unbreak: remove extra closing brace - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/07/04 23:08:25 - [packet.c] - handle EINTR in packet_write_poll()l ok dtucker@ - - djm@cvs.openbsd.org 2008/07/04 23:30:16 - [auth1.c auth2.c] - Make protocol 1 MaxAuthTries logic match protocol 2's. - Do not treat the first protocol 2 authentication attempt as - a failure IFF it is for method "none". - Makes MaxAuthTries' user-visible behaviour identical for - protocol 1 vs 2. - ok dtucker@ - - djm@cvs.openbsd.org 2008/07/05 05:16:01 - [PROTOCOL] - grammar - -20080704 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/07/02 13:30:34 - [auth2.c] - really really remove the freebie "none" auth try for protocol 2 - - djm@cvs.openbsd.org 2008/07/02 13:47:39 - [ssh.1 ssh.c] - When forking after authentication ("ssh -f") with ExitOnForwardFailure - enabled, delay the fork until after replies for any -R forwards have - been seen. Allows for robust detection of -R forward failure when - using -f (similar to bz#92); ok dtucker@ - - otto@cvs.openbsd.org 2008/07/03 21:46:58 - [auth2-pubkey.c] - avoid nasty double free; ok dtucker@ djm@ - - djm@cvs.openbsd.org 2008/07/04 03:44:59 - [servconf.c groupaccess.h groupaccess.c] - support negation of groups in "Match group" block (bz#1315); ok dtucker@ - - dtucker@cvs.openbsd.org 2008/07/04 03:47:02 - [monitor.c] - Make debug a little clearer. ok djm@ - - djm@cvs.openbsd.org 2008/06/30 08:07:34 - [regress/key-options.sh] - shell portability: use "=" instead of "==" in test(1) expressions, - double-quote string with backslash escaped / - - djm@cvs.openbsd.org 2008/06/30 10:31:11 - [regress/{putty-transfer,putty-kex,putty-ciphers}.sh] - remove "set -e" left over from debugging - - djm@cvs.openbsd.org 2008/06/30 10:43:03 - [regress/conch-ciphers.sh] - explicitly disable conch options that could interfere with the test - - (dtucker) [sftp-server.c] Bug #1447: fall back to racy rename if link - returns EXDEV. Patch from Mike Garrison, ok djm@ - - (djm) [atomicio.c channels.c clientloop.c defines.h includes.h] - [packet.c scp.c serverloop.c sftp-client.c ssh-agent.c ssh-keyscan.c] - [sshd.c] Explicitly handle EWOULDBLOCK wherever we handle EAGAIN, on - some platforms (HP nonstop) it is a distinct errno; - bz#1467 reported by sconeu AT yahoo.com; ok dtucker@ - -20080702 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/06/30 08:05:59 - [PROTOCOL.agent] - typo: s/constraint_date/constraint_data/ - - djm@cvs.openbsd.org 2008/06/30 12:15:39 - [serverloop.c] - only pass channel requests on session channels through to the session - channel handler, avoiding spurious log messages; ok! markus@ - - djm@cvs.openbsd.org 2008/06/30 12:16:02 - [nchan.c] - only send eow@openssh.com notifications for session channels; ok! markus@ - - djm@cvs.openbsd.org 2008/06/30 12:18:34 - [PROTOCOL] - clarify that eow@openssh.com is only sent on session channels - - dtucker@cvs.openbsd.org 2008/07/01 07:20:52 - [sshconnect.c] - Check ExitOnForwardFailure if forwardings are disabled due to a failed - host key check. ok djm@ - - dtucker@cvs.openbsd.org 2008/07/01 07:24:22 - [sshconnect.c sshd.c] - Send CR LF during protocol banner exchanges, but only for Protocol 2 only, - in order to comply with RFC 4253. bz #1443, ok djm@ - - stevesk@cvs.openbsd.org 2008/07/01 23:12:47 - [PROTOCOL.agent] - fix some typos; ok djm@ - - djm@cvs.openbsd.org 2008/07/02 02:24:18 - [sshd_config sshd_config.5 sshd.8 servconf.c] - increase default size of ssh protocol 1 ephemeral key from 768 to 1024 - bits; prodded by & ok dtucker@ ok deraadt@ - - dtucker@cvs.openbsd.org 2008/07/02 12:03:51 - [auth-rsa.c auth.c auth2-pubkey.c auth.h] - Merge duplicate host key file checks, based in part on a patch from Rob - Holland via bz #1348 . Also checks for non-regular files during protocol - 1 RSA auth. ok djm@ - - djm@cvs.openbsd.org 2008/07/02 12:36:39 - [auth2-none.c auth2.c] - Make protocol 2 MaxAuthTries behaviour a little more sensible: - Check whether client has exceeded MaxAuthTries before running - an authentication method and skip it if they have, previously it - would always allow one try (for "none" auth). - Preincrement failure count before post-auth test - previously this - checked and postincremented, also to allow one "none" try. - Together, these two changes always count the "none" auth method - which could be skipped by a malicious client (e.g. an SSH worm) - to get an extra attempt at a real auth method. They also make - MaxAuthTries=0 a useful way to block users entirely (esp. in a - sshd_config Match block). - Also, move sending of any preauth banner from "none" auth method - to the first call to input_userauth_request(), so worms that skip - the "none" method get to see it too. - -20080630 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2008/06/10 23:13:43 - [regress/Makefile regress/key-options.sh] - Add regress test for key options. ok djm@ - - dtucker@cvs.openbsd.org 2008/06/11 23:11:40 - [regress/Makefile] - Don't run cipher-speed test by default; mistakenly enabled by me - - djm@cvs.openbsd.org 2008/06/28 13:57:25 - [regress/Makefile regress/test-exec.sh regress/conch-ciphers.sh] - very basic regress test against Twisted Conch in "make interop" - target (conch is available in ports/devel/py-twisted/conch); - ok markus@ - - (djm) [regress/Makefile] search for conch by path, like we do putty - -20080629 - - (djm) OpenBSD CVS Sync - - martynas@cvs.openbsd.org 2008/06/21 07:46:46 - [sftp.c] - use optopt to get invalid flag, instead of return value of getopt, - which is always '?'; ok djm@ - - otto@cvs.openbsd.org 2008/06/25 11:13:43 - [key.c] - add key length to visual fingerprint; zap magical constants; - ok grunk@ djm@ - - djm@cvs.openbsd.org 2008/06/26 06:10:09 - [sftp-client.c sftp-server.c] - allow the sftp chmod(2)-equivalent operation to set set[ug]id/sticky - bits. Note that this only affects explicit setting of modes (e.g. via - sftp(1)'s chmod command) and not file transfers. (bz#1310) - ok deraadt@ at c2k8 - - djm@cvs.openbsd.org 2008/06/26 09:19:40 - [dh.c dh.h moduli.c] - when loading moduli from /etc/moduli in sshd(8), check that they - are of the expected "safe prime" structure and have had - appropriate primality tests performed; - feedback and ok dtucker@ - - grunk@cvs.openbsd.org 2008/06/26 11:46:31 - [readconf.c readconf.h ssh.1 ssh_config.5 sshconnect.c] - Move SSH Fingerprint Visualization away from sharing the config option - CheckHostIP to an own config option named VisualHostKey. - While there, fix the behaviour that ssh would draw a random art picture - on every newly seen host even when the option was not enabled. - prodded by deraadt@, discussions, - help and ok markus@ djm@ dtucker@ - - jmc@cvs.openbsd.org 2008/06/26 21:11:46 - [ssh.1] - add VisualHostKey to the list of options listed in -o; - - djm@cvs.openbsd.org 2008/06/28 07:25:07 - [PROTOCOL] - spelling fixes - - djm@cvs.openbsd.org 2008/06/28 13:58:23 - [ssh-agent.c] - refuse to add a key that has unknown constraints specified; - ok markus - - djm@cvs.openbsd.org 2008/06/28 14:05:15 - [ssh-agent.c] - reset global compat flag after processing a protocol 2 signature - request with the legacy DSA encoding flag set; ok markus - - djm@cvs.openbsd.org 2008/06/28 14:08:30 - [PROTOCOL PROTOCOL.agent] - document the protocol used by ssh-agent; "looks ok" markus@ - -20080628 - - (djm) [RFC.nroff contrib/cygwin/Makefile contrib/suse/openssh.spec] - RFC.nroff lacks a license, remove it (it is long gone in OpenBSD). - -20080626 - - (djm) [Makefile.in moduli.5] Include moduli(5) manpage from OpenBSD. - (bz#1372) - - (djm) [ contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Include moduli.5 in RPM spec files. - -20080616 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2008/06/16 13:22:53 - [session.c channels.c] - Rename the isatty argument to is_tty so we don't shadow - isatty(3). ok markus@ - - (dtucker) [channels.c] isatty -> is_tty here too. - -20080615 - - (dtucker) [configure.ac] Enable -fno-builtin-memset when using gcc. - - OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2008/06/14 15:49:48 - [sshd.c] - wrap long line at 80 chars - - dtucker@cvs.openbsd.org 2008/06/14 17:07:11 - [sshd.c] - ensure default umask disallows at least group and world write; ok djm@ - - djm@cvs.openbsd.org 2008/06/14 18:33:43 - [session.c] - suppress the warning message from chdir(homedir) failures - when chrooted (bz#1461); ok dtucker - - dtucker@cvs.openbsd.org 2008/06/14 19:42:10 - [scp.1] - Mention that scp follows symlinks during -r. bz #1466, - from nectar at apple - - dtucker@cvs.openbsd.org 2008/06/15 16:55:38 - [sshd_config.5] - MaxSessions is allowed in a Match block too - - dtucker@cvs.openbsd.org 2008/06/15 16:58:40 - [servconf.c sshd_config.5] - Allow MaxAuthTries within a Match block. ok djm@ - - djm@cvs.openbsd.org 2008/06/15 20:06:26 - [channels.c channels.h session.c] - don't call isatty() on a pty master, instead pass a flag down to - channel_set_fds() indicating that te fds refer to a tty. Fixes a - hang on exit on Solaris (bz#1463) in portable but is actually - a generic bug; ok dtucker deraadt markus - -20080614 - - (djm) [openbsd-compat/sigact.c] Avoid NULL derefs in ancient sigaction - replacement code; patch from ighighi AT gmail.com in bz#1240; - ok dtucker - -20080613 - - (dtucker) OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2008/06/13 09:44:36 - [packet.c] - compile on older gcc; no decl after code - - dtucker@cvs.openbsd.org 2008/06/13 13:56:59 - [monitor.c] - Clear key options in the monitor on failed authentication, prevents - applying additional restrictions to non-pubkey authentications in - the case where pubkey fails but another method subsequently succeeds. - bz #1472, found by Colin Watson, ok markus@ djm@ - - dtucker@cvs.openbsd.org 2008/06/13 14:18:51 - [auth2-pubkey.c auth-rhosts.c] - Include unistd.h for close(), prevents warnings in -portable - - dtucker@cvs.openbsd.org 2008/06/13 17:21:20 - [mux.c] - Friendlier error messages for mux fallback. ok djm@ - - dtucker@cvs.openbsd.org 2008/06/13 18:55:22 - [scp.c] - Prevent -Wsign-compare warnings on LP64 systems. bz #1192, ok deraadt@ - - grunk@cvs.openbsd.org 2008/06/13 20:13:26 - [ssh.1] - Explain the use of SSH fpr visualization using random art, and cite the - original scientific paper inspiring that technique. - Much help with English and nroff by jmc@, thanks. - - (dtucker) [configure.ac] Bug #1276: avoid linking against libgssapi, which - despite its name doesn't seem to implement all of GSSAPI. Patch from - Jan Engelhardt, sanity checked by Simon Wilkinson. - -20080612 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2008/06/11 07:30:37 - [sshd.8] - kill trailing whitespace; - - grunk@cvs.openbsd.org 2008/06/11 21:01:35 - [ssh_config.5 key.h readconf.c readconf.h ssh-keygen.1 ssh-keygen.c key.c - sshconnect.c] - Introduce SSH Fingerprint ASCII Visualization, a technique inspired by the - graphical hash visualization schemes known as "random art", and by - Dan Kaminsky's musings on the subject during a BlackOp talk at the - 23C3 in Berlin. - Scientific publication (original paper): - "Hash Visualization: a New Technique to improve Real-World Security", - Perrig A. and Song D., 1999, International Workshop on Cryptographic - Techniques and E-Commerce (CrypTEC '99) - http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf - The algorithm used here is a worm crawling over a discrete plane, - leaving a trace (augmenting the field) everywhere it goes. - Movement is taken from dgst_raw 2bit-wise. Bumping into walls - makes the respective movement vector be ignored for this turn, - thus switching to the other color of the chessboard. - Graphs are not unambiguous for now, because circles in graphs can be - walked in either direction. - discussions with several people, - help, corrections and ok markus@ djm@ - - grunk@cvs.openbsd.org 2008/06/11 21:38:25 - [ssh-keygen.c] - ssh-keygen -lv -f /etc/ssh/ssh_host_rsa_key.pub - would not display you the random art as intended, spotted by canacar@ - - grunk@cvs.openbsd.org 2008/06/11 22:20:46 - [ssh-keygen.c ssh-keygen.1] - ssh-keygen would write fingerprints to STDOUT, and random art to STDERR, - that is not how it was envisioned. - Also correct manpage saying that -v is needed along with -l for it to work. - spotted by naddy@ - - otto@cvs.openbsd.org 2008/06/11 23:02:22 - [key.c] - simpler way of computing the augmentations; ok grunk@ - - grunk@cvs.openbsd.org 2008/06/11 23:03:56 - [ssh_config.5] - CheckHostIP set to ``fingerprint'' will display both hex and random art - spotted by naddy@ - - grunk@cvs.openbsd.org 2008/06/11 23:51:57 - [key.c] - #define statements that are not atoms need braces around them, else they - will cause trouble in some cases. - Also do a computation of -1 once, and not in a loop several times. - spotted by otto@ - - dtucker@cvs.openbsd.org 2008/06/12 00:03:49 - [dns.c canohost.c sshconnect.c] - Do not pass "0" strings as ports to getaddrinfo because the lookups - can slow things down and we never use the service info anyway. bz - #859, patch from YOSHIFUJI Hideaki and John Devitofranceschi. ok - deraadt@ djm@ - djm belives that the reason for the "0" strings is to ensure that - it's not possible to call getaddrinfo with both host and port being - NULL. In the case of canohost.c host is a local array. In the - case of sshconnect.c, it's checked for null immediately before use. - In dns.c it ultimately comes from ssh.c:main() and is guaranteed to - be non-null but it's not obvious, so I added a warning message in - case it is ever passed a null. - - grunk@cvs.openbsd.org 2008/06/12 00:13:55 - [sshconnect.c] - Make ssh print the random art also when ssh'ing to a host using IP only. - spotted by naddy@, ok and help djm@ dtucker@ - - otto@cvs.openbsd.org 2008/06/12 00:13:13 - [key.c] - use an odd number of rows and columns and a separate start marker, looks - better; ok grunk@ - - djm@cvs.openbsd.org 2008/06/12 03:40:52 - [clientloop.h mux.c channels.c clientloop.c channels.h] - Enable ~ escapes for multiplex slave sessions; give each channel - its own escape state and hook the escape filters up to muxed - channels. bz #1331 - Mux slaves do not currently support the ~^Z and ~& escapes. - NB. this change cranks the mux protocol version, so a new ssh - mux client will not be able to connect to a running old ssh - mux master. - ok dtucker@ - - djm@cvs.openbsd.org 2008/06/12 04:06:00 - [clientloop.h ssh.c clientloop.c] - maintain an ordered queue of outstanding global requests that we - expect replies to, similar to the per-channel confirmation queue. - Use this queue to verify success or failure for remote forward - establishment in a race free way. - ok dtucker@ - - djm@cvs.openbsd.org 2008/06/12 04:17:47 - [clientloop.c] - thall shalt not code past the eightieth column - - djm@cvs.openbsd.org 2008/06/12 04:24:06 - [ssh.c] - thal shalt not code past the eightieth column - - djm@cvs.openbsd.org 2008/06/12 05:15:41 - [PROTOCOL] - document tun@openssh.com forwarding method - - djm@cvs.openbsd.org 2008/06/12 05:32:30 - [mux.c] - some more TODO for me - - grunk@cvs.openbsd.org 2008/06/12 05:42:46 - [key.c] - supply the key type (rsa1, rsa, dsa) as a caption in the frame of the - random art. while there, stress the fact that the field base should at - least be 8 characters for the pictures to make sense. - comment and ok djm@ - - grunk@cvs.openbsd.org 2008/06/12 06:32:59 - [key.c] - We already mark the start of the worm, now also mark the end of the worm - in our random art drawings. - ok djm@ - - djm@cvs.openbsd.org 2008/06/12 15:19:17 - [clientloop.h channels.h clientloop.c channels.c mux.c] - The multiplexing escape char handler commit last night introduced a - small memory leak per session; plug it. - - dtucker@cvs.openbsd.org 2008/06/12 16:35:31 - [ssh_config.5 ssh.c] - keyword expansion for localcommand. ok djm@ - - jmc@cvs.openbsd.org 2008/06/12 19:10:09 - [ssh_config.5 ssh-keygen.1] - tweak the ascii art text; ok grunk - - dtucker@cvs.openbsd.org 2008/06/12 20:38:28 - [sshd.c sshconnect.c packet.h misc.c misc.h packet.c] - Make keepalive timeouts apply while waiting for a packet, particularly - during key renegotiation (bz #1363). With djm and Matt Day, ok djm@ - - djm@cvs.openbsd.org 2008/06/12 20:47:04 - [sftp-client.c] - print extension revisions for extensions that we understand - - djm@cvs.openbsd.org 2008/06/12 21:06:25 - [clientloop.c] - I was coalescing expected global request confirmation replies at - the wrong end of the queue - fix; prompted by markus@ - - grunk@cvs.openbsd.org 2008/06/12 21:14:46 - [ssh-keygen.c] - make ssh-keygen -lf show the key type just as ssh-add -l would do it - ok djm@ markus@ - - grunk@cvs.openbsd.org 2008/06/12 22:03:36 - [key.c] - add my copyright, ok djm@ - - ian@cvs.openbsd.org 2008/06/12 23:24:58 - [sshconnect.c] - tweak wording in message, ok deraadt@ jmc@ - - dtucker@cvs.openbsd.org 2008/06/13 00:12:02 - [sftp.h log.h] - replace __dead with __attribute__((noreturn)), makes things - a little easier to port. Also, add it to sigdie(). ok djm@ - - djm@cvs.openbsd.org 2008/06/13 00:16:49 - [mux.c] - fall back to creating a new TCP connection on most multiplexing errors - (socket connect fail, invalid version, refused permittion, corrupted - messages, etc.); bz #1329 ok dtucker@ - - dtucker@cvs.openbsd.org 2008/06/13 00:47:53 - [mux.c] - upcast size_t to u_long to match format arg; ok djm@ - - dtucker@cvs.openbsd.org 2008/06/13 00:51:47 - [mac.c] - upcast another size_t to u_long to match format - - dtucker@cvs.openbsd.org 2008/06/13 01:38:23 - [misc.c] - upcast uid to long with matching %ld, prevents warnings in portable - - djm@cvs.openbsd.org 2008/06/13 04:40:22 - [auth2-pubkey.c auth-rhosts.c] - refuse to read ~/.shosts or ~/.ssh/authorized_keys that are not - regular files; report from Solar Designer via Colin Watson in bz#1471 - ok dtucker@ deraadt - - (dtucker) [clientloop.c serverloop.c] channel_register_filter now - takes 2 more args. with djm@ - - (dtucker) [defines.h] Bug #1112: __dead is, well dead. Based on a patch - from Todd Vierling. - - (dtucker) [auth-sia.c] Bug #1241: support password expiry on Tru64 SIA - systems. Patch from R. Scott Bailey. - - (dtucker) [umac.c] STORE_UINT32_REVERSED and endian_convert are never used - on big endian machines, so ifdef them for little-endian only to prevent - unused function warnings on big-endians. - - (dtucker) [openbsd-compat/setenv.c] Make offsets size_t to prevent - compiler warnings on some platforms. Based on a discussion with otto@ - -20080611 - - (djm) [channels.c configure.ac] - Do not set SO_REUSEADDR on wildcard X11 listeners (X11UseLocalhost=no) - bz#1464; ok dtucker - -20080610 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/06/10 03:57:27 - [servconf.c match.h sshd_config.5] - support CIDR address matching in sshd_config "Match address" blocks, with - full support for negation and fall-back to classic wildcard matching. - For example: - Match address 192.0.2.0/24,3ffe:ffff::/32,!10.* - PasswordAuthentication yes - addrmatch.c code mostly lifted from flowd's addr.c - feedback and ok dtucker@ - - djm@cvs.openbsd.org 2008/06/10 04:17:46 - [sshd_config.5] - better reference for pattern-list - - dtucker@cvs.openbsd.org 2008/06/10 04:50:25 - [sshd.c channels.h channels.c log.c servconf.c log.h servconf.h sshd.8] - Add extended test mode (-T) and connection parameters for test mode (-C). - -T causes sshd to write its effective configuration to stdout and exit. - -C causes any relevant Match rules to be applied before output. The - combination allows tesing of the parser and config files. ok deraadt djm - - jmc@cvs.openbsd.org 2008/06/10 07:12:00 - [sshd_config.5] - tweak previous; - - jmc@cvs.openbsd.org 2008/06/10 08:17:40 - [sshd.8 sshd.c] - - update usage() - - fix SYNOPSIS, and sort options - - some minor additional fixes - - dtucker@cvs.openbsd.org 2008/06/09 18:06:32 - [regress/test-exec.sh] - Don't generate putty keys if we're not going to use them. ok djm - - dtucker@cvs.openbsd.org 2008/06/10 05:23:32 - [regress/addrmatch.sh regress/Makefile] - Regress test for Match CIDR rules. ok djm@ - - dtucker@cvs.openbsd.org 2008/06/10 15:21:41 - [test-exec.sh] - Use a more portable construct for checking if we're running a putty test - - dtucker@cvs.openbsd.org 2008/06/10 15:28:49 - [test-exec.sh] - Add quotes - - dtucker@cvs.openbsd.org 2008/06/10 18:21:24 - [ssh_config.5] - clarify that Host patterns are space-separated. ok deraadt - - djm@cvs.openbsd.org 2008/06/10 22:15:23 - [PROTOCOL ssh.c serverloop.c] - Add a no-more-sessions@openssh.com global request extension that the - client sends when it knows that it will never request another session - (i.e. when session multiplexing is disabled). This allows a server to - disallow further session requests and terminate the session. - Why would a non-multiplexing client ever issue additional session - requests? It could have been attacked with something like SSH'jack: - http://www.storm.net.nz/projects/7 - feedback & ok markus - - djm@cvs.openbsd.org 2008/06/10 23:06:19 - [auth-options.c match.c servconf.c addrmatch.c sshd.8] - support CIDR address matching in .ssh/authorized_keys from="..." stanzas - ok and extensive testing dtucker@ - - dtucker@cvs.openbsd.org 2008/06/10 23:21:34 - [bufaux.c] - Use '\0' for a nul byte rather than unadorned 0. ok djm@ - - dtucker@cvs.openbsd.org 2008/06/10 23:13:43 - [Makefile regress/key-options.sh] - Add regress test for key options. ok djm@ - - (dtucker) [openbsd-compat/fake-rfc2553.h] Add sin6_scope_id to sockaddr_in6 - since the new CIDR code in addmatch.c references it. - - (dtucker) [Makefile.in configure.ac regress/addrmatch.sh] Skip IPv6 - specific tests on platforms that don't do IPv6. - - (dtucker) [Makefile.in] Define TEST_SSH_IPV6 in make's arguments as well - as environment. - - (dtucker) [Makefile.in] Move addrmatch.o to libssh.a where it's needed now. - -20080609 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2008/06/08 17:04:41 - [sftp-server.c] - Add case for ENOSYS in errno_to_portable; ok deraadt - - dtucker@cvs.openbsd.org 2008/06/08 20:15:29 - [sftp.c sftp-client.c sftp-client.h] - Have the sftp client store the statvfs replies in wire format, - which prevents problems when the server's native sizes exceed the - client's. - Also extends the sizes of the remaining 32bit wire format to 64bit, - they're specified as unsigned long in the standard. - - dtucker@cvs.openbsd.org 2008/06/09 13:02:39 - [sftp-server.c] - Extend 32bit -> 64bit values for statvfs extension missed in previous - commit. - - dtucker@cvs.openbsd.org 2008/06/09 13:38:46 - [PROTOCOL] - Use a $OpenBSD tag so our scripts will sync changes. - -20080608 - - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c - openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h - openbsd-compat/bsd-statvfs.{c,h}] Add a null implementation of statvfs and - fstatvfs and remove #defines around statvfs code. ok djm@ - - (dtucker) [configure.ac defines.h sftp-client.c M sftp-server.c] Add a - macro to convert fsid to unsigned long for platforms where fsid is a - 2-member array. - -20080607 - - (dtucker) [mux.c] Include paths.h inside ifdef HAVE_PATHS_H. - - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c] - Do not enable statvfs extensions on platforms that do not have statvfs. - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/05/19 06:14:02 - [packet.c] unbreak protocol keepalive timeouts bz#1465; ok dtucker@ - - djm@cvs.openbsd.org 2008/05/19 15:45:07 - [sshtty.c ttymodes.c sshpty.h] - Fix sending tty modes when stdin is not a tty (bz#1199). Previously - we would send the modes corresponding to a zeroed struct termios, - whereas we should have been sending an empty list of modes. - Based on patch from daniel.ritz AT alcatel.ch; ok dtucker@ markus@ - - djm@cvs.openbsd.org 2008/05/19 15:46:31 - [ssh-keygen.c] - support -l (print fingerprint) in combination with -F (find host) to - search for a host in ~/.ssh/known_hosts and display its fingerprint; - ok markus@ - - djm@cvs.openbsd.org 2008/05/19 20:53:52 - [clientloop.c] - unbreak tree by committing this bit that I missed from: - Fix sending tty modes when stdin is not a tty (bz#1199). Previously - we would send the modes corresponding to a zeroed struct termios, - whereas we should have been sending an empty list of modes. - Based on patch from daniel.ritz AT alcatel.ch; ok dtucker@ markus@ - -20080604 - - (djm) [openbsd-compat/bsd-arc4random.c] Fix math bug that caused bias - in arc4random_uniform with upper_bound in (2^30,2*31). Note that - OpenSSH did not make requests with upper bounds in this range. - -20080519 - - (djm) [configure.ac mux.c sftp.c openbsd-compat/Makefile.in] - [openbsd-compat/fmt_scaled.c openbsd-compat/openbsd-compat.h] - Fix compilation on Linux, including pulling in fmt_scaled(3) - implementation from OpenBSD's libutil. - -20080518 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/04/04 05:14:38 - [sshd_config.5] - ChrootDirectory is supported in Match blocks (in fact, it is most useful - there). Spotted by Minstrel AT minstrel.org.uk - - djm@cvs.openbsd.org 2008/04/04 06:44:26 - [sshd_config.5] - oops, some unrelated stuff crept into that commit - backout. - spotted by jmc@ - - djm@cvs.openbsd.org 2008/04/05 02:46:02 - [sshd_config.5] - HostbasedAuthentication is supported under Match too - - (djm) [openbsd-compat/bsd-arc4random.c openbsd-compat/openbsd-compat.c] - [configure.ac] Implement arc4random_buf(), import implementation of - arc4random_uniform() from OpenBSD - - (djm) [openbsd-compat/bsd-arc4random.c] Warning fixes - - (djm) [openbsd-compat/port-tun.c] needs sys/queue.h - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2008/04/13 00:22:17 - [dh.c sshd.c] - Use arc4random_buf() when requesting more than a single word of output - Use arc4random_uniform() when the desired random number upper bound - is not a power of two - ok deraadt@ millert@ - - djm@cvs.openbsd.org 2008/04/18 12:32:11 - [sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c sftp.h] - introduce sftp extension methods statvfs@openssh.com and - fstatvfs@openssh.com that implement statvfs(2)-like operations, - based on a patch from miklos AT szeredi.hu (bz#1399) - also add a "df" command to the sftp client that uses the - statvfs@openssh.com to produce a df(1)-like display of filesystem - space and inode utilisation - ok markus@ - - jmc@cvs.openbsd.org 2008/04/18 17:15:47 - [sftp.1] - macro fixage; - - djm@cvs.openbsd.org 2008/04/18 22:01:33 - [session.c] - remove unneccessary parentheses - - otto@cvs.openbsd.org 2008/04/29 11:20:31 - [monitor_mm.h] - garbage collect two unused fields in struct mm_master; ok markus@ - - djm@cvs.openbsd.org 2008/04/30 10:14:03 - [ssh-keyscan.1 ssh-keyscan.c] - default to rsa (protocol 2) keys, instead of rsa1 keys; spotted by - larsnooden AT openoffice.org - - pyr@cvs.openbsd.org 2008/05/07 05:49:37 - [servconf.c servconf.h session.c sshd_config.5] - Enable the AllowAgentForwarding option in sshd_config (global and match - context), to specify if agents should be permitted on the server. - As the man page states: - ``Note that disabling Agent forwarding does not improve security - unless users are also denied shell access, as they can always install - their own forwarders.'' - ok djm@, ok and a mild frown markus@ - - pyr@cvs.openbsd.org 2008/05/07 06:43:35 - [sshd_config] - push the sshd_config bits in, spotted by ajacoutot@ - - jmc@cvs.openbsd.org 2008/05/07 08:00:14 - [sshd_config.5] - sort; - - markus@cvs.openbsd.org 2008/05/08 06:59:01 - [bufaux.c buffer.h channels.c packet.c packet.h] - avoid extra malloc/copy/free when receiving data over the net; - ~10% speedup for localhost-scp; ok djm@ - - djm@cvs.openbsd.org 2008/05/08 12:02:23 - [auth-options.c auth1.c channels.c channels.h clientloop.c gss-serv.c] - [monitor.c monitor_wrap.c nchan.c servconf.c serverloop.c session.c] - [ssh.c sshd.c] - Implement a channel success/failure status confirmation callback - mechanism. Each channel maintains a queue of callbacks, which will - be drained in order (RFC4253 guarantees confirm messages are not - reordered within an channel). - Also includes a abandonment callback to clean up if a channel is - closed without sending confirmation messages. This probably - shouldn't happen in compliant implementations, but it could be - abused to leak memory. - ok markus@ (as part of a larger diff) - - djm@cvs.openbsd.org 2008/05/08 12:21:16 - [monitor.c monitor_wrap.c session.h servconf.c servconf.h session.c] - [sshd_config sshd_config.5] - Make the maximum number of sessions run-time controllable via - a sshd_config MaxSessions knob. This is useful for disabling - login/shell/subsystem access while leaving port-forwarding working - (MaxSessions 0), disabling connection multiplexing (MaxSessions 1) or - simply increasing the number of allows multiplexed sessions. - Because some bozos are sure to configure MaxSessions in excess of the - number of available file descriptors in sshd (which, at peak, might be - as many as 9*MaxSessions), audit sshd to ensure that it doesn't leak fds - on error paths, and make it fail gracefully on out-of-fd conditions - - sending channel errors instead of than exiting with fatal(). - bz#1090; MaxSessions config bits and manpage from junyer AT gmail.com - ok markus@ - - djm@cvs.openbsd.org 2008/05/08 13:06:11 - [clientloop.c clientloop.h ssh.c] - Use new channel status confirmation callback system to properly deal - with "important" channel requests that fail, in particular command exec, - shell and subsystem requests. Previously we would optimistically assume - that the requests would always succeed, which could cause hangs if they - did not (e.g. when the server runs out of fds) or were unimplemented by - the server (bz #1384) - Also, properly report failing multiplex channel requests via the mux - client stderr (subject to LogLevel in the mux master) - better than - silently failing. - most bits ok markus@ (as part of a larger diff) - - djm@cvs.openbsd.org 2008/05/09 04:55:56 - [channels.c channels.h clientloop.c serverloop.c] - Try additional addresses when connecting to a port forward destination - whose DNS name resolves to more than one address. The previous behaviour - was to try the first address and give up. - Reported by stig AT venaas.com in bz#343 - great feedback and ok markus@ - - djm@cvs.openbsd.org 2008/05/09 14:18:44 - [clientloop.c clientloop.h ssh.c mux.c] - tidy up session multiplexing code, moving it into its own file and - making the function names more consistent - making ssh.c and - clientloop.c a fair bit more readable. - ok markus@ - - djm@cvs.openbsd.org 2008/05/09 14:26:08 - [ssh.c] - dingo stole my diff hunk - - markus@cvs.openbsd.org 2008/05/09 16:16:06 - [session.c] - re-add the USE_PIPES code and enable it. - without pipes shutdown-read from the sshd does not trigger - a SIGPIPE when the forked program does a write. - ok djm@ - (Id sync only, USE_PIPES never left portable OpenSSH) - - markus@cvs.openbsd.org 2008/05/09 16:17:51 - [channels.c] - error-fd race: don't enable the error fd in the select bitmask - for channels with both in- and output closed, since the channel - will go away before we call select(); - report, lots of debugging help and ok djm@ - - markus@cvs.openbsd.org 2008/05/09 16:21:13 - [channels.h clientloop.c nchan.c serverloop.c] - unbreak - ssh -2 localhost od /bin/ls | true - ignoring SIGPIPE by adding a new channel message (EOW) that signals - the peer that we're not interested in any data it might send. - fixes bz #85; discussion, debugging and ok djm@ - - pvalchev@cvs.openbsd.org 2008/05/12 20:52:20 - [umac.c] - Ensure nh_result lies on a 64-bit boundary (fixes warnings observed - on Itanium on Linux); from Dale Talcott (bug #1462); ok djm@ - - djm@cvs.openbsd.org 2008/05/15 23:52:24 - [nchan2.ms] - document eow message in ssh protocol 2 channel state machine; - feedback and ok markus@ - - djm@cvs.openbsd.org 2008/05/18 21:29:05 - [sftp-server.c] - comment extension announcement - - djm@cvs.openbsd.org 2008/05/16 08:30:42 - [PROTOCOL] - document our protocol extensions and deviations; ok markus@ - - djm@cvs.openbsd.org 2008/05/17 01:31:56 - [PROTOCOL] - grammar and correctness fixes from stevesk@ - -20080403 - - (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile- - time warnings on LynxOS. Patch from ops AT iki.fi - - (djm) Force string arguments to replacement setproctitle() though - strnvis first. Ok dtucker@ - -20080403 - - (djm) OpenBSD CVS sync: - - markus@cvs.openbsd.org 2008/04/02 15:36:51 - [channels.c] - avoid possible hijacking of x11-forwarded connections (back out 1.183) - CVE-2008-1483; ok djm@ - - jmc@cvs.openbsd.org 2008/03/27 22:37:57 - [sshd.8] - remove trailing whitespace; - - djm@cvs.openbsd.org 2008/04/03 09:50:14 - [version.h] - openssh-5.0 - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank version numbers in RPM spec files - - (djm) [README] Update link to release notes - - (djm) Release 5.0p1 diff --git a/LICENCE b/LICENCE index 3964b1d7718d..120d6fd54dbb 100644 --- a/LICENCE +++ b/LICENCE @@ -206,6 +206,7 @@ OpenSSH contains no GPL code. Sun Microsystems The SCO Group Daniel Walsh + Red Hat, Inc * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Makefile.in b/Makefile.in index 5654d4341467..77a78aa61295 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.310 2010/05/12 06:51:39 dtucker Exp $ +# $Id: Makefile.in,v 1.320 2011/01/17 10:15:29 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -58,6 +58,7 @@ ENT=@ENT@ XAUTH_PATH=@XAUTH_PATH@ LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ EXEEXT=@EXEEXT@ +MANFMT=@MANFMT@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ @@ -71,26 +72,27 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ log.o match.o md-sha256.o moduli.o nchan.o packet.o \ readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ - monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ - kexgex.o kexdhc.o kexgexc.o msg.o progressmeter.o dns.o \ - entropy.o gss-genr.o umac.o jpake.o schnorr.o \ - ssh-pkcs11.o + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o jpake.o \ + schnorr.o ssh-pkcs11.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ roaming_common.o roaming_client.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 \ sshpty.o sshlogin.o servconf.o serverloop.o \ auth.o auth1.o auth2.o auth-options.o session.o \ auth-chall.o auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ - monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ + monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ - audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \ + sftp-server.o sftp-common.o \ roaming_common.o roaming_serv.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-rand-helper.8.out ssh-keysign.8.out ssh-pkcs11-helper.8.out sshd_config.5.out ssh_config.5.out @@ -108,6 +110,7 @@ PATHSUBS = \ -e 's|/usr/libexec|$(libexecdir)|g' \ -e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \ -e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \ + -e 's|/etc/ssh/ssh_host_ecdsa_key|$(sysconfdir)/ssh_host_ecdsa_key|g' \ -e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \ -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \ -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \ @@ -230,7 +233,7 @@ catman-do: @for f in $(MANPAGES_IN) ; do \ base=`echo $$f | sed 's/\..*$$//'` ; \ echo "$$f -> $$base.0" ; \ - nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + $(MANFMT) $$f | cat -v | sed -e 's/.\^H//g' \ >$$base.0 ; \ done @@ -324,20 +327,27 @@ install-sysconf: host-key: ssh-keygen$(EXEEXT) @if [ -z "$(DESTDIR)" ] ; then \ - if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ - echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + if [ -f "$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(sysconfdir)/ssh_host_key already exists, skipping." ; \ else \ - ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + ./ssh-keygen -t rsa1 -f $(sysconfdir)/ssh_host_key -N "" ; \ fi ; \ - if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ - echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + if [ -f $(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ else \ - ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + ./ssh-keygen -t dsa -f $(sysconfdir)/ssh_host_dsa_key -N "" ; \ fi ; \ - if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key ] ; then \ - echo "$(DESTDIR)$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \ + if [ -f $(sysconfdir)/ssh_host_rsa_key ] ; then \ + echo "$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \ else \ - ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ; \ + ./ssh-keygen -t rsa -f $(sysconfdir)/ssh_host_rsa_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 ; @@ -345,6 +355,7 @@ host-key-force: ssh-keygen$(EXEEXT) ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" + test -z "@COMMENT_OUT_ECC@" && ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N "" uninstallall: uninstall -rm -f $(DESTDIR)$(sysconfdir)/ssh_config @@ -405,6 +416,8 @@ tests interop-tests: $(TARGETS) TEST_SSH_PUTTYGEN="puttygen"; \ TEST_SSH_CONCH="conch"; \ TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \ + TEST_SSH_ECC="@TEST_SSH_ECC@" ; \ + TEST_SSH_SHA256="@TEST_SSH_SHA256@" ; \ cd $(srcdir)/regress || exit $$?; \ $(MAKE) \ .OBJDIR="$${BUILDDIR}/regress" \ @@ -425,7 +438,9 @@ tests interop-tests: $(TARGETS) TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \ TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \ TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \ - TEST_SSH_IPV6="@TEST_SSH_IPV6@" \ + TEST_SSH_IPV6="$${TEST_SSH_IPV6}" \ + TEST_SSH_ECC="$${TEST_SSH_ECC}" \ + TEST_SSH_SHA256="$${TEST_SSH_SHA256}" \ EXEEXT="$(EXEEXT)" \ $@ && echo all tests passed diff --git a/PROTOCOL b/PROTOCOL index 5fc31eade32a..c2819601137a 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -12,7 +12,9 @@ are individually implemented as extensions described below. The protocol used by OpenSSH's ssh-agent is described in the file PROTOCOL.agent -1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com" +1. Transport protocol changes + +1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com" This is a new transport-layer MAC method using the UMAC algorithm (rfc4418). This method is identical to the "umac-64" method documented @@ -20,7 +22,7 @@ in: http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt -2. transport: Protocol 2 compression algorithm "zlib@openssh.com" +1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com" This transport-layer compression method uses the zlib compression algorithm (identical to the "zlib" method in rfc4253), but delays the @@ -31,14 +33,27 @@ The method is documented in: http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt -3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com" and - "ssh-dsa-cert-v00@openssh.com" +1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com", + "ssh-dsa-cert-v00@openssh.com", + "ecdsa-sha2-nistp256-cert-v01@openssh.com", + "ecdsa-sha2-nistp384-cert-v01@openssh.com" and + "ecdsa-sha2-nistp521-cert-v01@openssh.com" -OpenSSH introduces two new public key algorithms to support certificate +OpenSSH introduces new public key algorithms to support certificate authentication for users and hostkeys. These methods are documented in the file PROTOCOL.certkeys -4. connection: Channel write close extension "eow@openssh.com" +1.4. transport: Elliptic Curve cryptography + +OpenSSH supports ECC key exchange and public key authentication as +specified in RFC5656. Only the ecdsa-sha2-nistp256, ecdsa-sha2-nistp384 +and ecdsa-sha2-nistp521 curves over GF(p) are supported. Elliptic +curve points encoded using point compression are NOT accepted or +generated. + +2. Connection protocol changes + +2.1. connection: Channel write close extension "eow@openssh.com" The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF message to allow an endpoint to signal its peer that it will send no @@ -77,8 +92,8 @@ message is only sent to OpenSSH peers (identified by banner). Other SSH implementations may be whitelisted to receive this message upon request. -5. connection: disallow additional sessions extension - "no-more-sessions@openssh.com" +2.2. connection: disallow additional sessions extension + "no-more-sessions@openssh.com" Most SSH connections will only ever request a single session, but a attacker may abuse a running ssh client to surreptitiously open @@ -105,7 +120,7 @@ of this message, the no-more-sessions request is only sent to OpenSSH servers (identified by banner). Other SSH implementations may be whitelisted to receive this message upon request. -6. connection: Tunnel forward extension "tun@openssh.com" +2.3. connection: Tunnel forward extension "tun@openssh.com" OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" channel type. This channel type supports forwarding of network packets @@ -166,7 +181,9 @@ The contents of the "data" field for layer 2 packets is: The "frame" field contains an IEEE 802.3 Ethernet frame, including header. -7. sftp: Reversal of arguments to SSH_FXP_SYMLINK +3. SFTP protocol changes + +3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK When OpenSSH's sftp-server was implemented, the order of the arguments to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, @@ -179,7 +196,7 @@ SSH_FXP_SYMLINK as follows: string targetpath string linkpath -8. sftp: Server extension announcement in SSH_FXP_VERSION +3.2. sftp: Server extension announcement in SSH_FXP_VERSION OpenSSH's sftp-server lists the extensions it supports using the standard extension announcement mechanism in the SSH_FXP_VERSION server @@ -200,7 +217,7 @@ ever changed in an incompatible way. The server MAY advertise the same extension with multiple versions (though this is unlikely). Clients MUST check the version number before attempting to use the extension. -9. sftp: Extension request "posix-rename@openssh.com" +3.3. sftp: Extension request "posix-rename@openssh.com" This operation provides a rename operation with POSIX semantics, which are different to those provided by the standard SSH_FXP_RENAME in @@ -217,7 +234,7 @@ rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. This extension is advertised in the SSH_FXP_VERSION hello with version "1". -10. sftp: Extension requests "statvfs@openssh.com" and +3.4. sftp: Extension requests "statvfs@openssh.com" and "fstatvfs@openssh.com" These requests correspond to the statvfs and fstatvfs POSIX system @@ -258,4 +275,20 @@ The values of the f_flag bitmask are as follows: Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are advertised in the SSH_FXP_VERSION hello with version "2". -$OpenBSD: PROTOCOL,v 1.15 2010/02/26 20:29:54 djm Exp $ +10. sftp: Extension request "hardlink@openssh.com" + +This request is for creating a hard link to a regular file. This +request is implemented as a SSH_FXP_EXTENDED request with the +following format: + + uint32 id + string "hardlink@openssh.com" + string oldpath + string newpath + +On receiving this request the server will perform the operation +link(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. +This extension is advertised in the SSH_FXP_VERSION hello with version +"1". + +$OpenBSD: PROTOCOL,v 1.17 2010/12/04 00:18:01 djm Exp $ diff --git a/PROTOCOL.agent b/PROTOCOL.agent index b34fcd318e13..de94d037d82f 100644 --- a/PROTOCOL.agent +++ b/PROTOCOL.agent @@ -159,8 +159,8 @@ successfully added or a SSH_AGENT_FAILURE if an error occurred. 2.2.3 Add protocol 2 key -The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may -be added using the following request +The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA +keys may be added using the following request byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED @@ -182,6 +182,30 @@ DSA certificates may be added with: string key_comment constraint[] key_constraints +ECDSA keys may be added using the following request + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ecdsa-sha2-nistp256" | + "ecdsa-sha2-nistp384" | + "ecdsa-sha2-nistp521" + string ecdsa_curve_name + string ecdsa_public_key + mpint ecdsa_private + string key_comment + constraint[] key_constraints + +ECDSA certificates may be added with: + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ecdsa-sha2-nistp256-cert-v01@openssh.com" | + "ecdsa-sha2-nistp384-cert-v01@openssh.com" | + "ecdsa-sha2-nistp521-cert-v01@openssh.com" + string certificate + mpint ecdsa_private_key + string key_comment + constraint[] key_constraints + RSA keys may be added with this request: byte SSH2_AGENTC_ADD_IDENTITY or @@ -214,7 +238,7 @@ order to the protocol 1 add keys message. As with the corresponding protocol 1 "add key" request, the private key is overspecified to avoid redundant processing. -For both DSA and RSA key add requests, "key_constraints" may only be +For DSA, ECDSA and RSA key add requests, "key_constraints" may only be present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED. The agent will reply with a SSH_AGENT_SUCCESS if the key has been @@ -294,8 +318,7 @@ Protocol 2 keys may be removed with the following request: string key_blob Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key -Algorithms" for either of the supported key types: "ssh-dss" or -"ssh-rsa". +Algorithms" for any of the supported protocol 2 key types. The agent will delete any private key matching the specified public key and return SSH_AGENT_SUCCESS. If no such key was found, the agent will @@ -364,8 +387,7 @@ Followed by zero or more consecutive keys, encoded as: string key_comment Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key -Algorithms" for either of the supported key types: "ssh-dss" or -"ssh-rsa". +Algorithms" for any of the supported protocol 2 key types. 2.6 Private key operations @@ -429,9 +451,9 @@ a protocol 2 key: uint32 flags Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key -Algorithms" for either of the supported key types: "ssh-dss" or -"ssh-rsa". "flags" is a bit-mask, but at present only one possible value -is defined (see below for its meaning): +Algorithms" for any of the supported protocol 2 key types. "flags" is +a bit-mask, but at present only one possible value is defined (see below +for its meaning): SSH_AGENT_OLD_SIGNATURE 1 @@ -535,4 +557,4 @@ Locking and unlocking affects both protocol 1 and protocol 2 keys. SSH_AGENT_CONSTRAIN_LIFETIME 1 SSH_AGENT_CONSTRAIN_CONFIRM 2 -$OpenBSD: PROTOCOL.agent,v 1.5 2010/02/26 20:29:54 djm Exp $ +$OpenBSD: PROTOCOL.agent,v 1.6 2010/08/31 11:54:45 djm Exp $ diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys index 1d1be13da773..2f97649814b1 100644 --- a/PROTOCOL.certkeys +++ b/PROTOCOL.certkeys @@ -5,31 +5,37 @@ Background ---------- The SSH protocol currently supports a simple public key authentication -mechanism. Unlike other public key implementations, SSH eschews the -use of X.509 certificates and uses raw keys. This approach has some -benefits relating to simplicity of configuration and minimisation -of attack surface, but it does not support the important use-cases -of centrally managed, passwordless authentication and centrally -certified host keys. +mechanism. Unlike other public key implementations, SSH eschews the use +of X.509 certificates and uses raw keys. This approach has some benefits +relating to simplicity of configuration and minimisation of attack +surface, but it does not support the important use-cases of centrally +managed, passwordless authentication and centrally certified host keys. These protocol extensions build on the simple public key authentication -system already in SSH to allow certificate-based authentication. -The certificates used are not traditional X.509 certificates, with -numerous options and complex encoding rules, but something rather -more minimal: a key, some identity information and usage options -that have been signed with some other trusted key. +system already in SSH to allow certificate-based authentication. The +certificates used are not traditional X.509 certificates, with numerous +options and complex encoding rules, but something rather more minimal: a +key, some identity information and usage options that have been signed +with some other trusted key. A sshd server may be configured to allow authentication via certified -keys, by extending the existing ~/.ssh/authorized_keys mechanism -to allow specification of certification authority keys in addition -to raw user keys. The ssh client will support automatic verification -of acceptance of certified host keys, by adding a similar ability -to specify CA keys in ~/.ssh/known_hosts. +keys, by extending the existing ~/.ssh/authorized_keys mechanism to +allow specification of certification authority keys in addition to +raw user keys. The ssh client will support automatic verification of +acceptance of certified host keys, by adding a similar ability to +specify CA keys in ~/.ssh/known_hosts. -Certified keys are represented using two new key types: -ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com that -include certification information along with the public key that is used -to sign challenges. ssh-keygen performs the CA signing operation. +Certified keys are represented using new key types: + + ssh-rsa-cert-v01@openssh.com + ssh-dss-cert-v01@openssh.com + ecdsa-sha2-nistp256-cert-v01@openssh.com + ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com + +These include certification information along with the public key +that is used to sign challenges. ssh-keygen performs the CA signing +operation. Protocol extensions ------------------- @@ -47,10 +53,9 @@ in RFC4252 section 7. New public key formats ---------------------- -The ssh-rsa-cert-v01@openssh.com and ssh-dss-cert-v01@openssh.com key -types take a similar high-level format (note: data types and -encoding are as per RFC4251 section 5). The serialised wire encoding of -these certificates is also used for storing them on disk. +The certificate key types take a similar high-level format (note: data +types and encoding are as per RFC4251 section 5). The serialised wire +encoding of these certificates is also used for storing them on disk. #define SSH_CERT_TYPE_USER 1 #define SSH_CERT_TYPE_HOST 2 @@ -93,6 +98,26 @@ DSA certificate string signature key string signature +ECDSA certificate + + string "ecdsa-sha2-nistp256@openssh.com" | + "ecdsa-sha2-nistp384@openssh.com" | + "ecdsa-sha2-nistp521@openssh.com" + string nonce + string curve + string public_key + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + The nonce field is a CA-provided random bitstring of arbitrary length (but typically 16 or 32 bytes) included to make attacks that depend on inducing collisions in the signature hash infeasible. @@ -101,6 +126,9 @@ e and n are the RSA exponent and public modulus respectively. p, q, g, y are the DSA parameters as described in FIPS-186-2. +curve and public key are respectively the ECDSA "[identifier]" and "Q" +defined in section 3.1 of RFC5656. + serial is an optional certificate serial number set by the CA to provide an abbreviated way to refer to certificates from that CA. If a CA does not wish to number its certificates it must set this @@ -123,7 +151,8 @@ any principal of the specified type. XXX DNS wildcards? "valid after" and "valid before" specify a validity period for the certificate. Each represents a time in seconds since 1970-01-01 00:00:00. A certificate is considered valid if: - valid after <= current time < valid before + + valid after <= current time < valid before criticial options is a set of zero or more key options encoded as below. All such options are "critical" in the sense that an implementation @@ -137,15 +166,17 @@ The reserved field is currently unused and is ignored in this version of the protocol. signature key contains the CA key used to sign the certificate. -The valid key types for CA keys are ssh-rsa and ssh-dss. "Chained" +The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types +ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where the signature key type is a certificate type itself are NOT supported. Note that it is possible for a RSA certificate key to -be signed by a DSS CA key and vice-versa. +be signed by a DSS or ECDSA CA key and vice-versa. signature is computed over all preceding fields from the initial string up to, and including the signature key. Signatures are computed and encoded according to the rules defined for the CA's public key algorithm -(RFC4253 section 6.6 for ssh-rsa and ssh-dss). +(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA +types). Critical options ---------------- @@ -222,4 +253,4 @@ permit-user-rc empty Flag indicating that execution of of this script will not be permitted if this option is not present. -$OpenBSD: PROTOCOL.certkeys,v 1.7 2010/08/04 05:40:39 djm Exp $ +$OpenBSD: PROTOCOL.certkeys,v 1.8 2010/08/31 11:54:45 djm Exp $ diff --git a/PROTOCOL.mux b/PROTOCOL.mux index 1d8c463a7477..3d6f81878588 100644 --- a/PROTOCOL.mux +++ b/PROTOCOL.mux @@ -28,7 +28,7 @@ defined. To open a new multiplexed session, a client may send the following request: - uint32 MUX_C_MSG_NEW_SESSION + uint32 MUX_C_NEW_SESSION uint32 request id string reserved bool want tty flag @@ -99,7 +99,7 @@ The server will reply with one of MUX_S_OK or MUX_S_PERMISSION_DENIED. A client may request the master to establish a port forward: - uint32 MUX_C_OPEN_FORWARD + uint32 MUX_C_OPEN_FWD uint32 request id uint32 forwarding type string listen host @@ -118,24 +118,23 @@ For dynamically allocated listen port the server replies with uint32 client request id uint32 allocated remote listen port -5. Requesting closure of port forwards +6. Requesting closure of port forwards + +Note: currently unimplemented (server will always reply with MUX_S_FAILURE). A client may request the master to establish a port forward: - uint32 MUX_C_OPEN_FORWARD + uint32 MUX_C_CLOSE_FWD uint32 request id - uint32 forwarding type string listen host string listen port string connect host string connect port -forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. - A server may reply with a MUX_S_OK, a MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. -6. Requesting stdio forwarding +7. Requesting stdio forwarding A client may request the master to establish a stdio forwarding: @@ -153,7 +152,7 @@ The contents of "reserved" are currently ignored. A server may reply with a MUX_S_SESSION_OPEED, a MUX_S_PERMISSION_DENIED or a MUX_S_FAILURE. -7. Status messages +8. Status messages The MUX_S_OK message is empty: @@ -170,14 +169,15 @@ The MUX_S_PERMISSION_DENIED and MUX_S_FAILURE include a reason: uint32 client request id string reason -7. Protocol numbers +9. Protocol numbers #define MUX_MSG_HELLO 0x00000001 #define MUX_C_NEW_SESSION 0x10000002 #define MUX_C_ALIVE_CHECK 0x10000004 #define MUX_C_TERMINATE 0x10000005 -#define MUX_C_OPEN_FORWARD 0x10000006 -#define MUX_C_CLOSE_FORWARD 0x10000007 +#define MUX_C_OPEN_FWD 0x10000006 +#define MUX_C_CLOSE_FWD 0x10000007 +#define MUX_C_NEW_STDIO_FWD 0x10000008 #define MUX_S_OK 0x80000001 #define MUX_S_PERMISSION_DENIED 0x80000002 #define MUX_S_FAILURE 0x80000003 @@ -200,4 +200,4 @@ XXX server->client error/warning notifications XXX port0 rfwd (need custom response message) XXX send signals via mux -$OpenBSD: PROTOCOL.mux,v 1.2 2010/05/16 12:55:51 markus Exp $ +$OpenBSD: PROTOCOL.mux,v 1.3 2011/01/13 21:55:25 djm Exp $ diff --git a/README b/README index 4eaa5458814f..4e7e9a9f2c5d 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-5.6 for the release notes. +See http://www.openssh.com/txt/release-5.7 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html @@ -62,4 +62,4 @@ References - [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [7] http://www.openssh.com/faq.html -$Id: README,v 1.74 2010/08/08 16:32:06 djm Exp $ +$Id: README,v 1.75 2011/01/22 09:23:12 djm Exp $ diff --git a/atomicio.c b/atomicio.c index a6b2d127a9b8..601b3c371c21 100644 --- a/atomicio.c +++ b/atomicio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */ +/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 djm Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -48,7 +48,8 @@ * ensure all of data on socket comes through. f==read || f==vwrite */ size_t -atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, + int (*cb)(void *, size_t), void *cb_arg) { char *s = _s; size_t pos = 0; @@ -73,17 +74,28 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) return pos; default: pos += (size_t)res; + if (cb != NULL && cb(cb_arg, (size_t)res) == -1) { + errno = EINTR; + return pos; + } } } - return (pos); + return pos; +} + +size_t +atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +{ + return atomicio6(f, fd, _s, n, NULL, NULL); } /* * ensure all of data on socket comes through. f==readv || f==writev */ size_t -atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, - const struct iovec *_iov, int iovcnt) +atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, + const struct iovec *_iov, int iovcnt, + int (*cb)(void *, size_t), void *cb_arg) { size_t pos = 0, rem; ssize_t res; @@ -137,6 +149,17 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, iov[0].iov_base = ((char *)iov[0].iov_base) + rem; iov[0].iov_len -= rem; } + if (cb != NULL && cb(cb_arg, (size_t)res) == -1) { + errno = EINTR; + return pos; + } } return pos; } + +size_t +atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, + const struct iovec *_iov, int iovcnt) +{ + return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL); +} diff --git a/atomicio.h b/atomicio.h index 2fcd25d43269..0d728ac86ea9 100644 --- a/atomicio.h +++ b/atomicio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.h,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: atomicio.h,v 1.11 2010/09/22 22:58:51 djm Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. @@ -32,6 +32,9 @@ /* * Ensure all of data on socket comes through. f==read || f==vwrite */ +size_t +atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n, + int (*cb)(void *, size_t), void *); size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); #define vwrite (ssize_t (*)(int, void *, size_t))write @@ -39,6 +42,9 @@ size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); /* * ensure all of data on socket comes through. f==readv || f==writev */ +size_t +atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, + const struct iovec *_iov, int iovcnt, int (*cb)(void *, size_t), void *); size_t atomiciov(ssize_t (*)(int, const struct iovec *, int), int, const struct iovec *, int); diff --git a/audit-bsm.c b/audit-bsm.c index 2c417bc27ca0..f196d4f1e814 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -1,4 +1,4 @@ -/* $Id: audit-bsm.c,v 1.6 2008/02/25 10:05:04 dtucker Exp $ */ +/* $Id: audit-bsm.c,v 1.7 2011/01/17 10:15:29 dtucker Exp $ */ /* * TODO @@ -305,13 +305,13 @@ audit_run_command(const char *command) } void -audit_session_open(const char *ttyn) +audit_session_open(struct logininfo *li) { /* not implemented */ } void -audit_session_close(const char *ttyn) +audit_session_close(struct logininfo *li) { /* not implemented */ } diff --git a/audit-linux.c b/audit-linux.c new file mode 100644 index 000000000000..20174d700a5d --- /dev/null +++ b/audit-linux.c @@ -0,0 +1,126 @@ +/* $Id$ */ + +/* + * Copyright 2010 Red Hat, Inc. All rights reserved. + * Use is subject to license terms. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Red Hat author: Jan F. Chadima + */ + +#include "includes.h" +#if defined(USE_LINUX_AUDIT) +#include +#include +#include + +#include "log.h" +#include "audit.h" +#include "canohost.h" + +const char* audit_username(void); + +int +linux_audit_record_event(int uid, const char *username, + const char *hostname, const char *ip, const char *ttyn, int success) +{ + int audit_fd, rc, saved_errno; + + audit_fd = audit_open(); + if (audit_fd < 0) { + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return 1; /* No audit support in kernel */ + else + return 0; /* Must prevent login */ + } + rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, + NULL, "login", username ? username : "(unknown)", + username == NULL ? uid : -1, hostname, ip, ttyn, success); + saved_errno = errno; + close(audit_fd); + /* + * Do not report error if the error is EPERM and sshd is run as non + * root user. + */ + if ((rc == -EPERM) && (geteuid() != 0)) + rc = 0; + errno = saved_errno; + return (rc >= 0); +} + +/* Below is the sshd audit API code */ + +void +audit_connection_from(const char *host, int port) +{ +} + /* not implemented */ + +void +audit_run_command(const char *command) +{ + /* not implemented */ +} + +void +audit_session_open(struct logininfo *li) +{ + if (linux_audit_record_event(li->uid, NULL, li->hostname, + NULL, li->line, 1) == 0) + fatal("linux_audit_write_entry failed: %s", strerror(errno)); +} + +void +audit_session_close(struct logininfo *li) +{ + /* not implemented */ +} + +void +audit_event(ssh_audit_event_t event) +{ + switch(event) { + case SSH_AUTH_SUCCESS: + case SSH_CONNECTION_CLOSE: + case SSH_NOLOGIN: + case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_LOGIN_ROOT_DENIED: + break; + + case SSH_AUTH_FAIL_NONE: + case SSH_AUTH_FAIL_PASSWD: + case SSH_AUTH_FAIL_KBDINT: + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: + case SSH_INVALID_USER: + linux_audit_record_event(-1, audit_username(), NULL, + get_remote_ipaddr(), "sshd", 0); + break; + + default: + debug("%s: unhandled event %d", __func__, event); + } +} + +#endif /* USE_LINUX_AUDIT */ diff --git a/audit.c b/audit.c index dbea34cb23f6..ced57fa64c46 100644 --- a/audit.c +++ b/audit.c @@ -1,4 +1,4 @@ -/* $Id: audit.c,v 1.5 2006/09/01 05:38:36 djm Exp $ */ +/* $Id: audit.c,v 1.6 2011/01/17 10:15:30 dtucker Exp $ */ /* * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. @@ -147,9 +147,9 @@ audit_event(ssh_audit_event_t event) * within a single connection. */ void -audit_session_open(const char *ttyn) +audit_session_open(struct logininfo *li) { - const char *t = ttyn ? ttyn : "(no tty)"; + const char *t = li->line ? li->line : "(no tty)"; debug("audit session open euid %d user %s tty name %s", geteuid(), audit_username(), t); @@ -163,9 +163,9 @@ audit_session_open(const char *ttyn) * within a single connection. */ void -audit_session_close(const char *ttyn) +audit_session_close(struct logininfo *li) { - const char *t = ttyn ? ttyn : "(no tty)"; + const char *t = li->line ? li->line : "(no tty)"; debug("audit session close euid %d user %s tty name %s", geteuid(), audit_username(), t); diff --git a/audit.h b/audit.h index 695f723549ea..92ede5bc4728 100644 --- a/audit.h +++ b/audit.h @@ -1,4 +1,4 @@ -/* $Id: audit.h,v 1.3 2006/08/05 14:05:10 dtucker Exp $ */ +/* $Id: audit.h,v 1.4 2011/01/17 10:15:30 dtucker Exp $ */ /* * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. @@ -26,6 +26,9 @@ #ifndef _SSH_AUDIT_H # define _SSH_AUDIT_H + +#include "loginrec.h" + enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, SSH_LOGIN_ROOT_DENIED, @@ -46,8 +49,8 @@ typedef enum ssh_audit_event_type ssh_audit_event_t; void audit_connection_from(const char *, int); void audit_event(ssh_audit_event_t); -void audit_session_open(const char *); -void audit_session_close(const char *); +void audit_session_open(struct logininfo *); +void audit_session_close(struct logininfo *); void audit_run_command(const char *); ssh_audit_event_t audit_classify_auth(const char *); diff --git a/auth-options.c b/auth-options.c index a7040247fe67..eae45cf2b4fc 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.52 2010/05/20 23:46:02 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.54 2010/12/24 21:41:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -172,7 +172,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) goto bad_option; } forced_command[i] = '\0'; - auth_debug_add("Forced command: %.900s", forced_command); + auth_debug_add("Forced command."); opts++; goto next_option; } @@ -444,7 +444,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, buffer_append(&c, optblob, optblob_len); while (buffer_len(&c) > 0) { - if ((name = buffer_get_string_ret(&c, &nlen)) == NULL || + if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL || (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { error("Certificate options corrupt"); goto out; @@ -479,7 +479,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, } if (!found && (which & OPTIONS_CRITICAL) != 0) { if (strcmp(name, "force-command") == 0) { - if ((command = buffer_get_string_ret(&data, + if ((command = buffer_get_cstring_ret(&data, &clen)) == NULL) { error("Certificate constraint \"%s\" " "corrupt", name); @@ -500,7 +500,7 @@ parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw, found = 1; } if (strcmp(name, "source-address") == 0) { - if ((allowed = buffer_get_string_ret(&data, + if ((allowed = buffer_get_cstring_ret(&data, &clen)) == NULL) { error("Certificate constraint " "\"%s\" corrupt", name); diff --git a/auth-rsa.c b/auth-rsa.c index 56702d130f9c..4edaab056aa0 100644 --- a/auth-rsa.c +++ b/auth-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rsa.c,v 1.78 2010/07/13 23:13:16 djm Exp $ */ +/* $OpenBSD: auth-rsa.c,v 1.79 2010/12/03 23:55:27 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -94,9 +94,6 @@ auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) MD5_CTX md; int len; - if (auth_key_is_revoked(key)) - return 0; - /* don't allow short keys */ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", @@ -249,6 +246,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); + /* Never accept a revoked key */ + if (auth_key_is_revoked(key)) + break; + /* We have found the desired key. */ /* * If our options do not allow this key to be used, diff --git a/auth.c b/auth.c index dba1e6555ebd..33680b91bfec 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.89 2010/08/04 05:42:47 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.91 2010/11/29 23:45:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -379,16 +379,15 @@ HostStatus check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, const char *sysfile, const char *userfile) { - Key *found; char *user_hostfile; struct stat st; HostStatus host_status; + struct hostkeys *hostkeys; + const struct hostkey_entry *found; - /* Check if we know the host and its host key. */ - found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); - host_status = check_host_in_hostfile(sysfile, host, key, found, NULL); - - if (host_status != HOST_OK && userfile != NULL) { + hostkeys = init_hostkeys(); + load_hostkeys(hostkeys, host, sysfile); + if (userfile != NULL) { user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); if (options.strict_modes && (stat(user_hostfile, &st) == 0) && @@ -401,16 +400,23 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, user_hostfile); } else { temporarily_use_uid(pw); - host_status = check_host_in_hostfile(user_hostfile, - host, key, found, NULL); + load_hostkeys(hostkeys, host, user_hostfile); restore_uid(); } xfree(user_hostfile); } - key_free(found); + host_status = check_key_in_hostkeys(hostkeys, key, &found); + if (host_status == HOST_REVOKED) + error("WARNING: revoked key for %s attempted authentication", + found->host); + else if (host_status == HOST_OK) + debug("%s: key for %s found at %s:%ld", __func__, + found->host, found->file, found->line); + else + debug("%s: key for host %s not found", __func__, host); + + free_hostkeys(hostkeys); - debug2("check_key_in_hostfiles: key %s for %s", host_status == HOST_OK ? - "ok" : "not found", host); return host_status; } @@ -518,7 +524,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes, close(fd); return NULL; } - if (options.strict_modes && + if (strict_modes && secure_filename(f, file, pw, line, sizeof(line)) != 0) { fclose(f); logit("Authentication refused: %s", line); diff --git a/auth1.c b/auth1.c index bf442dbf6e7b..cc85aec74032 100644 --- a/auth1.c +++ b/auth1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth1.c,v 1.74 2010/06/25 08:46:17 djm Exp $ */ +/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -167,7 +167,7 @@ auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen) * trust the client; root on the client machine can * claim to be any user. */ - client_user = packet_get_string(&ulen); + client_user = packet_get_cstring(&ulen); /* Get the client host key. */ client_host_key = key_new(KEY_RSA1); @@ -389,7 +389,7 @@ do_authentication(Authctxt *authctxt) packet_read_expect(SSH_CMSG_USER); /* Get the user name. */ - user = packet_get_string(&ulen); + user = packet_get_cstring(&ulen); packet_check_eom(); if ((style = strchr(user, ':')) != NULL) diff --git a/auth2-jpake.c b/auth2-jpake.c index 5de5506a6641..a460e8216253 100644 --- a/auth2-jpake.c +++ b/auth2-jpake.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-jpake.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */ +/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */ /* * Copyright (c) 2008 Damien Miller. All rights reserved. * @@ -162,6 +162,11 @@ derive_rawsalt(const char *username, u_char *rawsalt, u_int len) fatal("%s: DSA key missing priv_key", __func__); buffer_put_bignum2(&b, k->dsa->priv_key); break; + case KEY_ECDSA: + if (EC_KEY_get0_private_key(k->ecdsa) == NULL) + fatal("%s: ECDSA key missing priv_key", __func__); + buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa)); + break; default: fatal("%s: unknown key type %d", __func__, k->type); } diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 35cf79c9f783..7d2141355994 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.26 2010/06/29 23:16:46 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.27 2010/11/20 05:12:38 deraadt Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -232,7 +232,7 @@ match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert) if ((ep = strrchr(cp, ' ')) != NULL || (ep = strrchr(cp, '\t')) != NULL) { for (; *ep == ' ' || *ep == '\t'; ep++) - ;; + ; line_opts = cp; cp = ep; } diff --git a/auth2.c b/auth2.c index 5d54685596c8..95820f96fa08 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */ +/* $OpenBSD: auth2.c,v 1.122 2010/08/31 09:58:37 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -182,7 +182,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt) Authctxt *authctxt = ctxt; u_int len; int acceptit = 0; - char *service = packet_get_string(&len); + char *service = packet_get_cstring(&len); packet_check_eom(); if (authctxt == NULL) @@ -221,9 +221,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) if (authctxt == NULL) fatal("input_userauth_request: no authctxt"); - user = packet_get_string(NULL); - service = packet_get_string(NULL); - method = packet_get_string(NULL); + user = packet_get_cstring(NULL); + service = packet_get_cstring(NULL); + method = packet_get_cstring(NULL); debug("userauth-request for user %s service %s method %s", user, service, method); debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); diff --git a/authfd.c b/authfd.c index 739722fbfba8..c11c3f5a828b 100644 --- a/authfd.c +++ b/authfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.c,v 1.83 2010/04/16 01:47:26 djm Exp $ */ +/* $OpenBSD: authfd.c,v 1.84 2010/08/31 11:54:45 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -509,6 +509,21 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) buffer_len(&key->cert->certblob)); buffer_put_bignum2(b, key->dsa->priv_key); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); + buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), + EC_KEY_get0_public_key(key->ecdsa)); + buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); + break; + case KEY_ECDSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); + break; +#endif } buffer_put_cstring(b, comment); } @@ -541,6 +556,8 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, case KEY_DSA: case KEY_DSA_CERT: case KEY_DSA_CERT_V00: + case KEY_ECDSA: + case KEY_ECDSA_CERT: type = constrained ? SSH2_AGENTC_ADD_ID_CONSTRAINED : SSH2_AGENTC_ADD_IDENTITY; @@ -589,7 +606,8 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key) buffer_put_bignum(&msg, key->rsa->e); buffer_put_bignum(&msg, key->rsa->n); } else if (key_type_plain(key->type) == KEY_DSA || - key_type_plain(key->type) == KEY_RSA) { + key_type_plain(key->type) == KEY_RSA || + key_type_plain(key->type) == KEY_ECDSA) { key_to_blob(key, &blob, &blen); buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); buffer_put_string(&msg, blob, blen); diff --git a/authfile.c b/authfile.c index 2bd887845cc0..f2aec267a5a6 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */ +/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -74,19 +74,18 @@ static const char authfile_id_string[] = "SSH PRIVATE KEY FILE FORMAT 1.1\n"; /* - * Saves the authentication (private) key in a file, encrypting it with - * passphrase. The identification of the file (lowest 64 bits of n) will + * Serialises the authentication (private) key to a blob, encrypting it with + * passphrase. The identification of the blob (lowest 64 bits of n) will * precede the key to provide identification of the key without needing a * passphrase. */ - static int -key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, +key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, const char *comment) { Buffer buffer, encrypted; u_char buf[100], *cp; - int fd, i, cipher_num; + int i, cipher_num; CipherContext ciphercontext; Cipher *cipher; u_int32_t rnd; @@ -157,88 +156,200 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, memset(buf, 0, sizeof(buf)); buffer_free(&buffer); - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { - error("open %s failed: %s.", filename, strerror(errno)); - buffer_free(&encrypted); - return 0; - } - if (atomicio(vwrite, fd, buffer_ptr(&encrypted), - buffer_len(&encrypted)) != buffer_len(&encrypted)) { - error("write to key file %s failed: %s", filename, - strerror(errno)); - buffer_free(&encrypted); - close(fd); - unlink(filename); - return 0; - } - close(fd); + buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); buffer_free(&encrypted); + return 1; } -/* save SSH v2 key in OpenSSL PEM format */ +/* convert SSH v2 key in OpenSSL PEM format */ static int -key_save_private_pem(Key *key, const char *filename, const char *_passphrase, +key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase, const char *comment) { - FILE *fp; - int fd; int success = 0; - int len = strlen(_passphrase); + int blen, len = strlen(_passphrase); u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; #if (OPENSSL_VERSION_NUMBER < 0x00907000L) const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; #else const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; #endif + const u_char *bptr; + BIO *bio; if (len > 0 && len <= 4) { error("passphrase too short: have %d bytes, need > 4", len); return 0; } - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) { - error("open %s failed: %s.", filename, strerror(errno)); - return 0; - } - fp = fdopen(fd, "w"); - if (fp == NULL) { - error("fdopen %s failed: %s.", filename, strerror(errno)); - close(fd); + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + error("%s: BIO_new failed", __func__); return 0; } switch (key->type) { case KEY_DSA: - success = PEM_write_DSAPrivateKey(fp, key->dsa, + success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, cipher, passphrase, len, NULL, NULL); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, + cipher, passphrase, len, NULL, NULL); + break; +#endif case KEY_RSA: - success = PEM_write_RSAPrivateKey(fp, key->rsa, + success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, cipher, passphrase, len, NULL, NULL); break; } - fclose(fp); + if (success) { + if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) + success = 0; + else + buffer_append(blob, bptr, blen); + } + BIO_free(bio); return success; } +/* Save a key blob to a file */ +static int +key_save_private_blob(Buffer *keybuf, const char *filename) +{ + int fd; + + if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { + error("open %s failed: %s.", filename, strerror(errno)); + return 0; + } + if (atomicio(vwrite, fd, buffer_ptr(keybuf), + buffer_len(keybuf)) != buffer_len(keybuf)) { + error("write to key file %s failed: %s", filename, + strerror(errno)); + close(fd); + unlink(filename); + return 0; + } + close(fd); + return 1; +} + +/* Serialise "key" to buffer "blob" */ +static int +key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, + const char *comment) +{ + switch (key->type) { + case KEY_RSA1: + return key_private_rsa1_to_blob(key, blob, passphrase, comment); + case KEY_DSA: + case KEY_ECDSA: + case KEY_RSA: + return key_private_pem_to_blob(key, blob, passphrase, comment); + default: + error("%s: cannot save key type %d", __func__, key->type); + return 0; + } +} + int key_save_private(Key *key, const char *filename, const char *passphrase, const char *comment) { - switch (key->type) { - case KEY_RSA1: - return key_save_private_rsa1(key, filename, passphrase, - comment); - case KEY_DSA: - case KEY_RSA: - return key_save_private_pem(key, filename, passphrase, - comment); - default: - break; + Buffer keyblob; + int success = 0; + + buffer_init(&keyblob); + if (!key_private_to_blob(key, &keyblob, passphrase, comment)) + goto out; + if (!key_save_private_blob(&keyblob, filename)) + goto out; + success = 1; + out: + buffer_free(&keyblob); + return success; +} + +/* + * Parse the public, unencrypted portion of a RSA1 key. + */ +static Key * +key_parse_public_rsa1(Buffer *blob, char **commentp) +{ + Key *pub; + + /* Check that it is at least big enough to contain the ID string. */ + if (buffer_len(blob) < sizeof(authfile_id_string)) { + debug3("Truncated RSA1 identifier"); + return NULL; } - error("key_save_private: cannot save key type %d", key->type); - return 0; + + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + if (memcmp(buffer_ptr(blob), authfile_id_string, + sizeof(authfile_id_string)) != 0) { + debug3("Incorrect RSA1 identifier"); + return NULL; + } + buffer_consume(blob, sizeof(authfile_id_string)); + + /* Skip cipher type and reserved data. */ + (void) buffer_get_char(blob); /* cipher type */ + (void) buffer_get_int(blob); /* reserved */ + + /* Read the public key from the buffer. */ + (void) buffer_get_int(blob); + pub = key_new(KEY_RSA1); + buffer_get_bignum(blob, pub->rsa->n); + buffer_get_bignum(blob, pub->rsa->e); + if (commentp) + *commentp = buffer_get_string(blob, NULL); + /* The encrypted private part is not parsed by this function. */ + buffer_clear(blob); + + return pub; +} + +/* Load the contents of a key file into a buffer */ +static int +key_load_file(int fd, const char *filename, Buffer *blob) +{ + size_t len; + u_char *cp; + struct stat st; + + if (fstat(fd, &st) < 0) { + error("%s: fstat of key file %.200s%sfailed: %.100s", __func__, + filename == NULL ? "" : filename, + filename == NULL ? "" : " ", + strerror(errno)); + close(fd); + return 0; + } + if (st.st_size > 1*1024*1024) { + error("%s: key file %.200s%stoo large", __func__, + filename == NULL ? "" : filename, + filename == NULL ? "" : " "); + close(fd); + return 0; + } + len = (size_t)st.st_size; /* truncated */ + + buffer_init(blob); + cp = buffer_append_space(blob, len); + + if (atomicio(read, fd, cp, len) != len) { + debug("%s: read from key file %.200s%sfailed: %.100s", __func__, + filename == NULL ? "" : filename, + filename == NULL ? "" : " ", + strerror(errno)); + buffer_clear(blob); + close(fd); + return 0; + } + return 1; } /* @@ -246,67 +357,21 @@ key_save_private(Key *key, const char *filename, const char *passphrase, * encountered (the file does not exist or is not readable), and the key * otherwise. */ - static Key * key_load_public_rsa1(int fd, const char *filename, char **commentp) { Buffer buffer; Key *pub; - struct stat st; - char *cp; - u_int i; - size_t len; - - if (fstat(fd, &st) < 0) { - error("fstat for key file %.200s failed: %.100s", - filename, strerror(errno)); - return NULL; - } - if (st.st_size > 1*1024*1024) { - error("key file %.200s too large", filename); - return NULL; - } - len = (size_t)st.st_size; /* truncated */ buffer_init(&buffer); - cp = buffer_append_space(&buffer, len); - - if (atomicio(read, fd, cp, len) != len) { - debug("Read from key file %.200s failed: %.100s", filename, - strerror(errno)); + if (!key_load_file(fd, filename, &buffer)) { buffer_free(&buffer); return NULL; } - /* Check that it is at least big enough to contain the ID string. */ - if (len < sizeof(authfile_id_string)) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - return NULL; - } - /* - * Make sure it begins with the id string. Consume the id string - * from the buffer. - */ - for (i = 0; i < sizeof(authfile_id_string); i++) - if (buffer_get_char(&buffer) != authfile_id_string[i]) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - return NULL; - } - /* Skip cipher type and reserved data. */ - (void) buffer_get_char(&buffer); /* cipher type */ - (void) buffer_get_int(&buffer); /* reserved */ - - /* Read the public key from the buffer. */ - (void) buffer_get_int(&buffer); - pub = key_new(KEY_RSA1); - buffer_get_bignum(&buffer, pub->rsa->n); - buffer_get_bignum(&buffer, pub->rsa->e); - if (commentp) - *commentp = buffer_get_string(&buffer, NULL); - /* The encrypted private part is not parsed by this function. */ - + pub = key_parse_public_rsa1(&buffer, commentp); + if (pub == NULL) + debug3("Could not load \"%s\" as a RSA1 public key", filename); buffer_free(&buffer); return pub; } @@ -329,113 +394,73 @@ key_load_public_type(int type, const char *filename, char **commentp) return NULL; } -/* - * Loads the private key from the file. Returns 0 if an error is encountered - * (file does not exist or is not readable, or passphrase is bad). This - * initializes the private key. - * Assumes we are called under uid of the owner of the file. - */ - static Key * -key_load_private_rsa1(int fd, const char *filename, const char *passphrase, - char **commentp) +key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) { - u_int i; int check1, check2, cipher_type; - size_t len; - Buffer buffer, decrypted; + Buffer decrypted; u_char *cp; CipherContext ciphercontext; Cipher *cipher; Key *prv = NULL; - struct stat st; - - if (fstat(fd, &st) < 0) { - error("fstat for key file %.200s failed: %.100s", - filename, strerror(errno)); - close(fd); - return NULL; - } - if (st.st_size > 1*1024*1024) { - error("key file %.200s too large", filename); - close(fd); - return (NULL); - } - len = (size_t)st.st_size; /* truncated */ - - buffer_init(&buffer); - cp = buffer_append_space(&buffer, len); - - if (atomicio(read, fd, cp, len) != len) { - debug("Read from key file %.200s failed: %.100s", filename, - strerror(errno)); - buffer_free(&buffer); - close(fd); - return NULL; - } /* Check that it is at least big enough to contain the ID string. */ - if (len < sizeof(authfile_id_string)) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - close(fd); + if (buffer_len(blob) < sizeof(authfile_id_string)) { + debug3("Truncated RSA1 identifier"); return NULL; } + /* * Make sure it begins with the id string. Consume the id string * from the buffer. */ - for (i = 0; i < sizeof(authfile_id_string); i++) - if (buffer_get_char(&buffer) != authfile_id_string[i]) { - debug3("Not a RSA1 key file %.200s.", filename); - buffer_free(&buffer); - close(fd); - return NULL; - } + if (memcmp(buffer_ptr(blob), authfile_id_string, + sizeof(authfile_id_string)) != 0) { + debug3("Incorrect RSA1 identifier"); + return NULL; + } + buffer_consume(blob, sizeof(authfile_id_string)); /* Read cipher type. */ - cipher_type = buffer_get_char(&buffer); - (void) buffer_get_int(&buffer); /* Reserved data. */ + cipher_type = buffer_get_char(blob); + (void) buffer_get_int(blob); /* Reserved data. */ /* Read the public key from the buffer. */ - (void) buffer_get_int(&buffer); + (void) buffer_get_int(blob); prv = key_new_private(KEY_RSA1); - buffer_get_bignum(&buffer, prv->rsa->n); - buffer_get_bignum(&buffer, prv->rsa->e); + buffer_get_bignum(blob, prv->rsa->n); + buffer_get_bignum(blob, prv->rsa->e); if (commentp) - *commentp = buffer_get_string(&buffer, NULL); + *commentp = buffer_get_string(blob, NULL); else - xfree(buffer_get_string(&buffer, NULL)); + (void)buffer_get_string_ptr(blob, NULL); /* Check that it is a supported cipher. */ cipher = cipher_by_number(cipher_type); if (cipher == NULL) { - debug("Unsupported cipher %d used in key file %.200s.", - cipher_type, filename); - buffer_free(&buffer); + debug("Unsupported RSA1 cipher %d", cipher_type); goto fail; } /* Initialize space for decrypted data. */ buffer_init(&decrypted); - cp = buffer_append_space(&decrypted, buffer_len(&buffer)); + cp = buffer_append_space(&decrypted, buffer_len(blob)); /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ cipher_set_key_string(&ciphercontext, cipher, passphrase, CIPHER_DECRYPT); cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer)); + buffer_ptr(blob), buffer_len(blob)); cipher_cleanup(&ciphercontext); memset(&ciphercontext, 0, sizeof(ciphercontext)); - buffer_free(&buffer); + buffer_clear(blob); check1 = buffer_get_char(&decrypted); check2 = buffer_get_char(&decrypted); if (check1 != buffer_get_char(&decrypted) || check2 != buffer_get_char(&decrypted)) { if (strcmp(passphrase, "") != 0) - debug("Bad passphrase supplied for key file %.200s.", - filename); + debug("Bad passphrase supplied for RSA1 key"); /* Bad passphrase. */ buffer_free(&decrypted); goto fail; @@ -454,38 +479,37 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase, /* enable blinding */ if (RSA_blinding_on(prv->rsa, NULL) != 1) { - error("key_load_private_rsa1: RSA_blinding_on failed"); + error("%s: RSA_blinding_on failed", __func__); goto fail; } - close(fd); return prv; fail: if (commentp) xfree(*commentp); - close(fd); key_free(prv); return NULL; } -Key * -key_load_private_pem(int fd, int type, const char *passphrase, +static Key * +key_parse_private_pem(Buffer *blob, int type, const char *passphrase, char **commentp) { - FILE *fp; EVP_PKEY *pk = NULL; Key *prv = NULL; char *name = ""; + BIO *bio; - fp = fdopen(fd, "r"); - if (fp == NULL) { - error("fdopen failed: %s", strerror(errno)); - close(fd); + if ((bio = BIO_new_mem_buf(buffer_ptr(blob), + buffer_len(blob))) == NULL) { + error("%s: BIO_new_mem_buf failed", __func__); return NULL; } - pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); + + pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase); + BIO_free(bio); if (pk == NULL) { - debug("PEM_read_PrivateKey failed"); + debug("%s: PEM_read_PrivateKey failed", __func__); (void)ERR_get_error(); } else if (pk->type == EVP_PKEY_RSA && (type == KEY_UNSPEC||type==KEY_RSA)) { @@ -497,7 +521,7 @@ key_load_private_pem(int fd, int type, const char *passphrase, RSA_print_fp(stderr, prv->rsa, 8); #endif if (RSA_blinding_on(prv->rsa, NULL) != 1) { - error("key_load_private_pem: RSA_blinding_on failed"); + error("%s: RSA_blinding_on failed", __func__); key_free(prv); prv = NULL; } @@ -510,11 +534,31 @@ key_load_private_pem(int fd, int type, const char *passphrase, #ifdef DEBUG_PK DSA_print_fp(stderr, prv->dsa, 8); #endif +#ifdef OPENSSL_HAS_ECC + } else if (pk->type == EVP_PKEY_EC && + (type == KEY_UNSPEC||type==KEY_ECDSA)) { + prv = key_new(KEY_UNSPEC); + prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); + prv->type = KEY_ECDSA; + if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 || + key_curve_nid_to_name(prv->ecdsa_nid) == NULL || + key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), + EC_KEY_get0_public_key(prv->ecdsa)) != 0 || + key_ec_validate_private(prv->ecdsa) != 0) { + error("%s: bad ECDSA key", __func__); + key_free(prv); + prv = NULL; + } + name = "ecdsa w/o comment"; +#ifdef DEBUG_PK + if (prv != NULL && prv->ecdsa != NULL) + key_dump_ec_key(prv->ecdsa); +#endif +#endif /* OPENSSL_HAS_ECC */ } else { - error("PEM_read_PrivateKey: mismatch or " - "unknown EVP_PKEY save_type %d", pk->save_type); + error("%s: PEM_read_PrivateKey: mismatch or " + "unknown EVP_PKEY save_type %d", __func__, pk->save_type); } - fclose(fp); if (pk != NULL) EVP_PKEY_free(pk); if (prv != NULL && commentp) @@ -524,6 +568,23 @@ key_load_private_pem(int fd, int type, const char *passphrase, return prv; } +Key * +key_load_private_pem(int fd, int type, const char *passphrase, + char **commentp) +{ + Buffer buffer; + Key *prv; + + buffer_init(&buffer); + if (!key_load_file(fd, NULL, &buffer)) { + buffer_free(&buffer); + return NULL; + } + prv = key_parse_private_pem(&buffer, type, passphrase, commentp); + buffer_free(&buffer); + return prv; +} + int key_perm_ok(int fd, const char *filename) { @@ -552,11 +613,31 @@ key_perm_ok(int fd, const char *filename) return 1; } +static Key * +key_parse_private_type(Buffer *blob, int type, const char *passphrase, + char **commentp) +{ + switch (type) { + case KEY_RSA1: + return key_parse_private_rsa1(blob, passphrase, commentp); + case KEY_DSA: + case KEY_ECDSA: + case KEY_RSA: + case KEY_UNSPEC: + return key_parse_private_pem(blob, type, passphrase, commentp); + default: + break; + } + return NULL; +} + Key * key_load_private_type(int type, const char *filename, const char *passphrase, char **commentp, int *perm_ok) { int fd; + Key *ret; + Buffer buffer; fd = open(filename, O_RDONLY); if (fd < 0) { @@ -575,21 +656,17 @@ key_load_private_type(int type, const char *filename, const char *passphrase, } if (perm_ok != NULL) *perm_ok = 1; - switch (type) { - case KEY_RSA1: - return key_load_private_rsa1(fd, filename, passphrase, - commentp); - /* closes fd */ - case KEY_DSA: - case KEY_RSA: - case KEY_UNSPEC: - return key_load_private_pem(fd, type, passphrase, commentp); - /* closes fd */ - default: + + buffer_init(&buffer); + if (!key_load_file(fd, filename, &buffer)) { + buffer_free(&buffer); close(fd); - break; + return NULL; } - return NULL; + close(fd); + ret = key_parse_private_type(&buffer, type, passphrase, commentp); + buffer_free(&buffer); + return ret; } Key * @@ -597,6 +674,7 @@ key_load_private(const char *filename, const char *passphrase, char **commentp) { Key *pub, *prv; + Buffer buffer, pubcopy; int fd; fd = open(filename, O_RDONLY); @@ -610,20 +688,33 @@ key_load_private(const char *filename, const char *passphrase, close(fd); return NULL; } - pub = key_load_public_rsa1(fd, filename, commentp); - lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ + + buffer_init(&buffer); + if (!key_load_file(fd, filename, &buffer)) { + buffer_free(&buffer); + close(fd); + return NULL; + } + close(fd); + + buffer_init(&pubcopy); + buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer)); + /* it's a SSH v1 key if the public key part is readable */ + pub = key_parse_public_rsa1(&pubcopy, commentp); + buffer_free(&pubcopy); if (pub == NULL) { - /* closes fd */ - prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); + prv = key_parse_private_type(&buffer, KEY_UNSPEC, + passphrase, NULL); /* use the filename as a comment for PEM */ if (commentp && prv) *commentp = xstrdup(filename); } else { - /* it's a SSH v1 key if the public key part is readable */ key_free(pub); - /* closes fd */ - prv = key_load_private_rsa1(fd, filename, passphrase, NULL); + /* key_parse_public_rsa1() has already loaded the comment */ + prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase, + NULL); } + buffer_free(&buffer); return prv; } @@ -721,6 +812,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase, switch (type) { case KEY_RSA: case KEY_DSA: + case KEY_ECDSA: break; default: error("%s: unsupported key type", __func__); diff --git a/bufaux.c b/bufaux.c index 854fd510a967..00208ca279a3 100644 --- a/bufaux.c +++ b/bufaux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufaux.c,v 1.49 2010/03/26 03:13:17 djm Exp $ */ +/* $OpenBSD: bufaux.c,v 1.50 2010/08/31 09:58:37 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -202,6 +202,39 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr) return (ret); } +char * +buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr) +{ + u_int length; + char *cp, *ret = buffer_get_string_ret(buffer, &length); + + if (ret == NULL) + return NULL; + if ((cp = memchr(ret, '\0', length)) != NULL) { + /* XXX allow \0 at end-of-string for a while, remove later */ + if (cp == ret + length - 1) + error("buffer_get_cstring_ret: string contains \\0"); + else { + bzero(ret, length); + xfree(ret); + return NULL; + } + } + if (length_ptr != NULL) + *length_ptr = length; + return ret; +} + +char * +buffer_get_cstring(Buffer *buffer, u_int *length_ptr) +{ + char *ret; + + if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL) + fatal("buffer_get_cstring: buffer error"); + return ret; +} + void * buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) { diff --git a/bufec.c b/bufec.c new file mode 100644 index 000000000000..3dcb49477d4f --- /dev/null +++ b/bufec.c @@ -0,0 +1,146 @@ +/* $OpenBSD: bufec.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */ +/* + * Copyright (c) 2010 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef OPENSSL_HAS_ECC + +#include + +#include +#include + +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" + +/* + * Maximum supported EC GFp field length is 528 bits. SEC1 uncompressed + * encoding represents this as two bitstring points that should each + * be no longer than the field length, SEC1 specifies a 1 byte + * point type header. + * Being paranoid here may insulate us to parsing problems in + * EC_POINT_oct2point. + */ +#define BUFFER_MAX_ECPOINT_LEN ((528*2 / 8) + 1) + +/* + * Append an EC_POINT to the buffer as a string containing a SEC1 encoded + * uncompressed point. Fortunately OpenSSL handles the gory details for us. + */ +int +buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, + const EC_POINT *point) +{ + u_char *buf = NULL; + size_t len; + BN_CTX *bnctx; + int ret = -1; + + /* Determine length */ + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + len = EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, bnctx); + if (len > BUFFER_MAX_ECPOINT_LEN) { + error("%s: giant EC point: len = %lu (max %u)", + __func__, (u_long)len, BUFFER_MAX_ECPOINT_LEN); + goto out; + } + /* Convert */ + buf = xmalloc(len); + if (EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED, + buf, len, bnctx) != len) { + error("%s: EC_POINT_point2oct length mismatch", __func__); + goto out; + } + /* Append */ + buffer_put_string(buffer, buf, len); + ret = 0; + out: + if (buf != NULL) { + bzero(buf, len); + xfree(buf); + } + BN_CTX_free(bnctx); + return ret; +} + +void +buffer_put_ecpoint(Buffer *buffer, const EC_GROUP *curve, + const EC_POINT *point) +{ + if (buffer_put_ecpoint_ret(buffer, curve, point) == -1) + fatal("%s: buffer error", __func__); +} + +int +buffer_get_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, + EC_POINT *point) +{ + u_char *buf; + u_int len; + BN_CTX *bnctx; + int ret = -1; + + if ((buf = buffer_get_string_ret(buffer, &len)) == NULL) { + error("%s: invalid point", __func__); + return -1; + } + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + if (len > BUFFER_MAX_ECPOINT_LEN) { + error("%s: EC_POINT too long: %u > max %u", __func__, + len, BUFFER_MAX_ECPOINT_LEN); + goto out; + } + if (len == 0) { + error("%s: EC_POINT buffer is empty", __func__); + goto out; + } + if (buf[0] != POINT_CONVERSION_UNCOMPRESSED) { + error("%s: EC_POINT is in an incorrect form: " + "0x%02x (want 0x%02x)", __func__, buf[0], + POINT_CONVERSION_UNCOMPRESSED); + goto out; + } + if (EC_POINT_oct2point(curve, point, buf, len, bnctx) != 1) { + error("buffer_get_bignum2_ret: BN_bin2bn failed"); + goto out; + } + /* EC_POINT_oct2point verifies that the point is on the curve for us */ + ret = 0; + out: + BN_CTX_free(bnctx); + bzero(buf, len); + xfree(buf); + return ret; +} + +void +buffer_get_ecpoint(Buffer *buffer, const EC_GROUP *curve, + EC_POINT *point) +{ + if (buffer_get_ecpoint_ret(buffer, curve, point) == -1) + fatal("%s: buffer error", __func__); +} + +#endif /* OPENSSL_HAS_ECC */ diff --git a/buffer.h b/buffer.h index 4ef4f80b35aa..e2a9dd1002a0 100644 --- a/buffer.h +++ b/buffer.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.h,v 1.19 2010/02/09 03:56:28 djm Exp $ */ +/* $OpenBSD: buffer.h,v 1.21 2010/08/31 11:54:45 djm Exp $ */ /* * Author: Tatu Ylonen @@ -68,6 +68,7 @@ void buffer_put_char(Buffer *, int); void *buffer_get_string(Buffer *, u_int *); void *buffer_get_string_ptr(Buffer *, u_int *); void buffer_put_string(Buffer *, const void *, u_int); +char *buffer_get_cstring(Buffer *, u_int *); void buffer_put_cstring(Buffer *, const char *); #define buffer_skip_string(b) \ @@ -81,7 +82,17 @@ int buffer_get_short_ret(u_short *, Buffer *); int buffer_get_int_ret(u_int *, Buffer *); int buffer_get_int64_ret(u_int64_t *, Buffer *); void *buffer_get_string_ret(Buffer *, u_int *); +char *buffer_get_cstring_ret(Buffer *, u_int *); void *buffer_get_string_ptr_ret(Buffer *, u_int *); int buffer_get_char_ret(char *, Buffer *); +#ifdef OPENSSL_HAS_ECC +#include + +int buffer_put_ecpoint_ret(Buffer *, const EC_GROUP *, const EC_POINT *); +void buffer_put_ecpoint(Buffer *, const EC_GROUP *, const EC_POINT *); +int buffer_get_ecpoint_ret(Buffer *, const EC_GROUP *, EC_POINT *); +void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *); +#endif + #endif /* BUFFER_H */ diff --git a/canohost.c b/canohost.c index ef94d9155ea4..dabd8a31ac87 100644 --- a/canohost.c +++ b/canohost.c @@ -199,7 +199,7 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); port = a6->sin6_port; - memset(addr, 0, sizeof(*a4)); + bzero(a4, sizeof(*a4)); a4->sin_family = AF_INET; *len = sizeof(*a4); diff --git a/channels.c b/channels.c index 1cd5004c47bb..6abe2d012730 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.309 2010/08/05 13:08:42 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.310 2010/11/24 01:24:14 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -373,9 +373,6 @@ channel_close_fd(int *fdp) static void channel_close_fds(Channel *c) { - debug3("channel %d: close_fds r %d w %d e %d", - c->self, c->rfd, c->wfd, c->efd); - channel_close_fd(&c->sock); channel_close_fd(&c->rfd); channel_close_fd(&c->wfd); diff --git a/cipher-3des1.c b/cipher-3des1.c index 17a13a133abb..b7aa588cd5b4 100644 --- a/cipher-3des1.c +++ b/cipher-3des1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher-3des1.c,v 1.6 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: cipher-3des1.c,v 1.7 2010/10/01 23:05:32 djm Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * @@ -103,7 +103,8 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, } static int -ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len) +ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + LIBCRYPTO_EVP_INL_TYPE len) { struct ssh1_3des_ctx *c; diff --git a/cipher-acss.c b/cipher-acss.c index cb0bf736c39d..e755f92b975c 100644 --- a/cipher-acss.c +++ b/cipher-acss.c @@ -23,6 +23,7 @@ #if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) #include "acss.h" +#include "openbsd-compat/openssl-compat.h" #define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data) @@ -43,7 +44,7 @@ acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, static int acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, - unsigned int inl) + LIBCRYPTO_EVP_INL_TYPE inl) { acss(&data(ctx)->ks,inl,in,out); return 1; diff --git a/cipher-aes.c b/cipher-aes.c index 3ea594969eab..bfda6d2f241c 100644 --- a/cipher-aes.c +++ b/cipher-aes.c @@ -72,7 +72,7 @@ ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, static int ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, - u_int len) + LIBCRYPTO_EVP_INL_TYPE len) { struct ssh_rijndael_ctx *c; u_char buf[RIJNDAEL_BLOCKSIZE]; diff --git a/cipher-bf1.c b/cipher-bf1.c index e0e33b4c0511..309509dd7806 100644 --- a/cipher-bf1.c +++ b/cipher-bf1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher-bf1.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: cipher-bf1.c,v 1.6 2010/10/01 23:05:32 djm Exp $ */ /* * Copyright (c) 2003 Markus Friedl. All rights reserved. * @@ -76,10 +76,12 @@ static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key, } #endif -static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL; +static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, + const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL; static int -bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len) +bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, + LIBCRYPTO_EVP_INL_TYPE len) { int ret; diff --git a/cipher-ctr.c b/cipher-ctr.c index 3b86cc10bc69..04975b4b65b8 100644 --- a/cipher-ctr.c +++ b/cipher-ctr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher-ctr.c,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */ /* * Copyright (c) 2003 Markus Friedl * @@ -34,7 +34,7 @@ #endif const EVP_CIPHER *evp_aes_128_ctr(void); -void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); +void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); struct ssh_aes_ctr_ctx { @@ -48,7 +48,7 @@ struct ssh_aes_ctr_ctx * (LSB at ctr[len-1], MSB at ctr[0]) */ static void -ssh_ctr_inc(u_char *ctr, u_int len) +ssh_ctr_inc(u_char *ctr, size_t len) { int i; @@ -59,10 +59,10 @@ ssh_ctr_inc(u_char *ctr, u_int len) static int ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, - u_int len) + LIBCRYPTO_EVP_INL_TYPE len) { struct ssh_aes_ctr_ctx *c; - u_int n = 0; + size_t n = 0; u_char buf[AES_BLOCK_SIZE]; if (len == 0) @@ -113,7 +113,7 @@ ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) } void -ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) +ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, size_t len) { struct ssh_aes_ctr_ctx *c; diff --git a/clientloop.c b/clientloop.c index de79793666af..f6c1444a385b 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.222 2010/07/19 09:15:12 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.231 2011/01/16 12:05:59 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -325,7 +325,7 @@ client_x11_get_proto(const char *display, const char *xauth_path, if (trusted == 0) { xauthdir = xmalloc(MAXPATHLEN); xauthfile = xmalloc(MAXPATHLEN); - strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); + mktemp_proto(xauthdir, MAXPATHLEN); if (mkdtemp(xauthdir) != NULL) { do_unlink = 1; snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", @@ -544,7 +544,7 @@ static void server_alive_check(void) { if (packet_inc_alive_timeouts() > options.server_alive_count_max) { - logit("Timeout, server not responding."); + logit("Timeout, server %s not responding.", host); cleanup_exit(255); } packet_start(SSH2_MSG_GLOBAL_REQUEST); @@ -1590,25 +1590,23 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) } /* Output any buffered data for stdout. */ - while (buffer_len(&stdout_buffer) > 0) { - len = write(fileno(stdout), buffer_ptr(&stdout_buffer), - buffer_len(&stdout_buffer)); - if (len <= 0) { + if (buffer_len(&stdout_buffer) > 0) { + len = atomicio(vwrite, fileno(stdout), + buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); + if (len < 0 || (u_int)len != buffer_len(&stdout_buffer)) error("Write failed flushing stdout buffer."); - break; - } - buffer_consume(&stdout_buffer, len); + else + buffer_consume(&stdout_buffer, len); } /* Output any buffered data for stderr. */ - while (buffer_len(&stderr_buffer) > 0) { - len = write(fileno(stderr), buffer_ptr(&stderr_buffer), - buffer_len(&stderr_buffer)); - if (len <= 0) { + if (buffer_len(&stderr_buffer) > 0) { + len = atomicio(vwrite, fileno(stderr), + buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); + if (len < 0 || (u_int)len != buffer_len(&stderr_buffer)) error("Write failed flushing stderr buffer."); - break; - } - buffer_consume(&stderr_buffer, len); + else + buffer_consume(&stderr_buffer, len); } /* Clear and free any buffers. */ @@ -1622,7 +1620,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", - obytes, ibytes, total_time); + (unsigned long long)obytes, (unsigned long long)ibytes, total_time); if (total_time > 0) verbose("Bytes per second: sent %.1f, received %.1f", obytes / total_time, ibytes / total_time); @@ -1933,7 +1931,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) } packet_check_eom(); } - if (reply) { + if (reply && c != NULL) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); packet_put_int(c->remote_id); @@ -1973,6 +1971,9 @@ client_session2_setup(int id, int want_tty, int want_subsystem, if ((c = channel_lookup(id)) == NULL) fatal("client_session2_setup: channel %d: unknown channel", id); + packet_set_interactive(want_tty, + options.ip_qos_interactive, options.ip_qos_bulk); + if (want_tty) { struct winsize ws; @@ -2129,5 +2130,6 @@ cleanup_exit(int i) leave_non_blocking(); if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); + ssh_kill_proxy_command(); _exit(i); } diff --git a/compress.c b/compress.c index c058d222412f..24778e524b4a 100644 --- a/compress.c +++ b/compress.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compress.c,v 1.25 2006/08/06 01:13:32 stevesk Exp $ */ +/* $OpenBSD: compress.c,v 1.26 2010/09/08 04:13:31 deraadt Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -17,12 +17,13 @@ #include #include -#include #include "log.h" #include "buffer.h" #include "compress.h" +#include + z_stream incoming_stream; z_stream outgoing_stream; static int compress_init_send_called = 0; diff --git a/config.h.in b/config.h.in index 4ff407fcc020..e5c9379c85f9 100644 --- a/config.h.in +++ b/config.h.in @@ -125,6 +125,9 @@ /* Builtin PRNG command timeout */ #undef ENTROPY_TIMEOUT_MSEC +/* File names may not contain backslash characters */ +#undef FILESYSTEM_NO_BACKSLASH + /* fsid_t has member val */ #undef FSID_HAS_VAL @@ -143,6 +146,9 @@ /* Define if your system glob() function has gl_matchc options in glob_t */ #undef GLOB_HAS_GL_MATCHC +/* Define if your system glob() function has gl_statv options in glob_t */ +#undef GLOB_HAS_GL_STATV + /* Define this if you want GSSAPI support in the version 2 protocol */ #undef GSSAPI @@ -203,6 +209,9 @@ /* Define to 1 if you have the `bindresvport_sa' function. */ #undef HAVE_BINDRESVPORT_SA +/* Define to 1 if you have the `BN_is_prime_ex' function. */ +#undef HAVE_BN_IS_PRIME_EX + /* Define to 1 if you have the header file. */ #undef HAVE_BSM_AUDIT_H @@ -311,6 +320,9 @@ /* Define to 1 if you have the `dirname' function. */ #undef HAVE_DIRNAME +/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */ +#undef HAVE_DSA_GENERATE_PARAMETERS_EX + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H @@ -533,9 +545,15 @@ /* Define to 1 if the system has the type `in_port_t'. */ #undef HAVE_IN_PORT_T +/* Define if you have isblank(3C). */ +#undef HAVE_ISBLANK + /* Define to 1 if you have the header file. */ #undef HAVE_LASTLOG_H +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBAUDIT_H + /* Define to 1 if you have the `bsm' library (-lbsm). */ #undef HAVE_LIBBSM @@ -738,6 +756,12 @@ /* Define to 1 if you have the `rresvport_af' function. */ #undef HAVE_RRESVPORT_AF +/* Define to 1 if you have the `RSA_generate_key_ex' function. */ +#undef HAVE_RSA_GENERATE_KEY_EX + +/* Define to 1 if you have the `RSA_get_default_method' function. */ +#undef HAVE_RSA_GET_DEFAULT_METHOD + /* define if you have sa_family_t data type */ #undef HAVE_SA_FAMILY_T @@ -1044,6 +1068,9 @@ /* Define if you have ut_time in utmpx.h */ #undef HAVE_TIME_IN_UTMPX +/* Define to 1 if you have the `timingsafe_bcmp' function. */ +#undef HAVE_TIMINGSAFE_BCMP + /* Define to 1 if you have the header file. */ #undef HAVE_TMPDIR_H @@ -1259,6 +1286,9 @@ /* Define if EVP_DigestUpdate returns void */ #undef OPENSSL_EVP_DIGESTUPDATE_VOID +/* libcrypto includes complete ECC support */ +#undef OPENSSL_HAS_ECC + /* libcrypto is missing AES 192 and 256 bit functions */ #undef OPENSSL_LOBOTOMISED_AES @@ -1390,6 +1420,9 @@ /* Use libedit for sftp */ #undef USE_LIBEDIT +/* Use Linux audit module */ +#undef USE_LINUX_AUDIT + /* Enable OpenSSL engine support */ #undef USE_OPENSSL_ENGINE @@ -1402,6 +1435,9 @@ /* Define if you have Solaris process contracts */ #undef USE_SOLARIS_PROCESS_CONTRACTS +/* Define if you have Solaris projects */ +#undef USE_SOLARIS_PROJECTS + /* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */ #undef WITH_ABBREV_NO_TTY diff --git a/configure b/configure index ef3bb0f0fa2d..6e05311aa834 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac Revision: 1.451 . +# From configure.ac Revision: 1.469 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for OpenSSH Portable. # @@ -684,7 +684,11 @@ SED ENT TEST_MINUS_S_SH SH +GROFF +NROFF +MANDOC TEST_SHELL +MANFMT PATH_GROUPADD_PROG PATH_USERADD_PROG MAKE_PACKAGE_SUPPORTED @@ -695,6 +699,9 @@ LD SSHDLIBS PKGCONFIG LIBEDIT +TEST_SSH_SHA256 +TEST_SSH_ECC +COMMENT_OUT_ECC INSTALL_SSH_RAND_HELPER SSH_PRIVSEP_USER PROG_LS @@ -719,7 +726,6 @@ PRIVSEP_PATH xauth_path STRIP_OPT XAUTH_PATH -NROFF MANTYPE mansubdir user_path @@ -1334,13 +1340,14 @@ Optional Packages: --with-libs Specify additional libraries to link with --with-Werror Build main code with -Werror --with-solaris-contracts Enable Solaris process contracts (experimental) + --with-solaris-projects Enable Solaris projects (experimental) --with-osfsia Enable Digital Unix SIA --with-zlib=PATH Use zlib in PATH --without-zlib-version-check Disable zlib version check --with-skey[=PATH] Enable S/Key support (optionally in PATH) --with-tcp-wrappers[=PATH] Enable tcpwrappers support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp - --with-audit=module Enable EXPERIMENTAL audit support (modules=debug,bsm) + --with-audit=module Enable audit support (modules=debug,bsm,linux) --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support @@ -1809,6 +1816,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +# local macros + + ac_config_headers="$ac_config_headers config.h" ac_ext=c @@ -4657,9 +4667,142 @@ echo "${ECHO_T}no" >&6; } fi +# Extract the first word of "groff", so it can be a program name with args. +set dummy groff; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_GROFF+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $GROFF in + [\\/]* | ?:[\\/]*) + ac_cv_path_GROFF="$GROFF" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +GROFF=$ac_cv_path_GROFF +if test -n "$GROFF"; then + { echo "$as_me:$LINENO: result: $GROFF" >&5 +echo "${ECHO_T}$GROFF" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "nroff", so it can be a program name with args. +set dummy nroff; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_NROFF+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $NROFF in + [\\/]* | ?:[\\/]*) + ac_cv_path_NROFF="$NROFF" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +NROFF=$ac_cv_path_NROFF +if test -n "$NROFF"; then + { echo "$as_me:$LINENO: result: $NROFF" >&5 +echo "${ECHO_T}$NROFF" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Extract the first word of "mandoc", so it can be a program name with args. +set dummy mandoc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_MANDOC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $MANDOC in + [\\/]* | ?:[\\/]*) + ac_cv_path_MANDOC="$MANDOC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MANDOC="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +MANDOC=$ac_cv_path_MANDOC +if test -n "$MANDOC"; then + { echo "$as_me:$LINENO: result: $MANDOC" >&5 +echo "${ECHO_T}$MANDOC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + TEST_SHELL=sh +if test "x$MANDOC" != "x" ; then + MANFMT="$MANDOC" +elif test "x$NROFF" != "x" ; then + MANFMT="$NROFF -mandoc" +elif test "x$GROFF" != "x" ; then + MANFMT="$GROFF -mandoc -Tascii" +else + { echo "$as_me:$LINENO: WARNING: no manpage formatted found" >&5 +echo "$as_me: WARNING: no manpage formatted found" >&2;} + MANFMT="false" +fi + + # Extract the first word of "groupadd", so it can be a program name with args. set dummy groupadd; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 @@ -5395,20 +5538,333 @@ if test "${with_stackprotect+set}" = set; then fi + if test "$GCC" = "yes" || test "$GCC" = "egcs"; then - CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized" + { + { echo "$as_me:$LINENO: checking if $CC supports -Wall" >&5 +echo $ECHO_N "checking if $CC supports -Wall... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -Wpointer-arith" >&5 +echo $ECHO_N "checking if $CC supports -Wpointer-arith... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wpointer-arith" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -Wuninitialized" >&5 +echo $ECHO_N "checking if $CC supports -Wuninitialized... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wuninitialized" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -Wsign-compare" >&5 +echo $ECHO_N "checking if $CC supports -Wsign-compare... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wsign-compare" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -Wformat-security" >&5 +echo $ECHO_N "checking if $CC supports -Wformat-security... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wformat-security" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -Wno-pointer-sign" >&5 +echo $ECHO_N "checking if $CC supports -Wno-pointer-sign... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wno-pointer-sign" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -Wno-unused-result" >&5 +echo $ECHO_N "checking if $CC supports -Wno-unused-result... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wno-unused-result" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { + { echo "$as_me:$LINENO: checking if $CC supports -fno-strict-aliasing" >&5 +echo $ECHO_N "checking if $CC supports -fno-strict-aliasing... $ECHO_C" >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-strict-aliasing" + cat >conftest.$ac_ext <<_ACEOF +void main(void) { return 0; } +_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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + CFLAGS="$saved_CFLAGS" + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +} + { echo "$as_me:$LINENO: checking gcc version" >&5 +echo $ECHO_N "checking gcc version... $ECHO_C" >&6; } GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in 1.*) no_attrib_nonnull=1 ;; 2.8* | 2.9*) - CFLAGS="$CFLAGS -Wsign-compare" no_attrib_nonnull=1 ;; 2.*) no_attrib_nonnull=1 ;; - 3.*) CFLAGS="$CFLAGS -Wsign-compare -Wformat-security" ;; - 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security -fno-strict-aliasing" ;; *) ;; esac + { echo "$as_me:$LINENO: result: $GCC_VER" >&5 +echo "${ECHO_T}$GCC_VER" >&6; } { echo "$as_me:$LINENO: checking if $CC accepts -fno-builtin-memset" >&5 echo $ECHO_N "checking if $CC accepts -fno-builtin-memset... $ECHO_C" >&6; } @@ -6256,6 +6712,7 @@ done # Messages for features tested for in target-specific section SIA_MSG="no" SPC_MSG="no" +SP_MSG="no" # Check for some target-specific stuff case "$host" in @@ -7245,6 +7702,11 @@ cat >>confdefs.h <<\_ACEOF #define SSH_IOBUFSZ 65535 _ACEOF + +cat >>confdefs.h <<\_ACEOF +#define FILESYSTEM_NO_BACKSLASH 1 +_ACEOF + ;; *-*-dgux*) @@ -8590,6 +9052,85 @@ _ACEOF fi +fi + + +# Check whether --with-solaris-projects was given. +if test "${with_solaris_projects+set}" = set; then + withval=$with_solaris_projects; + { echo "$as_me:$LINENO: checking for setproject in -lproject" >&5 +echo $ECHO_N "checking for setproject in -lproject... $ECHO_C" >&6; } +if test "${ac_cv_lib_project_setproject+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lproject $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 setproject (); +int +main () +{ +return setproject (); + ; + 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_project_setproject=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_project_setproject=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_project_setproject" >&5 +echo "${ECHO_T}$ac_cv_lib_project_setproject" >&6; } +if test $ac_cv_lib_project_setproject = yes; then + +cat >>confdefs.h <<\_ACEOF +#define USE_SOLARIS_PROJECTS 1 +_ACEOF + + SSHDLIBS="$SSHDLIBS -lproject" + + SP_MSG="yes" +fi + + fi ;; @@ -12010,6 +12551,69 @@ sed 's/^/| /' conftest.$ac_ext >&5 echo "${ECHO_T}no" >&6; } +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +# Check for g.gl_statv glob() extension +{ echo "$as_me:$LINENO: checking for gl_statv and GLOB_KEEPSTAT extensions for glob" >&5 +echo $ECHO_N "checking for gl_statv and GLOB_KEEPSTAT extensions for glob... $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 +int +main () +{ + +#ifndef GLOB_KEEPSTAT +#error "glob does not support GLOB_KEEPSTAT extension" +#endif +glob_t g; +g.gl_statv = NULL; + + ; + return 0; +} +_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 + + +cat >>confdefs.h <<\_ACEOF +#define GLOB_HAS_GL_STATV 1 +_ACEOF + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext @@ -12468,7 +13072,7 @@ echo "${ECHO_T}no" >&6; } LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi fi - if test "x$use_pkgconfig_for_libedit" == "xyes"; then + if test "x$use_pkgconfig_for_libedit" = "xyes"; then LIBEDIT=`$PKGCONFIG --libs-only-l libedit` CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`" else @@ -12958,6 +13562,162 @@ done cat >>confdefs.h <<\_ACEOF #define USE_BSM_AUDIT 1 +_ACEOF + + ;; + linux) + { echo "$as_me:$LINENO: result: linux" >&5 +echo "${ECHO_T}linux" >&6; } + AUDIT_MODULE=linux + +for ac_header in libaudit.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 + + SSHDLIBS="$SSHDLIBS -laudit" + +cat >>confdefs.h <<\_ACEOF +#define USE_LINUX_AUDIT 1 _ACEOF ;; @@ -13077,6 +13837,7 @@ fi + for ac_func in \ @@ -13166,6 +13927,7 @@ for ac_func in \ swap32 \ sysconf \ tcgetpgrp \ + timingsafe_bcmp \ truncate \ unsetenv \ updwtmpx \ @@ -13268,6 +14030,49 @@ fi done +cat >conftest.$ac_ext <<_ACEOF + +#include +int main(void) +{ + return (isblank('a')); +} + +_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 + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ISBLANK 1 +_ACEOF + + +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 conftest.$ac_ext + # PKCS#11 support requires dlopen() and co { echo "$as_me:$LINENO: checking for library containing dlopen" >&5 echo $ECHO_N "checking for library containing dlopen... $ECHO_C" >&6; } @@ -17135,6 +17940,104 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext + + + +for ac_func in RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method +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 + + + # Check whether --with-ssl-engine was given. if test "${with_ssl_engine+set}" = set; then withval=$with_ssl_engine; if test "x$withval" != "xno" ; then @@ -17547,11 +18450,86 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF - + TEST_SSH_SHA256=yes +else + TEST_SSH_SHA256=no fi done + +# Check complete ECC support in OpenSSL +{ echo "$as_me:$LINENO: checking whether OpenSSL has complete ECC support" >&5 +echo $ECHO_N "checking whether OpenSSL has complete ECC support... $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 +#include +#include +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ +# error "OpenSSL < 0.9.8g has unreliable ECC code" +#endif +int main(void) { + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ +} + +_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 + + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +cat >>confdefs.h <<\_ACEOF +#define OPENSSL_HAS_ECC 1 +_ACEOF + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + TEST_SSH_ECC=no + COMMENT_OUT_ECC="#no ecc#" + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + + + saved_LIBS="$LIBS" { echo "$as_me:$LINENO: checking for ia_openinfo in -liaf" >&5 echo $ECHO_N "checking for ia_openinfo in -liaf... $ECHO_C" >&6; } @@ -27106,7 +28084,7 @@ echo "${ECHO_T}yes" >&6; } #define HEIMDAL 1 _ACEOF - K5LIBS="-lkrb5 -ldes" + K5LIBS="-lkrb5" K5LIBS="$K5LIBS -lcom_err -lasn1" { echo "$as_me:$LINENO: checking for net_write in -lroken" >&5 echo $ECHO_N "checking for net_write in -lroken... $ECHO_C" >&6; } @@ -27173,6 +28151,71 @@ if test $ac_cv_lib_roken_net_write = yes; then K5LIBS="$K5LIBS -lroken" fi + { echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes" >&5 +echo $ECHO_N "checking for des_cbc_encrypt in -ldes... $ECHO_C" >&6; } +if test "${ac_cv_lib_des_des_cbc_encrypt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldes $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 des_cbc_encrypt (); +int +main () +{ +return des_cbc_encrypt (); + ; + 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_des_des_cbc_encrypt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_des_des_cbc_encrypt=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_des_des_cbc_encrypt" >&5 +echo "${ECHO_T}$ac_cv_lib_des_des_cbc_encrypt" >&6; } +if test $ac_cv_lib_des_des_cbc_encrypt = yes; then + K5LIBS="$K5LIBS -ldes" +fi + else echo "$as_me: failed program was:" >&5 @@ -30361,7 +31404,11 @@ SED!$SED$ac_delim ENT!$ENT$ac_delim TEST_MINUS_S_SH!$TEST_MINUS_S_SH$ac_delim SH!$SH$ac_delim +GROFF!$GROFF$ac_delim +NROFF!$NROFF$ac_delim +MANDOC!$MANDOC$ac_delim TEST_SHELL!$TEST_SHELL$ac_delim +MANFMT!$MANFMT$ac_delim PATH_GROUPADD_PROG!$PATH_GROUPADD_PROG$ac_delim PATH_USERADD_PROG!$PATH_USERADD_PROG$ac_delim MAKE_PACKAGE_SUPPORTED!$MAKE_PACKAGE_SUPPORTED$ac_delim @@ -30372,6 +31419,9 @@ LD!$LD$ac_delim SSHDLIBS!$SSHDLIBS$ac_delim PKGCONFIG!$PKGCONFIG$ac_delim LIBEDIT!$LIBEDIT$ac_delim +TEST_SSH_SHA256!$TEST_SSH_SHA256$ac_delim +TEST_SSH_ECC!$TEST_SSH_ECC$ac_delim +COMMENT_OUT_ECC!$COMMENT_OUT_ECC$ac_delim INSTALL_SSH_RAND_HELPER!$INSTALL_SSH_RAND_HELPER$ac_delim SSH_PRIVSEP_USER!$SSH_PRIVSEP_USER$ac_delim PROG_LS!$PROG_LS$ac_delim @@ -30383,13 +31433,6 @@ PROG_PS!$PROG_PS$ac_delim PROG_SAR!$PROG_SAR$ac_delim PROG_W!$PROG_W$ac_delim PROG_WHO!$PROG_WHO$ac_delim -PROG_LAST!$PROG_LAST$ac_delim -PROG_LASTLOG!$PROG_LASTLOG$ac_delim -PROG_DF!$PROG_DF$ac_delim -PROG_VMSTAT!$PROG_VMSTAT$ac_delim -PROG_UPTIME!$PROG_UPTIME$ac_delim -PROG_IPCS!$PROG_IPCS$ac_delim -PROG_TAIL!$PROG_TAIL$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -30431,13 +31474,19 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +PROG_LAST!$PROG_LAST$ac_delim +PROG_LASTLOG!$PROG_LASTLOG$ac_delim +PROG_DF!$PROG_DF$ac_delim +PROG_VMSTAT!$PROG_VMSTAT$ac_delim +PROG_UPTIME!$PROG_UPTIME$ac_delim +PROG_IPCS!$PROG_IPCS$ac_delim +PROG_TAIL!$PROG_TAIL$ac_delim INSTALL_SSH_PRNG_CMDS!$INSTALL_SSH_PRNG_CMDS$ac_delim KRB5CONF!$KRB5CONF$ac_delim PRIVSEP_PATH!$PRIVSEP_PATH$ac_delim xauth_path!$xauth_path$ac_delim STRIP_OPT!$STRIP_OPT$ac_delim XAUTH_PATH!$XAUTH_PATH$ac_delim -NROFF!$NROFF$ac_delim MANTYPE!$MANTYPE$ac_delim mansubdir!$mansubdir$ac_delim user_path!$user_path$ac_delim @@ -30447,7 +31496,7 @@ LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 14; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 20; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 @@ -30924,6 +31973,7 @@ echo " TCP Wrappers support: $TCPW_MSG" 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 " 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 637e7b536fd4..769e83594fee 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.451 2010/08/16 03:15:23 dtucker Exp $ +# $Id: configure.ac,v 1.469 2011/01/21 22:37:05 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,9 +15,21 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.451 $) +AC_REVISION($Revision: 1.469 $) AC_CONFIG_SRCDIR([ssh.c]) +# local macros +AC_DEFUN([OPENSSH_CHECK_CFLAG_COMPILE], [{ + AC_MSG_CHECKING([if $CC supports $1]) + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_COMPILE_IFELSE([void main(void) { return 0; }], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + CFLAGS="$saved_CFLAGS" ] + ) +}]) + AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_CANONICAL_HOST @@ -41,8 +53,24 @@ AC_PATH_PROG(TEST_MINUS_S_SH, bash) AC_PATH_PROG(TEST_MINUS_S_SH, ksh) AC_PATH_PROG(TEST_MINUS_S_SH, sh) AC_PATH_PROG(SH, sh) +AC_PATH_PROG(GROFF, groff) +AC_PATH_PROG(NROFF, nroff) +AC_PATH_PROG(MANDOC, mandoc) AC_SUBST(TEST_SHELL,sh) +dnl select manpage formatter +if test "x$MANDOC" != "x" ; then + MANFMT="$MANDOC" +elif test "x$NROFF" != "x" ; then + MANFMT="$NROFF -mandoc" +elif test "x$GROFF" != "x" ; then + MANFMT="$GROFF -mandoc -Tascii" +else + AC_MSG_WARN([no manpage formatted found]) + MANFMT="false" +fi +AC_SUBST(MANFMT) + dnl for buildpkg.sh AC_PATH_PROG(PATH_GROUPADD_PROG, groupadd, groupadd, [/usr/sbin${PATH_SEPARATOR}/etc]) @@ -97,20 +125,27 @@ AC_ARG_WITH(stackprotect, use_stack_protector=0 fi ]) + if test "$GCC" = "yes" || test "$GCC" = "egcs"; then - CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized" + OPENSSH_CHECK_CFLAG_COMPILE([-Wall]) + OPENSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith]) + OPENSSH_CHECK_CFLAG_COMPILE([-Wuninitialized]) + OPENSSH_CHECK_CFLAG_COMPILE([-Wsign-compare]) + OPENSSH_CHECK_CFLAG_COMPILE([-Wformat-security]) + OPENSSH_CHECK_CFLAG_COMPILE([-Wno-pointer-sign]) + OPENSSH_CHECK_CFLAG_COMPILE([-Wno-unused-result]) + OPENSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing]) + AC_MSG_CHECKING(gcc version) GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in 1.*) no_attrib_nonnull=1 ;; 2.8* | 2.9*) - CFLAGS="$CFLAGS -Wsign-compare" no_attrib_nonnull=1 ;; 2.*) no_attrib_nonnull=1 ;; - 3.*) CFLAGS="$CFLAGS -Wsign-compare -Wformat-security" ;; - 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign -Wformat-security -fno-strict-aliasing" ;; *) ;; esac + AC_MSG_RESULT($GCC_VER) AC_MSG_CHECKING(if $CC accepts -fno-builtin-memset) saved_CFLAGS="$CFLAGS" @@ -333,6 +368,7 @@ AC_CHECK_HEADERS(sys/mount.h, [], [], [ # Messages for features tested for in target-specific section SIA_MSG="no" SPC_MSG="no" +SP_MSG="no" # Check for some target-specific stuff case "$host" in @@ -447,6 +483,7 @@ int main(void) { exit(0); } [Define if your platform needs to skip post auth file descriptor passing]) AC_DEFINE(SSH_IOBUFSZ, 65535, [Windows is sensitive to read buffer size]) + AC_DEFINE(FILESYSTEM_NO_BACKSLASH, 1, [File names may not contain backslash characters]) ;; *-*-dgux*) AC_DEFINE(IP_TOS_IS_BROKEN, 1, @@ -704,6 +741,17 @@ mips-sony-bsd|mips-sony-newsos4) SPC_MSG="yes" ], ) ], ) + AC_ARG_WITH(solaris-projects, + [ --with-solaris-projects Enable Solaris projects (experimental)], + [ + AC_CHECK_LIB(project, setproject, + [ AC_DEFINE(USE_SOLARIS_PROJECTS, 1, + [Define if you have Solaris projects]) + SSHDLIBS="$SSHDLIBS -lproject" + AC_SUBST(SSHDLIBS) + SP_MSG="yes" ], ) + ], + ) ;; *-*-sunos4*) CPPFLAGS="$CPPFLAGS -DSUNOS4" @@ -1118,6 +1166,28 @@ AC_TRY_COMPILE( ] ) +# Check for g.gl_statv glob() extension +AC_MSG_CHECKING(for gl_statv and GLOB_KEEPSTAT extensions for glob) +AC_TRY_COMPILE( + [ #include ], + [ +#ifndef GLOB_KEEPSTAT +#error "glob does not support GLOB_KEEPSTAT extension" +#endif +glob_t g; +g.gl_statv = NULL; +], + [ + AC_DEFINE(GLOB_HAS_GL_STATV, 1, + [Define if your system glob() function has + gl_statv options in glob_t]) + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + ] +) + AC_CHECK_DECLS(GLOB_NOMATCH, , , [#include ]) AC_MSG_CHECKING([whether struct dirent allocates space for d_name]) @@ -1273,7 +1343,7 @@ AC_ARG_WITH(libedit, LDFLAGS="-L${withval}/lib ${LDFLAGS}" fi fi - if test "x$use_pkgconfig_for_libedit" == "xyes"; then + if test "x$use_pkgconfig_for_libedit" = "xyes"; then LIBEDIT=`$PKGCONFIG --libs-only-l libedit` CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`" else @@ -1308,7 +1378,7 @@ int main(void) AUDIT_MODULE=none AC_ARG_WITH(audit, - [ --with-audit=module Enable EXPERIMENTAL audit support (modules=debug,bsm)], + [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], [ AC_MSG_CHECKING(for supported audit module) case "$withval" in @@ -1332,10 +1402,18 @@ AC_ARG_WITH(audit, AC_CHECK_FUNCS(getaudit_addr aug_get_machine) AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module]) ;; + linux) + AC_MSG_RESULT(linux) + AUDIT_MODULE=linux + dnl Checks for headers, libs and functions + AC_CHECK_HEADERS(libaudit.h) + SSHDLIBS="$SSHDLIBS -laudit" + AC_DEFINE(USE_LINUX_AUDIT, 1, [Use Linux audit module]) + ;; debug) AUDIT_MODULE=debug AC_MSG_RESULT(debug) - AC_DEFINE(SSH_AUDIT_EVENTS, 1, Use audit debugging module) + AC_DEFINE(SSH_AUDIT_EVENTS, 1, [Use audit debugging module]) ;; no) AC_MSG_RESULT(no) @@ -1434,6 +1512,7 @@ AC_CHECK_FUNCS( \ swap32 \ sysconf \ tcgetpgrp \ + timingsafe_bcmp \ truncate \ unsetenv \ updwtmpx \ @@ -1444,6 +1523,17 @@ AC_CHECK_FUNCS( \ waitpid \ ) +AC_LINK_IFELSE( +[ +#include +int main(void) +{ + return (isblank('a')); +} +], + [AC_DEFINE(HAVE_ISBLANK, 1, [Define if you have isblank(3C).]) +]) + # PKCS#11 support requires dlopen() and co AC_SEARCH_LIBS(dlopen, dl, AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support]) @@ -2090,6 +2180,8 @@ int main(void) { SSLeay_add_all_algorithms(); } ] ) +AC_CHECK_FUNCS(RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method) + AC_ARG_WITH(ssl-engine, [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], [ if test "x$withval" != "xno" ; then @@ -2156,7 +2248,43 @@ if test "x$check_for_libcrypt_later" = "x1"; then fi # Search for SHA256 support in libc and/or OpenSSL -AC_CHECK_FUNCS(SHA256_Update EVP_sha256) +AC_CHECK_FUNCS(SHA256_Update EVP_sha256, [TEST_SSH_SHA256=yes], + [TEST_SSH_SHA256=no]) +AC_SUBST(TEST_SSH_SHA256) + +# Check complete ECC support in OpenSSL +AC_MSG_CHECKING([whether OpenSSL has complete ECC support]) +AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include +#include +#include +#include +#if OPENSSL_VERSION_NUMBER < 0x0090807f /* 0.9.8g */ +# error "OpenSSL < 0.9.8g has unreliable ECC code" +#endif +int main(void) { + EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1); + const EVP_MD *m = EVP_sha512(); /* We need this too */ +} + ]])], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(OPENSSL_HAS_ECC, 1, + [libcrypto includes complete ECC support]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + ], + [ + AC_MSG_RESULT(no) + TEST_SSH_ECC=no + COMMENT_OUT_ECC="#no ecc#" + ] +) +AC_SUBST(TEST_SSH_ECC) +AC_SUBST(COMMENT_OUT_ECC) saved_LIBS="$LIBS" AC_CHECK_LIB(iaf, ia_openinfo, [ @@ -3443,10 +3571,12 @@ AC_ARG_WITH(kerberos5, [ char *tmp = heimdal_version; ], [ AC_MSG_RESULT(yes) AC_DEFINE(HEIMDAL) - K5LIBS="-lkrb5 -ldes" + K5LIBS="-lkrb5" K5LIBS="$K5LIBS -lcom_err -lasn1" AC_CHECK_LIB(roken, net_write, [K5LIBS="$K5LIBS -lroken"]) + AC_CHECK_LIB(des, des_cbc_encrypt, + [K5LIBS="$K5LIBS -ldes"]) ], [ AC_MSG_RESULT(no) K5LIBS="-lkrb5 -lk5crypto -lcom_err" @@ -4191,6 +4321,7 @@ echo " TCP Wrappers support: $TCPW_MSG" 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 " 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/caldera/openssh.spec b/contrib/caldera/openssh.spec index 515fe334d2c3..23397b04d93c 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec @@ -16,7 +16,7 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 -%define version 5.6p1 +%define version 5.7p1 %if %{use_stable} %define cvs %{nil} %define release 1 @@ -57,7 +57,7 @@ BuildRequires : XFree86-imake # %{use_stable}==0: :pserver:cvs@bass.directhit.com:/cvs/openssh_cvs Source0: see-above:/.../openssh-%{version}.tar.gz %if %{use_stable} -Source1: see-above:/.../openssh-%{version}.tar.gz.sig +Source1: see-above:/.../openssh-%{version}.tar.gz.asc %endif Source2: http://www.jmknoble.net/software/%{xsa}/%{askpass}.tar.gz Source3: http://www.openssh.com/faq.html @@ -182,7 +182,7 @@ CFLAGS="$RPM_OPT_FLAGS" \ --with-privsep-path=%{_var}/empty/sshd \ #leave this line for easy edits. -%__make CFLAGS="$RPM_OPT_FLAGS" +%__make cd %{askpass} %configure \ @@ -356,7 +356,11 @@ fi %ChangeLog +* Tue Jan 18 2011 Tim Rice +- Use CFLAGS from Makefile instead of RPM so build completes. +- Signatures were changed to .asc since 4.1p1. + * Mon Jan 01 1998 ... Template Version: 1.31 -$Id: openssh.spec,v 1.71 2010/08/08 16:32:09 djm Exp $ +$Id: openssh.spec,v 1.73 2011/01/22 09:23:33 djm Exp $ diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 77e66252ec5d..8fc76b62541c 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 5.6p1 +%define ver 5.7p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID diff --git a/contrib/redhat/sshd.init b/contrib/redhat/sshd.init index e5d837cbc104..854aff665c8f 100755 --- a/contrib/redhat/sshd.init +++ b/contrib/redhat/sshd.init @@ -104,7 +104,7 @@ start() do_dsa_keygen echo -n $"Starting $prog:" - initlog -c "$SSHD $OPTIONS" && success || failure + $SSHD $OPTIONS && success || failure RETVAL=$? [ "$RETVAL" = 0 ] && touch /var/lock/subsys/sshd echo diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index f099746f2a03..4573c52fde9e 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: 5.6p1 +Version: 5.7p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/defines.h b/defines.h index fe25170e6188..cd273066daf5 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.160 2010/04/09 08:13:27 dtucker Exp $ */ +/* $Id: defines.h,v 1.164 2011/01/17 10:15:31 dtucker Exp $ */ /* Constants */ @@ -42,6 +42,9 @@ enum # define SHUT_RDWR SHUT_RDWR #endif +/* + * Definitions for IP type of service (ip_tos) + */ #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 # define IPTOS_THROUGHPUT 0x08 @@ -50,6 +53,40 @@ enum # define IPTOS_MINCOST IPTOS_LOWCOST #endif /* IPTOS_LOWDELAY */ +/* + * Definitions for DiffServ Codepoints as per RFC2474 + */ +#include +#include +#ifndef IPTOS_DSCP_AF11 +# define IPTOS_DSCP_AF11 0x28 +# define IPTOS_DSCP_AF12 0x30 +# define IPTOS_DSCP_AF13 0x38 +# define IPTOS_DSCP_AF21 0x48 +# define IPTOS_DSCP_AF22 0x50 +# define IPTOS_DSCP_AF23 0x58 +# define IPTOS_DSCP_AF31 0x68 +# define IPTOS_DSCP_AF32 0x70 +# define IPTOS_DSCP_AF33 0x78 +# define IPTOS_DSCP_AF41 0x88 +# define IPTOS_DSCP_AF42 0x90 +# define IPTOS_DSCP_AF43 0x98 +# define IPTOS_DSCP_EF 0xb8 +#endif /* IPTOS_DSCP_AF11 */ +#ifndef IPTOS_DSCP_CS0 +# define IPTOS_DSCP_CS0 0x00 +# define IPTOS_DSCP_CS1 0x20 +# define IPTOS_DSCP_CS2 0x40 +# define IPTOS_DSCP_CS3 0x60 +# define IPTOS_DSCP_CS4 0x80 +# define IPTOS_DSCP_CS5 0xa0 +# define IPTOS_DSCP_CS6 0xc0 +# define IPTOS_DSCP_CS7 0xe0 +#endif /* IPTOS_DSCP_CS0 */ +#ifndef IPTOS_DSCP_EF +# define IPTOS_DSCP_EF 0xb8 +#endif /* IPTOS_DSCP_EF */ + #ifndef MAXPATHLEN # ifdef PATH_MAX # define MAXPATHLEN PATH_MAX @@ -256,6 +293,10 @@ typedef unsigned int size_t; # define SIZE_T_MAX UINT_MAX #endif /* HAVE_SIZE_T */ +#ifndef SIZE_MAX +#define SIZE_MAX SIZE_T_MAX +#endif + #ifndef HAVE_SSIZE_T typedef int ssize_t; # define HAVE_SSIZE_T @@ -566,6 +607,11 @@ struct winsize { # define CUSTOM_SSH_AUDIT_EVENTS #endif +#ifdef USE_LINUX_AUDIT +# define SSH_AUDIT_EVENTS +# define CUSTOM_SSH_AUDIT_EVENTS +#endif + #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) # define __func__ __FUNCTION__ #elif !defined(HAVE___func__) diff --git a/dns.c b/dns.c index 2e7bb5aae9fe..131cb3d8b5d5 100644 --- a/dns.c +++ b/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.26 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.27 2010/08/31 11:54:45 djm Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -86,6 +86,7 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, case KEY_DSA: *algorithm = SSHFP_KEY_DSA; break; + /* XXX KEY_ECDSA */ default: *algorithm = SSHFP_KEY_RESERVED; /* 0 */ } diff --git a/entropy.c b/entropy.c index 8b705397ff9a..a82166258e87 100644 --- a/entropy.c +++ b/entropy.c @@ -157,7 +157,7 @@ init_rng(void) */ if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) fatal("OpenSSL version mismatch. Built against %lx, you " - "have %lx", OPENSSL_VERSION_NUMBER, SSLeay()); + "have %lx", (u_long)OPENSSL_VERSION_NUMBER, SSLeay()); #ifndef OPENSSL_PRNG_ONLY original_uid = getuid(); diff --git a/hostfile.c b/hostfile.c index afab6dad1823..b6f924b234cc 100644 --- a/hostfile.c +++ b/hostfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.c,v 1.48 2010/03/04 10:36:03 djm Exp $ */ +/* $OpenBSD: hostfile.c,v 1.50 2010/12/04 13:31:37 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -56,6 +56,12 @@ #include "key.h" #include "hostfile.h" #include "log.h" +#include "misc.h" + +struct hostkeys { + struct hostkey_entry *entries; + u_int num_entries; +}; static int extract_salt(const char *s, u_int l, char *salt, size_t salt_len) @@ -164,26 +170,28 @@ hostfile_read_key(char **cpp, u_int *bitsp, Key *ret) /* Return results. */ *cpp = cp; - *bitsp = key_size(ret); + if (bitsp != NULL) + *bitsp = key_size(ret); return 1; } static int -hostfile_check_key(int bits, const Key *key, const char *host, const char *filename, int linenum) +hostfile_check_key(int bits, const Key *key, const char *host, + const char *filename, u_long linenum) { if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) return 1; if (bits != BN_num_bits(key->rsa->n)) { - logit("Warning: %s, line %d: keysize mismatch for host %s: " + logit("Warning: %s, line %lu: keysize mismatch for host %s: " "actual %d vs. announced %d.", filename, linenum, host, BN_num_bits(key->rsa->n), bits); - logit("Warning: replace %d with %d in %s, line %d.", + logit("Warning: replace %d with %d in %s, line %lu.", bits, BN_num_bits(key->rsa->n), filename, linenum); } return 1; } -static enum { MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA } +static HostkeyMarker check_markers(char **cpp) { char marker[32], *sp, *cp = *cpp; @@ -218,49 +226,32 @@ check_markers(char **cpp) return ret; } -/* - * Checks whether the given host (which must be in all lowercase) is already - * in the list of our known hosts. Returns HOST_OK if the host is known and - * has the specified key, HOST_NEW if the host is not known, and HOST_CHANGED - * if the host is known but used to have a different host key. - * - * If no 'key' has been specified and a key of type 'keytype' is known - * for the specified host, then HOST_FOUND is returned. - */ +struct hostkeys * +init_hostkeys(void) +{ + struct hostkeys *ret = xcalloc(1, sizeof(*ret)); -static HostStatus -check_host_in_hostfile_by_key_or_type(const char *filename, - const char *host, const Key *key, int keytype, Key *found, - int want_revocation, int *numret) + ret->entries = NULL; + return ret; +} + +void +load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) { FILE *f; char line[8192]; - int want, have, linenum = 0, want_cert = key_is_cert(key); - u_int kbits; + u_long linenum = 0, num_loaded = 0; char *cp, *cp2, *hashed_host; - HostStatus end_return; + HostkeyMarker marker; + Key *key; + int kbits; - debug3("check_host_in_hostfile: host %s filename %s", host, filename); - - if (want_revocation && (key == NULL || keytype != 0 || found != NULL)) - fatal("%s: invalid arguments", __func__); - - /* Open the file containing the list of known hosts. */ - f = fopen(filename, "r"); - if (!f) - return HOST_NEW; - - /* - * Return value when the loop terminates. This is set to - * HOST_CHANGED if we have seen a different key for the host and have - * not found the proper one. - */ - end_return = HOST_NEW; - - /* Go through the file. */ - while (fgets(line, sizeof(line), f)) { + if ((f = fopen(path, "r")) == NULL) + return; + debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", + __func__, host, path); + while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { cp = line; - linenum++; /* Skip any leading whitespace, comments and empty lines. */ for (; *cp == ' ' || *cp == '\t'; cp++) @@ -268,19 +259,11 @@ check_host_in_hostfile_by_key_or_type(const char *filename, if (!*cp || *cp == '#' || *cp == '\n') continue; - if (want_revocation) - want = MRK_REVOKE; - else if (want_cert) - want = MRK_CA; - else - want = MRK_NONE; - - if ((have = check_markers(&cp)) == MRK_ERROR) { - verbose("%s: invalid marker at %s:%d", - __func__, filename, linenum); - continue; - } else if (want != have) + if ((marker = check_markers(&cp)) == MRK_ERROR) { + verbose("%s: invalid marker at %s:%lu", + __func__, path, linenum); continue; + } /* Find the end of the host name portion. */ for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) @@ -292,8 +275,8 @@ check_host_in_hostfile_by_key_or_type(const char *filename, continue; hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); if (hashed_host == NULL) { - debug("Invalid hashed host line %d of %s", - linenum, filename); + debug("Invalid hashed host line %lu of %s", + linenum, path); continue; } if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) @@ -303,98 +286,167 @@ check_host_in_hostfile_by_key_or_type(const char *filename, /* Got a match. Skip host name. */ cp = cp2; - if (want_revocation) - found = key_new(KEY_UNSPEC); - /* * Extract the key from the line. This will skip any leading * whitespace. Ignore badly formatted lines. */ - if (!hostfile_read_key(&cp, &kbits, found)) - continue; - - if (numret != NULL) - *numret = linenum; - - if (key == NULL) { - /* we found a key of the requested type */ - if (found->type == keytype) { - fclose(f); - return HOST_FOUND; + key = key_new(KEY_UNSPEC); + if (!hostfile_read_key(&cp, &kbits, key)) { + key_free(key); + key = key_new(KEY_RSA1); + if (!hostfile_read_key(&cp, &kbits, key)) { + key_free(key); + continue; } - continue; } - - if (!hostfile_check_key(kbits, found, host, filename, linenum)) + if (!hostfile_check_key(kbits, key, host, path, linenum)) continue; - if (want_revocation) { - if (key_is_cert(key) && - key_equal_public(key->cert->signature_key, found)) { - verbose("check_host_in_hostfile: revoked CA " - "line %d", linenum); - key_free(found); - return HOST_REVOKED; - } - if (key_equal_public(key, found)) { - verbose("check_host_in_hostfile: revoked key " - "line %d", linenum); - key_free(found); - return HOST_REVOKED; - } - key_free(found); - continue; - } - - /* Check if the current key is the same as the given key. */ - if (want_cert && key_equal(key->cert->signature_key, found)) { - /* Found CA cert for key */ - debug3("check_host_in_hostfile: CA match line %d", - linenum); - fclose(f); - return HOST_OK; - } else if (!want_cert && key_equal(key, found)) { - /* Found identical key */ - debug3("check_host_in_hostfile: match line %d", linenum); - fclose(f); - return HOST_OK; - } - /* - * They do not match. We will continue to go through the - * file; however, we note that we will not return that it is - * new. - */ - end_return = HOST_CHANGED; + debug3("%s: found %skey type %s in file %s:%lu", __func__, + marker == MRK_NONE ? "" : + (marker == MRK_CA ? "ca " : "revoked "), + key_type(key), path, linenum); + hostkeys->entries = xrealloc(hostkeys->entries, + hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); + hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); + hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); + hostkeys->entries[hostkeys->num_entries].line = linenum; + hostkeys->entries[hostkeys->num_entries].key = key; + hostkeys->entries[hostkeys->num_entries].marker = marker; + hostkeys->num_entries++; + num_loaded++; } - /* Clear variables and close the file. */ + debug3("%s: loaded %lu keys", __func__, num_loaded); fclose(f); + return; +} - /* - * Return either HOST_NEW or HOST_CHANGED, depending on whether we - * saw a different key for the host. - */ - return end_return; +void +free_hostkeys(struct hostkeys *hostkeys) +{ + u_int i; + + for (i = 0; i < hostkeys->num_entries; i++) { + xfree(hostkeys->entries[i].host); + xfree(hostkeys->entries[i].file); + key_free(hostkeys->entries[i].key); + bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); + } + if (hostkeys->entries != NULL) + xfree(hostkeys->entries); + hostkeys->entries = NULL; + hostkeys->num_entries = 0; + xfree(hostkeys); } +static int +check_key_not_revoked(struct hostkeys *hostkeys, Key *k) +{ + int is_cert = key_is_cert(k); + u_int i; + + for (i = 0; i < hostkeys->num_entries; i++) { + if (hostkeys->entries[i].marker != MRK_REVOKE) + continue; + if (key_equal_public(k, hostkeys->entries[i].key)) + return -1; + if (is_cert && + key_equal_public(k->cert->signature_key, + hostkeys->entries[i].key)) + return -1; + } + return 0; +} + +/* + * Match keys against a specified key, or look one up by key type. + * + * If looking for a keytype (key == NULL) and one is found then return + * HOST_FOUND, otherwise HOST_NEW. + * + * If looking for a key (key != NULL): + * 1. If the key is a cert and a matching CA is found, return HOST_OK + * 2. If the key is not a cert and a matching key is found, return HOST_OK + * 3. If no key matches but a key with a different type is found, then + * return HOST_CHANGED + * 4. If no matching keys are found, then return HOST_NEW. + * + * Finally, check any found key is not revoked. + */ +static HostStatus +check_hostkeys_by_key_or_type(struct hostkeys *hostkeys, + Key *k, int keytype, const struct hostkey_entry **found) +{ + u_int i; + HostStatus end_return = HOST_NEW; + int want_cert = key_is_cert(k); + HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE; + int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2; + + if (found != NULL) + *found = NULL; + + for (i = 0; i < hostkeys->num_entries; i++) { + if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1) + continue; + if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1) + continue; + if (hostkeys->entries[i].marker != want_marker) + continue; + if (k == NULL) { + if (hostkeys->entries[i].key->type != keytype) + continue; + end_return = HOST_FOUND; + if (found != NULL) + *found = hostkeys->entries + i; + k = hostkeys->entries[i].key; + break; + } + if (want_cert) { + if (key_equal_public(k->cert->signature_key, + hostkeys->entries[i].key)) { + /* A matching CA exists */ + end_return = HOST_OK; + if (found != NULL) + *found = hostkeys->entries + i; + break; + } + } else { + if (key_equal(k, hostkeys->entries[i].key)) { + end_return = HOST_OK; + if (found != NULL) + *found = hostkeys->entries + i; + break; + } + /* A non-maching key exists */ + end_return = HOST_CHANGED; + if (found != NULL) + *found = hostkeys->entries + i; + } + } + if (check_key_not_revoked(hostkeys, k) != 0) { + end_return = HOST_REVOKED; + if (found != NULL) + *found = NULL; + } + return end_return; +} + HostStatus -check_host_in_hostfile(const char *filename, const char *host, const Key *key, - Key *found, int *numret) +check_key_in_hostkeys(struct hostkeys *hostkeys, Key *key, + const struct hostkey_entry **found) { if (key == NULL) fatal("no key to look up"); - if (check_host_in_hostfile_by_key_or_type(filename, host, - key, 0, NULL, 1, NULL) == HOST_REVOKED) - return HOST_REVOKED; - return check_host_in_hostfile_by_key_or_type(filename, host, key, 0, - found, 0, numret); + return check_hostkeys_by_key_or_type(hostkeys, key, 0, found); } int -lookup_key_in_hostfile_by_type(const char *filename, const char *host, - int keytype, Key *found, int *numret) +lookup_key_in_hostkeys_by_type(struct hostkeys *hostkeys, int keytype, + const struct hostkey_entry **found) { - return (check_host_in_hostfile_by_key_or_type(filename, host, NULL, - keytype, found, 0, numret) == HOST_FOUND); + return (check_hostkeys_by_key_or_type(hostkeys, NULL, keytype, + found) == HOST_FOUND); } /* diff --git a/hostfile.h b/hostfile.h index 1d460c1a915d..d84d422ff6ee 100644 --- a/hostfile.h +++ b/hostfile.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hostfile.h,v 1.18 2010/03/04 10:36:03 djm Exp $ */ +/* $OpenBSD: hostfile.h,v 1.19 2010/11/29 23:45:51 djm Exp $ */ /* * Author: Tatu Ylonen @@ -18,12 +18,30 @@ typedef enum { HOST_OK, HOST_NEW, HOST_CHANGED, HOST_REVOKED, HOST_FOUND } HostStatus; +typedef enum { + MRK_ERROR, MRK_NONE, MRK_REVOKE, MRK_CA +} HostkeyMarker; + +struct hostkey_entry { + char *host; + char *file; + u_long line; + Key *key; + HostkeyMarker marker; +}; +struct hostkeys; + +struct hostkeys *init_hostkeys(void); +void load_hostkeys(struct hostkeys *, const char *, const char *); +void free_hostkeys(struct hostkeys *); + +HostStatus check_key_in_hostkeys(struct hostkeys *, Key *, + const struct hostkey_entry **); +int lookup_key_in_hostkeys_by_type(struct hostkeys *, int, + const struct hostkey_entry **); + int hostfile_read_key(char **, u_int *, Key *); -HostStatus check_host_in_hostfile(const char *, const char *, - const Key *, Key *, int *); -int add_host_to_hostfile(const char *, const char *, const Key *, int); -int lookup_key_in_hostfile_by_type(const char *, const char *, - int, Key *, int *); +int add_host_to_hostfile(const char *, const char *, const Key *, int); #define HASH_MAGIC "|1|" #define HASH_DELIM '|' diff --git a/includes.h b/includes.h index 6bb98780729c..b4c53d9b4fd0 100644 --- a/includes.h +++ b/includes.h @@ -30,7 +30,7 @@ # include #endif #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ - defined(GLOB_HAS_GL_MATCHC) && \ + defined(GLOB_HAS_GL_MATCHC) && defined(GLOB_HAS_GL_STATV) && \ defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \ !defined(BROKEN_GLOB) # include diff --git a/jpake.c b/jpake.c index cdf65f509228..ac9a4bc34ad6 100644 --- a/jpake.c +++ b/jpake.c @@ -1,4 +1,4 @@ -/* $OpenBSD: jpake.c,v 1.4 2010/07/13 23:13:16 djm Exp $ */ +/* $OpenBSD: jpake.c,v 1.6 2010/09/20 04:54:07 djm Exp $ */ /* * Copyright (c) 2008 Damien Miller. All rights reserved. * @@ -45,6 +45,7 @@ #include "packet.h" #include "dispatch.h" #include "log.h" +#include "misc.h" #include "jpake.h" #include "schnorr.h" @@ -257,8 +258,12 @@ jpake_step2(struct modp_group *grp, BIGNUM *s, /* Validate peer's step 1 values */ if (BN_cmp(theirpub1, BN_value_one()) <= 0) fatal("%s: theirpub1 <= 1", __func__); + if (BN_cmp(theirpub1, grp->p) >= 0) + fatal("%s: theirpub1 >= p", __func__); if (BN_cmp(theirpub2, BN_value_one()) <= 0) fatal("%s: theirpub2 <= 1", __func__); + if (BN_cmp(theirpub2, grp->p) >= 0) + fatal("%s: theirpub2 >= p", __func__); if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1, theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1) @@ -363,6 +368,8 @@ jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val, /* Validate step 2 values */ if (BN_cmp(step2_val, BN_value_one()) <= 0) fatal("%s: step2_val <= 1", __func__); + if (BN_cmp(step2_val, grp->p) >= 0) + fatal("%s: step2_val >= p", __func__); /* * theirpriv2_s_proof is calculated with a different generator: diff --git a/kex.c b/kex.c index 148cfee8046a..c65e28f94dec 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.82 2009/10/24 11:13:54 andreas Exp $ */ +/* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -62,6 +62,34 @@ extern const EVP_MD *evp_ssh_sha256(void); static void kex_kexinit_finish(Kex *); static void kex_choose_conf(Kex *); +/* Validate KEX method name list */ +int +kex_names_valid(const char *names) +{ + char *s, *cp, *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + s = cp = xstrdup(names); + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (strcmp(p, KEX_DHGEX_SHA256) != 0 && + strcmp(p, KEX_DHGEX_SHA1) != 0 && + strcmp(p, KEX_DH14) != 0 && + strcmp(p, KEX_DH1) != 0 && + (strncmp(p, KEX_ECDH_SHA2_STEM, + sizeof(KEX_ECDH_SHA2_STEM) - 1) != 0 || + kex_ecdh_name_to_nid(p) == -1)) { + error("Unsupported KEX algorithm \"%.100s\"", p); + xfree(s); + return 0; + } + } + debug3("kex names ok: [%s]", names); + xfree(s); + return 1; +} + /* put algorithm proposal into buffer */ static void kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) @@ -98,7 +126,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows) buffer_get_char(&b); /* extract kex init proposal strings */ for (i = 0; i < PROPOSAL_MAX; i++) { - proposal[i] = buffer_get_string(&b,NULL); + proposal[i] = buffer_get_cstring(&b,NULL); debug2("kex_parse_kexinit: %s", proposal[i]); } /* first kex follows / reserved */ @@ -325,6 +353,10 @@ choose_kex(Kex *k, char *client, char *server) } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) { k->kex_type = KEX_DH_GEX_SHA256; k->evp_md = evp_ssh_sha256(); + } else if (strncmp(k->name, KEX_ECDH_SHA2_STEM, + sizeof(KEX_ECDH_SHA2_STEM) - 1) == 0) { + k->kex_type = KEX_ECDH_SHA2; + k->evp_md = kex_ecdh_name_to_evpmd(k->name); #endif } else fatal("bad kex alg %s", k->name); @@ -559,11 +591,11 @@ derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, memset(&md, 0, sizeof(md)); } -#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) +#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) void dump_digest(char *msg, u_char *digest, int len) { - u_int i; + int i; fprintf(stderr, "%s\n", msg); for (i = 0; i < len; i++) { diff --git a/kex.h b/kex.h index 62fa2ea50f0c..7373d3c789f4 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.49 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -29,6 +29,9 @@ #include #include #include +#ifdef OPENSSL_HAS_ECC +#include +#endif #define KEX_COOKIE_LEN 16 @@ -37,6 +40,8 @@ #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" #define KEX_RESUME "resume@appgate.com" +/* The following represents the family of ECDH methods */ +#define KEX_ECDH_SHA2_STEM "ecdh-sha2-" #define COMP_NONE 0 #define COMP_ZLIB 1 @@ -67,6 +72,7 @@ enum kex_exchange { KEX_DH_GRP14_SHA1, KEX_DH_GEX_SHA1, KEX_DH_GEX_SHA256, + KEX_ECDH_SHA2, KEX_MAX }; @@ -132,6 +138,8 @@ struct Kex { void (*kex[KEX_MAX])(Kex *); }; +int kex_names_valid(const char *); + Kex *kex_setup(char *[PROPOSAL_MAX]); void kex_finish(Kex *); @@ -145,6 +153,8 @@ void kexdh_client(Kex *); void kexdh_server(Kex *); void kexgex_client(Kex *); void kexgex_server(Kex *); +void kexecdh_client(Kex *); +void kexecdh_server(Kex *); void kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, @@ -153,11 +163,22 @@ void kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *, int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); +#ifdef OPENSSL_HAS_ECC +void +kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int, + char *, int, u_char *, int, const EC_POINT *, const EC_POINT *, + const BIGNUM *, u_char **, u_int *); +int kex_ecdh_name_to_nid(const char *); +const EVP_MD *kex_ecdh_name_to_evpmd(const char *); +#else +# define kex_ecdh_name_to_nid(x) (-1) +# define kex_ecdh_name_to_evpmd(x) (NULL) +#endif void derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); -#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) +#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) void dump_digest(char *, u_char *, int); #endif diff --git a/kexdhc.c b/kexdhc.c index d384c8052b60..76ceb5dd89e0 100644 --- a/kexdhc.c +++ b/kexdhc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhc.c,v 1.11 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: kexdhc.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -27,6 +27,8 @@ #include +#include + #include #include #include diff --git a/kexdhs.c b/kexdhs.c index e722877d5f86..f56e88764a7c 100644 --- a/kexdhs.c +++ b/kexdhs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexdhs.c,v 1.11 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: kexdhs.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -31,6 +31,8 @@ #include #include +#include + #include "xmalloc.h" #include "buffer.h" #include "key.h" diff --git a/kexecdh.c b/kexecdh.c new file mode 100644 index 000000000000..f13f69d3b335 --- /dev/null +++ b/kexecdh.c @@ -0,0 +1,117 @@ +/* $OpenBSD: kexecdh.c,v 1.3 2010/09/22 05:01:29 djm Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef OPENSSL_HAS_ECC + +#include + +#include +#include + +#include +#include +#include +#include + +#include "buffer.h" +#include "ssh2.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" + +int +kex_ecdh_name_to_nid(const char *kexname) +{ + if (strlen(kexname) < sizeof(KEX_ECDH_SHA2_STEM) - 1) + fatal("%s: kexname too short \"%s\"", __func__, kexname); + return key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1); +} + +const EVP_MD * +kex_ecdh_name_to_evpmd(const char *kexname) +{ + int nid = kex_ecdh_name_to_nid(kexname); + + if (nid == -1) + fatal("%s: unsupported ECDH curve \"%s\"", __func__, kexname); + return key_ec_nid_to_evpmd(nid); +} + +void +kex_ecdh_hash( + const EVP_MD *evp_md, + const EC_GROUP *ec_group, + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + u_char *serverhostkeyblob, int sbloblen, + const EC_POINT *client_dh_pub, + const EC_POINT *server_dh_pub, + const BIGNUM *shared_secret, + u_char **hash, u_int *hashlen) +{ + Buffer b; + EVP_MD_CTX md; + static u_char digest[EVP_MAX_MD_SIZE]; + + buffer_init(&b); + buffer_put_cstring(&b, client_version_string); + buffer_put_cstring(&b, server_version_string); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_ecpoint(&b, ec_group, client_dh_pub); + buffer_put_ecpoint(&b, ec_group, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest("hash", digest, EVP_MD_size(evp_md)); +#endif + *hash = digest; + *hashlen = EVP_MD_size(evp_md); +} + +#endif /* OPENSSL_HAS_ECC */ diff --git a/kexecdhc.c b/kexecdhc.c new file mode 100644 index 000000000000..115d4bf83451 --- /dev/null +++ b/kexecdhc.c @@ -0,0 +1,168 @@ +/* $OpenBSD: kexecdhc.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include + +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" + +#ifdef OPENSSL_HAS_ECC + +#include + +void +kexecdh_client(Kex *kex) +{ + EC_KEY *client_key; + EC_POINT *server_public; + const EC_GROUP *group; + BIGNUM *shared_secret; + Key *server_host_key; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, slen, sbloblen, hashlen; + int curve_nid; + + if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) + fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); + if ((client_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_generate_key(client_key) != 1) + fatal("%s: EC_KEY_generate_key failed", __func__); + group = EC_KEY_get0_group(client_key); + + packet_start(SSH2_MSG_KEX_ECDH_INIT); + packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key)); + packet_send(); + debug("sending SSH2_MSG_KEX_ECDH_INIT"); + +#ifdef DEBUG_KEXECDH + fputs("client private key:\n", stderr); + key_dump_ec_key(client_key); +#endif + + debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); + packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); + + /* hostkey */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* Q_S, server public key */ + if ((server_public = EC_POINT_new(group)) == NULL) + fatal("%s: EC_POINT_new failed", __func__); + packet_get_ecpoint(group, server_public); + + if (key_ec_validate_public(group, server_public) != 0) + fatal("%s: invalid server public key", __func__); + +#ifdef DEBUG_KEXECDH + fputs("server public key:\n", stderr); + key_dump_ec_point(group, server_public); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + klen = (EC_GROUP_get_degree(group) + 7) / 8; + kbuf = xmalloc(klen); + if (ECDH_compute_key(kbuf, klen, server_public, + client_key, NULL) != (int)klen) + fatal("%s: ECDH_compute_key failed", __func__); + +#ifdef DEBUG_KEXECDH + dump_digest("shared secret", kbuf, klen); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) + fatal("%s: BN_bin2bn failed", __func__); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + kex_ecdh_hash( + kex->evp_md, + group, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + EC_KEY_get0_public_key(client_key), + server_public, + shared_secret, + &hash, &hashlen + ); + xfree(server_host_key_blob); + EC_POINT_clear_free(server_public); + EC_KEY_free(client_key); + + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} +#else /* OPENSSL_HAS_ECC */ +void +kexecdh_client(Kex *kex) +{ + fatal("ECC support is not enabled"); +} +#endif /* OPENSSL_HAS_ECC */ diff --git a/kexecdhs.c b/kexecdhs.c new file mode 100644 index 000000000000..8c515dfa61cf --- /dev/null +++ b/kexecdhs.c @@ -0,0 +1,173 @@ +/* $OpenBSD: kexecdhs.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +#ifdef OPENSSL_HAS_ECC + +#include + +void +kexecdh_server(Kex *kex) +{ + EC_POINT *client_public; + EC_KEY *server_key; + const EC_GROUP *group; + BIGNUM *shared_secret; + Key *server_host_private, *server_host_public; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, slen, sbloblen, hashlen; + int curve_nid; + + if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) + fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); + if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_generate_key(server_key) != 1) + fatal("%s: EC_KEY_generate_key failed", __func__); + group = EC_KEY_get0_group(server_key); + +#ifdef DEBUG_KEXECDH + fputs("server private key:\n", stderr); + key_dump_ec_key(server_key); +#endif + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) + fatal("Cannot load hostkey"); + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + if (server_host_private == NULL) + fatal("Missing private key for hostkey type %d", + kex->hostkey_type); + + debug("expecting SSH2_MSG_KEX_ECDH_INIT"); + packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); + if ((client_public = EC_POINT_new(group)) == NULL) + fatal("%s: EC_POINT_new failed", __func__); + packet_get_ecpoint(group, client_public); + packet_check_eom(); + + if (key_ec_validate_public(group, client_public) != 0) + fatal("%s: invalid client public key", __func__); + +#ifdef DEBUG_KEXECDH + fputs("client public key:\n", stderr); + key_dump_ec_point(group, client_public); +#endif + + /* Calculate shared_secret */ + klen = (EC_GROUP_get_degree(group) + 7) / 8; + kbuf = xmalloc(klen); + if (ECDH_compute_key(kbuf, klen, client_public, + server_key, NULL) != (int)klen) + fatal("%s: ECDH_compute_key failed", __func__); + +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, klen); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) + fatal("%s: BN_bin2bn failed", __func__); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc H */ + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); + kex_ecdh_hash( + kex->evp_md, + group, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + client_public, + EC_KEY_get0_public_key(server_key), + shared_secret, + &hash, &hashlen + ); + EC_POINT_clear_free(client_public); + + /* save session id := H */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + if (PRIVSEP(key_sign(server_host_private, &signature, &slen, + hash, hashlen)) < 0) + fatal("kexdh_server: key_sign failed"); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ + packet_start(SSH2_MSG_KEX_ECDH_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key)); + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free server key */ + EC_KEY_free(server_key); + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} +#else /* OPENSSL_HAS_ECC */ +void +kexecdh_server(Kex *kex) +{ + fatal("ECC support is not enabled"); +} +#endif /* OPENSSL_HAS_ECC */ diff --git a/kexgexc.c b/kexgexc.c index adb973d5b40c..79552d70983a 100644 --- a/kexgexc.c +++ b/kexgexc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexc.c,v 1.11 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: kexgexc.c,v 1.12 2010/11/10 01:33:07 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -28,6 +28,8 @@ #include +#include + #include #include #include diff --git a/kexgexs.c b/kexgexs.c index f4156af96362..a5e3df7bcc3b 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.13 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.14 2010/11/10 01:33:07 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -33,6 +33,8 @@ #include #include +#include + #include "xmalloc.h" #include "buffer.h" #include "key.h" diff --git a/key.c b/key.c index e4aa25c035f9..1defb1132e82 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.90 2010/07/13 23:13:16 djm Exp $ */ +/* $OpenBSD: key.c,v 1.95 2010/11/10 01:33:07 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -78,6 +78,8 @@ key_new(int type) DSA *dsa; k = xcalloc(1, sizeof(*k)); k->type = type; + k->ecdsa = NULL; + k->ecdsa_nid = -1; k->dsa = NULL; k->rsa = NULL; k->cert = NULL; @@ -109,6 +111,12 @@ key_new(int type) fatal("key_new: BN_new failed"); k->dsa = dsa; break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + /* Cannot do anything until we know the group */ + break; +#endif case KEY_UNSPEC: break; default: @@ -149,6 +157,10 @@ key_add_private(Key *k) if ((k->dsa->priv_key = BN_new()) == NULL) fatal("key_new_private: BN_new failed"); break; + case KEY_ECDSA: + case KEY_ECDSA_CERT: + /* Cannot do anything until we know the group */ + break; case KEY_UNSPEC: break; default: @@ -204,6 +216,14 @@ key_free(Key *k) DSA_free(k->dsa); k->dsa = NULL; break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + if (k->ecdsa != NULL) + EC_KEY_free(k->ecdsa); + k->ecdsa = NULL; + break; +#endif case KEY_UNSPEC: break; default: @@ -241,6 +261,10 @@ cert_compare(struct KeyCert *a, struct KeyCert *b) int key_equal_public(const Key *a, const Key *b) { +#ifdef OPENSSL_HAS_ECC + BN_CTX *bnctx; +#endif + if (a == NULL || b == NULL || key_type_plain(a->type) != key_type_plain(b->type)) return 0; @@ -261,6 +285,26 @@ key_equal_public(const Key *a, const Key *b) BN_cmp(a->dsa->q, b->dsa->q) == 0 && BN_cmp(a->dsa->g, b->dsa->g) == 0 && BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: + if (a->ecdsa == NULL || b->ecdsa == NULL || + EC_KEY_get0_public_key(a->ecdsa) == NULL || + EC_KEY_get0_public_key(b->ecdsa) == NULL) + return 0; + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), + EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || + EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), + EC_KEY_get0_public_key(a->ecdsa), + EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { + BN_CTX_free(bnctx); + return 0; + } + BN_CTX_free(bnctx); + return 1; +#endif /* OPENSSL_HAS_ECC */ default: fatal("key_equal: bad key type %d", a->type); } @@ -312,12 +356,14 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) BN_bn2bin(k->rsa->e, blob + nlen); break; case KEY_DSA: + case KEY_ECDSA: case KEY_RSA: key_to_blob(k, &blob, &len); break; case KEY_DSA_CERT_V00: case KEY_RSA_CERT_V00: case KEY_DSA_CERT: + case KEY_ECDSA_CERT: case KEY_RSA_CERT: /* We want a fingerprint of the _key_ not of the cert */ otype = k->type; @@ -615,6 +661,9 @@ key_read(Key *ret, char **cpp) int len, n, type; u_int bits; u_char *blob; +#ifdef OPENSSL_HAS_ECC + int curve_nid = -1; +#endif cp = *cpp; @@ -644,9 +693,11 @@ key_read(Key *ret, char **cpp) case KEY_UNSPEC: case KEY_RSA: case KEY_DSA: + case KEY_ECDSA: case KEY_DSA_CERT_V00: case KEY_RSA_CERT_V00: case KEY_DSA_CERT: + case KEY_ECDSA_CERT: case KEY_RSA_CERT: space = strchr(cp, ' '); if (space == NULL) { @@ -655,6 +706,13 @@ key_read(Key *ret, char **cpp) } *space = '\0'; type = key_type_from_name(cp); +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(type) == KEY_ECDSA && + (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) { + debug("key_read: invalid curve"); + return -1; + } +#endif *space = ' '; if (type == KEY_UNSPEC) { debug3("key_read: missing keytype"); @@ -691,6 +749,14 @@ key_read(Key *ret, char **cpp) key_free(k); return -1; } +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(type) == KEY_ECDSA && + curve_nid != k->ecdsa_nid) { + error("key_read: type mismatch: EC curve mismatch"); + key_free(k); + return -1; + } +#endif /*XXXX*/ if (key_is_cert(ret)) { if (!key_is_cert(k)) { @@ -721,6 +787,19 @@ key_read(Key *ret, char **cpp) DSA_print_fp(stderr, ret->dsa, 8); #endif } +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(ret->type) == KEY_ECDSA) { + if (ret->ecdsa != NULL) + EC_KEY_free(ret->ecdsa); + ret->ecdsa = k->ecdsa; + ret->ecdsa_nid = k->ecdsa_nid; + k->ecdsa = NULL; + k->ecdsa_nid = -1; +#ifdef DEBUG_PK + key_dump_ec_key(ret->ecdsa); +#endif + } +#endif success = 1; /*XXXX*/ key_free(k); @@ -777,6 +856,13 @@ key_write(const Key *key, FILE *f) if (key->dsa == NULL) return 0; break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + if (key->ecdsa == NULL) + return 0; + break; +#endif case KEY_RSA: case KEY_RSA_CERT_V00: case KEY_RSA_CERT: @@ -810,6 +896,10 @@ key_type(const Key *k) return "RSA"; case KEY_DSA: return "DSA"; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + return "ECDSA"; +#endif case KEY_RSA_CERT_V00: return "RSA-CERT-V00"; case KEY_DSA_CERT_V00: @@ -818,6 +908,10 @@ key_type(const Key *k) return "RSA-CERT"; case KEY_DSA_CERT: return "DSA-CERT"; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + return "ECDSA-CERT"; +#endif } return "unknown"; } @@ -835,10 +929,10 @@ key_cert_type(const Key *k) } } -const char * -key_ssh_name(const Key *k) +static const char * +key_ssh_name_from_type_nid(int type, int nid) { - switch (k->type) { + switch (type) { case KEY_RSA: return "ssh-rsa"; case KEY_DSA: @@ -851,10 +945,49 @@ key_ssh_name(const Key *k) return "ssh-rsa-cert-v01@openssh.com"; case KEY_DSA_CERT: return "ssh-dss-cert-v01@openssh.com"; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + switch (nid) { + case NID_X9_62_prime256v1: + return "ecdsa-sha2-nistp256"; + case NID_secp384r1: + return "ecdsa-sha2-nistp384"; + case NID_secp521r1: + return "ecdsa-sha2-nistp521"; + default: + break; + } + break; + case KEY_ECDSA_CERT: + switch (nid) { + case NID_X9_62_prime256v1: + return "ecdsa-sha2-nistp256-cert-v01@openssh.com"; + case NID_secp384r1: + return "ecdsa-sha2-nistp384-cert-v01@openssh.com"; + case NID_secp521r1: + return "ecdsa-sha2-nistp521-cert-v01@openssh.com"; + default: + break; + } + break; +#endif /* OPENSSL_HAS_ECC */ } return "ssh-unknown"; } +const char * +key_ssh_name(const Key *k) +{ + return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid); +} + +const char * +key_ssh_name_plain(const Key *k) +{ + return key_ssh_name_from_type_nid(key_type_plain(k->type), + k->ecdsa_nid); +} + u_int key_size(const Key *k) { @@ -868,6 +1001,11 @@ key_size(const Key *k) case KEY_DSA_CERT_V00: case KEY_DSA_CERT: return BN_num_bits(k->dsa->p); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + return key_curve_nid_to_bits(k->ecdsa_nid); +#endif } return 0; } @@ -875,28 +1013,116 @@ key_size(const Key *k) static RSA * rsa_generate_private_key(u_int bits) { - RSA *private; + RSA *private = RSA_new(); + BIGNUM *f4 = BN_new(); - private = RSA_generate_key(bits, RSA_F4, NULL, NULL); if (private == NULL) - fatal("rsa_generate_private_key: key generation failed."); + fatal("%s: RSA_new failed", __func__); + if (f4 == NULL) + fatal("%s: BN_new failed", __func__); + if (!BN_set_word(f4, RSA_F4)) + fatal("%s: BN_new failed", __func__); + if (!RSA_generate_key_ex(private, bits, f4, NULL)) + fatal("%s: key generation failed.", __func__); + BN_free(f4); return private; } static DSA* dsa_generate_private_key(u_int bits) { - DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); + DSA *private = DSA_new(); if (private == NULL) - fatal("dsa_generate_private_key: DSA_generate_parameters failed"); + fatal("%s: DSA_new failed", __func__); + if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, + NULL, NULL)) + fatal("%s: DSA_generate_parameters failed", __func__); if (!DSA_generate_key(private)) - fatal("dsa_generate_private_key: DSA_generate_key failed."); - if (private == NULL) - fatal("dsa_generate_private_key: NULL."); + fatal("%s: DSA_generate_key failed.", __func__); return private; } +int +key_ecdsa_bits_to_nid(int bits) +{ + switch (bits) { +#ifdef OPENSSL_HAS_ECC + case 256: + return NID_X9_62_prime256v1; + case 384: + return NID_secp384r1; + case 521: + return NID_secp521r1; +#endif + default: + return -1; + } +} + +#ifdef OPENSSL_HAS_ECC +int +key_ecdsa_key_to_nid(EC_KEY *k) +{ + EC_GROUP *eg; + int nids[] = { + NID_X9_62_prime256v1, + NID_secp384r1, + NID_secp521r1, + -1 + }; + int nid; + u_int i; + BN_CTX *bnctx; + const EC_GROUP *g = EC_KEY_get0_group(k); + + /* + * The group may be stored in a ASN.1 encoded private key in one of two + * ways: as a "named group", which is reconstituted by ASN.1 object ID + * or explicit group parameters encoded into the key blob. Only the + * "named group" case sets the group NID for us, but we can figure + * it out for the other case by comparing against all the groups that + * are supported. + */ + if ((nid = EC_GROUP_get_curve_name(g)) > 0) + return nid; + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new() failed", __func__); + for (i = 0; nids[i] != -1; i++) { + if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) + fatal("%s: EC_GROUP_new_by_curve_name failed", + __func__); + if (EC_GROUP_cmp(g, eg, bnctx) == 0) + break; + EC_GROUP_free(eg); + } + BN_CTX_free(bnctx); + debug3("%s: nid = %d", __func__, nids[i]); + if (nids[i] != -1) { + /* Use the group with the NID attached */ + EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(k, eg) != 1) + fatal("%s: EC_KEY_set_group", __func__); + } + return nids[i]; +} + +static EC_KEY* +ecdsa_generate_private_key(u_int bits, int *nid) +{ + EC_KEY *private; + + if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1) + fatal("%s: invalid key length", __func__); + if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_generate_key(private) != 1) + fatal("%s: EC_KEY_generate_key failed", __func__); + EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); + return private; +} +#endif /* OPENSSL_HAS_ECC */ + Key * key_generate(int type, u_int bits) { @@ -905,6 +1131,11 @@ key_generate(int type, u_int bits) case KEY_DSA: k->dsa = dsa_generate_private_key(bits); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid); + break; +#endif case KEY_RSA: case KEY_RSA1: k->rsa = rsa_generate_private_key(bits); @@ -981,6 +1212,18 @@ key_from_private(const Key *k) (BN_copy(n->dsa->pub_key, k->dsa->pub_key) == NULL)) fatal("key_from_private: BN_copy failed"); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + n = key_new(k->type); + n->ecdsa_nid = k->ecdsa_nid; + if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_set_public_key(n->ecdsa, + EC_KEY_get0_public_key(k->ecdsa)) != 1) + fatal("%s: EC_KEY_set_public_key failed", __func__); + break; +#endif case KEY_RSA: case KEY_RSA1: case KEY_RSA_CERT_V00: @@ -1012,6 +1255,13 @@ key_type_from_name(char *name) return KEY_RSA; } else if (strcmp(name, "ssh-dss") == 0) { return KEY_DSA; +#ifdef OPENSSL_HAS_ECC + } else if (strcmp(name, "ecdsa") == 0 || + strcmp(name, "ecdsa-sha2-nistp256") == 0 || + strcmp(name, "ecdsa-sha2-nistp384") == 0 || + strcmp(name, "ecdsa-sha2-nistp521") == 0) { + return KEY_ECDSA; +#endif } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { return KEY_RSA_CERT_V00; } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { @@ -1020,11 +1270,37 @@ key_type_from_name(char *name) return KEY_RSA_CERT; } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { return KEY_DSA_CERT; +#ifdef OPENSSL_HAS_ECC + } else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0 || + strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0 || + strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) { + return KEY_ECDSA_CERT; +#endif } + debug2("key_type_from_name: unknown key type '%s'", name); return KEY_UNSPEC; } +int +key_ecdsa_nid_from_name(const char *name) +{ +#ifdef OPENSSL_HAS_ECC + if (strcmp(name, "ecdsa-sha2-nistp256") == 0 || + strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0) + return NID_X9_62_prime256v1; + if (strcmp(name, "ecdsa-sha2-nistp384") == 0 || + strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0) + return NID_secp384r1; + if (strcmp(name, "ecdsa-sha2-nistp521") == 0 || + strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) + return NID_secp521r1; +#endif /* OPENSSL_HAS_ECC */ + + debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name); + return -1; +} + int key_names_valid2(const char *names) { @@ -1067,7 +1343,7 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) principals = exts = critical = sig_key = sig = NULL; if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || buffer_get_int_ret(&key->cert->type, b) != 0 || - (key->cert->key_id = buffer_get_string_ret(b, &kidlen)) == NULL || + (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL || (principals = buffer_get_string_ret(b, &plen)) == NULL || buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || @@ -1105,15 +1381,10 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) error("%s: Too many principals", __func__); goto out; } - if ((principal = buffer_get_string_ret(&tmp, &plen)) == NULL) { + if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) { error("%s: Principals data invalid", __func__); goto out; } - if (strlen(principal) != plen) { - error("%s: Principal contains \\0 character", - __func__); - goto out; - } key->cert->principals = xrealloc(key->cert->principals, key->cert->nprincipals + 1, sizeof(*key->cert->principals)); key->cert->principals[key->cert->nprincipals++] = principal; @@ -1151,7 +1422,8 @@ cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) goto out; } if (key->cert->signature_key->type != KEY_RSA && - key->cert->signature_key->type != KEY_DSA) { + key->cert->signature_key->type != KEY_DSA && + key->cert->signature_key->type != KEY_ECDSA) { error("%s: Invalid signature key type %s (%d)", __func__, key_type(key->cert->signature_key), key->cert->signature_key->type); @@ -1192,20 +1464,28 @@ key_from_blob(const u_char *blob, u_int blen) { Buffer b; int rlen, type; - char *ktype = NULL; + char *ktype = NULL, *curve = NULL; Key *key = NULL; +#ifdef OPENSSL_HAS_ECC + EC_POINT *q = NULL; + int nid = -1; +#endif #ifdef DEBUG_PK dump_base64(stderr, blob, blen); #endif buffer_init(&b); buffer_append(&b, blob, blen); - if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) { + if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) { error("key_from_blob: can't read key type"); goto out; } type = key_type_from_name(ktype); +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(type) == KEY_ECDSA) + nid = key_ecdsa_nid_from_name(ktype); +#endif switch (type) { case KEY_RSA_CERT: @@ -1243,6 +1523,43 @@ key_from_blob(const u_char *blob, u_int blen) DSA_print_fp(stderr, key->dsa, 8); #endif break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ + /* FALLTHROUGH */ + case KEY_ECDSA: + key = key_new(type); + key->ecdsa_nid = nid; + if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) { + error("key_from_blob: can't read ecdsa curve"); + goto badkey; + } + if (key->ecdsa_nid != key_curve_name_to_nid(curve)) { + error("key_from_blob: ecdsa curve doesn't match type"); + goto badkey; + } + if (key->ecdsa != NULL) + EC_KEY_free(key->ecdsa); + if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) + == NULL) + fatal("key_from_blob: EC_KEY_new_by_curve_name failed"); + if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) + fatal("key_from_blob: EC_POINT_new failed"); + if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa), + q) == -1) { + error("key_from_blob: can't read ecdsa key point"); + goto badkey; + } + if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), + q) != 0) + goto badkey; + if (EC_KEY_set_public_key(key->ecdsa, q) != 1) + fatal("key_from_blob: EC_KEY_set_public_key failed"); +#ifdef DEBUG_PK + key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); +#endif + break; +#endif /* OPENSSL_HAS_ECC */ case KEY_UNSPEC: key = key_new(type); break; @@ -1260,6 +1577,12 @@ key_from_blob(const u_char *blob, u_int blen) out: if (ktype != NULL) xfree(ktype); + if (curve != NULL) + xfree(curve); +#ifdef OPENSSL_HAS_ECC + if (q != NULL) + EC_POINT_free(q); +#endif buffer_free(&b); return key; } @@ -1279,6 +1602,7 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) case KEY_DSA_CERT_V00: case KEY_RSA_CERT_V00: case KEY_DSA_CERT: + case KEY_ECDSA_CERT: case KEY_RSA_CERT: /* Use the existing blob */ buffer_append(&b, buffer_ptr(&key->cert->certblob), @@ -1291,6 +1615,14 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp) buffer_put_bignum2(&b, key->dsa->g); buffer_put_bignum2(&b, key->dsa->pub_key); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + buffer_put_cstring(&b, key_ssh_name(key)); + buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid)); + buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa), + EC_KEY_get0_public_key(key->ecdsa)); + break; +#endif case KEY_RSA: buffer_put_cstring(&b, key_ssh_name(key)); buffer_put_bignum2(&b, key->rsa->e); @@ -1324,6 +1656,11 @@ key_sign( case KEY_DSA_CERT: case KEY_DSA: return ssh_dss_sign(key, sigp, lenp, data, datalen); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: + return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); +#endif case KEY_RSA_CERT_V00: case KEY_RSA_CERT: case KEY_RSA: @@ -1352,6 +1689,11 @@ key_verify( case KEY_DSA_CERT: case KEY_DSA: return ssh_dss_verify(key, signature, signaturelen, data, datalen); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: + return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen); +#endif case KEY_RSA_CERT_V00: case KEY_RSA_CERT: case KEY_RSA: @@ -1371,7 +1713,9 @@ key_demote(const Key *k) pk = xcalloc(1, sizeof(*pk)); pk->type = k->type; pk->flags = k->flags; + pk->ecdsa_nid = k->ecdsa_nid; pk->dsa = NULL; + pk->ecdsa = NULL; pk->rsa = NULL; switch (k->type) { @@ -1404,6 +1748,18 @@ key_demote(const Key *k) if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) fatal("key_demote: BN_dup failed"); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ + case KEY_ECDSA: + if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL) + fatal("key_demote: EC_KEY_new_by_curve_name failed"); + if (EC_KEY_set_public_key(pk->ecdsa, + EC_KEY_get0_public_key(k->ecdsa)) != 1) + fatal("key_demote: EC_KEY_set_public_key failed"); + break; +#endif default: fatal("key_free: bad key type %d", k->type); break; @@ -1422,6 +1778,7 @@ key_is_cert(const Key *k) case KEY_DSA_CERT_V00: case KEY_RSA_CERT: case KEY_DSA_CERT: + case KEY_ECDSA_CERT: return 1; default: return 0; @@ -1439,6 +1796,8 @@ key_type_plain(int type) case KEY_DSA_CERT_V00: case KEY_DSA_CERT: return KEY_DSA; + case KEY_ECDSA_CERT: + return KEY_ECDSA; default: return type; } @@ -1457,6 +1816,10 @@ key_to_certified(Key *k, int legacy) k->cert = cert_new(); k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; return 0; + case KEY_ECDSA: + k->cert = cert_new(); + k->type = KEY_ECDSA_CERT; + return 0; default: error("%s: key has incorrect type %s", __func__, key_type(k)); return -1; @@ -1478,13 +1841,20 @@ key_drop_cert(Key *k) cert_free(k->cert); k->type = KEY_DSA; return 0; + case KEY_ECDSA_CERT: + cert_free(k->cert); + k->type = KEY_ECDSA; + return 0; default: error("%s: key has incorrect type %s", __func__, key_type(k)); return -1; } } -/* Sign a KEY_RSA_CERT or KEY_DSA_CERT, (re-)generating the signed certblob */ +/* + * Sign a KEY_RSA_CERT, KEY_DSA_CERT or KEY_ECDSA_CERT, (re-)generating + * the signed certblob + */ int key_certify(Key *k, Key *ca) { @@ -1503,7 +1873,8 @@ key_certify(Key *k, Key *ca) return -1; } - if (ca->type != KEY_RSA && ca->type != KEY_DSA) { + if (ca->type != KEY_RSA && ca->type != KEY_DSA && + ca->type != KEY_ECDSA) { error("%s: CA key has unsupported type %s", __func__, key_type(ca)); return -1; @@ -1515,7 +1886,7 @@ key_certify(Key *k, Key *ca) buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); /* -v01 certs put nonce first */ - if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) { + if (!key_cert_is_legacy(k)) { arc4random_buf(&nonce, sizeof(nonce)); buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); } @@ -1528,6 +1899,15 @@ key_certify(Key *k, Key *ca) buffer_put_bignum2(&k->cert->certblob, k->dsa->g); buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + buffer_put_cstring(&k->cert->certblob, + key_curve_nid_to_name(k->ecdsa_nid)); + buffer_put_ecpoint(&k->cert->certblob, + EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)); + break; +#endif case KEY_RSA_CERT_V00: case KEY_RSA_CERT: buffer_put_bignum2(&k->cert->certblob, k->rsa->e); @@ -1541,7 +1921,7 @@ key_certify(Key *k, Key *ca) } /* -v01 certs have a serial number next */ - if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) + if (!key_cert_is_legacy(k)) buffer_put_int64(&k->cert->certblob, k->cert->serial); buffer_put_int(&k->cert->certblob, k->cert->type); @@ -1560,14 +1940,14 @@ key_certify(Key *k, Key *ca) buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); /* -v01 certs have non-critical options here */ - if (k->type == KEY_DSA_CERT || k->type == KEY_RSA_CERT) { + if (!key_cert_is_legacy(k)) { buffer_put_string(&k->cert->certblob, buffer_ptr(&k->cert->extensions), buffer_len(&k->cert->extensions)); } /* -v00 certs put the nonce at the end */ - if (k->type == KEY_DSA_CERT_V00 || k->type == KEY_RSA_CERT_V00) + if (key_cert_is_legacy(k)) buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ @@ -1652,3 +2032,240 @@ key_cert_is_legacy(Key *k) return 0; } } + +/* XXX: these are really begging for a table-driven approach */ +int +key_curve_name_to_nid(const char *name) +{ +#ifdef OPENSSL_HAS_ECC + if (strcmp(name, "nistp256") == 0) + return NID_X9_62_prime256v1; + else if (strcmp(name, "nistp384") == 0) + return NID_secp384r1; + else if (strcmp(name, "nistp521") == 0) + return NID_secp521r1; +#endif + + debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); + return -1; +} + +u_int +key_curve_nid_to_bits(int nid) +{ + switch (nid) { +#ifdef OPENSSL_HAS_ECC + case NID_X9_62_prime256v1: + return 256; + case NID_secp384r1: + return 384; + case NID_secp521r1: + return 521; +#endif + default: + error("%s: unsupported EC curve nid %d", __func__, nid); + return 0; + } +} + +const char * +key_curve_nid_to_name(int nid) +{ +#ifdef OPENSSL_HAS_ECC + if (nid == NID_X9_62_prime256v1) + return "nistp256"; + else if (nid == NID_secp384r1) + return "nistp384"; + else if (nid == NID_secp521r1) + return "nistp521"; +#endif + error("%s: unsupported EC curve nid %d", __func__, nid); + return NULL; +} + +#ifdef OPENSSL_HAS_ECC +const EVP_MD * +key_ec_nid_to_evpmd(int nid) +{ + int kbits = key_curve_nid_to_bits(nid); + + if (kbits == 0) + fatal("%s: invalid nid %d", __func__, nid); + /* RFC5656 section 6.2.1 */ + if (kbits <= 256) + return EVP_sha256(); + else if (kbits <= 384) + return EVP_sha384(); + else + return EVP_sha512(); +} + +int +key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) +{ + BN_CTX *bnctx; + EC_POINT *nq = NULL; + BIGNUM *order, *x, *y, *tmp; + int ret = -1; + + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + BN_CTX_start(bnctx); + + /* + * We shouldn't ever hit this case because bignum_get_ecpoint() + * refuses to load GF2m points. + */ + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_prime_field) { + error("%s: group is not a prime field", __func__); + goto out; + } + + /* Q != infinity */ + if (EC_POINT_is_at_infinity(group, public)) { + error("%s: received degenerate public key (infinity)", + __func__); + goto out; + } + + if ((x = BN_CTX_get(bnctx)) == NULL || + (y = BN_CTX_get(bnctx)) == NULL || + (order = BN_CTX_get(bnctx)) == NULL || + (tmp = BN_CTX_get(bnctx)) == NULL) + fatal("%s: BN_CTX_get failed", __func__); + + /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ + if (EC_GROUP_get_order(group, order, bnctx) != 1) + fatal("%s: EC_GROUP_get_order failed", __func__); + if (EC_POINT_get_affine_coordinates_GFp(group, public, + x, y, bnctx) != 1) + fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); + if (BN_num_bits(x) <= BN_num_bits(order) / 2) { + error("%s: public key x coordinate too small: " + "bits(x) = %d, bits(order)/2 = %d", __func__, + BN_num_bits(x), BN_num_bits(order) / 2); + goto out; + } + if (BN_num_bits(y) <= BN_num_bits(order) / 2) { + error("%s: public key y coordinate too small: " + "bits(y) = %d, bits(order)/2 = %d", __func__, + BN_num_bits(x), BN_num_bits(order) / 2); + goto out; + } + + /* nQ == infinity (n == order of subgroup) */ + if ((nq = EC_POINT_new(group)) == NULL) + fatal("%s: BN_CTX_tmp failed", __func__); + if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) + fatal("%s: EC_GROUP_mul failed", __func__); + if (EC_POINT_is_at_infinity(group, nq) != 1) { + error("%s: received degenerate public key (nQ != infinity)", + __func__); + goto out; + } + + /* x < order - 1, y < order - 1 */ + if (!BN_sub(tmp, order, BN_value_one())) + fatal("%s: BN_sub failed", __func__); + if (BN_cmp(x, tmp) >= 0) { + error("%s: public key x coordinate >= group order - 1", + __func__); + goto out; + } + if (BN_cmp(y, tmp) >= 0) { + error("%s: public key y coordinate >= group order - 1", + __func__); + goto out; + } + ret = 0; + out: + BN_CTX_free(bnctx); + EC_POINT_free(nq); + return ret; +} + +int +key_ec_validate_private(const EC_KEY *key) +{ + BN_CTX *bnctx; + BIGNUM *order, *tmp; + int ret = -1; + + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + BN_CTX_start(bnctx); + + if ((order = BN_CTX_get(bnctx)) == NULL || + (tmp = BN_CTX_get(bnctx)) == NULL) + fatal("%s: BN_CTX_get failed", __func__); + + /* log2(private) > log2(order)/2 */ + if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) + fatal("%s: EC_GROUP_get_order failed", __func__); + if (BN_num_bits(EC_KEY_get0_private_key(key)) <= + BN_num_bits(order) / 2) { + error("%s: private key too small: " + "bits(y) = %d, bits(order)/2 = %d", __func__, + BN_num_bits(EC_KEY_get0_private_key(key)), + BN_num_bits(order) / 2); + goto out; + } + + /* private < order - 1 */ + if (!BN_sub(tmp, order, BN_value_one())) + fatal("%s: BN_sub failed", __func__); + if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { + error("%s: private key >= group order - 1", __func__); + goto out; + } + ret = 0; + out: + BN_CTX_free(bnctx); + return ret; +} + +#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) +void +key_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) +{ + BIGNUM *x, *y; + BN_CTX *bnctx; + + if (point == NULL) { + fputs("point=(NULL)\n", stderr); + return; + } + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + BN_CTX_start(bnctx); + if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) + fatal("%s: BN_CTX_get failed", __func__); + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_prime_field) + fatal("%s: group is not a prime field", __func__); + if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) + fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); + fputs("x=", stderr); + BN_print_fp(stderr, x); + fputs("\ny=", stderr); + BN_print_fp(stderr, y); + fputs("\n", stderr); + BN_CTX_free(bnctx); +} + +void +key_dump_ec_key(const EC_KEY *key) +{ + const BIGNUM *exponent; + + key_dump_ec_point(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key)); + fputs("exponent=", stderr); + if ((exponent = EC_KEY_get0_private_key(key)) == NULL) + fputs("(NULL)", stderr); + else + BN_print_fp(stderr, EC_KEY_get0_private_key(key)); + fputs("\n", stderr); +} +#endif /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ +#endif /* OPENSSL_HAS_ECC */ diff --git a/key.h b/key.h index 11d30eae685b..ec5ac5eb87c1 100644 --- a/key.h +++ b/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.30 2010/04/16 01:47:26 djm Exp $ */ +/* $OpenBSD: key.h,v 1.33 2010/10/28 11:22:09 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -29,14 +29,19 @@ #include "buffer.h" #include #include +#ifdef OPENSSL_HAS_ECC +#include +#endif typedef struct Key Key; enum types { KEY_RSA1, KEY_RSA, KEY_DSA, + KEY_ECDSA, KEY_RSA_CERT, KEY_DSA_CERT, + KEY_ECDSA_CERT, KEY_RSA_CERT_V00, KEY_DSA_CERT_V00, KEY_UNSPEC @@ -73,6 +78,12 @@ struct Key { int flags; RSA *rsa; DSA *dsa; + int ecdsa_nid; /* NID of curve */ +#ifdef OPENSSL_HAS_ECC + EC_KEY *ecdsa; +#else + void *ecdsa; +#endif struct KeyCert *cert; }; @@ -104,9 +115,22 @@ int key_cert_check_authority(const Key *, int, int, const char *, const char **); int key_cert_is_legacy(Key *); +int key_ecdsa_nid_from_name(const char *); +int key_curve_name_to_nid(const char *); +const char * key_curve_nid_to_name(int); +u_int key_curve_nid_to_bits(int); +int key_ecdsa_bits_to_nid(int); +#ifdef OPENSSL_HAS_ECC +int key_ecdsa_key_to_nid(EC_KEY *); +const EVP_MD * key_ec_nid_to_evpmd(int nid); +int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); +int key_ec_validate_private(const EC_KEY *); +#endif + Key *key_from_blob(const u_char *, u_int); int key_to_blob(const Key *, u_char **, u_int *); const char *key_ssh_name(const Key *); +const char *key_ssh_name_plain(const Key *); int key_names_valid2(const char *); int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int); @@ -114,7 +138,14 @@ int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); int ssh_dss_sign(const Key *, u_char **, u_int *, const u_char *, u_int); int ssh_dss_verify(const Key *, const u_char *, u_int, const u_char *, u_int); +int ssh_ecdsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); +#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK)) +void key_dump_ec_point(const EC_GROUP *, const EC_POINT *); +void key_dump_ec_key(const EC_KEY *); +#endif + #endif diff --git a/loginrec.c b/loginrec.c index 6f655cb16cd5..32941c985ea4 100644 --- a/loginrec.c +++ b/loginrec.c @@ -273,7 +273,7 @@ login_logout(struct logininfo *li) * try to retrieve lastlog information from wtmp/wtmpx. */ unsigned int -login_get_lastlog_time(const int uid) +login_get_lastlog_time(const uid_t uid) { struct logininfo li; @@ -297,7 +297,7 @@ login_get_lastlog_time(const int uid) * 0 on failure (will use OpenSSH's logging facilities for diagnostics) */ struct logininfo * -login_get_lastlog(struct logininfo *li, const int uid) +login_get_lastlog(struct logininfo *li, const uid_t uid) { struct passwd *pw; @@ -311,7 +311,8 @@ login_get_lastlog(struct logininfo *li, const int uid) */ pw = getpwuid(uid); if (pw == NULL) - fatal("%s: Cannot find account for uid %i", __func__, uid); + fatal("%s: Cannot find account for uid %ld", __func__, + (long)uid); /* No MIN_SIZEOF here - we absolutely *must not* truncate the * username (XXX - so check for trunc!) */ @@ -335,7 +336,7 @@ login_get_lastlog(struct logininfo *li, const int uid) * allocation fails, the program halts. */ struct -logininfo *login_alloc_entry(int pid, const char *username, +logininfo *login_alloc_entry(pid_t pid, const char *username, const char *hostname, const char *line) { struct logininfo *newli; @@ -363,7 +364,7 @@ login_free_entry(struct logininfo *li) * Returns: 1 */ int -login_init_entry(struct logininfo *li, int pid, const char *username, +login_init_entry(struct logininfo *li, pid_t pid, const char *username, const char *hostname, const char *line) { struct passwd *pw; @@ -468,9 +469,9 @@ login_write(struct logininfo *li) #endif #ifdef SSH_AUDIT_EVENTS if (li->type == LTYPE_LOGIN) - audit_session_open(li->line); + audit_session_open(li); else if (li->type == LTYPE_LOGOUT) - audit_session_close(li->line); + audit_session_close(li); #endif return (0); } @@ -872,11 +873,13 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) pos = (off_t)tty * sizeof(struct utmp); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); + close(fd); return (0); } if (ret != pos) { logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); + close(fd); return (0); } /* @@ -892,16 +895,20 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); + close(fd); return (0); } if (ret != pos) { logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); + close(fd); return (0); } if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { logit("%s: error writing %s: %s", __func__, UTMP_FILE, strerror(errno)); + close(fd); + return (0); } close(fd); @@ -1205,7 +1212,7 @@ wtmp_get_entry(struct logininfo *li) close (fd); return (0); } - if ( wtmp_islogin(li, &ut) ) { + if (wtmp_islogin(li, &ut) ) { found = 1; /* * We've already checked for a time in struct @@ -1496,11 +1503,12 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) if (S_ISREG(st.st_mode)) { /* find this uid's offset in the lastlog file */ - offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); + offset = (off_t) ((u_long)li->uid * sizeof(struct lastlog)); if (lseek(*fd, offset, SEEK_SET) != offset) { logit("%s: %s->lseek(): %s", __func__, lastlog_file, strerror(errno)); + close(*fd); return (0); } } @@ -1672,7 +1680,7 @@ record_failed_login(const char *username, const char *hostname, strerror(errno)); goto out; } - if((fst.st_mode & (S_IRWXG | S_IRWXO)) || (fst.st_uid != 0)){ + if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){ logit("Excess permission or bad ownership on file %s", _PATH_BTMP); goto out; diff --git a/loginrec.h b/loginrec.h index 84b48659003c..28923e7812e5 100644 --- a/loginrec.h +++ b/loginrec.h @@ -63,8 +63,8 @@ struct logininfo { char progname[LINFO_PROGSIZE]; /* name of program (for PAM) */ int progname_null; short int type; /* type of login (LTYPE_*) */ - int pid; /* PID of login process */ - int uid; /* UID of this user */ + pid_t pid; /* PID of login process */ + uid_t uid; /* UID of this user */ char line[LINFO_LINESIZE]; /* tty/pty name */ char username[LINFO_NAMESIZE]; /* login username */ char hostname[LINFO_HOSTSIZE]; /* remote hostname */ @@ -86,12 +86,12 @@ struct logininfo { /** 'public' functions */ /* construct a new login entry */ -struct logininfo *login_alloc_entry(int pid, const char *username, +struct logininfo *login_alloc_entry(pid_t pid, const char *username, const char *hostname, const char *line); /* free a structure */ void login_free_entry(struct logininfo *li); /* fill out a pre-allocated structure with useful information */ -int login_init_entry(struct logininfo *li, int pid, const char *username, +int login_init_entry(struct logininfo *li, pid_t pid, const char *username, const char *hostname, const char *line); /* place the current time in a logininfo struct */ void login_set_current_time(struct logininfo *li); @@ -117,9 +117,9 @@ void login_set_addr(struct logininfo *li, const struct sockaddr *sa, * lastlog retrieval functions */ /* lastlog *entry* functions fill out a logininfo */ -struct logininfo *login_get_lastlog(struct logininfo *li, const int uid); +struct logininfo *login_get_lastlog(struct logininfo *li, const uid_t uid); /* lastlog *time* functions return time_t equivalent (uint) */ -unsigned int login_get_lastlog_time(const int uid); +unsigned int login_get_lastlog_time(const uid_t uid); /* produce various forms of the line filename */ char *line_fullname(char *dst, const char *src, u_int dstsize); diff --git a/misc.c b/misc.c index a82e7936ed6e..919b04e6b7a9 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.80 2010/07/21 02:10:58 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.84 2010/11/21 01:01:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -35,9 +35,12 @@ #include #include #include +#include #include #include +#include +#include #include #include @@ -850,16 +853,138 @@ ms_to_timeval(struct timeval *tv, int ms) tv->tv_usec = (ms % 1000) * 1000; } -int -timingsafe_bcmp(const void *b1, const void *b2, size_t n) +void +bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) { - const unsigned char *p1 = b1, *p2 = b2; - int ret = 0; + bw->buflen = buflen; + bw->rate = kbps; + bw->thresh = bw->rate; + bw->lamt = 0; + timerclear(&bw->bwstart); + timerclear(&bw->bwend); +} - for (; n > 0; n--) - ret |= *p1++ ^ *p2++; - return (ret != 0); +/* Callback from read/write loop to insert bandwidth-limiting delays */ +void +bandwidth_limit(struct bwlimit *bw, size_t read_len) +{ + u_int64_t waitlen; + struct timespec ts, rm; + + if (!timerisset(&bw->bwstart)) { + gettimeofday(&bw->bwstart, NULL); + return; + } + + bw->lamt += read_len; + if (bw->lamt < bw->thresh) + return; + + gettimeofday(&bw->bwend, NULL); + timersub(&bw->bwend, &bw->bwstart, &bw->bwend); + if (!timerisset(&bw->bwend)) + return; + + bw->lamt *= 8; + waitlen = (double)1000000L * bw->lamt / bw->rate; + + bw->bwstart.tv_sec = waitlen / 1000000L; + bw->bwstart.tv_usec = waitlen % 1000000L; + + if (timercmp(&bw->bwstart, &bw->bwend, >)) { + timersub(&bw->bwstart, &bw->bwend, &bw->bwend); + + /* Adjust the wait time */ + if (bw->bwend.tv_sec) { + bw->thresh /= 2; + if (bw->thresh < bw->buflen / 4) + bw->thresh = bw->buflen / 4; + } else if (bw->bwend.tv_usec < 10000) { + bw->thresh *= 2; + if (bw->thresh > bw->buflen * 8) + bw->thresh = bw->buflen * 8; + } + + TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); + while (nanosleep(&ts, &rm) == -1) { + if (errno != EINTR) + break; + ts = rm; + } + } + + bw->lamt = 0; + gettimeofday(&bw->bwstart, NULL); } + +/* Make a template filename for mk[sd]temp() */ +void +mktemp_proto(char *s, size_t len) +{ + const char *tmpdir; + int r; + + if ((tmpdir = getenv("TMPDIR")) != NULL) { + r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); + if (r > 0 && (size_t)r < len) + return; + } + r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); + if (r < 0 || (size_t)r >= len) + fatal("%s: template string too short", __func__); +} + +static const struct { + const char *name; + int value; +} ipqos[] = { + { "af11", IPTOS_DSCP_AF11 }, + { "af12", IPTOS_DSCP_AF12 }, + { "af13", IPTOS_DSCP_AF13 }, + { "af14", IPTOS_DSCP_AF21 }, + { "af22", IPTOS_DSCP_AF22 }, + { "af23", IPTOS_DSCP_AF23 }, + { "af31", IPTOS_DSCP_AF31 }, + { "af32", IPTOS_DSCP_AF32 }, + { "af33", IPTOS_DSCP_AF33 }, + { "af41", IPTOS_DSCP_AF41 }, + { "af42", IPTOS_DSCP_AF42 }, + { "af43", IPTOS_DSCP_AF43 }, + { "cs0", IPTOS_DSCP_CS0 }, + { "cs1", IPTOS_DSCP_CS1 }, + { "cs2", IPTOS_DSCP_CS2 }, + { "cs3", IPTOS_DSCP_CS3 }, + { "cs4", IPTOS_DSCP_CS4 }, + { "cs5", IPTOS_DSCP_CS5 }, + { "cs6", IPTOS_DSCP_CS6 }, + { "cs7", IPTOS_DSCP_CS7 }, + { "ef", IPTOS_DSCP_EF }, + { "lowdelay", IPTOS_LOWDELAY }, + { "throughput", IPTOS_THROUGHPUT }, + { "reliability", IPTOS_RELIABILITY }, + { NULL, -1 } +}; + +int +parse_ipqos(const char *cp) +{ + u_int i; + char *ep; + long val; + + if (cp == NULL) + return -1; + for (i = 0; ipqos[i].name != NULL; i++) { + if (strcasecmp(cp, ipqos[i].name) == 0) + return ipqos[i].value; + } + /* Try parsing as an integer */ + val = strtol(cp, &ep, 0); + if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) + return -1; + return val; +} + void sock_set_v6only(int s) { diff --git a/misc.h b/misc.h index bb799f616379..65cf4a6163f3 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.43 2010/07/13 23:13:16 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.47 2010/11/21 01:01:13 djm Exp $ */ /* * Author: Tatu Ylonen @@ -36,7 +36,6 @@ void sanitise_stdfd(void); void ms_subtract_diff(struct timeval *, int *); void ms_to_timeval(struct timeval *, int); void sock_set_v6only(int); -int timingsafe_bcmp(const void *, const void *, size_t); struct passwd *pwcopy(struct passwd *); const char *ssh_gai_strerror(int); @@ -80,6 +79,17 @@ void put_u32(void *, u_int32_t) void put_u16(void *, u_int16_t) __attribute__((__bounded__( __minbytes__, 1, 2))); +struct bwlimit { + size_t buflen; + u_int64_t rate, thresh, lamt; + struct timeval bwstart, bwend; +}; + +void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t); +void bandwidth_limit(struct bwlimit *, size_t); + +int parse_ipqos(const char *); +void mktemp_proto(char *, size_t); /* readpass.c */ diff --git a/moduli.0 b/moduli.0 index 6d707ff8257a..af4b375112c5 100644 --- a/moduli.0 +++ b/moduli.0 @@ -17,7 +17,6 @@ DESCRIPTION The file consists of newline-separated records, one per modulus, containing seven space separated fields. These fields are as follows: - timestamp The time that the modulus was last processed as YYYYMMDDHHMMSS. diff --git a/moduli.c b/moduli.c index f737cb3f517d..2964a8b3de02 100644 --- a/moduli.c +++ b/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.21 2008/06/26 09:19:40 djm Exp $ */ +/* $OpenBSD: moduli.c,v 1.22 2010/11/10 01:33:07 djm Exp $ */ /* * Copyright 1994 Phil Karn * Copyright 1996-1998, 2003 William Allen Simpson @@ -54,6 +54,8 @@ #include "dh.h" #include "log.h" +#include "openbsd-compat/openssl-compat.h" + /* * File output defines */ @@ -600,7 +602,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) * that p is also prime. A single pass will weed out the * vast majority of composite q's. */ - if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) { + if (BN_is_prime_ex(q, 1, ctx, NULL) <= 0) { debug("%10u: q failed first possible prime test", count_in); continue; @@ -613,14 +615,14 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) * will show up on the first Rabin-Miller iteration so it * doesn't hurt to specify a high iteration count. */ - if (!BN_is_prime(p, trials, NULL, ctx, NULL)) { + if (!BN_is_prime_ex(p, trials, ctx, NULL)) { debug("%10u: p is not prime", count_in); continue; } debug("%10u: p is almost certainly prime", count_in); /* recheck q more rigorously */ - if (!BN_is_prime(q, trials - 1, NULL, ctx, NULL)) { + if (!BN_is_prime_ex(q, trials - 1, ctx, NULL)) { debug("%10u: q is not prime", count_in); continue; } diff --git a/monitor.c b/monitor.c index 9eb4e35c97e1..29d987c70fdc 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.108 2010/07/13 23:13:16 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.110 2010/09/09 10:45:45 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -590,10 +590,10 @@ mm_answer_sign(int sock, Buffer *m) p = buffer_get_string(m, &datlen); /* - * Supported KEX types will only return SHA1 (20 byte) or - * SHA256 (32 byte) hashes + * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), + * SHA384 (48 bytes) and SHA512 (64 bytes). */ - if (datlen != 20 && datlen != 32) + if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) fatal("%s: data length incorrect: %u", __func__, datlen); /* save session id, it will be passed on the first call */ @@ -1691,6 +1691,7 @@ mm_get_kex(Buffer *m) kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; + kex->kex[KEX_ECDH_SHA2] = kexecdh_server; kex->server = 1; kex->hostkey_type = buffer_get_int(m); kex->kex_type = buffer_get_int(m); diff --git a/monitor_wrap.c b/monitor_wrap.c index faeb02cfa359..1a5dda56158e 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.69 2010/03/07 11:57:13 dtucker Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.70 2010/08/31 11:54:45 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -73,6 +73,7 @@ #include "misc.h" #include "schnorr.h" #include "jpake.h" +#include "uuencode.h" #include "channels.h" #include "session.h" diff --git a/mux.c b/mux.c index 5c3857ee816b..e370462db5a2 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.21 2010/06/25 23:15:36 djm Exp $ */ +/* $OpenBSD: mux.c,v 1.24 2011/01/13 21:54:53 djm Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -879,7 +879,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r) if (options.control_master == SSHCTL_MASTER_ASK || options.control_master == SSHCTL_MASTER_AUTO_ASK) { - if (!ask_permission("Allow forward to to %s:%u? ", + if (!ask_permission("Allow forward to %s:%u? ", chost, cport)) { debug2("%s: stdio fwd refused by user", __func__); /* prepare reply */ @@ -1026,6 +1026,9 @@ muxserver_listen(void) struct sockaddr_un addr; socklen_t sun_len; mode_t old_umask; + char *orig_control_path = options.control_path; + char rbuf[16+1]; + u_int i, r; if (options.control_path == NULL || options.control_master == SSHCTL_MASTER_NO) @@ -1033,6 +1036,23 @@ muxserver_listen(void) debug("setting up multiplex master socket"); + /* + * Use a temporary path before listen so we can pseudo-atomically + * establish the listening socket in its final location to avoid + * other processes racing in between bind() and listen() and hitting + * an unready socket. + */ + for (i = 0; i < sizeof(rbuf) - 1; i++) { + r = arc4random_uniform(26+26+10); + rbuf[i] = (r < 26) ? 'a' + r : + (r < 26*2) ? 'A' + r - 26 : + '0' + r - 26 - 26; + } + rbuf[sizeof(rbuf) - 1] = '\0'; + options.control_path = NULL; + xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf); + debug3("%s: temporary control path %s", __func__, options.control_path); + memset(&addr, '\0', sizeof(addr)); addr.sun_family = AF_UNIX; sun_len = offsetof(struct sockaddr_un, sun_path) + @@ -1051,6 +1071,7 @@ muxserver_listen(void) if (errno == EINVAL || errno == EADDRINUSE) { error("ControlSocket %s already exists, " "disabling multiplexing", options.control_path); + disable_mux_master: close(muxserver_sock); muxserver_sock = -1; xfree(options.control_path); @@ -1065,12 +1086,29 @@ muxserver_listen(void) if (listen(muxserver_sock, 64) == -1) fatal("%s listen(): %s", __func__, strerror(errno)); + /* Now atomically "move" the mux socket into position */ + if (link(options.control_path, orig_control_path) != 0) { + if (errno != EEXIST) { + fatal("%s: link mux listener %s => %s: %s", __func__, + options.control_path, orig_control_path, + strerror(errno)); + } + error("ControlSocket %s already exists, disabling multiplexing", + orig_control_path); + xfree(orig_control_path); + unlink(options.control_path); + goto disable_mux_master; + } + unlink(options.control_path); + xfree(options.control_path); + options.control_path = orig_control_path; + set_nonblock(muxserver_sock); mux_listener_channel = channel_new("mux listener", SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, - 0, addr.sun_path, 1); + 0, options.control_path, 1); mux_listener_channel->mux_rcb = mux_master_read_cb; debug3("%s: mux listener channel %d fd %d", __func__, mux_listener_channel->self, mux_listener_channel->sock); @@ -1492,7 +1530,7 @@ mux_client_request_forward(int fd, u_int ftype, Forward *fwd) case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); buffer_free(&m); - error("%s: session request failed: %s", __func__, e); + error("%s: forwarding request failed: %s", __func__, e); return -1; default: fatal("%s: unexpected response from master 0x%08x", @@ -1611,12 +1649,12 @@ mux_client_request_session(int fd) case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); buffer_free(&m); - error("Master refused forwarding request: %s", e); + error("Master refused session request: %s", e); return -1; case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); buffer_free(&m); - error("%s: forwarding request failed: %s", __func__, e); + error("%s: session request failed: %s", __func__, e); return -1; default: buffer_free(&m); @@ -1743,7 +1781,7 @@ mux_client_request_stdio_fwd(int fd) case MUX_S_PERMISSION_DENIED: e = buffer_get_string(&m, NULL); buffer_free(&m); - fatal("Master refused forwarding request: %s", e); + fatal("Master refused stdio forwarding request: %s", e); case MUX_S_FAILURE: e = buffer_get_string(&m, NULL); buffer_free(&m); @@ -1823,9 +1861,13 @@ muxclient(const char *path) fatal("Control socket connect(%.100s): %s", path, strerror(errno)); } - if (errno == ENOENT) + if (errno == ECONNREFUSED && + options.control_master != SSHCTL_MASTER_NO) { + debug("Stale control socket %.100s, unlinking", path); + unlink(path); + } else if (errno == ENOENT) { debug("Control socket \"%.100s\" does not exist", path); - else { + } else { error("Control socket connect(%.100s): %s", path, strerror(errno)); } diff --git a/myproposal.h b/myproposal.h index 7bedfab0a935..2c43607a7bd6 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.25 2010/04/16 01:47:26 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.27 2010/09/01 22:42:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -26,26 +26,49 @@ #include -/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */ -#if OPENSSL_VERSION_NUMBER < 0x00907000L -# define KEX_DEFAULT_KEX \ - "diffie-hellman-group-exchange-sha1," \ - "diffie-hellman-group14-sha1," \ - "diffie-hellman-group1-sha1" +#ifdef OPENSSL_HAS_ECC +# define KEX_ECDH_METHODS \ + "ecdh-sha2-nistp256," \ + "ecdh-sha2-nistp384," \ + "ecdh-sha2-nistp521," +# define HOSTKEY_ECDSA_CERT_METHODS \ + "ecdsa-sha2-nistp256-cert-v01@openssh.com," \ + "ecdsa-sha2-nistp384-cert-v01@openssh.com," \ + "ecdsa-sha2-nistp521-cert-v01@openssh.com," +# define HOSTKEY_ECDSA_METHODS \ + "ecdsa-sha2-nistp256," \ + "ecdsa-sha2-nistp384," \ + "ecdsa-sha2-nistp521," #else -# define KEX_DEFAULT_KEX \ - "diffie-hellman-group-exchange-sha256," \ - "diffie-hellman-group-exchange-sha1," \ - "diffie-hellman-group14-sha1," \ - "diffie-hellman-group1-sha1" +# define KEX_ECDH_METHODS +# define HOSTKEY_ECDSA_CERT_METHODS +# define HOSTKEY_ECDSA_METHODS #endif +/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */ +#if OPENSSL_VERSION_NUMBER >= 0x00907000L +# define KEX_SHA256_METHODS \ + "diffie-hellman-group-exchange-sha256," +#else +# define KEX_SHA256_METHODS +#endif + +# define KEX_DEFAULT_KEX \ + KEX_ECDH_METHODS \ + KEX_SHA256_METHODS \ + "diffie-hellman-group-exchange-sha1," \ + "diffie-hellman-group14-sha1," \ + "diffie-hellman-group1-sha1" + #define KEX_DEFAULT_PK_ALG \ - "ssh-rsa-cert-v01@openssh.com," \ - "ssh-dss-cert-v01@openssh.com," \ - "ssh-rsa-cert-v00@openssh.com," \ - "ssh-dss-cert-v00@openssh.com," \ - "ssh-rsa,ssh-dss" + HOSTKEY_ECDSA_CERT_METHODS \ + "ssh-rsa-cert-v01@openssh.com," \ + "ssh-dss-cert-v01@openssh.com," \ + "ssh-rsa-cert-v00@openssh.com," \ + "ssh-dss-cert-v00@openssh.com," \ + HOSTKEY_ECDSA_METHODS \ + "ssh-rsa," \ + "ssh-dss" #define KEX_DEFAULT_ENCRYPT \ "aes128-ctr,aes192-ctr,aes256-ctr," \ diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index d22efd66cb7b..41b22d837b14 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.45 2010/08/16 03:15:23 dtucker Exp $ +# $Id: Makefile.in,v 1.46 2010/10/07 11:19:24 djm Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -16,7 +16,7 @@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ -OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o vis.o +OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o timingsafe_bcmp.o vis.o COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o diff --git a/openbsd-compat/bindresvport.c b/openbsd-compat/bindresvport.c index c0d5bdb5c335..c89f21403445 100644 --- a/openbsd-compat/bindresvport.c +++ b/openbsd-compat/bindresvport.c @@ -89,7 +89,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) port = ntohs(*portp); if (port == 0) - port = (arc4random() % NPORTS) + STARTPORT; + port = arc4random_uniform(NPORTS) + STARTPORT; /* Avoid warning */ error = -1; diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 55f100ac0432..3ef373f566fd 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -240,3 +240,10 @@ strdup(const char *str) return NULL; } #endif + +#ifndef HAVE_ISBLANK +int isblank(int c) +{ + return (c == ' ' || c == '\t'); +} +#endif diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index b61ec4244935..e70c3f9e9ebe 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -1,4 +1,4 @@ -/* $Id: bsd-misc.h,v 1.18 2005/02/25 23:07:38 dtucker Exp $ */ +/* $Id: bsd-misc.h,v 1.19 2010/11/08 22:26:23 tim Exp $ */ /* * Copyright (c) 1999-2004 Damien Miller @@ -95,4 +95,8 @@ mysig_t mysignal(int sig, mysig_t act); #define signal(a,b) mysignal(a,b) +#ifndef HAVE_ISBLANK +int isblank(int); +#endif + #endif /* _BSD_MISC_H */ diff --git a/openbsd-compat/charclass.h b/openbsd-compat/charclass.h new file mode 100644 index 000000000000..91f517447b8f --- /dev/null +++ b/openbsd-compat/charclass.h @@ -0,0 +1,31 @@ +/* + * Public domain, 2008, Todd C. Miller + * + * $OpenBSD: charclass.h,v 1.1 2008/10/01 23:04:13 millert Exp $ + */ + +/* OPENBSD ORIGINAL: lib/libc/gen/charclass.h */ + +/* + * POSIX character class support for fnmatch() and glob(). + */ +static struct cclass { + const char *name; + int (*isctype)(int); +} cclasses[] = { + { "alnum", isalnum }, + { "alpha", isalpha }, + { "blank", isblank }, + { "cntrl", iscntrl }, + { "digit", isdigit }, + { "graph", isgraph }, + { "lower", islower }, + { "print", isprint }, + { "punct", ispunct }, + { "space", isspace }, + { "upper", isupper }, + { "xdigit", isxdigit }, + { NULL, NULL } +}; + +#define NCCLASSES (sizeof(cclasses) / sizeof(cclasses[0]) - 1) diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c index 74b506403ec8..0341225cd12b 100644 --- a/openbsd-compat/glob.c +++ b/openbsd-compat/glob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.c,v 1.26 2005/11/28 17:50:12 deraadt Exp $ */ +/* $OpenBSD: glob.c,v 1.35 2011/01/12 01:53:14 djm Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -33,36 +33,6 @@ /* OPENBSD ORIGINAL: lib/libc/gen/glob.c */ -#include "includes.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ - !defined(GLOB_HAS_GL_MATCHC) || \ - !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ - defined(BROKEN_GLOB) - -static long -get_arg_max(void) -{ -#ifdef ARG_MAX - return(ARG_MAX); -#elif defined(HAVE_SYSCONF) && defined(_SC_ARG_MAX) - return(sysconf(_SC_ARG_MAX)); -#else - return(256); /* XXX: arbitrary */ -#endif -} - /* * glob(3) -- a superset of the one defined in POSIX 1003.2. * @@ -88,6 +58,25 @@ get_arg_max(void) * Number of matches in the current invocation of glob. */ +#include "includes.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(HAVE_GLOB) || !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 "charclass.h" #define DOLLAR '$' #define DOT '.' @@ -100,7 +89,6 @@ get_arg_max(void) #define RBRACKET ']' #define SEP '/' #define STAR '*' -#undef TILDE /* Some platforms may already define it */ #define TILDE '~' #define UNDERSCORE '_' #define LBRACE '{' @@ -137,26 +125,39 @@ typedef char Char; #define M_ONE META('?') #define M_RNG META('-') #define M_SET META('[') +#define M_CLASS META(':') #define ismeta(c) (((c)&M_QUOTE) != 0) +#define GLOB_LIMIT_MALLOC 65536 +#define GLOB_LIMIT_STAT 128 +#define GLOB_LIMIT_READDIR 16384 + +struct glob_lim { + size_t glim_malloc; + size_t glim_stat; + size_t glim_readdir; +}; static int compare(const void *, const void *); static int g_Ctoc(const Char *, char *, u_int); static int g_lstat(Char *, struct stat *, glob_t *); static DIR *g_opendir(Char *, glob_t *); -static Char *g_strchr(Char *, int); +static Char *g_strchr(const Char *, int); +static int g_strncmp(const Char *, const char *, size_t); static int g_stat(Char *, struct stat *, glob_t *); -static int glob0(const Char *, glob_t *); -static int glob1(Char *, Char *, glob_t *, size_t *); +static int glob0(const Char *, glob_t *, struct glob_lim *); +static int glob1(Char *, Char *, glob_t *, struct glob_lim *); static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, - glob_t *, size_t *); + glob_t *, struct glob_lim *); static int glob3(Char *, Char *, Char *, Char *, Char *, - Char *, Char *, glob_t *, size_t *); -static int globextend(const Char *, glob_t *, size_t *); + Char *, Char *, glob_t *, struct glob_lim *); +static int globextend(const Char *, glob_t *, struct glob_lim *, + struct stat *); static const Char * globtilde(const Char *, Char *, size_t, glob_t *); -static int globexp1(const Char *, glob_t *); -static int globexp2(const Char *, const Char *, glob_t *, int *); +static int globexp1(const Char *, glob_t *, struct glob_lim *); +static int globexp2(const Char *, const Char *, glob_t *, + struct glob_lim *); static int match(Char *, Char *, Char *); #ifdef DEBUG static void qprintf(const char *, Char *); @@ -169,11 +170,13 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), const u_char *patnext; int c; Char *bufnext, *bufend, patbuf[MAXPATHLEN]; + struct glob_lim limit = { 0, 0, 0 }; patnext = (u_char *) pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; + pglob->gl_statv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } @@ -181,6 +184,11 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; + if (pglob->gl_offs < 0 || pglob->gl_pathc < 0 || + pglob->gl_offs >= INT_MAX || pglob->gl_pathc >= INT_MAX || + pglob->gl_pathc >= INT_MAX - pglob->gl_offs - 1) + return GLOB_NOSPACE; + bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; if (flags & GLOB_NOESCAPE) @@ -201,9 +209,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), *bufnext = EOS; if (flags & GLOB_BRACE) - return globexp1(patbuf, pglob); + return globexp1(patbuf, pglob, &limit); else - return glob0(patbuf, pglob); + return glob0(patbuf, pglob, &limit); } /* @@ -212,20 +220,18 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int), * characters */ static int -globexp1(const Char *pattern, glob_t *pglob) +globexp1(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char* ptr = pattern; - int rv; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) - return glob0(pattern, pglob); + return glob0(pattern, pglob, limitp); - while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) - if (!globexp2(ptr, pattern, pglob, &rv)) - return rv; + if ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) + return globexp2(ptr, pattern, pglob, limitp); - return glob0(pattern, pglob); + return glob0(pattern, pglob, limitp); } @@ -235,9 +241,10 @@ globexp1(const Char *pattern, glob_t *pglob) * If it fails then it tries to glob the rest of the pattern and returns. */ static int -globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) +globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, + struct glob_lim *limitp) { - int i; + int i, rv; Char *lm, *ls; const Char *pe, *pm, *pl; Char patbuf[MAXPATHLEN]; @@ -270,10 +277,8 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) } /* Non matching braces; just glob the pattern */ - if (i != 0 || *pe == EOS) { - *rv = glob0(patbuf, pglob); - return 0; - } + if (i != 0 || *pe == EOS) + return glob0(patbuf, pglob, limitp); for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { @@ -319,7 +324,9 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) #ifdef DEBUG qprintf("globexp2:", patbuf); #endif - *rv = globexp1(patbuf, pglob); + rv = globexp1(patbuf, pglob, limitp); + if (rv && rv != GLOB_NOMATCH) + return rv; /* move after the comma, to the next string */ pl = pm + 1; @@ -330,7 +337,6 @@ globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) break; } } - *rv = 0; return 0; } @@ -399,6 +405,47 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) return patbuf; } +static int +g_strncmp(const Char *s1, const char *s2, size_t n) +{ + int rv = 0; + + while (n--) { + rv = *(Char *)s1 - *(const unsigned char *)s2++; + if (rv) + break; + if (*s1++ == '\0') + break; + } + return rv; +} + +static int +g_charclass(const Char **patternp, Char **bufnextp) +{ + const Char *pattern = *patternp + 1; + Char *bufnext = *bufnextp; + const Char *colon; + struct cclass *cc; + size_t len; + + if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']') + return 1; /* not a character class */ + + len = (size_t)(colon - pattern); + for (cc = cclasses; cc->name != NULL; cc++) { + if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0') + break; + } + if (cc->name == NULL) + return -1; /* invalid character class */ + *bufnext++ = M_CLASS; + *bufnext++ = (Char)(cc - &cclasses[0]); + *bufnextp = bufnext; + *patternp += len + 3; + + return 0; +} /* * The main glob() routine: compiles the pattern (optionally processing @@ -408,12 +455,11 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) * to find no matches. */ static int -glob0(const Char *pattern, glob_t *pglob) +glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp) { const Char *qpatnext; int c, err, oldpathc; Char *bufnext, patbuf[MAXPATHLEN]; - size_t limit = 0; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); oldpathc = pglob->gl_pathc; @@ -427,7 +473,7 @@ glob0(const Char *pattern, glob_t *pglob) if (c == NOT) ++qpatnext; if (*qpatnext == EOS || - g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; @@ -438,6 +484,20 @@ glob0(const Char *pattern, glob_t *pglob) *bufnext++ = M_NOT; c = *qpatnext++; do { + if (c == LBRACKET && *qpatnext == ':') { + do { + err = g_charclass(&qpatnext, + &bufnext); + if (err) + break; + c = *qpatnext++; + } while (c == LBRACKET && *qpatnext == ':'); + if (err == -1 && + !(pglob->gl_flags & GLOB_NOCHECK)) + return GLOB_NOMATCH; + if (c == RBRACKET) + break; + } *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { @@ -471,7 +531,7 @@ glob0(const Char *pattern, glob_t *pglob) qprintf("glob0:", patbuf); #endif - if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) + if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, limitp)) != 0) return(err); /* @@ -484,7 +544,7 @@ glob0(const Char *pattern, glob_t *pglob) if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) - return(globextend(pattern, pglob, &limit)); + return(globextend(pattern, pglob, limitp, NULL)); else return(GLOB_NOMATCH); } @@ -501,7 +561,7 @@ compare(const void *p, const void *q) } static int -glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) +glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { Char pathbuf[MAXPATHLEN]; @@ -520,7 +580,7 @@ glob1(Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) */ static int glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, - Char *pattern, Char *pattern_last, glob_t *pglob, size_t *limitp) + Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) { struct stat sb; Char *p, *q; @@ -536,6 +596,14 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, if (g_lstat(pathbuf, &sb, pglob)) return(0); + if ((pglob->gl_flags & GLOB_LIMIT) && + limitp->glim_stat++ >= GLOB_LIMIT_STAT) { + errno = 0; + *pathend++ = SEP; + *pathend = EOS; + return(GLOB_NOSPACE); + } + if (((pglob->gl_flags & GLOB_MARK) && pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && @@ -547,7 +615,7 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, *pathend = EOS; } ++pglob->gl_matchc; - return(globextend(pathbuf, pglob, limitp)); + return(globextend(pathbuf, pglob, limitp, &sb)); } /* Find end of next segment, copy tentatively to pathend. */ @@ -581,7 +649,7 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, - size_t *limitp) + struct glob_lim *limitp) { struct dirent *dp; DIR *dirp; @@ -624,6 +692,14 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, u_char *sc; Char *dc; + if ((pglob->gl_flags & GLOB_LIMIT) && + limitp->glim_readdir++ >= GLOB_LIMIT_READDIR) { + errno = 0; + *pathend++ = SEP; + *pathend = EOS; + return(GLOB_NOSPACE); + } + /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; @@ -670,25 +746,44 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int -globextend(const Char *path, glob_t *pglob, size_t *limitp) +globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp, + struct stat *sb) { char **pathv; - int i; - u_int newsize, len; - char *copy; + ssize_t i; + size_t newn, len; + char *copy = NULL; const Char *p; + struct stat **statv; - newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); - pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) : - malloc(newsize); - if (pathv == NULL) { + newn = 2 + pglob->gl_pathc + pglob->gl_offs; + if (pglob->gl_offs >= INT_MAX || + pglob->gl_pathc >= INT_MAX || + newn >= INT_MAX || + SIZE_MAX / sizeof(*pathv) <= newn || + SIZE_MAX / sizeof(*statv) <= newn) { + nospace: + for (i = pglob->gl_offs; i < (ssize_t)(newn - 2); i++) { + if (pglob->gl_pathv && pglob->gl_pathv[i]) + free(pglob->gl_pathv[i]); + if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0 && + pglob->gl_pathv && pglob->gl_pathv[i]) + free(pglob->gl_statv[i]); + } if (pglob->gl_pathv) { free(pglob->gl_pathv); pglob->gl_pathv = NULL; } + if (pglob->gl_statv) { + free(pglob->gl_statv); + pglob->gl_statv = NULL; + } return(GLOB_NOSPACE); } + pathv = realloc(pglob->gl_pathv, newn * sizeof(*pathv)); + if (pathv == NULL) + goto nospace; if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; @@ -697,10 +792,39 @@ globextend(const Char *path, glob_t *pglob, size_t *limitp) } pglob->gl_pathv = pathv; + if ((pglob->gl_flags & GLOB_KEEPSTAT) != 0) { + statv = realloc(pglob->gl_statv, newn * sizeof(*statv)); + if (statv == NULL) + goto nospace; + if (pglob->gl_statv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + statv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--statv = NULL; + } + pglob->gl_statv = statv; + if (sb == NULL) + statv[pglob->gl_offs + pglob->gl_pathc] = NULL; + else { + limitp->glim_malloc += sizeof(**statv); + if ((pglob->gl_flags & GLOB_LIMIT) && + limitp->glim_malloc >= GLOB_LIMIT_MALLOC) { + errno = 0; + return(GLOB_NOSPACE); + } + if ((statv[pglob->gl_offs + pglob->gl_pathc] = + malloc(sizeof(**statv))) == NULL) + goto copy_error; + memcpy(statv[pglob->gl_offs + pglob->gl_pathc], sb, + sizeof(*sb)); + } + statv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL; + } + for (p = path; *p++;) ; len = (size_t)(p - path); - *limitp += len; + limitp->glim_malloc += len; if ((copy = malloc(len)) != NULL) { if (g_Ctoc(path, copy, len)) { free(copy); @@ -711,11 +835,12 @@ globextend(const Char *path, glob_t *pglob, size_t *limitp) pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; if ((pglob->gl_flags & GLOB_LIMIT) && - newsize + *limitp >= (u_int) get_arg_max()) { + (newn * sizeof(*pathv)) + limitp->glim_malloc > + GLOB_LIMIT_MALLOC) { errno = 0; return(GLOB_NOSPACE); } - + copy_error: return(copy == NULL ? GLOB_NOSPACE : 0); } @@ -751,13 +876,21 @@ match(Char *name, Char *pat, Char *patend) return(0); if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) ++pat; - while (((c = *pat++) & M_MASK) != M_END) + while (((c = *pat++) & M_MASK) != M_END) { + if ((c & M_MASK) == M_CLASS) { + Char idx = *pat & M_MASK; + if (idx < NCCLASSES && + cclasses[idx].isctype(k)) + ok = 1; + ++pat; + } if ((*pat & M_MASK) == M_RNG) { if (c <= k && k <= pat[1]) ok = 1; pat += 2; } else if (c == k) ok = 1; + } if (ok == negate_range) return(0); break; @@ -785,6 +918,14 @@ globfree(glob_t *pglob) free(pglob->gl_pathv); pglob->gl_pathv = NULL; } + if (pglob->gl_statv != NULL) { + for (i = 0; i < pglob->gl_pathc; i++) { + if (pglob->gl_statv[i] != NULL) + free(pglob->gl_statv[i]); + } + free(pglob->gl_statv); + pglob->gl_statv = NULL; + } } static DIR * @@ -830,11 +971,11 @@ g_stat(Char *fn, struct stat *sb, glob_t *pglob) } static Char * -g_strchr(Char *str, int ch) +g_strchr(const Char *str, int ch) { do { if (*str == ch) - return (str); + return ((Char *)str); } while (*str++); return (NULL); } @@ -870,5 +1011,4 @@ qprintf(const char *str, Char *s) #endif #endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || - !defined(GLOB_HAS_GL_MATCHC) */ - + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) */ diff --git a/openbsd-compat/glob.h b/openbsd-compat/glob.h index a2b36f97453a..f8a7fa5ffe3e 100644 --- a/openbsd-compat/glob.h +++ b/openbsd-compat/glob.h @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.h,v 1.10 2005/12/13 00:35:22 millert Exp $ */ +/* $OpenBSD: glob.h,v 1.11 2010/09/24 13:32:55 djm Exp $ */ /* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ /* @@ -38,13 +38,15 @@ /* OPENBSD ORIGINAL: include/glob.h */ #if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ - !defined(GLOB_HAS_GL_MATCHC) || \ + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOB_HAS_GL_STATV) || \ !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ defined(BROKEN_GLOB) #ifndef _GLOB_H_ #define _GLOB_H_ +#include + struct stat; typedef struct { int gl_pathc; /* Count of total paths so far. */ @@ -52,6 +54,7 @@ typedef struct { int gl_offs; /* Reserved at beginning of gl_pathv. */ int gl_flags; /* Copy of flags parameter to glob. */ char **gl_pathv; /* List of paths matching pattern. */ + struct stat **gl_statv; /* Stat entries corresponding to gl_pathv */ /* Copy of errfunc parameter to glob. */ int (*gl_errfunc)(const char *, int); @@ -75,12 +78,10 @@ typedef struct { #define GLOB_NOSORT 0x0020 /* Don't sort. */ #define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ -/* Error values returned by glob(3) */ #define GLOB_NOSPACE (-1) /* Malloc call failed. */ #define GLOB_ABORTED (-2) /* Unignored error. */ #define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ #define GLOB_NOSYS (-4) /* Function not supported. */ -#define GLOB_ABEND GLOB_ABORTED #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ @@ -89,6 +90,8 @@ typedef struct { #define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ #define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ +#define GLOB_KEEPSTAT 0x4000 /* Retain stat data for paths in gl_statv. */ +#define GLOB_ABEND GLOB_ABORTED /* backward compatibility */ int glob(const char *, int, int (*)(const char *, int), glob_t *); void globfree(glob_t *); @@ -96,5 +99,5 @@ void globfree(glob_t *); #endif /* !_GLOB_H_ */ #endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || - !defined(GLOB_HAS_GL_MATCHC */ + !defined(GLOB_HAS_GL_MATCHC) || !defined(GLOH_HAS_GL_STATV) */ diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index e15d2bd96900..77c5ed2b1ee5 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.50 2010/08/16 03:15:23 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.51 2010/10/07 10:25:29 djm Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -213,6 +213,10 @@ char *user_from_uid(uid_t, int); char *group_from_gid(gid_t, int); #endif +#ifndef HAVE_TIMINGSAFE_BCMP +int timingsafe_bcmp(const void *, const void *, size_t); +#endif + void *xmmap(size_t size); char *xcrypt(const char *password, const char *salt); char *shadow_pw(struct passwd *pw); diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 420496caa5ad..b617fdf19451 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.c,v 1.9 2010/01/28 23:54:11 dtucker Exp $ */ +/* $Id: openssl-compat.c,v 1.13 2011/01/21 22:37:06 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -18,10 +18,20 @@ #include "includes.h" +#include +#include + #ifdef USE_OPENSSL_ENGINE # include +# include #endif +#ifndef HAVE_RSA_GET_DEFAULT_METHOD +# include +#endif + +#include "log.h" + #define SSH_DONT_OVERLOAD_OPENSSL_FUNCS #include "openssl-compat.h" @@ -58,6 +68,70 @@ ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt) } #endif +#ifndef HAVE_BN_IS_PRIME_EX +int +BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, void *cb) +{ + if (cb != NULL) + fatal("%s: callback args not supported", __func__); + return BN_is_prime(p, nchecks, NULL, ctx, NULL); +} +#endif + +#ifndef HAVE_RSA_GENERATE_KEY_EX +int +RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *bn_e, void *cb) +{ + RSA *new_rsa, tmp_rsa; + unsigned long e; + + if (cb != NULL) + fatal("%s: callback args not supported", __func__); + e = BN_get_word(bn_e); + if (e == 0xffffffffL) + fatal("%s: value of e too large", __func__); + new_rsa = RSA_generate_key(bits, e, NULL, NULL); + if (new_rsa == NULL) + return 0; + /* swap rsa/new_rsa then free new_rsa */ + tmp_rsa = *rsa; + *rsa = *new_rsa; + *new_rsa = tmp_rsa; + RSA_free(new_rsa); + return 1; +} +#endif + +#ifndef HAVE_DSA_GENERATE_PARAMETERS_EX +int +DSA_generate_parameters_ex(DSA *dsa, int bits, const unsigned char *seed, + int seed_len, int *counter_ret, unsigned long *h_ret, void *cb) +{ + DSA *new_dsa, tmp_dsa; + + if (cb != NULL) + fatal("%s: callback args not supported", __func__); + new_dsa = DSA_generate_parameters(bits, (unsigned char *)seed, seed_len, + counter_ret, h_ret, NULL, NULL); + if (new_dsa == NULL) + return 0; + /* swap dsa/new_dsa then free new_dsa */ + tmp_dsa = *dsa; + *dsa = *new_dsa; + *new_dsa = tmp_dsa; + DSA_free(new_dsa); + return 1; +} +#endif + +#ifndef HAVE_RSA_GET_DEFAULT_METHOD +RSA_METHOD * +RSA_get_default_method(void) +{ + return RSA_PKCS1_SSLeay(); +} +#endif + #ifdef USE_OPENSSL_ENGINE void ssh_SSLeay_add_all_algorithms(void) diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index b7caa650c24a..6d4f3f215c6d 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.h,v 1.15 2010/05/12 07:50:02 djm Exp $ */ +/* $Id: openssl-compat.h,v 1.18 2011/01/21 22:37:06 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -17,6 +17,7 @@ */ #include "includes.h" +#include #include #include #include @@ -39,6 +40,12 @@ # define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) #endif +#if OPENSSL_VERSION_NUMBER < 0x1000000fL +# define LIBCRYPTO_EVP_INL_TYPE unsigned int +#else +# define LIBCRYPTO_EVP_INL_TYPE size_t +#endif + #if (OPENSSL_VERSION_NUMBER < 0x00907000L) || defined(OPENSSL_LOBOTOMISED_AES) # define USE_BUILTIN_RIJNDAEL #endif @@ -71,6 +78,10 @@ extern const EVP_CIPHER *evp_acss(void); # define EVP_CIPHER_CTX_key_length(c) ((c)->key_len) #endif +#ifndef HAVE_RSA_GET_DEFAULT_METHOD +RSA_METHOD *RSA_get_default_method(void); +#endif + /* * We overload some of the OpenSSL crypto functions with ssh_* equivalents * which cater for older and/or less featureful OpenSSL version. @@ -101,6 +112,19 @@ extern const EVP_CIPHER *evp_acss(void); # define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms() # endif +# ifndef HAVE_BN_IS_PRIME_EX +int BN_is_prime_ex(const BIGNUM *, int, BN_CTX *, void *); +# endif + +# ifndef HAVE_DSA_GENERATE_PARAMETERS_EX +int DSA_generate_parameters_ex(DSA *, int, const unsigned char *, int, int *, + unsigned long *, void *); +# endif + +# ifndef HAVE_RSA_GENERATE_KEY_EX +int RSA_generate_key_ex(RSA *, int, BIGNUM *, void *); +# endif + int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, unsigned char *, int); int ssh_EVP_Cipher(EVP_CIPHER_CTX *, char *, char *, int); diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 89b9a734041d..5b1cf402c817 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -1,4 +1,4 @@ -/* $Id: port-linux.c,v 1.8 2010/03/01 04:52:50 dtucker Exp $ */ +/* $Id: port-linux.c,v 1.11 2011/01/17 07:50:24 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh @@ -45,7 +45,7 @@ ssh_selinux_enabled(void) static int enabled = -1; if (enabled == -1) { - enabled = is_selinux_enabled(); + enabled = (is_selinux_enabled() == 1); debug("SELinux support %s", enabled ? "enabled" : "disabled"); } @@ -208,14 +208,22 @@ ssh_selinux_change_context(const char *newname) #endif /* WITH_SELINUX */ #ifdef LINUX_OOM_ADJUST -#define OOM_ADJ_PATH "/proc/self/oom_adj" /* - * The magic "don't kill me", as documented in eg: + * The magic "don't kill me" values, old and new, as documented in eg: * http://lxr.linux.no/#linux+v2.6.32/Documentation/filesystems/proc.txt + * http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt */ -#define OOM_ADJ_NOKILL -17 static int oom_adj_save = INT_MIN; +static char *oom_adj_path = NULL; +struct { + char *path; + int value; +} oom_adjust[] = { + {"/proc/self/oom_score_adj", -1000}, /* kernels >= 2.6.36 */ + {"/proc/self/oom_adj", -17}, /* kernels <= 2.6.35 */ + {NULL, 0}, +}; /* * Tell the kernel's out-of-memory killer to avoid sshd. @@ -224,23 +232,31 @@ static int oom_adj_save = INT_MIN; void oom_adjust_setup(void) { + int i, value; FILE *fp; debug3("%s", __func__); - if ((fp = fopen(OOM_ADJ_PATH, "r+")) != NULL) { - if (fscanf(fp, "%d", &oom_adj_save) != 1) - verbose("error reading %s: %s", OOM_ADJ_PATH, strerror(errno)); - else { - rewind(fp); - if (fprintf(fp, "%d\n", OOM_ADJ_NOKILL) <= 0) - verbose("error writing %s: %s", - OOM_ADJ_PATH, strerror(errno)); - else - verbose("Set %s from %d to %d", - OOM_ADJ_PATH, oom_adj_save, OOM_ADJ_NOKILL); + for (i = 0; oom_adjust[i].path != NULL; i++) { + oom_adj_path = oom_adjust[i].path; + value = oom_adjust[i].value; + if ((fp = fopen(oom_adj_path, "r+")) != NULL) { + if (fscanf(fp, "%d", &oom_adj_save) != 1) + verbose("error reading %s: %s", oom_adj_path, + strerror(errno)); + else { + rewind(fp); + if (fprintf(fp, "%d\n", value) <= 0) + verbose("error writing %s: %s", + oom_adj_path, strerror(errno)); + else + verbose("Set %s from %d to %d", + oom_adj_path, oom_adj_save, value); + } + fclose(fp); + return; } - fclose(fp); } + oom_adj_path = NULL; } /* Restore the saved OOM adjustment */ @@ -250,13 +266,14 @@ oom_adjust_restore(void) FILE *fp; debug3("%s", __func__); - if (oom_adj_save == INT_MIN || (fp = fopen(OOM_ADJ_PATH, "w")) == NULL) + if (oom_adj_save == INT_MIN || oom_adj_path == NULL || + (fp = fopen(oom_adj_path, "w")) == NULL) return; if (fprintf(fp, "%d\n", oom_adj_save) <= 0) - verbose("error writing %s: %s", OOM_ADJ_PATH, strerror(errno)); + verbose("error writing %s: %s", oom_adj_path, strerror(errno)); else - verbose("Set %s to %d", OOM_ADJ_PATH, oom_adj_save); + verbose("Set %s to %d", oom_adj_path, oom_adj_save); fclose(fp); return; diff --git a/openbsd-compat/port-solaris.c b/openbsd-compat/port-solaris.c index 2ab64d487e9c..25382f1c907c 100644 --- a/openbsd-compat/port-solaris.c +++ b/openbsd-compat/port-solaris.c @@ -1,4 +1,4 @@ -/* $Id: port-solaris.c,v 1.3 2006/10/31 23:28:49 dtucker Exp $ */ +/* $Id: port-solaris.c,v 1.4 2010/11/05 01:03:05 dtucker Exp $ */ /* * Copyright (c) 2006 Chad Mynhier. @@ -197,3 +197,33 @@ solaris_contract_post_fork_parent(pid_t pid) close(ctl_fd); } #endif + +#ifdef USE_SOLARIS_PROJECTS +#include +#include + +/* + * Get/set solaris default project. + * If we fail, just run along gracefully. + */ +void +solaris_set_default_project(struct passwd *pw) +{ + struct project *defaultproject; + struct project tempproject; + char buf[1024]; + + /* get default project, if we fail just return gracefully */ + if ((defaultproject = getdefaultproj(pw->pw_name, &tempproject, &buf, + sizeof(buf))) > 0) { + /* set default project */ + if (setproject(defaultproject->pj_name, pw->pw_name, + TASK_NORMAL) != 0) + debug("setproject(%s): %s", defaultproject->pj_name, + strerror(errno)); + } else { + /* debug on getdefaultproj() error */ + debug("getdefaultproj(%s): %s", pw->pw_name, strerror(errno)); + } +} +#endif /* USE_SOLARIS_PROJECTS */ diff --git a/openbsd-compat/port-solaris.h b/openbsd-compat/port-solaris.h index 4c324871eb19..cd442e78b10e 100644 --- a/openbsd-compat/port-solaris.h +++ b/openbsd-compat/port-solaris.h @@ -1,4 +1,4 @@ -/* $Id: port-solaris.h,v 1.1 2006/08/30 17:24:42 djm Exp $ */ +/* $Id: port-solaris.h,v 1.2 2010/11/05 01:03:05 dtucker Exp $ */ /* * Copyright (c) 2006 Chad Mynhier. @@ -20,8 +20,11 @@ #include +#include + 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 *); #endif diff --git a/openbsd-compat/timingsafe_bcmp.c b/openbsd-compat/timingsafe_bcmp.c new file mode 100644 index 000000000000..7e28c0e2a58f --- /dev/null +++ b/openbsd-compat/timingsafe_bcmp.c @@ -0,0 +1,34 @@ +/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */ +/* + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/timingsafe_bcmp.c */ + +#include "includes.h" +#ifndef HAVE_TIMINGSAFE_BCMP + +int +timingsafe_bcmp(const void *b1, const void *b2, size_t n) +{ + const unsigned char *p1 = b1, *p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); +} + +#endif /* TIMINGSAFE_BCMP */ diff --git a/opensshd.init.in b/opensshd.init.in index d0aff7794873..0db60caa7511 100755 --- a/opensshd.init.in +++ b/opensshd.init.in @@ -20,6 +20,7 @@ SSH_KEYGEN=$prefix/bin/ssh-keygen HOST_KEY_RSA1=$sysconfdir/ssh_host_key HOST_KEY_DSA=$sysconfdir/ssh_host_dsa_key HOST_KEY_RSA=$sysconfdir/ssh_host_rsa_key +@COMMENT_OUT_ECC@HOST_KEY_ECDSA=$sysconfdir/ssh_host_ecdsa_key checkkeys() { @@ -32,6 +33,9 @@ checkkeys() { if [ ! -f $HOST_KEY_RSA ]; then ${SSH_KEYGEN} -t rsa -f ${HOST_KEY_RSA} -N "" fi +@COMMENT_OUT_ECC@ if [ ! -f $HOST_KEY_ECDSA ]; then +@COMMENT_OUT_ECC@ ${SSH_KEYGEN} -t ecdsa -f ${HOST_KEY_ECDSA} -N "" +@COMMENT_OUT_ECC@ fi } stop_service() { diff --git a/packet.c b/packet.c index 48f7fe61332d..b4e01f716b47 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.168 2010/07/13 23:13:16 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.172 2010/11/13 23:27:50 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -199,13 +199,13 @@ static struct session_state *active_state, *backup_state; static struct session_state * alloc_session_state(void) { - struct session_state *s = xcalloc(1, sizeof(*s)); + struct session_state *s = xcalloc(1, sizeof(*s)); - s->connection_in = -1; - s->connection_out = -1; - s->max_packet_size = 32768; - s->packet_timeout_ms = -1; - return s; + s->connection_in = -1; + s->connection_out = -1; + s->max_packet_size = 32768; + s->packet_timeout_ms = -1; + return s; } /* @@ -391,8 +391,8 @@ packet_get_ssh1_cipher(void) } void -packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets, - u_int64_t *bytes) +packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, + u_int32_t *packets, u_int64_t *bytes) { struct packet_state *state; @@ -547,8 +547,7 @@ packet_start_compression(int level) */ void -packet_set_encryption_key(const u_char *key, u_int keylen, - int number) +packet_set_encryption_key(const u_char *key, u_int keylen, int number) { Cipher *cipher = cipher_by_number(number); @@ -641,6 +640,14 @@ packet_put_bignum2(BIGNUM * value) buffer_put_bignum2(&active_state->outgoing_packet, value); } +#ifdef OPENSSL_HAS_ECC +void +packet_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point) +{ + buffer_put_ecpoint(&active_state->outgoing_packet, curve, point); +} +#endif + /* * Finalizes and sends the packet. If the encryption key has been set, * encrypts the packet before sending. @@ -1511,6 +1518,14 @@ packet_get_bignum2(BIGNUM * value) buffer_get_bignum2(&active_state->incoming_packet, value); } +#ifdef OPENSSL_HAS_ECC +void +packet_get_ecpoint(const EC_GROUP *curve, EC_POINT *point) +{ + buffer_get_ecpoint(&active_state->incoming_packet, curve, point); +} +#endif + void * packet_get_raw(u_int *length_ptr) { @@ -1546,6 +1561,13 @@ packet_get_string_ptr(u_int *length_ptr) return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr); } +/* Ensures the returned string has no embedded \0 characters in it. */ +char * +packet_get_cstring(u_int *length_ptr) +{ + return buffer_get_cstring(&active_state->incoming_packet, length_ptr); +} + /* * Sends a diagnostic message from the server to the client. This message * can be sent at any time (but not while constructing another message). The @@ -1728,14 +1750,13 @@ packet_not_very_much_data_to_write(void) } static void -packet_set_tos(int interactive) +packet_set_tos(int tos) { #if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) - int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT; - if (!packet_connection_is_on_socket() || !packet_connection_is_ipv4()) return; + debug3("%s: set IP_TOS 0x%02x", __func__, tos); if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) error("setsockopt IP_TOS %d: %.100s:", @@ -1746,7 +1767,7 @@ packet_set_tos(int interactive) /* Informs that the current session is interactive. Sets IP flags for that. */ void -packet_set_interactive(int interactive) +packet_set_interactive(int interactive, int qos_interactive, int qos_bulk) { if (active_state->set_interactive_called) return; @@ -1759,7 +1780,7 @@ packet_set_interactive(int interactive) if (!packet_connection_is_on_socket()) return; set_nodelay(active_state->connection_in); - packet_set_tos(interactive); + packet_set_tos(interactive ? qos_interactive : qos_bulk); } /* Returns true if the current connection is interactive. */ diff --git a/packet.h b/packet.h index 33523d7503ca..d516aae8d491 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */ +/* $OpenBSD: packet.h,v 1.55 2010/11/13 23:27:50 djm Exp $ */ /* * Author: Tatu Ylonen @@ -19,6 +19,9 @@ #include #include +#ifdef OPENSSL_HAS_ECC +#include +#endif void packet_set_connection(int, int); void packet_set_timeout(int, int); @@ -31,7 +34,7 @@ u_int packet_get_encryption_key(u_char *); void packet_set_protocol_flags(u_int); u_int packet_get_protocol_flags(void); void packet_start_compression(int); -void packet_set_interactive(int); +void packet_set_interactive(int, int, int); int packet_is_interactive(void); void packet_set_server(void); void packet_set_authenticated(void); @@ -42,6 +45,9 @@ void packet_put_int(u_int value); void packet_put_int64(u_int64_t value); void packet_put_bignum(BIGNUM * value); void packet_put_bignum2(BIGNUM * value); +#ifdef OPENSSL_HAS_ECC +void packet_put_ecpoint(const EC_GROUP *, const EC_POINT *); +#endif void packet_put_string(const void *buf, u_int len); void packet_put_cstring(const char *str); void packet_put_raw(const void *buf, u_int len); @@ -59,8 +65,12 @@ u_int packet_get_int(void); u_int64_t packet_get_int64(void); void packet_get_bignum(BIGNUM * value); void packet_get_bignum2(BIGNUM * value); +#ifdef OPENSSL_HAS_ECC +void packet_get_ecpoint(const EC_GROUP *, EC_POINT *); +#endif void *packet_get_raw(u_int *length_ptr); void *packet_get_string(u_int *length_ptr); +char *packet_get_cstring(u_int *length_ptr); void *packet_get_string_ptr(u_int *length_ptr); void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); diff --git a/pathnames.h b/pathnames.h index 9e50950fe12b..e2dd49a9b724 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.19 2010/02/11 20:37:47 djm Exp $ */ +/* $OpenBSD: pathnames.h,v 1.20 2010/08/31 11:54:45 djm Exp $ */ /* * Author: Tatu Ylonen @@ -38,6 +38,7 @@ #define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config" #define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key" #define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" +#define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" #define _PATH_DH_MODULI SSHDIR "/moduli" /* Backwards compatibility */ @@ -74,6 +75,7 @@ */ #define _PATH_SSH_CLIENT_IDENTITY ".ssh/identity" #define _PATH_SSH_CLIENT_ID_DSA ".ssh/id_dsa" +#define _PATH_SSH_CLIENT_ID_ECDSA ".ssh/id_ecdsa" #define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa" /* diff --git a/platform.c b/platform.c index e3a428aaa089..a455472b3f54 100644 --- a/platform.c +++ b/platform.c @@ -1,4 +1,4 @@ -/* $Id: platform.c,v 1.3 2009/12/20 23:49:22 dtucker Exp $ */ +/* $Id: platform.c,v 1.18 2011/01/11 06:02:25 djm Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -16,11 +16,27 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "config.h" +#include "includes.h" + +#include + +#include +#include + +#include "log.h" +#include "buffer.h" +#include "servconf.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-pam.h" #include "platform.h" #include "openbsd-compat/openbsd-compat.h" +extern int use_privsep; +extern ServerOptions options; + void platform_pre_listen(void) { @@ -57,6 +73,118 @@ platform_post_fork_child(void) #endif } +/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ +int +platform_privileged_uidswap(void) +{ +#ifdef HAVE_CYGWIN + /* uid 0 is not special on Cygwin so always try */ + return 1; +#else + return (getuid() == 0 || geteuid() == 0); +#endif +} + +/* + * This gets called before switching UIDs, and is called even when sshd is + * not running as root. + */ +void +platform_setusercontext(struct passwd *pw) +{ +#ifdef WITH_SELINUX + /* Cache selinux status for later use */ + (void)ssh_selinux_enabled(); +#endif + +#ifdef USE_SOLARIS_PROJECTS + /* if solaris projects were detected, set the default now */ + if (getuid() == 0 || geteuid() == 0) + solaris_set_default_project(pw); +#endif + +#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) + if (getuid() == 0 || geteuid() == 0) + setpgid(0, 0); +# endif + +#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) + /* + * If we have both LOGIN_CAP and PAM, we want to establish creds + * before calling setusercontext (in session.c:do_setusercontext). + */ + if (getuid() == 0 || geteuid() == 0) { + if (options.use_pam) { + do_pam_setcred(use_privsep); + } + } +# endif /* USE_PAM */ + +#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) + if (getuid() == 0 || geteuid() == 0) { + /* Sets login uid for accounting */ + if (getluid() == -1 && setluid(pw->pw_uid) == -1) + error("setluid: %s", strerror(errno)); + } +#endif +} + +/* + * This gets called after we've established the user's groups, and is only + * called if sshd is running as root. + */ +void +platform_setusercontext_post_groups(struct passwd *pw) +{ +#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) + /* + * PAM credentials may take the form of supplementary groups. + * These will have been wiped by the above initgroups() call. + * Reestablish them here. + */ + if (options.use_pam) { + do_pam_setcred(use_privsep); + } +#endif /* USE_PAM */ + +#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) + irix_setusercontext(pw); +#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ + +#ifdef _AIX + aix_usrinfo(pw); +#endif /* _AIX */ + +#if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF) + if (set_id(pw->pw_name) != 0) { + exit(1); + } +# endif /* USE_LIBIAF */ + +#ifdef HAVE_SETPCRED + /* + * If we have a chroot directory, we set all creds except real + * uid which we will need for chroot. If we don't have a + * chroot directory, we don't override anything. + */ + { + char **creds = NULL, *chroot_creds[] = + { "REAL_USER=root", NULL }; + + if (options.chroot_directory != NULL && + strcasecmp(options.chroot_directory, "none") != 0) + creds = chroot_creds; + + if (setpcred(pw->pw_name, creds) == -1) + fatal("Failed to set process credentials"); + } +#endif /* HAVE_SETPCRED */ +#ifdef WITH_SELINUX + ssh_selinux_setup_exec_context(pw->pw_name); +#endif +} + char * platform_krb5_get_principal_name(const char *pw_name) { diff --git a/platform.h b/platform.h index 30a1d2259d3c..944d2c340dee 100644 --- a/platform.h +++ b/platform.h @@ -1,4 +1,4 @@ -/* $Id: platform.h,v 1.4 2010/01/14 01:44:16 djm Exp $ */ +/* $Id: platform.h,v 1.7 2010/11/05 03:47:01 dtucker Exp $ */ /* * Copyright (c) 2006 Darren Tucker. All rights reserved. @@ -18,10 +18,15 @@ #include +#include + void platform_pre_listen(void); void platform_pre_fork(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); +int platform_privileged_uidswap(void); +void platform_setusercontext(struct passwd *); +void platform_setusercontext_post_groups(struct passwd *); char *platform_get_krb5_client(const char *); char *platform_krb5_get_principal_name(const char *); diff --git a/readconf.c b/readconf.c index 0296590e2f41..eb4a8b9eea6a 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.187 2010/07/19 09:15:12 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.190 2010/11/13 23:27:50 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include @@ -132,6 +134,7 @@ typedef enum { oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, + oKexAlgorithms, oIPQoS, oDeprecated, oUnsupported } OpCodes; @@ -240,6 +243,8 @@ static struct { #else { "zeroknowledgepasswordauthentication", oUnsupported }, #endif + { "kexalgorithms", oKexAlgorithms }, + { "ipqos", oIPQoS }, { NULL, oBadOption } }; @@ -699,6 +704,18 @@ process_config_line(Options *options, const char *host, options->macs = xstrdup(arg); break; + case oKexAlgorithms: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", + filename, linenum); + if (!kex_names_valid(arg)) + fatal("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.", + filename, linenum, arg ? arg : ""); + if (*activep && options->kex_algorithms == NULL) + options->kex_algorithms = xstrdup(arg); + break; + case oHostKeyAlgorithms: arg = strdelim(&s); if (!arg || *arg == '\0') @@ -959,6 +976,23 @@ process_config_line(Options *options, const char *host, intptr = &options->visual_host_key; goto parse_flag; + case oIPQoS: + arg = strdelim(&s); + if ((value = parse_ipqos(arg)) == -1) + fatal("%s line %d: Bad IPQoS value: %s", + filename, linenum, arg); + arg = strdelim(&s); + if (arg == NULL) + value2 = value; + else if ((value2 = parse_ipqos(arg)) == -1) + fatal("%s line %d: Bad IPQoS value: %s", + filename, linenum, arg); + if (*activep) { + options->ip_qos_interactive = value; + options->ip_qos_bulk = value2; + } + break; + case oUseRoaming: intptr = &options->use_roaming; goto parse_flag; @@ -1078,6 +1112,7 @@ initialize_options(Options * options) options->cipher = -1; options->ciphers = NULL; options->macs = NULL; + options->kex_algorithms = NULL; options->hostkeyalgorithms = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->num_identity_files = 0; @@ -1120,6 +1155,8 @@ initialize_options(Options * options) options->use_roaming = -1; options->visual_host_key = -1; options->zero_knowledge_password_authentication = -1; + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; } /* @@ -1191,6 +1228,7 @@ fill_default_options(Options * options) options->cipher = SSH_CIPHER_NOT_SET; /* options->ciphers, default set in myproposals.h */ /* options->macs, default set in myproposals.h */ + /* options->kex_algorithms, default set in myproposals.h */ /* options->hostkeyalgorithms, default set in myproposals.h */ if (options->protocol == SSH_PROTO_UNKNOWN) options->protocol = SSH_PROTO_2; @@ -1214,6 +1252,13 @@ fill_default_options(Options * options) xmalloc(len); snprintf(options->identity_files[options->num_identity_files++], len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA); +#ifdef OPENSSL_HAS_ECC + len = 2 + strlen(_PATH_SSH_CLIENT_ID_ECDSA) + 1; + options->identity_files[options->num_identity_files] = + xmalloc(len); + snprintf(options->identity_files[options->num_identity_files++], + len, "~/%.100s", _PATH_SSH_CLIENT_ID_ECDSA); +#endif } } if (options->escape_char == -1) @@ -1266,6 +1311,10 @@ fill_default_options(Options * options) options->visual_host_key = 0; if (options->zero_knowledge_password_authentication == -1) options->zero_knowledge_password_authentication = 0; + if (options->ip_qos_interactive == -1) + options->ip_qos_interactive = IPTOS_LOWDELAY; + if (options->ip_qos_bulk == -1) + options->ip_qos_bulk = IPTOS_THROUGHPUT; /* options->local_command should not be set by default */ /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ diff --git a/readconf.h b/readconf.h index 95d104674724..ee160dfe7b1c 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.86 2010/07/19 09:15:12 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.88 2010/11/13 23:27:50 djm Exp $ */ /* * Author: Tatu Ylonen @@ -59,6 +59,8 @@ typedef struct { int compression_level; /* Compression level 1 (fast) to 9 * (best). */ int tcp_keep_alive; /* Set SO_KEEPALIVE. */ + int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ + int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ @@ -73,6 +75,7 @@ typedef struct { char *ciphers; /* SSH2 ciphers in order of preference. */ char *macs; /* SSH2 macs in order of preference. */ char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */ + char *kex_algorithms; /* SSH2 kex methods in order of preference. */ int protocol; /* Protocol in order of preference. */ char *hostname; /* Real host to connect. */ char *host_key_alias; /* hostname alias for .ssh/known_hosts */ diff --git a/readpass.c b/readpass.c index bd144c2e3917..599c8ef9a855 100644 --- a/readpass.c +++ b/readpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readpass.c,v 1.47 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: readpass.c,v 1.48 2010/12/15 00:49:27 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -33,6 +33,7 @@ #ifdef HAVE_PATHS_H # include #endif +#include #include #include #include @@ -49,11 +50,12 @@ static char * ssh_askpass(char *askpass, const char *msg) { - pid_t pid; + pid_t pid, ret; size_t len; char *pass; - int p[2], status, ret; + int p[2], status; char buf[1024]; + void (*osigchld)(int); if (fflush(stdout) != 0) error("ssh_askpass: fflush: %s", strerror(errno)); @@ -63,8 +65,10 @@ ssh_askpass(char *askpass, const char *msg) error("ssh_askpass: pipe: %s", strerror(errno)); return NULL; } + osigchld = signal(SIGCHLD, SIG_DFL); if ((pid = fork()) < 0) { error("ssh_askpass: fork: %s", strerror(errno)); + signal(SIGCHLD, osigchld); return NULL; } if (pid == 0) { @@ -77,23 +81,24 @@ ssh_askpass(char *askpass, const char *msg) } close(p[1]); - len = ret = 0; + len = 0; do { - ret = read(p[0], buf + len, sizeof(buf) - 1 - len); - if (ret == -1 && errno == EINTR) + ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len); + + if (r == -1 && errno == EINTR) continue; - if (ret <= 0) + if (r <= 0) break; - len += ret; + len += r; } while (sizeof(buf) - 1 - len > 0); buf[len] = '\0'; close(p[0]); - while (waitpid(pid, &status, 0) < 0) + while ((ret = waitpid(pid, &status, 0)) < 0) if (errno != EINTR) break; - - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + signal(SIGCHLD, osigchld); + if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { memset(buf, 0, sizeof(buf)); return NULL; } diff --git a/regress/Makefile b/regress/Makefile index 9762ab204ed1..f114c27e912d 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.54 2010/06/27 19:19:56 phessler Exp $ +# $OpenBSD: Makefile,v 1.58 2011/01/06 22:46:21 djm Exp $ -REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec +REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t-exec tests: $(REGRESS_TARGETS) # Interop tests are not run by default @@ -53,14 +53,20 @@ LTESTS= connect \ localcommand \ forcecommand \ portnum \ + keytype \ + kextype \ cert-hostkey \ - cert-userkey + cert-userkey \ + host-expand INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers #INTEROP_TESTS+=ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp +#LTESTS= cipher-speed + USER!= id -un -CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ +CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ + t8.out t8.out.pub t9.out t9.out.pub \ authorized_keys_${USER} known_hosts pidfile \ ssh_config sshd_config.orig ssh_proxy sshd_config sshd_proxy \ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ @@ -69,45 +75,68 @@ CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ scp-ssh-wrapper.scp ssh_proxy_envpass remote_pid \ sshd_proxy_bak rsa_ssh2_cr.prv rsa_ssh2_crnl.prv \ known_hosts-cert host_ca_key* cert_host_key* \ - putty.rsa2 sshd_proxy_orig \ - authorized_principals_${USER} + putty.rsa2 sshd_proxy_orig ssh_proxy_bak \ + key.rsa-* key.dsa-* key.ecdsa-* \ + authorized_principals_${USER} expect actual # Enable all malloc(3) randomisations and checks TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" +TEST_SSH_SSHKEYGEN?=ssh-keygen + t1: - ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv + ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv + tr '\n' '\r' <${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_cr.prv + ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_cr.prv | diff - ${.CURDIR}/rsa_openssh.prv + awk '{print $$0 "\r"}' ${.CURDIR}/rsa_ssh2.prv > ${.OBJDIR}/rsa_ssh2_crnl.prv + ${TEST_SSH_SSHKEYGEN} -if ${.OBJDIR}/rsa_ssh2_crnl.prv | diff - ${.CURDIR}/rsa_openssh.prv t2: cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out chmod 600 $(OBJ)/t2.out - ssh-keygen -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub + ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub t3: - ssh-keygen -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/rsa_secsh.pub - ssh-keygen -if $(OBJ)/rsa_secsh.pub | diff - ${.CURDIR}/rsa_openssh.pub - rm -f ${.CURDIR}/rsa_secsh.pub + ${TEST_SSH_SSHKEYGEN} -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/t3.out + ${TEST_SSH_SSHKEYGEN} -if $(OBJ)/t3.out | diff - ${.CURDIR}/rsa_openssh.pub t4: - ssh-keygen -lf ${.CURDIR}/rsa_openssh.pub |\ + ${TEST_SSH_SSHKEYGEN} -lf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t4.ok t5: - ssh-keygen -Bf ${.CURDIR}/rsa_openssh.pub |\ + ${TEST_SSH_SSHKEYGEN} -Bf ${.CURDIR}/rsa_openssh.pub |\ awk '{print $$2}' | diff - ${.CURDIR}/t5.ok t6: - ssh-keygen -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 - ssh-keygen -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 + ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 + ${TEST_SSH_SSHKEYGEN} -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 chmod 600 $(OBJ)/t6.out1 - ssh-keygen -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 + ${TEST_SSH_SSHKEYGEN} -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 $(OBJ)/t7.out: - ssh-keygen -q -t rsa -N '' -f $@ + ${TEST_SSH_SSHKEYGEN} -q -t rsa -N '' -f $@ t7: $(OBJ)/t7.out - ssh-keygen -lf $(OBJ)/t7.out > /dev/null - ssh-keygen -Bf $(OBJ)/t7.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t7.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t7.out > /dev/null + +$(OBJ)/t8.out: + ${TEST_SSH_SSHKEYGEN} -q -t dsa -N '' -f $@ + +t8: $(OBJ)/t8.out + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t8.out > /dev/null + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t8.out > /dev/null + +$(OBJ)/t9.out: + test "${TEST_SSH_ECC}" != yes || \ + ${TEST_SSH_SSHKEYGEN} -q -t ecdsa -N '' -f $@ + +t9: $(OBJ)/t9.out + test "${TEST_SSH_ECC}" != yes || \ + ${TEST_SSH_SSHKEYGEN} -lf $(OBJ)/t9.out > /dev/null + test "${TEST_SSH_ECC}" != yes || \ + ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null t-exec: ${LTESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ @@ -123,3 +152,5 @@ t-exec-interop: ${INTEROP_TESTS:=.sh} (env SUDO="${SUDO}" TEST_ENV=${TEST_ENV} sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ done +# Not run by default +interop: ${INTEROP_TARGETS} diff --git a/regress/agent-getpeereid.sh b/regress/agent-getpeereid.sh index 5d7f73291dc8..faf654c042d8 100644 --- a/regress/agent-getpeereid.sh +++ b/regress/agent-getpeereid.sh @@ -7,10 +7,9 @@ UNPRIV=nobody ASOCK=${OBJ}/agent SSH_AUTH_SOCK=/nonexistent -if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 && \ - grep "#undef.*HAVE_GETPEERUCRED" ${BUILDDIR}/config.h >/dev/null && \ - grep "#undef.*HAVE_SO_PEERCRED" ${BUILDDIR}/config.h >/dev/null -then +if config_defined HAVE_GETPEEREID HAVE_GETPEERUCRED HAVE_SO_PEERCRED ; then + : +else echo "skipped (not supported on this platform)" exit 0 fi @@ -34,7 +33,7 @@ else fail "ssh-add failed with $r != 1" fi - < /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l > /dev/null 2>&1 + < /dev/null ${SUDO} -S -u ${UNPRIV} ssh-add -l 2>/dev/null r=$? if [ $r -lt 2 ]; then fail "ssh-add did not fail for ${UNPRIV}: $r < 2" diff --git a/regress/agent-ptrace.sh b/regress/agent-ptrace.sh index d5892ed03098..9f29464c59cc 100644 --- a/regress/agent-ptrace.sh +++ b/regress/agent-ptrace.sh @@ -41,7 +41,7 @@ EOF if [ $? -ne 0 ]; then fail "gdb failed: exit code $?" fi - egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.' >/dev/null ${OBJ}/gdb.out + egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null ${OBJ}/gdb.out r=$? rm -f ${OBJ}/gdb.out if [ $r -ne 0 ]; then diff --git a/regress/cert-hostkey.sh b/regress/cert-hostkey.sh index 0265e8f6b04e..3b147b9f77c3 100755 --- a/regress/cert-hostkey.sh +++ b/regress/cert-hostkey.sh @@ -1,8 +1,14 @@ -# $OpenBSD: cert-hostkey.sh,v 1.4 2010/04/16 01:58:45 djm Exp $ +# $OpenBSD: cert-hostkey.sh,v 1.5 2010/08/31 12:24:09 djm Exp $ # Placed in the Public Domain. tid="certified host keys" +# used to disable ECC based tests on platforms without ECC +ecdsa="" +if test "x$TEST_SSH_ECC" = "xyes"; then + ecdsa=ecdsa +fi + rm -f $OBJ/known_hosts-cert $OBJ/host_ca_key* $OBJ/cert_host_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak @@ -18,7 +24,7 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key ||\ ) > $OBJ/known_hosts-cert # Generate and sign host keys -for ktype in rsa dsa ; do +for ktype in rsa dsa $ecdsa ; do verbose "$tid: sign host ${ktype} cert" # Generate and sign a host key ${SSHKEYGEN} -q -N '' -t ${ktype} \ @@ -28,6 +34,8 @@ for ktype in rsa dsa ; do -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype} || fail "couldn't sign cert_host_key_${ktype}" + # v00 ecdsa certs do not exist + test "${ktype}" = "ecdsa" && continue cp $OBJ/cert_host_key_${ktype} $OBJ/cert_host_key_${ktype}_v00 cp $OBJ/cert_host_key_${ktype}.pub $OBJ/cert_host_key_${ktype}_v00.pub ${SSHKEYGEN} -t v00 -h -q -s $OBJ/host_ca_key \ @@ -38,7 +46,7 @@ done # Basic connect tests for privsep in yes no ; do - for ktype in rsa dsa rsa_v00 dsa_v00; do + for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do verbose "$tid: host ${ktype} cert connect privsep $privsep" ( cat $OBJ/sshd_proxy_bak @@ -64,6 +72,11 @@ done echon '@revoked ' echon "* " cat $OBJ/cert_host_key_rsa.pub + if test "x$TEST_SSH_ECC" = "xyes"; then + echon '@revoked ' + echon "* " + cat $OBJ/cert_host_key_ecdsa.pub + fi echon '@revoked ' echon "* " cat $OBJ/cert_host_key_dsa.pub @@ -75,7 +88,7 @@ done cat $OBJ/cert_host_key_dsa_v00.pub ) > $OBJ/known_hosts-cert for privsep in yes no ; do - for ktype in rsa dsa rsa_v00 dsa_v00; do + for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00; do verbose "$tid: host ${ktype} revoked cert privsep $privsep" ( cat $OBJ/sshd_proxy_bak @@ -102,7 +115,7 @@ done echon "* " cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert -for ktype in rsa dsa rsa_v00 dsa_v00 ; do +for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do verbose "$tid: host ${ktype} revoked cert" ( cat $OBJ/sshd_proxy_bak @@ -173,7 +186,9 @@ test_one "cert has constraints" failure "-h -Oforce-command=false" # Check downgrade of cert to raw key when no CA found for v in v01 v00 ; do - for ktype in rsa dsa ; do + for ktype in rsa dsa $ecdsa ; do + # v00 ecdsa certs do not exist. + test "${v}${ktype}" = "v00ecdsa" && continue rm -f $OBJ/known_hosts-cert $OBJ/cert_host_key* verbose "$tid: host ${ktype} ${v} cert downgrade to raw key" # Generate and sign a host key @@ -210,7 +225,9 @@ done cat $OBJ/host_ca_key.pub ) > $OBJ/known_hosts-cert for v in v01 v00 ; do - for kt in rsa dsa ; do + for kt in rsa dsa $ecdsa ; do + # v00 ecdsa certs do not exist. + test "${v}${ktype}" = "v00ecdsa" && continue rm -f $OBJ/cert_host_key* # Self-sign key ${SSHKEYGEN} -q -N '' -t ${kt} \ diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index a41a9a9c012b..fcca3708b219 100755 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,8 +1,14 @@ -# $OpenBSD: cert-userkey.sh,v 1.6 2010/06/29 23:59:54 djm Exp $ +# $OpenBSD: cert-userkey.sh,v 1.7 2010/08/31 12:24:09 djm Exp $ # Placed in the Public Domain. tid="certified user keys" +# used to disable ECC based tests on platforms without ECC +ecdsa="" +if test "x$TEST_SSH_ECC" = "xyes"; then + ecdsa=ecdsa +fi + rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak @@ -11,7 +17,7 @@ ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/user_ca_key ||\ fail "ssh-keygen of user_ca_key failed" # Generate and sign user keys -for ktype in rsa dsa ; do +for ktype in rsa dsa $ecdsa ; do verbose "$tid: sign user ${ktype} cert" ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_user_key_${ktype} || \ @@ -20,6 +26,8 @@ for ktype in rsa dsa ; do "regress user key for $USER" \ -n ${USER},mekmitasdigoat $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" + # v00 ecdsa certs do not exist + test "{ktype}" = "ecdsa" && continue cp $OBJ/cert_user_key_${ktype} $OBJ/cert_user_key_${ktype}_v00 cp $OBJ/cert_user_key_${ktype}.pub $OBJ/cert_user_key_${ktype}_v00.pub ${SSHKEYGEN} -q -t v00 -s $OBJ/user_ca_key -I \ @@ -29,7 +37,7 @@ for ktype in rsa dsa ; do done # Test explicitly-specified principals -for ktype in rsa dsa rsa_v00 dsa_v00 ; do +for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do for privsep in yes no ; do _prefix="${ktype} privsep $privsep" @@ -155,7 +163,7 @@ basic_tests() { extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" fi - for ktype in rsa dsa rsa_v00 dsa_v00 ; do + for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do for privsep in yes no ; do _prefix="${ktype} privsep $privsep $auth" # Simple connect @@ -230,6 +238,11 @@ test_one() { for auth in $auth_choice ; do for ktype in rsa rsa_v00 ; do + case $ktype in + *_v00) keyv="-t v00" ;; + *) keyv="" ;; + esac + cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy if test "x$auth" = "xauthorized_keys" ; then # Add CA to authorized_keys @@ -249,7 +262,7 @@ test_one() { verbose "$tid: $ident auth $auth expect $result $ktype" ${SSHKEYGEN} -q -s $OBJ/user_ca_key \ -I "regress user key for $USER" \ - $sign_opts \ + $sign_opts $keyv \ $OBJ/cert_user_key_${ktype} || fail "couldn't sign cert_user_key_${ktype}" @@ -302,7 +315,7 @@ test_one "principals key option no principals" failure "" \ # Wrong certificate cat $OBJ/sshd_proxy_bak > $OBJ/sshd_proxy -for ktype in rsa dsa rsa_v00 dsa_v00 ; do +for ktype in rsa dsa $ecdsa rsa_v00 dsa_v00 ; do case $ktype in *_v00) args="-t v00" ;; *) args="" ;; diff --git a/regress/host-expand.sh b/regress/host-expand.sh new file mode 100755 index 000000000000..a0188363dc69 --- /dev/null +++ b/regress/host-expand.sh @@ -0,0 +1,18 @@ +# Placed in the Public Domain. + +tid="expand %h and %n" + +echo 'PermitLocalCommand yes' >> $OBJ/ssh_proxy +printf 'LocalCommand printf "%%%%s\\n" "%%n" "%%h"\n' >> $OBJ/ssh_proxy + +cat >$OBJ/expect <$OBJ/actual + diff $OBJ/expect $OBJ/actual || fail "$tid proto $p" +done + diff --git a/regress/kextype.sh b/regress/kextype.sh new file mode 100755 index 000000000000..79c0817bb05c --- /dev/null +++ b/regress/kextype.sh @@ -0,0 +1,30 @@ +# $OpenBSD: kextype.sh,v 1.1 2010/09/22 12:26:05 djm Exp $ +# Placed in the Public Domain. + +tid="login with different key exchange algorithms" + +TIME=/usr/bin/time +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + +if test "$TEST_SSH_ECC" = "yes"; then + kextypes="ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521" +fi +if test "$TEST_SSH_SHA256" = "yes"; then + kextypes="$kextypes diffie-hellman-group-exchange-sha256" +fi +kextypes="$kextypes diffie-hellman-group-exchange-sha1" +kextypes="$kextypes diffie-hellman-group14-sha1" +kextypes="$kextypes diffie-hellman-group1-sha1" + +tries="1 2 3 4" +for k in $kextypes; do + verbose "kex $k" + for i in $tries; do + ${SSH} -F $OBJ/ssh_proxy -o KexAlgorithms=$k x true + if [ $? -ne 0 ]; then + fail "ssh kex $k" + fi + done +done + diff --git a/regress/keytype.sh b/regress/keytype.sh new file mode 100755 index 000000000000..2cbf132bd16d --- /dev/null +++ b/regress/keytype.sh @@ -0,0 +1,55 @@ +# $OpenBSD: keytype.sh,v 1.1 2010/09/02 16:12:55 markus Exp $ +# Placed in the Public Domain. + +tid="login with different key types" + +TIME=`which time` 2>/dev/null +if test ! -x "$TIME"; then + TIME="" +fi + +cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak + +ktypes="dsa-1024 rsa-2048 rsa-3072" +if test "$TEST_SSH_ECC" = "yes"; then + ktypes="$ktypes ecdsa-256 ecdsa-384 ecdsa-521" +fi + +for kt in $ktypes; do + rm -f $OBJ/key.$kt + bits=`echo ${kt} | awk -F- '{print $2}'` + type=`echo ${kt} | awk -F- '{print $1}'` + printf "keygen $type, $bits bits:\t" + ${TIME} ${SSHKEYGEN} -b $bits -q -N '' -t $type -f $OBJ/key.$kt ||\ + fail "ssh-keygen for type $type, $bits bits failed" +done + +tries="1 2 3" +for ut in $ktypes; do + htypes=$ut + #htypes=$ktypes + for ht in $htypes; do + trace "ssh connect, userkey $ut, hostkey $ht" + ( + grep -v HostKey $OBJ/sshd_proxy_bak + echo HostKey $OBJ/key.$ht + ) > $OBJ/sshd_proxy + ( + grep -v IdentityFile $OBJ/ssh_proxy_bak + echo IdentityFile $OBJ/key.$ut + ) > $OBJ/ssh_proxy + ( + echon 'localhost-with-alias,127.0.0.1,::1 ' + cat $OBJ/key.$ht.pub + ) > $OBJ/known_hosts + cat $OBJ/key.$ut.pub > $OBJ/authorized_keys_$USER + for i in $tries; do + printf "userkey $ut, hostkey ${ht}:\t" + ${TIME} ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + fail "ssh userkey $ut, hostkey $ht failed" + fi + done + done +done diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 8a98a6e54026..b94cdf02f785 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -5,8 +5,7 @@ CTL=/tmp/openssh.regress.ctl-sock.$$ tid="connection multiplexing" -if grep "#define.*DISABLE_FD_PASSING" ${BUILDDIR}/config.h >/dev/null 2>&1 -then +if config_defined DISABLE_FD_PASSING ; then echo "skipped (not supported on this platform)" exit 0 fi diff --git a/regress/sftp-cmds.sh b/regress/sftp-cmds.sh index c4d6ae2deb3a..1c67b6476638 100644 --- a/regress/sftp-cmds.sh +++ b/regress/sftp-cmds.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sftp-cmds.sh,v 1.10 2009/08/13 01:11:55 djm Exp $ +# $OpenBSD: sftp-cmds.sh,v 1.11 2010/12/04 00:21:19 djm Exp $ # Placed in the Public Domain. # XXX - TODO: @@ -209,7 +209,13 @@ test -d ${COPY}.dd2 || fail "missing newname after rename directory" verbose "$tid: ln" echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" -test -h ${COPY}.2 || fail "missing file after ln" +test -f ${COPY}.2 || fail "missing file after ln" +cmp ${COPY}.1 ${COPY}.2 || fail "created file is not equal after ln" + +verbose "$tid: ln -s" +rm -f ${COPY}.2 +echo "ln -s ${COPY}.1 ${COPY}.2" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 || fail "ln -s failed" +test -h ${COPY}.2 || fail "missing file after ln -s" verbose "$tid: mkdir" echo "mkdir ${COPY}.dd" | ${SFTP} -D ${SFTPSERVER} >/dev/null 2>&1 \ diff --git a/regress/sftp-glob.sh b/regress/sftp-glob.sh index 72bb17d75336..8d4df2c98b5f 100644 --- a/regress/sftp-glob.sh +++ b/regress/sftp-glob.sh @@ -3,11 +3,18 @@ tid="sftp glob" +config_defined FILESYSTEM_NO_BACKSLASH && nobs="not supported on this platform" + sftp_ls() { target=$1 errtag=$2 expected=$3 unexpected=$4 + skip=$5 + if test "x$skip" != "x" ; then + verbose "$tid: $errtag (skipped: $skip)" + return + fi verbose "$tid: $errtag" printf "ls -l %s" "${target}" | \ ${SFTP} -b - -D ${SFTPSERVER} 2>/dev/null | \ @@ -44,8 +51,8 @@ SPACE="${DIR}/g-q space" rm -rf ${BASE} mkdir -p ${DIR} -touch "${DATA}" "${GLOB1}" "${GLOB2}" "${QUOTE}" -touch "${QSLASH}" "${ESLASH}" "${SLASH}" "${SPACE}" +touch "${DATA}" "${GLOB1}" "${GLOB2}" "${QUOTE}" "${SPACE}" +test "x$nobs" = "x" && touch "${QSLASH}" "${ESLASH}" "${SLASH}" # target message expected unexpected sftp_ls "${DIR}/fil*" "file glob" "${DATA}" "" @@ -55,14 +62,14 @@ sftp_ls "${DIR}/g-wild\*" "escaped glob" "g-wild*" "g-wildx" sftp_ls "${DIR}/g-quote\\\"" "escaped quote" "g-quote\"" "" sftp_ls "\"${DIR}/g-quote\\\"\"" "quoted quote" "g-quote\"" "" sftp_ls "'${DIR}/g-quote\"'" "single-quoted quote" "g-quote\"" "" -sftp_ls "${DIR}/g-sl\\\\ash" "escaped slash" "g-sl\\ash" "" -sftp_ls "'${DIR}/g-sl\\\\ash'" "quoted slash" "g-sl\\ash" "" -sftp_ls "${DIR}/g-slash\\\\" "escaped slash at EOL" "g-slash\\" "" -sftp_ls "'${DIR}/g-slash\\\\'" "quoted slash at EOL" "g-slash\\" "" -sftp_ls "${DIR}/g-qs\\\\\\\"" "escaped slash+quote" "g-qs\\\"" "" -sftp_ls "'${DIR}/g-qs\\\\\"'" "quoted slash+quote" "g-qs\\\"" "" sftp_ls "${DIR}/g-q\\ space" "escaped space" "g-q space" "" sftp_ls "'${DIR}/g-q space'" "quoted space" "g-q space" "" +sftp_ls "${DIR}/g-sl\\\\ash" "escaped slash" "g-sl\\ash" "" "$nobs" +sftp_ls "'${DIR}/g-sl\\\\ash'" "quoted slash" "g-sl\\ash" "" "$nobs" +sftp_ls "${DIR}/g-slash\\\\" "escaped slash at EOL" "g-slash\\" "" "$nobs" +sftp_ls "'${DIR}/g-slash\\\\'" "quoted slash at EOL" "g-slash\\" "" "$nobs" +sftp_ls "${DIR}/g-qs\\\\\\\"" "escaped slash+quote" "g-qs\\\"" "" "$nobs" +sftp_ls "'${DIR}/g-qs\\\\\"'" "quoted slash+quote" "g-qs\\\"" "" "$nobs" rm -rf ${BASE} diff --git a/regress/test-exec.sh b/regress/test-exec.sh index b64dcdbcf86c..5c56aefff9c2 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -221,6 +221,17 @@ fatal () exit $RESULT } +# Check whether preprocessor symbols are defined in config.h. +config_defined () +{ + str=$1 + while test "x$2" != "x" ; do + str="$str|$2" + shift + done + egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1 +} + RESULT=0 PIDFILE=$OBJ/pidfile diff --git a/schnorr.c b/schnorr.c index c17ff3241b7c..4d54d68812cf 100644 --- a/schnorr.c +++ b/schnorr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */ +/* $OpenBSD: schnorr.c,v 1.5 2010/12/03 23:49:26 djm Exp $ */ /* * Copyright (c) 2008 Damien Miller. All rights reserved. * @@ -138,6 +138,10 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, error("%s: g_x < 1", __func__); return -1; } + if (BN_cmp(g_x, grp_p) >= 0) { + error("%s: g_x > g", __func__); + return -1; + } h = g_v = r = tmp = v = NULL; if ((bn_ctx = BN_CTX_new()) == NULL) { @@ -254,14 +258,19 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, const BIGNUM *r, const BIGNUM *e) { int success = -1; - BIGNUM *h, *g_xh, *g_r, *expected; + BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL; + BIGNUM *expected = NULL; BN_CTX *bn_ctx; SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); /* Avoid degenerate cases: g^0 yields a spoofable signature */ if (BN_cmp(g_x, BN_value_one()) <= 0) { - error("%s: g_x < 1", __func__); + error("%s: g_x <= 1", __func__); + return -1; + } + if (BN_cmp(g_x, grp_p) >= 0) { + error("%s: g_x >= p", __func__); return -1; } @@ -272,6 +281,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, } if ((g_xh = BN_new()) == NULL || (g_r = BN_new()) == NULL || + (gx_q = BN_new()) == NULL || (expected = BN_new()) == NULL) { error("%s: BN_new", __func__); goto out; @@ -280,6 +290,17 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); + /* gx_q = (g^x)^q must === 1 mod p */ + if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) { + error("%s: BN_mod_exp (g_x^q mod p)", __func__); + goto out; + } + if (BN_cmp(gx_q, BN_value_one()) != 0) { + error("%s: Invalid signature (g^x)^q != 1 mod p", __func__); + goto out; + } + + SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); /* h = H(g || g^v || g^x || id) */ if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, id, idlen)) == NULL) { @@ -314,9 +335,14 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, BN_CTX_free(bn_ctx); if (h != NULL) BN_clear_free(h); - BN_clear_free(g_xh); - BN_clear_free(g_r); - BN_clear_free(expected); + if (gx_q != NULL) + BN_clear_free(gx_q); + if (g_xh != NULL) + BN_clear_free(g_xh); + if (g_r != NULL) + BN_clear_free(g_r); + if (expected != NULL) + BN_clear_free(expected); return success; } diff --git a/scp.0 b/scp.0 index f5af8ccd5824..f006316269ea 100644 --- a/scp.0 +++ b/scp.0 @@ -4,7 +4,7 @@ NAME scp - secure copy (remote file copy program) SYNOPSIS - scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] + scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-S program] [[user@]host1:]file1 ... [[user@]host2:]file2 @@ -26,6 +26,11 @@ DESCRIPTION -2 Forces scp to use protocol 2. + -3 Copies between two remote hosts are transferred through the local + host. Without this option the data is copied directly between + the two remote hosts. Note that this option disables the + progress meter. + -4 Forces scp to use IPv4 addresses only. -6 Forces scp to use IPv6 addresses only. @@ -83,7 +88,9 @@ DESCRIPTION HostName IdentityFile IdentitiesOnly + IPQoS KbdInteractiveDevices + KexAlgorithms LogLevel MACs NoHostAuthenticationForLocalhost @@ -131,6 +138,7 @@ DESCRIPTION about their progress. This is helpful in debugging connection, authentication, and configuration problems. +EXIT STATUS The scp utility exits 0 on success, and >0 if an error occurs. SEE ALSO @@ -145,4 +153,4 @@ AUTHORS Timo Rinne Tatu Ylonen -OpenBSD 4.8 February 8, 2010 OpenBSD 4.8 +OpenBSD 4.8 December 9, 2010 OpenBSD 4.8 diff --git a/scp.1 b/scp.1 index bc5e259f54fe..577dd52c1dd9 100644 --- a/scp.1 +++ b/scp.1 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" scp.1 .\" @@ -9,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.50 2010/02/08 10:50:20 markus Exp $ +.\" $OpenBSD: scp.1,v 1.56 2010/12/09 14:13:32 jmc Exp $ .\" -.Dd $Mdocdate: February 8 2010 $ +.Dd $Mdocdate: December 9 2010 $ .Dt SCP 1 .Os .Sh NAME @@ -20,7 +19,7 @@ .Sh SYNOPSIS .Nm scp .Bk -words -.Op Fl 1246BCpqrv +.Op Fl 12346BCpqrv .Op Fl c Ar cipher .Op Fl F Ar ssh_config .Op Fl i Ar identity_file @@ -76,6 +75,11 @@ to use protocol 1. Forces .Nm to use protocol 2. +.It Fl 3 +Copies between two remote hosts are transferred through the local host. +Without this option the data is copied directly between the two remote +hosts. +Note that this option disables the progress meter. .It Fl 4 Forces .Nm @@ -147,7 +151,9 @@ For full details of the options listed below, and their possible values, see .It HostName .It IdentityFile .It IdentitiesOnly +.It IPQoS .It KbdInteractiveDevices +.It KexAlgorithms .It LogLevel .It MACs .It NoHostAuthenticationForLocalhost @@ -209,7 +215,7 @@ to print debugging messages about their progress. This is helpful in debugging connection, authentication, and configuration problems. .El -.Pp +.Sh EXIT STATUS .Ex -std scp .Sh SEE ALSO .Xr rcp 1 , diff --git a/scp.c b/scp.c index e07de42f776d..18b2597fe13b 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.166 2010/07/01 13:06:59 millert Exp $ */ +/* $OpenBSD: scp.c,v 1.170 2010/12/09 14:13:33 jmc Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -119,14 +119,15 @@ extern char *__progname; #define COPY_BUFLEN 16384 int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); - -void bwlimit(int); +int do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout); /* Struct for addargs */ arglist args; +arglist remote_remote_args; /* Bandwidth limit */ -off_t limit_rate = 0; +long long limit_kbps = 0; +struct bwlimit bwlimit; /* Name of current file being transferred. */ char *curfile; @@ -137,6 +138,12 @@ int verbose_mode = 0; /* This is set to zero if the progressmeter is not desired. */ int showprogress = 1; +/* + * This is set to non-zero if remote-remote copy should be piped + * through this process. + */ +int throughlocal = 0; + /* This is the program to execute for the secured connection. ("ssh" or -S) */ char *ssh_program = _PATH_SSH_PROGRAM; @@ -287,6 +294,50 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) return 0; } +/* + * This functions executes a command simlar to do_cmd(), but expects the + * input and output descriptors to be setup by a previous call to do_cmd(). + * This way the input and output of two commands can be connected. + */ +int +do_cmd2(char *host, char *remuser, char *cmd, int fdin, int fdout) +{ + pid_t pid; + int status; + + if (verbose_mode) + fprintf(stderr, + "Executing: 2nd program %s host %s, user %s, command %s\n", + ssh_program, host, + remuser ? remuser : "(unspecified)", cmd); + + /* Fork a child to execute the command on the remote host using ssh. */ + pid = fork(); + if (pid == 0) { + dup2(fdin, 0); + dup2(fdout, 1); + + replacearg(&args, 0, "%s", ssh_program); + if (remuser != NULL) { + addargs(&args, "-l"); + addargs(&args, "%s", remuser); + } + addargs(&args, "--"); + addargs(&args, "%s", host); + addargs(&args, "%s", cmd); + + execvp(ssh_program, args.list); + perror(ssh_program); + exit(1); + } else if (pid == -1) { + fatal("fork: %s", strerror(errno)); + } + while (waitpid(pid, &status, 0) == -1) + if (errno != EINTR) + fatal("do_cmd2: waitpid: %s", strerror(errno)); + return 0; +} + typedef struct { size_t cnt; char *buf; @@ -312,15 +363,14 @@ void sink(int, char *[]); void source(int, char *[]); void tolocal(int, char *[]); void toremote(char *, int, char *[]); -size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *); void usage(void); int main(int argc, char **argv) { int ch, fflag, tflag, status, n; - double speed; - char *targ, *endp, **newargv; + char *targ, **newargv; + const char *errstr; extern char *optarg; extern int optind; @@ -336,15 +386,16 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); memset(&args, '\0', sizeof(args)); - args.list = NULL; + memset(&remote_remote_args, '\0', sizeof(remote_remote_args)); + args.list = remote_remote_args.list = NULL; addargs(&args, "%s", ssh_program); addargs(&args, "-x"); - addargs(&args, "-oForwardAgent no"); - addargs(&args, "-oPermitLocalCommand no"); - addargs(&args, "-oClearAllForwardings yes"); + addargs(&args, "-oForwardAgent=no"); + addargs(&args, "-oPermitLocalCommand=no"); + addargs(&args, "-oClearAllForwardings=yes"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1) switch (ch) { /* User-visible flags. */ case '1': @@ -353,26 +404,37 @@ main(int argc, char **argv) case '6': case 'C': addargs(&args, "-%c", ch); + addargs(&remote_remote_args, "-%c", ch); + break; + case '3': + throughlocal = 1; break; case 'o': case 'c': case 'i': case 'F': + addargs(&remote_remote_args, "-%c", ch); + addargs(&remote_remote_args, "%s", optarg); addargs(&args, "-%c", ch); addargs(&args, "%s", optarg); break; case 'P': + addargs(&remote_remote_args, "-p"); + addargs(&remote_remote_args, "%s", optarg); addargs(&args, "-p"); addargs(&args, "%s", optarg); break; case 'B': - addargs(&args, "-oBatchmode yes"); + addargs(&remote_remote_args, "-oBatchmode=yes"); + addargs(&args, "-oBatchmode=yes"); break; case 'l': - speed = strtod(optarg, &endp); - if (speed <= 0 || *endp != '\0') + limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024, + &errstr); + if (errstr != NULL) usage(); - limit_rate = speed * 1024; + limit_kbps *= 1024; /* kbps */ + bandwidth_limit_init(&bwlimit, limit_kbps, COPY_BUFLEN); break; case 'p': pflag = 1; @@ -385,10 +447,12 @@ main(int argc, char **argv) break; case 'v': addargs(&args, "-v"); + addargs(&remote_remote_args, "-v"); verbose_mode = 1; break; case 'q': addargs(&args, "-q"); + addargs(&remote_remote_args, "-q"); showprogress = 0; break; @@ -474,41 +538,16 @@ main(int argc, char **argv) exit(errs != 0); } -/* - * atomicio-like wrapper that also applies bandwidth limits and updates - * the progressmeter counter. - */ -size_t -scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c) +/* Callback from atomicio6 to update progress meter and limit bandwidth */ +static int +scpio(void *_cnt, size_t s) { - u_char *p = (u_char *)_p; - size_t offset; - ssize_t r; - struct pollfd pfd; + off_t *cnt = (off_t *)_cnt; - pfd.fd = fd; - pfd.events = f == read ? POLLIN : POLLOUT; - for (offset = 0; offset < l;) { - r = f(fd, p + offset, l - offset); - if (r == 0) { - errno = EPIPE; - return offset; - } - if (r < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN || errno == EWOULDBLOCK) { - (void)poll(&pfd, 1, -1); /* Ignore errors */ - continue; - } - return offset; - } - offset += (size_t)r; - *c += (off_t)r; - if (limit_rate) - bwlimit(r); - } - return offset; + *cnt += s; + if (limit_kbps > 0) + bandwidth_limit(&bwlimit, s); + return 0; } void @@ -517,6 +556,7 @@ toremote(char *targ, int argc, char **argv) char *bp, *host, *src, *suser, *thost, *tuser, *arg; arglist alist; int i; + u_int j; memset(&alist, '\0', sizeof(alist)); alist.list = NULL; @@ -544,15 +584,45 @@ toremote(char *targ, int argc, char **argv) for (i = 0; i < argc - 1; i++) { src = colon(argv[i]); - if (src) { /* remote to remote */ + if (src && throughlocal) { /* extended remote to remote */ + *src++ = 0; + if (*src == 0) + src = "."; + host = strrchr(argv[i], '@'); + if (host) { + *host++ = 0; + host = cleanhostname(host); + suser = argv[i]; + if (*suser == '\0') + suser = pwd->pw_name; + else if (!okname(suser)) + continue; + } else { + host = cleanhostname(argv[i]); + suser = NULL; + } + xasprintf(&bp, "%s -f -- %s", cmd, src); + if (do_cmd(host, suser, bp, &remin, &remout) < 0) + exit(1); + (void) xfree(bp); + host = cleanhostname(thost); + xasprintf(&bp, "%s -t -- %s", cmd, targ); + if (do_cmd2(host, tuser, bp, remin, remout) < 0) + exit(1); + (void) xfree(bp); + (void) close(remin); + (void) close(remout); + remin = remout = -1; + } else if (src) { /* standard remote to remote */ freeargs(&alist); addargs(&alist, "%s", ssh_program); - if (verbose_mode) - addargs(&alist, "-v"); addargs(&alist, "-x"); - addargs(&alist, "-oClearAllForwardings yes"); + addargs(&alist, "-oClearAllForwardings=yes"); addargs(&alist, "-n"); - + for (j = 0; j < remote_remote_args.num; j++) { + addargs(&alist, "%s", + remote_remote_args.list[j]); + } *src++ = 0; if (*src == 0) src = "."; @@ -750,7 +820,7 @@ next: if (fd != -1) { (void)atomicio(vwrite, remout, bp->buf, amt); continue; } - if (scpio(vwrite, remout, bp->buf, amt, + if (atomicio6(vwrite, remout, bp->buf, amt, scpio, &statbytes) != amt) haderr = errno; } @@ -824,60 +894,6 @@ rsource(char *name, struct stat *statp) (void) response(); } -void -bwlimit(int amount) -{ - static struct timeval bwstart, bwend; - static int lamt, thresh = 16384; - u_int64_t waitlen; - struct timespec ts, rm; - - if (!timerisset(&bwstart)) { - gettimeofday(&bwstart, NULL); - return; - } - - lamt += amount; - if (lamt < thresh) - return; - - gettimeofday(&bwend, NULL); - timersub(&bwend, &bwstart, &bwend); - if (!timerisset(&bwend)) - return; - - lamt *= 8; - waitlen = (double)1000000L * lamt / limit_rate; - - bwstart.tv_sec = waitlen / 1000000L; - bwstart.tv_usec = waitlen % 1000000L; - - if (timercmp(&bwstart, &bwend, >)) { - timersub(&bwstart, &bwend, &bwend); - - /* Adjust the wait time */ - if (bwend.tv_sec) { - thresh /= 2; - if (thresh < 2048) - thresh = 2048; - } else if (bwend.tv_usec < 10000) { - thresh *= 2; - if (thresh > COPY_BUFLEN * 4) - thresh = COPY_BUFLEN * 4; - } - - TIMEVAL_TO_TIMESPEC(&bwend, &ts); - while (nanosleep(&ts, &rm) == -1) { - if (errno != EINTR) - break; - ts = rm; - } - } - - lamt = 0; - gettimeofday(&bwstart, NULL); -} - void sink(int argc, char **argv) { @@ -1071,7 +1087,8 @@ bad: run_err("%s: %s", np, strerror(errno)); amt = size - i; count += amt; do { - j = scpio(read, remin, cp, amt, &statbytes); + j = atomicio6(read, remin, cp, amt, + scpio, &statbytes); if (j == 0) { run_err("%s", j != EPIPE ? strerror(errno) : @@ -1197,7 +1214,7 @@ void usage(void) { (void) fprintf(stderr, - "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" + "usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" " [-l limit] [-o ssh_option] [-P port] [-S program]\n" " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); exit(1); diff --git a/servconf.c b/servconf.c index 986a5b92f692..e2f20a3d11d3 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.209 2010/06/22 04:22:59 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.213 2010/11/13 23:27:50 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -15,6 +15,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -109,6 +113,7 @@ initialize_server_options(ServerOptions *options) options->num_deny_groups = 0; options->ciphers = NULL; options->macs = NULL; + options->kex_algorithms = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->gateway_ports = -1; options->num_subsystems = 0; @@ -132,6 +137,8 @@ initialize_server_options(ServerOptions *options) options->revoked_keys_file = NULL; options->trusted_user_ca_keys = NULL; options->authorized_principals_file = NULL; + options->ip_qos_interactive = -1; + options->ip_qos_bulk = -1; } void @@ -154,6 +161,10 @@ fill_default_server_options(ServerOptions *options) _PATH_HOST_RSA_KEY_FILE; options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE; +#ifdef OPENSSL_HAS_ECC + options->host_key_files[options->num_host_key_files++] = + _PATH_HOST_ECDSA_KEY_FILE; +#endif } } /* No certificates by default */ @@ -256,16 +267,20 @@ fill_default_server_options(ServerOptions *options) if (options->authorized_keys_file2 == NULL) { /* authorized_keys_file2 falls back to authorized_keys_file */ if (options->authorized_keys_file != NULL) - options->authorized_keys_file2 = options->authorized_keys_file; + options->authorized_keys_file2 = xstrdup(options->authorized_keys_file); else - options->authorized_keys_file2 = _PATH_SSH_USER_PERMITTED_KEYS2; + options->authorized_keys_file2 = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); } if (options->authorized_keys_file == NULL) - options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; if (options->zero_knowledge_password_authentication == -1) options->zero_knowledge_password_authentication = 0; + if (options->ip_qos_interactive == -1) + options->ip_qos_interactive = IPTOS_LOWDELAY; + if (options->ip_qos_bulk == -1) + options->ip_qos_bulk = IPTOS_THROUGHPUT; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -312,6 +327,7 @@ typedef enum { sUsePrivilegeSeparation, sAllowAgentForwarding, sZeroKnowledgePasswordAuthentication, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, + sKexAlgorithms, sIPQoS, sDeprecated, sUnsupported } ServerOpCodes; @@ -434,6 +450,8 @@ static struct { { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -663,7 +681,7 @@ process_server_config_line(ServerOptions *options, char *line, const char *host, const char *address) { char *cp, **charptr, *arg, *p; - int cmdline = 0, *intptr, value, n; + int cmdline = 0, *intptr, value, value2, n; SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; ServerOpCodes opcode; @@ -1129,6 +1147,18 @@ process_server_config_line(ServerOptions *options, char *line, options->macs = xstrdup(arg); break; + case sKexAlgorithms: + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing argument.", + filename, linenum); + if (!kex_names_valid(arg)) + fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.", + filename, linenum, arg ? arg : ""); + if (options->kex_algorithms == NULL) + options->kex_algorithms = xstrdup(arg); + break; + case sProtocol: intptr = &options->protocol; arg = strdelim(&cp); @@ -1351,6 +1381,23 @@ process_server_config_line(ServerOptions *options, char *line, charptr = &options->revoked_keys_file; goto parse_filename; + case sIPQoS: + arg = strdelim(&cp); + if ((value = parse_ipqos(arg)) == -1) + fatal("%s line %d: Bad IPQoS value: %s", + filename, linenum, arg); + arg = strdelim(&cp); + if (arg == NULL) + value2 = value; + else if ((value2 = parse_ipqos(arg)) == -1) + fatal("%s line %d: Bad IPQoS value: %s", + filename, linenum, arg); + if (*activep) { + options->ip_qos_interactive = value; + options->ip_qos_bulk = value2; + } + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); @@ -1461,6 +1508,8 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(x11_use_localhost); M_CP_INTOPT(max_sessions); M_CP_INTOPT(max_authtries); + M_CP_INTOPT(ip_qos_interactive); + M_CP_INTOPT(ip_qos_bulk); M_CP_STROPT(banner); if (preauth) @@ -1726,5 +1775,7 @@ dump_config(ServerOptions *o) } dump_cfg_string(sPermitTunnel, s); + printf("ipqos 0x%02x 0x%02x\n", o->ip_qos_interactive, o->ip_qos_bulk); + channel_print_adm_permitted_opens(); } diff --git a/servconf.h b/servconf.h index 45d2a2ae3552..5a058a416443 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.93 2010/05/07 11:30:30 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.95 2010/11/13 23:27:50 djm Exp $ */ /* * Author: Tatu Ylonen @@ -70,8 +70,11 @@ typedef struct { char *xauth_location; /* Location of xauth program */ int strict_modes; /* If true, require string home dir modes. */ int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */ + int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */ + int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ char *ciphers; /* Supported SSH2 ciphers. */ char *macs; /* Supported SSH2 macs. */ + char *kex_algorithms; /* SSH2 kex methods in order of preference. */ int protocol; /* Supported protocol versions. */ int gateway_ports; /* If true, allow remote connects to forwarded ports. */ SyslogFacility log_facility; /* Facility for system logging. */ diff --git a/session.c b/session.c index 71e4fbe7cfc8..fff31b02e624 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.256 2010/06/25 07:20:04 djm Exp $ */ +/* $OpenBSD: session.c,v 1.258 2010/11/25 04:10:09 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -585,7 +585,8 @@ do_exec_no_pty(Session *s, const char *command) s->pid = pid; /* Set interactive/non-interactive mode. */ - packet_set_interactive(s->display != NULL); + packet_set_interactive(s->display != NULL, + options.ip_qos_interactive, options.ip_qos_bulk); /* * Clear loginmsg, since it's the child's responsibility to display @@ -739,7 +740,8 @@ do_exec_pty(Session *s, const char *command) /* Enter interactive session. */ s->ptymaster = ptymaster; - packet_set_interactive(1); + packet_set_interactive(1, + options.ip_qos_interactive, options.ip_qos_bulk); if (compat20) { session_set_fds(s, ptyfd, fdout, -1, 1, 1); } else { @@ -1469,36 +1471,16 @@ do_setusercontext(struct passwd *pw) { char *chroot_path, *tmp; -#ifdef WITH_SELINUX - /* Cache selinux status for later use */ - (void)ssh_selinux_enabled(); -#endif + platform_setusercontext(pw); -#ifndef HAVE_CYGWIN - if (getuid() == 0 || geteuid() == 0) -#endif /* HAVE_CYGWIN */ - { + if (platform_privileged_uidswap()) { #ifdef HAVE_LOGIN_CAP -# ifdef __bsdi__ - setpgid(0, 0); -# endif -# ifdef USE_PAM - if (options.use_pam) { - do_pam_setcred(use_privsep); - } -# endif /* USE_PAM */ if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { perror("unable to set user context"); exit(1); } #else -# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID) - /* Sets login uid for accounting */ - if (getluid() == -1 && setluid(pw->pw_uid) == -1) - error("setluid: %s", strerror(errno)); -# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */ - if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) { @@ -1511,50 +1493,9 @@ do_setusercontext(struct passwd *pw) exit(1); } endgrent(); -# ifdef USE_PAM - /* - * PAM credentials may take the form of supplementary groups. - * These will have been wiped by the above initgroups() call. - * Reestablish them here. - */ - if (options.use_pam) { - do_pam_setcred(use_privsep); - } -# endif /* USE_PAM */ -# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) - irix_setusercontext(pw); -# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ -# ifdef _AIX - aix_usrinfo(pw); -# endif /* _AIX */ -# ifdef USE_LIBIAF - if (set_id(pw->pw_name) != 0) { - exit(1); - } -# endif /* USE_LIBIAF */ #endif -#ifdef HAVE_SETPCRED - /* - * If we have a chroot directory, we set all creds except real - * uid which we will need for chroot. If we don't have a - * chroot directory, we don't override anything. - */ - { - char **creds = NULL, *chroot_creds[] = - { "REAL_USER=root", NULL }; - if (options.chroot_directory != NULL && - strcasecmp(options.chroot_directory, "none") != 0) - creds = chroot_creds; - - if (setpcred(pw->pw_name, creds) == -1) - fatal("Failed to set process credentials"); - } -#endif /* HAVE_SETPCRED */ - -#ifdef WITH_SELINUX - ssh_selinux_setup_exec_context(pw->pw_name); -#endif + platform_setusercontext_post_groups(pw); if (options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { @@ -1628,8 +1569,6 @@ launch_login(struct passwd *pw, const char *hostname) static void child_close_fds(void) { - int i; - if (packet_get_connection_in() == packet_get_connection_out()) close(packet_get_connection_in()); else { @@ -1655,8 +1594,7 @@ child_close_fds(void) * initgroups, because at least on Solaris 2.3 it leaves file * descriptors open. */ - for (i = 3; i < 64; i++) - close(i); + closefrom(STDERR_FILENO + 1); } /* diff --git a/sftp-client.c b/sftp-client.c index 9dab477806aa..caa384b4e702 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.92 2010/07/19 03:16:33 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.94 2010/12/04 00:18:01 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -75,15 +75,28 @@ struct sftp_conn { #define SFTP_EXT_POSIX_RENAME 0x00000001 #define SFTP_EXT_STATVFS 0x00000002 #define SFTP_EXT_FSTATVFS 0x00000004 +#define SFTP_EXT_HARDLINK 0x00000008 u_int exts; + u_int64_t limit_kbps; + struct bwlimit bwlimit_in, bwlimit_out; }; static char * -get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) - __attribute__((format(printf, 4, 5))); +get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len, + const char *errfmt, ...) __attribute__((format(printf, 4, 5))); + +/* ARGSUSED */ +static int +sftpio(void *_bwlimit, size_t amount) +{ + struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit; + + bandwidth_limit(bwlimit, amount); + return 0; +} static void -send_msg(int fd, Buffer *m) +send_msg(struct sftp_conn *conn, Buffer *m) { u_char mlen[4]; struct iovec iov[2]; @@ -98,19 +111,22 @@ send_msg(int fd, Buffer *m) iov[1].iov_base = buffer_ptr(m); iov[1].iov_len = buffer_len(m); - if (atomiciov(writev, fd, iov, 2) != buffer_len(m) + sizeof(mlen)) + if (atomiciov6(writev, conn->fd_out, iov, 2, + conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) != + buffer_len(m) + sizeof(mlen)) fatal("Couldn't send packet: %s", strerror(errno)); buffer_clear(m); } static void -get_msg(int fd, Buffer *m) +get_msg(struct sftp_conn *conn, Buffer *m) { u_int msg_len; buffer_append_space(m, 4); - if (atomicio(read, fd, buffer_ptr(m), 4) != 4) { + if (atomicio6(read, conn->fd_in, buffer_ptr(m), 4, + conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) { if (errno == EPIPE) fatal("Connection closed"); else @@ -122,7 +138,9 @@ get_msg(int fd, Buffer *m) fatal("Received message too long %u", msg_len); buffer_append_space(m, msg_len); - if (atomicio(read, fd, buffer_ptr(m), msg_len) != msg_len) { + if (atomicio6(read, conn->fd_in, buffer_ptr(m), msg_len, + conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) + != msg_len) { if (errno == EPIPE) fatal("Connection closed"); else @@ -131,7 +149,7 @@ get_msg(int fd, Buffer *m) } static void -send_string_request(int fd, u_int id, u_int code, char *s, +send_string_request(struct sftp_conn *conn, u_int id, u_int code, char *s, u_int len) { Buffer msg; @@ -140,14 +158,14 @@ send_string_request(int fd, u_int id, u_int code, char *s, buffer_put_char(&msg, code); buffer_put_int(&msg, id); buffer_put_string(&msg, s, len); - send_msg(fd, &msg); - debug3("Sent message fd %d T:%u I:%u", fd, code, id); + send_msg(conn, &msg); + debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); buffer_free(&msg); } static void -send_string_attrs_request(int fd, u_int id, u_int code, char *s, - u_int len, Attrib *a) +send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code, + char *s, u_int len, Attrib *a) { Buffer msg; @@ -156,19 +174,19 @@ send_string_attrs_request(int fd, u_int id, u_int code, char *s, buffer_put_int(&msg, id); buffer_put_string(&msg, s, len); encode_attrib(&msg, a); - send_msg(fd, &msg); - debug3("Sent message fd %d T:%u I:%u", fd, code, id); + send_msg(conn, &msg); + debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id); buffer_free(&msg); } static u_int -get_status(int fd, u_int expected_id) +get_status(struct sftp_conn *conn, u_int expected_id) { Buffer msg; u_int type, id, status; buffer_init(&msg); - get_msg(fd, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -183,11 +201,12 @@ get_status(int fd, u_int expected_id) debug3("SSH2_FXP_STATUS %u", status); - return(status); + return status; } static char * -get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) +get_handle(struct sftp_conn *conn, u_int expected_id, u_int *len, + const char *errfmt, ...) { Buffer msg; u_int type, id; @@ -201,7 +220,7 @@ get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) va_end(args); buffer_init(&msg); - get_msg(fd, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -225,14 +244,14 @@ get_handle(int fd, u_int expected_id, u_int *len, const char *errfmt, ...) } static Attrib * -get_decode_stat(int fd, u_int expected_id, int quiet) +get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet) { Buffer msg; u_int type, id; Attrib *a; buffer_init(&msg); - get_msg(fd, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -260,14 +279,14 @@ get_decode_stat(int fd, u_int expected_id, int quiet) } static int -get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id, - int quiet) +get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st, + u_int expected_id, int quiet) { Buffer msg; u_int type, id, flag; buffer_init(&msg); - get_msg(fd, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -311,21 +330,29 @@ get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id, } struct sftp_conn * -do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) +do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, + u_int64_t limit_kbps) { - u_int type, exts = 0; - int version; + u_int type; Buffer msg; struct sftp_conn *ret; + ret = xmalloc(sizeof(*ret)); + ret->fd_in = fd_in; + ret->fd_out = fd_out; + ret->transfer_buflen = transfer_buflen; + ret->num_requests = num_requests; + ret->exts = 0; + ret->limit_kbps = 0; + buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_INIT); buffer_put_int(&msg, SSH2_FILEXFER_VERSION); - send_msg(fd_out, &msg); + send_msg(ret, &msg); buffer_clear(&msg); - get_msg(fd_in, &msg); + get_msg(ret, &msg); /* Expecting a VERSION reply */ if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { @@ -334,9 +361,9 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) buffer_free(&msg); return(NULL); } - version = buffer_get_int(&msg); + ret->version = buffer_get_int(&msg); - debug2("Remote version: %d", version); + debug2("Remote version: %u", ret->version); /* Check for extensions */ while (buffer_len(&msg) > 0) { @@ -346,15 +373,19 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) if (strcmp(name, "posix-rename@openssh.com") == 0 && strcmp(value, "1") == 0) { - exts |= SFTP_EXT_POSIX_RENAME; + ret->exts |= SFTP_EXT_POSIX_RENAME; known = 1; } else if (strcmp(name, "statvfs@openssh.com") == 0 && strcmp(value, "2") == 0) { - exts |= SFTP_EXT_STATVFS; + ret->exts |= SFTP_EXT_STATVFS; known = 1; - } if (strcmp(name, "fstatvfs@openssh.com") == 0 && + } else if (strcmp(name, "fstatvfs@openssh.com") == 0 && strcmp(value, "2") == 0) { - exts |= SFTP_EXT_FSTATVFS; + ret->exts |= SFTP_EXT_FSTATVFS; + known = 1; + } else if (strcmp(name, "hardlink@openssh.com") == 0 && + strcmp(value, "1") == 0) { + ret->exts |= SFTP_EXT_HARDLINK; known = 1; } if (known) { @@ -369,26 +400,25 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) buffer_free(&msg); - ret = xmalloc(sizeof(*ret)); - ret->fd_in = fd_in; - ret->fd_out = fd_out; - ret->transfer_buflen = transfer_buflen; - ret->num_requests = num_requests; - ret->version = version; - ret->msg_id = 1; - ret->exts = exts; - /* Some filexfer v.0 servers don't support large packets */ - if (version == 0) + if (ret->version == 0) ret->transfer_buflen = MIN(ret->transfer_buflen, 20480); - return(ret); + ret->limit_kbps = limit_kbps; + if (ret->limit_kbps > 0) { + bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps, + ret->transfer_buflen); + bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps, + ret->transfer_buflen); + } + + return ret; } u_int sftp_proto_version(struct sftp_conn *conn) { - return(conn->version); + return conn->version; } int @@ -403,16 +433,16 @@ do_close(struct sftp_conn *conn, char *handle, u_int handle_len) buffer_put_char(&msg, SSH2_FXP_CLOSE); buffer_put_int(&msg, id); buffer_put_string(&msg, handle, handle_len); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); debug3("Sent message SSH2_FXP_CLOSE I:%u", id); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't close file: %s", fx2txt(status)); buffer_free(&msg); - return(status); + return status; } @@ -430,14 +460,14 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, buffer_put_char(&msg, SSH2_FXP_OPENDIR); buffer_put_int(&msg, id); buffer_put_cstring(&msg, path); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); buffer_clear(&msg); - handle = get_handle(conn->fd_in, id, &handle_len, + handle = get_handle(conn, id, &handle_len, "remote readdir(\"%s\")", path); if (handle == NULL) - return(-1); + return -1; if (dir) { ents = 0; @@ -454,11 +484,11 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, buffer_put_char(&msg, SSH2_FXP_READDIR); buffer_put_int(&msg, id); buffer_put_string(&msg, handle, handle_len); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); buffer_clear(&msg); - get_msg(conn->fd_in, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -537,7 +567,7 @@ do_lsreaddir(struct sftp_conn *conn, char *path, int printflag, **dir = NULL; } - return(0); + return 0; } int @@ -566,9 +596,8 @@ do_rm(struct sftp_conn *conn, char *path) debug2("Sending SSH2_FXP_REMOVE \"%s\"", path); id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path, - strlen(path)); - status = get_status(conn->fd_in, id); + send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path)); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't delete file: %s", fx2txt(status)); return(status); @@ -580,10 +609,10 @@ do_mkdir(struct sftp_conn *conn, char *path, Attrib *a, int printflag) u_int status, id; id = conn->msg_id++; - send_string_attrs_request(conn->fd_out, id, SSH2_FXP_MKDIR, path, + send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path, strlen(path), a); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK && printflag) error("Couldn't create directory: %s", fx2txt(status)); @@ -596,10 +625,10 @@ do_rmdir(struct sftp_conn *conn, char *path) u_int status, id; id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_RMDIR, path, + send_string_request(conn, id, SSH2_FXP_RMDIR, path, strlen(path)); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't remove directory: %s", fx2txt(status)); @@ -613,11 +642,11 @@ do_stat(struct sftp_conn *conn, char *path, int quiet) id = conn->msg_id++; - send_string_request(conn->fd_out, id, + send_string_request(conn, id, conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, path, strlen(path)); - return(get_decode_stat(conn->fd_in, id, quiet)); + return(get_decode_stat(conn, id, quiet)); } Attrib * @@ -634,10 +663,10 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) } id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_LSTAT, path, + send_string_request(conn, id, SSH2_FXP_LSTAT, path, strlen(path)); - return(get_decode_stat(conn->fd_in, id, quiet)); + return(get_decode_stat(conn, id, quiet)); } #ifdef notyet @@ -647,10 +676,10 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) u_int id; id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_FSTAT, handle, + send_string_request(conn, id, SSH2_FXP_FSTAT, handle, handle_len); - return(get_decode_stat(conn->fd_in, id, quiet)); + return(get_decode_stat(conn, id, quiet)); } #endif @@ -660,10 +689,10 @@ do_setstat(struct sftp_conn *conn, char *path, Attrib *a) u_int status, id; id = conn->msg_id++; - send_string_attrs_request(conn->fd_out, id, SSH2_FXP_SETSTAT, path, + send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path, strlen(path), a); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't setstat on \"%s\": %s", path, fx2txt(status)); @@ -678,10 +707,10 @@ do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len, u_int status, id; id = conn->msg_id++; - send_string_attrs_request(conn->fd_out, id, SSH2_FXP_FSETSTAT, handle, + send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle, handle_len, a); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't fsetstat: %s", fx2txt(status)); @@ -697,12 +726,12 @@ do_realpath(struct sftp_conn *conn, char *path) Attrib *a; expected_id = id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path, + send_string_request(conn, id, SSH2_FXP_REALPATH, path, strlen(path)); buffer_init(&msg); - get_msg(conn->fd_in, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -756,13 +785,13 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) } buffer_put_cstring(&msg, oldpath); buffer_put_cstring(&msg, newpath); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); debug3("Sent message %s \"%s\" -> \"%s\"", (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" : "SSH2_FXP_RENAME", oldpath, newpath); buffer_free(&msg); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); @@ -770,6 +799,39 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) return(status); } +int +do_hardlink(struct sftp_conn *conn, char *oldpath, char *newpath) +{ + Buffer msg; + u_int status, id; + + buffer_init(&msg); + + /* Send link request */ + id = conn->msg_id++; + if ((conn->exts & SFTP_EXT_HARDLINK) == 0) { + error("Server does not support hardlink@openssh.com extension"); + return -1; + } + + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "hardlink@openssh.com"); + buffer_put_cstring(&msg, oldpath); + buffer_put_cstring(&msg, newpath); + send_msg(conn, &msg); + debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"", + oldpath, newpath); + buffer_free(&msg); + + status = get_status(conn, id); + if (status != SSH2_FX_OK) + error("Couldn't link file \"%s\" to \"%s\": %s", oldpath, + newpath, fx2txt(status)); + + return(status); +} + int do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) { @@ -789,12 +851,12 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) buffer_put_int(&msg, id); buffer_put_cstring(&msg, oldpath); buffer_put_cstring(&msg, newpath); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath, newpath); buffer_free(&msg); - status = get_status(conn->fd_in, id); + status = get_status(conn, id); if (status != SSH2_FX_OK) error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, newpath, fx2txt(status)); @@ -812,12 +874,11 @@ do_readlink(struct sftp_conn *conn, char *path) Attrib *a; expected_id = id = conn->msg_id++; - send_string_request(conn->fd_out, id, SSH2_FXP_READLINK, path, - strlen(path)); + send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path)); buffer_init(&msg); - get_msg(conn->fd_in, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); @@ -871,10 +932,10 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, buffer_put_int(&msg, id); buffer_put_cstring(&msg, "statvfs@openssh.com"); buffer_put_cstring(&msg, path); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); buffer_free(&msg); - return get_decode_statvfs(conn->fd_in, st, id, quiet); + return get_decode_statvfs(conn, st, id, quiet); } #ifdef notyet @@ -898,16 +959,16 @@ do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, buffer_put_int(&msg, id); buffer_put_cstring(&msg, "fstatvfs@openssh.com"); buffer_put_string(&msg, handle, handle_len); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); buffer_free(&msg); - return get_decode_statvfs(conn->fd_in, st, id, quiet); + return get_decode_statvfs(conn, st, id, quiet); } #endif static void -send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, - char *handle, u_int handle_len) +send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, + u_int len, char *handle, u_int handle_len) { Buffer msg; @@ -918,7 +979,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, buffer_put_string(&msg, handle, handle_len); buffer_put_int64(&msg, offset); buffer_put_int(&msg, len); - send_msg(fd_out, &msg); + send_msg(conn, &msg); buffer_free(&msg); } @@ -976,10 +1037,10 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, buffer_put_int(&msg, SSH2_FXF_READ); attrib_clear(&junk); /* Send empty attributes */ encode_attrib(&msg, &junk); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); - handle = get_handle(conn->fd_in, id, &handle_len, + handle = get_handle(conn, id, &handle_len, "remote open(\"%s\")", remote_path); if (handle == NULL) { buffer_free(&msg); @@ -1032,12 +1093,12 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, offset += buflen; num_req++; TAILQ_INSERT_TAIL(&requests, req, tq); - send_read_request(conn->fd_out, req->id, req->offset, + send_read_request(conn, req->id, req->offset, req->len, handle, handle_len); } buffer_clear(&msg); - get_msg(conn->fd_in, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); id = buffer_get_int(&msg); debug3("Received reply T:%u I:%u R:%d", type, id, max_req); @@ -1092,7 +1153,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, req->id = conn->msg_id++; req->len -= len; req->offset += len; - send_read_request(conn->fd_out, req->id, + send_read_request(conn, req->id, req->offset, req->len, handle, handle_len); /* Reduce the request size */ if (len < buflen) @@ -1327,12 +1388,12 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, buffer_put_cstring(&msg, remote_path); buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); encode_attrib(&msg, &a); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); buffer_clear(&msg); - handle = get_handle(conn->fd_in, id, &handle_len, + handle = get_handle(conn, id, &handle_len, "remote open(\"%s\")", remote_path); if (handle == NULL) { close(local_fd); @@ -1381,7 +1442,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, buffer_put_string(&msg, handle, handle_len); buffer_put_int64(&msg, offset); buffer_put_string(&msg, data, len); - send_msg(conn->fd_out, &msg); + send_msg(conn, &msg); debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", id, (unsigned long long)offset, len); } else if (TAILQ_FIRST(&acks) == NULL) @@ -1395,7 +1456,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, u_int r_id; buffer_clear(&msg); - get_msg(conn->fd_in, &msg); + get_msg(conn, &msg); type = buffer_get_char(&msg); r_id = buffer_get_int(&msg); diff --git a/sftp-client.h b/sftp-client.h index 1d08c40493b8..aef54ef49dd0 100644 --- a/sftp-client.h +++ b/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.18 2009/08/18 18:36:20 djm Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.20 2010/12/04 00:18:01 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller @@ -51,7 +51,7 @@ struct sftp_statvfs { * Initialise a SSH filexfer connection. Returns NULL on error or * a pointer to a initialized sftp_conn struct on success. */ -struct sftp_conn *do_init(int, int, u_int, u_int); +struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t); u_int sftp_proto_version(struct sftp_conn *); @@ -94,6 +94,9 @@ int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); /* Rename 'oldpath' to 'newpath' */ int do_rename(struct sftp_conn *, char *, char *); +/* Link 'oldpath' to 'newpath' */ +int do_hardlink(struct sftp_conn *, char *, char *); + /* Rename 'oldpath' to 'newpath' */ int do_symlink(struct sftp_conn *, char *, char *); diff --git a/sftp-server.0 b/sftp-server.0 index 05b9ddc9c589..d8d91c5d546a 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -51,7 +51,7 @@ DESCRIPTION SEE ALSO sftp(1), ssh(1), sshd_config(5), sshd(8) - T. Ylonen, S. Lehtinen, SSH File Transfer Protocol, + T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-filexfer-00.txt, January 2001, work in progress material. diff --git a/sftp-server.c b/sftp-server.c index a98ac2b6dd28..b268d08835f5 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.91 2010/01/13 01:40:16 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.93 2010/12/04 00:18:01 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -535,6 +535,9 @@ process_init(void) /* fstatvfs extension */ buffer_put_cstring(&msg, "fstatvfs@openssh.com"); buffer_put_cstring(&msg, "2"); /* version */ + /* hardlink extension */ + buffer_put_cstring(&msg, "hardlink@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ send_msg(&msg); buffer_free(&msg); } @@ -1222,6 +1225,27 @@ process_extended_fstatvfs(u_int32_t id) send_statvfs(id, &st); } +static void +process_extended_hardlink(u_int32_t id) +{ + char *oldpath, *newpath; + int ret, status; + + oldpath = get_string(NULL); + newpath = get_string(NULL); + debug3("request %u: hardlink", id); + logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath); + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = link(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); + xfree(oldpath); + xfree(newpath); +} + static void process_extended(void) { @@ -1236,6 +1260,8 @@ process_extended(void) process_extended_statvfs(id); else if (strcmp(request, "fstatvfs@openssh.com") == 0) process_extended_fstatvfs(id); + else if (strcmp(request, "hardlink@openssh.com") == 0) + process_extended_hardlink(id); else send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); @@ -1377,8 +1403,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, buf[4*4096]; - const char *errmsg; - mode_t mask; + long mask; extern char *optarg; extern char *__progname; @@ -1412,11 +1437,12 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) error("Invalid log facility \"%s\"", optarg); break; case 'u': - mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); - if (errmsg != NULL) - fatal("Invalid umask \"%s\": %s", - optarg, errmsg); - (void)umask(mask); + errno = 0; + mask = strtol(optarg, &cp, 8); + if (mask < 0 || mask > 0777 || *cp != '\0' || + cp == optarg || (mask == 0 && errno != 0)) + fatal("Invalid umask \"%s\"", optarg); + (void)umask((mode_t)mask); break; case 'h': default: diff --git a/sftp.0 b/sftp.0 index 40de1a0cd990..6ceed93ab2a8 100644 --- a/sftp.0 +++ b/sftp.0 @@ -5,7 +5,7 @@ NAME SYNOPSIS sftp [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher] - [-D sftp_server_path] [-F ssh_config] [-i identity_file] + [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] @@ -50,9 +50,9 @@ DESCRIPTION batchfile of `-' may be used to indicate standard input. sftp will abort if any of the following commands fail: get, put, rename, ln, rm, mkdir, chdir, ls, lchdir, chmod, chown, chgrp, - lpwd, df, and lmkdir. Termination on error can be suppressed on - a command by command basis by prefixing the command with a `-' - character (for example, -rm /tmp/blah*). + lpwd, df, symlink, and lmkdir. Termination on error can be + suppressed on a command by command basis by prefixing the command + with a `-' character (for example, -rm /tmp/blah*). -C Enables compression (via ssh's -C flag). @@ -73,6 +73,9 @@ DESCRIPTION key authentication is read. This option is directly passed to ssh(1). + -l limit + Limits the used bandwidth, specified in Kbit/s. + -o ssh_option Can be used to pass options to ssh in the format used in ssh_config(5). This is useful for specifying options for which @@ -105,7 +108,9 @@ DESCRIPTION HostName IdentityFile IdentitiesOnly + IPQoS KbdInteractiveDevices + KexAlgorithms LogLevel MACs NoHostAuthenticationForLocalhost @@ -225,8 +230,10 @@ INTERACTIVE COMMANDS lmkdir path Create local directory specified by path. - ln oldpath newpath - Create a symbolic link from oldpath to newpath. + ln [-s] oldpath newpath + Create a link from oldpath to newpath. If the -s flag is + specified the created link is a symbolic link, otherwise it is a + hard link. lpwd Print local working directory. @@ -317,8 +324,8 @@ SEE ALSO ftp(1), ls(1), scp(1), ssh(1), ssh-add(1), ssh-keygen(1), glob(3), ssh_config(5), sftp-server(8), sshd(8) - T. Ylonen, S. Lehtinen, SSH File Transfer Protocol, + T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh-filexfer-00.txt, January 2001, work in progress material. -OpenBSD 4.8 February 8, 2010 OpenBSD 4.8 +OpenBSD 4.8 December 4, 2010 OpenBSD 4.8 diff --git a/sftp.1 b/sftp.1 index 777b02a58424..89b5d3544dd7 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.83 2010/02/08 10:50:20 markus Exp $ +.\" $OpenBSD: sftp.1,v 1.88 2010/12/04 00:18:01 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: February 8 2010 $ +.Dd $Mdocdate: December 4 2010 $ .Dt SFTP 1 .Os .Sh NAME @@ -38,6 +38,7 @@ .Op Fl D Ar sftp_server_path .Op Fl F Ar ssh_config .Op Fl i Ar identity_file +.Op Fl l Ar limit .Op Fl o Ar ssh_option .Op Fl P Ar port .Op Fl R Ar num_requests @@ -49,9 +50,11 @@ .Oo Ar user Ns @ Oc Ns .Ar host Ns Op : Ns Ar .Nm sftp -.Oo Ar user Ns @ Oc Ns +.Oo +.Ar user Ns @ Oc Ns .Ar host Ns Oo : Ns Ar dir Ns -.Op Ar / Oc +.Op Ar / +.Oc .Nm sftp .Fl b Ar batchfile .Oo Ar user Ns @ Oc Ns Ar host @@ -125,7 +128,7 @@ commands fail: .Ic get , put , rename , ln , .Ic rm , mkdir , chdir , ls , .Ic lchdir , chmod , chown , -.Ic chgrp , lpwd , df , +.Ic chgrp , lpwd , df , symlink , and .Ic lmkdir . Termination on error can be suppressed on a command by command basis by @@ -157,6 +160,8 @@ Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to .Xr ssh 1 . +.It Fl l Ar limit +Limits the used bandwidth, specified in Kbit/s. .It Fl o Ar ssh_option Can be used to pass options to .Nm ssh @@ -196,7 +201,9 @@ For full details of the options listed below, and their possible values, see .It HostName .It IdentityFile .It IdentitiesOnly +.It IPQoS .It KbdInteractiveDevices +.It KexAlgorithms .It LogLevel .It MACs .It NoHostAuthenticationForLocalhost @@ -385,11 +392,19 @@ characters and may match multiple files. .It Ic lmkdir Ar path Create local directory specified by .Ar path . -.It Ic ln Ar oldpath Ar newpath -Create a symbolic link from +.It Xo Ic ln +.Op Fl s +.Ar oldpath +.Ar newpath +.Xc +Create a link from .Ar oldpath to .Ar newpath . +If the +.Fl s +flag is specified the created link is a symbolic link, otherwise it is +a hard link. .It Ic lpwd Print local working directory. .It Xo Ic ls diff --git a/sftp.c b/sftp.c index 229f12987e50..ab667f5a55e0 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.125 2010/06/18 00:58:39 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.132 2010/12/04 00:18:01 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -132,6 +132,7 @@ extern char *__progname; #define I_GET 5 #define I_HELP 6 #define I_LCHDIR 7 +#define I_LINK 25 #define I_LLS 8 #define I_LMKDIR 9 #define I_LPWD 10 @@ -176,7 +177,7 @@ static const struct CMD cmds[] = { { "lchdir", I_LCHDIR, LOCAL }, { "lls", I_LLS, LOCAL }, { "lmkdir", I_LMKDIR, LOCAL }, - { "ln", I_SYMLINK, REMOTE }, + { "ln", I_LINK, REMOTE }, { "lpwd", I_LPWD, LOCAL }, { "ls", I_LS, REMOTE }, { "lumask", I_LUMASK, NOARGS }, @@ -240,7 +241,7 @@ help(void) "lcd path Change local directory to 'path'\n" "lls [ls-options [path]] Display local directory listing\n" "lmkdir path Create local directory\n" - "ln oldpath newpath Symlink remote file\n" + "ln [-s] oldpath newpath Link remote file (-s for symlink)\n" "lpwd Print local working directory\n" "ls [-1afhlnrSt] [path] Display remote directory listing\n" "lumask umask Set local umask to 'umask'\n" @@ -269,7 +270,7 @@ local_do_shell(const char *args) if (!*args) args = NULL; - if ((shell = getenv("SHELL")) == NULL) + if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; if ((pid = fork()) == -1) @@ -376,6 +377,30 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag, return optind; } +static int +parse_link_flags(const char *cmd, char **argv, int argc, int *sflag) +{ + extern int opterr, optind, optopt, optreset; + int ch; + + optind = optreset = 1; + opterr = 0; + + *sflag = 0; + while ((ch = getopt(argc, argv, "s")) != -1) { + switch (ch) { + case 's': + *sflag = 1; + break; + default: + error("%s: Invalid flag -%c", cmd, optopt); + return -1; + } + } + + return optind; +} + static int parse_ls_flags(char **argv, int argc, int *lflag) { @@ -758,18 +783,22 @@ static int do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { - glob_t g; - u_int i, c = 1, colspace = 0, columns = 1; Attrib *a = NULL; + char *fname, *lname; + glob_t g; + int err; + struct winsize ws; + u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80; memset(&g, 0, sizeof(g)); - if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE, - NULL, &g) || (g.gl_pathc && !g.gl_matchc)) { + if (remote_glob(conn, path, + GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT, NULL, &g) || + (g.gl_pathc && !g.gl_matchc)) { if (g.gl_pathc) globfree(&g); error("Can't ls: \"%s\" not found", path); - return (-1); + return -1; } if (interrupted) @@ -779,59 +808,35 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, * If the glob returns a single match and it is a directory, * then just list its contents. */ - if (g.gl_matchc == 1) { - if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) { - globfree(&g); - return (-1); - } - if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && - S_ISDIR(a->perm)) { - int err; - - err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); - globfree(&g); - return (err); - } + if (g.gl_matchc == 1 && g.gl_statv[0] != NULL && + S_ISDIR(g.gl_statv[0]->st_mode)) { + err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); + globfree(&g); + return err; } - if (!(lflag & LS_SHORT_VIEW)) { - u_int m = 0, width = 80; - struct winsize ws; + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) + width = ws.ws_col; + if (!(lflag & LS_SHORT_VIEW)) { /* Count entries for sort and find longest filename */ for (i = 0; g.gl_pathv[i]; i++) m = MAX(m, strlen(g.gl_pathv[i])); - if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) - width = ws.ws_col; - columns = width / (m + 2); columns = MAX(columns, 1); colspace = width / columns; } for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) { - char *fname; - fname = path_strip(g.gl_pathv[i], strip_path); - if (lflag & LS_LONG_VIEW) { - char *lname; - struct stat sb; - - /* - * XXX: this is slow - 1 roundtrip per path - * A solution to this is to fork glob() and - * build a sftp specific version which keeps the - * attribs (which currently get thrown away) - * that the server returns as well as the filenames. - */ - memset(&sb, 0, sizeof(sb)); - if (a == NULL) - a = do_lstat(conn, g.gl_pathv[i], 1); - if (a != NULL) - attrib_to_stat(a, &sb); - lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS)); + if (g.gl_statv[i] == NULL) { + error("no stat information for %s", fname); + continue; + } + lname = ls_file(fname, g.gl_statv[i], 1, + (lflag & LS_SI_UNITS)); printf("%s\n", lname); xfree(lname); } else { @@ -852,7 +857,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, if (g.gl_pathc) globfree(&g); - return (0); + return 0; } static int @@ -1108,7 +1113,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote, static int parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, - int *hflag, unsigned long *n_arg, char **path1, char **path2) + int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; char *cp2, **argv; @@ -1158,7 +1163,8 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, switch (cmdnum) { case I_GET: case I_PUT: - if ((optidx = parse_getput_flags(cmd, argv, argc, pflag, rflag)) == -1) + if ((optidx = parse_getput_flags(cmd, argv, argc, + pflag, rflag)) == -1) return -1; /* Get first pathname (mandatory) */ if (argc - optidx < 1) { @@ -1174,8 +1180,11 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, undo_glob_escape(*path2); } break; - case I_RENAME: + case I_LINK: + if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1) + return -1; case I_SYMLINK: + case I_RENAME: if (argc - optidx < 2) { error("You must specify two paths after a %s " "command.", cmd); @@ -1278,7 +1287,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i; + int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0; + int cmdnum, i; unsigned long n_arg = 0; Attrib a, *aa; char path_buf[MAXPATHLEN]; @@ -1286,8 +1296,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, &n_arg, - &path1, &path2); + cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, + &sflag, &n_arg, &path1, &path2); if (iflag != 0) err_abort = 0; @@ -1315,8 +1325,11 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, err = do_rename(conn, path1, path2); break; case I_SYMLINK: + sflag = 1; + case I_LINK: + path1 = make_absolute(path1, *pwd); path2 = make_absolute(path2, *pwd); - err = do_symlink(conn, path1, path2); + err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2); break; case I_RM: path1 = make_absolute(path1, *pwd); @@ -1745,6 +1758,7 @@ complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path, case '"': case '\\': case '\t': + case '[': case ' ': if (quote == '\0' || tmp2[i] == quote) { if (el_insertstr(el, ins) == -1) @@ -1874,7 +1888,7 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) /* Tab Completion */ el_set(el, EL_ADDFN, "ftp-complete", - "Context senstive argument completion", complete); + "Context sensitive argument completion", complete); complete_ctx.conn = conn; complete_ctx.remote_pathp = &remote_path; el_set(el, EL_CLIENTDATA, (void*)&complete_ctx); @@ -2054,7 +2068,7 @@ usage(void) fprintf(stderr, "usage: %s [-1246Cpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" " [-D sftp_server_path] [-F ssh_config] " - "[-i identity_file]\n" + "[-i identity_file] [-l limit]\n" " [-o ssh_option] [-P port] [-R num_requests] " "[-S program]\n" " [-s subsystem | sftp_server] host\n" @@ -2073,6 +2087,7 @@ main(int argc, char **argv) int debug_level = 0, sshver = 2; char *file1 = NULL, *sftp_server = NULL; char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; + const char *errstr; LogLevel ll = SYSLOG_LEVEL_INFO; arglist args; extern int optind; @@ -2080,6 +2095,7 @@ main(int argc, char **argv) struct sftp_conn *conn; size_t copy_buffer_len = DEFAULT_COPY_BUFLEN; size_t num_requests = DEFAULT_NUM_REQUESTS; + long long limit_kbps = 0; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -2097,7 +2113,7 @@ main(int argc, char **argv) infile = stdin; while ((ch = getopt(argc, argv, - "1246hpqrvCc:D:i:o:s:S:b:B:F:P:R:")) != -1) { + "1246hpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) { switch (ch) { /* Passed through to ssh(1) */ case '4': @@ -2158,6 +2174,13 @@ main(int argc, char **argv) case 'D': sftp_direct = optarg; break; + case 'l': + limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024, + &errstr); + if (errstr != NULL) + usage(); + limit_kbps *= 1024; /* kbps */ + break; case 'r': global_rflag = 1; break; @@ -2235,7 +2258,7 @@ main(int argc, char **argv) } freeargs(&args); - conn = do_init(in, out, copy_buffer_len, num_requests); + conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps); if (conn == NULL) fatal("Couldn't initialise connection to server"); diff --git a/ssh-add.0 b/ssh-add.0 index 86f3994c4cb5..bf62ca905b2e 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -1,7 +1,7 @@ SSH-ADD(1) OpenBSD Reference Manual SSH-ADD(1) NAME - ssh-add - adds RSA or DSA identities to the authentication agent + ssh-add - adds private key identities to the authentication agent SYNOPSIS ssh-add [-cDdLlXx] [-t life] [file ...] @@ -9,10 +9,10 @@ SYNOPSIS ssh-add -e pkcs11 DESCRIPTION - ssh-add adds RSA or DSA identities to the authentication agent, + ssh-add adds private key identities to the authentication agent, ssh-agent(1). When run without arguments, it adds the files - ~/.ssh/id_rsa, ~/.ssh/id_dsa and ~/.ssh/identity. After loading a - private key, ssh-add will try to load corresponding certificate + ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/identity. After + loading a private key, ssh-add will try to load corresponding certificate information from the filename obtained by appending -cert.pub to the name of the private key file. Alternative file names can be given on the command line. @@ -87,6 +87,10 @@ FILES Contains the protocol version 2 DSA authentication identity of the user. + ~/.ssh/id_ecdsa + Contains the protocol version 2 ECDSA authentication identity of + the user. + ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. @@ -94,7 +98,7 @@ FILES Identity files should not be readable by anyone but the user. Note that ssh-add ignores identity files if they are accessible by others. -DIAGNOSTICS +EXIT STATUS Exit status is 0 on success, 1 if the specified command fails, and 2 if ssh-add is unable to contact the authentication agent. @@ -108,4 +112,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.8 March 5, 2010 OpenBSD 4.8 +OpenBSD 4.8 October 28, 2010 OpenBSD 4.8 diff --git a/ssh-add.1 b/ssh-add.1 index d7cc53101f8d..fd48ff98fa3f 100644 --- a/ssh-add.1 +++ b/ssh-add.1 @@ -1,6 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.52 2010/03/05 10:28:21 djm Exp $ -.\" -.\" -*- nroff -*- +.\" $OpenBSD: ssh-add.1,v 1.55 2010/10/28 18:33:28 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -37,12 +35,12 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: March 5 2010 $ +.Dd $Mdocdate: October 28 2010 $ .Dt SSH-ADD 1 .Os .Sh NAME .Nm ssh-add -.Nd adds RSA or DSA identities to the authentication agent +.Nd adds private key identities to the authentication agent .Sh SYNOPSIS .Nm ssh-add .Op Fl cDdLlXx @@ -54,11 +52,12 @@ .Fl e Ar pkcs11 .Sh DESCRIPTION .Nm -adds RSA or DSA identities to the authentication agent, +adds private key identities to the authentication agent, .Xr ssh-agent 1 . When run without arguments, it adds the files .Pa ~/.ssh/id_rsa , -.Pa ~/.ssh/id_dsa +.Pa ~/.ssh/id_dsa , +.Pa ~/.ssh/id_ecdsa and .Pa ~/.ssh/identity . After loading a private key, @@ -165,6 +164,8 @@ socket used to communicate with the agent. Contains the protocol version 1 RSA authentication identity of the user. .It Pa ~/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. +.It Pa ~/.ssh/id_ecdsa +Contains the protocol version 2 ECDSA authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. .El @@ -173,7 +174,7 @@ Identity files should not be readable by anyone but the user. Note that .Nm ignores identity files if they are accessible by others. -.Sh DIAGNOSTICS +.Sh EXIT STATUS Exit status is 0 on success, 1 if the specified command fails, and 2 if .Nm diff --git a/ssh-add.c b/ssh-add.c index fb641ec489ad..125d6645b19e 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.96 2010/05/14 00:47:22 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.100 2010/08/31 12:33:38 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -70,6 +70,9 @@ extern char *__progname; static char *default_files[] = { _PATH_SSH_CLIENT_ID_RSA, _PATH_SSH_CLIENT_ID_DSA, +#ifdef OPENSSL_HAS_ECC + _PATH_SSH_CLIENT_ID_ECDSA, +#endif _PATH_SSH_CLIENT_IDENTITY, NULL }; @@ -372,7 +375,7 @@ main(int argc, char **argv) init_rng(); seed_rng(); - SSLeay_add_all_algorithms(); + OpenSSL_add_all_algorithms(); /* At first, get a connection to the authentication agent. */ ac = ssh_get_authentication_connection(); diff --git a/ssh-agent.0 b/ssh-agent.0 index dfc82a966f6b..7fe1560d32e2 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -9,17 +9,18 @@ SYNOPSIS DESCRIPTION ssh-agent is a program to hold private keys used for public key - authentication (RSA, DSA). The idea is that ssh-agent is started in the - beginning of an X-session or a login session, and all other windows or - programs are started as clients to the ssh-agent program. Through use of - environment variables the agent can be located and automatically used for - authentication when logging in to other machines using ssh(1). + authentication (RSA, DSA, ECDSA). The idea is that ssh-agent is started + in the beginning of an X-session or a login session, and all other + windows or programs are started as clients to the ssh-agent program. + Through use of environment variables the agent can be located and + automatically used for authentication when logging in to other machines + using ssh(1). The options are as follows: -a bind_address Bind the agent to the UNIX-domain socket bind_address. The - default is /tmp/ssh-XXXXXXXXXX/agent.. + default is $TMPDIR/ssh-XXXXXXXXXX/agent.. -c Generate C-shell commands on stdout. This is the default if SHELL looks like it's a csh style of shell. @@ -45,13 +46,13 @@ DESCRIPTION The agent initially does not have any private keys. Keys are added using ssh-add(1). When executed without arguments, ssh-add(1) adds the files - ~/.ssh/id_rsa, ~/.ssh/id_dsa and ~/.ssh/identity. If the identity has a - passphrase, ssh-add(1) asks for the passphrase on the terminal if it has - one or from a small X11 program if running under X11. If neither of - these is the case then the authentication will fail. It then sends the - identity to the agent. Several identities can be stored in the agent; - the agent can automatically use any of these identities. ssh-add -l - displays the identities currently held by the agent. + ~/.ssh/id_rsa, ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and ~/.ssh/identity. If + the identity has a passphrase, ssh-add(1) asks for the passphrase on the + terminal if it has one or from a small X11 program if running under X11. + If neither of these is the case then the authentication will fail. It + then sends the identity to the agent. Several identities can be stored + in the agent; the agent can automatically use any of these identities. + ssh-add -l displays the identities currently held by 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, @@ -95,11 +96,15 @@ FILES Contains the protocol version 2 DSA authentication identity of the user. + ~/.ssh/id_ecdsa + Contains the protocol version 2 ECDSA authentication identity of + the user. + ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. - /tmp/ssh-XXXXXXXXXX/agent. + $TMPDIR/ssh-XXXXXXXXXX/agent. UNIX-domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the @@ -115,4 +120,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.8 January 17, 2010 OpenBSD 4.8 +OpenBSD 4.8 November 21, 2010 OpenBSD 4.8 diff --git a/ssh-agent.1 b/ssh-agent.1 index f65e8e625537..bb801c902a97 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.50 2010/01/17 21:49:09 tedu Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.53 2010/11/21 01:01:13 djm 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: January 17 2010 $ +.Dd $Mdocdate: November 21 2010 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -42,18 +42,18 @@ .Nd authentication agent .Sh SYNOPSIS .Nm ssh-agent -.Op Fl c Li | Fl s +.Op Fl c | s .Op Fl d .Op Fl a Ar bind_address .Op Fl t Ar life .Op Ar command Op Ar arg ... .Nm ssh-agent -.Op Fl c Li | Fl s +.Op Fl c | s .Fl k .Sh DESCRIPTION .Nm is a program to hold private keys used for public key authentication -(RSA, DSA). +(RSA, DSA, ECDSA). The idea is that .Nm is started in the beginning of an X-session or a login session, and @@ -72,7 +72,7 @@ Bind the agent to the socket .Ar bind_address . The default is -.Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . +.Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . .It Fl c Generate C-shell commands on .Dv stdout . @@ -114,7 +114,8 @@ When executed without arguments, .Xr ssh-add 1 adds the files .Pa ~/.ssh/id_rsa , -.Pa ~/.ssh/id_dsa +.Pa ~/.ssh/id_dsa , +.Pa ~/.ssh/id_ecdsa and .Pa ~/.ssh/identity . If the identity has a passphrase, @@ -187,9 +188,11 @@ line terminates. Contains the protocol version 1 RSA authentication identity of the user. .It Pa ~/.ssh/id_dsa Contains the protocol version 2 DSA authentication identity of the user. +.It Pa ~/.ssh/id_ecdsa +Contains the protocol version 2 ECDSA authentication identity of the user. .It Pa ~/.ssh/id_rsa Contains the protocol version 2 RSA authentication identity of the user. -.It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt +.It Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt .Ux Ns -domain sockets used to contain the connection to the authentication agent. These sockets should only be readable by the owner. diff --git a/ssh-agent.c b/ssh-agent.c index 2c0e2869600e..afba413d7827 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.166 2010/04/16 01:47:26 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.171 2010/11/21 01:01:13 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -468,6 +468,11 @@ process_add_identity(SocketEntry *e, int version) int type, success = 0, death = 0, confirm = 0; char *type_name, *comment; Key *k = NULL; +#ifdef OPENSSL_HAS_ECC + BIGNUM *exponent; + EC_POINT *q; + char *curve; +#endif u_char *cert; u_int len; @@ -490,7 +495,6 @@ process_add_identity(SocketEntry *e, int version) case 2: type_name = buffer_get_string(&e->request, NULL); type = key_type_from_name(type_name); - xfree(type_name); switch (type) { case KEY_DSA: k = key_new_private(type); @@ -509,6 +513,59 @@ process_add_identity(SocketEntry *e, int version) key_add_private(k); buffer_get_bignum2(&e->request, k->dsa->priv_key); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + k = key_new_private(type); + k->ecdsa_nid = key_ecdsa_nid_from_name(type_name); + curve = buffer_get_string(&e->request, NULL); + if (k->ecdsa_nid != key_curve_name_to_nid(curve)) + fatal("%s: curve names mismatch", __func__); + xfree(curve); + k->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); + if (k->ecdsa == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", + __func__); + q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa)); + if (q == NULL) + fatal("%s: BN_new failed", __func__); + if ((exponent = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + buffer_get_ecpoint(&e->request, + EC_KEY_get0_group(k->ecdsa), q); + buffer_get_bignum2(&e->request, exponent); + if (EC_KEY_set_public_key(k->ecdsa, q) != 1) + fatal("%s: EC_KEY_set_public_key failed", + __func__); + if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) + fatal("%s: EC_KEY_set_private_key failed", + __func__); + if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)) != 0) + fatal("%s: bad ECDSA public key", __func__); + if (key_ec_validate_private(k->ecdsa) != 0) + fatal("%s: bad ECDSA private key", __func__); + BN_clear_free(exponent); + EC_POINT_free(q); + break; + case KEY_ECDSA_CERT: + cert = buffer_get_string(&e->request, &len); + if ((k = key_from_blob(cert, len)) == NULL) + fatal("Certificate parse failed"); + xfree(cert); + key_add_private(k); + if ((exponent = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + buffer_get_bignum2(&e->request, exponent); + if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1) + fatal("%s: EC_KEY_set_private_key failed", + __func__); + if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)) != 0 || + key_ec_validate_private(k->ecdsa) != 0) + fatal("%s: bad ECDSA key", __func__); + BN_clear_free(exponent); + break; +#endif /* OPENSSL_HAS_ECC */ case KEY_RSA: k = key_new_private(type); buffer_get_bignum2(&e->request, k->rsa->n); @@ -534,9 +591,11 @@ process_add_identity(SocketEntry *e, int version) buffer_get_bignum2(&e->request, k->rsa->q); break; default: + xfree(type_name); buffer_clear(&e->request); goto send; } + xfree(type_name); break; } /* enable blinding */ @@ -1092,7 +1151,7 @@ main(int ac, char **av) prctl(PR_SET_DUMPABLE, 0); #endif - SSLeay_add_all_algorithms(); + OpenSSL_add_all_algorithms(); __progname = ssh_get_progname(av[0]); init_rng(); @@ -1173,7 +1232,7 @@ main(int ac, char **av) if (agentsocket == NULL) { /* Create private directory for agent socket */ - strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir); + mktemp_proto(socket_dir, sizeof(socket_dir)); if (mkdtemp(socket_dir) == NULL) { perror("mkdtemp: private socket dir"); exit(1); diff --git a/ssh-dss.c b/ssh-dss.c index 175e4d030110..ede5e21e5578 100644 --- a/ssh-dss.c +++ b/ssh-dss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-dss.c,v 1.26 2010/04/16 01:47:26 djm Exp $ */ +/* $OpenBSD: ssh-dss.c,v 1.27 2010/08/31 09:58:37 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -133,7 +133,7 @@ ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen, char *ktype; buffer_init(&b); buffer_append(&b, signature, signaturelen); - ktype = buffer_get_string(&b, NULL); + ktype = buffer_get_cstring(&b, NULL); if (strcmp("ssh-dss", ktype) != 0) { error("ssh_dss_verify: cannot handle type %s", ktype); buffer_free(&b); diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c new file mode 100644 index 000000000000..c8276b460437 --- /dev/null +++ b/ssh-ecdsa.c @@ -0,0 +1,168 @@ +/* $OpenBSD: ssh-ecdsa.c,v 1.4 2010/09/10 01:04:10 djm Exp $ */ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2010 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef OPENSSL_HAS_ECC + +#include + +#include +#include +#include +#include + +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "compat.h" +#include "log.h" +#include "key.h" + +int +ssh_ecdsa_sign(const Key *key, u_char **sigp, u_int *lenp, + const u_char *data, u_int datalen) +{ + ECDSA_SIG *sig; + const EVP_MD *evp_md; + EVP_MD_CTX md; + u_char digest[EVP_MAX_MD_SIZE]; + u_int len, dlen; + Buffer b, bb; + + if (key == NULL || key->ecdsa == NULL || + (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { + error("%s: no ECDSA key", __func__); + return -1; + } + evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, &dlen); + + sig = ECDSA_do_sign(digest, dlen, key->ecdsa); + memset(digest, 'd', sizeof(digest)); + + if (sig == NULL) { + error("%s: sign failed", __func__); + return -1; + } + + buffer_init(&bb); + buffer_put_bignum2(&bb, sig->r); + buffer_put_bignum2(&bb, sig->s); + ECDSA_SIG_free(sig); + + buffer_init(&b); + buffer_put_cstring(&b, key_ssh_name_plain(key)); + buffer_put_string(&b, buffer_ptr(&bb), buffer_len(&bb)); + buffer_free(&bb); + len = buffer_len(&b); + if (lenp != NULL) + *lenp = len; + if (sigp != NULL) { + *sigp = xmalloc(len); + memcpy(*sigp, buffer_ptr(&b), len); + } + buffer_free(&b); + + return 0; +} +int +ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen, + const u_char *data, u_int datalen) +{ + ECDSA_SIG *sig; + const EVP_MD *evp_md; + EVP_MD_CTX md; + u_char digest[EVP_MAX_MD_SIZE], *sigblob; + u_int len, dlen; + int rlen, ret; + Buffer b, bb; + char *ktype; + + if (key == NULL || key->ecdsa == NULL || + (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) { + error("%s: no ECDSA key", __func__); + return -1; + } + evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid); + + /* fetch signature */ + buffer_init(&b); + buffer_append(&b, signature, signaturelen); + ktype = buffer_get_string(&b, NULL); + if (strcmp(key_ssh_name_plain(key), ktype) != 0) { + error("%s: cannot handle type %s", __func__, ktype); + buffer_free(&b); + xfree(ktype); + return -1; + } + xfree(ktype); + sigblob = buffer_get_string(&b, &len); + rlen = buffer_len(&b); + buffer_free(&b); + if (rlen != 0) { + error("%s: remaining bytes in signature %d", __func__, rlen); + xfree(sigblob); + return -1; + } + + /* parse signature */ + if ((sig = ECDSA_SIG_new()) == NULL) + fatal("%s: ECDSA_SIG_new failed", __func__); + if ((sig->r = BN_new()) == NULL || + (sig->s = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + + buffer_init(&bb); + buffer_append(&bb, sigblob, len); + buffer_get_bignum2(&bb, sig->r); + buffer_get_bignum2(&bb, sig->s); + if (buffer_len(&bb) != 0) + fatal("%s: remaining bytes in inner sigblob", __func__); + + /* clean up */ + memset(sigblob, 0, len); + xfree(sigblob); + + /* hash the data */ + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, data, datalen); + EVP_DigestFinal(&md, digest, &dlen); + + ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa); + memset(digest, 'd', sizeof(digest)); + + ECDSA_SIG_free(sig); + + debug("%s: signature %s", __func__, + ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); + return ret; +} + +#endif /* OPENSSL_HAS_ECC */ diff --git a/ssh-keygen.0 b/ssh-keygen.0 index fb78387241b2..e01ad16d9652 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -28,18 +28,19 @@ 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 RSA or DSA keys for use by SSH protocol version 2. The type of key - to be generated is specified with the -t option. If invoked without any - arguments, ssh-keygen will generate an RSA key for use in SSH protocol 2 - connections. + and DSA, ECDSA or RSA keys for use by SSH protocol version 2. The type + of key to be generated is specified with the -t option. If invoked + without any arguments, ssh-keygen will generate an RSA key for use in SSH + protocol 2 connections. ssh-keygen is also used to generate groups for use in Diffie-Hellman group exchange (DH-GEX). See the MODULI GENERATION section for details. - Normally each user wishing to use SSH with RSA or DSA authentication runs + Normally each user wishing to use SSH with public key authentication runs this once to create the authentication key in ~/.ssh/identity, - ~/.ssh/id_dsa or ~/.ssh/id_rsa. Additionally, the system administrator - may use this to generate host keys, as seen in /etc/rc. + ~/.ssh/id_ecdsa, ~/.ssh/id_dsa or ~/.ssh/id_rsa. Additionally, the + system administrator may use this to generate host keys, as seen in + /etc/rc. Normally this program generates the key and asks for a file in which to store the private key. The public key is stored in a file with the same @@ -255,8 +256,8 @@ DESCRIPTION -t type Specifies the type of key to create. The possible values are - ``rsa1'' for protocol version 1 and ``rsa'' or ``dsa'' for - protocol version 2. + ``rsa1'' for protocol version 1 and ``dsa'', ``ecdsa'' or ``rsa'' + for protocol version 2. -V validity_interval Specify a validity interval when signing a certificate. A @@ -391,10 +392,9 @@ FILES the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be used to encrypt the private part of - this file using 128-bit AES. This file is not automatically - accessed by ssh-keygen but it is offered as the default file for - the private key. ssh(1) will read this file when a login attempt - is made. + this file using 3DES. This file is not automatically accessed by + ssh-keygen but it is offered as the default file for the private + key. ssh(1) will read this file when a login attempt is made. ~/.ssh/identity.pub Contains the protocol version 1 RSA public key for @@ -404,34 +404,21 @@ FILES contents of this file secret. ~/.ssh/id_dsa - Contains the protocol version 2 DSA authentication identity of - the user. This file should not be readable by anyone but the - user. It is possible to specify a passphrase when generating the - key; that passphrase will be used to encrypt the private part of - this file using 128-bit AES. This file is not automatically - accessed by ssh-keygen but it is offered as the default file for - the private key. ssh(1) will read this file when a login attempt - is made. + ~/.ssh/id_ecdsa + ~/.ssh/id_rsa + Contains the protocol version 2 DSA, ECDSA or RSA authentication + identity of the user. This file should not be readable by anyone + but the user. It is possible to specify a passphrase when + generating the key; that passphrase will be used to encrypt the + private part of this file using 128-bit AES. This file is not + automatically accessed by ssh-keygen but it is offered as the + default file for the private key. ssh(1) will read this file + when a login attempt is made. ~/.ssh/id_dsa.pub - Contains the protocol version 2 DSA public key for - authentication. The contents of this file should be added to - ~/.ssh/authorized_keys on all machines where the user wishes to - log in using public key authentication. There is no need to keep - the contents of this file secret. - - ~/.ssh/id_rsa - Contains the protocol version 2 RSA authentication identity of - the user. This file should not be readable by anyone but the - user. It is possible to specify a passphrase when generating the - key; that passphrase will be used to encrypt the private part of - this file using 128-bit AES. This file is not automatically - accessed by ssh-keygen but it is offered as the default file for - the private key. ssh(1) will read this file when a login attempt - is made. - + ~/.ssh/id_ecdsa.pub ~/.ssh/id_rsa.pub - Contains the protocol version 2 RSA public key for + Contains the protocol version 2 DSA, ECDSA or RSA public key for authentication. The contents of this file should be added to ~/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no need to keep @@ -453,4 +440,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.8 August 4, 2010 OpenBSD 4.8 +OpenBSD 4.8 October 28, 2010 OpenBSD 4.8 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 9acd8f8c9288..205f741b8ab8 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,6 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.98 2010/08/04 06:07:11 djm Exp $ -.\" -.\" -*- nroff -*- +.\" $OpenBSD: ssh-keygen.1,v 1.101 2010/10/28 18:33:28 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -37,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 4 2010 $ +.Dd $Mdocdate: October 28 2010 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -125,7 +123,7 @@ generates, manages and converts authentication keys for .Xr ssh 1 . .Nm -can create RSA keys for use by SSH protocol version 1 and RSA or DSA +can create RSA keys for use by SSH protocol version 1 and DSA, ECDSA or RSA keys for use by SSH protocol version 2. The type of key to be generated is specified with the .Fl t @@ -142,9 +140,10 @@ See the section for details. .Pp Normally each user wishing to use SSH -with RSA or DSA authentication runs this once to create the authentication +with public key authentication runs this once to create the authentication key in .Pa ~/.ssh/identity , +.Pa ~/.ssh/id_ecdsa , .Pa ~/.ssh/id_dsa or .Pa ~/.ssh/id_rsa . @@ -426,9 +425,10 @@ Specifies the type of key to create. The possible values are .Dq rsa1 for protocol version 1 and -.Dq rsa +.Dq dsa , +.Dq ecdsa or -.Dq dsa +.Dq rsa for protocol version 2. .It Fl V Ar validity_interval Specify a validity interval when signing a certificate. @@ -605,18 +605,19 @@ or .Xr ssh 1 . Please refer to those manual pages for details. .Sh FILES -.Bl -tag -width Ds +.Bl -tag -width Ds -compact .It Pa ~/.ssh/identity Contains the protocol version 1 RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 128-bit AES. +used to encrypt the private part of this file using 3DES. This file is not automatically accessed by .Nm but it is offered as the default file for the private key. .Xr ssh 1 will read this file when a login attempt is made. +.Pp .It Pa ~/.ssh/identity.pub Contains the protocol version 1 RSA public key for authentication. The contents of this file should be added to @@ -624,26 +625,11 @@ The contents of this file should be added to on all machines where the user wishes to log in using RSA authentication. There is no need to keep the contents of this file secret. +.Pp .It Pa ~/.ssh/id_dsa -Contains the protocol version 2 DSA authentication identity of the user. -This file should not be readable by anyone but the user. -It is possible to -specify a passphrase when generating the key; that passphrase will be -used to encrypt the private part of this file using 128-bit AES. -This file is not automatically accessed by -.Nm -but it is offered as the default file for the private key. -.Xr ssh 1 -will read this file when a login attempt is made. -.It Pa ~/.ssh/id_dsa.pub -Contains the protocol version 2 DSA public key for authentication. -The contents of this file should be added to -.Pa ~/.ssh/authorized_keys -on all machines -where the user wishes to log in using public key authentication. -There is no need to keep the contents of this file secret. +.It Pa ~/.ssh/id_ecdsa .It Pa ~/.ssh/id_rsa -Contains the protocol version 2 RSA authentication identity of the user. +Contains the protocol version 2 DSA, ECDSA or RSA authentication identity of the user. This file should not be readable by anyone but the user. It is possible to specify a passphrase when generating the key; that passphrase will be @@ -653,13 +639,17 @@ This file is not automatically accessed by but it is offered as the default file for the private key. .Xr ssh 1 will read this file when a login attempt is made. +.Pp +.It Pa ~/.ssh/id_dsa.pub +.It Pa ~/.ssh/id_ecdsa.pub .It Pa ~/.ssh/id_rsa.pub -Contains the protocol version 2 RSA public key for authentication. +Contains the protocol version 2 DSA, ECDSA or RSA public key for authentication. The contents of this file should be added to .Pa ~/.ssh/authorized_keys on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. +.Pp .It Pa /etc/moduli Contains Diffie-Hellman groups used for DH-GEX. The file format is described in diff --git a/ssh-keygen.c b/ssh-keygen.c index d90b1dfdd389..c95e4ab2987f 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.197 2010/08/04 06:07:11 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.205 2011/01/11 06:13:10 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -57,6 +57,7 @@ /* Number of bits in the RSA/DSA key. This value can be set on the command line. */ #define DEFAULT_BITS 2048 #define DEFAULT_BITS_DSA 1024 +#define DEFAULT_BITS_ECDSA 256 u_int32_t bits = 0; /* @@ -176,6 +177,12 @@ ask_filename(struct passwd *pw, const char *prompt) case KEY_DSA: name = _PATH_SSH_CLIENT_ID_DSA; break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: + name = _PATH_SSH_CLIENT_ID_ECDSA; + break; +#endif case KEY_RSA_CERT: case KEY_RSA_CERT_V00: case KEY_RSA: @@ -260,6 +267,12 @@ do_convert_to_pkcs8(Key *k) if (!PEM_write_DSA_PUBKEY(stdout, k->dsa)) fatal("PEM_write_DSA_PUBKEY failed"); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) + fatal("PEM_write_EC_PUBKEY failed"); + break; +#endif default: fatal("%s: unsupported key type %s", __func__, key_type(k)); } @@ -280,6 +293,7 @@ do_convert_to_pem(Key *k) fatal("PEM_write_DSAPublicKey failed"); break; #endif + /* XXX ECDSA? */ default: fatal("%s: unsupported key type %s", __func__, key_type(k)); } @@ -539,6 +553,14 @@ do_convert_from_pkcs8(Key **k, int *private) (*k)->type = KEY_DSA; (*k)->dsa = EVP_PKEY_get1_DSA(pubkey); break; +#ifdef OPENSSL_HAS_ECC + case EVP_PKEY_EC: + *k = key_new(KEY_UNSPEC); + (*k)->type = KEY_ECDSA; + (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); + (*k)->ecdsa_nid = key_ecdsa_key_to_nid((*k)->ecdsa); + break; +#endif default: fatal("%s: unsupported pubkey type %d", __func__, EVP_PKEY_type(pubkey->type)); @@ -574,6 +596,7 @@ do_convert_from_pem(Key **k, int *private) fclose(fp); return; } + /* XXX ECDSA */ #endif fatal("%s: unrecognised raw private key format", __func__); } @@ -614,6 +637,12 @@ do_convert_from(struct passwd *pw) ok = PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL); break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, + NULL, 0, NULL, NULL); + break; +#endif case KEY_RSA: ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL); @@ -1404,7 +1433,8 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) tmp = tilde_expand_filename(argv[i], pw->pw_uid); if ((public = key_load_public(tmp, &comment)) == NULL) fatal("%s: unable to open \"%s\"", __func__, tmp); - if (public->type != KEY_RSA && public->type != KEY_DSA) + if (public->type != KEY_RSA && public->type != KEY_DSA && + public->type != KEY_ECDSA) fatal("%s: key \"%s\" type %s cannot be certified", __func__, tmp, key_type(public)); @@ -1450,7 +1480,8 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) if (!quiet) { logit("Signed %s key %s: id \"%s\" serial %llu%s%s " "valid %s", key_cert_type(public), - out, public->cert->key_id, public->cert->serial, + 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)); @@ -1675,8 +1706,10 @@ do_show_cert(struct passwd *pw) printf(" Signing CA: %s %s\n", key_type(key->cert->signature_key), ca_fp); printf(" Key ID: \"%s\"\n", key->cert->key_id); - if (!v00) - printf(" Serial: %llu\n", key->cert->serial); + if (!v00) { + 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(" Principals: "); @@ -1781,7 +1814,7 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); - SSLeay_add_all_algorithms(); + OpenSSL_add_all_algorithms(); log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); init_rng(); @@ -1802,7 +1835,7 @@ main(int argc, char **argv) "O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) { switch (opt) { case 'b': - bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr); + bits = (u_int32_t)strtonum(optarg, 256, 32768, &errstr); if (errstr) fatal("Bits has bad value %s (%s)", optarg, errstr); @@ -2086,8 +2119,14 @@ main(int argc, char **argv) fprintf(stderr, "unknown key type %s\n", key_type_name); exit(1); } - if (bits == 0) - bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS; + if (bits == 0) { + if (type == KEY_DSA) + bits = DEFAULT_BITS_DSA; + else if (type == KEY_ECDSA) + bits = DEFAULT_BITS_ECDSA; + else + bits = DEFAULT_BITS; + } maxbits = (type == KEY_DSA) ? OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS; if (bits > maxbits) { @@ -2096,6 +2135,11 @@ main(int argc, char **argv) } if (type == KEY_DSA && bits != 1024) fatal("DSA keys must be 1024 bits"); + else if (type != KEY_ECDSA && bits < 768) + fatal("Key must at least be 768 bits"); + else if (type == KEY_ECDSA && key_ecdsa_bits_to_nid(bits) == -1) + fatal("Invalid ECDSA key length - valid lengths are " + "256, 384 or 521 bits"); if (!quiet) printf("Generating public/private %s key pair.\n", key_type_name); private = key_generate(type, bits); diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 9bf4cc25279b..ba53bce8164a 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -48,9 +48,9 @@ DESCRIPTION -t type Specifies the type of the key to fetch from the scanned hosts. The possible values are ``rsa1'' for protocol version 1 and - ``rsa'' or ``dsa'' for protocol version 2. Multiple values may - be specified by separating them with commas. The default is - ``rsa''. + ``dsa'', ``ecdsa'' or ``rsa'' for protocol version 2. Multiple + values may be specified by separating them with commas. The + default is ``rsa''. -v Verbose mode. Causes ssh-keyscan to print debugging messages about its progress. @@ -72,11 +72,12 @@ FILES host-or-namelist bits exponent modulus - Output format for rsa and dsa keys: + Output format for rsa, dsa and ecdsa keys: host-or-namelist keytype base64-encoded-key - Where keytype is either ``ssh-rsa'' or ``ssh-dss''. + Where keytype is either ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'', + ``ecdsa-sha2-nistp521'', ``ssh-dss'' or ``ssh-rsa''. /etc/ssh/ssh_known_hosts @@ -88,7 +89,7 @@ EXAMPLES Find all hosts from the file ssh_hosts which have new or different keys from those in the sorted file ssh_known_hosts: - $ ssh-keyscan -t rsa,dsa -f ssh_hosts | \ + $ ssh-keyscan -t rsa,dsa,ecdsa -f ssh_hosts | \ sort -u - ssh_known_hosts | diff ssh_known_hosts - SEE ALSO @@ -105,4 +106,4 @@ BUGS This is because it opens a connection to the ssh port, reads the public key, and drops the connection as soon as it gets the key. -OpenBSD 4.8 January 9, 2010 OpenBSD 4.8 +OpenBSD 4.8 August 31, 2010 OpenBSD 4.8 diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 78255ff790f8..fe9bb6e07061 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.28 2010/01/09 23:04:13 dtucker Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.29 2010/08/31 11:54:45 djm 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: January 9 2010 $ +.Dd $Mdocdate: August 31 2010 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -88,9 +88,10 @@ Specifies the type of the key to fetch from the scanned hosts. The possible values are .Dq rsa1 for protocol version 1 and -.Dq rsa +.Dq dsa , +.Dq ecdsa or -.Dq dsa +.Dq rsa for protocol version 2. Multiple values may be specified by separating them with commas. The default is @@ -122,7 +123,7 @@ attacks which have begun after the ssh_known_hosts file was created. host-or-namelist bits exponent modulus .Ed .Pp -.Pa Output format for rsa and dsa keys: +.Pa Output format for rsa, dsa and ecdsa keys: .Bd -literal host-or-namelist keytype base64-encoded-key .Ed @@ -130,9 +131,12 @@ host-or-namelist keytype base64-encoded-key Where .Pa keytype is either -.Dq ssh-rsa +.Dq ecdsa-sha2-nistp256 , +.Dq ecdsa-sha2-nistp384 , +.Dq ecdsa-sha2-nistp521 , +.Dq ssh-dss or -.Dq ssh-dss . +.Dq ssh-rsa . .Pp .Pa /etc/ssh/ssh_known_hosts .Sh EXAMPLES @@ -149,7 +153,7 @@ Find all hosts from the file which have new or different keys from those in the sorted file .Pa ssh_known_hosts : .Bd -literal -$ ssh-keyscan -t rsa,dsa -f ssh_hosts | \e +$ ssh-keyscan -t rsa,dsa,ecdsa -f ssh_hosts | \e sort -u - ssh_known_hosts | diff ssh_known_hosts - .Ed .Sh SEE ALSO diff --git a/ssh-keyscan.c b/ssh-keyscan.c index b6cf427cd62a..25d7ac66f957 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.82 2010/06/22 04:54:30 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.84 2011/01/04 20:44:13 otto Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -52,9 +52,10 @@ int IPv4or6 = AF_UNSPEC; int ssh_port = SSH_DEFAULT_PORT; -#define KT_RSA1 1 -#define KT_DSA 2 -#define KT_RSA 4 +#define KT_RSA1 1 +#define KT_DSA 2 +#define KT_RSA 4 +#define KT_ECDSA 8 int get_keytypes = KT_RSA; /* Get only RSA keys by default */ @@ -245,12 +246,14 @@ keygrab_ssh2(con *c) packet_set_connection(c->c_fd, c->c_fd); enable_compat20(); myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? - "ssh-dss": "ssh-rsa"; + "ssh-dss" : (c->c_keytype == KT_RSA ? "ssh-rsa" : + "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"); c->c_kex = kex_setup(myproposal); c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; + c->c_kex->kex[KEX_ECDH_SHA2] = kexecdh_client; c->c_kex->verify_host_key = hostjump; if (!(j = setjmp(kexjmp))) { @@ -571,7 +574,7 @@ do_host(char *host) if (name == NULL) return; - for (j = KT_RSA1; j <= KT_RSA; j *= 2) { + for (j = KT_RSA1; j <= KT_ECDSA; j *= 2) { if (get_keytypes & j) { while (ncon >= MAXCON) conloop(); @@ -673,6 +676,9 @@ main(int argc, char **argv) case KEY_DSA: get_keytypes |= KT_DSA; break; + case KEY_ECDSA: + get_keytypes |= KT_ECDSA; + break; case KEY_RSA: get_keytypes |= KT_RSA; break; diff --git a/ssh-keysign.0 b/ssh-keysign.0 index cd119139f256..9da4b24466ef 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -23,14 +23,18 @@ FILES /etc/ssh/ssh_config Controls whether ssh-keysign is enabled. - /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key + /etc/ssh/ssh_host_dsa_key + /etc/ssh/ssh_host_ecdsa_key + /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. They should be owned by root, readable only by root, and not accessible to others. Since they are readable only by root, ssh-keysign must be set-uid root if host-based authentication is used. - /etc/ssh/ssh_host_dsa_key-cert.pub, /etc/ssh/ssh_host_rsa_key-cert.pub + /etc/ssh/ssh_host_dsa_key-cert.pub + /etc/ssh/ssh_host_ecdsa_key-cert.pub + /etc/ssh/ssh_host_rsa_key-cert.pub If these files exist they are assumed to contain public certificate information corresponding with the private keys above. @@ -44,4 +48,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 4.8 August 4, 2010 OpenBSD 4.8 +OpenBSD 4.8 August 31, 2010 OpenBSD 4.8 diff --git a/ssh-keysign.8 b/ssh-keysign.8 index 46c0ee9cd9d8..5e09e0271e31 100644 --- a/ssh-keysign.8 +++ b/ssh-keysign.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keysign.8,v 1.10 2010/08/04 05:42:47 djm Exp $ +.\" $OpenBSD: ssh-keysign.8,v 1.12 2010/08/31 11:54:45 djm 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: August 4 2010 $ +.Dd $Mdocdate: August 31 2010 $ .Dt SSH-KEYSIGN 8 .Os .Sh NAME @@ -55,12 +55,15 @@ and .Xr sshd 8 for more information about host-based authentication. .Sh FILES -.Bl -tag -width Ds +.Bl -tag -width Ds -compact .It Pa /etc/ssh/ssh_config Controls whether .Nm is enabled. -.It Pa /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key +.Pp +.It Pa /etc/ssh/ssh_host_dsa_key +.It Pa /etc/ssh/ssh_host_ecdsa_key +.It Pa /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. They should be owned by root, readable only by root, and not @@ -68,7 +71,10 @@ accessible to others. Since they are readable only by root, .Nm must be set-uid root if host-based authentication is used. -.It Pa /etc/ssh/ssh_host_dsa_key-cert.pub, /etc/ssh/ssh_host_rsa_key-cert.pub +.Pp +.It Pa /etc/ssh/ssh_host_dsa_key-cert.pub +.It Pa /etc/ssh/ssh_host_ecdsa_key-cert.pub +.It Pa /etc/ssh/ssh_host_rsa_key-cert.pub If these files exist they are assumed to contain public certificate information corresponding with the private keys above. .El diff --git a/ssh-keysign.c b/ssh-keysign.c index 0c7077050f37..d05156005cf8 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.32 2010/08/04 06:08:40 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.35 2010/08/31 12:33:38 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -194,7 +194,7 @@ main(int argc, char **argv) if (key_fd[0] == -1 && key_fd[1] == -1) fatal("could not open any host key"); - SSLeay_add_all_algorithms(); + OpenSSL_add_all_algorithms(); for (i = 0; i < 256; i++) rnd[i] = arc4random(); RAND_seed(rnd, sizeof(rnd)); diff --git a/ssh-rsa.c b/ssh-rsa.c index c471ff323bcf..c6355fa0946d 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.44 2010/07/16 14:07:35 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.45 2010/08/31 09:58:37 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -127,7 +127,7 @@ ssh_rsa_verify(const Key *key, const u_char *signature, u_int signaturelen, } buffer_init(&b); buffer_append(&b, signature, signaturelen); - ktype = buffer_get_string(&b, NULL); + ktype = buffer_get_cstring(&b, NULL); if (strcmp("ssh-rsa", ktype) != 0) { error("ssh_rsa_verify: cannot handle type %s", ktype); buffer_free(&b); diff --git a/ssh.0 b/ssh.0 index 8d53ad2893ac..3d2036253c0b 100644 --- a/ssh.0 +++ b/ssh.0 @@ -135,15 +135,15 @@ DESCRIPTION with a PKCS#11 token providing the user's private RSA key. -i identity_file - Selects a file from which the identity (private key) for RSA or - DSA authentication is read. The default is ~/.ssh/identity for - protocol version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa 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. + Selects a file from which the identity (private key) for public + key authentication is read. The default is ~/.ssh/identity for + protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa 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. -K Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server. @@ -244,7 +244,9 @@ DESCRIPTION HostName IdentityFile IdentitiesOnly + IPQoS KbdInteractiveDevices + KexAlgorithms LocalCommand LocalForward LogLevel @@ -380,9 +382,6 @@ DESCRIPTION configuration file and a system-wide configuration file. The file format and configuration options are described in ssh_config(5). - ssh exits with the exit status of the remote command or with 255 if an - error occurred. - 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 @@ -421,9 +420,9 @@ 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 - either the RSA or DSA algorithms. Protocol 1 is restricted to using only - RSA keys, but protocol 2 may use either. The HISTORY section of ssl(8) - contains a brief discussion of the two algorithms. + one of the DSA, ECDSA 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. 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 @@ -433,14 +432,15 @@ AUTHENTICATION The user creates his/her key pair by running ssh-keygen(1). This stores the private key in ~/.ssh/identity (protocol 1), ~/.ssh/id_dsa (protocol - 2 DSA), 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), or - ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home directory. The - user should then copy the public key to ~/.ssh/authorized_keys in his/her - home directory on the remote machine. The authorized_keys file - corresponds to the conventional ~/.rhosts file, and has one key per line, - though the lines can be very long. After this, the user can log in - without giving the password. + 2 DSA), ~/.ssh/id_ecdsa (protocol 2 ECDSA), 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), or ~/.ssh/id_rsa.pub (protocol 2 RSA) in the user's home + directory. The user should then copy the public key to + ~/.ssh/authorized_keys in his/her home directory on the remote machine. + The authorized_keys file corresponds to the conventional ~/.rhosts file, + and has one key per line, though the lines can be very long. After this, + the user can log in without giving the password. A variation on public key authentication is available in the form of certificate authentication: instead of a set of public/private keys, @@ -763,10 +763,10 @@ FILES for the user, and not accessible by others. ~/.ssh/authorized_keys - Lists the public keys (RSA/DSA) that can be used for logging in - as this user. The format of this file is described in the - sshd(8) manual page. This file is not highly sensitive, but the - recommended permissions are read/write for the user, and not + Lists the public keys (DSA/ECDSA/RSA) that can be used for + logging in as this user. The format of this file is described in + the sshd(8) manual page. This file is not highly sensitive, but + the recommended permissions are read/write for the user, and not accessible by others. ~/.ssh/config @@ -781,6 +781,7 @@ FILES ~/.ssh/identity ~/.ssh/id_dsa + ~/.ssh/id_ecdsa ~/.ssh/id_rsa Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not @@ -792,6 +793,7 @@ FILES ~/.ssh/identity.pub ~/.ssh/id_dsa.pub + ~/.ssh/id_ecdsa.pub ~/.ssh/id_rsa.pub Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone. @@ -822,6 +824,7 @@ FILES /etc/ssh/ssh_host_key /etc/ssh/ssh_host_dsa_key + /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys and are used for host-based authentication. If protocol version 1 is @@ -842,6 +845,10 @@ FILES just before the user's shell (or command) is started. See the sshd(8) manual page for more information. +EXIT STATUS + ssh exits with the exit status of the remote command or with 255 if an + error occurred. + SEE ALSO scp(1), sftp(1), ssh-add(1), ssh-agent(1), ssh-keygen(1), ssh-keyscan(1), tun(4), hosts.equiv(5), ssh_config(5), ssh-keysign(8), sshd(8) @@ -874,7 +881,10 @@ SEE ALSO The Secure Shell (SSH) Public Key File Format, RFC 4716, 2006. - A. Perrig, D. Song, Hash Visualization: a New Technique to improve + Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer, + RFC 5656, 2009. + + A. Perrig and D. Song, Hash Visualization: a New Technique to improve Real-World Security, 1999, International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99). @@ -885,4 +895,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.8 August 4, 2010 OpenBSD 4.8 +OpenBSD 4.8 November 18, 2010 OpenBSD 4.8 diff --git a/ssh.1 b/ssh.1 index 02d28a00b935..e3a42b5ad7de 100644 --- a/ssh.1 +++ b/ssh.1 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,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.308 2010/08/04 05:37:01 djm Exp $ -.Dd $Mdocdate: August 4 2010 $ +.\" $OpenBSD: ssh.1,v 1.316 2010/11/18 15:01:00 jmc Exp $ +.Dd $Mdocdate: November 18 2010 $ .Dt SSH 1 .Os .Sh NAME @@ -269,13 +268,14 @@ should use to communicate with a PKCS#11 token providing the user's private RSA key. .It Fl i Ar identity_file Selects a file from which the identity (private key) for -RSA or DSA authentication is read. +public key authentication is read. The default is .Pa ~/.ssh/identity for protocol version 1, and -.Pa ~/.ssh/id_rsa +.Pa ~/.ssh/id_dsa , +.Pa ~/.ssh/id_ecdsa and -.Pa ~/.ssh/id_dsa +.Pa ~/.ssh/id_rsa for protocol version 2. Identity files may also be specified on a per-host basis in the configuration file. @@ -435,7 +435,9 @@ For full details of the options listed below, and their possible values, see .It HostName .It IdentityFile .It IdentitiesOnly +.It IPQoS .It KbdInteractiveDevices +.It KexAlgorithms .It LocalCommand .It LocalForward .It LogLevel @@ -646,10 +648,6 @@ may additionally obtain configuration data from a per-user configuration file and a system-wide configuration file. The file format and configuration options are described in .Xr ssh_config 5 . -.Pp -.Nm -exits with the exit status of the remote command or with 255 -if an error occurred. .Sh AUTHENTICATION The OpenSSH SSH client supports SSH protocols 1 and 2. The default is to use protocol 2 only, @@ -721,14 +719,14 @@ key pair for authentication purposes. The server knows the public key, and only the user knows the private key. .Nm implements public key authentication protocol automatically, -using either the RSA or DSA algorithms. +using one of the DSA, ECDSA or RSA algorithms. Protocol 1 is restricted to using only RSA keys, -but protocol 2 may use either. +but protocol 2 may use any. The .Sx HISTORY section of .Xr ssl 8 -contains a brief discussion of the two algorithms. +contains a brief discussion of the DSA and RSA algorithms. .Pp The file .Pa ~/.ssh/authorized_keys @@ -748,6 +746,8 @@ This stores the private key in (protocol 1), .Pa ~/.ssh/id_dsa (protocol 2 DSA), +.Pa ~/.ssh/id_ecdsa +(protocol 2 ECDSA), or .Pa ~/.ssh/id_rsa (protocol 2 RSA) @@ -756,6 +756,8 @@ and stores the public key in (protocol 1), .Pa ~/.ssh/id_dsa.pub (protocol 2 DSA), +.Pa ~/.ssh/id_ecdsa.pub +(protocol 2 ECDSA), or .Pa ~/.ssh/id_rsa.pub (protocol 2 RSA) @@ -1250,7 +1252,7 @@ option in .Xr sshd_config 5 . .Sh FILES .Bl -tag -width Ds -compact -.It ~/.rhosts +.It Pa ~/.rhosts This file is used for host-based authentication (see above). On some machines this file may need to be world-readable if the user's home directory is on an NFS partition, @@ -1263,42 +1265,44 @@ The recommended permission for most machines is read/write for the user, and not accessible by others. .Pp -.It ~/.shosts +.It Pa ~/.shosts This file is used in exactly the same way as .Pa .rhosts , but allows host-based authentication without permitting login with rlogin/rsh. .Pp -.It ~/.ssh/ +.It Pa ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. There is no general requirement to keep the entire contents of this directory secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp -.It ~/.ssh/authorized_keys -Lists the public keys (RSA/DSA) that can be used for logging in as this user. +.It Pa ~/.ssh/authorized_keys +Lists the public keys (DSA/ECDSA/RSA) that can be used for logging in as +this user. The format of this file is described in the .Xr sshd 8 manual page. This file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. .Pp -.It ~/.ssh/config +.It Pa ~/.ssh/config This is the per-user configuration file. The file format and configuration options are described in .Xr ssh_config 5 . Because of the potential for abuse, this file must have strict permissions: read/write for the user, and not accessible by others. .Pp -.It ~/.ssh/environment +.It Pa ~/.ssh/environment Contains additional definitions for environment variables; see .Sx ENVIRONMENT , above. .Pp -.It ~/.ssh/identity -.It ~/.ssh/id_dsa -.It ~/.ssh/id_rsa +.It Pa ~/.ssh/identity +.It Pa ~/.ssh/id_dsa +.It Pa ~/.ssh/id_ecdsa +.It Pa ~/.ssh/id_rsa Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not @@ -1309,21 +1313,22 @@ It is possible to specify a passphrase when generating the key which will be used to encrypt the sensitive part of this file using 3DES. .Pp -.It ~/.ssh/identity.pub -.It ~/.ssh/id_dsa.pub -.It ~/.ssh/id_rsa.pub +.It Pa ~/.ssh/identity.pub +.It Pa ~/.ssh/id_dsa.pub +.It Pa ~/.ssh/id_ecdsa.pub +.It Pa ~/.ssh/id_rsa.pub Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone. .Pp -.It ~/.ssh/known_hosts +.It Pa ~/.ssh/known_hosts Contains a list of host keys for all hosts the user has logged into that are not already in the systemwide list of known host keys. See .Xr sshd 8 for further details of the format of this file. .Pp -.It ~/.ssh/rc +.It Pa ~/.ssh/rc Commands in this file are executed by .Nm when the user logs in, just before the user's shell (or command) is @@ -1332,11 +1337,11 @@ See the .Xr sshd 8 manual page for more information. .Pp -.It /etc/hosts.equiv +.It Pa /etc/hosts.equiv This file is for host-based authentication (see above). It should only be writable by root. .Pp -.It /etc/shosts.equiv +.It Pa /etc/shosts.equiv This file is used in exactly the same way as .Pa hosts.equiv , but allows host-based authentication without permitting login with @@ -1347,9 +1352,10 @@ Systemwide configuration file. The file format and configuration options are described in .Xr ssh_config 5 . .Pp -.It /etc/ssh/ssh_host_key -.It /etc/ssh/ssh_host_dsa_key -.It /etc/ssh/ssh_host_rsa_key +.It Pa /etc/ssh/ssh_host_key +.It Pa /etc/ssh/ssh_host_dsa_key +.It Pa /etc/ssh/ssh_host_ecdsa_key +.It Pa /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys and are used for host-based authentication. If protocol version 1 is used, @@ -1367,7 +1373,7 @@ By default .Nm is not setuid root. .Pp -.It /etc/ssh/ssh_known_hosts +.It Pa /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared by the system administrator to contain the public host keys of all machines in the @@ -1377,7 +1383,7 @@ See .Xr sshd 8 for further details of the format of this file. .Pp -.It /etc/ssh/sshrc +.It Pa /etc/ssh/sshrc Commands in this file are executed by .Nm when the user logs in, just before the user's shell (or command) is started. @@ -1385,6 +1391,10 @@ See the .Xr sshd 8 manual page for more information. .El +.Sh EXIT STATUS +.Nm +exits with the exit status of the remote command or with 255 +if an error occurred. .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , @@ -1458,6 +1468,11 @@ manual page for more information. .%D 2006 .Re .Rs +.%R RFC 5656 +.%T "Elliptic Curve Algorithm Integration in the Secure Shell Transport Layer" +.%D 2009 +.Re +.Rs .%T "Hash Visualization: a New Technique to improve Real-World Security" .%A A. Perrig .%A D. Song diff --git a/ssh.c b/ssh.c index 4419f7642e60..9409fa713d73 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.346 2010/08/12 21:49:44 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.356 2011/01/06 22:23:53 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -182,9 +183,6 @@ int subsystem_flag = 0; /* # of replies received for global requests */ static int remote_forward_confirms_received = 0; -/* pid of proxycommand child process */ -pid_t proxy_command_pid = 0; - /* mux.c */ extern int muxserver_sock; extern u_int muxclient_command; @@ -210,6 +208,7 @@ usage(void) static int ssh_session(void); static int ssh_session2(void); static void load_public_identity_files(void); +static void main_sigchld_handler(int); /* from muxclient.c */ void muxclient(const char *); @@ -222,7 +221,7 @@ int main(int ac, char **av) { int i, r, opt, exit_status, use_syslog; - char *p, *cp, *line, *argv0, buf[MAXPATHLEN]; + char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg; struct stat st; struct passwd *pw; int dummy, timeout_ms; @@ -599,7 +598,7 @@ main(int ac, char **av) if (!host) usage(); - SSLeay_add_all_algorithms(); + OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* Initialize the command to execute on remote host. */ @@ -694,6 +693,8 @@ main(int ac, char **av) options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; } + /* preserve host name given on command line for %n expansion */ + host_arg = host; if (options.hostname != NULL) { host = percent_expand(options.hostname, "h", host, (char *)NULL); @@ -708,7 +709,7 @@ main(int ac, char **av) debug3("expanding LocalCommand: %s", options.local_command); cp = options.local_command; options.local_command = percent_expand(cp, "d", pw->pw_dir, - "h", host, "l", thishost, "n", host, "r", options.user, + "h", host, "l", thishost, "n", host_arg, "r", options.user, "p", buf, "u", pw->pw_name, (char *)NULL); debug3("expanded LocalCommand: %s", options.local_command); xfree(cp); @@ -780,34 +781,53 @@ main(int ac, char **av) sensitive_data.external_keysign = 0; if (options.rhosts_rsa_authentication || options.hostbased_authentication) { - sensitive_data.nkeys = 5; + sensitive_data.nkeys = 7; sensitive_data.keys = xcalloc(sensitive_data.nkeys, sizeof(Key)); + for (i = 0; i < sensitive_data.nkeys; i++) + sensitive_data.keys[i] = NULL; PRIV_START; sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, _PATH_HOST_KEY_FILE, "", NULL, NULL); sensitive_data.keys[1] = key_load_private_cert(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL); - sensitive_data.keys[2] = key_load_private_cert(KEY_RSA, +#ifdef OPENSSL_HAS_ECC + sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA, + _PATH_HOST_ECDSA_KEY_FILE, "", NULL); +#endif + sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL); - sensitive_data.keys[3] = key_load_private_type(KEY_DSA, + sensitive_data.keys[4] = key_load_private_type(KEY_DSA, _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); - sensitive_data.keys[4] = key_load_private_type(KEY_RSA, +#ifdef OPENSSL_HAS_ECC + sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, + _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); +#endif + sensitive_data.keys[6] = key_load_private_type(KEY_RSA, _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); PRIV_END; if (options.hostbased_authentication == 1 && sensitive_data.keys[0] == NULL && - sensitive_data.keys[3] == NULL && - sensitive_data.keys[4] == NULL) { + sensitive_data.keys[4] == NULL && + sensitive_data.keys[5] == NULL && + sensitive_data.keys[6] == NULL) { sensitive_data.keys[1] = key_load_cert( _PATH_HOST_DSA_KEY_FILE); +#ifdef OPENSSL_HAS_ECC sensitive_data.keys[2] = key_load_cert( + _PATH_HOST_ECDSA_KEY_FILE); +#endif + sensitive_data.keys[3] = key_load_cert( _PATH_HOST_RSA_KEY_FILE); - sensitive_data.keys[3] = key_load_public( - _PATH_HOST_DSA_KEY_FILE, NULL); sensitive_data.keys[4] = key_load_public( + _PATH_HOST_DSA_KEY_FILE, NULL); +#ifdef OPENSSL_HAS_ECC + sensitive_data.keys[5] = key_load_public( + _PATH_HOST_ECDSA_KEY_FILE, NULL); +#endif + sensitive_data.keys[6] = key_load_public( _PATH_HOST_RSA_KEY_FILE, NULL); sensitive_data.external_keysign = 1; } @@ -830,10 +850,19 @@ main(int ac, char **av) */ r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); - if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) + if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) { +#ifdef WITH_SELINUX + char *scon; + + matchpathcon(buf, 0700, &scon); + setfscreatecon(scon); +#endif if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); - +#ifdef WITH_SELINUX + setfscreatecon(NULL); +#endif + } /* load options.identity_files */ load_public_identity_files(); @@ -849,10 +878,11 @@ main(int ac, char **av) tilde_expand_filename(options.user_hostfile2, original_real_uid); signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ + signal(SIGCHLD, main_sigchld_handler); /* Log into the remote system. Never returns if the login fails. */ ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, - pw, timeout_ms); + options.port, pw, timeout_ms); if (packet_connection_is_on_socket()) { verbose("Authenticated to %s ([%s]:%d).", host, @@ -890,12 +920,8 @@ main(int ac, char **av) if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); - /* - * Send SIGHUP to proxy command if used. We don't wait() in - * case it hangs and instead rely on init to reap the child - */ - if (proxy_command_pid > 1) - kill(proxy_command_pid, SIGHUP); + /* Kill ProxyCommand if it is running. */ + ssh_kill_proxy_command(); return exit_status; } @@ -927,6 +953,7 @@ control_persist_detach(void) tty_flag = otty_flag; close(muxserver_sock); muxserver_sock = -1; + options.control_master = SSHCTL_MASTER_NO; muxclient(options.control_path); /* muxclient() doesn't return on success. */ fatal("Failed to connect to new control master"); @@ -1199,7 +1226,8 @@ ssh_session(void) } } /* Tell the packet module whether this is an interactive session. */ - packet_set_interactive(interactive); + packet_set_interactive(interactive, + options.ip_qos_interactive, options.ip_qos_bulk); /* Request authentication agent forwarding if appropriate. */ check_agent_present(); @@ -1297,8 +1325,6 @@ ssh_session2_setup(int id, int success, void *arg) client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), NULL, fileno(stdin), &command, environ); - - packet_set_interactive(interactive); } /* open new channel for a session */ @@ -1516,3 +1542,19 @@ load_public_identity_files(void) bzero(pwdir, strlen(pwdir)); xfree(pwdir); } + +static void +main_sigchld_handler(int sig) +{ + int save_errno = errno; + pid_t pid; + int status; + + while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || + (pid < 0 && errno == EINTR)) + ; + + signal(sig, main_sigchld_handler); + errno = save_errno; +} + diff --git a/ssh2.h b/ssh2.h index 3ffaf686b86b..51a963cae27a 100644 --- a/ssh2.h +++ b/ssh2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh2.h,v 1.13 2010/02/26 20:29:54 djm Exp $ */ +/* $OpenBSD: ssh2.h,v 1.14 2010/08/31 11:54:45 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -98,6 +98,10 @@ #define SSH2_MSG_KEX_DH_GEX_REPLY 33 #define SSH2_MSG_KEX_DH_GEX_REQUEST 34 +/* ecdh */ +#define SSH2_MSG_KEX_ECDH_INIT 30 +#define SSH2_MSG_KEX_ECDH_REPLY 31 + /* user authentication: generic */ #define SSH2_MSG_USERAUTH_REQUEST 50 diff --git a/ssh_config.0 b/ssh_config.0 index 6c19de7653bb..71233b49bd9b 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -313,7 +313,18 @@ DESCRIPTION HostKeyAlgorithms Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. The default for this - option is: ``ssh-rsa,ssh-dss''. + option is: + + ecdsa-sha2-nistp256-cert-v01@openssh.com, + ecdsa-sha2-nistp384-cert-v01@openssh.com, + ecdsa-sha2-nistp521-cert-v01@openssh.com, + ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com, + ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com, + ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, + ssh-rsa,ssh-dss + + If hostkeys are known for the destination host then this default + is modified to prefer their algorithms. HostKeyAlias Specifies an alias that should be used instead of the real host @@ -340,14 +351,14 @@ DESCRIPTION ``no''. IdentityFile - Specifies a file from which the user's RSA or DSA authentication - identity is read. The default is ~/.ssh/identity for protocol - version 1, and ~/.ssh/id_rsa and ~/.ssh/id_dsa for protocol - version 2. Additionally, any identities represented by the - authentication agent will be used for authentication. ssh(1) - will try to load certificate information from the filename - obtained by appending -cert.pub to the path of a specified - IdentityFile. + Specifies a file from which the user's DSA, ECDSA or DSA + authentication identity is read. The default is ~/.ssh/identity + for protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and + ~/.ssh/id_rsa for protocol version 2. Additionally, any + identities represented by the authentication agent will be used + for authentication. 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: `%d' (local @@ -358,6 +369,19 @@ DESCRIPTION configuration files; all these identities will be tried in sequence. + IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. + Accepted values are ``af11'', ``af12'', ``af13'', ``af14'', + ``af22'', ``af23'', ``af31'', ``af32'', ``af33'', ``af41'', + ``af42'', ``af43'', ``cs0'', ``cs1'', ``cs2'', ``cs3'', ``cs4'', + ``cs5'', ``cs6'', ``cs7'', ``ef'', ``lowdelay'', ``throughput'', + ``reliability'', or a numeric value. This option may take one or + two arguments, separated by whitespace. If one argument is + specified, it is used as the packet class unconditionally. If + two values are specified, the first is automatically selected for + interactive sessions and the second for non-interactive sessions. + The default is ``lowdelay'' for interactive sessions and + ``throughput'' for non-interactive sessions. + KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. The argument to this keyword must be ``yes'' or ``no''. The @@ -371,6 +395,16 @@ DESCRIPTION OpenSSH server, it may be zero or more of: ``bsdauth'', ``pam'', and ``skey''. + KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. Multiple + algorithms must be comma-separated. The default is: + + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, + diffie-hellman-group-exchange-sha256, + diffie-hellman-group-exchange-sha1, + diffie-hellman-group14-sha1, + diffie-hellman-group1-sha1 + LocalCommand Specifies a command to execute on the local machine after successfully connecting to the server. The command string @@ -444,7 +478,7 @@ DESCRIPTION PKCS11Provider Specifies which PKCS#11 provider to use. The argument to this - keyword is the PKCS#11 shared libary ssh(1) should use to + keyword is the PKCS#11 shared library ssh(1) should use to communicate with a PKCS#11 token providing the user's private RSA key. @@ -614,7 +648,7 @@ DESCRIPTION Specifies the tun(4) devices to open on the client (local_tun) and the server (remote_tun). - The argument must be local_tun [:remote_tun]. The devices may be + The argument must be local_tun[:remote_tun]. The devices may be specified by numerical ID or the keyword ``any'', which uses the next available tunnel device. If remote_tun is not specified, it defaults to ``any''. The default is ``any:any''. @@ -707,4 +741,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.8 August 4, 2010 OpenBSD 4.8 +OpenBSD 4.8 December 8, 2010 OpenBSD 4.8 diff --git a/ssh_config.5 b/ssh_config.5 index ddb806ec00e7..50bcae82f661 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,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.138 2010/08/04 05:37:01 djm Exp $ -.Dd $Mdocdate: August 4 2010 $ +.\" $OpenBSD: ssh_config.5,v 1.146 2010/12/08 04:02:47 djm Exp $ +.Dd $Mdocdate: December 8 2010 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -547,7 +546,18 @@ is similar to Specifies the protocol version 2 host key algorithms that the client wants to use in order of preference. The default for this option is: -.Dq ssh-rsa,ssh-dss . +.Bd -literal -offset 3n +ecdsa-sha2-nistp256-cert-v01@openssh.com, +ecdsa-sha2-nistp384-cert-v01@openssh.com, +ecdsa-sha2-nistp521-cert-v01@openssh.com, +ssh-rsa-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com, +ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com, +ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521, +ssh-rsa,ssh-dss +.Ed +.Pp +If hostkeys are known for the destination host then this default is modified +to prefer their algorithms. .It Cm HostKeyAlias Specifies an alias that should be used instead of the real host name when looking up or saving the host key @@ -583,14 +593,15 @@ offers many different identities. The default is .Dq no . .It Cm IdentityFile -Specifies a file from which the user's RSA or DSA authentication identity -is read. +Specifies a file from which the user's DSA, ECDSA or DSA authentication +identity is read. The default is .Pa ~/.ssh/identity for protocol version 1, and -.Pa ~/.ssh/id_rsa +.Pa ~/.ssh/id_dsa , +.Pa ~/.ssh/id_ecdsa and -.Pa ~/.ssh/id_dsa +.Pa ~/.ssh/id_rsa for protocol version 2. Additionally, any identities represented by the authentication agent will be used for authentication. @@ -618,6 +629,43 @@ escape characters: It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence. +.It Cm IPQoS +Specifies the IPv4 type-of-service or DSCP class for connections. +Accepted values are +.Dq af11 , +.Dq af12 , +.Dq af13 , +.Dq af14 , +.Dq af22 , +.Dq af23 , +.Dq af31 , +.Dq af32 , +.Dq af33 , +.Dq af41 , +.Dq af42 , +.Dq af43 , +.Dq cs0 , +.Dq cs1 , +.Dq cs2 , +.Dq cs3 , +.Dq cs4 , +.Dq cs5 , +.Dq cs6 , +.Dq cs7 , +.Dq ef , +.Dq lowdelay , +.Dq throughput , +.Dq reliability , +or a numeric value. +This option may take one or two arguments, separated by whitespace. +If one argument is specified, it is used as the packet class unconditionally. +If two values are specified, the first is automatically selected for +interactive sessions and the second for non-interactive sessions. +The default is +.Dq lowdelay +for interactive sessions and +.Dq throughput +for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. The argument to this keyword must be @@ -637,6 +685,17 @@ it may be zero or more of: .Dq pam , and .Dq skey . +.It Cm KexAlgorithms +Specifies the available KEX (Key Exchange) algorithms. +Multiple algorithms must be comma-separated. +The default is: +.Bd -literal -offset indent +ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, +diffie-hellman-group-exchange-sha256, +diffie-hellman-group-exchange-sha1, +diffie-hellman-group14-sha1, +diffie-hellman-group1-sha1 +.Ed .It Cm LocalCommand Specifies a command to execute on the local machine after successfully connecting to the server. @@ -750,7 +809,7 @@ The default is .Dq no . .It Cm PKCS11Provider Specifies which PKCS#11 provider to use. -The argument to this keyword is the PKCS#11 shared libary +The argument to this keyword is the PKCS#11 shared library .Xr ssh 1 should use to communicate with a PKCS#11 token providing the user's private RSA key. diff --git a/sshconnect.c b/sshconnect.c index f55beffe40fc..74643a8c426a 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.224 2010/04/16 21:14:27 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.232 2011/01/16 11:50:36 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,6 +34,7 @@ #include #endif #include +#include #include #include #include @@ -66,14 +67,15 @@ char *server_version_string = NULL; static int matching_host_key_dns = 0; +static pid_t proxy_command_pid = 0; + /* import */ extern Options options; extern char *__progname; extern uid_t original_real_uid; extern uid_t original_effective_uid; -extern pid_t proxy_command_pid; -static int show_other_keys(const char *, Key *); +static int show_other_keys(struct hostkeys *, Key *); static void warn_changed_key(Key *); /* @@ -87,7 +89,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) pid_t pid; char *shell, strport[NI_MAXSERV]; - if ((shell = getenv("SHELL")) == NULL) + if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; /* Convert the port number into a string. */ @@ -141,6 +143,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) /* Execute the proxy command. Note that we gave up any extra privileges above. */ + signal(SIGPIPE, SIG_DFL); execv(argv[0], argv); perror(argv[0]); exit(1); @@ -167,6 +170,17 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) return 0; } +void +ssh_kill_proxy_command(void) +{ + /* + * Send SIGHUP to proxy command if used. We don't wait() in + * case it hangs and instead rely on init to reap the child + */ + if (proxy_command_pid > 1) + kill(proxy_command_pid, SIGHUP); +} + /* * Creates a (possibly privileged) socket for use as the ssh connection. */ @@ -594,6 +608,79 @@ check_host_cert(const char *host, const Key *host_key) return 1; } +static int +sockaddr_is_local(struct sockaddr *hostaddr) +{ + switch (hostaddr->sa_family) { + case AF_INET: + return (ntohl(((struct sockaddr_in *)hostaddr)-> + sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; + case AF_INET6: + return IN6_IS_ADDR_LOOPBACK( + &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); + default: + return 0; + } +} + +/* + * Prepare the hostname and ip address strings that are used to lookup + * host keys in known_hosts files. These may have a port number appended. + */ +void +get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr, + u_short port, char **hostfile_hostname, char **hostfile_ipaddr) +{ + char ntop[NI_MAXHOST]; + socklen_t addrlen; + + switch (hostaddr == NULL ? -1 : hostaddr->sa_family) { + case -1: + addrlen = 0; + break; + case AF_INET: + addrlen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrlen = sizeof(struct sockaddr_in6); + break; + default: + addrlen = sizeof(struct sockaddr); + break; + } + + /* + * We don't have the remote ip-address for connections + * using a proxy command + */ + if (hostfile_ipaddr != NULL) { + if (options.proxy_command == NULL) { + if (getnameinfo(hostaddr, addrlen, + ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) + fatal("check_host_key: getnameinfo failed"); + *hostfile_ipaddr = put_host_port(ntop, port); + } else { + *hostfile_ipaddr = xstrdup(""); + } + } + + /* + * Allow the user to record the key under a different name or + * differentiate a non-standard port. This is useful for ssh + * tunneling over forwarded connections or if you run multiple + * sshd's on different ports on the same machine. + */ + if (hostfile_hostname != NULL) { + if (options.host_key_alias != NULL) { + *hostfile_hostname = xstrdup(options.host_key_alias); + debug("using hostkeyalias: %s", *hostfile_hostname); + } else { + *hostfile_hostname = put_host_port(hostname, port); + } + } +} + /* * check whether the supplied host key is valid, return -1 if the key * is not valid. the user_hostfile will not be updated if 'readonly' is true. @@ -603,21 +690,21 @@ check_host_cert(const char *host, const Key *host_key) #define ROQUIET 2 static int check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, - Key *host_key, int readonly, const char *user_hostfile, - const char *system_hostfile) + Key *host_key, int readonly, char *user_hostfile, + char *system_hostfile) { - Key *file_key, *raw_key = NULL; + Key *raw_key = NULL; const char *type; char *ip = NULL, *host = NULL; char hostline[1000], *hostp, *fp, *ra; HostStatus host_status; HostStatus ip_status; - int r, want_cert, local = 0, host_ip_differ = 0; - int salen; - char ntop[NI_MAXHOST]; + int r, want_cert = key_is_cert(host_key), host_ip_differ = 0; + int local = sockaddr_is_local(hostaddr); char msg[1024]; - int len, host_line, ip_line, cancelled_forwarding = 0; - const char *host_file = NULL, *ip_file = NULL; + int len, cancelled_forwarding = 0; + struct hostkeys *host_hostkeys, *ip_hostkeys; + const struct hostkey_entry *host_found, *ip_found; /* * Force accepting of the host key for loopback/localhost. The @@ -627,23 +714,6 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, * essentially disables host authentication for localhost; however, * this is probably not a real problem. */ - /** hostaddr == 0! */ - switch (hostaddr->sa_family) { - case AF_INET: - local = (ntohl(((struct sockaddr_in *)hostaddr)-> - sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; - salen = sizeof(struct sockaddr_in); - break; - case AF_INET6: - local = IN6_IS_ADDR_LOOPBACK( - &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); - salen = sizeof(struct sockaddr_in6); - break; - default: - local = 0; - salen = sizeof(struct sockaddr_storage); - break; - } if (options.no_host_authentication_for_localhost == 1 && local && options.host_key_alias == NULL) { debug("Forcing accepting of host key for " @@ -652,17 +722,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, } /* - * We don't have the remote ip-address for connections - * using a proxy command + * Prepare the hostname and address strings used for hostkey lookup. + * In some cases, these will have a port number appended. */ - if (options.proxy_command == NULL) { - if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop), - NULL, 0, NI_NUMERICHOST) != 0) - fatal("check_host_key: getnameinfo failed"); - ip = put_host_port(ntop, port); - } else { - ip = xstrdup(""); - } + get_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip); /* * Turn off check_host_ip if the connection is to localhost, via proxy @@ -672,74 +735,52 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, strcmp(hostname, ip) == 0 || options.proxy_command != NULL)) options.check_host_ip = 0; - /* - * Allow the user to record the key under a different name or - * differentiate a non-standard port. This is useful for ssh - * tunneling over forwarded connections or if you run multiple - * sshd's on different ports on the same machine. - */ - if (options.host_key_alias != NULL) { - host = xstrdup(options.host_key_alias); - debug("using hostkeyalias: %s", host); - } else { - host = put_host_port(hostname, port); + host_hostkeys = init_hostkeys(); + load_hostkeys(host_hostkeys, host, user_hostfile); + load_hostkeys(host_hostkeys, host, system_hostfile); + + ip_hostkeys = NULL; + if (!want_cert && options.check_host_ip) { + ip_hostkeys = init_hostkeys(); + load_hostkeys(ip_hostkeys, ip, user_hostfile); + load_hostkeys(ip_hostkeys, ip, system_hostfile); } retry: + /* Reload these as they may have changed on cert->key downgrade */ want_cert = key_is_cert(host_key); type = key_type(host_key); - /* - * Store the host key from the known host file in here so that we can - * compare it with the key for the IP address. - */ - file_key = key_new(key_is_cert(host_key) ? KEY_UNSPEC : host_key->type); - /* * Check if the host key is present in the user's list of known * hosts or in the systemwide list. */ - host_file = user_hostfile; - host_status = check_host_in_hostfile(host_file, host, host_key, - file_key, &host_line); - if (host_status == HOST_NEW) { - host_file = system_hostfile; - host_status = check_host_in_hostfile(host_file, host, host_key, - file_key, &host_line); - } + host_status = check_key_in_hostkeys(host_hostkeys, host_key, + &host_found); + /* * Also perform check for the ip address, skip the check if we are * localhost, looking for a certificate, or the hostname was an ip * address to begin with. */ - if (!want_cert && options.check_host_ip) { - Key *ip_key = key_new(host_key->type); - - ip_file = user_hostfile; - ip_status = check_host_in_hostfile(ip_file, ip, host_key, - ip_key, &ip_line); - if (ip_status == HOST_NEW) { - ip_file = system_hostfile; - ip_status = check_host_in_hostfile(ip_file, ip, - host_key, ip_key, &ip_line); - } + if (!want_cert && ip_hostkeys != NULL) { + ip_status = check_key_in_hostkeys(ip_hostkeys, host_key, + &ip_found); if (host_status == HOST_CHANGED && - (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key))) + (ip_status != HOST_CHANGED || + (ip_found != NULL && + !key_equal(ip_found->key, host_found->key)))) host_ip_differ = 1; - - key_free(ip_key); } else ip_status = host_status; - key_free(file_key); - switch (host_status) { case HOST_OK: /* The host is known and the key matches. */ debug("Host '%.200s' is known and matches the %s host %s.", host, type, want_cert ? "certificate" : "key"); - debug("Found %s in %s:%d", - want_cert ? "CA key" : "key", host_file, host_line); + debug("Found %s in %s:%lu", want_cert ? "CA key" : "key", + host_found->file, host_found->line); if (want_cert && !check_host_cert(hostname, host_key)) goto fail; if (options.check_host_ip && ip_status == HOST_NEW) { @@ -790,7 +831,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, } else if (options.strict_host_key_checking == 2) { char msg1[1024], msg2[1024]; - if (show_other_keys(host, host_key)) + if (show_other_keys(host_hostkeys, host_key)) snprintf(msg1, sizeof(msg1), "\nbut keys of different type are already" " known for this host."); @@ -831,8 +872,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, * local known_hosts file. */ if (options.check_host_ip && ip_status == HOST_NEW) { - snprintf(hostline, sizeof(hostline), "%s,%s", - host, ip); + snprintf(hostline, sizeof(hostline), "%s,%s", host, ip); hostp = hostline; if (options.hash_known_hosts) { /* Add hash of host and IP separately */ @@ -886,8 +926,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, * all hosts that one might visit. */ debug("Host certificate authority does not " - "match %s in %s:%d", CA_MARKER, - host_file, host_line); + "match %s in %s:%lu", CA_MARKER, + host_found->file, host_found->line); goto fail; } if (readonly == ROQUIET) @@ -909,13 +949,15 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time."); if (ip_status != HOST_NEW) - error("Offending key for IP in %s:%d", ip_file, ip_line); + error("Offending key for IP in %s:%lu", + ip_found->file, ip_found->line); } /* The host key has changed. */ warn_changed_key(host_key); error("Add correct host key in %.100s to get rid of this message.", user_hostfile); - error("Offending key in %s:%d", host_file, host_line); + error("Offending %s key in %s:%lu", key_type(host_found->key), + host_found->file, host_found->line); /* * If strict host key checking is in use, the user will have @@ -1000,13 +1042,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, snprintf(msg, sizeof(msg), "Warning: the %s host key for '%.200s' " "differs from the key for the IP address '%.128s'" - "\nOffending key for IP in %s:%d", - type, host, ip, ip_file, ip_line); + "\nOffending key for IP in %s:%lu", + type, host, ip, ip_found->file, ip_found->line); if (host_status == HOST_OK) { len = strlen(msg); snprintf(msg + len, sizeof(msg) - len, - "\nMatching host key in %s:%d", - host_file, host_line); + "\nMatching host key in %s:%lu", + host_found->file, host_found->line); } if (options.strict_host_key_checking == 1) { logit("%s", msg); @@ -1024,6 +1066,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, xfree(ip); xfree(host); + if (host_hostkeys != NULL) + free_hostkeys(host_hostkeys); + if (ip_hostkeys != NULL) + free_hostkeys(ip_hostkeys); return 0; fail: @@ -1043,6 +1089,10 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, key_free(raw_key); xfree(ip); xfree(host); + if (host_hostkeys != NULL) + free_hostkeys(host_hostkeys); + if (ip_hostkeys != NULL) + free_hostkeys(ip_hostkeys); return -1; } @@ -1052,6 +1102,11 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { struct stat st; int flags = 0; + char *fp; + + fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + debug("Server host key: %s %s", key_type(host_key), fp); + xfree(fp); /* XXX certs are not yet supported for DNS */ if (!key_is_cert(host_key) && options.verify_host_key_dns && @@ -1095,7 +1150,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) */ void ssh_login(Sensitive *sensitive, const char *orighost, - struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms) + struct sockaddr *hostaddr, u_short port, struct passwd *pw, int timeout_ms) { char *host, *cp; char *server_user, *local_user; @@ -1118,7 +1173,7 @@ ssh_login(Sensitive *sensitive, const char *orighost, /* key exchange */ /* authenticate user */ if (compat20) { - ssh_kex2(host, hostaddr); + ssh_kex2(host, hostaddr, port); ssh_userauth2(local_user, server_user, host, sensitive); } else { ssh_kex(host, hostaddr); @@ -1145,68 +1200,41 @@ ssh_put_password(char *password) xfree(padded); } -static int -show_key_from_file(const char *file, const char *host, int keytype) -{ - Key *found; - char *fp, *ra; - int line, ret; - - found = key_new(keytype); - if ((ret = lookup_key_in_hostfile_by_type(file, host, - keytype, found, &line))) { - fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); - ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART); - logit("WARNING: %s key found for host %s\n" - "in %s:%d\n" - "%s key fingerprint %s.\n%s\n", - key_type(found), host, file, line, - key_type(found), fp, ra); - xfree(ra); - xfree(fp); - } - key_free(found); - return (ret); -} - /* print all known host keys for a given host, but skip keys of given type */ static int -show_other_keys(const char *host, Key *key) +show_other_keys(struct hostkeys *hostkeys, Key *key) { - int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, -1}; - int i, found = 0; + int type[] = { KEY_RSA1, KEY_RSA, KEY_DSA, KEY_ECDSA, -1}; + int i, ret = 0; + char *fp, *ra; + const struct hostkey_entry *found; for (i = 0; type[i] != -1; i++) { if (type[i] == key->type) continue; - if (type[i] != KEY_RSA1 && - show_key_from_file(options.user_hostfile2, host, type[i])) { - found = 1; + if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) continue; - } - if (type[i] != KEY_RSA1 && - show_key_from_file(options.system_hostfile2, host, type[i])) { - found = 1; - continue; - } - if (show_key_from_file(options.user_hostfile, host, type[i])) { - found = 1; - continue; - } - if (show_key_from_file(options.system_hostfile, host, type[i])) { - found = 1; - continue; - } - debug2("no key of type %d for host %s", type[i], host); + fp = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_HEX); + ra = key_fingerprint(found->key, SSH_FP_MD5, SSH_FP_RANDOMART); + logit("WARNING: %s key found for host %s\n" + "in %s:%lu\n" + "%s key fingerprint %s.", + key_type(found->key), + found->host, found->file, found->line, + key_type(found->key), fp); + if (options.visual_host_key) + logit("%s", ra); + xfree(ra); + xfree(fp); + ret = 1; } - return (found); + return ret; } static void warn_changed_key(Key *host_key) { char *fp; - const char *type = key_type(host_key); fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); @@ -1215,9 +1243,9 @@ warn_changed_key(Key *host_key) error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); - error("It is also possible that the %s host key has just been changed.", type); + error("It is also possible that a host key has just been changed."); error("The fingerprint for the %s key sent by the remote host is\n%s.", - type, fp); + key_type(host_key), fp); error("Please contact your system administrator."); xfree(fp); @@ -1232,16 +1260,19 @@ ssh_local_cmd(const char *args) char *shell; pid_t pid; int status; + void (*osighand)(int); if (!options.permit_local_command || args == NULL || !*args) return (1); - if ((shell = getenv("SHELL")) == NULL) + if ((shell = getenv("SHELL")) == NULL || *shell == '\0') shell = _PATH_BSHELL; + osighand = signal(SIGCHLD, SIG_DFL); pid = fork(); if (pid == 0) { + signal(SIGPIPE, SIG_DFL); debug3("Executing %s -c \"%s\"", shell, args); execl(shell, shell, "-c", args, (char *)NULL); error("Couldn't execute %s -c \"%s\": %s", @@ -1252,6 +1283,7 @@ ssh_local_cmd(const char *args) while (waitpid(pid, &status, 0) == -1) if (errno != EINTR) fatal("Couldn't wait for child: %s", strerror(errno)); + signal(SIGCHLD, osighand); if (!WIFEXITED(status)) return (1); diff --git a/sshconnect.h b/sshconnect.h index c59a097f4eba..fd7f7f7c6145 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.25 2009/05/27 06:38:16 andreas Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.27 2010/11/29 23:45:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -34,16 +34,20 @@ struct Sensitive { int ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, int *, int, int, const char *); +void ssh_kill_proxy_command(void); -void -ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int); +void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short, + struct passwd *, int); void ssh_exchange_identification(int); int verify_host_key(char *, struct sockaddr *, Key *); +void get_hostfile_hostname_ipaddr(char *, struct sockaddr *, u_short, + char **, char **); + void ssh_kex(char *, struct sockaddr *); -void ssh_kex2(char *, struct sockaddr *); +void ssh_kex2(char *, struct sockaddr *, u_short); void ssh_userauth1(const char *, const char *, char *, Sensitive *); void ssh_userauth2(const char *, const char *, char *, Sensitive *); diff --git a/sshconnect2.c b/sshconnect2.c index 4c379ae5988c..3cb9b101cb88 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.183 2010/04/26 22:28:24 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.186 2010/11/29 23:45:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -69,6 +69,7 @@ #include "msg.h" #include "pathnames.h" #include "uidswap.h" +#include "hostfile.h" #include "schnorr.h" #include "jpake.h" @@ -101,8 +102,60 @@ verify_host_key_callback(Key *hostkey) return 0; } +static char * +order_hostkeyalgs(char *host, struct sockaddr *hostaddr, u_short port) +{ + char *oavail, *avail, *first, *last, *alg, *hostname, *ret; + size_t maxlen; + struct hostkeys *hostkeys; + int ktype; + + /* Find all hostkeys for this hostname */ + get_hostfile_hostname_ipaddr(host, hostaddr, port, &hostname, NULL); + hostkeys = init_hostkeys(); + load_hostkeys(hostkeys, hostname, options.user_hostfile2); + load_hostkeys(hostkeys, hostname, options.system_hostfile2); + load_hostkeys(hostkeys, hostname, options.user_hostfile); + load_hostkeys(hostkeys, hostname, options.system_hostfile); + + oavail = avail = xstrdup(KEX_DEFAULT_PK_ALG); + maxlen = strlen(avail) + 1; + first = xmalloc(maxlen); + last = xmalloc(maxlen); + *first = *last = '\0'; + +#define ALG_APPEND(to, from) \ + do { \ + if (*to != '\0') \ + strlcat(to, ",", maxlen); \ + strlcat(to, from, maxlen); \ + } while (0) + + while ((alg = strsep(&avail, ",")) && *alg != '\0') { + if ((ktype = key_type_from_name(alg)) == KEY_UNSPEC) + fatal("%s: unknown alg %s", __func__, alg); + if (lookup_key_in_hostkeys_by_type(hostkeys, + key_type_plain(ktype), NULL)) + ALG_APPEND(first, alg); + else + ALG_APPEND(last, alg); + } +#undef ALG_APPEND + xasprintf(&ret, "%s%s%s", first, *first == '\0' ? "" : ",", last); + if (*first != '\0') + debug3("%s: prefer hostkeyalgs: %s", __func__, first); + + xfree(first); + xfree(last); + xfree(hostname); + xfree(oavail); + free_hostkeys(hostkeys); + + return ret; +} + void -ssh_kex2(char *host, struct sockaddr *hostaddr) +ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) { Kex *kex; @@ -135,6 +188,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) if (options.hostkeyalgorithms != NULL) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = options.hostkeyalgorithms; + else { + /* Prefer algorithms that we already have keys for */ + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + order_hostkeyalgs(host, hostaddr, port); + } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; if (options.rekey_limit) packet_set_rekey_limit((u_int32_t)options.rekey_limit); @@ -145,6 +205,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; + kex->kex[KEX_ECDH_SHA2] = kexecdh_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; diff --git a/sshd.0 b/sshd.0 index a5d40c4d83bc..bb01b716439d 100644 --- a/sshd.0 +++ b/sshd.0 @@ -78,10 +78,10 @@ DESCRIPTION be given if sshd is not run as root (as the normal host key files are normally not readable by anyone but root). The default is /etc/ssh/ssh_host_key for protocol version 1, and - /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for - protocol version 2. It is possible to have multiple host key - files for the different protocol versions and host key - algorithms. + /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key and + /etc/ssh/ssh_host_rsa_key for protocol version 2. It is possible + to have multiple host key files for the different protocol + versions and host key algorithms. -i Specifies that sshd is being run from inetd(8). sshd is normally not run from inetd because it needs to generate the server key @@ -143,8 +143,8 @@ 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 both RSA and DSA keys; protocol 1 - only supports RSA keys. For both protocols, each host has a host- + in sshd_config(5). Protocol 2 supports DSA, ECDSA 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. Forward security for protocol 1 is provided through an additional server @@ -273,13 +273,15 @@ AUTHORIZED_KEYS FILE FORMAT exponent, modulus, and comment fields give the RSA key for protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). For protocol version 2 the - keytype is ``ssh-dss'' or ``ssh-rsa''. + keytype is ``ecdsa-sha2-nistp256'', ``ecdsa-sha2-nistp384'', + ``ecdsa-sha2-nistp521'', ``ssh-dss'' or ``ssh-rsa''. Note that lines in this file are usually several hundred bytes long (because of the size of the public key encoding) up to a limit of 8 kilobytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16 kilobits. You don't want to type them in; instead, copy the - identity.pub, id_dsa.pub, or the id_rsa.pub file and edit it. + identity.pub, id_dsa.pub, id_ecdsa.pub, or the id_rsa.pub file and edit + it. sshd enforces a minimum RSA key modulus size for protocol 1 and protocol 2 keys of 768 bits. @@ -504,11 +506,11 @@ FILES for the user, and not accessible by others. ~/.ssh/authorized_keys - Lists the public keys (RSA/DSA) that can be used for logging in - as this user. The format of this file is described above. The - content of the file is not highly sensitive, but the recommended - permissions are read/write for the user, and not accessible by - others. + Lists the public keys (DSA/ECDSA/RSA) that can be used for + logging in as this user. The format of this file is described + above. The content of the file is not highly sensitive, but the + recommended permissions are read/write for the user, and not + accessible by others. If this file, the ~/.ssh directory, or the user's home directory are writable by other users, then the file could be modified or @@ -565,6 +567,7 @@ FILES /etc/ssh/ssh_host_key /etc/ssh/ssh_host_dsa_key + /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys. These files should only be owned by root, readable only by root, @@ -573,6 +576,7 @@ FILES /etc/ssh/ssh_host_key.pub /etc/ssh/ssh_host_dsa_key.pub + /etc/ssh/ssh_host_ecdsa_key.pub /etc/ssh/ssh_host_rsa_key.pub These three files contain the public parts of the host keys. These files should be world-readable but writable only by root. @@ -627,4 +631,4 @@ CAVEATS System security is not improved unless rshd, rlogind, and rexecd are disabled (thus completely disabling rlogin and rsh into the machine). -OpenBSD 4.8 August 4, 2010 OpenBSD 4.8 +OpenBSD 4.8 October 28, 2010 OpenBSD 4.8 diff --git a/sshd.8 b/sshd.8 index d3685b92b35d..5503b13311e5 100644 --- a/sshd.8 +++ b/sshd.8 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,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.257 2010/08/04 05:37:01 djm Exp $ -.Dd $Mdocdate: August 4 2010 $ +.\" $OpenBSD: sshd.8,v 1.260 2010/10/28 18:33:28 jmc Exp $ +.Dd $Mdocdate: October 28 2010 $ .Dt SSHD 8 .Os .Sh NAME @@ -170,9 +169,10 @@ host key files are normally not readable by anyone but root). The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and -.Pa /etc/ssh/ssh_host_rsa_key +.Pa /etc/ssh/ssh_host_dsa_key , +.Pa /etc/ssh/ssh_host_ecdsa_key and -.Pa /etc/ssh/ssh_host_dsa_key +.Pa /etc/ssh/ssh_host_rsa_key for protocol version 2. It is possible to have multiple host key files for the different protocol versions and host key algorithms. @@ -275,7 +275,7 @@ though this can be changed via the .Cm Protocol option in .Xr sshd_config 5 . -Protocol 2 supports both RSA and DSA keys; +Protocol 2 supports DSA, ECDSA and RSA keys; protocol 1 only supports RSA keys. For both protocols, each host has a host-specific key, @@ -483,6 +483,9 @@ protocol version 1; the comment field is not used for anything (but may be convenient for the user to identify the key). For protocol version 2 the keytype is +.Dq ecdsa-sha2-nistp256 , +.Dq ecdsa-sha2-nistp384 , +.Dq ecdsa-sha2-nistp521 , .Dq ssh-dss or .Dq ssh-rsa . @@ -494,6 +497,7 @@ keys up to 16 kilobits. You don't want to type them in; instead, copy the .Pa identity.pub , .Pa id_dsa.pub , +.Pa id_ecdsa.pub , or the .Pa id_rsa.pub file and edit it. @@ -751,7 +755,7 @@ AAAA1234.....= .Ed .Sh FILES .Bl -tag -width Ds -compact -.It ~/.hushlogin +.It Pa ~/.hushlogin This file is used to suppress printing the last login time and .Pa /etc/motd , if @@ -763,7 +767,7 @@ are enabled. It does not suppress printing of the banner specified by .Cm Banner . .Pp -.It ~/.rhosts +.It Pa ~/.rhosts This file is used for host-based authentication (see .Xr ssh 1 for more information). @@ -778,21 +782,22 @@ The recommended permission for most machines is read/write for the user, and not accessible by others. .Pp -.It ~/.shosts +.It Pa ~/.shosts This file is used in exactly the same way as .Pa .rhosts , but allows host-based authentication without permitting login with rlogin/rsh. .Pp -.It ~/.ssh/ +.It Pa ~/.ssh/ This directory is the default location for all user-specific configuration and authentication information. There is no general requirement to keep the entire contents of this directory secret, but the recommended permissions are read/write/execute for the user, and not accessible by others. .Pp -.It ~/.ssh/authorized_keys -Lists the public keys (RSA/DSA) that can be used for logging in as this user. +.It Pa ~/.ssh/authorized_keys +Lists the public keys (DSA/ECDSA/RSA) that can be used for logging in +as this user. The format of this file is described above. The content of the file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others. @@ -809,7 +814,7 @@ will not allow it to be used unless the option has been set to .Dq no . .Pp -.It ~/.ssh/environment +.It Pa ~/.ssh/environment This file is read into the environment at login (if it exists). It can only contain empty lines, comment lines (that start with .Ql # ) , @@ -821,40 +826,40 @@ controlled via the .Cm PermitUserEnvironment option. .Pp -.It ~/.ssh/known_hosts +.It Pa ~/.ssh/known_hosts Contains a list of host keys for all hosts the user has logged into that are not already in the systemwide list of known host keys. The format of this file is described above. This file should be writable only by root/the owner and can, but need not be, world-readable. .Pp -.It ~/.ssh/rc +.It Pa ~/.ssh/rc Contains initialization routines to be run before the user's home directory becomes accessible. This file should be writable only by the user, and need not be readable by anyone else. .Pp -.It /etc/hosts.allow -.It /etc/hosts.deny +.It Pa /etc/hosts.allow +.It Pa /etc/hosts.deny Access controls that should be enforced by tcp-wrappers are defined here. Further details are described in .Xr hosts_access 5 . .Pp -.It /etc/hosts.equiv +.It Pa /etc/hosts.equiv This file is for host-based authentication (see .Xr ssh 1 ) . It should only be writable by root. .Pp -.It /etc/moduli +.It Pa /etc/moduli Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange". The file format is described in .Xr moduli 5 . .Pp -.It /etc/motd +.It Pa /etc/motd See .Xr motd 5 . .Pp -.It /etc/nologin +.It Pa /etc/nologin If this file exists, .Nm refuses to let anyone except root log in. @@ -863,15 +868,16 @@ are displayed to anyone trying to log in, and non-root connections are refused. The file should be world-readable. .Pp -.It /etc/shosts.equiv +.It Pa /etc/shosts.equiv This file is used in exactly the same way as .Pa hosts.equiv , but allows host-based authentication without permitting login with rlogin/rsh. .Pp -.It /etc/ssh/ssh_host_key -.It /etc/ssh/ssh_host_dsa_key -.It /etc/ssh/ssh_host_rsa_key +.It Pa /etc/ssh/ssh_host_key +.It Pa /etc/ssh/ssh_host_dsa_key +.It Pa /etc/ssh/ssh_host_ecdsa_key +.It Pa /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys. These files should only be owned by root, readable only by root, and not accessible to others. @@ -879,9 +885,10 @@ Note that .Nm does not start if these files are group/world-accessible. .Pp -.It /etc/ssh/ssh_host_key.pub -.It /etc/ssh/ssh_host_dsa_key.pub -.It /etc/ssh/ssh_host_rsa_key.pub +.It Pa /etc/ssh/ssh_host_key.pub +.It Pa /etc/ssh/ssh_host_dsa_key.pub +.It Pa /etc/ssh/ssh_host_ecdsa_key.pub +.It Pa /etc/ssh/ssh_host_rsa_key.pub These three files contain the public parts of the host keys. These files should be world-readable but writable only by root. @@ -892,7 +899,7 @@ the user so their contents can be copied to known hosts files. These files are created using .Xr ssh-keygen 1 . .Pp -.It /etc/ssh/ssh_known_hosts +.It Pa /etc/ssh/ssh_known_hosts Systemwide list of known host keys. This file should be prepared by the system administrator to contain the public host keys of all machines in the @@ -901,20 +908,20 @@ The format of this file is described above. This file should be writable only by root/the owner and should be world-readable. .Pp -.It /etc/ssh/sshd_config +.It Pa /etc/ssh/sshd_config Contains configuration data for .Nm sshd . The file format and configuration options are described in .Xr sshd_config 5 . .Pp -.It /etc/ssh/sshrc +.It Pa /etc/ssh/sshrc Similar to .Pa ~/.ssh/rc , it can be used to specify machine-specific login-time initializations globally. This file should be writable only by root, and should be world-readable. .Pp -.It /var/empty +.It Pa /var/empty .Xr chroot 2 directory used by .Nm @@ -922,7 +929,7 @@ during privilege separation in the pre-authentication phase. The directory should not contain any files and must be owned by root and not group or world-writable. .Pp -.It /var/run/sshd.pid +.It Pa /var/run/sshd.pid Contains the process ID of the .Nm listening for connections (if there are several daemons running diff --git a/sshd.c b/sshd.c index a7d3ee5c4164..cb45cecbd8f1 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.375 2010/04/16 01:47:26 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.381 2011/01/11 06:13:10 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -733,6 +733,7 @@ list_hostkey_types(void) switch (key->type) { case KEY_RSA: case KEY_DSA: + case KEY_ECDSA: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); @@ -748,6 +749,7 @@ list_hostkey_types(void) case KEY_DSA_CERT_V00: case KEY_RSA_CERT: case KEY_DSA_CERT: + case KEY_ECDSA_CERT: if (buffer_len(&b) > 0) buffer_append(&b, ",", 1); p = key_ssh_name(key); @@ -774,6 +776,7 @@ get_hostkey_by_type(int type, int need_private) case KEY_DSA_CERT_V00: case KEY_RSA_CERT: case KEY_DSA_CERT: + case KEY_ECDSA_CERT: key = sensitive_data.host_certificates[i]; break; default: @@ -1464,7 +1467,7 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); - SSLeay_add_all_algorithms(); + OpenSSL_add_all_algorithms(); /* * Force logging to stderr until we have loaded the private host @@ -1576,6 +1579,7 @@ main(int ac, char **av) break; case KEY_RSA: case KEY_DSA: + case KEY_ECDSA: sensitive_data.have_ssh2_key = 1; break; } @@ -2023,7 +2027,8 @@ main(int ac, char **av) /* The connection has been terminated. */ packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); - verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes); + verbose("Transferred: sent %llu, received %llu bytes", + (unsigned long long)obytes, (unsigned long long)ibytes); verbose("Closing connection to %.500s port %d", remote_ip, remote_port); @@ -2293,6 +2298,8 @@ do_ssh2_kex(void) myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com"; } + if (options.kex_algorithms != NULL) + myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); @@ -2302,6 +2309,7 @@ do_ssh2_kex(void) kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; + kex->kex[KEX_ECDH_SHA2] = kexecdh_server; kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; diff --git a/sshd_config b/sshd_config index 72fbae37be65..4534841c101b 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.81 2009/10/08 14:03:41 markus Exp $ +# $OpenBSD: sshd_config,v 1.82 2010/09/06 17:10:19 naddy Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -23,6 +23,7 @@ # HostKeys for protocol version 2 #HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key +#HostKey /etc/ssh/ssh_host_ecdsa_key # Lifetime and size of ephemeral version 1 server key #KeyRegenerationInterval 1h diff --git a/sshd_config.0 b/sshd_config.0 index a49953851662..669d29a065c8 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -272,11 +272,12 @@ DESCRIPTION HostKey Specifies a file containing a private host key used by SSH. The default is /etc/ssh/ssh_host_key for protocol version 1, and - /etc/ssh/ssh_host_rsa_key and /etc/ssh/ssh_host_dsa_key for - protocol version 2. Note that sshd(8) will refuse to use a file - if it is group/world-accessible. It is possible to have multiple - host key files. ``rsa1'' keys are used for version 1 and ``dsa'' - or ``rsa'' are used for version 2 of the SSH protocol. + /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_ecdsa_key and + /etc/ssh/ssh_host_rsa_key for protocol version 2. Note that + sshd(8) will refuse to use a file if it is group/world- + accessible. It is possible to have multiple host key files. + ``rsa1'' keys are used for version 1 and ``dsa'', ``ecdsa'' or + ``rsa'' are used for version 2 of the SSH protocol. IgnoreRhosts Specifies that .rhosts and .shosts files will not be used in @@ -290,6 +291,20 @@ DESCRIPTION ~/.ssh/known_hosts during RhostsRSAAuthentication or HostbasedAuthentication. The default is ``no''. + IPQoS Specifies the IPv4 type-of-service or DSCP class for the + connection. Accepted values are ``af11'', ``af12'', ``af13'', + ``af14'', ``af22'', ``af23'', ``af31'', ``af32'', ``af33'', + ``af41'', ``af42'', ``af43'', ``cs0'', ``cs1'', ``cs2'', ``cs3'', + ``cs4'', ``cs5'', ``cs6'', ``cs7'', ``ef'', ``lowdelay'', + ``throughput'', ``reliability'', or a numeric value. This option + may take one or two arguments, separated by whitespace. If one + argument is specified, it is used as the packet class + unconditionally. If two values are specified, the first is + automatically selected for interactive sessions and the second + for non-interactive sessions. The default is ``lowdelay'' for + interactive sessions and ``throughput'' for non-interactive + sessions. + KerberosAuthentication Specifies whether the password provided by the user for PasswordAuthentication will be validated through the Kerberos @@ -311,6 +326,14 @@ DESCRIPTION Specifies whether to automatically destroy the user's ticket cache file on logout. The default is ``yes''. + KexAlgorithms + Specifies the available KEX (Key Exchange) algorithms. Multiple + algorithms must be comma-separated. The default is + ``ecdh-sha2-nistp256'', ``ecdh-sha2-nistp384'', + ``ecdh-sha2-nistp521'', ``diffie-hellman-group-exchange-sha256'', + ``diffie-hellman-group-exchange-sha1'', + ``diffie-hellman-group14-sha1'', ``diffie-hellman-group1-sha1''. + KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). The @@ -323,8 +346,8 @@ DESCRIPTION Specifies the local addresses sshd(8) should listen on. The following forms may be used: - ListenAddress host | IPv4_addr | IPv6_addr - ListenAddress host | IPv4_addr:port + ListenAddress host|IPv4_addr|IPv6_addr + ListenAddress host|IPv4_addr:port ListenAddress [host|IPv6_addr]:port If port is not specified, sshd will listen on the address and all @@ -424,7 +447,7 @@ DESCRIPTION PermitOpen host:port PermitOpen IPv4_addr:port - PermitOpen [ IPv6_addr ]:port + PermitOpen [IPv6_addr]:port Multiple forwards may be specified by separating them with whitespace. An argument of ``any'' can be used to remove all @@ -650,9 +673,9 @@ DESCRIPTION TIME FORMATS sshd(8) command-line arguments and configuration file options that - specify time may be expressed using a sequence of the form: time - [qualifier], where time is a positive integer value and qualifier is one - of the following: + specify time may be expressed using a sequence of the form: + time[qualifier], where time is a positive integer value and qualifier is + one of the following: seconds s | S seconds @@ -687,4 +710,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 4.8 June 30, 2010 OpenBSD 4.8 +OpenBSD 4.8 December 8, 2010 OpenBSD 4.8 diff --git a/sshd_config.5 b/sshd_config.5 index 596a728f80bd..c3d6df30a60f 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,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.125 2010/06/30 07:28:34 jmc Exp $ -.Dd $Mdocdate: June 30 2010 $ +.\" $OpenBSD: sshd_config.5,v 1.131 2010/12/08 04:02:47 djm Exp $ +.Dd $Mdocdate: December 8 2010 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -470,9 +469,10 @@ used by SSH. The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and -.Pa /etc/ssh/ssh_host_rsa_key +.Pa /etc/ssh/ssh_host_dsa_key , +.Pa /etc/ssh/ssh_host_ecdsa_key and -.Pa /etc/ssh/ssh_host_dsa_key +.Pa /etc/ssh/ssh_host_rsa_key for protocol version 2. Note that .Xr sshd 8 @@ -480,7 +480,8 @@ will refuse to use a file if it is group/world-accessible. It is possible to have multiple host key files. .Dq rsa1 keys are used for version 1 and -.Dq dsa +.Dq dsa , +.Dq ecdsa or .Dq rsa are used for version 2 of the SSH protocol. @@ -511,6 +512,43 @@ or .Cm HostbasedAuthentication . The default is .Dq no . +.It Cm IPQoS +Specifies the IPv4 type-of-service or DSCP class for the connection. +Accepted values are +.Dq af11 , +.Dq af12 , +.Dq af13 , +.Dq af14 , +.Dq af22 , +.Dq af23 , +.Dq af31 , +.Dq af32 , +.Dq af33 , +.Dq af41 , +.Dq af42 , +.Dq af43 , +.Dq cs0 , +.Dq cs1 , +.Dq cs2 , +.Dq cs3 , +.Dq cs4 , +.Dq cs5 , +.Dq cs6 , +.Dq cs7 , +.Dq ef , +.Dq lowdelay , +.Dq throughput , +.Dq reliability , +or a numeric value. +This option may take one or two arguments, separated by whitespace. +If one argument is specified, it is used as the packet class unconditionally. +If two values are specified, the first is automatically selected for +interactive sessions and the second for non-interactive sessions. +The default is +.Dq lowdelay +for interactive sessions and +.Dq throughput +for non-interactive sessions. .It Cm KerberosAuthentication Specifies whether the password provided by the user for .Cm PasswordAuthentication @@ -536,6 +574,17 @@ Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Dq yes . +.It Cm KexAlgorithms +Specifies the available KEX (Key Exchange) algorithms. +Multiple algorithms must be comma-separated. +The default is +.Dq ecdh-sha2-nistp256 , +.Dq ecdh-sha2-nistp384 , +.Dq ecdh-sha2-nistp521 , +.Dq diffie-hellman-group-exchange-sha256 , +.Dq diffie-hellman-group-exchange-sha1 , +.Dq diffie-hellman-group14-sha1 , +.Dq diffie-hellman-group1-sha1 . .It Cm KeyRegenerationInterval In protocol version 1, the ephemeral server key is automatically regenerated after this many seconds (if it has been used). diff --git a/sshlogin.c b/sshlogin.c index 33bd652fb0b5..54629f747715 100644 --- a/sshlogin.c +++ b/sshlogin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshlogin.c,v 1.26 2007/09/11 15:47:17 gilles Exp $ */ +/* $OpenBSD: sshlogin.c,v 1.27 2011/01/11 06:06:09 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland diff --git a/uuencode.c b/uuencode.c index b9e57e9934b1..09d80d2fcc14 100644 --- a/uuencode.c +++ b/uuencode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uuencode.c,v 1.25 2009/03/05 11:30:50 djm Exp $ */ +/* $OpenBSD: uuencode.c,v 1.26 2010/08/31 11:54:45 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -72,7 +72,7 @@ uudecode(const char *src, u_char *target, size_t targsize) } void -dump_base64(FILE *fp, u_char *data, u_int len) +dump_base64(FILE *fp, const u_char *data, u_int len) { char *buf; int i, n; diff --git a/uuencode.h b/uuencode.h index fec55b491294..4d9888126cdc 100644 --- a/uuencode.h +++ b/uuencode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uuencode.h,v 1.13 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: uuencode.h,v 1.14 2010/08/31 11:54:45 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -26,4 +26,4 @@ int uuencode(const u_char *, u_int, char *, size_t); int uudecode(const char *, u_char *, size_t); -void dump_base64(FILE *, u_char *, u_int); +void dump_base64(FILE *, const u_char *, u_int); diff --git a/version.h b/version.h index 67d78dcc3054..202e0dec25e8 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.59 2010/08/08 16:26:42 djm Exp $ */ +/* $OpenBSD: version.h,v 1.60 2011/01/22 09:18:53 djm Exp $ */ -#define SSH_VERSION "OpenSSH_5.6" +#define SSH_VERSION "OpenSSH_5.7" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE