From d44870087da70034f43297ca70c9bf10200edec7 Mon Sep 17 00:00:00 2001 From: basney Date: Tue, 11 Sep 2007 19:17:11 +0000 Subject: [PATCH] Import of OpenSSH 4.7p1 --- openssh/ChangeLog | 368 +++++ openssh/INSTALL | 57 +- openssh/LICENCE | 1 + openssh/Makefile.in | 7 +- openssh/README | 2 +- openssh/README.platform | 14 + openssh/atomicio.c | 30 +- openssh/auth-pam.c | 13 +- openssh/auth-shadow.c | 1 + openssh/auth.c | 8 +- openssh/auth2.c | 4 +- openssh/bufbn.c | 6 +- openssh/buildpkg.sh.in | 34 +- openssh/channels.c | 15 +- openssh/channels.h | 6 +- openssh/cipher-3des1.c | 4 +- openssh/cipher-bf1.c | 4 +- openssh/cipher-ctr.c | 8 +- openssh/clientloop.c | 89 +- openssh/clientloop.h | 3 +- openssh/configure.ac | 91 +- openssh/contrib/caldera/openssh.spec | 2 +- openssh/contrib/redhat/openssh.spec | 2 +- openssh/contrib/suse/openssh.spec | 2 +- openssh/defines.h | 17 +- openssh/entropy.c | 3 +- openssh/gss-genr.c | 51 +- openssh/gss-serv.c | 50 +- openssh/includes.h | 2 +- openssh/kex.c | 21 +- openssh/kex.h | 8 +- openssh/key.c | 4 +- openssh/log.c | 5 +- openssh/loginrec.c | 1 + openssh/mac.c | 127 +- openssh/mac.h | 6 +- openssh/mdoc2man.awk | 18 +- openssh/monitor.c | 3 +- openssh/monitor_wrap.c | 6 +- openssh/myproposal.h | 4 +- openssh/openbsd-compat/Makefile.in | 2 +- openssh/openbsd-compat/bsd-cray.c | 2 - openssh/openbsd-compat/bsd-getpeereid.c | 22 + openssh/openbsd-compat/bsd-misc.c | 5 +- openssh/openbsd-compat/bsd-poll.c | 117 ++ openssh/openbsd-compat/bsd-poll.h | 61 + openssh/openbsd-compat/getrrsetbyname.c | 8 +- openssh/openbsd-compat/openbsd-compat.h | 1 + openssh/openbsd-compat/openssl-compat.h | 5 + openssh/openbsd-compat/port-aix.c | 2 +- openssh/openbsd-compat/port-linux.c | 2 + openssh/openbsd-compat/port-uw.c | 6 +- openssh/openbsd-compat/port-uw.h | 2 +- .../openbsd-compat/regress/closefromtest.c | 2 +- openssh/openbsd-compat/xcrypt.c | 2 +- openssh/openbsd-compat/xmmap.c | 4 +- openssh/openssh.xml.in | 4 +- openssh/packet.c | 10 +- openssh/readconf.c | 4 +- openssh/regress/agent-getpeereid.sh | 4 +- openssh/scard-opensc.c | 1 + openssh/scp.1 | 6 +- openssh/scp.c | 22 +- openssh/servconf.c | 7 +- openssh/session.c | 28 +- openssh/sftp-server.8 | 4 +- openssh/sftp-server.c | 34 +- openssh/sftp.1 | 4 +- openssh/ssh-add.1 | 17 +- openssh/ssh-agent.1 | 4 +- openssh/ssh-agent.c | 66 +- openssh/ssh-gss.h | 5 +- openssh/ssh-keygen.1 | 4 +- openssh/ssh-keyscan.1 | 4 +- openssh/ssh-keysign.8 | 4 +- openssh/ssh-rand-helper.c | 1 + openssh/ssh.1 | 11 +- openssh/ssh.c | 95 +- openssh/ssh_config | 3 +- openssh/ssh_config.5 | 11 +- openssh/sshconnect2.c | 16 +- openssh/sshd.8 | 39 +- openssh/sshd.c | 6 +- openssh/sshd_config | 8 +- openssh/sshd_config.5 | 9 +- openssh/umac.c | 1272 +++++++++++++++++ openssh/umac.h | 123 ++ openssh/version.h | 4 +- 88 files changed, 2736 insertions(+), 434 deletions(-) create mode 100644 openssh/openbsd-compat/bsd-poll.c create mode 100644 openssh/openbsd-compat/bsd-poll.h create mode 100644 openssh/umac.c create mode 100644 openssh/umac.h diff --git a/openssh/ChangeLog b/openssh/ChangeLog index e746b83..1242fa0 100644 --- a/openssh/ChangeLog +++ b/openssh/ChangeLog @@ -1,3 +1,371 @@ +20070817 + - (dtucker) [sshd.8] Many Linux variants use a single "!" to denote locked + accounts and that's what the code looks for, so make man page and code + agree. Pointed out by Roumen Petrov. + - (dtucker) [INSTALL] Group the parts describing random options and PAM + implementations together which is hopefully more coherent. + - (dtucker) [INSTALL] the pid file is sshd.pid not ssh.pid. + - (dtucker) [INSTALL] Give PAM its own heading. + - (dtucker) [INSTALL] Link to tcpwrappers. + +20070816 + - (dtucker) [session.c] Call PAM cleanup functions for unauthenticated + connections too. Based on a patch from Sandro Wefel, with & ok djm@ + +20070815 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2007/08/15 08:14:46 + [clientloop.c] + do NOT fall back to the trused x11 cookie if generation of an untrusted + cookie fails; from Jan Pechanec, via security-alert at sun.com; + ok dtucker + - markus@cvs.openbsd.org 2007/08/15 08:16:49 + [version.h] + openssh 4.7 + - stevesk@cvs.openbsd.org 2007/08/15 12:13:41 + [ssh_config.5] + tun device forwarding now honours ExitOnForwardFailure; ok markus@ + - (dtucker) [openbsd-compat/bsd-cray.c] Remove debug from signal handler. + ok djm@ + - (dtucker) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec + contrib/suse/openssh.spec] Crank version. + +20070813 + - (dtucker) [session.c] Bug #1339: ensure that pam_setcred() is always + called with PAM_ESTABLISH_CRED at least once, which resolves a problem + with pam_dhkeys. Patch from David Leonard, ok djm@ + +20070810 + - (dtucker) [auth-pam.c] Use sigdie here too. ok djm@ + - (dtucker) [configure.ac] Bug #1343: Set DISABLE_FD_PASSING for QNX6. From + Matt Kraai, ok djm@ + +20070809 + - (dtucker) [openbsd-compat/port-aix.c] Comment typo. + - (dtucker) [README.platform] Document the interaction between PermitRootLogin + and the AIX native login restrictions. + - (dtucker) [defines.h] Remove _PATH_{CSHELL,SHELLS} which aren't + used anywhere and are a potential source of warnings. + +20070808 + - (djm) OpenBSD CVS Sync + - ray@cvs.openbsd.org 2007/07/12 05:48:05 + [key.c] + Delint: remove some unreachable statements, from Bret Lambert. + OK markus@ and dtucker@. + - sobrado@cvs.openbsd.org 2007/08/06 19:16:06 + [scp.1 scp.c] + the ellipsis is not an optional argument; while here, sync the usage + and synopsis of commands + lots of good ideas by jmc@ + ok jmc@ + - djm@cvs.openbsd.org 2007/08/07 07:32:53 + [clientloop.c clientloop.h ssh.c] + bz#1232: ensure that any specified LocalCommand is executed after the + tunnel device is opened. Also, make failures to open a tunnel device + fatal when ExitOnForwardFailure is active. + Reported by h.goebel AT goebel-consult.de; ok dtucker markus reyk deraadt + +20070724 + - (tim) [openssh.xml.in] make FMRI match what package scripts use. + - (tim) [openbsd-compat/regress/closefromtest.c] Bug 1345: fix open() call. + Report/patch by David.Leonard AT quest.com (and Bernhard Simon) + - (tim) [buildpkg.sh.in openssh.xml.in] Allow more flexibility where smf(5) + - (tim) [buildpkg.sh.in] s|$FAKE_ROOT/${sysconfdir}|$FAKE_ROOT${sysconfdir}| + +20070628 + - (djm) bz#1325: Fix SELinux in permissive mode where it would + incorrectly fatal() on errors. patch from cjwatson AT debian.org; + ok dtucker + +20070625 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2007/06/13 00:21:27 + [scp.c] + don't ftruncate() non-regular files; bz#1236 reported by wood AT + xmission.com; ok dtucker@ + - djm@cvs.openbsd.org 2007/06/14 21:43:25 + [ssh.c] + handle EINTR when waiting for mux exit status properly + - djm@cvs.openbsd.org 2007/06/14 22:48:05 + [ssh.c] + when waiting for the multiplex exit status, read until the master end + writes an entire int of data *and* closes the client_fd; fixes mux + regression spotted by dtucker, ok dtucker@ + - djm@cvs.openbsd.org 2007/06/19 02:04:43 + [atomicio.c] + if the fd passed to atomicio/atomiciov() is non blocking, then poll() to + avoid a spin if it is not yet ready for reading/writing; ok dtucker@ + - dtucker@cvs.openbsd.org 2007/06/25 08:20:03 + [channels.c] + Correct test for window updates every three packets; prevents sending + window updates for every single packet. ok markus@ + - dtucker@cvs.openbsd.org 2007/06/25 12:02:27 + [atomicio.c] + Include like the man page says rather than . ok djm@ + - (dtucker) [atomicio.c] Test for EWOULDBLOCK in atomiciov to match + atomicio. + - (dtucker) [atomicio.c configure.ac openbsd-compat/Makefile.in + openbsd-compat/bsd-poll.{c,h} openbsd-compat/openbsd-compat.h] + Add an implementation of poll() built on top of select(2). Code from + OpenNTPD with changes suggested by djm. ok djm@ + +20070614 + - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the + USE_BUILTIN_RIJNDAEL compat goop to openssl-compat.h so it can be + shared with umac.c. Allows building with OpenSSL 0.9.5 again including + umac support. With tim@ djm@, ok djm. + - (dtucker) [openbsd-compat/openssl-compat.h] Merge USE_BUILTIN_RIJNDAEL + sections. Fixes builds with early OpenSSL 0.9.6 versions. + - (dtucker) [openbsd-compat/openssl-compat.h] Remove redundant definition + of USE_BUILTIN_RIJNDAEL since the <0.9.6 test is covered by the + subsequent <0.9.7 test. + +20070612 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2007/06/11 09:14:00 + [channels.h] + increase default channel windows; ok djm + - djm@cvs.openbsd.org 2007/06/12 07:41:00 + [ssh-add.1] + better document ssh-add's -d option (delete identies from agent), bz#1224 + new text based on some provided by andrewmc-debian AT celt.dias.ie; + ok dtucker@ + - djm@cvs.openbsd.org 2007/06/12 08:20:00 + [ssh-gss.h gss-serv.c gss-genr.c] + relocate server-only GSSAPI code from libssh to server; bz #1225 + patch from simon AT sxw.org.uk; ok markus@ dtucker@ + - djm@cvs.openbsd.org 2007/06/12 08:24:20 + [scp.c] + make scp try to skip FIFOs rather than blocking when nothing is listening. + depends on the platform supporting sane O_NONBLOCK semantics for open + on FIFOs (apparently POSIX does not mandate this), which OpenBSD does. + bz #856; report by cjwatson AT debian.org; ok markus@ + - djm@cvs.openbsd.org 2007/06/12 11:11:08 + [ssh.c] + fix slave exit value when a control master goes away without passing the + full exit status by ensuring that the slave reads a full int. bz#1261 + reported by frekko AT gmail.com; ok markus@ dtucker@ + - djm@cvs.openbsd.org 2007/06/12 11:15:17 + [ssh.c ssh.1] + Add "-K" flag for ssh to set GSSAPIAuthentication=yes and + GSSAPIDelegateCredentials=yes. This is symmetric with -k (disable GSSAPI) + and is useful for hosts with /home on Kerberised NFS; bz #1312 + patch from Markus.Kuhn AT cl.cam.ac.uk; ok dtucker@ markus@ + - djm@cvs.openbsd.org 2007/06/12 11:45:27 + [ssh.c] + improved exit message from multiplex slave sessions; bz #1262 + reported by alexandre.nunes AT gmail.com; ok dtucker@ + - dtucker@cvs.openbsd.org 2007/06/12 11:56:15 + [gss-genr.c] + Pass GSS OID to gss_display_status to provide better information in + error messages. Patch from Simon Wilkinson via bz 1220. ok djm@ + - jmc@cvs.openbsd.org 2007/06/12 13:41:03 + [ssh-add.1] + identies -> identities; + - jmc@cvs.openbsd.org 2007/06/12 13:43:55 + [ssh.1] + add -K to SYNOPSIS; + - dtucker@cvs.openbsd.org 2007/06/12 13:54:28 + [scp.c] + Encode filename with strnvis if the name contains a newline (which can't + be represented in the scp protocol), from bz #891. ok markus@ + +20070611 + - (djm) Bugzilla #1306: silence spurious error messages from hang-on-exit + fix; tested by dtucker@ and jochen.kirn AT gmail.com + - pvalchev@cvs.openbsd.org 2007/06/07 19:37:34 + [kex.h mac.c mac.h monitor_wrap.c myproposal.h packet.c ssh.1] + [ssh_config.5 sshd.8 sshd_config.5] + Add a new MAC algorithm for data integrity, UMAC-64 (not default yet, + must specify umac-64@openssh.com). Provides about 20% end-to-end speedup + compared to hmac-md5. Represents a different approach to message + authentication to that of HMAC that may be beneficial if HMAC based on + one of its underlying hash algorithms is found to be vulnerable to a + new attack. http://www.ietf.org/rfc/rfc4418.txt + in conjunction with and OK djm@ + - pvalchev@cvs.openbsd.org 2007/06/08 04:40:40 + [ssh_config] + Add a "MACs" line after "Ciphers" with the default MAC algorithms, + to ease people who want to tweak both (eg. for performance reasons). + ok deraadt@ djm@ dtucker@ + - jmc@cvs.openbsd.org 2007/06/08 07:43:46 + [ssh_config.5] + put the MAC list into a display, like we do for ciphers, + since groff has trouble handling wide lines; + - jmc@cvs.openbsd.org 2007/06/08 07:48:09 + [sshd_config.5] + oops, here too: put the MAC list into a display, like we do for + ciphers, since groff has trouble with wide lines; + - markus@cvs.openbsd.org 2007/06/11 08:04:44 + [channels.c] + send 'window adjust' messages every tree packets and do not wait + until 50% of the window is consumed. ok djm dtucker + - (djm) [configure.ac umac.c] If platform doesn't provide swap32(3), then + fallback to provided bit-swizzing functions + - (dtucker) [openbsd-compat/bsd-misc.c] According to the spec the "remainder" + argument to nanosleep may be NULL. Currently this never happens in OpenSSH, + but check anyway in case this changes or the code gets used elsewhere. + - (dtucker) [includes.h] Bug #1243: HAVE_PATHS -> HAVE_PATHS_H. Should + prevent warnings about redefinitions of various things in paths.h. + Spotted by cartmanltd at hotmail.com. + +20070605 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2007/05/22 10:18:52 + [sshd.c] + zap double include; from p_nowaczyk AT o2.pl + (not required in -portable, Id sync only) + - djm@cvs.openbsd.org 2007/05/30 05:58:13 + [kex.c] + tidy: KNF, ARGSUSED and u_int + - jmc@cvs.openbsd.org 2007/05/31 19:20:16 + [scp.1 ssh_config.5 sftp-server.8 ssh-agent.1 sshd_config.5 sftp.1 + ssh-keygen.1 ssh-keyscan.1 ssh-add.1 sshd.8 ssh.1 ssh-keysign.8] + convert to new .Dd format; + (We will need to teach mdoc2man.awk to understand this too.) + - djm@cvs.openbsd.org 2007/05/31 23:34:29 + [packet.c] + gc unreachable code; spotted by Tavis Ormandy + - djm@cvs.openbsd.org 2007/06/02 09:04:58 + [bufbn.c] + memory leak on error path; from arnaud.lacombe.1 AT ulaval.ca + - djm@cvs.openbsd.org 2007/06/05 06:52:37 + [kex.c monitor_wrap.c packet.c mac.h kex.h mac.c] + Preserve MAC ctx between packets, saving 2xhash calls per-packet. + Yields around a 12-16% end-to-end speedup for arcfour256/hmac-md5 + patch from markus@ tested dtucker@ and myself, ok markus@ and me (I'm + committing at his request) + - (dtucker) [mdoc2man.awk] Teach it to deal with $Mdocdate tags that + OpenBSD's cvs now adds. + - (dtucker) [mdoc2man.awk] Remove trailing "$" from Mdocdate regex so + mindrot's cvs doesn't expand it on us. + - (dtucker) [mdoc2man.awk] Add support for %R references, used for RFCs. + +20070520 + - (dtucker) OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2007/04/14 22:01:58 + [auth2.c] + remove unused macro; from Dmitry V. Levin + - stevesk@cvs.openbsd.org 2007/04/18 01:12:43 + [sftp-server.c] + cast "%llu" format spec to (unsigned long long); do not assume a + u_int64_t arg is the same as 'unsigned long long'. + from Dmitry V. Levin + ok markus@ 'Yes, that looks correct' millert@ + - dtucker@cvs.openbsd.org 2007/04/23 10:15:39 + [servconf.c] + Remove debug() left over from development. ok deraadt@ + - djm@cvs.openbsd.org 2007/05/17 07:50:31 + [log.c] + save and restore errno when logging; ok deraadt@ + - djm@cvs.openbsd.org 2007/05/17 07:55:29 + [sftp-server.c] + bz#1286 stop reading and processing commands when input or output buffer + is nearly full, otherwise sftp-server would happily try to grow the + input/output buffers past the maximum supported by the buffer API and + promptly fatal() + based on patch from Thue Janus Kristensen; feedback & ok dtucker@ + - djm@cvs.openbsd.org 2007/05/17 20:48:13 + [sshconnect2.c] + fall back to gethostname() when the outgoing connection is not + on a socket, such as is the case when ProxyCommand is used. + Gives hostbased auth an opportunity to work; bz#616, report + and feedback stuart AT kaloram.com; ok markus@ + - djm@cvs.openbsd.org 2007/05/17 20:52:13 + [monitor.c] + pass received SIGINT from monitor to postauth child so it can clean + up properly. bz#1196, patch from senthilkumar_sen AT hotpop.com; + ok markus@ + - jolan@cvs.openbsd.org 2007/05/17 23:53:41 + [sshconnect2.c] + djm owes me a vb and a tism cd for breaking ssh compilation + - (dtucker) [auth-pam.c] malloc+memset -> calloc. Patch from + ldv at altlinux.org. + - (dtucker) [auth-pam.c] Return empty string if fgets fails in + sshpam_tty_conv. Patch from ldv at altlinux.org. + +20070509 + - (tim) [configure.ac] Bug #1287: Add missing test for ucred.h. + +20070429 + - (dtucker) [openbsd-compat/bsd-misc.c] Include unistd.h and sys/types.h + for select(2) prototype. + - (dtucker) [auth-shadow.c loginrec.c] Include time.h for time(2) prototype. + - (dtucker) [configure.ac openbsd-compat/getrrsetbyname.c] Bug #1299: Use the + platform's _res if it has one. Should fix problem of DNSSEC record lookups + on NetBSD as reported by Curt Sampson. + - (dtucker) [openbsd-compat/xmmap.c] Include stdlib.h for mkstemp prototype. + - (dtucker) [configure.ac defines.h] Have configure check for MAXSYMLINKS + so we don't get redefinition warnings. + - (dtucker) [openbsd-compat/xmmap.c] Include stdlib.h for mkstemp prototype. + - (dtucker) [configure.ac defines.h] Prevent warnings about __attribute__ + __nonnull__ for versions of GCC that don't support it. + - (dtucker) [configure.ac defines.h] Have configure check for offsetof + to prevent redefinition warnings. + +20070406 + - (dtucker) [INSTALL] Update the systems that have PAM as standard. Link + to OpenPAM too. + - (dtucker) [INSTALL] prngd lives at sourceforge these days. + +20070326 + - (tim) [auth.c configure.ac defines.h session.c openbsd-compat/port-uw.c + openbsd-compat/port-uw.h openbsd-compat/xcrypt.c] Rework libiaf test/defines + to account for IRIX having libiaf but not set_id(). Patch with & ok dtucker@ + +20070325 + - (dtucker) [Makefile.in configure.ac] Replace single-purpose LIBSELINUX, + LIBWRAP and LIBPAM variables in Makefile with the general-purpose + SSHDLIBS. "I like" djm@ + +20070321 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2007/03/09 05:20:06 + [servconf.c sshd.c] + Move C/R -> kbdint special case to after the defaults have been + loaded, which makes ChallengeResponse default to yes again. This + was broken by the Match changes and not fixed properly subsequently. + Found by okan at demirmen.com, ok djm@ "please do it" deraadt@ + - djm@cvs.openbsd.org 2007/03/19 01:01:29 + [sshd_config] + Disable the legacy SSH protocol 1 for new installations via + a configuration override. In the future, we will change the + server's default itself so users who need the legacy protocol + will need to turn it on explicitly + - dtucker@cvs.openbsd.org 2007/03/19 12:16:42 + [ssh-agent.c] + Remove the signal handler that checks if the agent's parent process + has gone away, instead check when the select loop returns. Record when + the next key will expire when scanning for expired keys. Set the select + timeout to whichever of these two things happens next. With djm@, with & + ok deraadt@ markus@ + - tedu@cvs.openbsd.org 2007/03/20 03:56:12 + [readconf.c clientloop.c] + remove some bogus *p tests from charles longeau + ok deraadt millert + - jmc@cvs.openbsd.org 2007/03/20 15:57:15 + [sshd.8] + - let synopsis and description agree for -f + - sort FILES + - +.Xr ssh-keyscan 1 , + from Igor Sobrado + - (dtucker) [configure.ac openbsd-compat/bsd-getpeereid.c] Bug #1287: Use + getpeerucred to implement getpeereid (currently only Solaris 10 and up). + Patch by Jan.Pechanec at Sun. + - (dtucker) [regress/agent-getpeereid.sh] Do peereid test if we have + HAVE_GETPEERUCRED too. Also from Jan Pechanec. + +20070313 + - (dtucker) [entropy.c scard-opensc.c ssh-rand-helper.c] Bug #1294: include + string.h to prevent warnings, from vapier at gentoo.org. + - (dtucker) [LICENCE] Add Daniel Walsh as a copyright holder for the + selinux bits in -portable. + - (dtucker) [cipher-3des1.c cipher-bf1.c] The OpenSSL 0.9.8e problem in + bug #1291 also affects Protocol 1 3des. While at it, use compat-openssl.h + in cipher-bf1.c. Patch from Juan Gallego. + - (dtucker) [README.platform] Info about blibpath on AIX. + 20070306 - (djm) OpenBSD CVS Sync - jmc@cvs.openbsd.org 2007/03/01 16:19:33 diff --git a/openssh/INSTALL b/openssh/INSTALL index 92001d4..a35c674 100644 --- a/openssh/INSTALL +++ b/openssh/INSTALL @@ -14,17 +14,37 @@ Blowfish) do not work correctly.) The remaining items are optional. -OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system -supports it. PAM is standard on Redhat and Debian Linux, Solaris and -HP-UX 11. - NB. If you operating system supports /dev/random, you should configure OpenSSL to use it. OpenSSH relies on OpenSSL's direct support of -/dev/random. If you don't you will have to rely on ssh-rand-helper, which -is inferior to a good kernel-based solution. +/dev/random, or failing that, either prngd or egd. If you don't have +any of these you will have to rely on ssh-rand-helper, which is inferior +to a good kernel-based solution or prngd. + +PRNGD: + +If your system lacks kernel-based random collection, the use of Lutz +Jaenicke's PRNGd is recommended. + +http://prngd.sourceforge.net/ + +EGD: + +The Entropy Gathering Daemon (EGD) is supported if you have a system which +lacks /dev/random and don't want to use OpenSSH's internal entropy collection. + +http://www.lothar.com/tech/crypto/ PAM: -http://www.kernel.org/pub/linux/libs/pam/ + +OpenSSH can utilise Pluggable Authentication Modules (PAM) if your +system supports it. PAM is standard most Linux distributions, Solaris, +HP-UX 11, AIX >= 5.2, FreeBSD and NetBSD. + +Information about the various PAM implementations are available: + +Solaris PAM: http://www.sun.com/software/solaris/pam/ +Linux PAM: http://www.kernel.org/pub/linux/libs/pam/ +OpenPAM: http://www.openpam.org/ If you wish to build the GNOME passphrase requester, you will need the GNOME libraries and headers. @@ -37,19 +57,14 @@ passphrase requester. This is maintained separately at: http://www.jmknoble.net/software/x11-ssh-askpass/ -PRNGD: - -If your system lacks Kernel based random collection, the use of Lutz -Jaenicke's PRNGd is recommended. - -http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html - -EGD: +TCP Wrappers: -The Entropy Gathering Daemon (EGD) is supported if you have a system which -lacks /dev/random and don't want to use OpenSSH's internal entropy collection. +If you wish to use the TCP wrappers functionality you will need at least +tcpd.h and libwrap.a, either in the standard include and library paths, +or in the directory specified by --with-tcp-wrappers. Version 7.6 is +known to work. -http://www.lothar.com/tech/crypto/ +http://ftp.porcupine.org/pub/security/index.html S/Key Libraries: @@ -72,7 +87,7 @@ Autoconf: If you modify configure.ac or configure doesn't exist (eg if you checked the code out of CVS yourself) then you will need autoconf-2.61 to rebuild the automatically generated files by running "autoreconf". Earlier -version may also work but this is not guaranteed. +versions may also work but this is not guaranteed. http://www.gnu.org/software/autoconf/ @@ -162,7 +177,7 @@ Integration Architecture. The default for OSF1 machines is enable. need the S/Key libraries and header files installed for this to work. --with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) -support. You will need libwrap.a and tcpd.h installed. +support. --with-md5-passwords will enable the use of MD5 passwords. Enable this if your operating system uses MD5 passwords and the system crypt() does @@ -180,7 +195,7 @@ $DISPLAY environment variable. Some broken systems need this. --with-default-path=PATH allows you to specify a default $PATH for sessions started by sshd. This replaces the standard path entirely. ---with-pid-dir=PATH specifies the directory in which the ssh.pid file is +--with-pid-dir=PATH specifies the directory in which the sshd.pid file is created. --with-xauth=PATH specifies the location of the xauth binary diff --git a/openssh/LICENCE b/openssh/LICENCE index 0c2ff06..3964b1d 100644 --- a/openssh/LICENCE +++ b/openssh/LICENCE @@ -205,6 +205,7 @@ OpenSSH contains no GPL code. Darren Tucker Sun Microsystems The SCO Group + Daniel Walsh * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/openssh/Makefile.in b/openssh/Makefile.in index bc3a925..c9cb175 100644 --- a/openssh/Makefile.in +++ b/openssh/Makefile.in @@ -44,11 +44,8 @@ LD=@LD@ CFLAGS=@CFLAGS@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ LIBS=@LIBS@ -LIBSELINUX=@LIBSELINUX@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ -LIBPAM=@LIBPAM@ -LIBWRAP=@LIBWRAP@ AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ @@ -74,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ - entropy.o scard-opensc.o gss-genr.o + entropy.o scard-opensc.o gss-genr.o umac.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o @@ -139,7 +136,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBSELINUX) $(SSHDLIBS) $(LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/openssh/README b/openssh/README index 2d67d7a..b32077a 100644 --- a/openssh/README +++ b/openssh/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-4.6 for the release notes. +See http://www.openssh.com/txt/release-4.7 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html diff --git a/openssh/README.platform b/openssh/README.platform index 5724b68..c54dbf4 100644 --- a/openssh/README.platform +++ b/openssh/README.platform @@ -23,6 +23,20 @@ to force the previous IPv4-only behaviour. IPv6 known to work: 5.1ML7 5.2ML2 5.2ML5 IPv6 known broken: 4.3.3ML11 5.1ML4 +If you wish to use dynamic libraries that aren't in the normal system +locations (eg IBM's OpenSSL and zlib packages) then you will need to +define the environment variable blibpath before running configure, eg + +blibpath=/lib:/usr/lib:/opt/freeware/lib ./configure \ + --with-ssl-dir=/opt/freeware --with-zlib=/opt/freeware + +If sshd is built with the WITH_AIXAUTHENTICATE option (which is enabled +by default) then sshd checks that users are permitted via the +loginrestrictions() function, in particular that the user has the +"rlogin" attribute set. This check is not done for the root account, +instead the PermitRootLogin setting in sshd_config is used. + + Cygwin ------ To build on Cygwin, OpenSSH requires the following packages: diff --git a/openssh/atomicio.c b/openssh/atomicio.c index f651a29..f32ff85 100644 --- a/openssh/atomicio.c +++ b/openssh/atomicio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.c,v 1.23 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: atomicio.c,v 1.25 2007/06/25 12:02:27 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller. All rights reserved. * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. @@ -32,7 +32,11 @@ #include #include +#ifdef HAVE_POLL_H +#include +#endif #include +#include #include "atomicio.h" @@ -45,17 +49,24 @@ atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) char *s = _s; size_t pos = 0; ssize_t res; + struct pollfd pfd; + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; while (n > pos) { res = (f) (fd, s + pos, n - pos); switch (res) { case -1: #ifdef EWOULDBLOCK - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + if (errno == EINTR || errno == EWOULDBLOCK) #else - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR) #endif continue; + if (errno == EAGAIN) { + (void)poll(&pfd, 1, -1); + continue; + } return 0; case 0: errno = EPIPE; @@ -77,6 +88,7 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, size_t pos = 0, rem; ssize_t res; struct iovec iov_array[IOV_MAX], *iov = iov_array; + struct pollfd pfd; if (iovcnt > IOV_MAX) { errno = EINVAL; @@ -85,12 +97,22 @@ atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, /* Make a copy of the iov array because we may modify it below */ memcpy(iov, _iov, iovcnt * sizeof(*_iov)); + pfd.fd = fd; + pfd.events = f == readv ? POLLIN : POLLOUT; for (; iovcnt > 0 && iov[0].iov_len > 0;) { res = (f) (fd, iov, iovcnt); switch (res) { case -1: - if (errno == EINTR || errno == EAGAIN) +#ifdef EWOULDBLOCK + if (errno == EINTR || errno == EWOULDBLOCK) +#else + if (errno == EINTR) +#endif continue; + if (errno == EAGAIN) { + (void)poll(&pfd, 1, -1); + continue; + } return 0; case 0: errno = EPIPE; diff --git a/openssh/auth-pam.c b/openssh/auth-pam.c index c08d472..a07f1fe 100644 --- a/openssh/auth-pam.c +++ b/openssh/auth-pam.c @@ -161,9 +161,9 @@ sshpam_sigchld_handler(int sig) WTERMSIG(sshpam_thread_status) == SIGTERM) return; /* terminated by pthread_cancel */ if (!WIFEXITED(sshpam_thread_status)) - fatal("PAM: authentication thread exited unexpectedly"); + sigdie("PAM: authentication thread exited unexpectedly"); if (WEXITSTATUS(sshpam_thread_status) != 0) - fatal("PAM: authentication thread exited uncleanly"); + sigdie("PAM: authentication thread exited uncleanly"); } /* ARGSUSED */ @@ -686,8 +686,7 @@ sshpam_init_ctx(Authctxt *authctxt) return (NULL); } - ctxt = xmalloc(sizeof *ctxt); - memset(ctxt, 0, sizeof(*ctxt)); + ctxt = xcalloc(1, sizeof *ctxt); /* Start the authentication thread */ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { @@ -985,7 +984,8 @@ sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, break; case PAM_PROMPT_ECHO_ON: fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); - fgets(input, sizeof input, stdin); + if (fgets(input, sizeof input, stdin) == NULL) + input[0] = '\0'; if ((reply[i].resp = strdup(input)) == NULL) goto fail; reply[i].resp_retcode = PAM_SUCCESS; @@ -1130,9 +1130,8 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg, if (n <= 0 || n > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); - if ((reply = malloc(n * sizeof(*reply))) == NULL) + if ((reply = calloc(n, sizeof(*reply))) == NULL) return (PAM_CONV_ERR); - memset(reply, 0, n * sizeof(*reply)); for (i = 0; i < n; ++i) { switch (PAM_MSG_MEMBER(msg, i, msg_style)) { diff --git a/openssh/auth-shadow.c b/openssh/auth-shadow.c index 8b3160a..2190916 100644 --- a/openssh/auth-shadow.c +++ b/openssh/auth-shadow.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "key.h" #include "hostfile.h" diff --git a/openssh/auth.c b/openssh/auth.c index 505102f..c1e0f48 100644 --- a/openssh/auth.c +++ b/openssh/auth.c @@ -115,11 +115,11 @@ allowed_user(struct passwd * pw) /* grab passwd field for locked account check */ #ifdef USE_SHADOW if (spw != NULL) -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF passwd = get_iaf_password(pw); #else passwd = spw->sp_pwdp; -#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ +#endif /* USE_LIBIAF */ #else passwd = pw->pw_passwd; #endif @@ -141,9 +141,9 @@ allowed_user(struct passwd * pw) if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) locked = 1; #endif -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF free(passwd); -#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ +#endif /* USE_LIBIAF */ if (locked) { logit("User %.100s not allowed because account is locked", pw->pw_name); diff --git a/openssh/auth2.c b/openssh/auth2.c index b1a4e36..bded8c2 100644 --- a/openssh/auth2.c +++ b/openssh/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.114 2007/03/01 10:28:02 dtucker Exp $ */ +/* $OpenBSD: auth2.c,v 1.115 2007/04/14 22:01:58 stevesk Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -281,8 +281,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) } } -#define DELIM "," - static char * authmethods_get(void) { diff --git a/openssh/bufbn.c b/openssh/bufbn.c index ce8fba5..251cd09 100644 --- a/openssh/bufbn.c +++ b/openssh/bufbn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufbn.c,v 1.5 2007/02/14 14:32:00 stevesk Exp $*/ +/* $OpenBSD: bufbn.c,v 1.6 2007/06/02 09:04:58 djm Exp $*/ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -201,12 +201,14 @@ buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value) return (-1); } if (len > 8 * 1024) { - error("buffer_get_bignum2_ret: cannot handle BN of size %d", len); + error("buffer_get_bignum2_ret: cannot handle BN of size %d", + len); xfree(bin); return (-1); } if (BN_bin2bn(bin, len, value) == NULL) { error("buffer_get_bignum2_ret: BN_bin2bn failed"); + xfree(bin); return (-1); } xfree(bin); diff --git a/openssh/buildpkg.sh.in b/openssh/buildpkg.sh.in index 8a96b90..22c66fb 100644 --- a/openssh/buildpkg.sh.in +++ b/openssh/buildpkg.sh.in @@ -49,6 +49,8 @@ PKG_REQUEST_LOCAL=../pkg-request.local OPENSSHD=opensshd.init OPENSSH_MANIFEST=openssh.xml OPENSSH_FMRI=svc:/site/${SYSVINIT_NAME}:default +SMF_METHOD_DIR=/lib/svc/method/site +SMF_MANIFEST_DIR=/var/svc/manifest/site PATH_GROUPADD_PROG=@PATH_GROUPADD_PROG@ PATH_USERADD_PROG=@PATH_USERADD_PROG@ @@ -196,15 +198,17 @@ then # For Solaris' SMF, /lib/svc/method/site is the preferred place # for start/stop scripts that aren't supplied with the OS, and # similarly /var/svc/manifest/site for manifests. - mkdir -p $FAKE_ROOT${TEST_DIR}/lib/svc/method/site - mkdir -p $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site + mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR} + mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR} - cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/lib/svc/method/site/${SYSVINIT_NAME} - chmod 744 $FAKE_ROOT${TEST_DIR}/lib/svc/method/site/${SYSVINIT_NAME} + cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME} + chmod 744 $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME} - cat ${OPENSSH_MANIFEST} | sed "s|__SYSVINIT_NAME__|${SYSVINIT_NAME}|" \ - > $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site/${SYSVINIT_NAME}.xml - chmod 644 $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site/${SYSVINIT_NAME}.xml + cat ${OPENSSH_MANIFEST} | \ + sed -e "s|__SYSVINIT_NAME__|${SYSVINIT_NAME}|" \ + -e "s|__SMF_METHOD_DIR__|${SMF_METHOD_DIR}|" \ + > $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml + chmod 644 $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml else mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d @@ -214,19 +218,19 @@ fi [ "${PERMIT_ROOT_LOGIN}" = no ] && \ perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \ - $FAKE_ROOT/${sysconfdir}/sshd_config + $FAKE_ROOT${sysconfdir}/sshd_config [ "${X11_FORWARDING}" = yes ] && \ perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \ - $FAKE_ROOT/${sysconfdir}/sshd_config + $FAKE_ROOT${sysconfdir}/sshd_config # fix PrintMotd perl -p -i -e "s/#PrintMotd yes/PrintMotd no/" \ - $FAKE_ROOT/${sysconfdir}/sshd_config + $FAKE_ROOT${sysconfdir}/sshd_config # We don't want to overwrite config files on multiple installs -mv $FAKE_ROOT/${sysconfdir}/ssh_config $FAKE_ROOT/${sysconfdir}/ssh_config.default -mv $FAKE_ROOT/${sysconfdir}/sshd_config $FAKE_ROOT/${sysconfdir}/sshd_config.default -[ -f $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds ] && \ -mv $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds.default +mv $FAKE_ROOT${sysconfdir}/ssh_config $FAKE_ROOT${sysconfdir}/ssh_config.default +mv $FAKE_ROOT${sysconfdir}/sshd_config $FAKE_ROOT${sysconfdir}/sshd_config.default +[ -f $FAKE_ROOT${sysconfdir}/ssh_prng_cmds ] && \ +mv $FAKE_ROOT${sysconfdir}/ssh_prng_cmds $FAKE_ROOT${sysconfdir}/ssh_prng_cmds.default # local tweeks here [ -s "${POST_MAKE_INSTALL_FIXES}" ] && . ${POST_MAKE_INSTALL_FIXES} @@ -336,7 +340,7 @@ then svccfg delete -f $OPENSSH_FMRI fi # NOTE, The manifest disables sshd by default. - svccfg import ${TEST_DIR}/var/svc/manifest/site/${SYSVINIT_NAME}.xml + svccfg import ${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml else if [ "\${USE_SYM_LINKS}" = yes ] then diff --git a/openssh/channels.c b/openssh/channels.c index c68ad64..2006353 100644 --- a/openssh/channels.c +++ b/openssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.268 2007/01/03 03:01:40 stevesk Exp $ */ +/* $OpenBSD: channels.c,v 1.270 2007/06/25 08:20:03 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1446,14 +1446,13 @@ static int channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset) { char buf[CHAN_RBUF]; - int len; + int len, force; - if (c->rfd != -1 && - (c->detach_close || FD_ISSET(c->rfd, readset))) { + force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED; + if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) { errno = 0; len = read(c->rfd, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || - (errno == EAGAIN && !(c->isatty && c->detach_close)))) + if (len < 0 && (errno == EINTR || (errno == EAGAIN && !force))) return 1; #ifndef PTY_ZEROREAD if (len <= 0) { @@ -1658,7 +1657,9 @@ channel_check_window(Channel *c) { if (c->type == SSH_CHANNEL_OPEN && !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && - c->local_window < c->local_window_max/2 && + ((c->local_window_max - c->local_window > + c->local_maxpacket*3) || + c->local_window < c->local_window_max/2) && c->local_consumed > 0) { packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); packet_put_int(c->remote_id); diff --git a/openssh/channels.h b/openssh/channels.h index 2674f09..b632a86 100644 --- a/openssh/channels.h +++ b/openssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.88 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: channels.h,v 1.89 2007/06/11 09:14:00 markus Exp $ */ /* * Author: Tatu Ylonen @@ -122,9 +122,9 @@ struct Channel { /* default window/packet sizes for tcp/x11-fwd-channel */ #define CHAN_SES_PACKET_DEFAULT (32*1024) -#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT) +#define CHAN_SES_WINDOW_DEFAULT (64*CHAN_SES_PACKET_DEFAULT) #define CHAN_TCP_PACKET_DEFAULT (32*1024) -#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT) +#define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT) #define CHAN_X11_PACKET_DEFAULT (16*1024) #define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) diff --git a/openssh/cipher-3des1.c b/openssh/cipher-3des1.c index fc16e20..17a13a1 100644 --- a/openssh/cipher-3des1.c +++ b/openssh/cipher-3des1.c @@ -35,9 +35,7 @@ #include "xmalloc.h" #include "log.h" -#if OPENSSL_VERSION_NUMBER < 0x00906000L -#define SSH_OLD_EVP -#endif +#include "openbsd-compat/openssl-compat.h" /* * This is used by SSH1: diff --git a/openssh/cipher-bf1.c b/openssh/cipher-bf1.c index 292488c..e0e33b4 100644 --- a/openssh/cipher-bf1.c +++ b/openssh/cipher-bf1.c @@ -35,9 +35,7 @@ #include "xmalloc.h" #include "log.h" -#if OPENSSL_VERSION_NUMBER < 0x00906000L -#define SSH_OLD_EVP -#endif +#include "openbsd-compat/openssl-compat.h" /* * SSH1 uses a variation on Blowfish, all bytes must be swapped before diff --git a/openssh/cipher-ctr.c b/openssh/cipher-ctr.c index b24f3a4..3b86cc1 100644 --- a/openssh/cipher-ctr.c +++ b/openssh/cipher-ctr.c @@ -29,13 +29,7 @@ /* compatibility with old or broken OpenSSL versions */ #include "openbsd-compat/openssl-compat.h" -#ifdef USE_BUILTIN_RIJNDAEL -#include "rijndael.h" -#define AES_KEY rijndael_ctx -#define AES_BLOCK_SIZE 16 -#define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b) -#define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1) -#else +#ifndef USE_BUILTIN_RIJNDAEL #include #endif diff --git a/openssh/clientloop.c b/openssh/clientloop.c index c7362ca..b57fda0 100644 --- a/openssh/clientloop.c +++ b/openssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.178 2007/02/20 10:25:14 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.181 2007/08/15 08:14:46 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -290,19 +290,29 @@ client_x11_get_proto(const char *display, const char *xauth_path, generated = 1; } } - snprintf(cmd, sizeof(cmd), - "%s %s%s list %s 2>" _PATH_DEVNULL, - xauth_path, - generated ? "-f " : "" , - generated ? xauthfile : "", - display); - debug2("x11_get_proto: %s", cmd); - f = popen(cmd, "r"); - if (f && fgets(line, sizeof(line), f) && - sscanf(line, "%*s %511s %511s", proto, data) == 2) - got_data = 1; - if (f) - pclose(f); + + /* + * When in untrusted mode, we read the cookie only if it was + * successfully generated as an untrusted one in the step + * above. + */ + if (trusted || generated) { + snprintf(cmd, sizeof(cmd), + "%s %s%s list %s 2>" _PATH_DEVNULL, + xauth_path, + generated ? "-f " : "" , + generated ? xauthfile : "", + display); + debug2("x11_get_proto: %s", cmd); + f = popen(cmd, "r"); + if (f && fgets(line, sizeof(line), f) && + sscanf(line, "%*s %511s %511s", proto, data) == 2) + got_data = 1; + if (f) + pclose(f); + } else + error("Warning: untrusted X11 forwarding setup failed: " + "xauth key data not generated"); } if (do_unlink) { @@ -935,7 +945,7 @@ process_cmdline(void) cmd = s = read_passphrase("\r\nssh> ", RP_ECHO); if (s == NULL) goto out; - while (*s && isspace(*s)) + while (isspace(*s)) s++; if (*s == '-') s++; /* Skip cmdline '-', if any */ @@ -982,9 +992,8 @@ process_cmdline(void) goto out; } - s++; - while (*s && isspace(*s)) - s++; + while (isspace(*++s)) + ; if (delete) { cancel_port = 0; @@ -1774,6 +1783,50 @@ client_request_agent(const char *request_type, int rchan) return c; } +int +client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) +{ + Channel *c; + int fd; + + if (tun_mode == SSH_TUNMODE_NO) + return 0; + + if (!compat20) { + error("Tunnel forwarding is not support for protocol 1"); + return -1; + } + + debug("Requesting tun unit %d in mode %d", local_tun, tun_mode); + + /* Open local tunnel device */ + if ((fd = tun_open(local_tun, tun_mode)) == -1) { + error("Tunnel device open failed."); + return -1; + } + + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + c->datagram = 1; + +#if defined(SSH_TUN_FILTER) + if (options.tun_open == SSH_TUNMODE_POINTOPOINT) + channel_register_filter(c->self, sys_tun_infilter, + sys_tun_outfilter); +#endif + + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("tun@openssh.com"); + packet_put_int(c->self); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + packet_put_int(tun_mode); + packet_put_int(remote_tun); + packet_send(); + + return 0; +} + /* XXXX move to generic input handler */ static void client_input_channel_open(int type, u_int32_t seq, void *ctxt) diff --git a/openssh/clientloop.h b/openssh/clientloop.h index beec62f..c7d2233 100644 --- a/openssh/clientloop.h +++ b/openssh/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.16 2006/03/25 22:22:42 djm Exp $ */ +/* $OpenBSD: clientloop.h,v 1.17 2007/08/07 07:32:53 djm Exp $ */ /* * Author: Tatu Ylonen @@ -44,6 +44,7 @@ void client_x11_get_proto(const char *, const char *, u_int, void client_global_request_reply_fwd(int, u_int32_t, void *); void client_session2_setup(int, int, int, const char *, struct termios *, int, Buffer *, char **, dispatch_fn *); +int client_request_tun_fwd(int, int, int); /* Multiplexing protocol version */ #define SSHMUX_VER 1 diff --git a/openssh/configure.ac b/openssh/configure.ac index a07aa3c..a27c547 100644 --- a/openssh/configure.ac +++ b/openssh/configure.ac @@ -94,9 +94,12 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized" GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in - 1.*) ;; - 2.8* | 2.9*) CFLAGS="$CFLAGS -Wsign-compare" ;; - 2.*) ;; + 1.*) no_attrib_nonnull=1 ;; + 2.8* | 2.9*) + CFLAGS="$CFLAGS -Wsign-compare" + no_attrib_nonnull=1 + ;; + 2.*) no_attrib_nonnull=1 ;; 3.*) CFLAGS="$CFLAGS -Wsign-compare" ;; 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign" ;; *) ;; @@ -115,6 +118,10 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then fi fi +if test "x$no_attrib_nonnull" != "x1" ; then + AC_DEFINE(HAVE_ATTRIBUTE__NONNULL__, 1, [Have attribute nonnull]) +fi + AC_ARG_WITH(rpath, [ --without-rpath Disable auto-added -R linker paths], [ @@ -198,6 +205,7 @@ AC_CHECK_HEADERS( \ netgroup.h \ pam/pam_appl.h \ paths.h \ + poll.h \ pty.h \ readpassphrase.h \ rpc/types.h \ @@ -229,6 +237,7 @@ AC_CHECK_HEADERS( \ time.h \ tmpdir.h \ ttyent.h \ + ucred.h \ unistd.h \ usersec.h \ util.h \ @@ -777,6 +786,11 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(DISABLE_LASTLOG) AC_DEFINE(SSHD_ACQUIRES_CTTY) enable_etc_default_login=no # has incompatible /etc/default/login + case "$host" in + *-*-nto-qnx6*) + AC_DEFINE(DISABLE_FD_PASSING) + ;; + esac ;; *-*-ultrix*) @@ -1109,8 +1123,7 @@ AC_ARG_WITH(tcp-wrappers, CPPFLAGS="-I${withval} ${CPPFLAGS}" fi fi - LIBWRAP="-lwrap" - LIBS="$LIBWRAP $LIBS" + LIBS="-lwrap $LIBS" AC_MSG_CHECKING(for libwrap) AC_TRY_LINK( [ @@ -1126,7 +1139,7 @@ AC_ARG_WITH(tcp-wrappers, AC_DEFINE(LIBWRAP, 1, [Define if you want TCP Wrappers support]) - AC_SUBST(LIBWRAP) + SSHDLIBS="$SSHDLIBS -lwrap" TCPW_MSG="yes" ], [ @@ -1241,6 +1254,7 @@ AC_CHECK_FUNCS( \ getnameinfo \ getopt \ getpeereid \ + getpeerucred \ _getpty \ getrlimit \ getttyent \ @@ -1259,6 +1273,7 @@ AC_CHECK_FUNCS( \ ogetaddrinfo \ openlog_r \ openpty \ + poll \ prctl \ pstat \ readpassphrase \ @@ -1292,6 +1307,7 @@ AC_CHECK_FUNCS( \ strtonum \ strtoll \ strtoul \ + swap32 \ sysconf \ tcgetpgrp \ truncate \ @@ -1364,6 +1380,14 @@ AC_CHECK_DECLS(writev, , , [ #include ]) +AC_CHECK_DECLS(MAXSYMLINKS, , , [ +#include + ]) + +AC_CHECK_DECLS(offsetof, , , [ +#include + ]) + AC_CHECK_FUNCS(setresuid, [ dnl Some platorms have setresuid that isn't implemented, test for this AC_MSG_CHECKING(if setresuid seems to work) @@ -1489,7 +1513,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include # Check for missing getpeereid (or equiv) support NO_PEERCHECK="" -if test "x$ac_cv_func_getpeereid" != "xyes" ; then +if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt]) AC_TRY_COMPILE( [#include @@ -1977,7 +2001,12 @@ fi # Search for SHA256 support in libc and/or OpenSSL AC_CHECK_FUNCS(SHA256_Update EVP_sha256) -AC_CHECK_LIB(iaf, ia_openinfo) +saved_LIBS="$LIBS" +AC_CHECK_LIB(iaf, ia_openinfo, [ + LIBS="$LIBS -liaf" + AC_CHECK_FUNCS(set_id, [SSHDLIBS="$SSHDLIBS -liaf"]) +]) +LIBS="$saved_LIBS" ### Configure cryptographic random number support @@ -2027,7 +2056,7 @@ AC_ARG_WITH(pam, PAM_MSG="yes" - LIBPAM="-lpam" + SSHDLIBS="$SSHDLIBS -lpam" AC_DEFINE(USE_PAM, 1, [Define if you want to enable PAM support]) @@ -2037,11 +2066,10 @@ AC_ARG_WITH(pam, # libdl already in LIBS ;; *) - LIBPAM="$LIBPAM -ldl" + SSHDLIBS="$SSHDLIBS -ldl" ;; esac fi - AC_SUBST(LIBPAM) fi ] ) @@ -3150,25 +3178,43 @@ int main() [#include ]) ]) +AC_MSG_CHECKING(if struct __res_state _res is an extern) +AC_LINK_IFELSE([ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#include +#include +#include +extern struct __res_state _res; +int main() { return 0; } + ], + [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE__RES_EXTERN, 1, + [Define if you have struct __res_state _res as an extern]) + ], + [ AC_MSG_RESULT(no) ] +) + # Check whether user wants SELinux support SELINUX_MSG="no" LIBSELINUX="" AC_ARG_WITH(selinux, [ --with-selinux Enable SELinux support], [ if test "x$withval" != "xno" ; then + save_LIBS="$LIBS" AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.]) SELINUX_MSG="yes" AC_CHECK_HEADER([selinux/selinux.h], , AC_MSG_ERROR(SELinux support requires selinux.h header)) AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ], AC_MSG_ERROR(SELinux support requires libselinux library)) - save_LIBS="$LIBS" - LIBS="$LIBS $LIBSELINUX" + SSHDLIBS="$SSHDLIBS $LIBSELINUX" AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level) LIBS="$save_LIBS" fi ] ) -AC_SUBST(LIBSELINUX) # Check whether user wants Kerberos 5 support KRB5_MSG="no" @@ -4004,7 +4050,10 @@ echo " Compiler: ${CC}" echo " Compiler flags: ${CFLAGS}" echo "Preprocessor flags: ${CPPFLAGS}" echo " Linker flags: ${LDFLAGS}" -echo " Libraries: ${LIBWRAP} ${LIBPAM} ${LIBS}" +echo " Libraries: ${LIBS}" +if test ! -z "${SSHDLIBS}"; then +echo " +for sshd: ${SSHDLIBS}" +fi echo "" @@ -4030,12 +4079,12 @@ if test ! -z "$RAND_HELPER_CMDHASH" ; then fi if test ! -z "$NO_PEERCHECK" ; then - echo "WARNING: the operating system that you are using does not " - echo "appear to support either the getpeereid() API nor the " - echo "SO_PEERCRED getsockopt() option. These facilities are used to " - echo "enforce security checks to prevent unauthorised connections to " - echo "ssh-agent. Their absence increases the risk that a malicious " - echo "user can connect to your agent. " + echo "WARNING: the operating system that you are using does not" + echo "appear to support getpeereid(), getpeerucred() or the" + echo "SO_PEERCRED getsockopt() option. These facilities are used to" + echo "enforce security checks to prevent unauthorised connections to" + echo "ssh-agent. Their absence increases the risk that a malicious" + echo "user can connect to your agent." echo "" fi diff --git a/openssh/contrib/caldera/openssh.spec b/openssh/contrib/caldera/openssh.spec index 95b9129..5b81d27 100644 --- a/openssh/contrib/caldera/openssh.spec +++ b/openssh/contrib/caldera/openssh.spec @@ -17,7 +17,7 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 %if %{use_stable} - %define version 4.6p1 + %define version 4.7p1 %define cvs %{nil} %define release 1 %else diff --git a/openssh/contrib/redhat/openssh.spec b/openssh/contrib/redhat/openssh.spec index 08515d2..34ec6b7 100644 --- a/openssh/contrib/redhat/openssh.spec +++ b/openssh/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 4.6p1 +%define ver 4.7p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID diff --git a/openssh/contrib/suse/openssh.spec b/openssh/contrib/suse/openssh.spec index 95b394f..1f52305 100644 --- a/openssh/contrib/suse/openssh.spec +++ b/openssh/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 4.6p1 +Version: 4.7p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/openssh/defines.h b/openssh/defines.h index 143ede9..0b1640e 100644 --- a/openssh/defines.h +++ b/openssh/defines.h @@ -68,7 +68,7 @@ enum # endif #endif -#ifndef MAXSYMLINKS +#if defined(HAVE_DECL_MAXSYMLINKS) && HAVE_DECL_MAXSYMLINKS == 0 # define MAXSYMLINKS 5 #endif @@ -321,12 +321,6 @@ struct winsize { #ifndef _PATH_BSHELL # define _PATH_BSHELL "/bin/sh" #endif -#ifndef _PATH_CSHELL -# define _PATH_CSHELL "/bin/csh" -#endif -#ifndef _PATH_SHELLS -# define _PATH_SHELLS "/etc/shells" -#endif #ifdef USER_PATH # ifdef _PATH_STDPATH @@ -449,6 +443,10 @@ struct winsize { # define __bounded__(x, y, z) #endif +#if !defined(HAVE_ATTRIBUTE__NONNULL__) && !defined(__nonnull__) +# define __nonnull__(x) +#endif + /* *-*-nto-qnx doesn't define this macro in the system headers */ #ifdef MISSING_HOWMANY # define howmany(x,y) (((x)+((y)-1))/(y)) @@ -487,7 +485,7 @@ struct winsize { (struct cmsghdr *)NULL) #endif /* CMSG_FIRSTHDR */ -#ifndef offsetof +#if defined(HAVE_DECL_OFFSETOF) && HAVE_DECL_OFFSETOF == 0 # define offsetof(type, member) ((size_t) &((type *)0)->member) #endif @@ -696,7 +694,8 @@ struct winsize { # define CUSTOM_SYS_AUTH_PASSWD 1 #endif -#ifdef HAVE_LIBIAF +#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF) +# define USE_LIBIAF # define CUSTOM_SYS_AUTH_PASSWD 1 #endif diff --git a/openssh/entropy.c b/openssh/entropy.c index ccabb13..8b70539 100644 --- a/openssh/entropy.c +++ b/openssh/entropy.c @@ -35,8 +35,9 @@ # include #endif #include -#include +#include #include +#include #include #include diff --git a/openssh/gss-genr.c b/openssh/gss-genr.c index 57f12a2..e919057 100644 --- a/openssh/gss-genr.c +++ b/openssh/gss-genr.c @@ -1,7 +1,7 @@ -/* $OpenBSD: gss-genr.c,v 1.17 2006/08/29 12:02:30 dtucker Exp $ */ +/* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */ /* - * Copyright (c) 2001-2006 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -107,7 +107,7 @@ ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status, /* The GSSAPI error */ do { gss_display_status(&lmin, ctxt->major, - GSS_C_GSS_CODE, GSS_C_NULL_OID, &ctx, &msg); + GSS_C_GSS_CODE, ctxt->oid, &ctx, &msg); buffer_append(&b, msg.value, msg.length); buffer_put_char(&b, '\n'); @@ -118,7 +118,7 @@ ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status, /* The mechanism specific error */ do { gss_display_status(&lmin, ctxt->minor, - GSS_C_MECH_CODE, GSS_C_NULL_OID, &ctx, &msg); + GSS_C_MECH_CODE, ctxt->oid, &ctx, &msg); buffer_append(&b, msg.value, msg.length); buffer_put_char(&b, '\n'); @@ -226,39 +226,6 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host) return (ctx->major); } -/* Acquire credentials for a server running on the current host. - * Requires that the context structure contains a valid OID - */ - -/* Returns a GSSAPI error code */ -OM_uint32 -ssh_gssapi_acquire_cred(Gssctxt *ctx) -{ - OM_uint32 status; - char lname[MAXHOSTNAMELEN]; - gss_OID_set oidset; - - gss_create_empty_oid_set(&status, &oidset); - gss_add_oid_set_member(&status, ctx->oid, &oidset); - - if (gethostname(lname, MAXHOSTNAMELEN)) { - gss_release_oid_set(&status, &oidset); - return (-1); - } - - if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { - gss_release_oid_set(&status, &oidset); - return (ctx->major); - } - - if ((ctx->major = gss_acquire_cred(&ctx->minor, - ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) - ssh_gssapi_error(ctx); - - gss_release_oid_set(&status, &oidset); - return (ctx->major); -} - OM_uint32 ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash) { @@ -281,16 +248,6 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, buffer_put_cstring(b, context); } -OM_uint32 -ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) -{ - if (*ctx) - ssh_gssapi_delete_ctx(ctx); - ssh_gssapi_build_ctx(ctx); - ssh_gssapi_set_oid(*ctx, oid); - return (ssh_gssapi_acquire_cred(*ctx)); -} - int ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) { diff --git a/openssh/gss-serv.c b/openssh/gss-serv.c index e8191a8..bc498fd 100644 --- a/openssh/gss-serv.c +++ b/openssh/gss-serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: gss-serv.c,v 1.21 2007/06/12 08:20:00 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -29,6 +29,7 @@ #ifdef GSSAPI #include +#include #include #include @@ -64,6 +65,53 @@ ssh_gssapi_mech* supported_mechs[]= { &gssapi_null_mech, }; + +/* + * Acquire credentials for a server running on the current host. + * Requires that the context structure contains a valid OID + */ + +/* Returns a GSSAPI error code */ +/* Privileged (called from ssh_gssapi_server_ctx) */ +static OM_uint32 +ssh_gssapi_acquire_cred(Gssctxt *ctx) +{ + OM_uint32 status; + char lname[MAXHOSTNAMELEN]; + gss_OID_set oidset; + + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); + + if (gethostname(lname, MAXHOSTNAMELEN)) { + gss_release_oid_set(&status, &oidset); + return (-1); + } + + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { + gss_release_oid_set(&status, &oidset); + return (ctx->major); + } + + if ((ctx->major = gss_acquire_cred(&ctx->minor, + ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) + ssh_gssapi_error(ctx); + + gss_release_oid_set(&status, &oidset); + return (ctx->major); +} + +/* Privileged */ +OM_uint32 +ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) +{ + if (*ctx) + ssh_gssapi_delete_ctx(ctx); + ssh_gssapi_build_ctx(ctx); + ssh_gssapi_set_oid(*ctx, oid); + return (ssh_gssapi_acquire_cred(*ctx)); +} + /* Unprivileged */ void ssh_gssapi_supported_oids(gss_OID_set *oidset) diff --git a/openssh/includes.h b/openssh/includes.h index 967fcc2..9fcf1b0 100644 --- a/openssh/includes.h +++ b/openssh/includes.h @@ -49,7 +49,7 @@ #ifdef HAVE_NEXT # include #endif -#ifdef HAVE_PATHS +#ifdef HAVE_PATHS_H # include #endif diff --git a/openssh/kex.c b/openssh/kex.c index b2223c5..332fadf 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.77 2007/01/21 01:41:54 stevesk Exp $ */ +/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -87,7 +87,7 @@ static char ** kex_buf2prop(Buffer *raw, int *first_kex_follows) { Buffer b; - int i; + u_int i; char **proposal; proposal = xcalloc(PROPOSAL_MAX, sizeof(char *)); @@ -108,7 +108,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows) *first_kex_follows = i; debug2("kex_parse_kexinit: first_kex_follows %d ", i); i = buffer_get_int(&b); - debug2("kex_parse_kexinit: reserved %d ", i); + debug2("kex_parse_kexinit: reserved %u ", i); buffer_free(&b); return proposal; } @@ -123,6 +123,7 @@ kex_prop_free(char **proposal) xfree(proposal); } +/* ARGSUSED */ static void kex_protocol_error(int type, u_int32_t seq, void *ctxt) { @@ -194,6 +195,7 @@ kex_send_kexinit(Kex *kex) kex->flags |= KEX_INIT_SENT; } +/* ARGSUSED */ void kex_input_kexinit(int type, u_int32_t seq, void *ctxt) { @@ -258,7 +260,8 @@ choose_enc(Enc *enc, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) - fatal("no matching cipher found: client %s server %s", client, server); + fatal("no matching cipher found: client %s server %s", + client, server); if ((enc->cipher = cipher_by_name(name)) == NULL) fatal("matching cipher is not supported: %s", name); enc->name = name; @@ -274,8 +277,9 @@ choose_mac(Mac *mac, char *client, char *server) { char *name = match_list(client, server, NULL); if (name == NULL) - fatal("no matching mac found: client %s server %s", client, server); - if (mac_init(mac, name) < 0) + fatal("no matching mac found: client %s server %s", + client, server); + if (mac_setup(mac, name) < 0) fatal("unsupported mac %s", name); /* truncate the key */ if (datafellows & SSH_BUG_HMAC) @@ -308,7 +312,7 @@ choose_kex(Kex *k, char *client, char *server) { k->name = match_list(client, server, NULL); if (k->name == NULL) - fatal("no kex alg"); + fatal("Unable to negotiate a key exchange method"); if (strcmp(k->name, KEX_DH1) == 0) { k->kex_type = KEX_DH_GRP1_SHA1; k->evp_md = EVP_sha1(); @@ -388,7 +392,8 @@ kex_choose_conf(Kex *kex) for (mode = 0; mode < MODE_MAX; mode++) { newkeys = xcalloc(1, sizeof(*newkeys)); kex->newkeys[mode] = newkeys; - ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN); + ctos = (!kex->server && mode == MODE_OUT) || + (kex->server && mode == MODE_IN); nenc = ctos ? PROPOSAL_ENC_ALGS_CTOS : PROPOSAL_ENC_ALGS_STOC; nmac = ctos ? PROPOSAL_MAC_ALGS_CTOS : PROPOSAL_MAC_ALGS_STOC; ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC; diff --git a/openssh/kex.h b/openssh/kex.h index b1b20f5..8e29c90 100644 --- a/openssh/kex.h +++ b/openssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.44 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: kex.h,v 1.46 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -28,6 +28,7 @@ #include #include +#include #define KEX_DH1 "diffie-hellman-group1-sha1" #define KEX_DH14 "diffie-hellman-group14-sha1" @@ -86,10 +87,13 @@ struct Enc { struct Mac { char *name; int enabled; - const EVP_MD *md; u_int mac_len; u_char *key; u_int key_len; + int type; + const EVP_MD *evp_md; + HMAC_CTX evp_ctx; + struct umac_ctx *umac_ctx; }; struct Comp { int type; diff --git a/openssh/key.c b/openssh/key.c index 93b2d41..8fef9b4 100644 --- a/openssh/key.c +++ b/openssh/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.68 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: key.c,v 1.69 2007/07/12 05:48:05 ray Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -170,9 +170,7 @@ key_equal(const Key *a, const Key *b) BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0; default: fatal("key_equal: bad key type %d", a->type); - break; } - return 0; } u_char* diff --git a/openssh/log.c b/openssh/log.c index 7f88674..fae5b04 100644 --- a/openssh/log.c +++ b/openssh/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.39 2006/08/18 09:13:25 deraadt Exp $ */ +/* $OpenBSD: log.c,v 1.40 2007/05/17 07:50:31 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -44,6 +44,7 @@ #include #include #include +#include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) # include #endif @@ -313,6 +314,7 @@ do_log(LogLevel level, const char *fmt, va_list args) char fmtbuf[MSGBUFSIZ]; char *txt = NULL; int pri = LOG_INFO; + int saved_errno = errno; if (level > log_level) return; @@ -373,4 +375,5 @@ do_log(LogLevel level, const char *fmt, va_list args) closelog(); #endif } + errno = saved_errno; } diff --git a/openssh/loginrec.c b/openssh/loginrec.c index e591277..b411141 100644 --- a/openssh/loginrec.c +++ b/openssh/loginrec.c @@ -161,6 +161,7 @@ #include #include #include +#include #include #include "xmalloc.h" diff --git a/openssh/mac.c b/openssh/mac.c index e5d5bfa..3446465 100644 --- a/openssh/mac.c +++ b/openssh/mac.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: mac.c,v 1.14 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -42,63 +42,126 @@ #include "mac.h" #include "misc.h" +#include "umac.h" + +#define SSH_EVP 1 /* OpenSSL EVP-based MAC */ +#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ + struct { char *name; + int type; const EVP_MD * (*mdfunc)(void); int truncatebits; /* truncate digest if != 0 */ + int key_len; /* just for UMAC */ + int len; /* just for UMAC */ } macs[] = { - { "hmac-sha1", EVP_sha1, 0, }, - { "hmac-sha1-96", EVP_sha1, 96 }, - { "hmac-md5", EVP_md5, 0 }, - { "hmac-md5-96", EVP_md5, 96 }, - { "hmac-ripemd160", EVP_ripemd160, 0 }, - { "hmac-ripemd160@openssh.com", EVP_ripemd160, 0 }, - { NULL, NULL, 0 } + { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, + { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 }, + { "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 }, + { "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1, -1 }, + { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1, -1 }, + { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1 }, + { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64 }, + { NULL, 0, NULL, 0, -1, -1 } }; +static void +mac_setup_by_id(Mac *mac, int which) +{ + int evp_len; + mac->type = macs[which].type; + if (mac->type == SSH_EVP) { + mac->evp_md = (*macs[which].mdfunc)(); + if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) + fatal("mac %s len %d", mac->name, evp_len); + mac->key_len = mac->mac_len = (u_int)evp_len; + } else { + mac->mac_len = macs[which].len / 8; + mac->key_len = macs[which].key_len / 8; + mac->umac_ctx = NULL; + } + if (macs[which].truncatebits != 0) + mac->mac_len = macs[which].truncatebits / 8; +} + int -mac_init(Mac *mac, char *name) +mac_setup(Mac *mac, char *name) { - int i, evp_len; + int i; for (i = 0; macs[i].name; i++) { if (strcmp(name, macs[i].name) == 0) { - if (mac != NULL) { - mac->md = (*macs[i].mdfunc)(); - if ((evp_len = EVP_MD_size(mac->md)) <= 0) - fatal("mac %s len %d", name, evp_len); - mac->key_len = mac->mac_len = (u_int)evp_len; - if (macs[i].truncatebits != 0) - mac->mac_len = macs[i].truncatebits/8; - } - debug2("mac_init: found %s", name); + if (mac != NULL) + mac_setup_by_id(mac, i); + debug2("mac_setup: found %s", name); return (0); } } - debug2("mac_init: unknown %s", name); + debug2("mac_setup: unknown %s", name); return (-1); } +int +mac_init(Mac *mac) +{ + if (mac->key == NULL) + fatal("mac_init: no key"); + switch (mac->type) { + case SSH_EVP: + if (mac->evp_md == NULL) + return -1; + HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md); + return 0; + case SSH_UMAC: + mac->umac_ctx = umac_new(mac->key); + return 0; + default: + return -1; + } +} + u_char * mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) { - HMAC_CTX c; static u_char m[EVP_MAX_MD_SIZE]; - u_char b[4]; + u_char b[4], nonce[8]; - if (mac->key == NULL) - fatal("mac_compute: no key"); if (mac->mac_len > sizeof(m)) - fatal("mac_compute: mac too long"); - HMAC_Init(&c, mac->key, mac->key_len, mac->md); - put_u32(b, seqno); - HMAC_Update(&c, b, sizeof(b)); - HMAC_Update(&c, data, datalen); - HMAC_Final(&c, m, NULL); - HMAC_cleanup(&c); + fatal("mac_compute: mac too long %u %lu", + mac->mac_len, sizeof(m)); + + switch (mac->type) { + case SSH_EVP: + put_u32(b, seqno); + /* reset HMAC context */ + HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); + HMAC_Update(&mac->evp_ctx, b, sizeof(b)); + HMAC_Update(&mac->evp_ctx, data, datalen); + HMAC_Final(&mac->evp_ctx, m, NULL); + break; + case SSH_UMAC: + put_u64(nonce, seqno); + umac_update(mac->umac_ctx, data, datalen); + umac_final(mac->umac_ctx, m, nonce); + break; + default: + fatal("mac_compute: unknown MAC type"); + } return (m); } +void +mac_clear(Mac *mac) +{ + if (mac->type == SSH_UMAC) { + if (mac->umac_ctx != NULL) + umac_delete(mac->umac_ctx); + } else if (mac->evp_md != NULL) + HMAC_cleanup(&mac->evp_ctx); + mac->evp_md = NULL; + mac->umac_ctx = NULL; +} + /* XXX copied from ciphers_valid */ #define MAC_SEP "," int @@ -111,7 +174,7 @@ mac_valid(const char *names) maclist = cp = xstrdup(names); for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; (p = strsep(&cp, MAC_SEP))) { - if (mac_init(NULL, p) < 0) { + if (mac_setup(NULL, p) < 0) { debug("bad mac %s [%s]", p, names); xfree(maclist); return (0); diff --git a/openssh/mac.h b/openssh/mac.h index 960cc5c..39f564d 100644 --- a/openssh/mac.h +++ b/openssh/mac.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mac.h,v 1.4 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: mac.h,v 1.6 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -24,5 +24,7 @@ */ int mac_valid(const char *); -int mac_init(Mac *, char *); +int mac_setup(Mac *, char *); +int mac_init(Mac *); u_char *mac_compute(Mac *, u_int32_t, u_char *, int); +void mac_clear(Mac *); diff --git a/openssh/mdoc2man.awk b/openssh/mdoc2man.awk index d6eaf46..7ad1457 100644 --- a/openssh/mdoc2man.awk +++ b/openssh/mdoc2man.awk @@ -1,6 +1,9 @@ #!/usr/bin/awk # +# $Id$ +# # Version history: +# v4+ Adapted for OpenSSH Portable (see cvs Id and history) # v3, I put the program under a proper license # Dan Nelson added .An, .Aq and fixed a typo # v2, fixed to work on GNU awk --posix and MacOS X @@ -135,6 +138,12 @@ function add(str) { nospace=0 } if(match(words[w],"^Dd$")) { + if(match(words[w+1],"^\\$Mdocdate:")) { + w++; + if(match(words[w+4],"^\\$$")) { + words[w+4] = "" + } + } date=wtail() next } else if(match(words[w],"^Dt$")) { @@ -157,6 +166,7 @@ function add(str) { refissue="" refdate="" refopt="" + refreport="" reference=1 next } else if(match(words[w],"^Re$")) { @@ -168,9 +178,14 @@ function add(str) { } if(nrefauthors>1) add(" and ") - add(refauthors[0] ", \\fI" reftitle "\\fP") + if(nrefauthors>0) + add(refauthors[0] ", ") + add("\\fI" reftitle "\\fP") if(length(refissue)) add(", " refissue) + if(length(refreport)) { + add(", " refreport) + } if(length(refdate)) add(", " refdate) if(length(refopt)) @@ -187,6 +202,7 @@ function add(str) { if(match(words[w],"^%N$")) { refissue=wtail() } if(match(words[w],"^%D$")) { refdate=wtail() } if(match(words[w],"^%O$")) { refopt=wtail() } + if(match(words[w],"^%R$")) { refreport=wtail() } } else if(match(words[w],"^Nm$")) { if(synopsis) { add(".br") diff --git a/openssh/monitor.c b/openssh/monitor.c index 02f2dc8..08c7ea3 100644 --- a/openssh/monitor.c +++ b/openssh/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.90 2007/02/19 10:45:58 dtucker Exp $ */ +/* $OpenBSD: monitor.c,v 1.91 2007/05/17 20:52:13 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -409,6 +409,7 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_set_child_handler(pmonitor->m_pid); signal(SIGHUP, &monitor_child_handler); signal(SIGTERM, &monitor_child_handler); + signal(SIGINT, &monitor_child_handler); if (compat20) { mon_dispatch = mon_dispatch_postauth20; diff --git a/openssh/monitor_wrap.c b/openssh/monitor_wrap.c index 27cc1c5..edf2814 100644 --- a/openssh/monitor_wrap.c +++ b/openssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.55 2007/02/19 10:45:58 dtucker Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -476,8 +476,8 @@ mm_newkeys_from_blob(u_char *blob, int blen) /* Mac structure */ mac->name = buffer_get_string(&b, NULL); - if (mac->name == NULL || mac_init(mac, mac->name) == -1) - fatal("%s: can not init mac %s", __func__, mac->name); + if (mac->name == NULL || mac_setup(mac, mac->name) == -1) + fatal("%s: can not setup mac %s", __func__, mac->name); mac->enabled = buffer_get_int(&b); mac->key = buffer_get_string(&b, &len); if (len > mac->key_len) diff --git a/openssh/myproposal.h b/openssh/myproposal.h index e246e0d..87a9e58 100644 --- a/openssh/myproposal.h +++ b/openssh/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.21 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -47,7 +47,7 @@ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_DEFAULT_MAC \ - "hmac-md5,hmac-sha1,hmac-ripemd160," \ + "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \ "hmac-ripemd160@openssh.com," \ "hmac-sha1-96,hmac-md5-96" #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" diff --git a/openssh/openbsd-compat/Makefile.in b/openssh/openbsd-compat/Makefile.in index be1926b..1e13be7 100644 --- a/openssh/openbsd-compat/Makefile.in +++ b/openssh/openbsd-compat/Makefile.in @@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o -COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o +COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o diff --git a/openssh/openbsd-compat/bsd-cray.c b/openssh/openbsd-compat/bsd-cray.c index fda00da..e73f797 100644 --- a/openssh/openbsd-compat/bsd-cray.c +++ b/openssh/openbsd-compat/bsd-cray.c @@ -751,8 +751,6 @@ cray_job_termination_handler(int sig) char *login = NULL; struct jtab jtab; - debug("received signal %d",sig); - if ((jid = waitjob(&jtab)) == -1 || (login = uid2nam(jtab.j_uid)) == NULL) return; diff --git a/openssh/openbsd-compat/bsd-getpeereid.c b/openssh/openbsd-compat/bsd-getpeereid.c index bdae8b6..5f7e677 100644 --- a/openssh/openbsd-compat/bsd-getpeereid.c +++ b/openssh/openbsd-compat/bsd-getpeereid.c @@ -37,6 +37,28 @@ getpeereid(int s, uid_t *euid, gid_t *gid) return (0); } +#elif defined(HAVE_GETPEERUCRED) + +#ifdef HAVE_UCRED_H +# include +#endif + +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + ucred_t *ucred = NULL; + + if (getpeerucred(s, &ucred) == -1) + return (-1); + if ((*euid = ucred_geteuid(ucred)) == -1) + return (-1); + if ((*gid = ucred_getrgid(ucred)) == -1) + return (-1); + + ucred_free(ucred); + + return (0); +} #else int getpeereid(int s, uid_t *euid, gid_t *gid) diff --git a/openssh/openbsd-compat/bsd-misc.c b/openssh/openbsd-compat/bsd-misc.c index 17d731b..55f100a 100644 --- a/openssh/openbsd-compat/bsd-misc.c +++ b/openssh/openbsd-compat/bsd-misc.c @@ -17,6 +17,7 @@ #include "includes.h" +#include #ifdef HAVE_SYS_SELECT_H # include #endif @@ -27,6 +28,7 @@ #include #include #include +#include #include "xmalloc.h" @@ -156,7 +158,8 @@ int nanosleep(const struct timespec *req, struct timespec *rem) tremain.tv_sec = 0; tremain.tv_usec = 0; } - TIMEVAL_TO_TIMESPEC(&tremain, rem) + if (rem != NULL) + TIMEVAL_TO_TIMESPEC(&tremain, rem) return(rc); } diff --git a/openssh/openbsd-compat/bsd-poll.c b/openssh/openbsd-compat/bsd-poll.c new file mode 100644 index 0000000..4dd6fc4 --- /dev/null +++ b/openssh/openbsd-compat/bsd-poll.c @@ -0,0 +1,117 @@ +/* $Id$ */ + +/* + * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). + * + * 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" +#if !defined(HAVE_POLL) && defined(HAVE_SELECT) + +#ifdef HAVE_SYS_SELECT_H +# include +#endif + +#include +#include "bsd-poll.h" + +/* + * A minimal implementation of poll(2), built on top of select(2). + * + * Only supports POLLIN and POLLOUT flags in pfd.events, and POLLIN, POLLOUT + * and POLLERR flags in revents. + * + * Supports pfd.fd = -1 meaning "unused" although it's not standard. + */ + +int +poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + nfds_t i; + int saved_errno, ret, fd, maxfd = 0; + fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL; + size_t nmemb; + struct timeval tv, *tvp = NULL; + + for (i = 0; i < nfds; i++) { + if (fd >= FD_SETSIZE) { + errno = EINVAL; + return -1; + } + maxfd = MAX(maxfd, fds[i].fd); + } + + nmemb = howmany(maxfd + 1 , NFDBITS); + if ((readfds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (writefds = calloc(nmemb, sizeof(fd_mask))) == NULL || + (exceptfds = calloc(nmemb, sizeof(fd_mask))) == NULL) { + saved_errno = ENOMEM; + ret = -1; + goto out; + } + + /* populate event bit vectors for the events we're interested in */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + if (fd == -1) + continue; + if (fds[i].events & POLLIN) { + FD_SET(fd, readfds); + FD_SET(fd, exceptfds); + } + if (fds[i].events & POLLOUT) { + FD_SET(fd, writefds); + FD_SET(fd, exceptfds); + } + } + + /* poll timeout is msec, select is timeval (sec + usec) */ + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + tvp = &tv; + } + + ret = select(maxfd + 1, readfds, writefds, exceptfds, tvp); + saved_errno = errno; + + /* scan through select results and set poll() flags */ + for (i = 0; i < nfds; i++) { + fd = fds[i].fd; + fds[i].revents = 0; + if (fd == -1) + continue; + if (FD_ISSET(fd, readfds)) { + fds[i].revents |= POLLIN; + } + if (FD_ISSET(fd, writefds)) { + fds[i].revents |= POLLOUT; + } + if (FD_ISSET(fd, exceptfds)) { + fds[i].revents |= POLLERR; + } + } + +out: + if (readfds != NULL) + free(readfds); + if (writefds != NULL) + free(writefds); + if (exceptfds != NULL) + free(exceptfds); + if (ret == -1) + errno = saved_errno; + return ret; +} +#endif diff --git a/openssh/openbsd-compat/bsd-poll.h b/openssh/openbsd-compat/bsd-poll.h new file mode 100644 index 0000000..dcbb9ca --- /dev/null +++ b/openssh/openbsd-compat/bsd-poll.h @@ -0,0 +1,61 @@ +/* $OpenBSD: poll.h,v 1.11 2003/12/10 23:10:08 millert Exp $ */ + +/* + * Copyright (c) 1996 Theo de Raadt + * 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. + */ + +/* OPENBSD ORIGINAL: sys/sys/poll.h */ + +#if !defined(HAVE_POLL) && !defined(HAVE_POLL_H) +#ifndef _COMPAT_POLL_H_ +#define _COMPAT_POLL_H_ + +typedef struct pollfd { + int fd; + short events; + short revents; +} pollfd_t; + +typedef unsigned int nfds_t; + +#define POLLIN 0x0001 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#if 0 +/* the following are currently not implemented */ +#define POLLPRI 0x0002 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLNORM POLLRDNORM +#define POLLWRNORM POLLOUT +#define POLLRDBAND 0x0080 +#define POLLWRBAND 0x0100 +#endif + +#define INFTIM (-1) /* not standard */ + +int poll(struct pollfd *, nfds_t, int); +#endif /* !_COMPAT_POLL_H_ */ +#endif /* !HAVE_POLL_H */ diff --git a/openssh/openbsd-compat/getrrsetbyname.c b/openssh/openbsd-compat/getrrsetbyname.c index 07231d0..80af3f5 100644 --- a/openssh/openbsd-compat/getrrsetbyname.c +++ b/openssh/openbsd-compat/getrrsetbyname.c @@ -67,13 +67,9 @@ extern int h_errno; #endif #define _THREAD_PRIVATE(a,b,c) (c) -/* to avoid conflicts where a platform already has _res */ -#ifdef _res -# undef _res -#endif -#define _res _compat_res - +#ifndef HAVE__RES_EXTERN struct __res_state _res; +#endif /* Necessary functions and macros */ diff --git a/openssh/openbsd-compat/openbsd-compat.h b/openssh/openbsd-compat/openbsd-compat.h index 6fe30fe..edf4b9d 100644 --- a/openssh/openbsd-compat/openbsd-compat.h +++ b/openssh/openbsd-compat/openbsd-compat.h @@ -140,6 +140,7 @@ int writev(int, struct iovec *, int); /* Home grown routines */ #include "bsd-misc.h" #include "bsd-waitpid.h" +#include "bsd-poll.h" #ifndef HAVE_GETPEEREID int getpeereid(int , uid_t *, gid_t *); diff --git a/openssh/openbsd-compat/openssl-compat.h b/openssh/openbsd-compat/openssl-compat.h index a37f147..e44f501 100644 --- a/openssh/openbsd-compat/openssl-compat.h +++ b/openssh/openbsd-compat/openssl-compat.h @@ -29,6 +29,11 @@ #endif #ifdef USE_BUILTIN_RIJNDAEL +# include "rijndael.h" +# define AES_KEY rijndael_ctx +# define AES_BLOCK_SIZE 16 +# define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b) +# define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1) # define EVP_aes_128_cbc evp_rijndael # define EVP_aes_192_cbc evp_rijndael # define EVP_aes_256_cbc evp_rijndael diff --git a/openssh/openbsd-compat/port-aix.c b/openssh/openbsd-compat/port-aix.c index b9fabf6..94faec6 100644 --- a/openssh/openbsd-compat/port-aix.c +++ b/openssh/openbsd-compat/port-aix.c @@ -240,7 +240,7 @@ sys_auth_allowed_user(struct passwd *pw, Buffer *loginmsg) /* * Don't perform checks for root account (PermitRootLogin controls - * logins via * ssh) or if running as non-root user (since + * logins via ssh) or if running as non-root user (since * loginrestrictions will always fail due to insufficient privilege). */ if (pw->pw_uid == 0 || geteuid() != 0) { diff --git a/openssh/openbsd-compat/port-linux.c b/openssh/openbsd-compat/port-linux.c index 5386d9d..45615ea 100644 --- a/openssh/openbsd-compat/port-linux.c +++ b/openssh/openbsd-compat/port-linux.c @@ -79,6 +79,7 @@ ssh_selinux_getctxbyname(char *pwname) case 0: error("%s: Failed to get default SELinux security " "context for %s", __func__, pwname); + break; default: fatal("%s: Failed to get default SELinux security " "context for %s (in enforcing mode)", @@ -115,6 +116,7 @@ ssh_selinux_setup_exec_context(char *pwname) case 0: error("%s: Failed to set SELinux execution " "context for %s", __func__, pwname); + break; default: fatal("%s: Failed to set SELinux execution context " "for %s (in enforcing mode)", __func__, pwname); diff --git a/openssh/openbsd-compat/port-uw.c b/openssh/openbsd-compat/port-uw.c index 6f35239..ebc229a 100644 --- a/openssh/openbsd-compat/port-uw.c +++ b/openssh/openbsd-compat/port-uw.c @@ -79,7 +79,7 @@ sys_auth_passwd(Authctxt *authctxt, const char *password) #endif /* UNIXWARE_LONG_PASSWORDS */ result = (strcmp(xcrypt(password, salt), pw_password) == 0); -#if !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF if (authctxt->valid) free(pw_password); #endif @@ -127,7 +127,7 @@ nischeck(char *namep) functions that call shadow_pw() will need to free */ -#if !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF char * get_iaf_password(struct passwd *pw) { @@ -144,6 +144,6 @@ get_iaf_password(struct passwd *pw) else fatal("ia_openinfo: Unable to open the shadow passwd file"); } -#endif /* !BROKEN_LIBIAF */ +#endif /* USE_LIBIAF */ #endif /* HAVE_LIBIAF */ diff --git a/openssh/openbsd-compat/port-uw.h b/openssh/openbsd-compat/port-uw.h index 3589b2e..263d8b5 100644 --- a/openssh/openbsd-compat/port-uw.h +++ b/openssh/openbsd-compat/port-uw.h @@ -24,7 +24,7 @@ #include "includes.h" -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF char * get_iaf_password(struct passwd *pw); #endif diff --git a/openssh/openbsd-compat/regress/closefromtest.c b/openssh/openbsd-compat/regress/closefromtest.c index feb1b56..bb129fa 100644 --- a/openssh/openbsd-compat/regress/closefromtest.c +++ b/openssh/openbsd-compat/regress/closefromtest.c @@ -38,7 +38,7 @@ main(void) char buf[512]; for (i = 0; i < NUM_OPENS; i++) - if ((fds[i] = open("/dev/null", "r")) == -1) + if ((fds[i] = open("/dev/null", O_RDONLY)) == -1) exit(0); /* can't test */ max = i - 1; diff --git a/openssh/openbsd-compat/xcrypt.c b/openssh/openbsd-compat/xcrypt.c index 1489932..d8636bb 100644 --- a/openssh/openbsd-compat/xcrypt.c +++ b/openssh/openbsd-compat/xcrypt.c @@ -98,7 +98,7 @@ shadow_pw(struct passwd *pw) pw_password = spw->sp_pwdp; # endif -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF return(get_iaf_password(pw)); #endif diff --git a/openssh/openbsd-compat/xmmap.c b/openssh/openbsd-compat/xmmap.c index 4239d0e..322ffc2 100644 --- a/openssh/openbsd-compat/xmmap.c +++ b/openssh/openbsd-compat/xmmap.c @@ -38,12 +38,14 @@ #endif #include #include +#include #include #include #include "log.h" -void *xmmap(size_t size) +void * +xmmap(size_t size) { #ifdef HAVE_MMAP void *address; diff --git a/openssh/openssh.xml.in b/openssh/openssh.xml.in index 2fcdea0..8afe1d3 100644 --- a/openssh/openssh.xml.in +++ b/openssh/openssh.xml.in @@ -19,7 +19,7 @@ @@ -56,7 +56,7 @@ diff --git a/openssh/packet.c b/openssh/packet.c index 7d8fab1..f82a63c 100644 --- a/openssh/packet.c +++ b/openssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.145 2006/09/19 21:14:08 markus Exp $ */ +/* $OpenBSD: packet.c,v 1.148 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -629,7 +629,7 @@ set_newkeys(int mode) enc = &newkeys[mode]->enc; mac = &newkeys[mode]->mac; comp = &newkeys[mode]->comp; - memset(mac->key, 0, mac->key_len); + mac_clear(mac); xfree(enc->name); xfree(enc->iv); xfree(enc->key); @@ -644,14 +644,15 @@ set_newkeys(int mode) enc = &newkeys[mode]->enc; mac = &newkeys[mode]->mac; comp = &newkeys[mode]->comp; - if (mac->md != NULL) + if (mac_init(mac) == 0) mac->enabled = 1; DBG(debug("cipher_init_context: %d", mode)); cipher_init(cc, enc->cipher, enc->key, enc->key_len, enc->iv, enc->block_size, crypt_type); /* Deleting the keys does not gain extra security */ /* memset(enc->iv, 0, enc->block_size); - memset(enc->key, 0, enc->key_len); */ + memset(enc->key, 0, enc->key_len); + memset(mac->key, 0, mac->key_len); */ if ((comp->type == COMP_ZLIB || (comp->type == COMP_DELAYED && after_authentication)) && comp->enabled == 0) { @@ -1235,7 +1236,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) logit("Received disconnect from %s: %.400s", get_remote_ipaddr(), msg); cleanup_exit(255); - xfree(msg); break; default: if (type) diff --git a/openssh/readconf.c b/openssh/readconf.c index 2485146..d57d455 100644 --- a/openssh/readconf.c +++ b/openssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.161 2007/01/21 01:45:35 stevesk Exp $ */ +/* $OpenBSD: readconf.c,v 1.162 2007/03/20 03:56:12 tedu Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1224,7 +1224,7 @@ parse_forward(Forward *fwd, const char *fwdspec) cp = p = xstrdup(fwdspec); /* skip leading spaces */ - while (*cp && isspace(*cp)) + while (isspace(*cp)) cp++; for (i = 0; i < 4; ++i) diff --git a/openssh/regress/agent-getpeereid.sh b/openssh/regress/agent-getpeereid.sh index e5fcedd..d713242 100644 --- a/openssh/regress/agent-getpeereid.sh +++ b/openssh/regress/agent-getpeereid.sh @@ -7,7 +7,9 @@ UNPRIV=nobody ASOCK=${OBJ}/agent SSH_AUTH_SOCK=/nonexistant -if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 +if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 && \ + grep "#undef.*HAVE_GETPEERUCRED" ${BUILDDIR}/config.h >/dev/null && \ + grep "#undef.*HAVE_SO_PEERCRED" ${BUILDDIR}/config.h >/dev/null then echo "skipped (not supported on this platform)" exit 0 diff --git a/openssh/scard-opensc.c b/openssh/scard-opensc.c index 4751ea2..36dae05 100644 --- a/openssh/scard-opensc.c +++ b/openssh/scard-opensc.c @@ -32,6 +32,7 @@ #include #include +#include #include #include diff --git a/openssh/scp.1 b/openssh/scp.1 index 43662ab..b37ac84 100644 --- a/openssh/scp.1 +++ b/openssh/scp.1 @@ -9,9 +9,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.40 2006/07/18 07:56:28 jmc Exp $ +.\" $OpenBSD: scp.1,v 1.42 2007/08/06 19:16:06 sobrado Exp $ .\" -.Dd September 25, 1999 +.Dd $Mdocdate: August 8 2007 $ .Dt SCP 1 .Os .Sh NAME @@ -34,7 +34,7 @@ .Ar host1 No : .Oc Ns Ar file1 .Sm on -.Op Ar ... +.Ar ... .Sm off .Oo .Op Ar user No @ diff --git a/openssh/scp.c b/openssh/scp.c index a52aaeb..1765a44 100644 --- a/openssh/scp.c +++ b/openssh/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.156 2007/01/22 13:06:21 djm Exp $ */ +/* $OpenBSD: scp.c,v 1.160 2007/08/06 19:16:06 sobrado Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -96,6 +96,9 @@ #include #include #include +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +#include +#endif #include "xmalloc.h" #include "atomicio.h" @@ -582,7 +585,7 @@ source(int argc, char **argv) off_t i, amt, statbytes; size_t result; int fd = -1, haderr, indx; - char *last, *name, buf[2048]; + char *last, *name, buf[2048], encname[MAXPATHLEN]; int len; for (indx = 0; indx < argc; ++indx) { @@ -591,17 +594,17 @@ source(int argc, char **argv) len = strlen(name); while (len > 1 && name[len-1] == '/') name[--len] = '\0'; + if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) + goto syserr; if (strchr(name, '\n') != NULL) { - run_err("%s: skipping, filename contains a newline", - name); - goto next; + strnvis(encname, name, sizeof(encname), VIS_NL); + name = encname; } - if ((fd = open(name, O_RDONLY, 0)) < 0) - goto syserr; if (fstat(fd, &stb) < 0) { syserr: run_err("%s: %s", name, strerror(errno)); goto next; } + unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: break; @@ -1021,7 +1024,8 @@ bad: run_err("%s: %s", np, strerror(errno)); wrerr = YES; wrerrno = errno; } - if (wrerr == NO && ftruncate(ofd, size) != 0) { + if (wrerr == NO && (!exists || S_ISREG(stb.st_mode)) && + ftruncate(ofd, size) != 0) { run_err("%s: truncate: %s", np, strerror(errno)); wrerr = DISPLAYED; } @@ -1116,7 +1120,7 @@ usage(void) (void) fprintf(stderr, "usage: scp [-1246BCpqrv] [-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"); + " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); exit(1); } diff --git a/openssh/servconf.c b/openssh/servconf.c index 1e3c213..1a75451 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.170 2007/03/01 10:28:02 dtucker Exp $ */ +/* $OpenBSD: servconf.c,v 1.172 2007/04/23 10:15:39 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -592,7 +592,6 @@ match_cfg_line(char **condition, int line, const char *user, const char *host, debug("connection from %.100s matched 'Host " "%.100s' at line %d", host, arg, line); } else if (strcasecmp(attrib, "address") == 0) { - debug("address '%s' arg '%s'", address, arg); if (!address) { result = 0; continue; @@ -1387,8 +1386,4 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, if (bad_options > 0) fatal("%s: terminating, %d bad configuration options", filename, bad_options); - - /* challenge-response is implemented via keyboard interactive */ - if (options->challenge_response_authentication == 1) - options->kbd_interactive_authentication = 1; } diff --git a/openssh/session.c b/openssh/session.c index 4c97c4a..9a606ef 100644 --- a/openssh/session.c +++ b/openssh/session.c @@ -1310,7 +1310,7 @@ do_setusercontext(struct passwd *pw) # ifdef USE_PAM if (options.use_pam) { do_pam_session(); - do_pam_setcred(0); + do_pam_setcred(use_privsep); } # endif /* USE_PAM */ if (setusercontext(lc, pw, pw->pw_uid, @@ -1352,7 +1352,7 @@ do_setusercontext(struct passwd *pw) */ if (options.use_pam) { do_pam_session(); - do_pam_setcred(0); + do_pam_setcred(use_privsep); } # endif /* USE_PAM */ # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) @@ -1361,11 +1361,11 @@ do_setusercontext(struct passwd *pw) # ifdef _AIX aix_usrinfo(pw); # endif /* _AIX */ -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef USE_LIBIAF if (set_id(pw->pw_name) != 0) { exit(1); } -#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ +#endif /* USE_LIBIAF */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -2478,8 +2478,19 @@ do_cleanup(Authctxt *authctxt) return; called = 1; - if (authctxt == NULL || !authctxt->authenticated) + if (authctxt == NULL) return; + +#ifdef USE_PAM + if (options.use_pam) { + sshpam_cleanup(); + sshpam_thread_cleanup(); + } +#endif + + if (!authctxt->authenticated) + return; + #ifdef KRB5 if (options.kerberos_ticket_cleanup && authctxt->krb5_ctx) @@ -2491,13 +2502,6 @@ do_cleanup(Authctxt *authctxt) ssh_gssapi_cleanup_creds(); #endif -#ifdef USE_PAM - if (options.use_pam) { - sshpam_cleanup(); - sshpam_thread_cleanup(); - } -#endif - /* remove agent socket */ auth_sock_cleanup_proc(authctxt->pw); diff --git a/openssh/sftp-server.8 b/openssh/sftp-server.8 index 199c4f3..7452eca 100644 --- a/openssh/sftp-server.8 +++ b/openssh/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.11 2006/07/06 10:47:57 djm Exp $ +.\" $OpenBSD: sftp-server.8,v 1.12 2007/05/31 19:20:16 jmc Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 30, 2000 +.Dd $Mdocdate: June 5 2007 $ .Dt SFTP-SERVER 8 .Os .Sh NAME diff --git a/openssh/sftp-server.c b/openssh/sftp-server.c index 64777be..76edebc 100644 --- a/openssh/sftp-server.c +++ b/openssh/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.71 2007/01/03 07:22:36 stevesk Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.73 2007/05/17 07:55:29 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -319,7 +319,8 @@ handle_log_close(int handle, char *emsg) logit("%s%sclose \"%s\" bytes read %llu written %llu", emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", handle_to_name(handle), - handle_bytes_read(handle), handle_bytes_write(handle)); + (unsigned long long)handle_bytes_read(handle), + (unsigned long long)handle_bytes_write(handle)); } else { logit("%s%sclosedir \"%s\"", emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ", @@ -702,7 +703,8 @@ process_setstat(void) a = get_attrib(); debug("request %u: setstat name \"%s\"", id, name); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { - logit("set \"%s\" size %llu", name, a->size); + logit("set \"%s\" size %llu", + name, (unsigned long long)a->size); ret = truncate(name, a->size); if (ret == -1) status = errno_to_portable(errno); @@ -754,7 +756,8 @@ process_fsetstat(void) char *name = handle_to_name(handle); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { - logit("set \"%s\" size %llu", name, a->size); + logit("set \"%s\" size %llu", + name, (unsigned long long)a->size); ret = ftruncate(fd, a->size); if (ret == -1) status = errno_to_portable(errno); @@ -1211,7 +1214,7 @@ main(int argc, char **argv) int in, out, max, ch, skipargs = 0, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; - char *cp; + char *cp, buf[4*4096]; extern char *optarg; extern char *__progname; @@ -1295,7 +1298,15 @@ main(int argc, char **argv) memset(rset, 0, set_size); memset(wset, 0, set_size); - FD_SET(in, rset); + /* + * Ensure that we can read a full buffer and handle + * the worst-case length packet it can generate, + * otherwise apply backpressure by stopping reads. + */ + if (buffer_check_alloc(&iqueue, sizeof(buf)) && + buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH)) + FD_SET(in, rset); + olen = buffer_len(&oqueue); if (olen > 0) FD_SET(out, wset); @@ -1309,7 +1320,6 @@ main(int argc, char **argv) /* copy stdin to iqueue */ if (FD_ISSET(in, rset)) { - char buf[4*4096]; len = read(in, buf, sizeof buf); if (len == 0) { debug("read eof"); @@ -1331,7 +1341,13 @@ main(int argc, char **argv) buffer_consume(&oqueue, len); } } - /* process requests from client */ - process(); + + /* + * Process requests from client if we can fit the results + * into the output buffer, otherwise stop processing input + * and let the output queue drain. + */ + if (buffer_check_alloc(&oqueue, SFTP_MAX_MSG_LENGTH)) + process(); } } diff --git a/openssh/sftp.1 b/openssh/sftp.1 index 47aafa8..6e025bc 100644 --- a/openssh/sftp.1 +++ b/openssh/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.63 2006/01/20 00:14:55 dtucker Exp $ +.\" $OpenBSD: sftp.1,v 1.64 2007/05/31 19:20:16 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 4, 2001 +.Dd $Mdocdate: June 5 2007 $ .Dt SFTP 1 .Os .Sh NAME diff --git a/openssh/ssh-add.1 b/openssh/ssh-add.1 index 327fcdd..005041b 100644 --- a/openssh/ssh-add.1 +++ b/openssh/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.43 2005/04/21 06:17:50 djm Exp $ +.\" $OpenBSD: ssh-add.1,v 1.46 2007/06/12 13:41:03 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,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 September 25, 1999 +.Dd $Mdocdate: June 12 2007 $ .Dt SSH-ADD 1 .Os .Sh NAME @@ -89,7 +89,18 @@ program, rather than text entered into the requester. .It Fl D Deletes all identities from the agent. .It Fl d -Instead of adding the identity, removes the identity from the agent. +Instead of adding identities, removes identities from the agent. +If +.Nm +has been run without arguments, the keys for the default identities will +be removed. +Otherwise, the argument list will be interpreted as a list of paths to +public key files and matching keys will be removed from the agent. +If no public key is found at a given path, +.Nm +will append +.Pa .pub +and retry. .It Fl e Ar reader Remove key in smartcard .Ar reader . diff --git a/openssh/ssh-agent.1 b/openssh/ssh-agent.1 index f1b8777..1b5a5bb 100644 --- a/openssh/ssh-agent.1 +++ b/openssh/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.44 2006/07/18 08:03:09 jmc Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.45 2007/05/31 19:20:16 jmc Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 25, 1999 +.Dd $Mdocdate: June 5 2007 $ .Dt SSH-AGENT 1 .Os .Sh NAME diff --git a/openssh/ssh-agent.c b/openssh/ssh-agent.c index a3a867c..c3d5e5a 100644 --- a/openssh/ssh-agent.c +++ b/openssh/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.154 2007/02/28 00:55:30 dtucker Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.155 2007/03/19 12:16:42 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -120,6 +120,7 @@ int max_fd = 0; /* pid of shell == parent of agent */ pid_t parent_pid = -1; +u_int parent_alive_interval = 0; /* pathname and directory for AUTH_SOCKET */ char socket_name[MAXPATHLEN]; @@ -421,10 +422,11 @@ process_remove_all_identities(SocketEntry *e, int version) buffer_put_char(&e->output, SSH_AGENT_SUCCESS); } -static void +/* removes expired keys and returns number of seconds until the next expiry */ +static u_int reaper(void) { - u_int now = time(NULL); + u_int deadline = 0, now = time(NULL); Identity *id, *nxt; int version; Idtab *tab; @@ -433,14 +435,22 @@ reaper(void) tab = idtab_lookup(version); for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { nxt = TAILQ_NEXT(id, next); - if (id->death != 0 && now >= id->death) { + if (id->death == 0) + continue; + if (now >= id->death) { debug("expiring key '%s'", id->comment); TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); tab->nentries--; - } + } else + deadline = (deadline == 0) ? id->death : + MIN(deadline, id->death); } } + if (deadline == 0 || deadline <= now) + return 0; + else + return (deadline - now); } static void @@ -826,10 +836,12 @@ new_socket(sock_type type, int fd) } static int -prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp) +prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, + struct timeval **tvpp) { - u_int i, sz; + u_int i, sz, deadline; int n = 0; + static struct timeval tv; for (i = 0; i < sockets_alloc; i++) { switch (sockets[i].type) { @@ -873,6 +885,17 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp) break; } } + deadline = reaper(); + if (parent_alive_interval != 0) + deadline = (deadline == 0) ? parent_alive_interval : + MIN(deadline, parent_alive_interval); + if (deadline == 0) { + *tvpp = NULL; + } else { + tv.tv_sec = deadline; + tv.tv_usec = 0; + *tvpp = &tv; + } return (1); } @@ -980,19 +1003,14 @@ cleanup_handler(int sig) _exit(2); } -/*ARGSUSED*/ static void -check_parent_exists(int sig) +check_parent_exists(void) { - int save_errno = errno; - if (parent_pid != -1 && kill(parent_pid, 0) < 0) { /* printf("Parent has died - Authentication agent exiting.\n"); */ - cleanup_handler(sig); /* safe */ + cleanup_socket(); + _exit(2); } - mysignal(SIGALRM, check_parent_exists); - alarm(10); - errno = save_errno; } static void @@ -1027,7 +1045,7 @@ main(int ac, char **av) extern char *optarg; pid_t pid; char pidstrbuf[1 + 3 * sizeof pid]; - struct timeval tv; + struct timeval *tvp = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -1228,10 +1246,8 @@ main(int ac, char **av) skip: new_socket(AUTH_SOCKET, sock); - if (ac > 0) { - mysignal(SIGALRM, check_parent_exists); - alarm(10); - } + if (ac > 0) + parent_alive_interval = 10; idtab_init(); if (!d_flag) signal(SIGINT, SIG_IGN); @@ -1241,12 +1257,12 @@ skip: nalloc = 0; while (1) { - tv.tv_sec = 10; - tv.tv_usec = 0; - prepare_select(&readsetp, &writesetp, &max_fd, &nalloc); - result = select(max_fd + 1, readsetp, writesetp, NULL, &tv); + prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); + result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); saved_errno = errno; - reaper(); /* remove expired keys */ + if (parent_alive_interval != 0) + check_parent_exists(); + (void) reaper(); /* remove expired keys */ if (result < 0) { if (saved_errno == EINTR) continue; diff --git a/openssh/ssh-gss.h b/openssh/ssh-gss.h index 1ef66e4..c29a1b7 100644 --- a/openssh/ssh-gss.h +++ b/openssh/ssh-gss.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-gss.h,v 1.9 2006/08/18 14:40:34 djm Exp $ */ +/* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * @@ -105,7 +105,6 @@ void ssh_gssapi_supported_oids(gss_OID_set *); ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); -OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *); OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *, @@ -116,11 +115,11 @@ char *ssh_gssapi_last_error(Gssctxt *, OM_uint32 *, OM_uint32 *); void ssh_gssapi_build_ctx(Gssctxt **); void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); -OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *); int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *); /* In the server */ +OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID); int ssh_gssapi_userok(char *name); OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_do_child(char ***, u_int *); diff --git a/openssh/ssh-keygen.1 b/openssh/ssh-keygen.1 index 5a8c8c4..4e629de 100644 --- a/openssh/ssh-keygen.1 +++ b/openssh/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.74 2007/01/12 20:20:41 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.75 2007/05/31 19:20:16 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,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 September 25, 1999 +.Dd $Mdocdate: June 5 2007 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME diff --git a/openssh/ssh-keyscan.1 b/openssh/ssh-keyscan.1 index a3656fc..005e57a 100644 --- a/openssh/ssh-keyscan.1 +++ b/openssh/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.22 2006/09/25 04:55:38 ray Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.23 2007/05/31 19:20:16 jmc Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd January 1, 1996 +.Dd $Mdocdate: June 5 2007 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME diff --git a/openssh/ssh-keysign.8 b/openssh/ssh-keysign.8 index 4cdcb7a..814bcb6 100644 --- a/openssh/ssh-keysign.8 +++ b/openssh/ssh-keysign.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keysign.8,v 1.8 2006/02/24 20:22:16 jmc Exp $ +.\" $OpenBSD: ssh-keysign.8,v 1.9 2007/05/31 19:20:16 jmc Exp $ .\" .\" Copyright (c) 2002 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 24, 2002 +.Dd $Mdocdate: June 5 2007 $ .Dt SSH-KEYSIGN 8 .Os .Sh NAME diff --git a/openssh/ssh-rand-helper.c b/openssh/ssh-rand-helper.c index 8520c3a..8b1c4b4 100644 --- a/openssh/ssh-rand-helper.c +++ b/openssh/ssh-rand-helper.c @@ -32,6 +32,7 @@ #include #include +#include #include #include diff --git a/openssh/ssh.1 b/openssh/ssh.1 index b87ab41..1bf6b5e 100644 --- a/openssh/ssh.1 +++ b/openssh/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.266 2006/12/11 21:25:46 markus Exp $ -.Dd September 25, 1999 +.\" $OpenBSD: ssh.1,v 1.270 2007/06/12 13:43:55 jmc Exp $ +.Dd $Mdocdate: June 12 2007 $ .Dt SSH 1 .Os .Sh NAME @@ -43,7 +43,7 @@ .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh -.Op Fl 1246AaCfgkMNnqsTtVvXxY +.Op Fl 1246AaCfgKkMNnqsTtVvXxY .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Oo Fl D\ \& @@ -315,6 +315,9 @@ It is possible to have multiple .Fl i options (and multiple identities specified in configuration files). +.It Fl K +Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI +credentials to the server. .It Fl k Disables forwarding (delegation) of GSSAPI credentials to the server. .It Fl L Xo @@ -674,7 +677,7 @@ Both protocols support similar authentication methods, but protocol 2 is preferred since it provides additional mechanisms for confidentiality (the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) -and integrity (hmac-md5, hmac-sha1, hmac-ripemd160). +and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160). Protocol 1 lacks a strong mechanism for ensuring the integrity of the connection. .Pp diff --git a/openssh/ssh.c b/openssh/ssh.c index cfaa1ff..d3a7ffc 100644 --- a/openssh/ssh.c +++ b/openssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.295 2007/01/03 03:01:40 stevesk Exp $ */ +/* $OpenBSD: ssh.c,v 1.301 2007/08/07 07:32:53 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -185,7 +185,7 @@ static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" @@ -272,7 +272,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -326,6 +326,10 @@ main(int ac, char **av) case 'k': options.gss_deleg_creds = 0; break; + case 'K': + options.gss_authentication = 1; + options.gss_deleg_creds = 1; + break; case 'i': if (stat(optarg, &st) < 0) { fprintf(stderr, "Warning: Identity file %s " @@ -853,6 +857,17 @@ ssh_init_forwarding(void) "forwarding."); } } + + /* Initiate tunnel forwarding. */ + if (options.tun_open != SSH_TUNMODE_NO) { + if (client_request_tun_fwd(options.tun_open, + options.tun_local, options.tun_remote) == -1) { + if (options.exit_on_forward_failure) + fatal("Could not request tunnel forwarding."); + else + error("Could not request tunnel forwarding."); + } + } } static void @@ -1115,33 +1130,6 @@ ssh_session2_setup(int id, void *arg) packet_send(); } - if (options.tun_open != SSH_TUNMODE_NO) { - Channel *c; - int fd; - - debug("Requesting tun."); - if ((fd = tun_open(options.tun_local, - options.tun_open)) >= 0) { - c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, - 0, "tun", 1); - c->datagram = 1; -#if defined(SSH_TUN_FILTER) - if (options.tun_open == SSH_TUNMODE_POINTOPOINT) - channel_register_filter(c->self, sys_tun_infilter, - sys_tun_outfilter); -#endif - packet_start(SSH2_MSG_CHANNEL_OPEN); - packet_put_cstring("tun@openssh.com"); - packet_put_int(c->self); - packet_put_int(c->local_window_max); - packet_put_int(c->local_maxpacket); - packet_put_int(options.tun_open); - packet_put_int(options.tun_remote); - packet_send(); - } - } - client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); @@ -1201,7 +1189,6 @@ ssh_session2(void) /* XXX should be pre-session */ ssh_init_forwarding(); - ssh_control_listener(); if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) id = ssh_session2_open(); @@ -1211,6 +1198,9 @@ ssh_session2(void) options.permit_local_command) ssh_local_cmd(options.local_command); + /* Start listening for multiplex clients */ + ssh_control_listener(); + /* If requested, let ssh continue in the background. */ if (fork_after_authentication_flag) if (daemon(1, 1) < 0) @@ -1307,7 +1297,7 @@ static void control_client(const char *path) { struct sockaddr_un addr; - int i, r, fd, sock, exitval, num_env, addr_len; + int i, r, fd, sock, exitval[2], num_env, addr_len; Buffer m; char *term; extern char **environ; @@ -1456,29 +1446,44 @@ control_client(const char *path) if (tty_flag) enter_raw_mode(); - /* Stick around until the controlee closes the client_fd */ - exitval = 0; - for (;!control_client_terminate;) { - r = read(sock, &exitval, sizeof(exitval)); + /* + * Stick around until the controlee closes the client_fd. + * Before it does, it is expected to write this process' exit + * value (one int). This process must read the value and wait for + * the closure of the client_fd; if this one closes early, the + * multiplex master will terminate early too (possibly losing data). + */ + exitval[0] = 0; + for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) { + r = read(sock, (char *)exitval + i, sizeof(exitval) - i); if (r == 0) { debug2("Received EOF from master"); break; } - if (r > 0) - debug2("Received exit status from master %d", exitval); - if (r == -1 && errno != EINTR) + if (r == -1) { + if (errno == EINTR) + continue; fatal("%s: read %s", __func__, strerror(errno)); + } + i += r; } - if (control_client_terminate) - debug2("Exiting on signal %d", control_client_terminate); - close(sock); - leave_raw_mode(); + if (i > (int)sizeof(int)) + fatal("%s: master returned too much data (%d > %lu)", + __func__, i, sizeof(int)); + if (control_client_terminate) { + debug2("Exiting on signal %d", control_client_terminate); + exitval[0] = 255; + } else if (i < (int)sizeof(int)) { + debug2("Control master terminated unexpectedly"); + exitval[0] = 255; + } else + debug2("Received exit status from master %d", exitval[0]); if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) - fprintf(stderr, "Connection to master closed.\r\n"); + fprintf(stderr, "Shared connection to %s closed.\r\n", host); - exit(exitval); + exit(exitval[0]); } diff --git a/openssh/ssh_config b/openssh/ssh_config index 177521c..8cb0698 100644 --- a/openssh/ssh_config +++ b/openssh/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.22 2006/05/29 12:56:33 dtucker Exp $ +# $OpenBSD: ssh_config,v 1.23 2007/06/08 04:40:40 pvalchev Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -38,6 +38,7 @@ # Protocol 2,1 # Cipher 3des # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc +# MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 # EscapeChar ~ # Tunnel no # TunnelDevice any:any diff --git a/openssh/ssh_config.5 b/openssh/ssh_config.5 index c1ad53d..95af397 100644 --- a/openssh/ssh_config.5 +++ b/openssh/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.98 2007/01/10 13:23:22 jmc Exp $ -.Dd September 25, 1999 +.\" $OpenBSD: ssh_config.5,v 1.102 2007/08/15 12:13:41 stevesk Exp $ +.Dd $Mdocdate: August 15 2007 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -387,7 +387,7 @@ data). Specifies whether .Xr ssh 1 should terminate the connection if it cannot set up all requested -dynamic, local, and remote port forwardings. +dynamic, tunnel, local, and remote port forwardings. The argument must be .Dq yes or @@ -641,7 +641,10 @@ The MAC algorithm is used in protocol version 2 for data integrity protection. Multiple algorithms must be comma-separated. The default is: -.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . +.Bd -literal -offset indent +hmac-md5,hmac-sha1,umac-64@openssh.com, +hmac-ripemd160,hmac-sha1-96,hmac-md5-96 +.Ed .It Cm NoHostAuthenticationForLocalhost This option can be used if the home directory is shared across machines. In this case localhost will refer to a different machine on each of diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index dd971a9..208df07 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.162 2006/08/30 00:06:51 dtucker Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.164 2007/05/17 23:53:41 jolan Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -1307,7 +1308,7 @@ userauth_hostbased(Authctxt *authctxt) Sensitive *sensitive = authctxt->sensitive; Buffer b; u_char *signature, *blob; - char *chost, *pkalg, *p; + char *chost, *pkalg, *p, myname[NI_MAXHOST]; const char *service; u_int blen, slen; int ok, i, len, found = 0; @@ -1331,7 +1332,16 @@ userauth_hostbased(Authctxt *authctxt) return 0; } /* figure out a name for the client host */ - p = get_local_name(packet_get_connection_in()); + p = NULL; + if (packet_connection_is_on_socket()) + p = get_local_name(packet_get_connection_in()); + if (p == NULL) { + if (gethostname(myname, sizeof(myname)) == -1) { + verbose("userauth_hostbased: gethostname: %s", + strerror(errno)); + } else + p = xstrdup(myname); + } if (p == NULL) { error("userauth_hostbased: cannot get local ipaddr/name"); key_free(private); diff --git a/openssh/sshd.8 b/openssh/sshd.8 index 522279e..12c2cef 100644 --- a/openssh/sshd.8 +++ b/openssh/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.234 2006/08/21 08:15:57 dtucker Exp $ -.Dd September 25, 1999 +.\" $OpenBSD: sshd.8,v 1.237 2007/06/07 19:37:34 pvalchev Exp $ +.Dd $Mdocdate: August 16 2007 $ .Dt SSHD 8 .Os .Sh NAME @@ -58,8 +58,11 @@ .Nm (OpenSSH Daemon) is the daemon program for .Xr ssh 1 . -Together these programs replace rlogin and rsh, and -provide secure encrypted communications between two untrusted hosts +Together these programs replace +.Xr rlogin 1 +and +.Xr rsh 1 , +and provide secure encrypted communications between two untrusted hosts over an insecure network. .Pp .Nm @@ -117,7 +120,7 @@ Maximum is 3. When this option is specified, .Nm will send the output to the standard error instead of the system log. -.It Fl f Ar configuration_file +.It Fl f Ar config_file Specifies the name of the configuration file. The default is .Pa /etc/ssh/sshd_config . @@ -273,7 +276,7 @@ The client selects the encryption algorithm to use from those offered by the server. Additionally, session integrity is provided through a cryptographic message authentication code -(hmac-sha1 or hmac-md5). +(hmac-md5, hmac-sha1, umac-64 or hmac-ripemd160). .Pp Finally, the server and the client enter an authentication dialog. The client tries to authenticate itself using @@ -299,8 +302,9 @@ on Tru64, a leading .Ql \&*LOCKED\&* on FreeBSD and a leading -.Ql \&!! -on Linux). If there is a requirement to disable password authentication +.Ql \&! +on most Linuxes). +If there is a requirement to disable password authentication for the account while allowing still public-key, then the passwd field should be set to something other than these values (eg .Ql NP @@ -758,15 +762,6 @@ This file is used in exactly the same way as but allows host-based authentication without permitting login with rlogin/rsh. .Pp -.It /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 -organization. -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/ssh_host_key .It /etc/ssh/ssh_host_dsa_key .It /etc/ssh/ssh_host_rsa_key @@ -790,6 +785,15 @@ 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 +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 +organization. +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 Contains configuration data for .Nm sshd . @@ -826,6 +830,7 @@ The content of this file is not sensitive; it can be world-readable. .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , +.Xr ssh-keyscan 1 , .Xr chroot 2 , .Xr hosts_access 5 , .Xr login.conf 5 , diff --git a/openssh/sshd.c b/openssh/sshd.c index 0a76f2d..04778ea 100644 --- a/openssh/sshd.c +++ b/openssh/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.349 2007/02/21 11:00:05 dtucker Exp $ */ +/* $OpenBSD: sshd.c,v 1.351 2007/05/22 10:18:52 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1421,6 +1421,10 @@ main(int ac, char **av) /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); + /* challenge-response is implemented via keyboard interactive */ + if (options.challenge_response_authentication) + options.kbd_interactive_authentication = 1; + /* set default channel AF */ channel_set_af(options.address_family); diff --git a/openssh/sshd_config b/openssh/sshd_config index 6a3cad8..3393cec 100644 --- a/openssh/sshd_config +++ b/openssh/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.74 2006/07/19 13:07:10 dtucker Exp $ +# $OpenBSD: sshd_config,v 1.75 2007/03/19 01:01:29 djm Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -11,11 +11,15 @@ # default value. #Port 22 -#Protocol 2,1 #AddressFamily any #ListenAddress 0.0.0.0 #ListenAddress :: +# Disable legacy (protocol version 1) support in the server for new +# installations. In future the default will change to require explicit +# activation of protocol 1 +Protocol 2 + # HostKey for protocol version 1 #HostKey /etc/ssh/ssh_host_key # HostKeys for protocol version 2 diff --git a/openssh/sshd_config.5 b/openssh/sshd_config.5 index af12214..7882f8b 100644 --- a/openssh/sshd_config.5 +++ b/openssh/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.74 2007/03/01 16:19:33 jmc Exp $ -.Dd September 25, 1999 +.\" $OpenBSD: sshd_config.5,v 1.77 2007/06/08 07:48:09 jmc Exp $ +.Dd $Mdocdate: June 11 2007 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -489,7 +489,10 @@ The MAC algorithm is used in protocol version 2 for data integrity protection. Multiple algorithms must be comma-separated. The default is: -.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 . +.Bd -literal -offset indent +hmac-md5,hmac-sha1,umac-64@openssh.com, +hmac-ripemd160,hmac-sha1-96,hmac-md5-96 +.Ed .It Cm Match Introduces a conditional block. If all of the criteria on the diff --git a/openssh/umac.c b/openssh/umac.c new file mode 100644 index 0000000..c2fdcf4 --- /dev/null +++ b/openssh/umac.c @@ -0,0 +1,1272 @@ +/* $OpenBSD: umac.c,v 1.1 2007/06/07 19:37:34 pvalchev Exp $ */ +/* ----------------------------------------------------------------------- + * + * umac.c -- C Implementation UMAC Message Authentication + * + * Version 0.93b of rfc4418.txt -- 2006 July 18 + * + * For a full description of UMAC message authentication see the UMAC + * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac + * Please report bugs and suggestions to the UMAC webpage. + * + * Copyright (c) 1999-2006 Ted Krovetz + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and with or without fee, is hereby + * granted provided that the above copyright notice appears in all copies + * and in supporting documentation, and that the name of the copyright + * holder not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * + * Comments should be directed to Ted Krovetz (tdk@acm.org) + * + * ---------------------------------------------------------------------- */ + + /* ////////////////////// IMPORTANT NOTES ///////////////////////////////// + * + * 1) This version does not work properly on messages larger than 16MB + * + * 2) If you set the switch to use SSE2, then all data must be 16-byte + * aligned + * + * 3) When calling the function umac(), it is assumed that msg is in + * a writable buffer of length divisible by 32 bytes. The message itself + * does not have to fill the entire buffer, but bytes beyond msg may be + * zeroed. + * + * 4) Three free AES implementations are supported by this implementation of + * UMAC. Paulo Barreto's version is in the public domain and can be found + * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for + * "Barreto"). The only two files needed are rijndael-alg-fst.c and + * rijndael-alg-fst.h. Brian Gladman's version is distributed with the GNU + * Public lisence at http://fp.gladman.plus.com/AES/index.htm. It + * includes a fast IA-32 assembly version. The OpenSSL crypo library is + * the third. + * + * 5) With FORCE_C_ONLY flags set to 0, incorrect results are sometimes + * produced under gcc with optimizations set -O3 or higher. Dunno why. + * + /////////////////////////////////////////////////////////////////////// */ + +/* ---------------------------------------------------------------------- */ +/* --- User Switches ---------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +#define UMAC_OUTPUT_LEN 8 /* Alowable: 4, 8, 12, 16 */ +/* #define FORCE_C_ONLY 1 ANSI C and 64-bit integers req'd */ +/* #define AES_IMPLEMENTAION 1 1 = OpenSSL, 2 = Barreto, 3 = Gladman */ +/* #define SSE2 0 Is SSE2 is available? */ +/* #define RUN_TESTS 0 Run basic correctness/speed tests */ +/* #define UMAC_AE_SUPPORT 0 Enable auhthenticated encrytion */ + +/* ---------------------------------------------------------------------- */ +/* -- Global Includes --------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +#include "includes.h" +#include + +#include "umac.h" +#include +#include +#include + +/* ---------------------------------------------------------------------- */ +/* --- Primitive Data Types --- */ +/* ---------------------------------------------------------------------- */ + +/* The following assumptions may need change on your system */ +typedef u_int8_t UINT8; /* 1 byte */ +typedef u_int16_t UINT16; /* 2 byte */ +typedef u_int32_t UINT32; /* 4 byte */ +typedef u_int64_t UINT64; /* 8 bytes */ +typedef unsigned int UWORD; /* Register */ + +/* ---------------------------------------------------------------------- */ +/* --- Constants -------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +#define UMAC_KEY_LEN 16 /* UMAC takes 16 bytes of external key */ + +/* Message "words" are read from memory in an endian-specific manner. */ +/* For this implementation to behave correctly, __LITTLE_ENDIAN__ must */ +/* be set true if the host computer is little-endian. */ + +#if BYTE_ORDER == LITTLE_ENDIAN +#define __LITTLE_ENDIAN__ 1 +#else +#define __LITTLE_ENDIAN__ 0 +#endif + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- Architecture Specific ------------------------------------------ */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- Primitive Routines --------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- */ +/* --- 32-bit by 32-bit to 64-bit Multiplication ------------------------ */ +/* ---------------------------------------------------------------------- */ + +#define MUL64(a,b) ((UINT64)((UINT64)(UINT32)(a) * (UINT64)(UINT32)(b))) + +/* ---------------------------------------------------------------------- */ +/* --- Endian Conversion --- Forcing assembly on some platforms */ +/* ---------------------------------------------------------------------- */ + +#if HAVE_SWAP32 +#define LOAD_UINT32_REVERSED(p) (swap32(*(UINT32 *)(p))) +#define STORE_UINT32_REVERSED(p,v) (*(UINT32 *)(p) = swap32(v)) +#else /* HAVE_SWAP32 */ + +static UINT32 LOAD_UINT32_REVERSED(void *ptr) +{ + UINT32 temp = *(UINT32 *)ptr; + temp = (temp >> 24) | ((temp & 0x00FF0000) >> 8 ) + | ((temp & 0x0000FF00) << 8 ) | (temp << 24); + return (UINT32)temp; +} + +static void STORE_UINT32_REVERSED(void *ptr, UINT32 x) +{ + UINT32 i = (UINT32)x; + *(UINT32 *)ptr = (i >> 24) | ((i & 0x00FF0000) >> 8 ) + | ((i & 0x0000FF00) << 8 ) | (i << 24); +} +#endif /* HAVE_SWAP32 */ + +/* The following definitions use the above reversal-primitives to do the right + * thing on endian specific load and stores. + */ + +#if (__LITTLE_ENDIAN__) +#define LOAD_UINT32_LITTLE(ptr) (*(UINT32 *)(ptr)) +#define STORE_UINT32_BIG(ptr,x) STORE_UINT32_REVERSED(ptr,x) +#else +#define LOAD_UINT32_LITTLE(ptr) LOAD_UINT32_REVERSED(ptr) +#define STORE_UINT32_BIG(ptr,x) (*(UINT32 *)(ptr) = (UINT32)(x)) +#endif + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- Begin KDF & PDF Section ---------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +/* UMAC uses AES with 16 byte block and key lengths */ +#define AES_BLOCK_LEN 16 + +/* OpenSSL's AES */ +#include "openbsd-compat/openssl-compat.h" +#ifndef USE_BUILTIN_RIJNDAEL +# include +#endif +typedef AES_KEY aes_int_key[1]; +#define aes_encryption(in,out,int_key) \ + AES_encrypt((u_char *)(in),(u_char *)(out),(AES_KEY *)int_key) +#define aes_key_setup(key,int_key) \ + AES_set_encrypt_key((u_char *)(key),UMAC_KEY_LEN*8,int_key) + +/* The user-supplied UMAC key is stretched using AES in a counter + * mode to supply all random bits needed by UMAC. The kdf function takes + * an AES internal key representation 'key' and writes a stream of + * 'nbytes' bytes to the memory pointed at by 'buffer_ptr'. Each distinct + * 'ndx' causes a distinct byte stream. + */ +static void kdf(void *buffer_ptr, aes_int_key key, UINT8 ndx, int nbytes) +{ + UINT8 in_buf[AES_BLOCK_LEN] = {0}; + UINT8 out_buf[AES_BLOCK_LEN]; + UINT8 *dst_buf = (UINT8 *)buffer_ptr; + int i; + + /* Setup the initial value */ + in_buf[AES_BLOCK_LEN-9] = ndx; + in_buf[AES_BLOCK_LEN-1] = i = 1; + + while (nbytes >= AES_BLOCK_LEN) { + aes_encryption(in_buf, out_buf, key); + memcpy(dst_buf,out_buf,AES_BLOCK_LEN); + in_buf[AES_BLOCK_LEN-1] = ++i; + nbytes -= AES_BLOCK_LEN; + dst_buf += AES_BLOCK_LEN; + } + if (nbytes) { + aes_encryption(in_buf, out_buf, key); + memcpy(dst_buf,out_buf,nbytes); + } +} + +/* The final UHASH result is XOR'd with the output of a pseudorandom + * function. Here, we use AES to generate random output and + * xor the appropriate bytes depending on the last bits of nonce. + * This scheme is optimized for sequential, increasing big-endian nonces. + */ + +typedef struct { + UINT8 cache[AES_BLOCK_LEN]; /* Previous AES output is saved */ + UINT8 nonce[AES_BLOCK_LEN]; /* The AES input making above cache */ + aes_int_key prf_key; /* Expanded AES key for PDF */ +} pdf_ctx; + +static void pdf_init(pdf_ctx *pc, aes_int_key prf_key) +{ + UINT8 buf[UMAC_KEY_LEN]; + + kdf(buf, prf_key, 0, UMAC_KEY_LEN); + aes_key_setup(buf, pc->prf_key); + + /* Initialize pdf and cache */ + memset(pc->nonce, 0, sizeof(pc->nonce)); + aes_encryption(pc->nonce, pc->cache, pc->prf_key); +} + +static void pdf_gen_xor(pdf_ctx *pc, UINT8 nonce[8], UINT8 buf[8]) +{ + /* 'ndx' indicates that we'll be using the 0th or 1st eight bytes + * of the AES output. If last time around we returned the ndx-1st + * element, then we may have the result in the cache already. + */ + +#if (UMAC_OUTPUT_LEN == 4) +#define LOW_BIT_MASK 3 +#elif (UMAC_OUTPUT_LEN == 8) +#define LOW_BIT_MASK 1 +#elif (UMAC_OUTPUT_LEN > 8) +#define LOW_BIT_MASK 0 +#endif + + UINT8 tmp_nonce_lo[4]; +#if LOW_BIT_MASK != 0 + int ndx = nonce[7] & LOW_BIT_MASK; +#endif + *(UINT32 *)tmp_nonce_lo = ((UINT32 *)nonce)[1]; + tmp_nonce_lo[3] &= ~LOW_BIT_MASK; /* zero last bit */ + + if ( (((UINT32 *)tmp_nonce_lo)[0] != ((UINT32 *)pc->nonce)[1]) || + (((UINT32 *)nonce)[0] != ((UINT32 *)pc->nonce)[0]) ) + { + ((UINT32 *)pc->nonce)[0] = ((UINT32 *)nonce)[0]; + ((UINT32 *)pc->nonce)[1] = ((UINT32 *)tmp_nonce_lo)[0]; + aes_encryption(pc->nonce, pc->cache, pc->prf_key); + } + +#if (UMAC_OUTPUT_LEN == 4) + *((UINT32 *)buf) ^= ((UINT32 *)pc->cache)[ndx]; +#elif (UMAC_OUTPUT_LEN == 8) + *((UINT64 *)buf) ^= ((UINT64 *)pc->cache)[ndx]; +#elif (UMAC_OUTPUT_LEN == 12) + ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0]; + ((UINT32 *)buf)[2] ^= ((UINT32 *)pc->cache)[2]; +#elif (UMAC_OUTPUT_LEN == 16) + ((UINT64 *)buf)[0] ^= ((UINT64 *)pc->cache)[0]; + ((UINT64 *)buf)[1] ^= ((UINT64 *)pc->cache)[1]; +#endif +} + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- Begin NH Hash Section ------------------------------------------ */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +/* The NH-based hash functions used in UMAC are described in the UMAC paper + * and specification, both of which can be found at the UMAC website. + * The interface to this implementation has two + * versions, one expects the entire message being hashed to be passed + * in a single buffer and returns the hash result immediately. The second + * allows the message to be passed in a sequence of buffers. In the + * muliple-buffer interface, the client calls the routine nh_update() as + * many times as necessary. When there is no more data to be fed to the + * hash, the client calls nh_final() which calculates the hash output. + * Before beginning another hash calculation the nh_reset() routine + * must be called. The single-buffer routine, nh(), is equivalent to + * the sequence of calls nh_update() and nh_final(); however it is + * optimized and should be prefered whenever the multiple-buffer interface + * is not necessary. When using either interface, it is the client's + * responsability to pass no more than L1_KEY_LEN bytes per hash result. + * + * The routine nh_init() initializes the nh_ctx data structure and + * must be called once, before any other PDF routine. + */ + + /* The "nh_aux" routines do the actual NH hashing work. They + * expect buffers to be multiples of L1_PAD_BOUNDARY. These routines + * produce output for all STREAMS NH iterations in one call, + * allowing the parallel implementation of the streams. + */ + +#define STREAMS (UMAC_OUTPUT_LEN / 4) /* Number of times hash is applied */ +#define L1_KEY_LEN 1024 /* Internal key bytes */ +#define L1_KEY_SHIFT 16 /* Toeplitz key shift between streams */ +#define L1_PAD_BOUNDARY 32 /* pad message to boundary multiple */ +#define ALLOC_BOUNDARY 16 /* Keep buffers aligned to this */ +#define HASH_BUF_BYTES 64 /* nh_aux_hb buffer multiple */ + +typedef struct { + UINT8 nh_key [L1_KEY_LEN + L1_KEY_SHIFT * (STREAMS - 1)]; /* NH Key */ + UINT8 data [HASH_BUF_BYTES]; /* Incomming data buffer */ + int next_data_empty; /* Bookeeping variable for data buffer. */ + int bytes_hashed; /* Bytes (out of L1_KEY_LEN) incorperated. */ + UINT64 state[STREAMS]; /* on-line state */ +} nh_ctx; + + +#if (UMAC_OUTPUT_LEN == 4) + +static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) +/* NH hashing primitive. Previous (partial) hash result is loaded and +* then stored via hp pointer. The length of the data pointed at by "dp", +* "dlen", is guaranteed to be divisible by L1_PAD_BOUNDARY (32). Key +* is expected to be endian compensated in memory at key setup. +*/ +{ + UINT64 h; + UWORD c = dlen / 32; + UINT32 *k = (UINT32 *)kp; + UINT32 *d = (UINT32 *)dp; + UINT32 d0,d1,d2,d3,d4,d5,d6,d7; + UINT32 k0,k1,k2,k3,k4,k5,k6,k7; + + h = *((UINT64 *)hp); + do { + d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); + d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); + d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); + d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); + k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); + k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); + h += MUL64((k0 + d0), (k4 + d4)); + h += MUL64((k1 + d1), (k5 + d5)); + h += MUL64((k2 + d2), (k6 + d6)); + h += MUL64((k3 + d3), (k7 + d7)); + + d += 8; + k += 8; + } while (--c); + *((UINT64 *)hp) = h; +} + +#elif (UMAC_OUTPUT_LEN == 8) + +static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) +/* Same as previous nh_aux, but two streams are handled in one pass, + * reading and writing 16 bytes of hash-state per call. + */ +{ + UINT64 h1,h2; + UWORD c = dlen / 32; + UINT32 *k = (UINT32 *)kp; + UINT32 *d = (UINT32 *)dp; + UINT32 d0,d1,d2,d3,d4,d5,d6,d7; + UINT32 k0,k1,k2,k3,k4,k5,k6,k7, + k8,k9,k10,k11; + + h1 = *((UINT64 *)hp); + h2 = *((UINT64 *)hp + 1); + k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); + do { + d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); + d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); + d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); + d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); + k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); + k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11); + + h1 += MUL64((k0 + d0), (k4 + d4)); + h2 += MUL64((k4 + d0), (k8 + d4)); + + h1 += MUL64((k1 + d1), (k5 + d5)); + h2 += MUL64((k5 + d1), (k9 + d5)); + + h1 += MUL64((k2 + d2), (k6 + d6)); + h2 += MUL64((k6 + d2), (k10 + d6)); + + h1 += MUL64((k3 + d3), (k7 + d7)); + h2 += MUL64((k7 + d3), (k11 + d7)); + + k0 = k8; k1 = k9; k2 = k10; k3 = k11; + + d += 8; + k += 8; + } while (--c); + ((UINT64 *)hp)[0] = h1; + ((UINT64 *)hp)[1] = h2; +} + +#elif (UMAC_OUTPUT_LEN == 12) + +static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) +/* Same as previous nh_aux, but two streams are handled in one pass, + * reading and writing 24 bytes of hash-state per call. +*/ +{ + UINT64 h1,h2,h3; + UWORD c = dlen / 32; + UINT32 *k = (UINT32 *)kp; + UINT32 *d = (UINT32 *)dp; + UINT32 d0,d1,d2,d3,d4,d5,d6,d7; + UINT32 k0,k1,k2,k3,k4,k5,k6,k7, + k8,k9,k10,k11,k12,k13,k14,k15; + + h1 = *((UINT64 *)hp); + h2 = *((UINT64 *)hp + 1); + h3 = *((UINT64 *)hp + 2); + k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); + k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); + do { + d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); + d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); + d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); + d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); + k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11); + k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15); + + h1 += MUL64((k0 + d0), (k4 + d4)); + h2 += MUL64((k4 + d0), (k8 + d4)); + h3 += MUL64((k8 + d0), (k12 + d4)); + + h1 += MUL64((k1 + d1), (k5 + d5)); + h2 += MUL64((k5 + d1), (k9 + d5)); + h3 += MUL64((k9 + d1), (k13 + d5)); + + h1 += MUL64((k2 + d2), (k6 + d6)); + h2 += MUL64((k6 + d2), (k10 + d6)); + h3 += MUL64((k10 + d2), (k14 + d6)); + + h1 += MUL64((k3 + d3), (k7 + d7)); + h2 += MUL64((k7 + d3), (k11 + d7)); + h3 += MUL64((k11 + d3), (k15 + d7)); + + k0 = k8; k1 = k9; k2 = k10; k3 = k11; + k4 = k12; k5 = k13; k6 = k14; k7 = k15; + + d += 8; + k += 8; + } while (--c); + ((UINT64 *)hp)[0] = h1; + ((UINT64 *)hp)[1] = h2; + ((UINT64 *)hp)[2] = h3; +} + +#elif (UMAC_OUTPUT_LEN == 16) + +static void nh_aux(void *kp, void *dp, void *hp, UINT32 dlen) +/* Same as previous nh_aux, but two streams are handled in one pass, + * reading and writing 24 bytes of hash-state per call. +*/ +{ + UINT64 h1,h2,h3,h4; + UWORD c = dlen / 32; + UINT32 *k = (UINT32 *)kp; + UINT32 *d = (UINT32 *)dp; + UINT32 d0,d1,d2,d3,d4,d5,d6,d7; + UINT32 k0,k1,k2,k3,k4,k5,k6,k7, + k8,k9,k10,k11,k12,k13,k14,k15, + k16,k17,k18,k19; + + h1 = *((UINT64 *)hp); + h2 = *((UINT64 *)hp + 1); + h3 = *((UINT64 *)hp + 2); + h4 = *((UINT64 *)hp + 3); + k0 = *(k+0); k1 = *(k+1); k2 = *(k+2); k3 = *(k+3); + k4 = *(k+4); k5 = *(k+5); k6 = *(k+6); k7 = *(k+7); + do { + d0 = LOAD_UINT32_LITTLE(d+0); d1 = LOAD_UINT32_LITTLE(d+1); + d2 = LOAD_UINT32_LITTLE(d+2); d3 = LOAD_UINT32_LITTLE(d+3); + d4 = LOAD_UINT32_LITTLE(d+4); d5 = LOAD_UINT32_LITTLE(d+5); + d6 = LOAD_UINT32_LITTLE(d+6); d7 = LOAD_UINT32_LITTLE(d+7); + k8 = *(k+8); k9 = *(k+9); k10 = *(k+10); k11 = *(k+11); + k12 = *(k+12); k13 = *(k+13); k14 = *(k+14); k15 = *(k+15); + k16 = *(k+16); k17 = *(k+17); k18 = *(k+18); k19 = *(k+19); + + h1 += MUL64((k0 + d0), (k4 + d4)); + h2 += MUL64((k4 + d0), (k8 + d4)); + h3 += MUL64((k8 + d0), (k12 + d4)); + h4 += MUL64((k12 + d0), (k16 + d4)); + + h1 += MUL64((k1 + d1), (k5 + d5)); + h2 += MUL64((k5 + d1), (k9 + d5)); + h3 += MUL64((k9 + d1), (k13 + d5)); + h4 += MUL64((k13 + d1), (k17 + d5)); + + h1 += MUL64((k2 + d2), (k6 + d6)); + h2 += MUL64((k6 + d2), (k10 + d6)); + h3 += MUL64((k10 + d2), (k14 + d6)); + h4 += MUL64((k14 + d2), (k18 + d6)); + + h1 += MUL64((k3 + d3), (k7 + d7)); + h2 += MUL64((k7 + d3), (k11 + d7)); + h3 += MUL64((k11 + d3), (k15 + d7)); + h4 += MUL64((k15 + d3), (k19 + d7)); + + k0 = k8; k1 = k9; k2 = k10; k3 = k11; + k4 = k12; k5 = k13; k6 = k14; k7 = k15; + k8 = k16; k9 = k17; k10 = k18; k11 = k19; + + d += 8; + k += 8; + } while (--c); + ((UINT64 *)hp)[0] = h1; + ((UINT64 *)hp)[1] = h2; + ((UINT64 *)hp)[2] = h3; + ((UINT64 *)hp)[3] = h4; +} + +/* ---------------------------------------------------------------------- */ +#endif /* UMAC_OUTPUT_LENGTH */ +/* ---------------------------------------------------------------------- */ + + +/* ---------------------------------------------------------------------- */ + +static void nh_transform(nh_ctx *hc, UINT8 *buf, UINT32 nbytes) +/* This function is a wrapper for the primitive NH hash functions. It takes + * as argument "hc" the current hash context and a buffer which must be a + * multiple of L1_PAD_BOUNDARY. The key passed to nh_aux is offset + * appropriately according to how much message has been hashed already. + */ +{ + UINT8 *key; + + key = hc->nh_key + hc->bytes_hashed; + nh_aux(key, buf, hc->state, nbytes); +} + +/* ---------------------------------------------------------------------- */ + +static void endian_convert(void *buf, UWORD bpw, UINT32 num_bytes) +/* We endian convert the keys on little-endian computers to */ +/* compensate for the lack of big-endian memory reads during hashing. */ +{ + UWORD iters = num_bytes / bpw; + if (bpw == 4) { + UINT32 *p = (UINT32 *)buf; + do { + *p = LOAD_UINT32_REVERSED(p); + p++; + } while (--iters); + } else if (bpw == 8) { + UINT32 *p = (UINT32 *)buf; + UINT32 t; + do { + t = LOAD_UINT32_REVERSED(p+1); + p[1] = LOAD_UINT32_REVERSED(p); + p[0] = t; + p += 2; + } while (--iters); + } +} +#if (__LITTLE_ENDIAN__) +#define endian_convert_if_le(x,y,z) endian_convert((x),(y),(z)) +#else +#define endian_convert_if_le(x,y,z) do{}while(0) /* Do nothing */ +#endif + +/* ---------------------------------------------------------------------- */ + +static void nh_reset(nh_ctx *hc) +/* Reset nh_ctx to ready for hashing of new data */ +{ + hc->bytes_hashed = 0; + hc->next_data_empty = 0; + hc->state[0] = 0; +#if (UMAC_OUTPUT_LEN >= 8) + hc->state[1] = 0; +#endif +#if (UMAC_OUTPUT_LEN >= 12) + hc->state[2] = 0; +#endif +#if (UMAC_OUTPUT_LEN == 16) + hc->state[3] = 0; +#endif + +} + +/* ---------------------------------------------------------------------- */ + +static void nh_init(nh_ctx *hc, aes_int_key prf_key) +/* Generate nh_key, endian convert and reset to be ready for hashing. */ +{ + kdf(hc->nh_key, prf_key, 1, sizeof(hc->nh_key)); + endian_convert_if_le(hc->nh_key, 4, sizeof(hc->nh_key)); + nh_reset(hc); +} + +/* ---------------------------------------------------------------------- */ + +static void nh_update(nh_ctx *hc, UINT8 *buf, UINT32 nbytes) +/* Incorporate nbytes of data into a nh_ctx, buffer whatever is not an */ +/* even multiple of HASH_BUF_BYTES. */ +{ + UINT32 i,j; + + j = hc->next_data_empty; + if ((j + nbytes) >= HASH_BUF_BYTES) { + if (j) { + i = HASH_BUF_BYTES - j; + memcpy(hc->data+j, buf, i); + nh_transform(hc,hc->data,HASH_BUF_BYTES); + nbytes -= i; + buf += i; + hc->bytes_hashed += HASH_BUF_BYTES; + } + if (nbytes >= HASH_BUF_BYTES) { + i = nbytes & ~(HASH_BUF_BYTES - 1); + nh_transform(hc, buf, i); + nbytes -= i; + buf += i; + hc->bytes_hashed += i; + } + j = 0; + } + memcpy(hc->data + j, buf, nbytes); + hc->next_data_empty = j + nbytes; +} + +/* ---------------------------------------------------------------------- */ + +static void zero_pad(UINT8 *p, int nbytes) +{ +/* Write "nbytes" of zeroes, beginning at "p" */ + if (nbytes >= (int)sizeof(UWORD)) { + while ((ptrdiff_t)p % sizeof(UWORD)) { + *p = 0; + nbytes--; + p++; + } + while (nbytes >= (int)sizeof(UWORD)) { + *(UWORD *)p = 0; + nbytes -= sizeof(UWORD); + p += sizeof(UWORD); + } + } + while (nbytes) { + *p = 0; + nbytes--; + p++; + } +} + +/* ---------------------------------------------------------------------- */ + +static void nh_final(nh_ctx *hc, UINT8 *result) +/* After passing some number of data buffers to nh_update() for integration + * into an NH context, nh_final is called to produce a hash result. If any + * bytes are in the buffer hc->data, incorporate them into the + * NH context. Finally, add into the NH accumulation "state" the total number + * of bits hashed. The resulting numbers are written to the buffer "result". + * If nh_update was never called, L1_PAD_BOUNDARY zeroes are incorporated. + */ +{ + int nh_len, nbits; + + if (hc->next_data_empty != 0) { + nh_len = ((hc->next_data_empty + (L1_PAD_BOUNDARY - 1)) & + ~(L1_PAD_BOUNDARY - 1)); + zero_pad(hc->data + hc->next_data_empty, + nh_len - hc->next_data_empty); + nh_transform(hc, hc->data, nh_len); + hc->bytes_hashed += hc->next_data_empty; + } else if (hc->bytes_hashed == 0) { + nh_len = L1_PAD_BOUNDARY; + zero_pad(hc->data, L1_PAD_BOUNDARY); + nh_transform(hc, hc->data, nh_len); + } + + nbits = (hc->bytes_hashed << 3); + ((UINT64 *)result)[0] = ((UINT64 *)hc->state)[0] + nbits; +#if (UMAC_OUTPUT_LEN >= 8) + ((UINT64 *)result)[1] = ((UINT64 *)hc->state)[1] + nbits; +#endif +#if (UMAC_OUTPUT_LEN >= 12) + ((UINT64 *)result)[2] = ((UINT64 *)hc->state)[2] + nbits; +#endif +#if (UMAC_OUTPUT_LEN == 16) + ((UINT64 *)result)[3] = ((UINT64 *)hc->state)[3] + nbits; +#endif + nh_reset(hc); +} + +/* ---------------------------------------------------------------------- */ + +static void nh(nh_ctx *hc, UINT8 *buf, UINT32 padded_len, + UINT32 unpadded_len, UINT8 *result) +/* All-in-one nh_update() and nh_final() equivalent. + * Assumes that padded_len is divisible by L1_PAD_BOUNDARY and result is + * well aligned + */ +{ + UINT32 nbits; + + /* Initialize the hash state */ + nbits = (unpadded_len << 3); + + ((UINT64 *)result)[0] = nbits; +#if (UMAC_OUTPUT_LEN >= 8) + ((UINT64 *)result)[1] = nbits; +#endif +#if (UMAC_OUTPUT_LEN >= 12) + ((UINT64 *)result)[2] = nbits; +#endif +#if (UMAC_OUTPUT_LEN == 16) + ((UINT64 *)result)[3] = nbits; +#endif + + nh_aux(hc->nh_key, buf, result, padded_len); +} + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- Begin UHASH Section -------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +/* UHASH is a multi-layered algorithm. Data presented to UHASH is first + * hashed by NH. The NH output is then hashed by a polynomial-hash layer + * unless the initial data to be hashed is short. After the polynomial- + * layer, an inner-product hash is used to produce the final UHASH output. + * + * UHASH provides two interfaces, one all-at-once and another where data + * buffers are presented sequentially. In the sequential interface, the + * UHASH client calls the routine uhash_update() as many times as necessary. + * When there is no more data to be fed to UHASH, the client calls + * uhash_final() which + * calculates the UHASH output. Before beginning another UHASH calculation + * the uhash_reset() routine must be called. The all-at-once UHASH routine, + * uhash(), is equivalent to the sequence of calls uhash_update() and + * uhash_final(); however it is optimized and should be + * used whenever the sequential interface is not necessary. + * + * The routine uhash_init() initializes the uhash_ctx data structure and + * must be called once, before any other UHASH routine. + */ + +/* ---------------------------------------------------------------------- */ +/* ----- Constants and uhash_ctx ---------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- */ +/* ----- Poly hash and Inner-Product hash Constants --------------------- */ +/* ---------------------------------------------------------------------- */ + +/* Primes and masks */ +#define p36 ((UINT64)0x0000000FFFFFFFFBull) /* 2^36 - 5 */ +#define p64 ((UINT64)0xFFFFFFFFFFFFFFC5ull) /* 2^64 - 59 */ +#define m36 ((UINT64)0x0000000FFFFFFFFFull) /* The low 36 of 64 bits */ + + +/* ---------------------------------------------------------------------- */ + +typedef struct uhash_ctx { + nh_ctx hash; /* Hash context for L1 NH hash */ + UINT64 poly_key_8[STREAMS]; /* p64 poly keys */ + UINT64 poly_accum[STREAMS]; /* poly hash result */ + UINT64 ip_keys[STREAMS*4]; /* Inner-product keys */ + UINT32 ip_trans[STREAMS]; /* Inner-product translation */ + UINT32 msg_len; /* Total length of data passed */ + /* to uhash */ +} uhash_ctx; +typedef struct uhash_ctx *uhash_ctx_t; + +/* ---------------------------------------------------------------------- */ + + +/* The polynomial hashes use Horner's rule to evaluate a polynomial one + * word at a time. As described in the specification, poly32 and poly64 + * require keys from special domains. The following implementations exploit + * the special domains to avoid overflow. The results are not guaranteed to + * be within Z_p32 and Z_p64, but the Inner-Product hash implementation + * patches any errant values. + */ + +static UINT64 poly64(UINT64 cur, UINT64 key, UINT64 data) +{ + UINT32 key_hi = (UINT32)(key >> 32), + key_lo = (UINT32)key, + cur_hi = (UINT32)(cur >> 32), + cur_lo = (UINT32)cur, + x_lo, + x_hi; + UINT64 X,T,res; + + X = MUL64(key_hi, cur_lo) + MUL64(cur_hi, key_lo); + x_lo = (UINT32)X; + x_hi = (UINT32)(X >> 32); + + res = (MUL64(key_hi, cur_hi) + x_hi) * 59 + MUL64(key_lo, cur_lo); + + T = ((UINT64)x_lo << 32); + res += T; + if (res < T) + res += 59; + + res += data; + if (res < data) + res += 59; + + return res; +} + + +/* Although UMAC is specified to use a ramped polynomial hash scheme, this + * implementation does not handle all ramp levels. Because we don't handle + * the ramp up to p128 modulus in this implementation, we are limited to + * 2^14 poly_hash() invocations per stream (for a total capacity of 2^24 + * bytes input to UMAC per tag, ie. 16MB). + */ +static void poly_hash(uhash_ctx_t hc, UINT32 data_in[]) +{ + int i; + UINT64 *data=(UINT64*)data_in; + + for (i = 0; i < STREAMS; i++) { + if ((UINT32)(data[i] >> 32) == 0xfffffffful) { + hc->poly_accum[i] = poly64(hc->poly_accum[i], + hc->poly_key_8[i], p64 - 1); + hc->poly_accum[i] = poly64(hc->poly_accum[i], + hc->poly_key_8[i], (data[i] - 59)); + } else { + hc->poly_accum[i] = poly64(hc->poly_accum[i], + hc->poly_key_8[i], data[i]); + } + } +} + + +/* ---------------------------------------------------------------------- */ + + +/* The final step in UHASH is an inner-product hash. The poly hash + * produces a result not neccesarily WORD_LEN bytes long. The inner- + * product hash breaks the polyhash output into 16-bit chunks and + * multiplies each with a 36 bit key. + */ + +static UINT64 ip_aux(UINT64 t, UINT64 *ipkp, UINT64 data) +{ + t = t + ipkp[0] * (UINT64)(UINT16)(data >> 48); + t = t + ipkp[1] * (UINT64)(UINT16)(data >> 32); + t = t + ipkp[2] * (UINT64)(UINT16)(data >> 16); + t = t + ipkp[3] * (UINT64)(UINT16)(data); + + return t; +} + +static UINT32 ip_reduce_p36(UINT64 t) +{ +/* Divisionless modular reduction */ + UINT64 ret; + + ret = (t & m36) + 5 * (t >> 36); + if (ret >= p36) + ret -= p36; + + /* return least significant 32 bits */ + return (UINT32)(ret); +} + + +/* If the data being hashed by UHASH is no longer than L1_KEY_LEN, then + * the polyhash stage is skipped and ip_short is applied directly to the + * NH output. + */ +static void ip_short(uhash_ctx_t ahc, UINT8 *nh_res, u_char *res) +{ + UINT64 t; + UINT64 *nhp = (UINT64 *)nh_res; + + t = ip_aux(0,ahc->ip_keys, nhp[0]); + STORE_UINT32_BIG((UINT32 *)res+0, ip_reduce_p36(t) ^ ahc->ip_trans[0]); +#if (UMAC_OUTPUT_LEN >= 8) + t = ip_aux(0,ahc->ip_keys+4, nhp[1]); + STORE_UINT32_BIG((UINT32 *)res+1, ip_reduce_p36(t) ^ ahc->ip_trans[1]); +#endif +#if (UMAC_OUTPUT_LEN >= 12) + t = ip_aux(0,ahc->ip_keys+8, nhp[2]); + STORE_UINT32_BIG((UINT32 *)res+2, ip_reduce_p36(t) ^ ahc->ip_trans[2]); +#endif +#if (UMAC_OUTPUT_LEN == 16) + t = ip_aux(0,ahc->ip_keys+12, nhp[3]); + STORE_UINT32_BIG((UINT32 *)res+3, ip_reduce_p36(t) ^ ahc->ip_trans[3]); +#endif +} + +/* If the data being hashed by UHASH is longer than L1_KEY_LEN, then + * the polyhash stage is not skipped and ip_long is applied to the + * polyhash output. + */ +static void ip_long(uhash_ctx_t ahc, u_char *res) +{ + int i; + UINT64 t; + + for (i = 0; i < STREAMS; i++) { + /* fix polyhash output not in Z_p64 */ + if (ahc->poly_accum[i] >= p64) + ahc->poly_accum[i] -= p64; + t = ip_aux(0,ahc->ip_keys+(i*4), ahc->poly_accum[i]); + STORE_UINT32_BIG((UINT32 *)res+i, + ip_reduce_p36(t) ^ ahc->ip_trans[i]); + } +} + + +/* ---------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- */ + +/* Reset uhash context for next hash session */ +static int uhash_reset(uhash_ctx_t pc) +{ + nh_reset(&pc->hash); + pc->msg_len = 0; + pc->poly_accum[0] = 1; +#if (UMAC_OUTPUT_LEN >= 8) + pc->poly_accum[1] = 1; +#endif +#if (UMAC_OUTPUT_LEN >= 12) + pc->poly_accum[2] = 1; +#endif +#if (UMAC_OUTPUT_LEN == 16) + pc->poly_accum[3] = 1; +#endif + return 1; +} + +/* ---------------------------------------------------------------------- */ + +/* Given a pointer to the internal key needed by kdf() and a uhash context, + * initialize the NH context and generate keys needed for poly and inner- + * product hashing. All keys are endian adjusted in memory so that native + * loads cause correct keys to be in registers during calculation. + */ +static void uhash_init(uhash_ctx_t ahc, aes_int_key prf_key) +{ + int i; + UINT8 buf[(8*STREAMS+4)*sizeof(UINT64)]; + + /* Zero the entire uhash context */ + memset(ahc, 0, sizeof(uhash_ctx)); + + /* Initialize the L1 hash */ + nh_init(&ahc->hash, prf_key); + + /* Setup L2 hash variables */ + kdf(buf, prf_key, 2, sizeof(buf)); /* Fill buffer with index 1 key */ + for (i = 0; i < STREAMS; i++) { + /* Fill keys from the buffer, skipping bytes in the buffer not + * used by this implementation. Endian reverse the keys if on a + * little-endian computer. + */ + memcpy(ahc->poly_key_8+i, buf+24*i, 8); + endian_convert_if_le(ahc->poly_key_8+i, 8, 8); + /* Mask the 64-bit keys to their special domain */ + ahc->poly_key_8[i] &= ((UINT64)0x01ffffffu << 32) + 0x01ffffffu; + ahc->poly_accum[i] = 1; /* Our polyhash prepends a non-zero word */ + } + + /* Setup L3-1 hash variables */ + kdf(buf, prf_key, 3, sizeof(buf)); /* Fill buffer with index 2 key */ + for (i = 0; i < STREAMS; i++) + memcpy(ahc->ip_keys+4*i, buf+(8*i+4)*sizeof(UINT64), + 4*sizeof(UINT64)); + endian_convert_if_le(ahc->ip_keys, sizeof(UINT64), + sizeof(ahc->ip_keys)); + for (i = 0; i < STREAMS*4; i++) + ahc->ip_keys[i] %= p36; /* Bring into Z_p36 */ + + /* Setup L3-2 hash variables */ + /* Fill buffer with index 4 key */ + kdf(ahc->ip_trans, prf_key, 4, STREAMS * sizeof(UINT32)); + endian_convert_if_le(ahc->ip_trans, sizeof(UINT32), + STREAMS * sizeof(UINT32)); +} + +/* ---------------------------------------------------------------------- */ + +#if 0 +static uhash_ctx_t uhash_alloc(u_char key[]) +{ +/* Allocate memory and force to a 16-byte boundary. */ + uhash_ctx_t ctx; + u_char bytes_to_add; + aes_int_key prf_key; + + ctx = (uhash_ctx_t)malloc(sizeof(uhash_ctx)+ALLOC_BOUNDARY); + if (ctx) { + if (ALLOC_BOUNDARY) { + bytes_to_add = ALLOC_BOUNDARY - + ((ptrdiff_t)ctx & (ALLOC_BOUNDARY -1)); + ctx = (uhash_ctx_t)((u_char *)ctx + bytes_to_add); + *((u_char *)ctx - 1) = bytes_to_add; + } + aes_key_setup(key,prf_key); + uhash_init(ctx, prf_key); + } + return (ctx); +} +#endif + +/* ---------------------------------------------------------------------- */ + +#if 0 +static int uhash_free(uhash_ctx_t ctx) +{ +/* Free memory allocated by uhash_alloc */ + u_char bytes_to_sub; + + if (ctx) { + if (ALLOC_BOUNDARY) { + bytes_to_sub = *((u_char *)ctx - 1); + ctx = (uhash_ctx_t)((u_char *)ctx - bytes_to_sub); + } + free(ctx); + } + return (1); +} +#endif +/* ---------------------------------------------------------------------- */ + +static int uhash_update(uhash_ctx_t ctx, u_char *input, long len) +/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and + * hash each one with NH, calling the polyhash on each NH output. + */ +{ + UWORD bytes_hashed, bytes_remaining; + UINT8 nh_result[STREAMS*sizeof(UINT64)]; + + if (ctx->msg_len + len <= L1_KEY_LEN) { + nh_update(&ctx->hash, (UINT8 *)input, len); + ctx->msg_len += len; + } else { + + bytes_hashed = ctx->msg_len % L1_KEY_LEN; + if (ctx->msg_len == L1_KEY_LEN) + bytes_hashed = L1_KEY_LEN; + + if (bytes_hashed + len >= L1_KEY_LEN) { + + /* If some bytes have been passed to the hash function */ + /* then we want to pass at most (L1_KEY_LEN - bytes_hashed) */ + /* bytes to complete the current nh_block. */ + if (bytes_hashed) { + bytes_remaining = (L1_KEY_LEN - bytes_hashed); + nh_update(&ctx->hash, (UINT8 *)input, bytes_remaining); + nh_final(&ctx->hash, nh_result); + ctx->msg_len += bytes_remaining; + poly_hash(ctx,(UINT32 *)nh_result); + len -= bytes_remaining; + input += bytes_remaining; + } + + /* Hash directly from input stream if enough bytes */ + while (len >= L1_KEY_LEN) { + nh(&ctx->hash, (UINT8 *)input, L1_KEY_LEN, + L1_KEY_LEN, nh_result); + ctx->msg_len += L1_KEY_LEN; + len -= L1_KEY_LEN; + input += L1_KEY_LEN; + poly_hash(ctx,(UINT32 *)nh_result); + } + } + + /* pass remaining < L1_KEY_LEN bytes of input data to NH */ + if (len) { + nh_update(&ctx->hash, (UINT8 *)input, len); + ctx->msg_len += len; + } + } + + return (1); +} + +/* ---------------------------------------------------------------------- */ + +static int uhash_final(uhash_ctx_t ctx, u_char *res) +/* Incorporate any pending data, pad, and generate tag */ +{ + UINT8 nh_result[STREAMS*sizeof(UINT64)]; + + if (ctx->msg_len > L1_KEY_LEN) { + if (ctx->msg_len % L1_KEY_LEN) { + nh_final(&ctx->hash, nh_result); + poly_hash(ctx,(UINT32 *)nh_result); + } + ip_long(ctx, res); + } else { + nh_final(&ctx->hash, nh_result); + ip_short(ctx,nh_result, res); + } + uhash_reset(ctx); + return (1); +} + +/* ---------------------------------------------------------------------- */ + +#if 0 +static int uhash(uhash_ctx_t ahc, u_char *msg, long len, u_char *res) +/* assumes that msg is in a writable buffer of length divisible by */ +/* L1_PAD_BOUNDARY. Bytes beyond msg[len] may be zeroed. */ +{ + UINT8 nh_result[STREAMS*sizeof(UINT64)]; + UINT32 nh_len; + int extra_zeroes_needed; + + /* If the message to be hashed is no longer than L1_HASH_LEN, we skip + * the polyhash. + */ + if (len <= L1_KEY_LEN) { + if (len == 0) /* If zero length messages will not */ + nh_len = L1_PAD_BOUNDARY; /* be seen, comment out this case */ + else + nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); + extra_zeroes_needed = nh_len - len; + zero_pad((UINT8 *)msg + len, extra_zeroes_needed); + nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result); + ip_short(ahc,nh_result, res); + } else { + /* Otherwise, we hash each L1_KEY_LEN chunk with NH, passing the NH + * output to poly_hash(). + */ + do { + nh(&ahc->hash, (UINT8 *)msg, L1_KEY_LEN, L1_KEY_LEN, nh_result); + poly_hash(ahc,(UINT32 *)nh_result); + len -= L1_KEY_LEN; + msg += L1_KEY_LEN; + } while (len >= L1_KEY_LEN); + if (len) { + nh_len = ((len + (L1_PAD_BOUNDARY - 1)) & ~(L1_PAD_BOUNDARY - 1)); + extra_zeroes_needed = nh_len - len; + zero_pad((UINT8 *)msg + len, extra_zeroes_needed); + nh(&ahc->hash, (UINT8 *)msg, nh_len, len, nh_result); + poly_hash(ahc,(UINT32 *)nh_result); + } + + ip_long(ahc, res); + } + + uhash_reset(ahc); + return 1; +} +#endif + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- Begin UMAC Section --------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +/* The UMAC interface has two interfaces, an all-at-once interface where + * the entire message to be authenticated is passed to UMAC in one buffer, + * and a sequential interface where the message is presented a little at a + * time. The all-at-once is more optimaized than the sequential version and + * should be preferred when the sequential interface is not required. + */ +struct umac_ctx { + uhash_ctx hash; /* Hash function for message compression */ + pdf_ctx pdf; /* PDF for hashed output */ + void *free_ptr; /* Address to free this struct via */ +} umac_ctx; + +/* ---------------------------------------------------------------------- */ + +#if 0 +int umac_reset(struct umac_ctx *ctx) +/* Reset the hash function to begin a new authentication. */ +{ + uhash_reset(&ctx->hash); + return (1); +} +#endif + +/* ---------------------------------------------------------------------- */ + +int umac_delete(struct umac_ctx *ctx) +/* Deallocate the ctx structure */ +{ + if (ctx) { + if (ALLOC_BOUNDARY) + ctx = (struct umac_ctx *)ctx->free_ptr; + free(ctx); + } + return (1); +} + +/* ---------------------------------------------------------------------- */ + +struct umac_ctx *umac_new(u_char key[]) +/* Dynamically allocate a umac_ctx struct, initialize variables, + * generate subkeys from key. Align to 16-byte boundary. + */ +{ + struct umac_ctx *ctx, *octx; + size_t bytes_to_add; + aes_int_key prf_key; + + octx = ctx = malloc(sizeof(*ctx) + ALLOC_BOUNDARY); + if (ctx) { + if (ALLOC_BOUNDARY) { + bytes_to_add = ALLOC_BOUNDARY - + ((ptrdiff_t)ctx & (ALLOC_BOUNDARY - 1)); + ctx = (struct umac_ctx *)((u_char *)ctx + bytes_to_add); + } + ctx->free_ptr = octx; + aes_key_setup(key,prf_key); + pdf_init(&ctx->pdf, prf_key); + uhash_init(&ctx->hash, prf_key); + } + + return (ctx); +} + +/* ---------------------------------------------------------------------- */ + +int umac_final(struct umac_ctx *ctx, u_char tag[], u_char nonce[8]) +/* Incorporate any pending data, pad, and generate tag */ +{ + uhash_final(&ctx->hash, (u_char *)tag); + pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag); + + return (1); +} + +/* ---------------------------------------------------------------------- */ + +int umac_update(struct umac_ctx *ctx, u_char *input, long len) +/* Given len bytes of data, we parse it into L1_KEY_LEN chunks and */ +/* hash each one, calling the PDF on the hashed output whenever the hash- */ +/* output buffer is full. */ +{ + uhash_update(&ctx->hash, input, len); + return (1); +} + +/* ---------------------------------------------------------------------- */ + +#if 0 +int umac(struct umac_ctx *ctx, u_char *input, + long len, u_char tag[], + u_char nonce[8]) +/* All-in-one version simply calls umac_update() and umac_final(). */ +{ + uhash(&ctx->hash, input, len, (u_char *)tag); + pdf_gen_xor(&ctx->pdf, (UINT8 *)nonce, (UINT8 *)tag); + + return (1); +} +#endif + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ----- End UMAC Section ----------------------------------------------- */ +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ diff --git a/openssh/umac.h b/openssh/umac.h new file mode 100644 index 0000000..055c705 --- /dev/null +++ b/openssh/umac.h @@ -0,0 +1,123 @@ +/* $OpenBSD: umac.h,v 1.1 2007/06/07 19:37:34 pvalchev Exp $ */ +/* ----------------------------------------------------------------------- + * + * umac.h -- C Implementation UMAC Message Authentication + * + * Version 0.93a of rfc4418.txt -- 2006 July 14 + * + * For a full description of UMAC message authentication see the UMAC + * world-wide-web page at http://www.cs.ucdavis.edu/~rogaway/umac + * Please report bugs and suggestions to the UMAC webpage. + * + * Copyright (c) 1999-2004 Ted Krovetz + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and with or without fee, is hereby + * granted provided that the above copyright notice appears in all copies + * and in supporting documentation, and that the name of the copyright + * holder not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * + * Comments should be directed to Ted Krovetz (tdk@acm.org) + * + * ---------------------------------------------------------------------- */ + + /* ////////////////////// IMPORTANT NOTES ///////////////////////////////// + * + * 1) This version does not work properly on messages larger than 16MB + * + * 2) If you set the switch to use SSE2, then all data must be 16-byte + * aligned + * + * 3) When calling the function umac(), it is assumed that msg is in + * a writable buffer of length divisible by 32 bytes. The message itself + * does not have to fill the entire buffer, but bytes beyond msg may be + * zeroed. + * + * 4) Two free AES implementations are supported by this implementation of + * UMAC. Paulo Barreto's version is in the public domain and can be found + * at http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ (search for + * "Barreto"). The only two files needed are rijndael-alg-fst.c and + * rijndael-alg-fst.h. + * Brian Gladman's version is distributed with GNU Public lisence + * and can be found at http://fp.gladman.plus.com/AES/index.htm. It + * includes a fast IA-32 assembly version. + * + /////////////////////////////////////////////////////////////////////// */ +#ifndef HEADER_UMAC_H +#define HEADER_UMAC_H + + +#ifdef __cplusplus + extern "C" { +#endif + +struct umac_ctx *umac_new(u_char key[]); +/* Dynamically allocate a umac_ctx struct, initialize variables, + * generate subkeys from key. + */ + +#if 0 +int umac_reset(struct umac_ctx *ctx); +/* Reset a umac_ctx to begin authenicating a new message */ +#endif + +int umac_update(struct umac_ctx *ctx, u_char *input, long len); +/* Incorporate len bytes pointed to by input into context ctx */ + +int umac_final(struct umac_ctx *ctx, u_char tag[], u_char nonce[8]); +/* Incorporate any pending data and the ctr value, and return tag. + * This function returns error code if ctr < 0. + */ + +int umac_delete(struct umac_ctx *ctx); +/* Deallocate the context structure */ + +#if 0 +int umac(struct umac_ctx *ctx, u_char *input, + long len, u_char tag[], + u_char nonce[8]); +/* All-in-one implementation of the functions Reset, Update and Final */ +#endif + +/* uhash.h */ + + +#if 0 +typedef struct uhash_ctx *uhash_ctx_t; + /* The uhash_ctx structure is defined by the implementation of the */ + /* UHASH functions. */ + +uhash_ctx_t uhash_alloc(u_char key[16]); + /* Dynamically allocate a uhash_ctx struct and generate subkeys using */ + /* the kdf and kdf_key passed in. If kdf_key_len is 0 then RC6 is */ + /* used to generate key with a fixed key. If kdf_key_len > 0 but kdf */ + /* is NULL then the first 16 bytes pointed at by kdf_key is used as a */ + /* key for an RC6 based KDF. */ + +int uhash_free(uhash_ctx_t ctx); + +int uhash_set_params(uhash_ctx_t ctx, + void *params); + +int uhash_reset(uhash_ctx_t ctx); + +int uhash_update(uhash_ctx_t ctx, + u_char *input, + long len); + +int uhash_final(uhash_ctx_t ctx, + u_char ouput[]); + +int uhash(uhash_ctx_t ctx, + u_char *input, + long len, + u_char output[]); + +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* HEADER_UMAC_H */ diff --git a/openssh/version.h b/openssh/version.h index 0f48111..6fcd7e0 100644 --- a/openssh/version.h +++ b/openssh/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.49 2007/03/06 10:13:14 djm Exp $ */ +/* $OpenBSD: version.h,v 1.50 2007/08/15 08:16:49 markus Exp $ */ -#define SSH_VERSION "OpenSSH_4.6" +#define SSH_VERSION "OpenSSH_4.7" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE -- 2.45.1