diff options
129 files changed, 5768 insertions, 4254 deletions
diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog index 6a3f64a..7fdf1ec 100644 --- a/crypto/openssh/ChangeLog +++ b/crypto/openssh/ChangeLog @@ -1,3 +1,742 @@ +20110403 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Prepare for 5.8p2 release. + - Release 5.8p2 + +20110329 + - (djm) [entropy.c] closefrom() before running ssh-rand-helper; leftover fds + noticed by tmraz AT redhat.com + +20110221 + - (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the + Cygwin-specific service installer script ssh-host-config. The actual + functionality is the same, the revisited version is just more + exact when it comes to check for problems which disallow to run + certain aspects of the script. So, part of this script and the also + rearranged service helper script library "csih" is to check if all + the tools required to run the script are available on the system. + The new script also is more thorough to inform the user why the + script failed. Patch from vinschen at redhat com. + +20110206 + - (dtucker) [openbsd-compat/port-linux.c] Bug #1851: fix syntax error in + selinux code. Patch from Leonardo Chiquitto + - (dtucker) [contrib/cygwin/ssh-{host,user}-config] Add ECDSA key + generation and simplify. Patch from Corinna Vinschen. + +20110204 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/31 21:42:15 + [PROTOCOL.mux] + cut'n'pasto; from bert.wesarg AT googlemail.com + - djm@cvs.openbsd.org 2011/02/04 00:44:21 + [key.c] + fix uninitialised nonce variable; reported by Mateusz Kocielski + - djm@cvs.openbsd.org 2011/02/04 00:44:43 + [version.h] + openssh-5.8 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] update versions in docs and spec files. + - Release OpenSSH 5.8p1 + +20110128 + - (djm) [openbsd-compat/port-linux.c] Check whether SELinux is enabled + before attempting setfscreatecon(). Check whether matchpathcon() + succeeded before using its result. Patch from cjwatson AT debian.org; + bz#1851 + +20110125 + - (djm) [configure.ac Makefile.in ssh.c openbsd-compat/port-linux.c + openbsd-compat/port-linux.h] Move SELinux-specific code from ssh.c to + port-linux.c to avoid compilation errors. Add -lselinux to ssh when + building with SELinux support to avoid linking failure; report from + amk AT spamfence.net; ok dtucker + +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 + <mattieu.b@gmail.com> + 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 +1256,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. - -20100428 - - (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 <sys/queue.h> 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 "-<switch>" "<value>" rather than "-<switch><value>" - 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 <inttypes.h> 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/crypto/openssh/LICENCE b/crypto/openssh/LICENCE index 3964b1d..120d6fd 100644 --- a/crypto/openssh/LICENCE +++ b/crypto/openssh/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/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL index 5fc31ea..c281960 100644 --- a/crypto/openssh/PROTOCOL +++ b/crypto/openssh/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/crypto/openssh/PROTOCOL.agent b/crypto/openssh/PROTOCOL.agent index b34fcd3..de94d037 100644 --- a/crypto/openssh/PROTOCOL.agent +++ b/crypto/openssh/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/crypto/openssh/PROTOCOL.certkeys b/crypto/openssh/PROTOCOL.certkeys index 1d1be13..2f97649 100644 --- a/crypto/openssh/PROTOCOL.certkeys +++ b/crypto/openssh/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/crypto/openssh/PROTOCOL.mux b/crypto/openssh/PROTOCOL.mux index 1d8c463..2a5817b 100644 --- a/crypto/openssh/PROTOCOL.mux +++ b/crypto/openssh/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 -A client may request the master to establish a port forward: +Note: currently unimplemented (server will always reply with MUX_S_FAILURE). + +A client may request the master to close 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.4 2011/01/31 21:42:15 djm Exp $ diff --git a/crypto/openssh/README b/crypto/openssh/README index 4eaa545..960abf9 100644 --- a/crypto/openssh/README +++ b/crypto/openssh/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.8p2 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.4.2 2011/05/03 00:04:21 djm Exp $ diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c index a6b2d12..601b3c3 100644 --- a/crypto/openssh/atomicio.c +++ b/crypto/openssh/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/crypto/openssh/atomicio.h b/crypto/openssh/atomicio.h index 2fcd25d..0d728ac 100644 --- a/crypto/openssh/atomicio.h +++ b/crypto/openssh/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/crypto/openssh/audit-bsm.c b/crypto/openssh/audit-bsm.c index 2c417bc..f196d4f 100644 --- a/crypto/openssh/audit-bsm.c +++ b/crypto/openssh/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/crypto/openssh/audit-linux.c b/crypto/openssh/audit-linux.c new file mode 100644 index 0000000..20174d7 --- /dev/null +++ b/crypto/openssh/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 <jchadima@redhat.com> + */ + +#include "includes.h" +#if defined(USE_LINUX_AUDIT) +#include <libaudit.h> +#include <unistd.h> +#include <string.h> + +#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/crypto/openssh/audit.c b/crypto/openssh/audit.c index dbea34c..ced57fa 100644 --- a/crypto/openssh/audit.c +++ b/crypto/openssh/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/crypto/openssh/audit.h b/crypto/openssh/audit.h index 695f723..92ede5b 100644 --- a/crypto/openssh/audit.h +++ b/crypto/openssh/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/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c index a704024..eae45cf 100644 --- a/crypto/openssh/auth-options.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c index 56702d1..4edaab0 100644 --- a/crypto/openssh/auth-rsa.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/auth.c b/crypto/openssh/auth.c index c50db1e..23c39e5 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/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. * @@ -380,16 +380,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) && @@ -402,16 +401,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; } @@ -519,7 +525,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/crypto/openssh/auth1.c b/crypto/openssh/auth1.c index bf442db..cc85aec 100644 --- a/crypto/openssh/auth1.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi>, 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/crypto/openssh/auth2-jpake.c b/crypto/openssh/auth2-jpake.c index 5de5506..a460e82 100644 --- a/crypto/openssh/auth2-jpake.c +++ b/crypto/openssh/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/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c index 35cf79c..7d21413 100644 --- a/crypto/openssh/auth2-pubkey.c +++ b/crypto/openssh/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/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 50fb339..827f034 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/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. * @@ -184,7 +184,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) @@ -230,9 +230,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/crypto/openssh/authfd.c b/crypto/openssh/authfd.c index 739722f..c11c3f5 100644 --- a/crypto/openssh/authfd.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/authfile.c b/crypto/openssh/authfile.c index 2bd8878..f2aec26 100644 --- a/crypto/openssh/authfile.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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,156 +156,222 @@ 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; } -int -key_save_private(Key *key, const char *filename, const char *passphrase, +/* 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_save_private_rsa1(key, filename, passphrase, - comment); + return key_private_rsa1_to_blob(key, blob, passphrase, comment); case KEY_DSA: + case KEY_ECDSA: case KEY_RSA: - return key_save_private_pem(key, filename, passphrase, - comment); + return key_private_pem_to_blob(key, blob, passphrase, comment); default: - break; + error("%s: cannot save key type %d", __func__, key->type); + return 0; } - error("key_save_private: cannot save key type %d", key->type); - return 0; +} + +int +key_save_private(Key *key, const char *filename, const char *passphrase, + const char *comment) +{ + 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; } /* - * Loads the public part of the ssh v1 key file. Returns NULL if an error was - * encountered (the file does not exist or is not readable), and the key - * otherwise. + * Parse the public, unencrypted portion of a RSA1 key. */ - static Key * -key_load_public_rsa1(int fd, const char *filename, char **commentp) +key_parse_public_rsa1(Buffer *blob, char **commentp) { - Buffer buffer; Key *pub; - struct stat st; - char *cp; - u_int i; + + /* 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; + } + + /* + * 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("fstat for key file %.200s failed: %.100s", - filename, strerror(errno)); - return NULL; + 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("key file %.200s too large", filename); - return NULL; + 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(&buffer); - cp = buffer_append_space(&buffer, len); + buffer_init(blob); + cp = buffer_append_space(blob, len); if (atomicio(read, fd, cp, len) != len) { - debug("Read from key file %.200s failed: %.100s", filename, + debug("%s: read from key file %.200s%sfailed: %.100s", __func__, + filename == NULL ? "" : filename, + filename == NULL ? "" : " ", strerror(errno)); - buffer_free(&buffer); - return NULL; + buffer_clear(blob); + close(fd); + return 0; } + return 1; +} - /* 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); +/* + * Loads the public part of the ssh v1 key file. Returns NULL if an error was + * 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; + + buffer_init(&buffer); + if (!key_load_file(fd, filename, &buffer)) { 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 = "<no key>"; + 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/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c index 854fd51..00208ca 100644 --- a/crypto/openssh/bufaux.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/bufec.c b/crypto/openssh/bufec.c new file mode 100644 index 0000000..3dcb494 --- /dev/null +++ b/crypto/openssh/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 <djm@mindrot.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef OPENSSL_HAS_ECC + +#include <sys/types.h> + +#include <openssl/bn.h> +#include <openssl/ec.h> + +#include <string.h> +#include <stdarg.h> + +#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/crypto/openssh/buffer.h b/crypto/openssh/buffer.h index 4ef4f80..e2a9dd1 100644 --- a/crypto/openssh/buffer.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -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 <openssl/ec.h> + +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/crypto/openssh/canohost.c b/crypto/openssh/canohost.c index ef94d91..dabd8a3 100644 --- a/crypto/openssh/canohost.c +++ b/crypto/openssh/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/crypto/openssh/channels.c b/crypto/openssh/channels.c index 1cd5004..6abe2d0 100644 --- a/crypto/openssh/channels.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/cipher-3des1.c b/crypto/openssh/cipher-3des1.c index 17a13a1..b7aa588 100644 --- a/crypto/openssh/cipher-3des1.c +++ b/crypto/openssh/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/crypto/openssh/cipher-acss.c b/crypto/openssh/cipher-acss.c index cb0bf73..e755f92 100644 --- a/crypto/openssh/cipher-acss.c +++ b/crypto/openssh/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/crypto/openssh/cipher-aes.c b/crypto/openssh/cipher-aes.c index 3ea5949..bfda6d2 100644 --- a/crypto/openssh/cipher-aes.c +++ b/crypto/openssh/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/crypto/openssh/cipher-bf1.c b/crypto/openssh/cipher-bf1.c index e0e33b4..309509d 100644 --- a/crypto/openssh/cipher-bf1.c +++ b/crypto/openssh/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/crypto/openssh/cipher-ctr.c b/crypto/openssh/cipher-ctr.c index 3b86cc1..04975b4 100644 --- a/crypto/openssh/cipher-ctr.c +++ b/crypto/openssh/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 <markus@openbsd.org> * @@ -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/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c index de79793..f6c1444 100644 --- a/crypto/openssh/clientloop.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/compress.c b/crypto/openssh/compress.c index c058d22..24778e5 100644 --- a/crypto/openssh/compress.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -17,12 +17,13 @@ #include <sys/types.h> #include <stdarg.h> -#include <zlib.h> #include "log.h" #include "buffer.h" #include "compress.h" +#include <zlib.h> + z_stream incoming_stream; z_stream outgoing_stream; static int compress_init_send_called = 0; diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index c89920b..de529cb 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -1,6 +1,9 @@ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + /* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address */ /* #undef AIX_GETNAMEINFO_HACK */ @@ -81,9 +84,6 @@ /* Define if you want to specify the path to your lastlog file */ /* #undef CONF_LASTLOG_FILE */ -/* Define if you want to specify the path to your utmpx file */ -/* #undef CONF_UTMPX_FILE */ - /* Define if you want to specify the path to your utmp file */ /* #undef CONF_UTMP_FILE */ @@ -129,6 +129,9 @@ /* Builtin PRNG command timeout */ #define ENTROPY_TIMEOUT_MSEC 200 +/* File names may not contain backslash characters */ +/* #undef FILESYSTEM_NO_BACKSLASH */ + /* fsid_t has member val */ /* #undef FSID_HAS_VAL */ @@ -147,6 +150,9 @@ /* Define if your system glob() function has gl_matchc options in glob_t */ #define GLOB_HAS_GL_MATCHC 1 +/* 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 */ @@ -207,6 +213,9 @@ /* Define to 1 if you have the `bindresvport_sa' function. */ #define HAVE_BINDRESVPORT_SA 1 +/* Define to 1 if you have the `BN_is_prime_ex' function. */ +#define HAVE_BN_IS_PRIME_EX 1 + /* Define to 1 if you have the <bsm/audit.h> header file. */ /* #undef HAVE_BSM_AUDIT_H */ @@ -315,6 +324,9 @@ /* Define to 1 if you have the `dirname' function. */ #define HAVE_DIRNAME 1 +/* Define to 1 if you have the `DSA_generate_parameters_ex' function. */ +#define HAVE_DSA_GENERATE_PARAMETERS_EX 1 + /* Define to 1 if you have the <endian.h> header file. */ /* #undef HAVE_ENDIAN_H */ @@ -537,9 +549,15 @@ /* Define to 1 if the system has the type `in_port_t'. */ #define HAVE_IN_PORT_T 1 +/* Define if you have isblank(3C). */ +#define HAVE_ISBLANK 1 + /* Define to 1 if you have the <lastlog.h> header file. */ /* #undef HAVE_LASTLOG_H */ +/* Define to 1 if you have the <libaudit.h> header file. */ +/* #undef HAVE_LIBAUDIT_H */ + /* Define to 1 if you have the `bsm' library (-lbsm). */ /* #undef HAVE_LIBBSM */ @@ -742,6 +760,12 @@ /* Define to 1 if you have the `rresvport_af' function. */ #define HAVE_RRESVPORT_AF 1 +/* Define to 1 if you have the `RSA_generate_key_ex' function. */ +#define HAVE_RSA_GENERATE_KEY_EX 1 + +/* Define to 1 if you have the `RSA_get_default_method' function. */ +#define HAVE_RSA_GET_DEFAULT_METHOD 1 + /* define if you have sa_family_t data type */ #define HAVE_SA_FAMILY_T 1 @@ -928,13 +952,13 @@ /* define if you have struct sockaddr_in6 data type */ #define HAVE_STRUCT_SOCKADDR_IN6 1 -/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */ +/* Define to 1 if `sin6_scope_id' is a member of `struct sockaddr_in6'. */ #define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* define if you have struct sockaddr_storage data type */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 -/* Define to 1 if `st_blksize' is member of `struct stat'. */ +/* Define to 1 if `st_blksize' is a member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 /* Define to 1 if the system has the type `struct timespec'. */ @@ -1048,6 +1072,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 <tmpdir.h> header file. */ /* #undef HAVE_TMPDIR_H */ @@ -1263,6 +1290,9 @@ /* Define if EVP_DigestUpdate returns void */ /* #undef OPENSSL_EVP_DIGESTUPDATE_VOID */ +/* libcrypto includes complete ECC support */ +#define OPENSSL_HAS_ECC 1 + /* libcrypto is missing AES 192 and 256 bit functions */ /* #undef OPENSSL_LOBOTOMISED_AES */ @@ -1281,6 +1311,9 @@ /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "openssh" +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + /* Define to the version of this package. */ #define PACKAGE_VERSION "Portable" @@ -1394,6 +1427,9 @@ /* Use libedit for sftp */ #define USE_LIBEDIT 1 +/* Use Linux audit module */ +/* #undef USE_LINUX_AUDIT */ + /* Enable OpenSSL engine support */ #define USE_OPENSSL_ENGINE 1 @@ -1406,6 +1442,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 */ @@ -1429,7 +1468,7 @@ /* #undef WITH_SELINUX */ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ + significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 #elif ! defined __LITTLE_ENDIAN__ diff --git a/crypto/openssh/config.h.in b/crypto/openssh/config.h.in index 4ff407f..e5c9379 100644 --- a/crypto/openssh/config.h.in +++ b/crypto/openssh/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 <bsm/audit.h> 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 <endian.h> 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 <lastlog.h> header file. */ #undef HAVE_LASTLOG_H +/* Define to 1 if you have the <libaudit.h> 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 <tmpdir.h> 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/crypto/openssh/defines.h b/crypto/openssh/defines.h index fe25170..a74392f 100644 --- a/crypto/openssh/defines.h +++ b/crypto/openssh/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,10 @@ enum # define SHUT_RDWR SHUT_RDWR #endif +/* + * Definitions for IP type of service (ip_tos) + */ +#include <netinet/ip.h> #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 # define IPTOS_THROUGHPUT 0x08 @@ -50,6 +54,39 @@ enum # define IPTOS_MINCOST IPTOS_LOWCOST #endif /* IPTOS_LOWDELAY */ +/* + * Definitions for DiffServ Codepoints as per RFC2474 + */ +#include <netinet/in_systm.h> +#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/crypto/openssh/dns.c b/crypto/openssh/dns.c index 2e7bb5a..131cb3d 100644 --- a/crypto/openssh/dns.c +++ b/crypto/openssh/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/crypto/openssh/entropy.c b/crypto/openssh/entropy.c index 8b70539..a650351 100644 --- a/crypto/openssh/entropy.c +++ b/crypto/openssh/entropy.c @@ -100,6 +100,7 @@ seed_rng(void) close(p[0]); close(p[1]); close(devnull); + closefrom(STDERR_FILENO + 1); if (original_uid != original_euid && ( seteuid(getuid()) == -1 || @@ -157,7 +158,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/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c index afab6da..b6f924b 100644 --- a/crypto/openssh/hostfile.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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; - - 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)) { + HostkeyMarker marker; + Key *key; + int kbits; + + 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)) + 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; + } + } + if (!hostfile_check_key(kbits, key, host, path, linenum)) continue; - if (numret != NULL) - *numret = linenum; + 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++; + } + debug3("%s: loaded %lu keys", __func__, num_loaded); + fclose(f); + return; +} - if (key == NULL) { - /* we found a key of the requested type */ - if (found->type == keytype) { - fclose(f); - return HOST_FOUND; - } - continue; - } +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; - if (!hostfile_check_key(kbits, found, host, filename, linenum)) + 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; +} - 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); +/* + * 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; } - - /* 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; + 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; } - /* - * 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; } - /* Clear variables and close the file. */ - fclose(f); - - /* - * Return either HOST_NEW or HOST_CHANGED, depending on whether we - * saw a different key for the host. - */ + 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/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h index 1d460c1..d84d422 100644 --- a/crypto/openssh/hostfile.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -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/crypto/openssh/includes.h b/crypto/openssh/includes.h index 6bb9878..b4c53d9 100644 --- a/crypto/openssh/includes.h +++ b/crypto/openssh/includes.h @@ -30,7 +30,7 @@ # include <bstring.h> #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 <glob.h> diff --git a/crypto/openssh/jpake.c b/crypto/openssh/jpake.c index cdf65f5..ac9a4bc 100644 --- a/crypto/openssh/jpake.c +++ b/crypto/openssh/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/crypto/openssh/kex.c b/crypto/openssh/kex.c index 148cfee..c65e28f 100644 --- a/crypto/openssh/kex.c +++ b/crypto/openssh/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/crypto/openssh/kex.h b/crypto/openssh/kex.h index 62fa2ea..7373d3c 100644 --- a/crypto/openssh/kex.h +++ b/crypto/openssh/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 <signal.h> #include <openssl/evp.h> #include <openssl/hmac.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ec.h> +#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/crypto/openssh/kexdhc.c b/crypto/openssh/kexdhc.c index d384c80..76ceb5d 100644 --- a/crypto/openssh/kexdhc.c +++ b/crypto/openssh/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 <sys/types.h> +#include <openssl/dh.h> + #include <stdarg.h> #include <stdio.h> #include <string.h> diff --git a/crypto/openssh/kexdhs.c b/crypto/openssh/kexdhs.c index e722877..f56e887 100644 --- a/crypto/openssh/kexdhs.c +++ b/crypto/openssh/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 <string.h> #include <signal.h> +#include <openssl/dh.h> + #include "xmalloc.h" #include "buffer.h" #include "key.h" diff --git a/crypto/openssh/kexecdh.c b/crypto/openssh/kexecdh.c new file mode 100644 index 0000000..f13f69d --- /dev/null +++ b/crypto/openssh/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 <sys/types.h> + +#include <signal.h> +#include <string.h> + +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/ec.h> +#include <openssl/ecdh.h> + +#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/crypto/openssh/kexecdhc.c b/crypto/openssh/kexecdhc.c new file mode 100644 index 0000000..115d4bf --- /dev/null +++ b/crypto/openssh/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 <sys/types.h> + +#include <stdio.h> +#include <string.h> +#include <signal.h> + +#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 <openssl/ecdh.h> + +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/crypto/openssh/kexecdhs.c b/crypto/openssh/kexecdhs.c new file mode 100644 index 0000000..8c515df --- /dev/null +++ b/crypto/openssh/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 <sys/types.h> +#include <string.h> +#include <signal.h> + +#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 <openssl/ecdh.h> + +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/crypto/openssh/kexgexc.c b/crypto/openssh/kexgexc.c index adb973d..79552d7 100644 --- a/crypto/openssh/kexgexc.c +++ b/crypto/openssh/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 <sys/types.h> +#include <openssl/dh.h> + #include <stdarg.h> #include <stdio.h> #include <string.h> diff --git a/crypto/openssh/kexgexs.c b/crypto/openssh/kexgexs.c index f4156af..a5e3df7 100644 --- a/crypto/openssh/kexgexs.c +++ b/crypto/openssh/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 <string.h> #include <signal.h> +#include <openssl/dh.h> + #include "xmalloc.h" #include "buffer.h" #include "key.h" diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c index e4aa25c..e3a305e 100644 --- a/crypto/openssh/key.c +++ b/crypto/openssh/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.96 2011/02/04 00:44:21 djm Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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,12 +1270,38 @@ 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) { char *s, *cp, *p; @@ -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,10 +1886,9 @@ 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) { - arc4random_buf(&nonce, sizeof(nonce)); + arc4random_buf(&nonce, sizeof(nonce)); + if (!key_cert_is_legacy(k)) buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); - } switch (k->type) { case KEY_DSA_CERT_V00: @@ -1528,6 +1898,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 +1920,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 +1939,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 +2031,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/crypto/openssh/key.h b/crypto/openssh/key.h index 11d30ea..ec5ac5e 100644 --- a/crypto/openssh/key.h +++ b/crypto/openssh/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 <openssl/rsa.h> #include <openssl/dsa.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ec.h> +#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/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c index 62962ac..0d0e807 100644 --- a/crypto/openssh/loginrec.c +++ b/crypto/openssh/loginrec.c @@ -274,7 +274,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; @@ -298,7 +298,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; @@ -312,7 +312,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!) */ @@ -336,7 +337,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; @@ -364,7 +365,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; @@ -469,9 +470,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); } @@ -877,11 +878,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); } /* @@ -897,16 +900,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); @@ -1210,7 +1217,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 @@ -1501,11 +1508,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); } } @@ -1677,7 +1685,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/crypto/openssh/loginrec.h b/crypto/openssh/loginrec.h index 84b4865..28923e7 100644 --- a/crypto/openssh/loginrec.h +++ b/crypto/openssh/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/crypto/openssh/misc.c b/crypto/openssh/misc.c index a82e793..919b04e 100644 --- a/crypto/openssh/misc.c +++ b/crypto/openssh/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 <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> #include <netinet/tcp.h> #include <errno.h> @@ -850,16 +853,138 @@ ms_to_timeval(struct timeval *tv, int ms) tv->tv_usec = (ms % 1000) * 1000; } +void +bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) +{ + bw->buflen = buflen; + bw->rate = kbps; + bw->thresh = bw->rate; + bw->lamt = 0; + timerclear(&bw->bwstart); + timerclear(&bw->bwend); +} + +/* 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 -timingsafe_bcmp(const void *b1, const void *b2, size_t n) +parse_ipqos(const char *cp) { - const unsigned char *p1 = b1, *p2 = b2; - int ret = 0; + u_int i; + char *ep; + long val; - for (; n > 0; n--) - ret |= *p1++ ^ *p2++; - return (ret != 0); + 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/crypto/openssh/misc.h b/crypto/openssh/misc.h index bb799f6..65cf4a6 100644 --- a/crypto/openssh/misc.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -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/crypto/openssh/moduli.c b/crypto/openssh/moduli.c index f737cb3..2964a8b 100644 --- a/crypto/openssh/moduli.c +++ b/crypto/openssh/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 <karn@qualcomm.com> * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> @@ -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/crypto/openssh/monitor.c b/crypto/openssh/monitor.c index 9eb4e35..29d987c 100644 --- a/crypto/openssh/monitor.c +++ b/crypto/openssh/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 <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -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/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c index faeb02c..1a5dda5 100644 --- a/crypto/openssh/monitor_wrap.c +++ b/crypto/openssh/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 <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -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/crypto/openssh/mux.c b/crypto/openssh/mux.c index 5c3857e..e370462 100644 --- a/crypto/openssh/mux.c +++ b/crypto/openssh/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 <djm@openbsd.org> * @@ -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/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h index 7bedfab..2c43607 100644 --- a/crypto/openssh/myproposal.h +++ b/crypto/openssh/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 <openssl/opensslv.h> +#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_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_DEFAULT_KEX \ - "diffie-hellman-group-exchange-sha1," \ - "diffie-hellman-group14-sha1," \ - "diffie-hellman-group1-sha1" +#if OPENSSL_VERSION_NUMBER >= 0x00907000L +# define KEX_SHA256_METHODS \ + "diffie-hellman-group-exchange-sha256," #else -# define KEX_DEFAULT_KEX \ - "diffie-hellman-group-exchange-sha256," \ +# 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" -#endif #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/crypto/openssh/openbsd-compat/bindresvport.c b/crypto/openssh/openbsd-compat/bindresvport.c index c0d5bdb..c89f214 100644 --- a/crypto/openssh/openbsd-compat/bindresvport.c +++ b/crypto/openssh/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/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c index 55f100a..3ef373f 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.c +++ b/crypto/openssh/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/crypto/openssh/openbsd-compat/bsd-misc.h b/crypto/openssh/openbsd-compat/bsd-misc.h index b61ec42..e70c3f9 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.h +++ b/crypto/openssh/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 <djm@mindrot.org> @@ -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/crypto/openssh/openbsd-compat/charclass.h b/crypto/openssh/openbsd-compat/charclass.h new file mode 100644 index 0000000..91f5174 --- /dev/null +++ b/crypto/openssh/openbsd-compat/charclass.h @@ -0,0 +1,31 @@ +/* + * Public domain, 2008, Todd C. Miller <Todd.Miller@courtesan.com> + * + * $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/crypto/openssh/openbsd-compat/glob.c b/crypto/openssh/openbsd-compat/glob.c index 74b5064..0341225 100644 --- a/crypto/openssh/openbsd-compat/glob.c +++ b/crypto/openssh/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 <sys/types.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <ctype.h> -#include <errno.h> -#include <pwd.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#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 <sys/types.h> +#include <sys/stat.h> + +#include <dirent.h> +#include <ctype.h> +#include <errno.h> +#include <pwd.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#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; - - 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) { + struct stat **statv; + + 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/crypto/openssh/openbsd-compat/glob.h b/crypto/openssh/openbsd-compat/glob.h index a2b36f9..f8a7fa5 100644 --- a/crypto/openssh/openbsd-compat/glob.h +++ b/crypto/openssh/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 <sys/stat.h> + 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/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h index e15d2bd..77c5ed2 100644 --- a/crypto/openssh/openbsd-compat/openbsd-compat.h +++ b/crypto/openssh/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/crypto/openssh/openbsd-compat/openssl-compat.c b/crypto/openssh/openbsd-compat/openssl-compat.c index 420496c..b617fdf 100644 --- a/crypto/openssh/openbsd-compat/openssl-compat.c +++ b/crypto/openssh/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 <dtucker@zip.com.au> @@ -18,10 +18,20 @@ #include "includes.h" +#include <stdarg.h> +#include <string.h> + #ifdef USE_OPENSSL_ENGINE # include <openssl/engine.h> +# include <openssl/conf.h> +#endif + +#ifndef HAVE_RSA_GET_DEFAULT_METHOD +# include <openssl/rsa.h> #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/crypto/openssh/openbsd-compat/openssl-compat.h b/crypto/openssh/openbsd-compat/openssl-compat.h index b7caa65..6d4f3f2 100644 --- a/crypto/openssh/openbsd-compat/openssl-compat.h +++ b/crypto/openssh/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 <dtucker@zip.com.au> @@ -17,6 +17,7 @@ */ #include "includes.h" +#include <openssl/opensslv.h> #include <openssl/evp.h> #include <openssl/rsa.h> #include <openssl/dsa.h> @@ -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/crypto/openssh/openbsd-compat/port-linux.c b/crypto/openssh/openbsd-compat/port-linux.c index 89b9a73..fe6fc2d 100644 --- a/crypto/openssh/openbsd-compat/port-linux.c +++ b/crypto/openssh/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.4.3 2011/02/06 02:24:17 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> @@ -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"); } @@ -205,17 +205,41 @@ ssh_selinux_change_context(const char *newname) xfree(oldctx); xfree(newctx); } + +void +ssh_selinux_setfscreatecon(const char *path) +{ + security_context_t context; + + if (!ssh_selinux_enabled()) + return; + if (path == NULL) { + setfscreatecon(NULL); + return; + } + if (matchpathcon(path, 0700, &context) == 0) + setfscreatecon(context); +} + #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 +248,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 +282,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/crypto/openssh/openbsd-compat/port-linux.h b/crypto/openssh/openbsd-compat/port-linux.h index 209d9a7..c2f6184 100644 --- a/crypto/openssh/openbsd-compat/port-linux.h +++ b/crypto/openssh/openbsd-compat/port-linux.h @@ -1,4 +1,4 @@ -/* $Id: port-linux.h,v 1.4 2009/12/08 02:39:48 dtucker Exp $ */ +/* $Id: port-linux.h,v 1.4.10.1 2011/02/04 00:42:21 djm Exp $ */ /* * Copyright (c) 2006 Damien Miller <djm@openbsd.org> @@ -24,6 +24,7 @@ int ssh_selinux_enabled(void); void ssh_selinux_setup_pty(char *, const char *); void ssh_selinux_setup_exec_context(char *); void ssh_selinux_change_context(const char *); +void ssh_selinux_setfscreatecon(const char *); #endif #ifdef LINUX_OOM_ADJUST diff --git a/crypto/openssh/openbsd-compat/port-solaris.c b/crypto/openssh/openbsd-compat/port-solaris.c index 2ab64d4..25382f1 100644 --- a/crypto/openssh/openbsd-compat/port-solaris.c +++ b/crypto/openssh/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 <sys/task.h> +#include <project.h> + +/* + * 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/crypto/openssh/openbsd-compat/port-solaris.h b/crypto/openssh/openbsd-compat/port-solaris.h index 4c32487..cd442e7 100644 --- a/crypto/openssh/openbsd-compat/port-solaris.h +++ b/crypto/openssh/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 <sys/types.h> +#include <pwd.h> + 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/crypto/openssh/openbsd-compat/timingsafe_bcmp.c b/crypto/openssh/openbsd-compat/timingsafe_bcmp.c new file mode 100644 index 0000000..7e28c0e --- /dev/null +++ b/crypto/openssh/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/crypto/openssh/packet.c b/crypto/openssh/packet.c index 48f7fe6..b4e01f7 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/packet.h b/crypto/openssh/packet.h index 33523d7..d516aae 100644 --- a/crypto/openssh/packet.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -19,6 +19,9 @@ #include <termios.h> #include <openssl/bn.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ec.h> +#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/crypto/openssh/pathnames.h b/crypto/openssh/pathnames.h index 0bb0c06..1b6e789 100644 --- a/crypto/openssh/pathnames.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -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/crypto/openssh/platform.c b/crypto/openssh/platform.c index e3a428a..a455472 100644 --- a/crypto/openssh/platform.c +++ b/crypto/openssh/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 <sys/types.h> + +#include <stdarg.h> +#include <unistd.h> + +#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/crypto/openssh/platform.h b/crypto/openssh/platform.h index 30a1d22..944d2c3 100644 --- a/crypto/openssh/platform.h +++ b/crypto/openssh/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 <sys/types.h> +#include <pwd.h> + 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/crypto/openssh/readconf.c b/crypto/openssh/readconf.c index 9d6091f..43779af 100644 --- a/crypto/openssh/readconf.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -21,6 +21,8 @@ __RCSID("$FreeBSD$"); #include <sys/sysctl.h> #include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> #include <ctype.h> #include <errno.h> @@ -135,6 +137,7 @@ typedef enum { oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication, + oKexAlgorithms, oIPQoS, oVersionAddendum, oDeprecated, oUnsupported } OpCodes; @@ -244,6 +247,8 @@ static struct { #else { "zeroknowledgepasswordauthentication", oUnsupported }, #endif + { "kexalgorithms", oKexAlgorithms }, + { "ipqos", oIPQoS }, { "versionaddendum", oVersionAddendum }, { NULL, oBadOption } @@ -716,6 +721,18 @@ parse_int: 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 : "<NONE>"); + if (*activep && options->kex_algorithms == NULL) + options->kex_algorithms = xstrdup(arg); + break; + case oHostKeyAlgorithms: arg = strdelim(&s); if (!arg || *arg == '\0') @@ -976,6 +993,23 @@ parse_int: 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; @@ -1102,6 +1136,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; @@ -1144,6 +1179,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; } /* @@ -1215,6 +1252,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; @@ -1238,6 +1276,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) @@ -1290,6 +1335,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/crypto/openssh/readconf.h b/crypto/openssh/readconf.h index 95d1046..ee160df 100644 --- a/crypto/openssh/readconf.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -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/crypto/openssh/readpass.c b/crypto/openssh/readpass.c index bd144c2..599c8ef 100644 --- a/crypto/openssh/readpass.c +++ b/crypto/openssh/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 <paths.h> #endif +#include <signal.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -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/crypto/openssh/schnorr.c b/crypto/openssh/schnorr.c index daeec06..fb6bd5e 100644 --- a/crypto/openssh/schnorr.c +++ b/crypto/openssh/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 $ */ /* $FreeBSD$ */ /* * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -141,6 +141,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) { @@ -257,14 +261,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; } @@ -275,6 +284,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; @@ -283,6 +293,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) { @@ -317,9 +338,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/crypto/openssh/scp.1 b/crypto/openssh/scp.1 index 2440272..4031bd4 100644 --- a/crypto/openssh/scp.1 +++ b/crypto/openssh/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 February 8, 2010 +.Dd 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/crypto/openssh/scp.c b/crypto/openssh/scp.c index e07de42..18b2597 100644 --- a/crypto/openssh/scp.c +++ b/crypto/openssh/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; - - 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; + off_t *cnt = (off_t *)_cnt; + + *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; } @@ -825,60 +895,6 @@ rsource(char *name, struct stat *statp) } 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) { static BUF buffer; @@ -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/crypto/openssh/servconf.c b/crypto/openssh/servconf.c index 506cf2e..c742e130 100644 --- a/crypto/openssh/servconf.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -16,6 +16,10 @@ __RCSID("$FreeBSD$"); #include <sys/types.h> #include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> + #include <netdb.h> #include <pwd.h> #include <stdio.h> @@ -111,6 +115,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; @@ -134,6 +139,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 @@ -156,6 +163,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 */ @@ -258,16 +269,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) @@ -314,6 +329,7 @@ typedef enum { sUsePrivilegeSeparation, sAllowAgentForwarding, sZeroKnowledgePasswordAuthentication, sHostCertificate, sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile, + sKexAlgorithms, sIPQoS, sVersionAddendum, sDeprecated, sUnsupported } ServerOpCodes; @@ -437,6 +453,8 @@ static struct { { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL }, + { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL }, + { "ipqos", sIPQoS, SSHCFG_ALL }, { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; @@ -667,7 +685,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; @@ -1133,6 +1151,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 : "<NONE>"); + if (options->kex_algorithms == NULL) + options->kex_algorithms = xstrdup(arg); + break; + case sProtocol: intptr = &options->protocol; arg = strdelim(&cp); @@ -1355,11 +1385,28 @@ 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 sVersionAddendum: - ssh_version_set_addendum(strtok(cp, "\n")); - do { - arg = strdelim(&cp); - } while (arg != NULL && *arg != '\0'); + ssh_version_set_addendum(strtok(cp, "\n")); + do { + arg = strdelim(&cp); + } while (arg != NULL && *arg != '\0'); break; case sDeprecated: @@ -1472,6 +1519,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) @@ -1737,5 +1786,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/crypto/openssh/servconf.h b/crypto/openssh/servconf.h index 45d2a2a..5a058a4 100644 --- a/crypto/openssh/servconf.h +++ b/crypto/openssh/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 <ylo@cs.hut.fi> @@ -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/crypto/openssh/session.c b/crypto/openssh/session.c index bc4d7a9..242a861 100644 --- a/crypto/openssh/session.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -586,7 +586,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 @@ -740,7 +741,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 { @@ -1481,36 +1483,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_SETENV|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) { @@ -1523,50 +1505,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) { @@ -1640,8 +1581,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 { @@ -1667,8 +1606,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/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c index 9dab477..caa384b 100644 --- a/crypto/openssh/sftp-client.c +++ b/crypto/openssh/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 <djm@openbsd.org> * @@ -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)); @@ -771,6 +800,39 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) } 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) { Buffer msg; @@ -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/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h index 1d08c40..aef54ef 100644 --- a/crypto/openssh/sftp-client.h +++ b/crypto/openssh/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 <djm@openbsd.org> @@ -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/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c index a98ac2b..b268d08 100644 --- a/crypto/openssh/sftp-server.c +++ b/crypto/openssh/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); } @@ -1223,6 +1226,27 @@ process_extended_fstatvfs(u_int32_t id) } 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) { u_int32_t id; @@ -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/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1 index 86dc5b2..6b506fe 100644 --- a/crypto/openssh/sftp.1 +++ b/crypto/openssh/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 $ .\" $FreeBSD$ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. @@ -23,7 +23,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 February 8, 2010 +.Dd December 4, 2010 .Dt SFTP 1 .Os .Sh NAME @@ -39,6 +39,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 @@ -50,9 +51,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 @@ -126,7 +129,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 @@ -158,6 +161,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 @@ -197,7 +202,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 @@ -386,11 +393,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/crypto/openssh/sftp.c b/crypto/openssh/sftp.c index 229f129..ab667f5 100644 --- a/crypto/openssh/sftp.c +++ b/crypto/openssh/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 <djm@openbsd.org> * @@ -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) @@ -377,6 +378,30 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag, } 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) { extern int opterr, optind, optopt, optreset; @@ -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/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 index 647b75a..4260cbd 100644 --- a/crypto/openssh/ssh-add.1 +++ b/crypto/openssh/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 <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 March 5, 2010 +.Dd 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/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c index fb641ec..125d664 100644 --- a/crypto/openssh/ssh-add.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 index 99e9326..7f4942f 100644 --- a/crypto/openssh/ssh-agent.1 +++ b/crypto/openssh/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 $ .\" $FreeBSD$ .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 17, 2010 +.Dd November 21, 2010 .Dt SSH-AGENT 1 .Os .Sh NAME @@ -43,18 +43,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 @@ -73,7 +73,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 . @@ -115,7 +115,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, @@ -188,9 +189,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/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index edd65a2..d8af4e4 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -469,6 +469,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; @@ -491,7 +496,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); @@ -510,6 +514,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); @@ -535,9 +592,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 */ @@ -1094,7 +1153,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(); @@ -1175,7 +1234,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/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c index 175e4d0..ede5e21 100644 --- a/crypto/openssh/ssh-dss.c +++ b/crypto/openssh/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/crypto/openssh/ssh-ecdsa.c b/crypto/openssh/ssh-ecdsa.c new file mode 100644 index 0000000..c8276b4 --- /dev/null +++ b/crypto/openssh/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 <sys/types.h> + +#include <openssl/bn.h> +#include <openssl/ec.h> +#include <openssl/ecdsa.h> +#include <openssl/evp.h> + +#include <string.h> + +#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/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1 index 5a04fc0..2e8727b 100644 --- a/crypto/openssh/ssh-keygen.1 +++ b/crypto/openssh/ssh-keygen.1 @@ -1,8 +1,6 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.98 2010/08/04 06:07:11 djm Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.101 2010/10/28 18:33:28 jmc Exp $ .\" $FreeBSD$ .\" -.\" -*- nroff -*- -.\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland .\" All rights reserved @@ -38,7 +36,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 August 4, 2010 +.Dd October 28, 2010 .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -126,7 +124,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 @@ -143,9 +141,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 . @@ -427,9 +426,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. @@ -606,18 +606,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 @@ -625,26 +626,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 @@ -654,13 +640,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/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c index d90b1df..c95e4ab 100644 --- a/crypto/openssh/ssh-keygen.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, 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/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1 index 47a7c6e..dbb0d7d 100644 --- a/crypto/openssh/ssh-keyscan.1 +++ b/crypto/openssh/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 $ .\" $FreeBSD$ .\" .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. @@ -7,7 +7,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd January 9, 2010 +.Dd August 31, 2010 .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -89,9 +89,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 @@ -123,7 +124,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 @@ -131,9 +132,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 @@ -150,7 +154,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/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c index b6cf427..25d7ac6 100644 --- a/crypto/openssh/ssh-keyscan.c +++ b/crypto/openssh/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 <dm@lcs.mit.edu>. * @@ -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/crypto/openssh/ssh-keysign.8 b/crypto/openssh/ssh-keysign.8 index abee1ea..a266af9 100644 --- a/crypto/openssh/ssh-keysign.8 +++ b/crypto/openssh/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 August 4, 2010 +.Dd 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/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c index 0c70770..d051560 100644 --- a/crypto/openssh/ssh-keysign.c +++ b/crypto/openssh/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/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c index c471ff3..c6355fa 100644 --- a/crypto/openssh/ssh-rsa.c +++ b/crypto/openssh/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 <markus@openbsd.org> * @@ -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/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1 index d5cd60c..4bdb30e 100644 --- a/crypto/openssh/ssh.1 +++ b/crypto/openssh/ssh.1 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -34,9 +33,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.308 2010/08/04 05:37:01 djm Exp $ +.\" $OpenBSD: ssh.1,v 1.316 2010/11/18 15:01:00 jmc Exp $ .\" $FreeBSD$ -.Dd August 4 2010 +.Dd November 18, 2010 .Dt SSH 1 .Os .Sh NAME @@ -270,13 +269,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. @@ -436,7 +436,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 @@ -648,10 +650,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, @@ -723,14 +721,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 @@ -750,6 +748,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) @@ -758,6 +758,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) @@ -1252,7 +1254,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, @@ -1265,42 +1267,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 @@ -1311,21 +1315,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 @@ -1334,11 +1339,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 @@ -1349,9 +1354,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, @@ -1369,7 +1375,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 @@ -1379,7 +1385,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. @@ -1387,6 +1393,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 , @@ -1460,6 +1470,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/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index 11eac21..c9b29fb 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -51,6 +51,7 @@ __RCSID("$FreeBSD$"); #include <sys/ioctl.h> #include <sys/param.h> #include <sys/socket.h> +#include <sys/wait.h> #include <ctype.h> #include <errno.h> @@ -183,9 +184,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; @@ -211,6 +209,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 *); @@ -223,7 +222,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; @@ -600,7 +599,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. */ @@ -695,6 +694,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); @@ -709,7 +710,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); @@ -798,34 +799,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; } @@ -848,10 +868,16 @@ 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 + ssh_selinux_setfscreatecon(buf); +#endif if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); - +#ifdef WITH_SELINUX + ssh_selinux_setfscreatecon(NULL); +#endif + } /* load options.identity_files */ load_public_identity_files(); @@ -867,10 +893,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, @@ -908,12 +935,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; } @@ -945,6 +968,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"); @@ -1217,7 +1241,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(); @@ -1315,8 +1340,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 */ @@ -1534,3 +1557,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/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h index 3ffaf68..51a963c 100644 --- a/crypto/openssh/ssh2.h +++ b/crypto/openssh/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/crypto/openssh/ssh_config b/crypto/openssh/ssh_config index e0c7f69..1ff198b 100644 --- a/crypto/openssh/ssh_config +++ b/crypto/openssh/ssh_config @@ -46,4 +46,4 @@ # PermitLocalCommand no # VisualHostKey no # ProxyCommand ssh -q -W %h:%p gateway.example.com -# VersionAddendum FreeBSD-20101111 +# VersionAddendum FreeBSD-20110503 diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5 index e36e574..f0754c3 100644 --- a/crypto/openssh/ssh_config.5 +++ b/crypto/openssh/ssh_config.5 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -34,9 +33,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.138 2010/08/04 05:37:01 djm Exp $ +.\" $OpenBSD: ssh_config.5,v 1.146 2010/12/08 04:02:47 djm Exp $ .\" $FreeBSD$ -.Dd August 4, 2010 +.Dd December 8, 2010 .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -548,7 +547,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 @@ -584,14 +594,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. @@ -619,6 +630,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 @@ -638,6 +686,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. @@ -751,7 +810,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. @@ -1114,7 +1173,7 @@ in Specifies a string to append to the regular version string to identify OS- or site-specific modifications. The default is -.Dq FreeBSD-20101111 . +.Dq FreeBSD-20110503 . .It Cm VisualHostKey If this flag is set to .Dq yes , diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h index caa14c8..d8d39e1 100644 --- a/crypto/openssh/ssh_namespace.h +++ b/crypto/openssh/ssh_namespace.h @@ -7,7 +7,7 @@ * * A list of symbols which need munging is obtained as follows: * - * nm libssh.a | awk '/[0-9a-z] [A-Z] / && $3 !~ /^ssh_/ { print "#define", $3, "ssh_" $3 }' + * nm libssh.a | awk '/[0-9a-z] [A-Z] / && $3 !~ /^ssh_/ { print "#define" $3 "\t\tssh_" $3 }' * * $FreeBSD$ */ @@ -18,14 +18,17 @@ #define acss_setkey ssh_acss_setkey #define acss_setsubkey ssh_acss_setsubkey #define add_host_to_hostfile ssh_add_host_to_hostfile -#define add_recv_bytes ssh_add_recv_bytes #define addargs ssh_addargs #define addr_match_cidr_list ssh_addr_match_cidr_list #define addr_match_list ssh_addr_match_list #define ask_permission ssh_ask_permission #define atomicio ssh_atomicio +#define atomicio6 ssh_atomicio6 #define atomiciov ssh_atomiciov +#define atomiciov6 ssh_atomiciov6 #define auth_request_forwarding ssh_auth_request_forwarding +#define bandwidth_limit ssh_bandwidth_limit +#define bandwidth_limit_init ssh_bandwidth_limit_init #define buffer_append ssh_buffer_append #define buffer_append_space ssh_buffer_append_space #define buffer_check_alloc ssh_buffer_check_alloc @@ -47,6 +50,10 @@ #define buffer_get_bignum_ret ssh_buffer_get_bignum_ret #define buffer_get_char ssh_buffer_get_char #define buffer_get_char_ret ssh_buffer_get_char_ret +#define buffer_get_cstring ssh_buffer_get_cstring +#define buffer_get_cstring_ret ssh_buffer_get_cstring_ret +#define buffer_get_ecpoint ssh_buffer_get_ecpoint +#define buffer_get_ecpoint_ret ssh_buffer_get_ecpoint_ret #define buffer_get_int ssh_buffer_get_int #define buffer_get_int64 ssh_buffer_get_int64 #define buffer_get_int64_ret ssh_buffer_get_int64_ret @@ -67,6 +74,8 @@ #define buffer_put_bignum_ret ssh_buffer_put_bignum_ret #define buffer_put_char ssh_buffer_put_char #define buffer_put_cstring ssh_buffer_put_cstring +#define buffer_put_ecpoint ssh_buffer_put_ecpoint +#define buffer_put_ecpoint_ret ssh_buffer_put_ecpoint_ret #define buffer_put_int ssh_buffer_put_int #define buffer_put_int64 ssh_buffer_put_int64 #define buffer_put_short ssh_buffer_put_short @@ -134,7 +143,7 @@ #define channel_setup_remote_fwd_listener ssh_channel_setup_remote_fwd_listener #define channel_still_open ssh_channel_still_open #define channel_stop_listening ssh_channel_stop_listening -#define check_host_in_hostfile ssh_check_host_in_hostfile +#define check_key_in_hostkeys ssh_check_key_in_hostkeys #define choose_dh ssh_choose_dh #define chop ssh_chop #define cipher_blocksize ssh_cipher_blocksize @@ -196,12 +205,12 @@ #define error ssh_error #define evp_acss ssh_evp_acss #define evp_aes_128_ctr ssh_evp_aes_128_ctr -#define evp_rijndael ssh_evp_rijndael #define evp_ssh1_3des ssh_evp_ssh1_3des #define evp_ssh1_bf ssh_evp_ssh1_bf #define export_dns_rr ssh_export_dns_rr #define fatal ssh_fatal #define fmt_scaled ssh_fmt_scaled +#define free_hostkeys ssh_free_hostkeys #define freeargs ssh_freeargs #define freerrset ssh_freerrset #define gen_candidates ssh_gen_candidates @@ -211,7 +220,6 @@ #define get_local_port ssh_get_local_port #define get_peer_ipaddr ssh_get_peer_ipaddr #define get_peer_port ssh_get_peer_port -#define get_recv_bytes ssh_get_recv_bytes #define get_remote_ipaddr ssh_get_remote_ipaddr #define get_remote_name_or_ip ssh_get_remote_name_or_ip #define get_remote_port ssh_get_remote_port @@ -226,24 +234,41 @@ #define hostfile_read_key ssh_hostfile_read_key #define hpdelim ssh_hpdelim #define incoming_stream ssh_incoming_stream +#define init_hostkeys ssh_init_hostkeys #define init_rng ssh_init_rng #define ipv64_normalise_mapped ssh_ipv64_normalise_mapped #define kex_derive_keys ssh_kex_derive_keys #define kex_dh_hash ssh_kex_dh_hash +#define kex_ecdh_hash ssh_kex_ecdh_hash +#define kex_ecdh_name_to_evpmd ssh_kex_ecdh_name_to_evpmd +#define kex_ecdh_name_to_nid ssh_kex_ecdh_name_to_nid #define kex_finish ssh_kex_finish #define kex_get_newkeys ssh_kex_get_newkeys #define kex_input_kexinit ssh_kex_input_kexinit +#define kex_names_valid ssh_kex_names_valid #define kex_send_kexinit ssh_kex_send_kexinit #define kex_setup ssh_kex_setup #define kexdh_client ssh_kexdh_client +#define kexecdh_client ssh_kexecdh_client #define kexgex_client ssh_kexgex_client #define kexgex_hash ssh_kexgex_hash #define key_add_private ssh_key_add_private #define key_cert_check_authority ssh_key_cert_check_authority #define key_cert_copy ssh_key_cert_copy +#define key_cert_is_legacy ssh_key_cert_is_legacy +#define key_cert_type ssh_key_cert_type #define key_certify ssh_key_certify +#define key_curve_name_to_nid ssh_key_curve_name_to_nid +#define key_curve_nid_to_bits ssh_key_curve_nid_to_bits +#define key_curve_nid_to_name ssh_key_curve_nid_to_name #define key_demote ssh_key_demote #define key_drop_cert ssh_key_drop_cert +#define key_ec_nid_to_evpmd ssh_key_ec_nid_to_evpmd +#define key_ec_validate_private ssh_key_ec_validate_private +#define key_ec_validate_public ssh_key_ec_validate_public +#define key_ecdsa_bits_to_nid ssh_key_ecdsa_bits_to_nid +#define key_ecdsa_key_to_nid ssh_key_ecdsa_key_to_nid +#define key_ecdsa_nid_from_name ssh_key_ecdsa_nid_from_name #define key_equal ssh_key_equal #define key_equal_public ssh_key_equal_public #define key_fingerprint ssh_key_fingerprint @@ -254,7 +279,9 @@ #define key_generate ssh_key_generate #define key_in_file ssh_key_in_file #define key_is_cert ssh_key_is_cert +#define key_load_cert ssh_key_load_cert #define key_load_private ssh_key_load_private +#define key_load_private_cert ssh_key_load_private_cert #define key_load_private_pem ssh_key_load_private_pem #define key_load_private_type ssh_key_load_private_type #define key_load_public ssh_key_load_public @@ -268,6 +295,7 @@ #define key_sign ssh_key_sign #define key_size ssh_key_size #define key_ssh_name ssh_key_ssh_name +#define key_ssh_name_plain ssh_key_ssh_name_plain #define key_to_blob ssh_key_to_blob #define key_to_certified ssh_key_to_certified #define key_type ssh_key_type @@ -275,13 +303,14 @@ #define key_type_plain ssh_key_type_plain #define key_verify ssh_key_verify #define key_write ssh_key_write +#define load_hostkeys ssh_load_hostkeys #define log_facility_name ssh_log_facility_name #define log_facility_number ssh_log_facility_number #define log_init ssh_log_init #define log_level_name ssh_log_level_name #define log_level_number ssh_log_level_number #define logit ssh_logit -#define lookup_key_in_hostfile_by_type ssh_lookup_key_in_hostfile_by_type +#define lookup_key_in_hostkeys_by_type ssh_lookup_key_in_hostkeys_by_type #define mac_clear ssh_mac_clear #define mac_compute ssh_mac_compute #define mac_init ssh_mac_init @@ -294,6 +323,7 @@ #define match_pattern ssh_match_pattern #define match_pattern_list ssh_match_pattern_list #define match_user ssh_match_user +#define mktemp_proto ssh_mktemp_proto #define mm_receive_fd ssh_mm_receive_fd #define mm_send_fd ssh_mm_send_fd #define ms_subtract_diff ssh_ms_subtract_diff @@ -311,6 +341,8 @@ #define packet_get_char ssh_packet_get_char #define packet_get_connection_in ssh_packet_get_connection_in #define packet_get_connection_out ssh_packet_get_connection_out +#define packet_get_cstring ssh_packet_get_cstring +#define packet_get_ecpoint ssh_packet_get_ecpoint #define packet_get_encryption_key ssh_packet_get_encryption_key #define packet_get_input ssh_packet_get_input #define packet_get_int ssh_packet_get_int @@ -337,6 +369,7 @@ #define packet_put_bignum2 ssh_packet_put_bignum2 #define packet_put_char ssh_packet_put_char #define packet_put_cstring ssh_packet_put_cstring +#define packet_put_ecpoint ssh_packet_put_ecpoint #define packet_put_int ssh_packet_put_int #define packet_put_int64 ssh_packet_put_int64 #define packet_put_raw ssh_packet_put_raw @@ -369,6 +402,7 @@ #define packet_start_compression ssh_packet_start_compression #define packet_write_poll ssh_packet_write_poll #define packet_write_wait ssh_packet_write_wait +#define parse_ipqos ssh_parse_ipqos #define percent_expand ssh_percent_expand #define permanently_drop_suid ssh_permanently_drop_suid #define permanently_set_uid ssh_permanently_set_uid @@ -390,20 +424,14 @@ #define refresh_progress_meter ssh_refresh_progress_meter #define replacearg ssh_replacearg #define restore_uid ssh_restore_uid -#define resume_in_progress ssh_resume_in_progress -#define resume_kex ssh_resume_kex #define rijndael_decrypt ssh_rijndael_decrypt #define rijndael_encrypt ssh_rijndael_encrypt #define rijndael_set_key ssh_rijndael_set_key -#define roaming_read ssh_roaming_read -#define roaming_write ssh_roaming_write #define rsa_generate_additional_parameters ssh_rsa_generate_additional_parameters #define rsa_private_decrypt ssh_rsa_private_decrypt #define rsa_public_encrypt ssh_rsa_public_encrypt #define sanitise_stdfd ssh_sanitise_stdfd #define scan_scaled ssh_scan_scaled -#define schnorr_sign ssh_schnorr_sign -#define schnorr_verify ssh_schnorr_verify #define seed_rng ssh_seed_rng #define set_newkeys ssh_set_newkeys #define set_nodelay ssh_set_nodelay @@ -421,6 +449,7 @@ #define sys_tun_open ssh_sys_tun_open #define temporarily_use_uid ssh_temporarily_use_uid #define tilde_expand_filename ssh_tilde_expand_filename +#define timingsafe_bcmp ssh_timingsafe_bcmp #define tohex ssh_tohex #define tty_make_modes ssh_tty_make_modes #define tty_parse_modes ssh_tty_parse_modes diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index f84d5bb..3e55b5d 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/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 $ */ /* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -35,6 +35,7 @@ #include <paths.h> #endif #include <pwd.h> +#include <signal.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -67,14 +68,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 *); /* @@ -88,7 +90,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. */ @@ -142,6 +144,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); @@ -168,6 +171,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. */ @@ -595,6 +609,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("<no hostip for proxy " + "command>"); + } + } + + /* + * 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. @@ -604,21 +691,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 @@ -628,23 +715,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 " @@ -653,17 +723,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("<no hostip for proxy command>"); - } + get_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip); /* * Turn off check_host_ip if the connection is to localhost, via proxy @@ -673,74 +736,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) { @@ -791,7 +832,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."); @@ -832,8 +873,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 */ @@ -887,8 +927,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) @@ -910,13 +950,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 @@ -1001,13 +1043,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); @@ -1025,6 +1067,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: @@ -1044,6 +1090,10 @@ fail: 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; } @@ -1053,6 +1103,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 && @@ -1096,7 +1151,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; @@ -1119,7 +1174,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); @@ -1146,72 +1201,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); - if (options.visual_host_key) - 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.%s%s\n", - key_type(found), host, file, line, - key_type(found), fp, - options.visual_host_key ? "\n" : "", - options.visual_host_key ? ra : ""); - if (options.visual_host_key) - 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; - 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; + if (!lookup_key_in_hostkeys_by_type(hostkeys, type[i], &found)) 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); @@ -1220,9 +1244,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); @@ -1237,16 +1261,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", @@ -1257,6 +1284,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/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h index c59a097..fd7f7f7 100644 --- a/crypto/openssh/sshconnect.h +++ b/crypto/openssh/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/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 4c379ae..3cb9b10 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/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/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 index 17909b8..314300d 100644 --- a/crypto/openssh/sshd.8 +++ b/crypto/openssh/sshd.8 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -34,9 +33,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.257 2010/08/04 05:37:01 djm Exp $ +.\" $OpenBSD: sshd.8,v 1.260 2010/10/28 18:33:28 jmc Exp $ .\" $FreeBSD$ -.Dd August 4, 2010 +.Dd October 28, 2010 .Dt SSHD 8 .Os .Sh NAME @@ -171,9 +170,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. @@ -276,7 +276,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, @@ -486,6 +486,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 . @@ -497,6 +500,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. @@ -754,7 +758,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 @@ -766,7 +770,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). @@ -781,21 +785,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. @@ -812,7 +817,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 # ) , @@ -824,40 +829,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. @@ -866,15 +871,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. @@ -882,9 +888,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. @@ -895,7 +902,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 @@ -904,20 +911,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 @@ -925,7 +932,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/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index d3f5bb8..18d2d8e8 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -744,6 +744,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); @@ -759,6 +760,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); @@ -785,6 +787,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: @@ -1475,7 +1478,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 @@ -1587,6 +1590,7 @@ main(int ac, char **av) break; case KEY_RSA: case KEY_DSA: + case KEY_ECDSA: sensitive_data.have_ssh2_key = 1; break; } @@ -2061,7 +2065,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); @@ -2331,6 +2336,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(); @@ -2340,6 +2347,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/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index bb8d24bc..7858e78 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/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 $ # $FreeBSD$ # This is the sshd server system-wide configuration file. See @@ -14,7 +14,7 @@ # Note that some of FreeBSD's defaults differ from OpenBSD's, and # FreeBSD has a few additional options. -#VersionAddendum FreeBSD-20101111 +#VersionAddendum FreeBSD-20110503 #Port 22 #AddressFamily any @@ -29,6 +29,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/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5 index cea5297..1f8f7d2 100644 --- a/crypto/openssh/sshd_config.5 +++ b/crypto/openssh/sshd_config.5 @@ -1,4 +1,3 @@ -.\" -*- nroff -*- .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -34,9 +33,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.125 2010/06/30 07:28:34 jmc Exp $ +.\" $OpenBSD: sshd_config.5,v 1.131 2010/12/08 04:02:47 djm Exp $ .\" $FreeBSD$ -.Dd June 30, 2010 +.Dd December 8, 2010 .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -471,9 +470,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 @@ -481,7 +481,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. @@ -512,6 +513,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 @@ -537,6 +575,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). @@ -1037,7 +1086,7 @@ The default is Specifies a string to append to the regular version string to identify OS- or site-specific modifications. The default is -.Dq FreeBSD-20101111 . +.Dq FreeBSD-20110503 . .It Cm X11DisplayOffset Specifies the first display number available for .Xr sshd 8 Ns 's diff --git a/crypto/openssh/sshlogin.c b/crypto/openssh/sshlogin.c index 33bd652..54629f7 100644 --- a/crypto/openssh/sshlogin.c +++ b/crypto/openssh/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 <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland diff --git a/crypto/openssh/uuencode.c b/crypto/openssh/uuencode.c index b9e57e9..09d80d2 100644 --- a/crypto/openssh/uuencode.c +++ b/crypto/openssh/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/crypto/openssh/uuencode.h b/crypto/openssh/uuencode.h index fec55b4..4d98881 100644 --- a/crypto/openssh/uuencode.h +++ b/crypto/openssh/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/crypto/openssh/version.h b/crypto/openssh/version.h index 20aeb01..00dbdf3 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -1,12 +1,12 @@ -/* $OpenBSD: version.h,v 1.59 2010/08/08 16:26:42 djm Exp $ */ +/* $OpenBSD: version.h,v 1.61 2011/02/04 00:44:43 djm Exp $ */ /* $FreeBSD$ */ #ifndef SSH_VERSION #define SSH_VERSION (ssh_version_get()) #define SSH_RELEASE (ssh_version_get()) -#define SSH_VERSION_BASE "OpenSSH_5.6p1" -#define SSH_VERSION_ADDENDUM "FreeBSD-20101111" +#define SSH_VERSION_BASE "OpenSSH_5.8p2" +#define SSH_VERSION_ADDENDUM "FreeBSD-20110503" const char *ssh_version_get(void); void ssh_version_set_addendum(const char *); diff --git a/etc/rc.d/sshd b/etc/rc.d/sshd index fd95d5a..9f00199 100755 --- a/etc/rc.d/sshd +++ b/etc/rc.d/sshd @@ -70,12 +70,20 @@ sshd_keygen() fi if [ -f /etc/ssh/ssh_host_rsa_key ]; then - echo "You already have a RSA host key" \ + echo "You already have an RSA host key" \ "in /etc/ssh/ssh_host_rsa_key" echo "Skipping protocol version 2 RSA Key Generation" else /usr/bin/ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' fi + + if [ -f /etc/ssh/ssh_host_ecdsa_key ]; then + echo "You already have an ECDSA host key" \ + "in /etc/ssh/ssh_host_ecdsa_key" + echo "Skipping protocol version 2 ECDSA Key Generation" + else + /usr/bin/ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' + fi ) } @@ -83,6 +91,7 @@ sshd_precmd() { if [ ! -f /etc/ssh/ssh_host_key -o \ ! -f /etc/ssh/ssh_host_dsa_key -o \ + ! -f /etc/ssh/ssh_host_ecdsa_key -o \ ! -f /etc/ssh/ssh_host_rsa_key ]; then user_reseed run_rc_command keygen diff --git a/secure/lib/libssh/Makefile b/secure/lib/libssh/Makefile index d50b8d1..662bb1a 100644 --- a/secure/lib/libssh/Makefile +++ b/secure/lib/libssh/Makefile @@ -11,17 +11,18 @@ SRCS= acss.c authfd.c authfile.c bufaux.c bufbn.c buffer.c \ log.c match.c md-sha256.c moduli.c nchan.c packet.c \ readpass.c rsa.c ttymodes.c xmalloc.c addrmatch.c \ atomicio.c key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \ - monitor_fdpass.c rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c \ - kexgex.c kexdhc.c kexgexc.c msg.c progressmeter.c dns.c \ - entropy.c umac.c jpake.c schnorr.c \ - ssh-pkcs11.c + monitor_fdpass.c rijndael.c ssh-dss.c ssh-ecdsa.c ssh-rsa.c dh.c \ + kexdh.c kexgex.c kexdhc.c kexgexc.c bufec.c kexecdh.c kexecdhc.c \ + msg.c progressmeter.c dns.c entropy.c umac.c jpake.c \ + schnorr.c ssh-pkcs11.c # gss-genr.c should be in $SRCS but causes linking problems, so it is # compiled directly into sshd instead. # Portability layer SRCS+= bsd-misc.c fmt_scaled.c getrrsetbyname.c glob.c \ - openssl-compat.c port-tun.c strtonum.c vis.c xcrypt.c xmmap.c + openssl-compat.c port-tun.c strtonum.c timingsafe_bcmp.c \ + vis.c xcrypt.c xmmap.c # FreeBSD additions SRCS+= version.c diff --git a/secure/usr.sbin/sshd/Makefile b/secure/usr.sbin/sshd/Makefile index b0b8bb7..702bcd0 100644 --- a/secure/usr.sbin/sshd/Makefile +++ b/secure/usr.sbin/sshd/Makefile @@ -5,16 +5,17 @@ PROG= sshd SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ + audit.c audit-bsm.c audit-linux.c platform.c \ sshpty.c sshlogin.c servconf.c serverloop.c \ auth.c auth1.c auth2.c auth-options.c session.c \ auth-chall.c auth2-chall.c groupaccess.c \ auth-skey.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \ auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-jpake.c \ - monitor_mm.c monitor.c monitor_wrap.c kexdhs.c kexgexs.c \ + monitor_mm.c monitor.c monitor_wrap.c kexdhs.c kexgexs.c kexecdhs.c \ auth-krb5.c \ auth2-gss.c gss-serv.c gss-serv-krb5.c \ loginrec.c auth-pam.c auth-shadow.c auth-sia.c md5crypt.c \ - audit.c audit-bsm.c platform.c sftp-server.c sftp-common.c \ + sftp-server.c sftp-common.c \ roaming_common.c roaming_serv.c # gss-genr.c really belongs in libssh; see src/secure/lib/libssh/Makefile |