diff options
author | des <des@FreeBSD.org> | 2008-08-01 02:48:36 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2008-08-01 02:48:36 +0000 |
commit | b7aa600c416b507a21191efa2689c0a03031d58e (patch) | |
tree | ed813bdf7d8dbee35f19092d185e1a2793885204 /crypto | |
parent | a2326b0bec3be2ec01f66d386cfe43139cbc579c (diff) | |
parent | 8f6f5baf400f08937451cf9c8ecc220e9efd2f63 (diff) | |
download | FreeBSD-src-b7aa600c416b507a21191efa2689c0a03031d58e.zip FreeBSD-src-b7aa600c416b507a21191efa2689c0a03031d58e.tar.gz |
Upgrade to OpenSSH 5.1p1.
I have worked hard to reduce diffs against the vendor branch. One
notable change in that respect is that we no longer prefer DSA over
RSA - the reasons for doing so went away years ago. This may cause
some surprises, as ssh will warn about unknown host keys even for
hosts whose keys haven't changed.
MFC after: 6 weeks
Diffstat (limited to 'crypto')
171 files changed, 13145 insertions, 4658 deletions
diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog index 2755591..3d08a80 100644 --- a/crypto/openssh/ChangeLog +++ b/crypto/openssh/ChangeLog @@ -1,3 +1,2108 @@ +20080721 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2008/07/18 22:51:01 + [sftp-server.8] + no need for .Pp before or after .Sh; + - djm@cvs.openbsd.org 2008/07/21 08:19:07 + [version.h] + openssh-5.1 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update version number in README and RPM specs + - (djm) Release OpenSSH-5.1 + +20080717 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/07/17 08:48:00 + [sshconnect2.c] + strnvis preauth banner; pointed out by mpf@ ok markus@ + - djm@cvs.openbsd.org 2008/07/17 08:51:07 + [auth2-hostbased.c] + strip trailing '.' from hostname when HostbasedUsesNameFromPacketOnly=yes + report and patch from res AT qoxp.net (bz#1200); ok markus@ + - (dtucker) [openbsd-compat/bsd-cygwin_util.c] Remove long-unneeded compat + code, replace with equivalent cygwin library call. Patch from vinschen + at redhat.com, ok djm@. + - (djm) [sshconnect2.c] vis.h isn't available everywhere + +20080716 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/07/15 02:23:14 + [sftp.1] + number of pipelined requests is now 64; + prodded by Iain.Morgan AT nasa.gov + - djm@cvs.openbsd.org 2008/07/16 11:51:14 + [clientloop.c] + rename variable first_gc -> last_gc (since it is actually the last + in the list). + - djm@cvs.openbsd.org 2008/07/16 11:52:19 + [channels.c] + this loop index should be automatic, not static + +20080714 + - (djm) OpenBSD CVS Sync + - sthen@cvs.openbsd.org 2008/07/13 21:22:52 + [ssh-keygen.c] + Change "ssh-keygen -F [host] -l" to not display random art unless + -v is also specified, making it consistent with the manual and other + uses of -l. + ok grunk@ + - djm@cvs.openbsd.org 2008/07/13 22:13:07 + [channels.c] + use struct sockaddr_storage instead of struct sockaddr for accept(2) + address argument. from visibilis AT yahoo.com in bz#1485; ok markus@ + - djm@cvs.openbsd.org 2008/07/13 22:16:03 + [sftp.c] + increase number of piplelined requests so they properly fill the + (recently increased) channel window. prompted by rapier AT psc.edu; + ok markus@ + - djm@cvs.openbsd.org 2008/07/14 01:55:56 + [sftp-server.8] + mention requirement for /dev/log inside chroot when using sftp-server + with ChrootDirectory + - (djm) [openbsd-compat/bindresvport.c] Rename variables s/sin/in/ to + avoid clash with sin(3) function; reported by + cristian.ionescu-idbohrn AT axis.com + - (djm) [openbsd-compat/rresvport.c] Add unistd.h for missing close() + prototype; reported by cristian.ionescu-idbohrn AT axis.com + - (djm) [umac.c] Rename variable s/buffer_ptr/bufp/ to avoid clash; + reported by cristian.ionescu-idbohrn AT axis.com + - (djm) [contrib/cygwin/Makefile contrib/cygwin/ssh-host-config] + [contrib/cygwin/ssh-user-config contrib/cygwin/sshd-inetd] + Revamped and simplified Cygwin ssh-host-config script that uses + unified csih configuration tool. Requires recent Cygwin. + Patch from vinschen AT redhat.com + +20080712 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/07/12 04:52:50 + [channels.c] + unbreak; move clearing of cctx struct to before first use + reported by dkrause@ + - djm@cvs.openbsd.org 2008/07/12 05:33:41 + [scp.1] + better description for -i flag: + s/RSA authentication/public key authentication/ + - (djm) [openbsd-compat/fake-rfc2553.c openbsd-compat/fake-rfc2553.h] + return EAI_FAMILY when trying to lookup unsupported address family; + from vinschen AT redhat.com + +20080711 + - (djm) OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2008/07/07 00:31:41 + [ttymodes.c] + we don't need arg after the debug3() was removed. from lint. + ok djm@ + - stevesk@cvs.openbsd.org 2008/07/07 23:32:51 + [key.c] + /*NOTREACHED*/ for lint warning: + warning: function key_equal falls off bottom without returning value + ok djm@ + - markus@cvs.openbsd.org 2008/07/10 18:05:58 + [channels.c] + missing bzero; from mickey; ok djm@ + - markus@cvs.openbsd.org 2008/07/10 18:08:11 + [clientloop.c monitor.c monitor_wrap.c packet.c packet.h sshd.c] + sync v1 and v2 traffic accounting; add it to sshd, too; + ok djm@, dtucker@ + +20080709 + - (djm) [Makefile.in] Print "all tests passed" when all regress tests pass + - (djm) [auth1.c] Fix format string vulnerability in protocol 1 PAM + account check failure path. The vulnerable format buffer is supplied + from PAM and should not contain attacker-supplied data. + - (djm) [auth.c] Missing unistd.h for close() + - (djm) [configure.ac] Add -Wformat-security to CFLAGS for gcc 3.x and 4.x + +20080705 + - (djm) [auth.c] Fixed test for locked account on HP/UX with shadowed + passwords disabled. bz#1083 report & patch from senthilkumar_sen AT + hotpop.com, w/ dtucker@ + - (djm) [atomicio.c configure.ac] Disable poll() fallback in atomiciov for + Tru64. readv doesn't seem to be a comparable object there. + bz#1386, patch from dtucker@ ok me + - (djm) [Makefile.in] Pass though pass to conch for interop tests + - (djm) [configure.ac] unbreak: remove extra closing brace + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/07/04 23:08:25 + [packet.c] + handle EINTR in packet_write_poll()l ok dtucker@ + - djm@cvs.openbsd.org 2008/07/04 23:30:16 + [auth1.c auth2.c] + Make protocol 1 MaxAuthTries logic match protocol 2's. + Do not treat the first protocol 2 authentication attempt as + a failure IFF it is for method "none". + Makes MaxAuthTries' user-visible behaviour identical for + protocol 1 vs 2. + ok dtucker@ + - djm@cvs.openbsd.org 2008/07/05 05:16:01 + [PROTOCOL] + grammar + +20080704 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/07/02 13:30:34 + [auth2.c] + really really remove the freebie "none" auth try for protocol 2 + - djm@cvs.openbsd.org 2008/07/02 13:47:39 + [ssh.1 ssh.c] + When forking after authentication ("ssh -f") with ExitOnForwardFailure + enabled, delay the fork until after replies for any -R forwards have + been seen. Allows for robust detection of -R forward failure when + using -f (similar to bz#92); ok dtucker@ + - otto@cvs.openbsd.org 2008/07/03 21:46:58 + [auth2-pubkey.c] + avoid nasty double free; ok dtucker@ djm@ + - djm@cvs.openbsd.org 2008/07/04 03:44:59 + [servconf.c groupaccess.h groupaccess.c] + support negation of groups in "Match group" block (bz#1315); ok dtucker@ + - dtucker@cvs.openbsd.org 2008/07/04 03:47:02 + [monitor.c] + Make debug a little clearer. ok djm@ + - djm@cvs.openbsd.org 2008/06/30 08:07:34 + [regress/key-options.sh] + shell portability: use "=" instead of "==" in test(1) expressions, + double-quote string with backslash escaped / + - djm@cvs.openbsd.org 2008/06/30 10:31:11 + [regress/{putty-transfer,putty-kex,putty-ciphers}.sh] + remove "set -e" left over from debugging + - djm@cvs.openbsd.org 2008/06/30 10:43:03 + [regress/conch-ciphers.sh] + explicitly disable conch options that could interfere with the test + - (dtucker) [sftp-server.c] Bug #1447: fall back to racy rename if link + returns EXDEV. Patch from Mike Garrison, ok djm@ + - (djm) [atomicio.c channels.c clientloop.c defines.h includes.h] + [packet.c scp.c serverloop.c sftp-client.c ssh-agent.c ssh-keyscan.c] + [sshd.c] Explicitly handle EWOULDBLOCK wherever we handle EAGAIN, on + some platforms (HP nonstop) it is a distinct errno; + bz#1467 reported by sconeu AT yahoo.com; ok dtucker@ + +20080702 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/06/30 08:05:59 + [PROTOCOL.agent] + typo: s/constraint_date/constraint_data/ + - djm@cvs.openbsd.org 2008/06/30 12:15:39 + [serverloop.c] + only pass channel requests on session channels through to the session + channel handler, avoiding spurious log messages; ok! markus@ + - djm@cvs.openbsd.org 2008/06/30 12:16:02 + [nchan.c] + only send eow@openssh.com notifications for session channels; ok! markus@ + - djm@cvs.openbsd.org 2008/06/30 12:18:34 + [PROTOCOL] + clarify that eow@openssh.com is only sent on session channels + - dtucker@cvs.openbsd.org 2008/07/01 07:20:52 + [sshconnect.c] + Check ExitOnForwardFailure if forwardings are disabled due to a failed + host key check. ok djm@ + - dtucker@cvs.openbsd.org 2008/07/01 07:24:22 + [sshconnect.c sshd.c] + Send CR LF during protocol banner exchanges, but only for Protocol 2 only, + in order to comply with RFC 4253. bz #1443, ok djm@ + - stevesk@cvs.openbsd.org 2008/07/01 23:12:47 + [PROTOCOL.agent] + fix some typos; ok djm@ + - djm@cvs.openbsd.org 2008/07/02 02:24:18 + [sshd_config sshd_config.5 sshd.8 servconf.c] + increase default size of ssh protocol 1 ephemeral key from 768 to 1024 + bits; prodded by & ok dtucker@ ok deraadt@ + - dtucker@cvs.openbsd.org 2008/07/02 12:03:51 + [auth-rsa.c auth.c auth2-pubkey.c auth.h] + Merge duplicate host key file checks, based in part on a patch from Rob + Holland via bz #1348 . Also checks for non-regular files during protocol + 1 RSA auth. ok djm@ + - djm@cvs.openbsd.org 2008/07/02 12:36:39 + [auth2-none.c auth2.c] + Make protocol 2 MaxAuthTries behaviour a little more sensible: + Check whether client has exceeded MaxAuthTries before running + an authentication method and skip it if they have, previously it + would always allow one try (for "none" auth). + Preincrement failure count before post-auth test - previously this + checked and postincremented, also to allow one "none" try. + Together, these two changes always count the "none" auth method + which could be skipped by a malicious client (e.g. an SSH worm) + to get an extra attempt at a real auth method. They also make + MaxAuthTries=0 a useful way to block users entirely (esp. in a + sshd_config Match block). + Also, move sending of any preauth banner from "none" auth method + to the first call to input_userauth_request(), so worms that skip + the "none" method get to see it too. + +20080630 + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2008/06/10 23:13:43 + [regress/Makefile regress/key-options.sh] + Add regress test for key options. ok djm@ + - dtucker@cvs.openbsd.org 2008/06/11 23:11:40 + [regress/Makefile] + Don't run cipher-speed test by default; mistakenly enabled by me + - djm@cvs.openbsd.org 2008/06/28 13:57:25 + [regress/Makefile regress/test-exec.sh regress/conch-ciphers.sh] + very basic regress test against Twisted Conch in "make interop" + target (conch is available in ports/devel/py-twisted/conch); + ok markus@ + - (djm) [regress/Makefile] search for conch by path, like we do putty + +20080629 + - (djm) OpenBSD CVS Sync + - martynas@cvs.openbsd.org 2008/06/21 07:46:46 + [sftp.c] + use optopt to get invalid flag, instead of return value of getopt, + which is always '?'; ok djm@ + - otto@cvs.openbsd.org 2008/06/25 11:13:43 + [key.c] + add key length to visual fingerprint; zap magical constants; + ok grunk@ djm@ + - djm@cvs.openbsd.org 2008/06/26 06:10:09 + [sftp-client.c sftp-server.c] + allow the sftp chmod(2)-equivalent operation to set set[ug]id/sticky + bits. Note that this only affects explicit setting of modes (e.g. via + sftp(1)'s chmod command) and not file transfers. (bz#1310) + ok deraadt@ at c2k8 + - djm@cvs.openbsd.org 2008/06/26 09:19:40 + [dh.c dh.h moduli.c] + when loading moduli from /etc/moduli in sshd(8), check that they + are of the expected "safe prime" structure and have had + appropriate primality tests performed; + feedback and ok dtucker@ + - grunk@cvs.openbsd.org 2008/06/26 11:46:31 + [readconf.c readconf.h ssh.1 ssh_config.5 sshconnect.c] + Move SSH Fingerprint Visualization away from sharing the config option + CheckHostIP to an own config option named VisualHostKey. + While there, fix the behaviour that ssh would draw a random art picture + on every newly seen host even when the option was not enabled. + prodded by deraadt@, discussions, + help and ok markus@ djm@ dtucker@ + - jmc@cvs.openbsd.org 2008/06/26 21:11:46 + [ssh.1] + add VisualHostKey to the list of options listed in -o; + - djm@cvs.openbsd.org 2008/06/28 07:25:07 + [PROTOCOL] + spelling fixes + - djm@cvs.openbsd.org 2008/06/28 13:58:23 + [ssh-agent.c] + refuse to add a key that has unknown constraints specified; + ok markus + - djm@cvs.openbsd.org 2008/06/28 14:05:15 + [ssh-agent.c] + reset global compat flag after processing a protocol 2 signature + request with the legacy DSA encoding flag set; ok markus + - djm@cvs.openbsd.org 2008/06/28 14:08:30 + [PROTOCOL PROTOCOL.agent] + document the protocol used by ssh-agent; "looks ok" markus@ + +20080628 + - (djm) [RFC.nroff contrib/cygwin/Makefile contrib/suse/openssh.spec] + RFC.nroff lacks a license, remove it (it is long gone in OpenBSD). + +20080626 + - (djm) [Makefile.in moduli.5] Include moduli(5) manpage from OpenBSD. + (bz#1372) + - (djm) [ contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Include moduli.5 in RPM spec files. + +20080616 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2008/06/16 13:22:53 + [session.c channels.c] + Rename the isatty argument to is_tty so we don't shadow + isatty(3). ok markus@ + - (dtucker) [channels.c] isatty -> is_tty here too. + +20080615 + - (dtucker) [configure.ac] Enable -fno-builtin-memset when using gcc. + - OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2008/06/14 15:49:48 + [sshd.c] + wrap long line at 80 chars + - dtucker@cvs.openbsd.org 2008/06/14 17:07:11 + [sshd.c] + ensure default umask disallows at least group and world write; ok djm@ + - djm@cvs.openbsd.org 2008/06/14 18:33:43 + [session.c] + suppress the warning message from chdir(homedir) failures + when chrooted (bz#1461); ok dtucker + - dtucker@cvs.openbsd.org 2008/06/14 19:42:10 + [scp.1] + Mention that scp follows symlinks during -r. bz #1466, + from nectar at apple + - dtucker@cvs.openbsd.org 2008/06/15 16:55:38 + [sshd_config.5] + MaxSessions is allowed in a Match block too + - dtucker@cvs.openbsd.org 2008/06/15 16:58:40 + [servconf.c sshd_config.5] + Allow MaxAuthTries within a Match block. ok djm@ + - djm@cvs.openbsd.org 2008/06/15 20:06:26 + [channels.c channels.h session.c] + don't call isatty() on a pty master, instead pass a flag down to + channel_set_fds() indicating that te fds refer to a tty. Fixes a + hang on exit on Solaris (bz#1463) in portable but is actually + a generic bug; ok dtucker deraadt markus + +20080614 + - (djm) [openbsd-compat/sigact.c] Avoid NULL derefs in ancient sigaction + replacement code; patch from ighighi AT gmail.com in bz#1240; + ok dtucker + +20080613 + - (dtucker) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2008/06/13 09:44:36 + [packet.c] + compile on older gcc; no decl after code + - dtucker@cvs.openbsd.org 2008/06/13 13:56:59 + [monitor.c] + Clear key options in the monitor on failed authentication, prevents + applying additional restrictions to non-pubkey authentications in + the case where pubkey fails but another method subsequently succeeds. + bz #1472, found by Colin Watson, ok markus@ djm@ + - dtucker@cvs.openbsd.org 2008/06/13 14:18:51 + [auth2-pubkey.c auth-rhosts.c] + Include unistd.h for close(), prevents warnings in -portable + - dtucker@cvs.openbsd.org 2008/06/13 17:21:20 + [mux.c] + Friendlier error messages for mux fallback. ok djm@ + - dtucker@cvs.openbsd.org 2008/06/13 18:55:22 + [scp.c] + Prevent -Wsign-compare warnings on LP64 systems. bz #1192, ok deraadt@ + - grunk@cvs.openbsd.org 2008/06/13 20:13:26 + [ssh.1] + Explain the use of SSH fpr visualization using random art, and cite the + original scientific paper inspiring that technique. + Much help with English and nroff by jmc@, thanks. + - (dtucker) [configure.ac] Bug #1276: avoid linking against libgssapi, which + despite its name doesn't seem to implement all of GSSAPI. Patch from + Jan Engelhardt, sanity checked by Simon Wilkinson. + +20080612 + - (dtucker) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2008/06/11 07:30:37 + [sshd.8] + kill trailing whitespace; + - grunk@cvs.openbsd.org 2008/06/11 21:01:35 + [ssh_config.5 key.h readconf.c readconf.h ssh-keygen.1 ssh-keygen.c key.c + sshconnect.c] + Introduce SSH Fingerprint ASCII Visualization, a technique inspired by the + graphical hash visualization schemes known as "random art", and by + Dan Kaminsky's musings on the subject during a BlackOp talk at the + 23C3 in Berlin. + Scientific publication (original paper): + "Hash Visualization: a New Technique to improve Real-World Security", + Perrig A. and Song D., 1999, International Workshop on Cryptographic + Techniques and E-Commerce (CrypTEC '99) + http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf + The algorithm used here is a worm crawling over a discrete plane, + leaving a trace (augmenting the field) everywhere it goes. + Movement is taken from dgst_raw 2bit-wise. Bumping into walls + makes the respective movement vector be ignored for this turn, + thus switching to the other color of the chessboard. + Graphs are not unambiguous for now, because circles in graphs can be + walked in either direction. + discussions with several people, + help, corrections and ok markus@ djm@ + - grunk@cvs.openbsd.org 2008/06/11 21:38:25 + [ssh-keygen.c] + ssh-keygen -lv -f /etc/ssh/ssh_host_rsa_key.pub + would not display you the random art as intended, spotted by canacar@ + - grunk@cvs.openbsd.org 2008/06/11 22:20:46 + [ssh-keygen.c ssh-keygen.1] + ssh-keygen would write fingerprints to STDOUT, and random art to STDERR, + that is not how it was envisioned. + Also correct manpage saying that -v is needed along with -l for it to work. + spotted by naddy@ + - otto@cvs.openbsd.org 2008/06/11 23:02:22 + [key.c] + simpler way of computing the augmentations; ok grunk@ + - grunk@cvs.openbsd.org 2008/06/11 23:03:56 + [ssh_config.5] + CheckHostIP set to ``fingerprint'' will display both hex and random art + spotted by naddy@ + - grunk@cvs.openbsd.org 2008/06/11 23:51:57 + [key.c] + #define statements that are not atoms need braces around them, else they + will cause trouble in some cases. + Also do a computation of -1 once, and not in a loop several times. + spotted by otto@ + - dtucker@cvs.openbsd.org 2008/06/12 00:03:49 + [dns.c canohost.c sshconnect.c] + Do not pass "0" strings as ports to getaddrinfo because the lookups + can slow things down and we never use the service info anyway. bz + #859, patch from YOSHIFUJI Hideaki and John Devitofranceschi. ok + deraadt@ djm@ + djm belives that the reason for the "0" strings is to ensure that + it's not possible to call getaddrinfo with both host and port being + NULL. In the case of canohost.c host is a local array. In the + case of sshconnect.c, it's checked for null immediately before use. + In dns.c it ultimately comes from ssh.c:main() and is guaranteed to + be non-null but it's not obvious, so I added a warning message in + case it is ever passed a null. + - grunk@cvs.openbsd.org 2008/06/12 00:13:55 + [sshconnect.c] + Make ssh print the random art also when ssh'ing to a host using IP only. + spotted by naddy@, ok and help djm@ dtucker@ + - otto@cvs.openbsd.org 2008/06/12 00:13:13 + [key.c] + use an odd number of rows and columns and a separate start marker, looks + better; ok grunk@ + - djm@cvs.openbsd.org 2008/06/12 03:40:52 + [clientloop.h mux.c channels.c clientloop.c channels.h] + Enable ~ escapes for multiplex slave sessions; give each channel + its own escape state and hook the escape filters up to muxed + channels. bz #1331 + Mux slaves do not currently support the ~^Z and ~& escapes. + NB. this change cranks the mux protocol version, so a new ssh + mux client will not be able to connect to a running old ssh + mux master. + ok dtucker@ + - djm@cvs.openbsd.org 2008/06/12 04:06:00 + [clientloop.h ssh.c clientloop.c] + maintain an ordered queue of outstanding global requests that we + expect replies to, similar to the per-channel confirmation queue. + Use this queue to verify success or failure for remote forward + establishment in a race free way. + ok dtucker@ + - djm@cvs.openbsd.org 2008/06/12 04:17:47 + [clientloop.c] + thall shalt not code past the eightieth column + - djm@cvs.openbsd.org 2008/06/12 04:24:06 + [ssh.c] + thal shalt not code past the eightieth column + - djm@cvs.openbsd.org 2008/06/12 05:15:41 + [PROTOCOL] + document tun@openssh.com forwarding method + - djm@cvs.openbsd.org 2008/06/12 05:32:30 + [mux.c] + some more TODO for me + - grunk@cvs.openbsd.org 2008/06/12 05:42:46 + [key.c] + supply the key type (rsa1, rsa, dsa) as a caption in the frame of the + random art. while there, stress the fact that the field base should at + least be 8 characters for the pictures to make sense. + comment and ok djm@ + - grunk@cvs.openbsd.org 2008/06/12 06:32:59 + [key.c] + We already mark the start of the worm, now also mark the end of the worm + in our random art drawings. + ok djm@ + - djm@cvs.openbsd.org 2008/06/12 15:19:17 + [clientloop.h channels.h clientloop.c channels.c mux.c] + The multiplexing escape char handler commit last night introduced a + small memory leak per session; plug it. + - dtucker@cvs.openbsd.org 2008/06/12 16:35:31 + [ssh_config.5 ssh.c] + keyword expansion for localcommand. ok djm@ + - jmc@cvs.openbsd.org 2008/06/12 19:10:09 + [ssh_config.5 ssh-keygen.1] + tweak the ascii art text; ok grunk + - dtucker@cvs.openbsd.org 2008/06/12 20:38:28 + [sshd.c sshconnect.c packet.h misc.c misc.h packet.c] + Make keepalive timeouts apply while waiting for a packet, particularly + during key renegotiation (bz #1363). With djm and Matt Day, ok djm@ + - djm@cvs.openbsd.org 2008/06/12 20:47:04 + [sftp-client.c] + print extension revisions for extensions that we understand + - djm@cvs.openbsd.org 2008/06/12 21:06:25 + [clientloop.c] + I was coalescing expected global request confirmation replies at + the wrong end of the queue - fix; prompted by markus@ + - grunk@cvs.openbsd.org 2008/06/12 21:14:46 + [ssh-keygen.c] + make ssh-keygen -lf show the key type just as ssh-add -l would do it + ok djm@ markus@ + - grunk@cvs.openbsd.org 2008/06/12 22:03:36 + [key.c] + add my copyright, ok djm@ + - ian@cvs.openbsd.org 2008/06/12 23:24:58 + [sshconnect.c] + tweak wording in message, ok deraadt@ jmc@ + - dtucker@cvs.openbsd.org 2008/06/13 00:12:02 + [sftp.h log.h] + replace __dead with __attribute__((noreturn)), makes things + a little easier to port. Also, add it to sigdie(). ok djm@ + - djm@cvs.openbsd.org 2008/06/13 00:16:49 + [mux.c] + fall back to creating a new TCP connection on most multiplexing errors + (socket connect fail, invalid version, refused permittion, corrupted + messages, etc.); bz #1329 ok dtucker@ + - dtucker@cvs.openbsd.org 2008/06/13 00:47:53 + [mux.c] + upcast size_t to u_long to match format arg; ok djm@ + - dtucker@cvs.openbsd.org 2008/06/13 00:51:47 + [mac.c] + upcast another size_t to u_long to match format + - dtucker@cvs.openbsd.org 2008/06/13 01:38:23 + [misc.c] + upcast uid to long with matching %ld, prevents warnings in portable + - djm@cvs.openbsd.org 2008/06/13 04:40:22 + [auth2-pubkey.c auth-rhosts.c] + refuse to read ~/.shosts or ~/.ssh/authorized_keys that are not + regular files; report from Solar Designer via Colin Watson in bz#1471 + ok dtucker@ deraadt + - (dtucker) [clientloop.c serverloop.c] channel_register_filter now + takes 2 more args. with djm@ + - (dtucker) [defines.h] Bug #1112: __dead is, well dead. Based on a patch + from Todd Vierling. + - (dtucker) [auth-sia.c] Bug #1241: support password expiry on Tru64 SIA + systems. Patch from R. Scott Bailey. + - (dtucker) [umac.c] STORE_UINT32_REVERSED and endian_convert are never used + on big endian machines, so ifdef them for little-endian only to prevent + unused function warnings on big-endians. + - (dtucker) [openbsd-compat/setenv.c] Make offsets size_t to prevent + compiler warnings on some platforms. Based on a discussion with otto@ + +20080611 + - (djm) [channels.c configure.ac] + Do not set SO_REUSEADDR on wildcard X11 listeners (X11UseLocalhost=no) + bz#1464; ok dtucker + +20080610 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/06/10 03:57:27 + [servconf.c match.h sshd_config.5] + support CIDR address matching in sshd_config "Match address" blocks, with + full support for negation and fall-back to classic wildcard matching. + For example: + Match address 192.0.2.0/24,3ffe:ffff::/32,!10.* + PasswordAuthentication yes + addrmatch.c code mostly lifted from flowd's addr.c + feedback and ok dtucker@ + - djm@cvs.openbsd.org 2008/06/10 04:17:46 + [sshd_config.5] + better reference for pattern-list + - dtucker@cvs.openbsd.org 2008/06/10 04:50:25 + [sshd.c channels.h channels.c log.c servconf.c log.h servconf.h sshd.8] + Add extended test mode (-T) and connection parameters for test mode (-C). + -T causes sshd to write its effective configuration to stdout and exit. + -C causes any relevant Match rules to be applied before output. The + combination allows tesing of the parser and config files. ok deraadt djm + - jmc@cvs.openbsd.org 2008/06/10 07:12:00 + [sshd_config.5] + tweak previous; + - jmc@cvs.openbsd.org 2008/06/10 08:17:40 + [sshd.8 sshd.c] + - update usage() + - fix SYNOPSIS, and sort options + - some minor additional fixes + - dtucker@cvs.openbsd.org 2008/06/09 18:06:32 + [regress/test-exec.sh] + Don't generate putty keys if we're not going to use them. ok djm + - dtucker@cvs.openbsd.org 2008/06/10 05:23:32 + [regress/addrmatch.sh regress/Makefile] + Regress test for Match CIDR rules. ok djm@ + - dtucker@cvs.openbsd.org 2008/06/10 15:21:41 + [test-exec.sh] + Use a more portable construct for checking if we're running a putty test + - dtucker@cvs.openbsd.org 2008/06/10 15:28:49 + [test-exec.sh] + Add quotes + - dtucker@cvs.openbsd.org 2008/06/10 18:21:24 + [ssh_config.5] + clarify that Host patterns are space-separated. ok deraadt + - djm@cvs.openbsd.org 2008/06/10 22:15:23 + [PROTOCOL ssh.c serverloop.c] + Add a no-more-sessions@openssh.com global request extension that the + client sends when it knows that it will never request another session + (i.e. when session multiplexing is disabled). This allows a server to + disallow further session requests and terminate the session. + Why would a non-multiplexing client ever issue additional session + requests? It could have been attacked with something like SSH'jack: + http://www.storm.net.nz/projects/7 + feedback & ok markus + - djm@cvs.openbsd.org 2008/06/10 23:06:19 + [auth-options.c match.c servconf.c addrmatch.c sshd.8] + support CIDR address matching in .ssh/authorized_keys from="..." stanzas + ok and extensive testing dtucker@ + - dtucker@cvs.openbsd.org 2008/06/10 23:21:34 + [bufaux.c] + Use '\0' for a nul byte rather than unadorned 0. ok djm@ + - dtucker@cvs.openbsd.org 2008/06/10 23:13:43 + [Makefile regress/key-options.sh] + Add regress test for key options. ok djm@ + - (dtucker) [openbsd-compat/fake-rfc2553.h] Add sin6_scope_id to sockaddr_in6 + since the new CIDR code in addmatch.c references it. + - (dtucker) [Makefile.in configure.ac regress/addrmatch.sh] Skip IPv6 + specific tests on platforms that don't do IPv6. + - (dtucker) [Makefile.in] Define TEST_SSH_IPV6 in make's arguments as well + as environment. + - (dtucker) [Makefile.in] Move addrmatch.o to libssh.a where it's needed now. + +20080609 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2008/06/08 17:04:41 + [sftp-server.c] + Add case for ENOSYS in errno_to_portable; ok deraadt + - dtucker@cvs.openbsd.org 2008/06/08 20:15:29 + [sftp.c sftp-client.c sftp-client.h] + Have the sftp client store the statvfs replies in wire format, + which prevents problems when the server's native sizes exceed the + client's. + Also extends the sizes of the remaining 32bit wire format to 64bit, + they're specified as unsigned long in the standard. + - dtucker@cvs.openbsd.org 2008/06/09 13:02:39 + [sftp-server.c] + Extend 32bit -> 64bit values for statvfs extension missed in previous + commit. + - dtucker@cvs.openbsd.org 2008/06/09 13:38:46 + [PROTOCOL] + Use a $OpenBSD tag so our scripts will sync changes. + +20080608 + - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c + openbsd-compat/Makefile.in openbsd-compat/openbsd-compat.h + openbsd-compat/bsd-statvfs.{c,h}] Add a null implementation of statvfs and + fstatvfs and remove #defines around statvfs code. ok djm@ + - (dtucker) [configure.ac defines.h sftp-client.c M sftp-server.c] Add a + macro to convert fsid to unsigned long for platforms where fsid is a + 2-member array. + +20080607 + - (dtucker) [mux.c] Include paths.h inside ifdef HAVE_PATHS_H. + - (dtucker) [configure.ac defines.h sftp-client.c sftp-server.c sftp.c] + Do not enable statvfs extensions on platforms that do not have statvfs. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/05/19 06:14:02 + [packet.c] unbreak protocol keepalive timeouts bz#1465; ok dtucker@ + - djm@cvs.openbsd.org 2008/05/19 15:45:07 + [sshtty.c ttymodes.c sshpty.h] + Fix sending tty modes when stdin is not a tty (bz#1199). Previously + we would send the modes corresponding to a zeroed struct termios, + whereas we should have been sending an empty list of modes. + Based on patch from daniel.ritz AT alcatel.ch; ok dtucker@ markus@ + - djm@cvs.openbsd.org 2008/05/19 15:46:31 + [ssh-keygen.c] + support -l (print fingerprint) in combination with -F (find host) to + search for a host in ~/.ssh/known_hosts and display its fingerprint; + ok markus@ + - djm@cvs.openbsd.org 2008/05/19 20:53:52 + [clientloop.c] + unbreak tree by committing this bit that I missed from: + Fix sending tty modes when stdin is not a tty (bz#1199). Previously + we would send the modes corresponding to a zeroed struct termios, + whereas we should have been sending an empty list of modes. + Based on patch from daniel.ritz AT alcatel.ch; ok dtucker@ markus@ + +20080604 + - (djm) [openbsd-compat/bsd-arc4random.c] Fix math bug that caused bias + in arc4random_uniform with upper_bound in (2^30,2*31). Note that + OpenSSH did not make requests with upper bounds in this range. + +20080519 + - (djm) [configure.ac mux.c sftp.c openbsd-compat/Makefile.in] + [openbsd-compat/fmt_scaled.c openbsd-compat/openbsd-compat.h] + Fix compilation on Linux, including pulling in fmt_scaled(3) + implementation from OpenBSD's libutil. + +20080518 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/04/04 05:14:38 + [sshd_config.5] + ChrootDirectory is supported in Match blocks (in fact, it is most useful + there). Spotted by Minstrel AT minstrel.org.uk + - djm@cvs.openbsd.org 2008/04/04 06:44:26 + [sshd_config.5] + oops, some unrelated stuff crept into that commit - backout. + spotted by jmc@ + - djm@cvs.openbsd.org 2008/04/05 02:46:02 + [sshd_config.5] + HostbasedAuthentication is supported under Match too + - (djm) [openbsd-compat/bsd-arc4random.c openbsd-compat/openbsd-compat.c] + [configure.ac] Implement arc4random_buf(), import implementation of + arc4random_uniform() from OpenBSD + - (djm) [openbsd-compat/bsd-arc4random.c] Warning fixes + - (djm) [openbsd-compat/port-tun.c] needs sys/queue.h + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/04/13 00:22:17 + [dh.c sshd.c] + Use arc4random_buf() when requesting more than a single word of output + Use arc4random_uniform() when the desired random number upper bound + is not a power of two + ok deraadt@ millert@ + - djm@cvs.openbsd.org 2008/04/18 12:32:11 + [sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c sftp.h] + introduce sftp extension methods statvfs@openssh.com and + fstatvfs@openssh.com that implement statvfs(2)-like operations, + based on a patch from miklos AT szeredi.hu (bz#1399) + also add a "df" command to the sftp client that uses the + statvfs@openssh.com to produce a df(1)-like display of filesystem + space and inode utilisation + ok markus@ + - jmc@cvs.openbsd.org 2008/04/18 17:15:47 + [sftp.1] + macro fixage; + - djm@cvs.openbsd.org 2008/04/18 22:01:33 + [session.c] + remove unneccessary parentheses + - otto@cvs.openbsd.org 2008/04/29 11:20:31 + [monitor_mm.h] + garbage collect two unused fields in struct mm_master; ok markus@ + - djm@cvs.openbsd.org 2008/04/30 10:14:03 + [ssh-keyscan.1 ssh-keyscan.c] + default to rsa (protocol 2) keys, instead of rsa1 keys; spotted by + larsnooden AT openoffice.org + - pyr@cvs.openbsd.org 2008/05/07 05:49:37 + [servconf.c servconf.h session.c sshd_config.5] + Enable the AllowAgentForwarding option in sshd_config (global and match + context), to specify if agents should be permitted on the server. + As the man page states: + ``Note that disabling Agent forwarding does not improve security + unless users are also denied shell access, as they can always install + their own forwarders.'' + ok djm@, ok and a mild frown markus@ + - pyr@cvs.openbsd.org 2008/05/07 06:43:35 + [sshd_config] + push the sshd_config bits in, spotted by ajacoutot@ + - jmc@cvs.openbsd.org 2008/05/07 08:00:14 + [sshd_config.5] + sort; + - markus@cvs.openbsd.org 2008/05/08 06:59:01 + [bufaux.c buffer.h channels.c packet.c packet.h] + avoid extra malloc/copy/free when receiving data over the net; + ~10% speedup for localhost-scp; ok djm@ + - djm@cvs.openbsd.org 2008/05/08 12:02:23 + [auth-options.c auth1.c channels.c channels.h clientloop.c gss-serv.c] + [monitor.c monitor_wrap.c nchan.c servconf.c serverloop.c session.c] + [ssh.c sshd.c] + Implement a channel success/failure status confirmation callback + mechanism. Each channel maintains a queue of callbacks, which will + be drained in order (RFC4253 guarantees confirm messages are not + reordered within an channel). + Also includes a abandonment callback to clean up if a channel is + closed without sending confirmation messages. This probably + shouldn't happen in compliant implementations, but it could be + abused to leak memory. + ok markus@ (as part of a larger diff) + - djm@cvs.openbsd.org 2008/05/08 12:21:16 + [monitor.c monitor_wrap.c session.h servconf.c servconf.h session.c] + [sshd_config sshd_config.5] + Make the maximum number of sessions run-time controllable via + a sshd_config MaxSessions knob. This is useful for disabling + login/shell/subsystem access while leaving port-forwarding working + (MaxSessions 0), disabling connection multiplexing (MaxSessions 1) or + simply increasing the number of allows multiplexed sessions. + Because some bozos are sure to configure MaxSessions in excess of the + number of available file descriptors in sshd (which, at peak, might be + as many as 9*MaxSessions), audit sshd to ensure that it doesn't leak fds + on error paths, and make it fail gracefully on out-of-fd conditions - + sending channel errors instead of than exiting with fatal(). + bz#1090; MaxSessions config bits and manpage from junyer AT gmail.com + ok markus@ + - djm@cvs.openbsd.org 2008/05/08 13:06:11 + [clientloop.c clientloop.h ssh.c] + Use new channel status confirmation callback system to properly deal + with "important" channel requests that fail, in particular command exec, + shell and subsystem requests. Previously we would optimistically assume + that the requests would always succeed, which could cause hangs if they + did not (e.g. when the server runs out of fds) or were unimplemented by + the server (bz #1384) + Also, properly report failing multiplex channel requests via the mux + client stderr (subject to LogLevel in the mux master) - better than + silently failing. + most bits ok markus@ (as part of a larger diff) + - djm@cvs.openbsd.org 2008/05/09 04:55:56 + [channels.c channels.h clientloop.c serverloop.c] + Try additional addresses when connecting to a port forward destination + whose DNS name resolves to more than one address. The previous behaviour + was to try the first address and give up. + Reported by stig AT venaas.com in bz#343 + great feedback and ok markus@ + - djm@cvs.openbsd.org 2008/05/09 14:18:44 + [clientloop.c clientloop.h ssh.c mux.c] + tidy up session multiplexing code, moving it into its own file and + making the function names more consistent - making ssh.c and + clientloop.c a fair bit more readable. + ok markus@ + - djm@cvs.openbsd.org 2008/05/09 14:26:08 + [ssh.c] + dingo stole my diff hunk + - markus@cvs.openbsd.org 2008/05/09 16:16:06 + [session.c] + re-add the USE_PIPES code and enable it. + without pipes shutdown-read from the sshd does not trigger + a SIGPIPE when the forked program does a write. + ok djm@ + (Id sync only, USE_PIPES never left portable OpenSSH) + - markus@cvs.openbsd.org 2008/05/09 16:17:51 + [channels.c] + error-fd race: don't enable the error fd in the select bitmask + for channels with both in- and output closed, since the channel + will go away before we call select(); + report, lots of debugging help and ok djm@ + - markus@cvs.openbsd.org 2008/05/09 16:21:13 + [channels.h clientloop.c nchan.c serverloop.c] + unbreak + ssh -2 localhost od /bin/ls | true + ignoring SIGPIPE by adding a new channel message (EOW) that signals + the peer that we're not interested in any data it might send. + fixes bz #85; discussion, debugging and ok djm@ + - pvalchev@cvs.openbsd.org 2008/05/12 20:52:20 + [umac.c] + Ensure nh_result lies on a 64-bit boundary (fixes warnings observed + on Itanium on Linux); from Dale Talcott (bug #1462); ok djm@ + - djm@cvs.openbsd.org 2008/05/15 23:52:24 + [nchan2.ms] + document eow message in ssh protocol 2 channel state machine; + feedback and ok markus@ + - djm@cvs.openbsd.org 2008/05/18 21:29:05 + [sftp-server.c] + comment extension announcement + - djm@cvs.openbsd.org 2008/05/16 08:30:42 + [PROTOCOL] + document our protocol extensions and deviations; ok markus@ + - djm@cvs.openbsd.org 2008/05/17 01:31:56 + [PROTOCOL] + grammar and correctness fixes from stevesk@ + +20080403 + - (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile- + time warnings on LynxOS. Patch from ops AT iki.fi + - (djm) Force string arguments to replacement setproctitle() though + strnvis first. Ok dtucker@ + +20080403 + - (djm) OpenBSD CVS sync: + - markus@cvs.openbsd.org 2008/04/02 15:36:51 + [channels.c] + avoid possible hijacking of x11-forwarded connections (back out 1.183) + CVE-2008-1483; ok djm@ + - jmc@cvs.openbsd.org 2008/03/27 22:37:57 + [sshd.8] + remove trailing whitespace; + - djm@cvs.openbsd.org 2008/04/03 09:50:14 + [version.h] + openssh-5.0 + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank version numbers in RPM spec files + - (djm) [README] Update link to release notes + - (djm) Release 5.0p1 + +20080315 + - (djm) [regress/test-exec.sh] Quote putty-related variables in case they are + empty; report and patch from Peter Stuge + - (djm) [regress/test-exec.sh] Silence noise from detection of putty + commands; report from Peter Stuge + - (djm) [session.c] Relocate incorrectly-placed closefrom() that was causing + crashes when used with ChrootDirectory + + +20080327 + - (dtucker) Cache selinux status earlier so we know if it's enabled after a + chroot. Allows ChrootDirectory to work with selinux support compiled in + but not enabled. Using it with selinux enabled will require some selinux + support inside the chroot. "looks sane" djm@ + - (djm) Fix RCS ident in sftp-server-main.c + - (djm) OpenBSD CVS sync: + - jmc@cvs.openbsd.org 2008/02/11 07:58:28 + [ssh.1 sshd.8 sshd_config.5] + bump Mdocdate for pages committed in "febuary", necessary because + of a typo in rcs.c; + - deraadt@cvs.openbsd.org 2008/03/13 01:49:53 + [monitor_fdpass.c] + Correct CMSG_SPACE and CMSG_LEN usage everywhere in the tree. Due to + an extensive discussion with otto, kettenis, millert, and hshoexer + - deraadt@cvs.openbsd.org 2008/03/15 16:19:02 + [monitor_fdpass.c] + Repair the simple cases for msg_controllen where it should just be + CMSG_SIZE(sizeof(int)), not sizeof(buffer) which may be larger because + of alignment; ok kettenis hshoexer + - djm@cvs.openbsd.org 2008/03/23 12:54:01 + [sftp-client.c] + prefer POSIX-style file renaming over filexfer rename behaviour if the + server supports the posix-rename@openssh.com extension. + Note that the old (filexfer) behaviour would refuse to clobber an + existing file. Users who depended on this should adjust their sftp(1) + usage. + ok deraadt@ markus@ + - deraadt@cvs.openbsd.org 2008/03/24 16:11:07 + [monitor_fdpass.c] + msg_controllen has to be CMSG_SPACE so that the kernel can account for + each cmsg_len (ie. msg_controllen = sum of CMSG_ALIGN(cmsg_len). This + works now that kernel fd passing has been fixed to accept a bit of + sloppiness because of this ABI repair. + lots of discussion with kettenis + - djm@cvs.openbsd.org 2008/03/25 11:58:02 + [session.c sshd_config.5] + ignore ~/.ssh/rc if a sshd_config ForceCommand is specified; + from dtucker@ ok deraadt@ djm@ + - djm@cvs.openbsd.org 2008/03/25 23:01:41 + [session.c] + last patch had backwards test; spotted by termim AT gmail.com + - djm@cvs.openbsd.org 2008/03/26 21:28:14 + [auth-options.c auth-options.h session.c sshd.8] + add no-user-rc authorized_keys option to disable execution of ~/.ssh/rc + - djm@cvs.openbsd.org 2008/03/27 00:16:49 + [version.h] + openssh-4.9 + - djm@cvs.openbsd.org 2008/03/24 21:46:54 + [regress/sftp-badcmds.sh] + disable no-replace rename test now that we prefer a POSIX rename; spotted + by dkrause@ + - (djm) [configure.ac] fix alignment of --without-stackprotect description + - (djm) [configure.ac] --with-selinux too + - (djm) [regress/Makefile] cleanup PuTTY interop test droppings + - (djm) [README] Update link to release notes + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank version numbers in RPM spec files + - (djm) Release 4.9p1 + +20080315 + - (djm) [regress/test-exec.sh] Quote putty-related variables in case they are + empty; report and patch from Peter Stuge + - (djm) [regress/test-exec.sh] Silence noise from detection of putty + commands; report from Peter Stuge + - (djm) [session.c] Relocate incorrectly-placed closefrom() that was causing + crashes when used with ChrootDirectory + +20080314 + - (tim) [regress/sftp-cmds.sh] s/cd/lcd/ in lls test. Reported by + vinschen at redhat.com. Add () to put echo commands in subshell for lls test + I mistakenly left out of last commit. + - (tim) [regress/localcommand.sh] Shell portability fix. Reported by imorgan at + nas.nasa.gov + +20080313 + - (djm) [Makefile.in regress/Makefile] Fix interop-tests target (note to + self: make changes to Makefile.in next time, not the generated Makefile). + - (djm) [Makefile.in regress/test-exec.sh] Find installed plink(1) and + puttygen(1) by $PATH + - (tim) [scp.c] Use poll.h if available, fall back to sys/poll.h if not. Patch + by vinschen at redhat.com. + - (tim) [regress/sftp-cmds.sh regress/ssh2putty.sh] Shell portability fixes + from vinschen at redhat.com and imorgan at nas.nasa.gov + +20080312 + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2007/10/29 06:57:13 + [regress/Makefile regress/localcommand.sh] + Add simple regress test for LocalCommand; ok djm@ + - jmc@cvs.openbsd.org 2007/11/25 15:35:09 + [regress/agent-getpeereid.sh regress/agent.sh] + more existant -> existent, from Martynas Venckus; + pfctl changes: ok henning + ssh changes: ok deraadt + - djm@cvs.openbsd.org 2007/12/12 05:04:03 + [regress/sftp-cmds.sh] + unbreak lls command and add a regress test that would have caught the + breakage; spotted by mouring@ + NB. sftp code change already committed. + - djm@cvs.openbsd.org 2007/12/21 04:13:53 + [regress/Makefile regress/test-exec.sh regress/putty-ciphers.sh] + [regress/putty-kex.sh regress/putty-transfer.sh regress/ssh2putty.sh] + basic (crypto, kex and transfer) interop regression tests against putty + To run these, install putty and run "make interop-tests" from the build + directory - the tests aren't run by default yet. + +20080311 + - (dtucker) [auth-pam.c monitor.c session.c sshd.c] Bug #926: Move + pam_open_session and pam_close_session into the privsep monitor, which + will ensure that pam_session_close is called as root. Patch from Tomas + Mraz. + +20080309 + - (dtucker) [configure.ac] It turns out gcc's -fstack-protector-all doesn't + always work for all platforms and versions, so test what we can and + add a configure flag to turn it of if needed. ok djm@ + - (dtucker) [openbsd-compat/port-aix.{c,h}] Remove AIX specific initgroups + implementation. It's not needed to fix bug #1081 and breaks the build + on some AIX configurations. + - (dtucker) [openbsd-compat/regress/strtonumtest.c] Bug #1347: Use platform's + equivalent of LLONG_MAX for the compat regression tests, which makes them + run on AIX and HP-UX. Patch from David Leonard. + - (dtucker) [configure.ac] Run stack-protector tests with -Werror to catch + platforms where gcc understands the option but it's not supported (and + thus generates a warning). + +20080307 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2008/02/11 07:58:28 + [ssh.1 sshd.8 sshd_config.5] + bump Mdocdate for pages committed in "febuary", necessary because + of a typo in rcs.c; + - djm@cvs.openbsd.org 2008/02/13 22:38:17 + [servconf.h session.c sshd.c] + rekey arc4random and OpenSSL RNG in postauth child + closefrom fds > 2 before shell/command execution + ok markus@ + - mbalmer@cvs.openbsd.org 2008/02/14 13:10:31 + [sshd.c] + When started in configuration test mode (-t) do not check that sshd is + being started with an absolute path. + ok djm + - markus@cvs.openbsd.org 2008/02/20 15:25:26 + [session.c] + correct boolean encoding for coredump; der Mouse via dugsong + - djm@cvs.openbsd.org 2008/02/22 05:58:56 + [session.c] + closefrom() call was too early, delay it until just before we execute + the user's rc files (if any). + - dtucker@cvs.openbsd.org 2008/02/22 20:44:02 + [clientloop.c packet.c packet.h serverloop.c] + Allow all SSH2 packet types, including UNIMPLEMENTED to reset the + keepalive timer (bz #1307). ok markus@ + - djm@cvs.openbsd.org 2008/02/27 20:21:15 + [sftp-server.c] + add an extension method "posix-rename@openssh.com" to perform POSIX atomic + rename() operations. based on patch from miklos AT szeredi.hu in bz#1400; + ok dtucker@ markus@ + - deraadt@cvs.openbsd.org 2008/03/02 18:19:35 + [monitor_fdpass.c] + use a union to ensure alignment of the cmsg (pay attention: various other + parts of the tree need this treatment too); ok djm + - deraadt@cvs.openbsd.org 2008/03/04 21:15:42 + [version.h] + crank version; from djm + - (tim) [regress/sftp-glob.sh] Shell portability fix. + +20080302 + - (dtucker) [configure.ac] FreeBSD's glob() doesn't behave the way we expect + either, so use our own. + +20080229 + - (dtucker) [openbsd-compat/bsd-poll.c] We don't check for select(2) in + configure (and there's not much point, as openssh won't work without it) + so HAVE_SELECT is not defined and the poll(2) compat code doesn't get + built in. Remove HAVE_SELECT so we can build on platforms without poll. + - (dtucker) [scp.c] Include sys/poll.h inside HAVE_SYS_POLL_H. + - (djm) [contrib/gnome-ssh-askpass2.h] Keep askpass windown on top. From + Debian patch via bernd AT openbsd.org + +20080228 + - (dtucker) [configure.ac] Add -fstack-protector to LDFLAGS too, fixes + linking problems on AIX with gcc 4.1.x. + - (dtucker) [includes.h ssh-add.c ssh-agent.c ssh-keygen.c ssh.c sshd.c + openbsd-compat/openssl-compat.{c,h}] Bug #1437 Move the OpenSSL compat + header to after OpenSSL headers, since some versions of OpenSSL have + SSLeay_add_all_algorithms as a macro already. + - (dtucker) [key.c defines.h openbsd-compat/openssl-compat.h] Move old OpenSSL + compat glue into openssl-compat.h. + - (dtucker) [configure.ac openbsd-compat/port-aix.{c,h}] Bug #1081: Implement + getgrouplist via getgrset on AIX, rather than iterating over getgrent. + This allows, eg, Match and AllowGroups directives to work with NIS and + LDAP groups. + - (dtucker) [sshd.c] Bug #1042: make log messages for tcpwrappers use the + same SyslogFacility as the rest of sshd. Patch from William Knox, + ok djm@. + +20080225 + - (dtucker) [openbsd-compat/fake-rfc2553.h] rename ssh_gai_strerror hack + since it now conflicts with the helper function in misc.c. From + vinschen AT redhat.com. + - (dtucker) [configure.ac audit-bsm.c] Bug #1420: Add a local implementation + of aug_get_machine for systems that don't have their own (eg OS X, FreeBSD). + Help and testing from csjp at FreeBSD org, vgiffin at apple com. ok djm@ + - (dtucker) [includes.h openbsd-compat/openssl-compat.c] Bug #1437: reshuffle + headers so ./configure --with-ssl-engine actually works. Patch from + Ian Lister. + +20080224 + - (tim) [contrib/cygwin/ssh-host-config] + Grammar changes on SYSCONFDIR LOCALSTATEDIR messages. + Check more thoroughly that it's possible to create the /var/empty directory. + Patch by vinschen AT redhat.com + +20080210 + - OpenBSD CVS Sync + - chl@cvs.openbsd.org 2008/01/11 07:22:28 + [sftp-client.c sftp-client.h] + disable unused functions + initially from tobias@, but disabled them by placing them in + "#ifdef notyet" which was asked by djm@ + ok djm@ tobias@ + - djm@cvs.openbsd.org 2008/01/19 19:13:28 + [ssh.1] + satisfy the pedants: -q does not suppress all diagnostic messages (e.g. + some commandline parsing warnings go unconditionally to stdout). + - djm@cvs.openbsd.org 2008/01/19 20:48:53 + [clientloop.c] + fd leak on session multiplexing error path. Report and patch from + gregory_shively AT fanniemae.com + - djm@cvs.openbsd.org 2008/01/19 20:51:26 + [ssh.c] + ignore SIGPIPE in multiplex client mode - we can receive this if the + server runs out of fds on us midway. Report and patch from + gregory_shively AT fanniemae.com + - djm@cvs.openbsd.org 2008/01/19 22:04:57 + [sftp-client.c] + fix remote handle leak in do_download() local file open error path; + report and fix from sworley AT chkno.net + - djm@cvs.openbsd.org 2008/01/19 22:22:58 + [ssh-keygen.c] + when hashing individual hosts (ssh-keygen -Hf hostname), make sure we + hash just the specified hostname and not the entire hostspec from the + keyfile. It may be of the form "hostname,ipaddr", which would lead to + a hash that never matches. report and fix from jp AT devnull.cz + - djm@cvs.openbsd.org 2008/01/19 22:37:19 + [ssh-keygen.c] + unbreak line numbering (broken in revision 1.164), fix error message + - djm@cvs.openbsd.org 2008/01/19 23:02:40 + [channels.c] + When we added support for specified bind addresses for port forwards, we + added a quirk SSH_OLD_FORWARD_ADDR. There is a bug in our handling of + this for -L port forwards that causes the client to listen on both v4 + and v6 addresses when connected to a server with this quirk, despite + having set 0.0.0.0 as a bind_address. + report and patch from Jan.Pechanec AT Sun.COM; ok dtucker@ + - djm@cvs.openbsd.org 2008/01/19 23:09:49 + [readconf.c readconf.h sshconnect2.c] + promote rekeylimit to a int64 so it can hold the maximum useful limit + of 2^32; report and patch from Jan.Pechanec AT Sun.COM, ok dtucker@ + - djm@cvs.openbsd.org 2008/01/20 00:38:30 + [sftp.c] + When uploading, correctly handle the case of an unquoted filename with + glob metacharacters that match a file exactly but not as a glob, e.g. a + file called "[abcd]". report and test cases from duncan2nd AT gmx.de + - djm@cvs.openbsd.org 2008/01/21 17:24:30 + [sftp-server.c] + Remove the fixed 100 handle limit in sftp-server and allocate as many + as we have available file descriptors. Patch from miklos AT szeredi.hu; + ok dtucker@ markus@ + - djm@cvs.openbsd.org 2008/01/21 19:20:17 + [sftp-client.c] + when a remote write error occurs during an upload, ensure that ACKs for + all issued requests are properly drained. patch from t8m AT centrum.cz + - dtucker@cvs.openbsd.org 2008/01/23 01:56:54 + [clientloop.c packet.c serverloop.c] + Revert the change for bz #1307 as it causes connection aborts if an IGNORE + packet arrives while we're waiting in packet_read_expect (and possibly + elsewhere). + - jmc@cvs.openbsd.org 2008/01/31 20:06:50 + [scp.1] + explain how to handle local file names containing colons; + requested by Tamas TEVESZ + ok dtucker + - markus@cvs.openbsd.org 2008/02/04 21:53:00 + [session.c sftp-server.c sftp.h] + link sftp-server into sshd; feedback and ok djm@ + - mcbride@cvs.openbsd.org 2008/02/09 12:15:43 + [ssh.1 sshd.8] + Document the correct permissions for the ~/.ssh/ directory. + ok jmc + - djm@cvs.openbsd.org 2008/02/10 09:55:37 + [sshd_config.5] + mantion that "internal-sftp" is useful with ForceCommand too + - djm@cvs.openbsd.org 2008/02/10 10:54:29 + [servconf.c session.c] + delay ~ expansion for ChrootDirectory so it expands to the logged-in user's + home, rather than the user who starts sshd (probably root) + +20080119 + - (djm) Silence noice from expr in ssh-copy-id; patch from + mikel AT mikelward.com + - (djm) Only listen for IPv6 connections on AF_INET6 sockets; patch from + tsr2600 AT gmail.com + +20080102 + - (dtucker) [configure.ac] Fix message for -fstack-protector-all test. + +20080101 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2007/12/31 10:41:31 + [readconf.c servconf.c] + Prevent strict-aliasing warnings on newer gcc versions. bz #1355, patch + from Dmitry V. Levin, ok djm@ + - dtucker@cvs.openbsd.org 2007/12/31 15:27:04 + [sshd.c] + When in inetd mode, have sshd generate a Protocol 1 ephemeral server + key only for connections where the client chooses Protocol 1 as opposed + to when it's enabled in the server's config. Speeds up Protocol 2 + connections to inetd-mode servers that also allow Protocol 1. bz #440, + based on a patch from bruno at wolff.to, ok markus@ + - dtucker@cvs.openbsd.org 2008/01/01 08:47:04 + [misc.c] + spaces -> tabs from my previous commit + - dtucker@cvs.openbsd.org 2008/01/01 09:06:39 + [scp.c] + If scp -p encounters a pre-epoch timestamp, use the epoch which is + as close as we can get given that it's used unsigned. Add a little + debugging while there. bz #828, ok djm@ + - dtucker@cvs.openbsd.org 2008/01/01 09:27:33 + [sshd_config.5 servconf.c] + Allow PermitRootLogin in a Match block. Allows for, eg, permitting root + only from the local network. ok markus@, man page bit ok jmc@ + - dtucker@cvs.openbsd.org 2008/01/01 08:51:20 + [moduli] + Updated moduli file; ok djm@ + +20071231 + - (dtucker) [configure.ac openbsd-compat/glob.{c,h}] Bug #1407: force use of + builtin glob implementation on Mac OS X. Based on a patch from + vgiffin at apple. + +20071229 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2007/12/12 05:04:03 + [sftp.c] + unbreak lls command and add a regress test that would have caught the + breakage; spotted by mouring@ + - dtucker@cvs.openbsd.org 2007/12/27 14:22:08 + [servconf.c canohost.c misc.c channels.c sshconnect.c misc.h ssh-keyscan.c + sshd.c] + Add a small helper function to consistently handle the EAI_SYSTEM error + code of getaddrinfo. Prompted by vgiffin at apple com via bz #1417. + ok markus@ stevesk@ + - dtucker@cvs.openbsd.org 2007/12/28 15:32:24 + [clientloop.c serverloop.c packet.c] + Make SSH2_MSG_UNIMPLEMENTED and SSH2_MSG_IGNORE messages reset the + ServerAlive and ClientAlive timers. Prevents dropping a connection + when these are enabled but the peer does not support our keepalives. + bz #1307, ok djm@. + - dtucker@cvs.openbsd.org 2007/12/28 22:34:47 + [clientloop.c] + Use the correct packet maximum sizes for remote port and agent forwarding. + Prevents the server from killing the connection if too much data is queued + and an excessively large packet gets sent. bz #1360, ok djm@. + +20071202 + - (dtucker) [configure.ac] Enable -fstack-protector-all on systems where + gcc supports it. ok djm@ + - (dtucker) [scp.c] Update $OpenBSD tag missing from rev 1.175 and remove + leftover debug code. + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2007/10/29 00:52:45 + [auth2-gss.c] + Allow build without -DGSSAPI; ok deraadt@ + (Id sync only, Portable already has the ifdefs) + - dtucker@cvs.openbsd.org 2007/10/29 01:55:04 + [ssh.c] + Plug tiny mem leaks in ControlPath and ProxyCommand option processing; + ok djm@ + - dtucker@cvs.openbsd.org 2007/10/29 04:08:08 + [monitor_wrap.c monitor.c] + Send config block back to slave for invalid users too so options + set by a Match block (eg Banner) behave the same for non-existent + users. Found by and ok djm@ + - dtucker@cvs.openbsd.org 2007/10/29 06:51:59 + [ssh_config.5] + ProxyCommand and LocalCommand use the user's shell, not /bin/sh; ok djm@ + - dtucker@cvs.openbsd.org 2007/10/29 06:54:50 + [ssh.c] + Make LocalCommand work for Protocol 1 too; ok djm@ + - jmc@cvs.openbsd.org 2007/10/29 07:48:19 + [ssh_config.5] + clean up after previous macro removal; + - djm@cvs.openbsd.org 2007/11/03 00:36:14 + [clientloop.c] + fix memory leak in process_cmdline(), patch from Jan.Pechanec AT Sun.COM; + ok dtucker@ + - deraadt@cvs.openbsd.org 2007/11/03 01:24:06 + [ssh.c] + bz #1377: getpwuid results were being clobbered by another getpw* call + inside tilde_expand_filename(); save the data we need carefully + ok djm + - dtucker@cvs.openbsd.org 2007/11/03 02:00:32 + [ssh.c] + Use xstrdup/xfree when saving pwname and pwdir; ok deraadt@ + - deraadt@cvs.openbsd.org 2007/11/03 02:03:49 + [ssh.c] + avoid errno trashing in signal handler; ok dtucker + +20071030 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2007/10/29 23:49:41 + [openbsd-compat/sys-tree.h] + remove extra backslash at the end of RB_PROTOTYPE, report from + Jan.Pechanec AT Sun.COM; ok deraadt@ + +20071026 + - (djm) OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2007/09/11 23:49:09 + [sshpty.c] + remove #if defined block not needed; ok markus@ dtucker@ + (NB. RCD ID sync only for portable) + - djm@cvs.openbsd.org 2007/09/21 03:05:23 + [ssh_config.5] + document KbdInteractiveAuthentication in ssh_config.5; + patch from dkg AT fifthhorseman.net + - djm@cvs.openbsd.org 2007/09/21 08:15:29 + [auth-bsdauth.c auth-passwd.c auth.c auth.h auth1.c auth2-chall.c] + [monitor.c monitor_wrap.c] + unifdef -DBSD_AUTH + unifdef -USKEY + These options have been in use for some years; + ok markus@ "no objection" millert@ + (NB. RCD ID sync only for portable) + - canacar@cvs.openbsd.org 2007/09/25 23:48:57 + [ssh-agent.c] + When adding a key that already exists, update the properties + (time, confirm, comment) instead of discarding them. ok djm@ markus@ + - ray@cvs.openbsd.org 2007/09/27 00:15:57 + [dh.c] + Don't return -1 on error in dh_pub_is_valid(), since it evaluates + to true. + Also fix a typo. + Initial diff from Matthew Dempsky, input from djm. + OK djm, markus. + - dtucker@cvs.openbsd.org 2007/09/29 00:25:51 + [auth2.c] + Remove unused prototype. ok djm@ + - chl@cvs.openbsd.org 2007/10/02 17:49:58 + [ssh-keygen.c] + handles zero-sized strings that fgets can return + properly removes trailing newline + removes an unused variable + correctly counts line number + "looks ok" ray@ markus@ + - markus@cvs.openbsd.org 2007/10/22 19:10:24 + [readconf.c] + make sure that both the local and remote port are correct when + parsing -L; Jan Pechanec (bz #1378) + - djm@cvs.openbsd.org 2007/10/24 03:30:02 + [sftp.c] + rework argument splitting and parsing to cope correctly with common + shell escapes and make handling of escaped characters consistent + with sh(1) and between sftp commands (especially between ones that + glob their arguments and ones that don't). + parse command flags using getopt(3) rather than hand-rolled parsers. + ok dtucker@ + - djm@cvs.openbsd.org 2007/10/24 03:44:02 + [scp.c] + factor out network read/write into an atomicio()-like function, and + use it to handle short reads, apply bandwidth limits and update + counters. make network IO non-blocking, so a small trickle of + reads/writes has a chance of updating the progress meter; bz #799 + ok dtucker@ + - djm@cvs.openbsd.org 2006/08/29 09:44:00 + [regress/sftp-cmds.sh] + clean up our mess + - markus@cvs.openbsd.org 2006/11/06 09:27:43 + [regress/cfgmatch.sh] + fix quoting for non-(c)sh login shells. + - dtucker@cvs.openbsd.org 2006/12/13 08:36:36 + [regress/cfgmatch.sh] + Additional test for multiple PermitOpen entries. ok djm@ + - pvalchev@cvs.openbsd.org 2007/06/07 19:41:46 + [regress/cipher-speed.sh regress/try-ciphers.sh] + test umac-64@openssh.com + ok djm@ + - djm@cvs.openbsd.org 2007/10/24 03:32:35 + [regress/sftp-cmds.sh regress/sftp-glob.sh regress/test-exec.sh] + comprehensive tests for sftp escaping its interaction with globbing; + ok dtucker@ + - djm@cvs.openbsd.org 2007/10/26 05:30:01 + [regress/sftp-glob.sh regress/test-exec.sh] + remove "echo -E" crap that I added in last commit and use printf(1) for + cases where we strictly require echo not to reprocess escape characters. + - deraadt@cvs.openbsd.org 2005/11/28 17:50:12 + [openbsd-compat/glob.c] + unused arg in internal static API + - jakob@cvs.openbsd.org 2007/10/11 18:36:41 + [openbsd-compat/getrrsetbyname.c openbsd-compat/getrrsetbyname.h] + use RRSIG instead of SIG for DNSSEC. ok djm@ + - otto@cvs.openbsd.org 2006/10/21 09:55:03 + [openbsd-compat/base64.c] + remove calls to abort(3) that can't happen anyway; from + <bret dot lambert at gmail.com>; ok millert@ deraadt@ + - frantzen@cvs.openbsd.org 2004/04/24 18:11:46 + [openbsd-compat/sys-tree.h] + sync to Niels Provos' version. avoid unused variable warning in + RB_NEXT() + - tdeval@cvs.openbsd.org 2004/11/24 18:10:42 + [openbsd-compat/sys-tree.h] + typo + - grange@cvs.openbsd.org 2004/05/04 16:59:32 + [openbsd-compat/sys-queue.h] + Remove useless ``elm'' argument from the SIMPLEQ_REMOVE_HEAD macro. + This matches our SLIST behaviour and NetBSD's SIMPLEQ as well. + ok millert krw deraadt + - deraadt@cvs.openbsd.org 2005/02/25 13:29:30 + [openbsd-compat/sys-queue.h] + minor white spacing + - otto@cvs.openbsd.org 2005/10/17 20:19:42 + [openbsd-compat/sys-queue.h] + Performing certain operations on queue.h data structurs produced + funny results. An example is calling LIST_REMOVE on the same + element twice. This will not fail, but result in a data structure + referencing who knows what. Prevent these accidents by NULLing some + fields on remove and replace. This way, either a panic or segfault + will be produced on the faulty operation. + - otto@cvs.openbsd.org 2005/10/24 20:25:14 + [openbsd-compat/sys-queue.h] + Partly backout. NOLIST, used in LISTs is probably interfering. + requested by deraadt@ + - otto@cvs.openbsd.org 2005/10/25 06:37:47 + [openbsd-compat/sys-queue.h] + Some uvm problem is being exposed with the more strict macros. + Revert until we've found out what's causing the panics. + - otto@cvs.openbsd.org 2005/11/25 08:06:25 + [openbsd-compat/sys-queue.h] + Introduce debugging aid for queue macros. Disabled by default; but + developers are encouraged to run with this enabled. + ok krw@ fgsch@ deraadt@ + - otto@cvs.openbsd.org 2007/04/30 18:42:34 + [openbsd-compat/sys-queue.h] + Enable QUEUE_MACRO_DEBUG on DIAGNOSTIC kernels. + Input and okays from krw@, millert@, otto@, deraadt@, miod@. + - millert@cvs.openbsd.org 2004/10/07 16:56:11 + GLOB_NOESCAPE is POSIX so move it out of the #ifndef _POSIX_SOURCE + block. + (NB. mostly an RCS ID sync, as portable strips out the conditionals) + - (djm) [regress/sftp-cmds.sh] + Use more restrictive glob to pick up test files from /bin - some platforms + ship broken symlinks there which could spoil the test. + - (djm) [openbsd-compat/bindresvport.c] + Sync RCS ID after irrelevant (for portable OpenSSH) header shuffling + +20070927 + - (dtucker) [configure.ac atomicio.c] Fall back to including <sys/poll.h> if + we don't have <poll.h> (eq QNX). From bacon at cs nyu edu. + - (dtucker) [configure.ac defines.h] Shadow expiry does not work on QNX6 + so disable it for that platform. From bacon at cs nyu edu. + +20070921 + - (djm) [atomicio.c] Fix spin avoidance for platforms that define + EWOULDBLOCK; patch from ben AT psc.edu + +20070917 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2007/08/23 02:49:43 + [auth-passwd.c auth.c session.c] + unifdef HAVE_LOGIN_CAP; ok deraadt@ millert@ + NB. RCS ID sync only for portable + - djm@cvs.openbsd.org 2007/08/23 02:55:51 + [auth-passwd.c auth.c session.c] + missed include bits from last commit + NB. RCS ID sync only for portable + - djm@cvs.openbsd.org 2007/08/23 03:06:10 + [auth.h] + login_cap.h doesn't belong here + NB. RCS ID sync only for portable + - djm@cvs.openbsd.org 2007/08/23 03:22:16 + [auth2-none.c sshd_config sshd_config.5] + Support "Banner=none" to disable displaying of the pre-login banner; + ok dtucker@ deraadt@ + - djm@cvs.openbsd.org 2007/08/23 03:23:26 + [sshconnect.c] + Execute ProxyCommands with $SHELL rather than /bin/sh unconditionally + - djm@cvs.openbsd.org 2007/09/04 03:21:03 + [clientloop.c monitor.c monitor_fdpass.c monitor_fdpass.h] + [monitor_wrap.c ssh.c] + make file descriptor passing code return an error rather than call fatal() + when it encounters problems, and use this to make session multiplexing + masters survive slaves failing to pass all stdio FDs; ok markus@ + - djm@cvs.openbsd.org 2007/09/04 11:15:56 + [ssh.c sshconnect.c sshconnect.h] + make ssh(1)'s ConnectTimeout option apply to both the TCP connection and + SSH banner exchange (previously it just covered the TCP connection). + This allows callers of ssh(1) to better detect and deal with stuck servers + that accept a TCP connection but don't progress the protocol, and also + makes ConnectTimeout useful for connections via a ProxyCommand; + feedback and "looks ok" markus@ + - sobrado@cvs.openbsd.org 2007/09/09 11:38:01 + [ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.c] + sort synopsis and options in ssh-agent(1); usage is lowercase + ok jmc@ + - stevesk@cvs.openbsd.org 2007/09/11 04:36:29 + [sshpty.c] + sort #include + NB. RCS ID sync only + - gilles@cvs.openbsd.org 2007/09/11 15:47:17 + [session.c ssh-keygen.c sshlogin.c] + use strcspn to properly overwrite '\n' in fgets returned buffer + ok pyr@, ray@, millert@, moritz@, chl@ + - stevesk@cvs.openbsd.org 2007/09/11 23:49:09 + [sshpty.c] + remove #if defined block not needed; ok markus@ dtucker@ + NB. RCS ID sync only + - stevesk@cvs.openbsd.org 2007/09/12 19:39:19 + [umac.c] + use xmalloc() and xfree(); ok markus@ pvalchev@ + - djm@cvs.openbsd.org 2007/09/13 04:39:04 + [sftp-server.c] + fix incorrect test when setting syslog facility; from Jan Pechanec + - djm@cvs.openbsd.org 2007/09/16 00:55:52 + [sftp-client.c] + use off_t instead of u_int64_t for file offsets, matching what the + progressmeter code expects; bz #842 + - (tim) [defines.h] Fix regression in long password support on OpenServer 6. + Problem report and additional testing rac AT tenzing.org. + +20070914 + - (dtucker) [openbsd-compat/bsd-asprintf.c] Plug mem leak in error path. + Patch from Jan.Pechanec at sun com. + +20070910 + - (dtucker) [openbsd-compat/regress/closefromtest.c] Bug #1358: Always + return 0 on successful test. From David.Leonard at quest com. + - (tim) [configure.ac] Autoconf didn't define HAVE_LIBIAF because we + did a AC_CHECK_FUNCS within the AC_CHECK_LIB test. + +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 <poll.h> like the man page says rather than <sys/poll.h>. 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 <ldv@altlinux.org> + - 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 <ldv@altlinux.org> + 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 + [sshd_config.5] + sort the `match' keywords; + - djm@cvs.openbsd.org 2007/03/06 10:13:14 + [version.h] + openssh-4.6; "please" deraadt@ + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] crank spec files for release + - (djm) [README] correct link to release notes + - (djm) Release 4.6p1 + +20070304 + - (djm) [configure.ac] add a --without-openssl-header-check option to + configure, as some platforms (OS X) ship OpenSSL headers whose version + does not match that of the shipping library. ok dtucker@ + - (dtucker) [openbsd-compat/openssl-compat.h] Bug #1291: Work around a + bug in OpenSSL 0.9.8e that prevents aes256-ctr, aes192-ctr and arcfour256 + ciphers from working correctly (disconnects with "Bad packet length" + errors) as found by Ben Harris. ok djm@ + +20070303 + - (dtucker) [regress/agent-ptrace.sh] Make ttrace gdb error a little more + general to cover newer gdb versions on HP-UX. + +20070302 + - (dtucker) [configure.ac] For Cygwin, read files in textmode (which allows + CRLF as well as LF lineendings) and write in binary mode. Patch from + vinschen at redhat.com. + - (dtucker) [INSTALL] Update to autoconf-2.61. + +20070301 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2007/03/01 10:28:02 + [auth2.c sshd_config.5 servconf.c] + Remove ChallengeResponseAuthentication support inside a Match + block as its interaction with KbdInteractive makes it difficult to + support. Also, relocate the CR/kbdint option special-case code into + servconf. "please commit" djm@, ok markus@ for the relocation. + - (tim) [buildpkg.sh.in openssh.xml.in] Clean up Solaris 10 smf(5) bits. + "Looks sane" dtucker@ + +20070228 + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2007/02/28 00:55:30 + [ssh-agent.c] + Remove expired keys periodically so they don't remain in memory when + the agent is entirely idle, as noted by David R. Piegdon. This is the + simple fix, a more efficient one will be done later. With markus, + deraadt, with & ok djm. + +20070225 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2007/02/20 10:25:14 + [clientloop.c] + set maximum packet and window sizes the same for multiplexed clients + as normal connections; ok markus@ + - dtucker@cvs.openbsd.org 2007/02/21 11:00:05 + [sshd.c] + Clear alarm() before restarting sshd on SIGHUP. Without this, if there's + a SIGALRM pending (for SSH1 key regeneration) when sshd is SIGHUP'ed, the + newly exec'ed sshd will get the SIGALRM and not have a handler for it, + and the default action will terminate the listening sshd. Analysis and + patch from andrew at gaul.org. + - dtucker@cvs.openbsd.org 2007/02/22 12:58:40 + [servconf.c] + Check activep so Match and GatewayPorts work together; ok markus@ + - ray@cvs.openbsd.org 2007/02/24 03:30:11 + [moduli.c] + - strlen returns size_t, not int. + - Pass full buffer size to fgets. + OK djm@, millert@, and moritz@. + +20070219 + - (dtucker) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2007/01/10 13:23:22 + [ssh_config.5] + do not use a list for SYNOPSIS; + this is actually part of a larger report sent by eric s. raymond + and forwarded by brad, but i only read half of it. spotted by brad. + - jmc@cvs.openbsd.org 2007/01/12 20:20:41 + [ssh-keygen.1 ssh-keygen.c] + more secsh -> rfc 4716 updates; + spotted by wiz@netbsd + ok markus + - dtucker@cvs.openbsd.org 2007/01/17 23:22:52 + [readconf.c] + Honour activep for times (eg ServerAliveInterval) while parsing + ssh_config and ~/.ssh/config so they work properly with Host directives. + From mario.lorenz@wincor-nixdorf.com via bz #1275. ok markus@ + - stevesk@cvs.openbsd.org 2007/01/21 01:41:54 + [auth-skey.c kex.c ssh-keygen.c session.c clientloop.c] + spaces + - stevesk@cvs.openbsd.org 2007/01/21 01:45:35 + [readconf.c] + spaces + - djm@cvs.openbsd.org 2007/01/22 11:32:50 + [sftp-client.c] + return error from do_upload() when a write fails. fixes bz#1252: zero + exit status from sftp when uploading to a full device. report from + jirkat AT atlas.cz; ok dtucker@ + - djm@cvs.openbsd.org 2007/01/22 13:06:21 + [scp.c] + fix detection of whether we should show progress meter or not: scp + tested isatty(stderr) but wrote the progress meter to stdout. This patch + makes it test stdout. bz#1265 reported by junkmail AT bitsculpture.com; + of dtucker@ + - stevesk@cvs.openbsd.org 2007/02/14 14:32:00 + [bufbn.c] + typos in comments; ok jmc@ + - dtucker@cvs.openbsd.org 2007/02/19 10:45:58 + [monitor_wrap.c servconf.c servconf.h monitor.c sshd_config.5] + Teach Match how handle config directives that are used before + authentication. This allows configurations such as permitting password + authentication from the local net only while requiring pubkey from + offsite. ok djm@, man page bits ok jmc@ + - (dtucker) [contrib/findssl.sh] Add "which" as a shell function since some + platforms don't have it. Patch from dleonard at vintela.com. + - (dtucker) [openbsd-compat/getrrsetbyname.c] Don't attempt to calloc + an array for signatures when there are none since "calloc(0, n) returns + NULL on some platforms (eg Tru64), which is explicitly permitted by + POSIX. Diagnosis and patch by svallet genoscope.cns.fr. + +20070128 + - (djm) [channels.c serverloop.c] Fix so-called "hang on exit" (bz #52) + when closing a tty session when a background process still holds tty + fds open. Great detective work and patch by Marc Aurele La France, + slightly tweaked by me; ok dtucker@ + +20070123 + - (dtucker) [openbsd-compat/bsd-snprintf.c] Static declarations for public + library interfaces aren't very helpful. Fix up the DOPR_OUTCH macro + so it works properly and modify its callers so that they don't pre or + post decrement arguments that are conditionally evaluated. While there, + put SNPRINTF_CONST back as it prevents build failures in some + configurations. ok djm@ (for most of it) + +20070122 + - (djm) [ssh-rand-helper.8] manpage nits; + from dleonard AT vintela.com (bz#1529) + +20070117 + - (dtucker) [packet.c] Re-remove in_systm.h since it's already in includes.h + and multiple including it causes problems on old IRIXes. (It snuck back + in during a sync.) Found (again) by Georg Schwarz. + +20070114 + - (dtucker) [ssh-keygen.c] av -> argv to match earlier sync. + - (djm) [openbsd-compat/bsd-snprintf.c] Fix integer overflow in return + value of snprintf replacement, similar to bugs in various libc + implementations. This overflow is not exploitable in OpenSSH. + While I'm fiddling with it, make it a fair bit faster by inlining the + append-char routine; ok dtucker@ + +20070105 + - (djm) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2006/11/14 19:41:04 + [ssh-keygen.c] + use argc and argv not some made up short form + - ray@cvs.openbsd.org 2006/11/23 01:35:11 + [misc.c sftp.c] + Don't access buf[strlen(buf) - 1] for zero-length strings. + ``ok by me'' djm@. + - markus@cvs.openbsd.org 2006/12/11 21:25:46 + [ssh-keygen.1 ssh.1] + add rfc 4716 (public key format); ok jmc + - djm@cvs.openbsd.org 2006/12/12 03:58:42 + [channels.c compat.c compat.h] + bz #1019: some ssh.com versions apparently can't cope with the + remote port forwarding bind_address being a hostname, so send + them an address for cases where they are not explicitly + specified (wildcard or localhost bind). reported by daveroth AT + acm.org; ok dtucker@ deraadt@ + - dtucker@cvs.openbsd.org 2006/12/13 08:34:39 + [servconf.c] + Make PermitOpen work with multiple values like the man pages says. + bz #1267 with details from peter at dmtz.com, with & ok djm@ + - dtucker@cvs.openbsd.org 2006/12/14 10:01:14 + [servconf.c] + Make "PermitOpen all" first-match within a block to match the way other + options work. ok markus@ djm@ + - jmc@cvs.openbsd.org 2007/01/02 09:57:25 + [sshd_config.5] + do not use lists for SYNOPSIS; + from eric s. raymond via brad + - stevesk@cvs.openbsd.org 2007/01/03 00:53:38 + [ssh-keygen.c] + remove small dead code; arnaud.lacombe.1@ulaval.ca via Coverity scan + - stevesk@cvs.openbsd.org 2007/01/03 03:01:40 + [auth2-chall.c channels.c dns.c sftp.c ssh-keygen.c ssh.c] + spaces + - stevesk@cvs.openbsd.org 2007/01/03 04:09:15 + [sftp.c] + ARGSUSED for lint + - stevesk@cvs.openbsd.org 2007/01/03 07:22:36 + [sftp-server.c] + spaces + +20061205 + - (djm) [auth.c] Fix NULL pointer dereference in fakepw(). Crash would + occur if the server did not have the privsep user and an invalid user + tried to login and both privsep and krb5 auth are disabled; ok dtucker@ + - (djm) [bsd-asprintf.c] Better test for bad vsnprintf lengths; ok dtucker@ + +20061108 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2006/11/07 13:02:07 + [dh.c] + BN_hex2bn returns int; from dtucker@ + 20061107 - (dtucker) [sshd.c] Use privsep_pw if we have it, but only require it if we absolutely need it. Pointed out by Corinna, ok djm@ @@ -13,7 +2118,6 @@ dtucker@ - (dtucker) [README contrib/{caldera,redhat,contrib}/openssh.spec] Bump versions. - - (dtucker) [dh.c] Type fix for BN_hex2bn; ok markus@ - (dtucker) Release 4.5p1. 20061105 @@ -2606,4 +4710,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4588.2.1 2006/11/07 13:02:59 dtucker Exp $ +$Id: ChangeLog,v 1.5095 2008/07/21 08:22:25 djm Exp $ diff --git a/crypto/openssh/FREEBSD-upgrade b/crypto/openssh/FREEBSD-upgrade index 86913ff..03b7dbf 100644 --- a/crypto/openssh/FREEBSD-upgrade +++ b/crypto/openssh/FREEBSD-upgrade @@ -3,6 +3,7 @@ FreeBSD maintainer's guide to OpenSSH-portable ============================================== +[needs rewriting for svn] 0) Make sure your mail spool has plenty of free space. It'll fill up pretty fast once you're done with this checklist. @@ -86,11 +87,7 @@ B) Re-commit everything on repoman (you *did* use a test repo for We've modified some configuration defaults in sshd: - - PasswordAuthentication defaults to "no" when PAM is enabled. - - - For protocol version 2, we don't load RSA host keys by - default. If both RSA and DSA keys are present, we prefer DSA - to RSA. + - PasswordAuthentication defaults to "no". - LoginGraceTime defaults to 120 seconds instead of 600. @@ -103,9 +100,6 @@ B) Re-commit everything on repoman (you *did* use a test repo for We've modified some configuration defaults in ssh: - - For protocol version 2, if both RSA and DSA keys are present, - we prefer DSA to RSA. - - CheckHostIP defaults to "no". 3) Canonic host names diff --git a/crypto/openssh/FREEBSD-vendor b/crypto/openssh/FREEBSD-vendor index b04a1ce..6329f5a 100644 --- a/crypto/openssh/FREEBSD-vendor +++ b/crypto/openssh/FREEBSD-vendor @@ -1,8 +1,8 @@ # $FreeBSD$ Project: Portable OpenSSH ProjectURL: http://www.openssh.com/portable.html -Version: 4.5p1 +Version: 5.1p1 VendorTag: OPENSSH -VersionTag: OpenSSH_4_5p1 +VersionTag: OpenSSH_5_1p1 License: BSD Maintainer: des diff --git a/crypto/openssh/INSTALL b/crypto/openssh/INSTALL index 1c784a5..001ebb6 100644 --- a/crypto/openssh/INSTALL +++ b/crypto/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: @@ -70,8 +85,9 @@ http://sourceforge.net/projects/libedit/ 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.60 to rebuild -the automatically generated files by running "autoreconf". +the code out of CVS yourself) then you will need autoconf-2.61 to rebuild +the automatically generated files by running "autoreconf". Earlier +versions may also work but this is not guaranteed. http://www.gnu.org/software/autoconf/ @@ -161,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 @@ -179,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 @@ -250,4 +266,4 @@ Please refer to the "reporting bugs" section of the webpage at http://www.openssh.com/ -$Id: INSTALL,v 1.76 2006/09/17 12:55:52 dtucker Exp $ +$Id: INSTALL,v 1.84 2007/08/17 12:52:05 dtucker Exp $ diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE index 0c2ff06..3964b1d 100644 --- a/crypto/openssh/LICENCE +++ b/crypto/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/crypto/openssh/PROTOCOL b/crypto/openssh/PROTOCOL new file mode 100644 index 0000000..37fd536 --- /dev/null +++ b/crypto/openssh/PROTOCOL @@ -0,0 +1,243 @@ +This documents OpenSSH's deviations and extensions to the published SSH +protocol. + +Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH +filexfer protocol described in: + +http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt + +Features from newer versions of the draft are not supported, unless +explicitly implemented as extensions described below. + +The protocol used by OpenSSH's ssh-agent is described in the file +PROTOCOL.agent + +1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com" + +This is a new transport-layer MAC method using the UMAC algorithm +(rfc4418). This method is identical to the "umac-64" method documented +in: + +http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt + +2. transport: Protocol 2 compression algorithm "zlib@openssh.com" + +This transport-layer compression method uses the zlib compression +algorithm (identical to the "zlib" method in rfc4253), but delays the +start of compression until after authentication has completed. This +avoids exposing compression code to attacks from unauthenticated users. + +The method is documented in: + +http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt + +3. connection: Channel write close extension "eow@openssh.com" + +The SSH connection protocol (rfc4254) provides the SSH_MSG_CHANNEL_EOF +message to allow an endpoint to signal its peer that it will send no +more data over a channel. Unfortunately, there is no symmetric way for +an endpoint to request that its peer should cease sending data to it +while still keeping the channel open for the endpoint to send data to +the peer. + +This is desirable, since it saves the transmission of data that would +otherwise need to be discarded and it allows an endpoint to signal local +processes of the condition, e.g. by closing the corresponding file +descriptor. + +OpenSSH implements a channel extension message to perform this +signalling: "eow@openssh.com" (End Of Write). This message is sent by +an endpoint when the local output of a session channel is closed or +experiences a write error. The message is formatted as follows: + + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string "eow@openssh.com" + boolean FALSE + +On receiving this message, the peer SHOULD cease sending data of +the channel and MAY signal the process from which the channel data +originates (e.g. by closing its read file descriptor). + +As with the symmetric SSH_MSG_CHANNEL_EOF message, the channel does +remain open after a "eow@openssh.com" has been sent and more data may +still be sent in the other direction. This message does not consume +window space and may be sent even if no window space is available. + +4. connection: disallow additional sessions extension + "no-more-sessions@openssh.com" + +Most SSH connections will only ever request a single session, but a +attacker may abuse a running ssh client to surreptitiously open +additional sessions under their control. OpenSSH provides a global +request "no-more-sessions@openssh.com" to mitigate this attack. + +When an OpenSSH client expects that it will never open another session +(i.e. it has been started with connection multiplexing disabled), it +will send the following global request: + + byte SSH_MSG_GLOBAL_REQUEST + string "no-more-sessions@openssh.com" + char want-reply + +On receipt of such a message, an OpenSSH server will refuse to open +future channels of type "session" and instead immediately abort the +connection. + +Note that this is not a general defence against compromised clients +(that is impossible), but it thwarts a simple attack. + +5. connection: Tunnel forward extension "tun@openssh.com" + +OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" +channel type. This channel type supports forwarding of network packets +with datagram boundaries intact between endpoints equipped with +interfaces like the BSD tun(4) device. Tunnel forwarding channels are +requested by the client with the following packet: + + byte SSH_MSG_CHANNEL_OPEN + string "tun@openssh.com" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + uint32 tunnel mode + uint32 remote unit number + +The "tunnel mode" parameter specifies whether the tunnel should forward +layer 2 frames or layer 3 packets. It may take one of the following values: + + SSH_TUNMODE_POINTOPOINT 1 /* layer 3 packets */ + SSH_TUNMODE_ETHERNET 2 /* layer 2 frames */ + +The "tunnel unit number" specifies the remote interface number, or may +be zero to allow the server to automatically chose an interface. A server +that is not willing to open a client-specified unit should refuse the +request with a SSH_MSG_CHANNEL_OPEN_FAILURE error. On successful open, +the server should reply with SSH_MSG_CHANNEL_OPEN_SUCCESS. + +Once established the client and server may exchange packet or frames +over the tunnel channel by encapsulating them in SSH protocol strings +and sending them as channel data. This ensures that packet boundaries +are kept intact. Specifically, packets are transmitted using normal +SSH_MSG_CHANNEL_DATA packets: + + byte SSH_MSG_CHANNEL_DATA + uint32 recipient channel + string data + +The contents of the "data" field for layer 3 packets is: + + uint32 packet length + uint32 address family + byte[packet length - 4] packet data + +The "address family" field identifies the type of packet in the message. +It may be one of: + + SSH_TUN_AF_INET 2 /* IPv4 */ + SSH_TUN_AF_INET6 24 /* IPv6 */ + +The "packet data" field consists of the IPv4/IPv6 datagram itself +without any link layer header. + +The contents of the "data" field for layer 3 packets is: + + uint32 packet length + byte[packet length] frame + +The "frame" field contains an IEEE 802.3 Ethernet frame, including +header. + +6. sftp: Reversal of arguments to SSH_FXP_SYMLINK + +When OpenSSH's sftp-server was implemented, the order of the arguments +to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, +the reversal was not noticed until the server was widely deployed. Since +fixing this to follow the specification would cause incompatibility, the +current order was retained. For correct operation, clients should send +SSH_FXP_SYMLINK as follows: + + uint32 id + string targetpath + string linkpath + +7. sftp: Server extension announcement in SSH_FXP_VERSION + +OpenSSH's sftp-server lists the extensions it supports using the +standard extension announcement mechanism in the SSH_FXP_VERSION server +hello packet: + + uint32 3 /* protocol version */ + string ext1-name + string ext1-version + string ext2-name + string ext2-version + ... + string extN-name + string extN-version + +Each extension reports its integer version number as an ASCII encoded +string, e.g. "1". The version will be incremented if the extension is +ever changed in an incompatible way. The server MAY advertise the same +extension with multiple versions (though this is unlikely). Clients MUST +check the version number before attempting to use the extension. + +8. sftp: Extension request "posix-rename@openssh.com" + +This operation provides a rename operation with POSIX semantics, which +are different to those provided by the standard SSH_FXP_RENAME in +draft-ietf-secsh-filexfer-02.txt. This request is implemented as a +SSH_FXP_EXTENDED request with the following format: + + uint32 id + string "posix-rename@openssh.com" + string oldpath + string newpath + +On receiving this request the server will perform the POSIX operation +rename(oldpath, newpath) and will respond with a SSH_FXP_STATUS message. +This extension is advertised in the SSH_FXP_VERSION hello with version +"1". + +9. sftp: Extension requests "statvfs@openssh.com" and + "fstatvfs@openssh.com" + +These requests correspond to the statvfs and fstatvfs POSIX system +interfaces. The "statvfs@openssh.com" request operates on an explicit +pathname, and is formatted as follows: + + uint32 id + string "statvfs@openssh.com" + string path + +The "fstatvfs@openssh.com" operates on an open file handle: + + uint32 id + string "fstatvfs@openssh.com" + string handle + +These requests return a SSH_FXP_STATUS reply on failure. On success they +return the following SSH_FXP_EXTENDED_REPLY reply: + + uint32 id + uint64 f_bsize /* file system block size */ + uint64 f_frsize /* fundamental fs block size */ + uint64 f_blocks /* number of blocks (unit f_frsize) */ + uint64 f_bfree /* free blocks in file system */ + uint64 f_bavail /* free blocks for non-root */ + uint64 f_files /* total file inodes */ + uint64 f_ffree /* free file inodes */ + uint64 f_favail /* free file inodes for to non-root */ + uint64 f_fsid /* file system id */ + uint64 f_flag /* bit mask of f_flag values */ + uint64 f_namemax /* maximum filename length */ + +The values of the f_flag bitmask are as follows: + + #define SSH_FXE_STATVFS_ST_RDONLY 0x1 /* read-only */ + #define SSH_FXE_STATVFS_ST_NOSUID 0x2 /* no setuid */ + +Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are +advertised in the SSH_FXP_VERSION hello with version "2". + +$OpenBSD: PROTOCOL,v 1.11 2008/07/05 05:16:01 djm Exp $ diff --git a/crypto/openssh/PROTOCOL.agent b/crypto/openssh/PROTOCOL.agent new file mode 100644 index 0000000..49adbdd --- /dev/null +++ b/crypto/openssh/PROTOCOL.agent @@ -0,0 +1,516 @@ +This describes the protocol used by OpenSSH's ssh-agent. + +OpenSSH's agent supports managing keys for the standard SSH protocol +2 as well as the legacy SSH protocol 1. Support for these key types +is almost completely disjoint - in all but a few cases, operations on +protocol 2 keys cannot see or affect protocol 1 keys and vice-versa. + +Protocol 1 and protocol 2 keys are separated because of the differing +cryptographic usage: protocol 1 private RSA keys are used to decrypt +challenges that were encrypted with the corresponding public key, +whereas protocol 2 RSA private keys are used to sign challenges with +a private key for verification with the corresponding public key. It +is considered unsound practice to use the same key for signing and +encryption. + +With a couple of exceptions, the protocol message names used in this +document indicate which type of key the message relates to. SSH_* +messages refer to protocol 1 keys only. SSH2_* messages refer to +protocol 2 keys. Furthermore, the names also indicate whether the +message is a request to the agent (*_AGENTC_*) or a reply from the +agent (*_AGENT_*). Section 3 below contains the mapping of the +protocol message names to their integer values. + +1. Data types + +Because of support for legacy SSH protocol 1 keys, OpenSSH's agent +protocol makes use of some data types not defined in RFC 4251. + +1.1 uint16 + +The "uint16" data type is a simple MSB-first 16 bit unsigned integer +encoded in two bytes. + +1.2 mpint1 + +The "mpint1" type represents an arbitrary precision integer (bignum). +Its format is as follows: + + uint16 bits + byte[(bits + 7) / 8] bignum + +"bignum" contains an unsigned arbitrary precision integer encoded as +eight bits per byte in big-endian (MSB first) format. + +Note the difference between the "mpint1" encoding and the "mpint" +encoding defined in RFC 4251. Also note that the length of the encoded +integer is specified in bits, not bytes and that the byte length of +the integer must be calculated by rounding up the number of bits to the +nearest eight. + +2. Protocol Messages + +All protocol messages are prefixed with their length in bytes, encoded +as a 32 bit unsigned integer. Specifically: + + uint32 message_length + byte[message_length] message + +The following message descriptions refer only to the content the +"message" field. + +2.1 Generic server responses + +The following generic messages may be sent by the server in response to +requests from the client. On success the agent may reply either with: + + byte SSH_AGENT_SUCCESS + +or a request-specific success message. + +On failure, the agent may reply with: + + byte SSH_AGENT_FAILURE + +SSH_AGENT_FAILURE messages are also sent in reply to unknown request +types. + +2.2 Adding keys to the agent + +Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and +SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys +respectively. + +Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED +and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional +"constraints" on their usage. + +OpenSSH may be built with support for keys hosted on a smartcard +or other hardware security module. These keys may be added +to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and +SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests. + +2.2.1 Key constraints + +The OpenSSH agent supports some basic optional constraints on key usage. +At present there are two constraints defined. + +The first constraint limits the validity duration of a key. It is +encoded as: + + byte SSH_AGENT_CONSTRAIN_LIFETIME + uint32 seconds + +Where "seconds" contains the number of seconds that the key shall remain +valid measured from the moment that the agent receives it. After the +validity period has expired, OpenSSH's agent will erase these keys from +memory. + +The second constraint requires the agent to seek explicit user +confirmation before performing private key operations with the loaded +key. This constraint is encoded as: + + byte SSH_AGENT_CONSTRAIN_CONFIRM + +Zero or more constraints may be specified when adding a key with one +of the *_CONSTRAINED requests. Multiple constraints are appended +consecutively to the end of the request: + + byte constraint1_type + .... constraint1_data + byte constraint2_type + .... constraint2_data + .... + byte constraintN_type + .... constraintN_data + +Such a sequence of zero or more constraints will be referred to below +as "constraint[]". Agents may determine whether there are constraints +by checking whether additional data exists in the "add key" request +after the key data itself. OpenSSH will refuse to add a key if it +contains unknown constraints. + +2.2.2 Add protocol 1 key + +A client may add a protocol 1 key to an agent with the following +request: + + byte SSH_AGENTC_ADD_RSA_IDENTITY or + SSH_AGENTC_ADD_RSA_ID_CONSTRAINED + uint32 ignored + mpint1 rsa_n + mpint1 rsa_e + mpint1 rsa_d + mpint1 rsa_iqmp + mpint1 rsa_q + mpint1 rsa_p + string key_comment + constraint[] key_constraints + +Note that there is some redundancy in the key parameters; a key could be +fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra +computation. + +"key_constraints" may only be present if the request type is +SSH_AGENTC_ADD_RSA_IDENTITY. + +The agent will reply with a SSH_AGENT_SUCCESS if the key has been +successfully added or a SSH_AGENT_FAILURE if an error occurred. + +2.2.3 Add protocol 2 key + +The OpenSSH agent supports DSA and RSA keys for protocol 2. DSA keys may +be added using the following request + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-dss" + mpint dsa_p + mpint dsa_q + mpint dsa_g + mpint dsa_public_key + mpint dsa_private_key + string key_comment + constraint[] key_constraints + +RSA keys may be added with this request: + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-rsa" + mpint rsa_n + mpint rsa_e + mpint rsa_d + mpint rsa_iqmp + mpint rsa_p + mpint rsa_q + string key_comment + constraint[] key_constraints + +Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse +order to the protocol 1 add keys message. As with the corresponding +protocol 1 "add key" request, the private key is overspecified to avoid +redundant processing. + +For both DSA and RSA key add requests, "key_constraints" may only be +present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED. + +The agent will reply with a SSH_AGENT_SUCCESS if the key has been +successfully added or a SSH_AGENT_FAILURE if an error occurred. + +2.2.4 Loading keys from a smartcard + +The OpenSSH agent may have optional smartcard support built in to it. If +so, it supports an operation to load keys from a smartcard. Technically, +only the public components of the keys are loaded into the agent so +this operation really arranges for future private key operations to be +delegated to the smartcard. + + byte SSH_AGENTC_ADD_SMARTCARD_KEY or + SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED + string reader_id + string pin + constraint[] key_constraints + +"reader_id" is an identifier to a smartcard reader and "pin" +is a PIN or passphrase used to unlock the private key(s) on the +device. "key_constraints" may only be present if the request type is +SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED. + +This operation may load all SSH keys that are unlocked using the +"pin" on the specified reader. The type of key loaded (protocol 1 +or protocol 2) will be specified by the smartcard itself, it is not +client-specified. + +The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have +been successfully loaded or a SSH_AGENT_FAILURE if an error occurred. +The agent will also return SSH_AGENT_FAILURE if it does not support +smartcards. + +2.3 Removing multiple keys + +A client may request that an agent delete all protocol 1 keys using the +following request: + + byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES + +This message requests the deletion of all protocol 2 keys: + + byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES + +On success, the agent will delete all keys of the requested type and +reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent +will reply with SSH_AGENT_FAILURE. + +Note that, to delete all keys (both protocol 1 and 2), a client +must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a +SSH2_AGENTC_REMOVE_ALL_IDENTITIES request. + +2.4 Removing specific keys + +2.4.1 Removing a protocol 1 key + +Removal of a protocol 1 key may be requested with the following message: + + byte SSH_AGENTC_REMOVE_RSA_IDENTITY + uint32 key_bits + mpint1 rsa_e + mpint1 rsa_n + +Note that key_bits is strictly redundant, as it may be inferred by the +length of rsa_n. + +The agent will delete any private key matching the specified public key +and return SSH_AGENT_SUCCESS. If no such key was found, the agent will +return SSH_AGENT_FAILURE. + +2.4.2 Removing a protocol 2 key + +Protocol 2 keys may be removed with the following request: + + byte SSH2_AGENTC_REMOVE_IDENTITY + string key_blob + +Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key +Algorithms" for either of the supported key types: "ssh-dss" or +"ssh-rsa". + +The agent will delete any private key matching the specified public key +and return SSH_AGENT_SUCCESS. If no such key was found, the agent will +return SSH_AGENT_FAILURE. + +2.4.3 Removing keys loaded from a smartcard + +A client may request that a server remove one or more smartcard-hosted +keys using this message: + + byte SSH_AGENTC_REMOVE_SMARTCARD_KEY + string reader_id + string pin + +"reader_id" the an identifier to a smartcard reader and "pin" is a PIN +or passphrase used to unlock the private key(s) on the device. + +When this message is received, and if the agent supports +smartcard-hosted keys, it will delete all keys that are hosted on the +specified smartcard that may be accessed with the given "pin". + +The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have +been successfully removed or a SSH_AGENT_FAILURE if an error occurred. +The agent will also return SSH_AGENT_FAILURE if it does not support +smartcards. + +2.5 Requesting a list of known keys + +An agent may be requested to list which keys it holds. Different +requests exist for protocol 1 and protocol 2 keys. + +2.5.1 Requesting a list of protocol 1 keys + +To request a list of protocol 1 keys that are held in the agent, a +client may send the following message: + + byte SSH_AGENTC_REQUEST_RSA_IDENTITIES + +The agent will reply with the following message: + + byte SSH_AGENT_RSA_IDENTITIES_ANSWER + uint32 num_keys + +Followed by zero or more consecutive keys, encoded as: + + uint32 bits + mpint1 rsa_e + mpint1 rsa_n + string key_comment + +2.5.2 Requesting a list of protocol 2 keys + +A client may send the following message to request a list of +protocol 2 keys that are stored in the agent: + + byte SSH2_AGENTC_REQUEST_IDENTITIES + +The agent will reply with the following message header: + + byte SSH2_AGENT_IDENTITIES_ANSWER + uint32 num_keys + +Followed by zero or more consecutive keys, encoded as: + + string key_blob + string key_comment + +Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key +Algorithms" for either of the supported key types: "ssh-dss" or +"ssh-rsa". + +2.6 Private key operations + +The purpose of the agent is to perform private key operations, such as +signing and encryption without requiring a passphrase to unlock the +key and without allowing the private key itself to be exposed. There +are separate requests for the protocol 1 and protocol 2 private key +operations. + +2.6.1 Protocol 1 private key challenge + +The private key operation used in version 1 of the SSH protocol is +decrypting a challenge that has been encrypted with a public key. +It may be requested using this message: + + byte SSH_AGENTC_RSA_CHALLENGE + uint32 ignored + mpint1 rsa_e + mpint1 rsa_n + mpint1 encrypted_challenge + byte[16] session_id + uint32 response_type /* must be 1 */ + +"rsa_e" and "rsa_n" are used to identify which private key to use. +"encrypted_challenge" is a challenge blob that has (presumably) +been encrypted with the public key and must be in the range +1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1 +session ID (computed from the server host key, the server semi-ephemeral +key and the session cookie). + +"ignored" and "response_type" exist for compatibility with legacy +implementations. "response_type" must be equal to 1; other response +types are not supported. + +On receiving this request, the server decrypts the "encrypted_challenge" +using the private key matching the supplied (rsa_e, rsa_n) values. For +the response derivation, the decrypted challenge is represented as an +unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values +smaller than 2^248 will have leading 0 bytes). + +The response value is then calculated as: + + response = MD5(decrypted_challenge || session_id) + +and returned in the following message + + byte SSH_AGENT_RSA_RESPONSE + byte[16] response + +If the agent cannot find the key specified by the supplied (rsa_e, +rsa_n) then it will return SSH_AGENT_FAILURE. + +2.6.2 Protocol 2 private key signature request + +A client may use the following message to request signing of data using +a protocol 2 key: + + byte SSH2_AGENTC_SIGN_REQUEST + string key_blob + string data + uint32 flags + +Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key +Algorithms" for either of the supported key types: "ssh-dss" or +"ssh-rsa". "flags" is a bit-mask, but at present only one possible value +is defined (see below for its meaning): + + SSH_AGENT_OLD_SIGNATURE 1 + +Upon receiving this request, the agent will look up the private key that +corresponds to the public key contained in key_blob. It will use this +private key to sign the "data" and produce a signature blob using the +key type-specific method described in RFC 4253 section 6.6 "Public Key +Algorithms". + +An exception to this is for "ssh-dss" keys where the "flags" word +contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy +signature encoding is used in lieu of the standard one. In this case, +the DSA signature blob is encoded as: + + byte[40] signature + +The signature will be returned in the response message: + + byte SSH2_AGENT_SIGN_RESPONSE + string signature_blob + +If the agent cannot find the key specified by the supplied key_blob then +it will return SSH_AGENT_FAILURE. + +2.7 Locking or unlocking an agent + +The agent supports temporary locking with a passphrase to suspend +processing of sensitive operations until it has been unlocked with the +same passphrase. To lock an agent, a client send the following request: + + byte SSH_AGENTC_LOCK + string passphrase + +Upon receipt of this message and if the agent is not already locked, +it will suspend processing requests and return a SSH_AGENT_SUCCESS +reply. If the agent is already locked, it will return SSH_AGENT_FAILURE. + +While locked, the agent will refuse all requests except +SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and +SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are +treated specially by a locked agent: it will always return an empty list +of keys. + +To unlock an agent, a client may request: + + byte SSH_AGENTC_UNLOCK + string passphrase + +If the passphrase matches and the agent is locked, then it will resume +processing all requests and return SSH_AGENT_SUCCESS. If the agent +is not locked or the passphrase does not match then it will return +SSH_AGENT_FAILURE. + +Locking and unlocking affects both protocol 1 and protocol 2 keys. + +3. Protocol message numbers + +3.1 Requests from client to agent for protocol 1 key operations + + SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 + SSH_AGENTC_RSA_CHALLENGE 3 + SSH_AGENTC_ADD_RSA_IDENTITY 7 + SSH_AGENTC_REMOVE_RSA_IDENTITY 8 + SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 + SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 + +3.2 Requests from client to agent for protocol 2 key operations + + SSH2_AGENTC_REQUEST_IDENTITIES 11 + SSH2_AGENTC_SIGN_REQUEST 13 + SSH2_AGENTC_ADD_IDENTITY 17 + SSH2_AGENTC_REMOVE_IDENTITY 18 + SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 + SSH2_AGENTC_ADD_ID_CONSTRAINED 25 + +3.3 Key-type independent requests from client to agent + + SSH_AGENTC_ADD_SMARTCARD_KEY 20 + SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 + SSH_AGENTC_LOCK 22 + SSH_AGENTC_UNLOCK 23 + SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 + +3.4 Generic replies from agent to client + + SSH_AGENT_FAILURE 5 + SSH_AGENT_SUCCESS 6 + +3.5 Replies from agent to client for protocol 1 key operations + + SSH_AGENT_RSA_IDENTITIES_ANSWER 2 + SSH_AGENT_RSA_RESPONSE 4 + +3.6 Replies from agent to client for protocol 2 key operations + + SSH2_AGENT_IDENTITIES_ANSWER 12 + SSH2_AGENT_SIGN_RESPONSE 14 + +3.7 Key constraint identifiers + + SSH_AGENT_CONSTRAIN_LIFETIME 1 + SSH_AGENT_CONSTRAIN_CONFIRM 2 + +$OpenBSD: PROTOCOL.agent,v 1.4 2008/07/01 23:12:47 stevesk Exp $ diff --git a/crypto/openssh/README b/crypto/openssh/README index fb53b55..183d92f 100644 --- a/crypto/openssh/README +++ b/crypto/openssh/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-4.5 for the release notes. +See http://www.openssh.com/txt/release-5.1 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html @@ -62,4 +62,4 @@ References - [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [7] http://www.openssh.com/faq.html -$Id: README,v 1.64 2006/11/07 12:25:45 dtucker Exp $ +$Id: README,v 1.69 2008/07/21 08:21:52 djm Exp $ diff --git a/crypto/openssh/README.platform b/crypto/openssh/README.platform index b7dc3f9..3d7db14 100644 --- a/crypto/openssh/README.platform +++ b/crypto/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: @@ -67,4 +81,4 @@ account stacks which will prevent authentication entirely, but will still return the output from pam_nologin to the client. -$Id: README.platform,v 1.7 2006/06/23 11:05:13 dtucker Exp $ +$Id: README.platform,v 1.9 2007/08/09 04:31:53 dtucker Exp $ diff --git a/crypto/openssh/RFC.nroff b/crypto/openssh/RFC.nroff deleted file mode 100644 index d6baed6..0000000 --- a/crypto/openssh/RFC.nroff +++ /dev/null @@ -1,1780 +0,0 @@ -.\" -*- nroff -*- -.\" -.\" $OpenBSD: RFC.nroff,v 1.2 2000/10/16 09:38:44 djm Exp $ -.\" -.pl 10.0i -.po 0 -.ll 7.2i -.lt 7.2i -.nr LL 7.2i -.nr LT 7.2i -.ds LF Ylonen -.ds RF FORMFEED[Page %] -.ds CF -.ds LH Internet-Draft -.ds RH 15 November 1995 -.ds CH SSH (Secure Shell) Remote Login Protocol -.na -.hy 0 -.in 0 -Network Working Group T. Ylonen -Internet-Draft Helsinki University of Technology -draft-ylonen-ssh-protocol-00.txt 15 November 1995 -Expires: 15 May 1996 - -.in 3 - -.ce -The SSH (Secure Shell) Remote Login Protocol - -.ti 0 -Status of This Memo - -This document is an Internet-Draft. Internet-Drafts are working -documents of the Internet Engineering Task Force (IETF), its areas, -and its working groups. Note that other groups may also distribute -working documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six -months and may be updated, replaced, or obsoleted by other docu- -ments at any time. It is inappropriate to use Internet-Drafts as -reference material or to cite them other than as ``work in pro- -gress.'' - -To learn the current status of any Internet-Draft, please check the -``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow -Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), -munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or -ftp.isi.edu (US West Coast). - -The distribution of this memo is unlimited. - -.ti 0 -Introduction - -SSH (Secure Shell) is a program to log into another computer over a -network, to execute commands in a remote machine, and to move files -from one machine to another. It provides strong authentication and -secure communications over insecure networks. Its features include -the following: -.IP o -Closes several security holes (e.g., IP, routing, and DNS spoofing). -New authentication methods: .rhosts together with RSA [RSA] based host -authentication, and pure RSA authentication. -.IP o -All communications are automatically and transparently encrypted. -Encryption is also used to protect integrity. -.IP o -X11 connection forwarding provides secure X11 sessions. -.IP o -Arbitrary TCP/IP ports can be redirected over the encrypted channel -in both directions. -.IP o -Client RSA-authenticates the server machine in the beginning of every -connection to prevent trojan horses (by routing or DNS spoofing) and -man-in-the-middle attacks, and the server RSA-authenticates the client -machine before accepting .rhosts or /etc/hosts.equiv authentication -(to prevent DNS, routing, or IP spoofing). -.IP o -An authentication agent, running in the user's local workstation or -laptop, can be used to hold the user's RSA authentication keys. -.RT - -The goal has been to make the software as easy to use as possible for -ordinary users. The protocol has been designed to be as secure as -possible while making it possible to create implementations that -are easy to use and install. The sample implementation has a number -of convenient features that are not described in this document as they -are not relevant for the protocol. - - -.ti 0 -Overview of the Protocol - -The software consists of a server program running on a server machine, -and a client program running on a client machine (plus a few auxiliary -programs). The machines are connected by an insecure IP [RFC0791] -network (that can be monitored, tampered with, and spoofed by hostile -parties). - -A connection is always initiated by the client side. The server -listens on a specific port waiting for connections. Many clients may -connect to the same server machine. - -The client and the server are connected via a TCP/IP [RFC0793] socket -that is used for bidirectional communication. Other types of -transport can be used but are currently not defined. - -When the client connects the server, the server accepts the connection -and responds by sending back its version identification string. The -client parses the server's identification, and sends its own -identification. The purpose of the identification strings is to -validate that the connection was to the correct port, declare the -protocol version number used, and to declare the software version used -on each side (for debugging purposes). The identification strings are -human-readable. If either side fails to understand or support the -other side's version, it closes the connection. - -After the protocol identification phase, both sides switch to a packet -based binary protocol. The server starts by sending its host key -(every host has an RSA key used to authenticate the host), server key -(an RSA key regenerated every hour), and other information to the -client. The client then generates a 256 bit session key, encrypts it -using both RSA keys (see below for details), and sends the encrypted -session key and selected cipher type to the server. Both sides then -turn on encryption using the selected algorithm and key. The server -sends an encrypted confirmation message to the client. - -The client then authenticates itself using any of a number of -authentication methods. The currently supported authentication -methods are .rhosts or /etc/hosts.equiv authentication (disabled by -default), the same with RSA-based host authentication, RSA -authentication, and password authentication. - -After successful authentication, the client makes a number of requests -to prepare for the session. Typical requests include allocating a -pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting -authentication agent forwarding, and executing the shell or a command. - -When a shell or command is executed, the connection enters interactive -session mode. In this mode, data is passed in both directions, -new forwarded connections may be opened, etc. The interactive session -normally terminates when the server sends the exit status of the -program to the client. - - -The protocol makes several reservations for future extensibility. -First of all, the initial protocol identification messages include the -protocol version number. Second, the first packet by both sides -includes a protocol flags field, which can be used to agree on -extensions in a compatible manner. Third, the authentication and -session preparation phases work so that the client sends requests to -the server, and the server responds with success or failure. If the -client sends a request that the server does not support, the server -simply returns failure for it. This permits compatible addition of -new authentication methods and preparation operations. The -interactive session phase, on the other hand, works asynchronously and -does not permit the use of any extensions (because there is no easy -and reliable way to signal rejection to the other side and problems -would be hard to debug). Any compatible extensions to this phase must -be agreed upon during any of the earlier phases. - -.ti 0 -The Binary Packet Protocol - -After the protocol identification strings, both sides only send -specially formatted packets. The packet layout is as follows: -.IP o -Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb -first. Gives the length of the packet, not including the length field -and padding. The maximum length of a packet (not including the length -field and padding) is 262144 bytes. -.IP o -Padding: 1-8 bytes of random data (or zeroes if not encrypting). The -amount of padding is (8 - (length % 8)) bytes (where % stands for the -modulo operator). The rationale for always having some random padding -at the beginning of each packet is to make known plaintext attacks -more difficult. -.IP o -Packet type: 8-bit unsigned byte. The value 255 is reserved for -future extension. -.IP o -Data: binary data bytes, depending on the packet type. The number of -data bytes is the "length" field minus 5. -.IP o -Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the -Cyclic Redundancy Check, with the polynomial 0xedb88320, of the -Padding, Packet type, and Data fields. The crc is computed before -any encryption. -.RT - -The packet, except for the length field, may be encrypted using any of -a number of algorithms. The length of the encrypted part (Padding + -Type + Data + Check) is always a multiple of 8 bytes. Typically the -cipher is used in a chained mode, with all packets chained together as -if it was a single data stream (the length field is never included in -the encryption process). Details of encryption are described below. - -When the session starts, encryption is turned off. Encryption is -enabled after the client has sent the session key. The encryption -algorithm to use is selected by the client. - - -.ti 0 -Packet Compression - -If compression is supported (it is an optional feature, see -SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields -of the packet are compressed using the gzip deflate algorithm [GZIP]. -If compression is in effect, the packet length field indicates the -length of the compressed data, plus 4 for the crc. The amount of -padding is computed from the compressed data, so that the amount of -data to be encrypted becomes a multiple of 8 bytes. - -When compressing, the packets (type + data portions) in each direction -are compressed as if they formed a continuous data stream, with only the -current compression block flushed between packets. This corresponds -to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression -dictionary is not flushed between packets. The two directions are -compressed independently of each other. - - -.ti 0 -Packet Encryption - -The protocol supports several encryption methods. During session -initialization, the server sends a bitmask of all encryption methods -that it supports, and the client selects one of these methods. The -client also generates a 256-bit random session key (32 8-bit bytes) and -sends it to the server. - -The encryption methods supported by the current implementation, and -their codes are: -.TS -center; -l r l. -SSH_CIPHER_NONE 0 No encryption -SSH_CIPHER_IDEA 1 IDEA in CFB mode -SSH_CIPHER_DES 2 DES in CBC mode -SSH_CIPHER_3DES 3 Triple-DES in CBC mode -SSH_CIPHER_TSS 4 An experimental stream cipher -SSH_CIPHER_RC4 5 RC4 -.TE - -All implementations are required to support SSH_CIPHER_DES and -SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and -SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is -optional (and it is not described in this document). Other ciphers -may be added at a later time; support for them is optional. - -For encryption, the encrypted portion of the packet is considered a -linear byte stream. The length of the stream is always a multiple of -8. The encrypted portions of consecutive packets (in the same -direction) are encrypted as if they were a continuous buffer (that is, -any initialization vectors are passed from the previous packet to the -next packet). Data in each direction is encrypted independently. -.IP SSH_CIPHER_DES -The key is taken from the first 8 bytes of the session key. The least -significant bit of each byte is ignored. This results in 56 bits of -key data. DES [DES] is used in CBC mode. The iv (initialization vector) is -initialized to all zeroes. -.IP SSH_CIPHER_3DES -The variant of triple-DES used here works as follows: there are three -independent DES-CBC ciphers, with independent initialization vectors. -The data (the whole encrypted data stream) is first encrypted with the -first cipher, then decrypted with the second cipher, and finally -encrypted with the third cipher. All these operations are performed -in CBC mode. - -The key for the first cipher is taken from the first 8 bytes of the -session key; the key for the next cipher from the next 8 bytes, and -the key for the third cipher from the following 8 bytes. All three -initialization vectors are initialized to zero. - -(Note: the variant of 3DES used here differs from some other -descriptions.) -.IP SSH_CIPHER_IDEA -The key is taken from the first 16 bytes of the session key. IDEA -[IDEA] is used in CFB mode. The initialization vector is initialized -to all zeroes. -.IP SSH_CIPHER_TSS -All 32 bytes of the session key are used as the key. - -There is no reference available for the TSS algorithm; it is currently -only documented in the sample implementation source code. The -security of this cipher is unknown (but it is quite fast). The cipher -is basically a stream cipher that uses MD5 as a random number -generator and takes feedback from the data. -.IP SSH_CIPHER_RC4 -The first 16 bytes of the session key are used as the key for the -server to client direction. The remaining 16 bytes are used as the -key for the client to server direction. This gives independent -128-bit keys for each direction. - -This algorithm is the alleged RC4 cipher posted to the Usenet in 1995. -It is widely believed to be equivalent with the original RSADSI RC4 -cipher. This is a very fast algorithm. -.RT - - -.ti 0 -Data Type Encodings - -The Data field of each packet contains data encoded as described in -this section. There may be several data items; each item is coded as -described here, and their representations are concatenated together -(without any alignment or padding). - -Each data type is stored as follows: -.IP "8-bit byte" -The byte is stored directly as a single byte. -.IP "32-bit unsigned integer" -Stored in 4 bytes, msb first. -.IP "Arbitrary length binary string" -First 4 bytes are the length of the string, msb first (not including -the length itself). The following "length" bytes are the string -value. There are no terminating null characters. -.IP "Multiple-precision integer" -First 2 bytes are the number of bits in the integer, msb first (for -example, the value 0x00012345 would have 17 bits). The value zero has -zero bits. It is permissible that the number of bits be larger than the -real number of bits. - -The number of bits is followed by (bits + 7) / 8 bytes of binary data, -msb first, giving the value of the integer. -.RT - - -.ti 0 -TCP/IP Port Number and Other Options - -The server listens for connections on TCP/IP port 22. - -The client may connect the server from any port. However, if the -client wishes to use any form of .rhosts or /etc/hosts.equiv -authentication, it must connect from a privileged port (less than -1024). - -For the IP Type of Service field [RFC0791], it is recommended that -interactive sessions (those having a user terminal or forwarding X11 -connections) use the IPTOS_LOWDELAY, and non-interactive connections -use IPTOS_THROUGHPUT. - -It is recommended that keepalives are used, because otherwise programs -on the server may never notice if the other end of the connection is -rebooted. - - -.ti 0 -Protocol Version Identification - -After the socket is opened, the server sends an identification string, -which is of the form -"SSH-<protocolmajor>.<protocolminor>-<version>\\n", where -<protocolmajor> and <protocolminor> are integers and specify the -protocol version number (not software distribution version). -<version> is server side software version string (max 40 characters); -it is not interpreted by the remote side but may be useful for -debugging. - -The client parses the server's string, and sends a corresponding -string with its own information in response. If the server has lower -version number, and the client contains special code to emulate it, -the client responds with the lower number; otherwise it responds with -its own number. The server then compares the version number the -client sent with its own, and determines whether they can work -together. The server either disconnects, or sends the first packet -using the binary packet protocol and both sides start working -according to the lower of the protocol versions. - -By convention, changes which keep the protocol compatible with -previous versions keep the same major protocol version; changes that -are not compatible increment the major version (which will hopefully -never happen). The version described in this document is 1.3. - -The client will - -.ti 0 -Key Exchange and Server Host Authentication - -The first message sent by the server using the packet protocol is -SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public -key, supported ciphers, supported authentication methods, and flags -for protocol extensions. It also contains a 64-bit random number -(cookie) that must be returned in the client's reply (to make IP -spoofing more difficult). No encryption is used for this message. - -Both sides compute a session id as follows. The modulus of the server -key is interpreted as a byte string (without explicit length field, -with minimum length able to hold the whole value), most significant -byte first. This string is concatenated with the server host key -interpreted the same way. Additionally, the cookie is concatenated -with this. Both sides compute MD5 of the resulting string. The -resulting 16 bytes (128 bits) are stored by both parties and are -called the session id. - -The client responds with a SSH_CMSG_SESSION_KEY message, which -contains the selected cipher type, a copy of the 64-bit cookie sent by -the server, client's protocol flags, and a session key encrypted -with both the server's host key and server key. No encryption is used -for this message. - -The session key is 32 8-bit bytes (a total of 256 random bits -generated by the client). The client first xors the 16 bytes of the -session id with the first 16 bytes of the session key. The resulting -string is then encrypted using the smaller key (one with smaller -modulus), and the result is then encrypted using the other key. The -number of bits in the public modulus of the two keys must differ by at -least 128 bits. - -At each encryption step, a multiple-precision integer is constructed -from the data to be encrypted as follows (the integer is here -interpreted as a sequence of bytes, msb first; the number of bytes is -the number of bytes needed to represent the modulus). - -The most significant byte (which is only partial as the value must be -less than the public modulus, which is never a power of two) is zero. - -The next byte contains the value 2 (which stands for public-key -encrypted data in the PKCS standard [PKCS#1]). Then, there are -non-zero random bytes to fill any unused space, a zero byte, and the -data to be encrypted in the least significant bytes, the last byte of -the data in the least significant byte. - -This algorithm is used twice. First, it is used to encrypt the 32 -random bytes generated by the client to be used as the session key -(xored by the session id). This value is converted to an integer as -described above, and encrypted with RSA using the key with the smaller -modulus. The resulting integer is converted to a byte stream, msb -first. This byte stream is padded and encrypted identically using the -key with the larger modulus. - -After the client has sent the session key, it starts to use the -selected algorithm and key for decrypting any received packets, and -for encrypting any sent packets. Separate ciphers are used for -different directions (that is, both directions have separate -initialization vectors or other state for the ciphers). - -When the server has received the session key message, and has turned -on encryption, it sends a SSH_SMSG_SUCCESS message to the client. - -The recommended size of the host key is 1024 bits, and 768 bits for -the server key. The minimum size is 512 bits for the smaller key. - - -.ti 0 -Declaring the User Name - -The client then sends a SSH_CMSG_USER message to the server. This -message specifies the user name to log in as. - -The server validates that such a user exists, checks whether -authentication is needed, and responds with either SSH_SMSG_SUCCESS or -SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication -is needed for this user (no password), and authentication phase has -now been completed. SSH_SMSG_FAILURE indicates that authentication is -needed (or the user does not exist). - -If the user does not exist, it is recommended that this returns -failure, but the server keeps reading messages from the client, and -responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE, -and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot -be certain whether the user exists. - - -.ti 0 -Authentication Phase - -Provided the server didn't immediately accept the login, an -authentication exchange begins. The client sends messages to the -server requesting different types of authentication in arbitrary order as -many times as desired (however, the server may close the connection -after a timeout). The server always responds with SSH_SMSG_SUCCESS if -it has accepted the authentication, and with SSH_SMSG_FAILURE if it has -denied authentication with the requested method or it does not -recognize the message. Some authentication methods cause an exchange -of further messages before the final result is sent. The -authentication phase ends when the server responds with success. - -The recommended value for the authentication timeout (timeout before -disconnecting if no successful authentication has been made) is 5 -minutes. - -The following authentication methods are currently supported: -.TS -center; -l r l. -SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv -SSH_AUTH_RSA 2 pure RSA authentication -SSH_AUTH_PASSWORD 3 password authentication -SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication -.TE -.IP SSH_AUTH_RHOSTS - -This is the authentication method used by rlogin and rsh [RFC1282]. - -The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name -as an argument. - -The server checks whether to permit authentication. On UNIX systems, -this is usually done by checking /etc/hosts.equiv, and .rhosts in the -user's home directory. The connection must come from a privileged -port. - -It is recommended that the server checks that there are no IP options -(such as source routing) specified for the socket before accepting -this type of authentication. The client host name should be -reverse-mapped and then forward mapped to ensure that it has the -proper IP-address. - -This authentication method trusts the remote host (root on the remote -host can pretend to be any other user on that host), the name -services, and partially the network: anyone who can see packets coming -out from the server machine can do IP-spoofing and pretend to be any -machine; however, the protocol prevents blind IP-spoofing (which used -to be possible with rlogin). - -Many sites probably want to disable this authentication method because -of the fundamental insecurity of conventional .rhosts or -/etc/hosts.equiv authentication when faced with spoofing. It is -recommended that this method not be supported by the server by -default. -.IP SSH_AUTH_RHOSTS_RSA - -In addition to conventional .rhosts and hosts.equiv authentication, -this method additionally requires that the client host be -authenticated using RSA. - -The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side -user name, and the public host key of the client host. - -The server first checks if normal .rhosts or /etc/hosts.equiv -authentication would be accepted, and if not, responds with -SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key -for the client machine (using the same name for the host that was used -for checking the .rhosts and /etc/hosts.equiv files). If it does not -know the RSA key for the client, access is denied and SSH_SMSG_FAILURE -is sent. - -If the server knows the host key of the client machine, it verifies -that the given host key matches that known for the client. If not, -access is denied and SSH_SMSG_FAILURE is sent. - -The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing -an encrypted challenge for the client. The challenge is 32 8-bit -random bytes (256 bits). When encrypted, the highest (partial) byte -is left as zero, the next byte contains the value 2, the following are -non-zero random bytes, followed by a zero byte, and the challenge put -in the remaining bytes. This is then encrypted using RSA with the -client host's public key. (The padding and encryption algorithm is -the same as that used for the session key.) - -The client decrypts the challenge using its private host key, -concatenates this with the session id, and computes an MD5 checksum -of the resulting 48 bytes. The MD5 output is returned as 16 bytes in -a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen -plaintext attacks against RSA; the session id binds it to a specific -session). - -The server verifies that the MD5 of the decrypted challenge returned by -the client matches that of the original value, and sends SSH_SMSG_SUCCESS if -so. Otherwise it sends SSH_SMSG_FAILURE and refuses the -authentication attempt. - -This authentication method trusts the client side machine in that root -on that machine can pretend to be any user on that machine. -Additionally, it trusts the client host key. The name and/or IP -address of the client host is only used to select the public host key. -The same host name is used when scanning .rhosts or /etc/hosts.equiv -and when selecting the host key. It would in principle be possible to -eliminate the host name entirely and substitute it directly by the -host key. IP and/or DNS [RFC1034] spoofing can only be used -to pretend to be a host for which the attacker has the private host -key. -.IP SSH_AUTH_RSA - -The idea behind RSA authentication is that the server recognizes the -public key offered by the client, generates a random challenge, and -encrypts the challenge with the public key. The client must then -prove that it has the corresponding private key by decrypting the -challenge. - -The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an -argument. - -The server may respond immediately with SSH_SMSG_FAILURE if it does -not permit authentication with this key. Otherwise it generates a -challenge, encrypts it using the user's public key (stored on the -server and identified using the modulus), and sends -SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an -argument. - -The challenge is 32 8-bit random bytes (256 bits). When encrypted, -the highest (partial) byte is left as zero, the next byte contains the -value 2, the following are non-zero random bytes, followed by a zero -byte, and the challenge put in the remaining bytes. This is then -encrypted with the public key. (The padding and encryption algorithm -is the same as that used for the session key.) - -The client decrypts the challenge using its private key, concatenates -it with the session id, and computes an MD5 checksum of the resulting -48 bytes. The MD5 output is returned as 16 bytes in a -SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary -to avoid chosen plaintext attacks against RSA; the session id binds it -to a specific session.) - -The server verifies that the MD5 of the decrypted challenge returned -by the client matches that of the original value, and sends -SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and -refuses the authentication attempt. - -This authentication method does not trust the remote host, the -network, name services, or anything else. Authentication is based -solely on the possession of the private identification keys. Anyone -in possession of the private keys can log in, but nobody else. - -The server may have additional requirements for a successful -authentiation. For example, to limit damage due to a compromised RSA -key, a server might restrict access to a limited set of hosts. -.IP SSH_AUTH_PASSWORD - -The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text -password. (Note that even though the password is plain text inside -the message, it is normally encrypted by the packet mechanism.) - -The server verifies the password, and sends SSH_SMSG_SUCCESS if -authentication was accepted and SSH_SMSG_FAILURE otherwise. - -Note that the password is read from the user by the client; the user -never interacts with a login program. - -This authentication method does not trust the remote host, the -network, name services or anything else. Authentication is based -solely on the possession of the password. Anyone in possession of the -password can log in, but nobody else. -.RT - -.ti 0 -Preparatory Operations - -After successful authentication, the server waits for a request from -the client, processes the request, and responds with SSH_SMSG_SUCCESS -whenever a request has been successfully processed. If it receives a -message that it does not recognize or it fails to honor a request, it -returns SSH_SMSG_FAILURE. It is expected that new message types might -be added to this phase in future. - -The following messages are currently defined for this phase. -.IP SSH_CMSG_REQUEST_COMPRESSION -Requests that compression be enabled for this session. A -gzip-compatible compression level (1-9) is passed as an argument. -.IP SSH_CMSG_REQUEST_PTY -Requests that a pseudo terminal device be allocated for this session. -The user terminal type and terminal modes are supplied as arguments. -.IP SSH_CMSG_X11_REQUEST_FORWARDING -Requests forwarding of X11 connections from the remote machine to the -local machine over the secure channel. Causes an internet-domain -socket to be allocated and the DISPLAY variable to be set on the server. -X11 authentication data is automatically passed to the server, and the -client may implement spoofing of authentication data for added -security. The authentication data is passed as arguments. -.IP SSH_CMSG_PORT_FORWARD_REQUEST -Requests forwarding of a TCP/IP port on the server host over the -secure channel. What happens is that whenever a connection is made to -the port on the server, a connection will be made from the client end -to the specified host/port. Any user can forward unprivileged ports; -only the root can forward privileged ports (as determined by -authentication done earlier). -.IP SSH_CMSG_AGENT_REQUEST_FORWARDING -Requests forwarding of the connection to the authentication agent. -.IP SSH_CMSG_EXEC_SHELL -Starts a shell (command interpreter) for the user, and moves into -interactive session mode. -.IP SSH_CMSG_EXEC_CMD -Executes the given command (actually "<shell> -c <command>" or -equivalent) for the user, and moves into interactive session mode. -.RT - - -.ti 0 -Interactive Session and Exchange of Data - -During the interactive session, any data written by the shell or -command running on the server machine is forwarded to stdin or -stderr on the client machine, and any input available from stdin on -the client machine is forwarded to the program on the server machine. - -All exchange is asynchronous; either side can send at any time, and -there are no acknowledgements (TCP/IP already provides reliable -transport, and the packet protocol protects against tampering or IP -spoofing). - -When the client receives EOF from its standard input, it will send -SSH_CMSG_EOF; however, this in no way terminates the exchange. The -exchange terminates and interactive mode is left when the server sends -SSH_SMSG_EXITSTATUS to indicate that the client program has -terminated. Alternatively, either side may disconnect at any time by -sending SSH_MSG_DISCONNECT or closing the connection. - -The server may send any of the following messages: -.IP SSH_SMSG_STDOUT_DATA -Data written to stdout by the program running on the server. The data -is passed as a string argument. The client writes this data to -stdout. -.IP SSH_SMSG_STDERR_DATA -Data written to stderr by the program running on the server. The data -is passed as a string argument. The client writes this data to -stderr. (Note that if the program is running on a tty, it is not -possible to separate stdout and stderr data, and all data will be sent -as stdout data.) -.IP SSH_SMSG_EXITSTATUS -Indicates that the shell or command has exited. Exit status is passed -as an integer argument. This message causes termination of the -interactive session. -.IP SSH_SMSG_AGENT_OPEN -Indicates that someone on the server side is requesting a connection -to the authentication agent. The server-side channel number is passed -as an argument. The client must respond with either -SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE. -.IP SSH_SMSG_X11_OPEN -Indicates that a connection has been made to the X11 socket on the -server side and should be forwarded to the real X server. An integer -argument indicates the channel number allocated for this connection on -the server side. The client should send back either -SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with -the same server side channel number. -.IP SSH_MSG_PORT_OPEN -Indicates that a connection has been made to a port on the server side -for which forwarding has been requested. Arguments are server side -channel number, host name to connect to, and port to connect to. The -client should send back either -SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with -the same server side channel number. -.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION -This is sent by the server to indicate that it has opened a connection -as requested in a previous message. The first argument indicates the -client side channel number, and the second argument is the channel number -that the server has allocated for this connection. -.IP SSH_MSG_CHANNEL_OPEN_FAILURE -This is sent by the server to indicate that it failed to open a -connection as requested in a previous message. The client-side -channel number is passed as an argument. The client will close the -descriptor associated with the channel and free the channel. -.IP SSH_MSG_CHANNEL_DATA -This packet contains data for a channel from the server. The first -argument is the client-side channel number, and the second argument (a -string) is the data. -.IP SSH_MSG_CHANNEL_CLOSE -This is sent by the server to indicate that whoever was in the other -end of the channel has closed it. The argument is the client side channel -number. The client will let all buffered data in the channel to -drain, and when ready, will close the socket, free the channel, and -send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the -channel. -.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION -This is send by the server to indicate that a channel previously -closed by the client has now been closed on the server side as well. -The argument indicates the client channel number. The client frees -the channel. -.RT - -The client may send any of the following messages: -.IP SSH_CMSG_STDIN_DATA -This is data to be sent as input to the program running on the server. -The data is passed as a string. -.IP SSH_CMSG_EOF -Indicates that the client has encountered EOF while reading standard -input. The server will allow any buffered input data to drain, and -will then close the input to the program. -.IP SSH_CMSG_WINDOW_SIZE -Indicates that window size on the client has been changed. The server -updates the window size of the tty and causes SIGWINCH to be sent to -the program. The new window size is passed as four integer arguments: -row, col, xpixel, ypixel. -.IP SSH_MSG_PORT_OPEN -Indicates that a connection has been made to a port on the client side -for which forwarding has been requested. Arguments are client side -channel number, host name to connect to, and port to connect to. The -server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or -SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number. -.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION -This is sent by the client to indicate that it has opened a connection -as requested in a previous message. The first argument indicates the -server side channel number, and the second argument is the channel -number that the client has allocated for this connection. -.IP SSH_MSG_CHANNEL_OPEN_FAILURE -This is sent by the client to indicate that it failed to open a -connection as requested in a previous message. The server side -channel number is passed as an argument. The server will close the -descriptor associated with the channel and free the channel. -.IP SSH_MSG_CHANNEL_DATA -This packet contains data for a channel from the client. The first -argument is the server side channel number, and the second argument (a -string) is the data. -.IP SSH_MSG_CHANNEL_CLOSE -This is sent by the client to indicate that whoever was in the other -end of the channel has closed it. The argument is the server channel -number. The server will allow buffered data to drain, and when ready, -will close the socket, free the channel, and send the client a -SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel. -.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION -This is send by the client to indicate that a channel previously -closed by the server has now been closed on the client side as well. -The argument indicates the server channel number. The server frees -the channel. -.RT - -Any unsupported messages during interactive mode cause the connection -to be terminated with SSH_MSG_DISCONNECT and an error message. -Compatible protocol upgrades should agree about any extensions during -the preparation phase or earlier. - - -.ti 0 -Termination of the Connection - -Normal termination of the connection is always initiated by the server -by sending SSH_SMSG_EXITSTATUS after the program has exited. The -client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION -and closes the socket; the server then closes the socket. There are -two purposes for the confirmation: some systems may lose previously -sent data when the socket is closed, and closing the client side first -causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not -consuming server resources. - -If the program terminates due to a signal, the server will send -SSH_MSG_DISCONNECT with an appropriate message. If the connection is -closed, all file descriptors to the program will be closed and the -server will exit. If the program runs on a tty, the kernel sends it -the SIGHUP signal when the pty master side is closed. - -.ti 0 -Protocol Flags - -Both the server and the client pass 32 bits of protocol flags to the -other side. The flags are intended for compatible protocol extension; -the server first announces which added capabilities it supports, and -the client then sends the capabilities that it supports. - -The following flags are currently defined (the values are bit masks): -.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER" -This flag can only be sent by the client. It indicates that the X11 -forwarding requests it sends will include the screen number. -.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN" -If both sides specify this flag, SSH_SMSG_X11_OPEN and -SSH_MSG_PORT_OPEN messages will contain an additional field containing -a description of the host at the other end of the connection. -.RT - -.ti 0 -Detailed Description of Packet Types and Formats - -The supported packet types and the corresponding message numbers are -given in the following table. Messages with _MSG_ in their name may -be sent by either side. Messages with _CMSG_ are only sent by the -client, and messages with _SMSG_ only by the server. - -A packet may contain additional data after the arguments specified -below. Any such data should be ignored by the receiver. However, it -is recommended that no such data be stored without good reason. (This -helps build compatible extensions.) -.IP "0 SSH_MSG_NONE" -This code is reserved. This message type is never sent. -.IP "1 SSH_MSG_DISCONNECT" -.TS -; -l l. -string Cause of disconnection -.TE -This message may be sent by either party at any time. It causes the -immediate disconnection of the connection. The message is intended to -be displayed to a human, and describes the reason for disconnection. -.IP "2 SSH_SMSG_PUBLIC_KEY" -.TS -; -l l. -8 bytes anti_spoofing_cookie -32-bit int server_key_bits -mp-int server_key_public_exponent -mp-int server_key_public_modulus -32-bit int host_key_bits -mp-int host_key_public_exponent -mp-int host_key_public_modulus -32-bit int protocol_flags -32-bit int supported_ciphers_mask -32-bit int supported_authentications_mask -.TE -Sent as the first message by the server. This message gives the -server's host key, server key, protocol flags (intended for compatible -protocol extension), supported_ciphers_mask (which is the -bitwise or of (1 << cipher_number), where << is the left shift -operator, for all supported ciphers), and -supported_authentications_mask (which is the bitwise or of (1 << -authentication_type) for all supported authentication types). The -anti_spoofing_cookie is 64 random bytes, and must be sent back -verbatim by the client in its reply. It is used to make IP-spoofing -more difficult (encryption and host keys are the real defense against -spoofing). -.IP "3 SSH_CMSG_SESSION_KEY" -.TS -; -l l. -1 byte cipher_type (must be one of the supported values) -8 bytes anti_spoofing_cookie (must match data sent by the server) -mp-int double-encrypted session key -32-bit int protocol_flags -.TE -Sent by the client as the first message in the session. Selects the -cipher to use, and sends the encrypted session key to the server. The -anti_spoofing_cookie must be the same bytes that were sent by the -server. Protocol_flags is intended for negotiating compatible -protocol extensions. -.IP "4 SSH_CMSG_USER" -.TS -; -l l. -string user login name on server -.TE -Sent by the client to begin authentication. Specifies the user name -on the server to log in as. The server responds with SSH_SMSG_SUCCESS -if no authentication is needed for this user, or SSH_SMSG_FAILURE if -authentication is needed (or the user does not exist). [Note to the -implementator: the user name is of arbitrary size. The implementation -must be careful not to overflow internal buffers.] -.IP "5 SSH_CMSG_AUTH_RHOSTS" -.TS -; -l l. -string client-side user name -.TE -Requests authentication using /etc/hosts.equiv and .rhosts (or -equivalent mechanisms). This authentication method is normally -disabled in the server because it is not secure (but this is the -method used by rsh and rlogin). The server responds with -SSH_SMSG_SUCCESS if authentication was successful, and -SSH_SMSG_FAILURE if access was not granted. The server should check -that the client side port number is less than 1024 (a privileged -port), and immediately reject authentication if it is not. Supporting -this authentication method is optional. This method should normally -not be enabled in the server because it is not safe. (However, not -enabling this only helps if rlogind and rshd are disabled.) -.IP "6 SSH_CMSG_AUTH_RSA" -.TS -; -l l. -mp-int identity_public_modulus -.TE -Requests authentication using pure RSA authentication. The server -checks if the given key is permitted to log in, and if so, responds -with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with -SSH_SMSG_FAILURE. The client often tries several different keys in -sequence until one supported by the server is found. Authentication -is accepted if the client gives the correct response to the challenge. -The server is free to add other criteria for authentication, such as a -requirement that the connection must come from a certain host. Such -additions are not visible at the protocol level. Supporting this -authentication method is optional but recommended. -.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE" -.TS -; -l l. -mp-int encrypted challenge -.TE -Presents an RSA authentication challenge to the client. The challenge -is a 256-bit random value encrypted as described elsewhere in this -document. The client must decrypt the challenge using the RSA private -key, compute MD5 of the challenge plus session id, and send back the -resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE. -.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE" -.TS -; -l l. -16 bytes MD5 of decrypted challenge -.TE -This message is sent by the client in response to an RSA challenge. -The MD5 checksum is returned instead of the decrypted challenge to -deter known-plaintext attacks against the RSA key. The server -responds to this message with either SSH_SMSG_SUCCESS or -SSH_SMSG_FAILURE. -.IP "9 SSH_CMSG_AUTH_PASSWORD" -.TS -; -l l. -string plain text password -.TE -Requests password authentication using the given password. Note that -even though the password is plain text inside the packet, the whole -packet is normally encrypted by the packet layer. It would not be -possible for the client to perform password encryption/hashing, -because it cannot know which kind of encryption/hashing, if any, the -server uses. The server responds to this message with -SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE. -.IP "10 SSH_CMSG_REQUEST_PTY" -.TS -; -l l. -string TERM environment variable value (e.g. vt100) -32-bit int terminal height, rows (e.g., 24) -32-bit int terminal width, columns (e.g., 80) -32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) -32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) -n bytes tty modes encoded in binary -.TE -Requests a pseudo-terminal to be allocated for this command. This -message can be used regardless of whether the session will later -execute the shell or a command. If a pty has been requested with this -message, the shell or command will run on a pty. Otherwise it will -communicate with the server using pipes, sockets or some other similar -mechanism. - -The terminal type gives the type of the user's terminal. In the UNIX -environment it is passed to the shell or command in the TERM -environment variable. - -The width and height values give the initial size of the user's -terminal or window. All values can be zero if not supported by the -operating system. The server will pass these values to the kernel if -supported. - -Terminal modes are encoded into a byte stream in a portable format. -The exact format is described later in this document. - -The server responds to the request with either SSH_SMSG_SUCCESS or -SSH_SMSG_FAILURE. If the server does not have the concept of pseudo -terminals, it should return success if it is possible to execute a -shell or a command so that it looks to the client as if it was running -on a pseudo terminal. -.IP "11 SSH_CMSG_WINDOW_SIZE" -.TS -; -l l. -32-bit int terminal height, rows -32-bit int terminal width, columns -32-bit int terminal width, pixels -32-bit int terminal height, pixels -.TE -This message can only be sent by the client during the interactive -session. This indicates that the size of the user's window has -changed, and provides the new size. The server will update the -kernel's notion of the window size, and a SIGWINCH signal or -equivalent will be sent to the shell or command (if supported by the -operating system). -.IP "12 SSH_CMSG_EXEC_SHELL" - -(no arguments) - -Starts a shell (command interpreter), and enters interactive session -mode. -.IP "13 SSH_CMSG_EXEC_CMD" -.TS -; -l l. -string command to execute -.TE -Starts executing the given command, and enters interactive session -mode. On UNIX, the command is run as "<shell> -c <command>", where -<shell> is the user's login shell. -.IP "14 SSH_SMSG_SUCCESS" - -(no arguments) - -This message is sent by the server in response to the session key, a -successful authentication request, and a successfully completed -preparatory operation. -.IP "15 SSH_SMSG_FAILURE" - -(no arguments) - -This message is sent by the server in response to a failed -authentication operation to indicate that the user has not yet been -successfully authenticated, and in response to a failed preparatory -operation. This is also sent in response to an authentication or -preparatory operation request that is not recognized or supported. -.IP "16 SSH_CMSG_STDIN_DATA" -.TS -; -l l. -string data -.TE -Delivers data from the client to be supplied as input to the shell or -program running on the server side. This message can only be used in -the interactive session mode. No acknowledgement is sent for this -message. -.IP "17 SSH_SMSG_STDOUT_DATA" -.TS -; -l l. -string data -.TE -Delivers data from the server that was read from the standard output of -the shell or program running on the server side. This message can -only be used in the interactive session mode. No acknowledgement is -sent for this message. -.IP "18 SSH_SMSG_STDERR_DATA" -.TS -; -l l. -string data -.TE -Delivers data from the server that was read from the standard error of -the shell or program running on the server side. This message can -only be used in the interactive session mode. No acknowledgement is -sent for this message. -.IP "19 SSH_CMSG_EOF" - -(no arguments) - -This message is sent by the client to indicate that EOF has been -reached on the input. Upon receiving this message, and after all -buffered input data has been sent to the shell or program, the server -will close the input file descriptor to the program. This message can -only be used in the interactive session mode. No acknowledgement is -sent for this message. -.IP "20 SSH_SMSG_EXITSTATUS" -.TS -; -l l. -32-bit int exit status of the command -.TE -Returns the exit status of the shell or program after it has exited. -The client should respond with SSH_CMSG_EXIT_CONFIRMATION when it has -received this message. This will be the last message sent by the -server. If the program being executed dies with a signal instead of -exiting normally, the server should terminate the session with -SSH_MSG_DISCONNECT (which can be used to pass a human-readable string -indicating that the program died due to a signal) instead of using -this message. -.IP "21 SSH_MSG_CHANNEL_OPEN_CONFIRMATION" -.TS -; -l l. -32-bit int remote_channel -32-bit int local_channel -.TE -This is sent in response to any channel open request if the channel -has been successfully opened. Remote_channel is the channel number -received in the initial open request; local_channel is the channel -number the side sending this message has allocated for the channel. -Data can be transmitted on the channel after this message. -.IP "22 SSH_MSG_CHANNEL_OPEN_FAILURE" -.TS -; -l l. -32-bit int remote_channel -.TE -This message indicates that an earlier channel open request by the -other side has failed or has been denied. Remote_channel is the -channel number given in the original request. -.IP "23 SSH_MSG_CHANNEL_DATA" -.TS -; -l l. -32-bit int remote_channel -string data -.TE -Data is transmitted in a channel in these messages. A channel is -bidirectional, and both sides can send these messages. There is no -acknowledgement for these messages. It is possible that either side -receives these messages after it has sent SSH_MSG_CHANNEL_CLOSE for -the channel. These messages cannot be received after the party has -sent or received SSH_MSG_CHANNEL_CLOSE_CONFIRMATION. -.IP "24 SSH_MSG_CHANNEL_CLOSE" -.TS -; -l l. -32-bit int remote_channel -.TE -When a channel is closed at one end of the connection, that side sends -this message. Upon receiving this message, the channel should be -closed. When this message is received, if the channel is already -closed (the receiving side has sent this message for the same channel -earlier), the channel is freed and no further action is taken; -otherwise the channel is freed and SSH_MSG_CHANNEL_CLOSE_CONFIRMATION -is sent in response. (It is possible that the channel is closed -simultaneously at both ends.) -.IP "25 SSH_MSG_CHANNEL_CLOSE_CONFIRMATION" -.TS -; -l l. -32-bit int remote_channel -.TE -This message is sent in response to SSH_MSG_CHANNEL_CLOSE unless the -channel was already closed. When this message is sent or received, -the channel is freed. -.IP "26 (OBSOLETED; was unix-domain X11 forwarding) -.IP "27 SSH_SMSG_X11_OPEN" -.TS -; -l l. -32-bit int local_channel -string originator_string (see below) -.TE -This message can be sent by the server during the interactive session -mode to indicate that a client has connected the fake X server. -Local_channel is the channel number that the server has allocated for -the connection. The client should try to open a connection to the -real X server, and respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or -SSH_MSG_CHANNEL_OPEN_FAILURE. - -The field originator_string is present if both sides -specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It -contains a description of the host originating the connection. -.IP "28 SSH_CMSG_PORT_FORWARD_REQUEST" -.TS -; -l l. -32-bit int server_port -string host_to_connect -32-bit int port_to_connect -.TE -Sent by the client in the preparatory phase, this message requests -that server_port on the server machine be forwarded over the secure -channel to the client machine, and from there to the specified host -and port. The server should start listening on the port, and send -SSH_MSG_PORT_OPEN whenever a connection is made to it. Supporting -this message is optional, and the server is free to reject any forward -request. For example, it is highly recommended that unless the user -has been authenticated as root, forwarding any privileged port numbers -(below 1024) is denied. -.IP "29 SSH_MSG_PORT_OPEN" -.TS -; -l l. -32-bit int local_channel -string host_name -32-bit int port -string originator_string (see below) -.TE -Sent by either party in interactive session mode, this message -indicates that a connection has been opened to a forwarded TCP/IP -port. Local_channel is the channel number that the sending party has -allocated for the connection. Host_name is the host the connection -should be be forwarded to, and the port is the port on that host to -connect. The receiving party should open the connection, and respond -with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or -SSH_MSG_CHANNEL_OPEN_FAILURE. It is recommended that the receiving -side check the host_name and port for validity to avoid compromising -local security by compromised remote side software. Particularly, it -is recommended that the client permit connections only to those ports -for which it has requested forwarding with SSH_CMSG_PORT_FORWARD_REQUEST. - -The field originator_string is present if both sides -specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It -contains a description of the host originating the connection. -.IP "30 SSH_CMSG_AGENT_REQUEST_FORWARDING" - -(no arguments) - -Requests that the connection to the authentication agent be forwarded -over the secure channel. The method used by clients to contact the -authentication agent within each machine is implementation and machine -dependent. If the server accepts this request, it should arrange that -any clients run from this session will actually contact the server -program when they try to contact the authentication agent. The server -should then send a SSH_SMSG_AGENT_OPEN to open a channel to the agent, -and the client should forward the connection to the real -authentication agent. Supporting this message is optional. -.IP "31 SSH_SMSG_AGENT_OPEN" -.TS -; -l l. -32-bit int local_channel -.TE -Sent by the server in interactive session mode, this message requests -opening a channel to the authentication agent. The client should open -a channel, and respond with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION -or SSH_MSG_CHANNEL_OPEN_FAILURE. -.IP "32 SSH_MSG_IGNORE" -.TS -; -l l. -string data -.TE -Either party may send this message at any time. This message, and the -argument string, is silently ignored. This message might be used in -some implementations to make traffic analysis more difficult. This -message is not currently sent by the implementation, but all -implementations are required to recognize and ignore it. -.IP "33 SSH_CMSG_EXIT_CONFIRMATION" - -(no arguments) - -Sent by the client in response to SSH_SMSG_EXITSTATUS. This is the -last message sent by the client. -.IP "34 SSH_CMSG_X11_REQUEST_FORWARDING" -.TS -; -l l. -string x11_authentication_protocol -string x11_authentication_data -32-bit int screen number (if SSH_PROTOFLAG_SCREEN_NUMBER) -.TE -Sent by the client during the preparatory phase, this message requests -that the server create a fake X11 display and set the DISPLAY -environment variable accordingly. An internet-domain display is -preferable. The given authentication protocol and the associated data -should be recorded by the server so that it is used as authentication -on connections (e.g., in .Xauthority). The authentication protocol -must be one of the supported X11 authentication protocols, e.g., -"MIT-MAGIC-COOKIE-1". Authentication data must be a lowercase hex -string of even length. Its interpretation is protocol dependent. -The data is in a format that can be used with e.g. the xauth program. -Supporting this message is optional. - -The client is permitted (and recommended) to generate fake -authentication information and send fake information to the server. -This way, a corrupt server will not have access to the user's terminal -after the connection has terminated. The correct authorization codes -will also not be left hanging around in files on the server (many -users keep the same X session for months, thus protecting the -authorization data becomes important). - -X11 authentication spoofing works by initially sending fake (random) -authentication data to the server, and interpreting the first packet -sent by the X11 client after the connection has been opened. The -first packet contains the client's authentication. If the packet -contains the correct fake data, it is replaced by the client by the -correct authentication data, and then sent to the X server. -.IP "35 SSH_CMSG_AUTH_RHOSTS_RSA" -.TS -; -l l. -string clint-side user name -32-bit int client_host_key_bits -mp-int client_host_key_public_exponent -mp-int client_host_key_public_modulus -.TE -Requests authentication using /etc/hosts.equiv and .rhosts (or -equivalent) together with RSA host authentication. The server should -check that the client side port number is less than 1024 (a privileged -port), and immediately reject authentication if it is not. The server -responds with SSH_SMSG_FAILURE or SSH_SMSG_AUTH_RSA_CHALLENGE. The -client must respond to the challenge with the proper -SSH_CMSG_AUTH_RSA_RESPONSE. The server then responds with success if -access was granted, or failure if the client gave a wrong response. -Supporting this authentication method is optional but recommended in -most environments. -.IP "36 SSH_MSG_DEBUG" -.TS -; -l l. -string debugging message sent to the other side -.TE -This message may be sent by either party at any time. It is used to -send debugging messages that may be informative to the user in -solving various problems. For example, if authentication fails -because of some configuration error (e.g., incorrect permissions for -some file), it can be very helpful for the user to make the cause of -failure available. On the other hand, one should not make too much -information available for security reasons. It is recommended that -the client provides an option to display the debugging information -sent by the sender (the user probably does not want to see it by default). -The server can log debugging data sent by the client (if any). Either -party is free to ignore any received debugging data. Every -implementation must be able to receive this message, but no -implementation is required to send these. -.IP "37 SSH_CMSG_REQUEST_COMPRESSION" -.TS -; -l l. -32-bit int gzip compression level (1-9) -.TE -This message can be sent by the client in the preparatory operations -phase. The server responds with SSH_SMSG_FAILURE if it does not -support compression or does not want to compress; it responds with -SSH_SMSG_SUCCESS if it accepted the compression request. In the -latter case the response to this packet will still be uncompressed, -but all further packets in either direction will be compressed by gzip. -.RT - - -.ti 0 -Encoding of Terminal Modes - -Terminal modes (as passed in SSH_CMSG_REQUEST_PTY) are encoded into a -byte stream. It is intended that the coding be portable across -different environments. - -The tty mode description is a stream of bytes. The stream consists of -opcode-argument pairs. It is terminated by opcode TTY_OP_END (0). -Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have 32-bit -integer arguments (stored msb first). Opcodes 160-255 are not yet -defined, and cause parsing to stop (they should only be used after any -other data). - -The client puts in the stream any modes it knows about, and the server -ignores any modes it does not know about. This allows some degree of -machine-independence, at least between systems that use a POSIX-like -[POSIX] tty interface. The protocol can support other systems as -well, but the client may need to fill reasonable values for a number -of parameters so the server pty gets set to a reasonable mode (the -server leaves all unspecified mode bits in their default values, and -only some combinations make sense). - -The following opcodes have been defined. The naming of opcodes mostly -follows the POSIX terminal mode flags. -.IP "0 TTY_OP_END" -Indicates end of options. -.IP "1 VINTR" -Interrupt character; 255 if none. Similarly for the other characters. -Not all of these characters are supported on all systems. -.IP "2 VQUIT" -The quit character (sends SIGQUIT signal on UNIX systems). -.IP "3 VERASE" -Erase the character to left of the cursor. -.IP "4 VKILL" -Kill the current input line. -.IP "5 VEOF " -End-of-file character (sends EOF from the terminal). -.IP "6 VEOL " -End-of-line character in addition to carriage return and/or linefeed. -.IP "7 VEOL2" -Additional end-of-line character. -.IP "8 VSTART" -Continues paused output (normally ^Q). -.IP "9 VSTOP" -Pauses output (^S). -.IP "10 VSUSP" -Suspends the current program. -.IP "11 VDSUSP" -Another suspend character. -.IP "12 VREPRINT" -Reprints the current input line. -.IP "13 VWERASE" -Erases a word left of cursor. -.IP "14 VLNEXT" -More special input characters; these are probably not supported on -most systems. -.IP "15 VFLUSH" -.IP "16 VSWTCH" -.IP "17 VSTATUS" -.IP "18 VDISCARD" - -.IP "30 IGNPAR" -The ignore parity flag. The next byte should be 0 if this flag is not -set, and 1 if it is set. -.IP "31 PARMRK" -More flags. The exact definitions can be found in the POSIX standard. -.IP "32 INPCK" -.IP "33 ISTRIP" -.IP "34 INLCR" -.IP "35 IGNCR" -.IP "36 ICRNL" -.IP "37 IUCLC" -.IP "38 IXON" -.IP "39 IXANY" -.IP "40 IXOFF" -.IP "41 IMAXBEL" - -.IP "50 ISIG" -.IP "51 ICANON" -.IP "52 XCASE" -.IP "53 ECHO" -.IP "54 ECHOE" -.IP "55 ECHOK" -.IP "56 ECHONL" -.IP "57 NOFLSH" -.IP "58 TOSTOP" -.IP "59 IEXTEN" -.IP "60 ECHOCTL" -.IP "61 ECHOKE" -.IP "62 PENDIN" - -.IP "70 OPOST" -.IP "71 OLCUC" -.IP "72 ONLCR" -.IP "73 OCRNL" -.IP "74 ONOCR" -.IP "75 ONLRET" - -.IP "90 CS7" -.IP "91 CS8" -.IP "92 PARENB" -.IP "93 PARODD" - -.IP "192 TTY_OP_ISPEED" -Specifies the input baud rate in bits per second. -.IP "193 TTY_OP_OSPEED" -Specifies the output baud rate in bits per second. -.RT - - -.ti 0 -The Authentication Agent Protocol - -The authentication agent is a program that can be used to hold RSA -authentication keys for the user (in future, it might hold data for -other authentication types as well). An authorized program can send -requests to the agent to generate a proper response to an RSA -challenge. How the connection is made to the agent (or its -representative) inside a host and how access control is done inside a -host is implementation-dependent; however, how it is forwarded and how -one interacts with it is specified in this protocol. The connection -to the agent is normally automatically forwarded over the secure -channel. - -A program that wishes to use the agent first opens a connection to its -local representative (typically, the agent itself or an SSH server). -It then writes a request to the connection, and waits for response. -It is recommended that at least five minutes of timeout are provided -waiting for the agent to respond to an authentication challenge (this -gives sufficient time for the user to cut-and-paste the challenge to a -separate machine, perform the computation there, and cut-and-paste the -result back if so desired). - -Messages sent to and by the agent are in the following format: -.TS -; -l l. -4 bytes Length, msb first. Does not include length itself. -1 byte Packet type. The value 255 is reserved for future extensions. -data Any data, depending on packet type. Encoding as in the ssh packet -protocol. -.TE - -The following message types are currently defined: -.IP "1 SSH_AGENTC_REQUEST_RSA_IDENTITIES" - -(no arguments) - -Requests the agent to send a list of all RSA keys for which it can -answer a challenge. -.IP "2 SSH_AGENT_RSA_IDENTITIES_ANSWER" -.TS -; -l l. -32-bit int howmany -howmany times: -32-bit int bits -mp-int public exponent -mp-int public modulus -string comment -.TE -The agent sends this message in response to the to -SSH_AGENTC_REQUEST_RSA_IDENTITIES. The answer lists all RSA keys for -which the agent can answer a challenge. The comment field is intended -to help identify each key; it may be printed by an application to -indicate which key is being used. If the agent is not holding any -keys, howmany will be zero. -.IP "3 SSH_AGENTC_RSA_CHALLENGE -.TS -; -l l. -32-bit int bits -mp-int public exponent -mp-int public modulus -mp-int challenge -16 bytes session_id -32-bit int response_type -.TE -Requests RSA decryption of random challenge to authenticate the other -side. The challenge will be decrypted with the RSA private key -corresponding to the given public key. - -The decrypted challenge must contain a zero in the highest (partial) -byte, 2 in the next byte, followed by non-zero random bytes, a zero -byte, and then the real challenge value in the lowermost bytes. The -real challenge must be 32 8-bit bytes (256 bits). - -Response_type indicates the format of the response to be returned. -Currently the only supported value is 1, which means to compute MD5 of -the real challenge plus session id, and return the resulting 16 bytes -in a SSH_AGENT_RSA_RESPONSE message. -.IP "4 SSH_AGENT_RSA_RESPONSE" -.TS -; -l l. -16 bytes MD5 of decrypted challenge -.TE -Answers an RSA authentication challenge. The response is 16 bytes: -the MD5 checksum of the 32-byte challenge. -.IP "5 SSH_AGENT_FAILURE" - -(no arguments) - -This message is sent whenever the agent fails to answer a request -properly. For example, if the agent cannot answer a challenge (e.g., -no longer has the proper key), it can respond with this. The agent -also responds with this message if it receives a message it does not -recognize. -.IP "6 SSH_AGENT_SUCCESS" - -(no arguments) - -This message is sent by the agent as a response to certain requests -that do not otherwise cause a message be sent. Currently, this is -only sent in response to SSH_AGENTC_ADD_RSA_IDENTITY and -SSH_AGENTC_REMOVE_RSA_IDENTITY. -.IP "7 SSH_AGENTC_ADD_RSA_IDENTITY" -.TS -; -l l. -32-bit int bits -mp-int public modulus -mp-int public exponent -mp-int private exponent -mp-int multiplicative inverse of p mod q -mp-int p -mp-int q -string comment -.TE -Registers an RSA key with the agent. After this request, the agent can -use this RSA key to answer requests. The agent responds with -SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. -.IP "8 SSH_AGENT_REMOVE_RSA_IDENTITY" -.TS -; -l l. -32-bit int bits -mp-int public exponent -mp-int public modulus -.TE -Removes an RSA key from the agent. The agent will no longer accept -challenges for this key and will not list it as a supported identity. -The agent responds with SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. -.RT - -If the agent receives a message that it does not understand, it -responds with SSH_AGENT_FAILURE. This permits compatible future -extensions. - -It is possible that several clients have a connection open to the -authentication agent simultaneously. Each client will use a separate -connection (thus, any SSH connection can have multiple agent -connections active simultaneously). - - -.ti 0 -References - -.IP "[DES] " -FIPS PUB 46-1: Data Encryption Standard. National Bureau of -Standards, January 1988. FIPS PUB 81: DES Modes of Operation. -National Bureau of Standards, December 1980. Bruce Schneier: Applied -Cryptography. John Wiley & Sons, 1994. J. Seberry and J. Pieprzyk: -Cryptography: An Introduction to Computer Security. Prentice-Hall, -1989. -.IP "[GZIP] " -The GNU GZIP program; available for anonymous ftp at prep.ai.mit.edu. -Please let me know if you know a paper describing the algorithm. -.IP "[IDEA] " -Xuejia Lai: On the Design and Security of Block Ciphers, ETH Series in -Information Processing, vol. 1, Hartung-Gorre Verlag, Konstanz, -Switzerland, 1992. Bruce Schneier: Applied Cryptography, John Wiley & -Sons, 1994. See also the following patents: PCT/CH91/00117, EP 0 482 -154 B1, US Pat. 5,214,703. -.IP [PKCS#1] -PKCS #1: RSA Encryption Standard. Version 1.5, RSA Laboratories, -November 1993. Available for anonymous ftp at ftp.rsa.com. -.IP [POSIX] -Portable Operating System Interface (POSIX) - Part 1: Application -Program Interface (API) [C language], ISO/IEC 9945-1, IEEE Std 1003.1, -1990. -.IP [RFC0791] -J. Postel: Internet Protocol, RFC 791, USC/ISI, September 1981. -.IP [RFC0793] -J. Postel: Transmission Control Protocol, RFC 793, USC/ISI, September -1981. -.IP [RFC1034] -P. Mockapetris: Domain Names - Concepts and Facilities, RFC 1034, -USC/ISI, November 1987. -.IP [RFC1282] -B. Kantor: BSD Rlogin, RFC 1258, UCSD, December 1991. -.IP "[RSA] " -Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. See -also R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic -Communications System and Method. US Patent 4,405,829, 1983. -.IP "[X11] " -R. Scheifler: X Window System Protocol, X Consortium Standard, Version -11, Release 6. Massachusetts Institute of Technology, Laboratory of -Computer Science, 1994. -.RT - - -.ti 0 -Security Considerations - -This protocol deals with the very issue of user authentication and -security. - -First of all, as an implementation issue, the server program will have -to run as root (or equivalent) on the server machine. This is because -the server program will need be able to change to an arbitrary user -id. The server must also be able to create a privileged TCP/IP port. - -The client program will need to run as root if any variant of .rhosts -authentication is to be used. This is because the client program will -need to create a privileged port. The client host key is also usually -stored in a file which is readable by root only. The client needs the -host key in .rhosts authentication only. Root privileges can be -dropped as soon as the privileged port has been created and the host -key has been read. - -The SSH protocol offers major security advantages over existing telnet -and rlogin protocols. -.IP o -IP spoofing is restricted to closing a connection (by encryption, host -keys, and the special random cookie). If encryption is not used, IP -spoofing is possible for those who can hear packets going out from the -server. -.IP o -DNS spoofing is made ineffective (by host keys). -.IP o -Routing spoofing is made ineffective (by host keys). -.IP o -All data is encrypted with strong algorithms to make eavesdropping as -difficult as possible. This includes encrypting any authentication -information such as passwords. The information for decrypting session -keys is destroyed every hour. -.IP o -Strong authentication methods: .rhosts combined with RSA host -authentication, and pure RSA authentication. -.IP o -X11 connections and arbitrary TCP/IP ports can be forwarded securely. -.IP o -Man-in-the-middle attacks are deterred by using the server host key to -encrypt the session key. -.IP o -Trojan horses to catch a password by routing manipulation are deterred -by checking that the host key of the server machine matches that -stored on the client host. -.RT - -The security of SSH against man-in-the-middle attacks and the security -of the new form of .rhosts authentication, as well as server host -validation, depends on the integrity of the host key and the files -containing known host keys. - -The host key is normally stored in a root-readable file. If the host -key is compromised, it permits attackers to use IP, DNS and routing -spoofing as with current rlogin and rsh. It should never be any worse -than the current situation. - -The files containing known host keys are not sensitive. However, if an -attacker gets to modify the known host key files, it has the same -consequences as a compromised host key, because the attacker can then -change the recorded host key. - -The security improvements obtained by this protocol for X11 are of -particular significance. Previously, there has been no way to protect -data communicated between an X server and a client running on a remote -machine. By creating a fake display on the server, and forwarding all -X11 requests over the secure channel, SSH can be used to run any X11 -applications securely without any cooperation with the vendors of the -X server or the application. - -Finally, the security of this program relies on the strength of the -underlying cryptographic algorithms. The RSA algorithm is used for -authentication key exchange. It is widely believed to be secure. Of -the algorithms used to encrypt the session, DES has a rather small key -these days, probably permitting governments and organized criminals to -break it in very short time with specialized hardware. 3DES is -probably safe (but slower). IDEA is widely believed to be secure. -People have varying degrees of confidence in the other algorithms. -This program is not secure if used with no encryption at all. - - -.ti 0 -Additional Information - -Additional information (especially on the implementation and mailing -lists) is available via WWW at http://www.cs.hut.fi/ssh. - -Comments should be sent to Tatu Ylonen <ylo@cs.hut.fi> or the SSH -Mailing List <ssh@clinet.fi>. - -.ti 0 -Author's Address - -.TS -; -l. -Tatu Ylonen -Helsinki University of Technology -Otakaari 1 -FIN-02150 Espoo, Finland - -Phone: +358-0-451-3374 -Fax: +358-0-451-3293 -EMail: ylo@cs.hut.fi -.TE diff --git a/crypto/openssh/addrmatch.c b/crypto/openssh/addrmatch.c new file mode 100644 index 0000000..2086afe --- /dev/null +++ b/crypto/openssh/addrmatch.c @@ -0,0 +1,421 @@ +/* $OpenBSD: addrmatch.c,v 1.3 2008/06/10 23:06:19 djm Exp $ */ + +/* + * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + +#include "match.h" +#include "log.h" + +struct xaddr { + sa_family_t af; + union { + struct in_addr v4; + struct in6_addr v6; + u_int8_t addr8[16]; + u_int32_t addr32[4]; + } xa; /* 128-bit address */ + u_int32_t scope_id; /* iface scope id for v6 */ +#define v4 xa.v4 +#define v6 xa.v6 +#define addr8 xa.addr8 +#define addr32 xa.addr32 +}; + +static int +addr_unicast_masklen(int af) +{ + switch (af) { + case AF_INET: + return 32; + case AF_INET6: + return 128; + default: + return -1; + } +} + +static inline int +masklen_valid(int af, u_int masklen) +{ + switch (af) { + case AF_INET: + return masklen <= 32 ? 0 : -1; + case AF_INET6: + return masklen <= 128 ? 0 : -1; + default: + return -1; + } +} + +/* + * Convert struct sockaddr to struct xaddr + * Returns 0 on success, -1 on failure. + */ +static int +addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) +{ + struct sockaddr_in *in4 = (struct sockaddr_in *)sa; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; + + memset(xa, '\0', sizeof(*xa)); + + switch (sa->sa_family) { + case AF_INET: + if (slen < sizeof(*in4)) + return -1; + xa->af = AF_INET; + memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4)); + break; + case AF_INET6: + if (slen < sizeof(*in6)) + return -1; + xa->af = AF_INET6; + memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); + xa->scope_id = in6->sin6_scope_id; + break; + default: + return -1; + } + + return 0; +} + +/* + * Calculate a netmask of length 'l' for address family 'af' and + * store it in 'n'. + * Returns 0 on success, -1 on failure. + */ +static int +addr_netmask(int af, u_int l, struct xaddr *n) +{ + int i; + + if (masklen_valid(af, l) != 0 || n == NULL) + return -1; + + memset(n, '\0', sizeof(*n)); + switch (af) { + case AF_INET: + n->af = AF_INET; + n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff); + return 0; + case AF_INET6: + n->af = AF_INET6; + for (i = 0; i < 4 && l >= 32; i++, l -= 32) + n->addr32[i] = 0xffffffffU; + if (i < 4 && l != 0) + n->addr32[i] = htonl((0xffffffff << (32 - l)) & + 0xffffffff); + return 0; + default: + return -1; + } +} + +/* + * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'. + * Returns 0 on success, -1 on failure. + */ +static int +addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) +{ + int i; + + if (dst == NULL || a == NULL || b == NULL || a->af != b->af) + return -1; + + memcpy(dst, a, sizeof(*dst)); + switch (a->af) { + case AF_INET: + dst->v4.s_addr &= b->v4.s_addr; + return 0; + case AF_INET6: + dst->scope_id = a->scope_id; + for (i = 0; i < 4; i++) + dst->addr32[i] &= b->addr32[i]; + return 0; + default: + return -1; + } +} + +/* + * Compare addresses 'a' and 'b' + * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b) + */ +static int +addr_cmp(const struct xaddr *a, const struct xaddr *b) +{ + int i; + + if (a->af != b->af) + return a->af == AF_INET6 ? 1 : -1; + + switch (a->af) { + case AF_INET: + if (a->v4.s_addr == b->v4.s_addr) + return 0; + return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1; + case AF_INET6: + for (i = 0; i < 16; i++) + if (a->addr8[i] - b->addr8[i] != 0) + return a->addr8[i] > b->addr8[i] ? 1 : -1; + if (a->scope_id == b->scope_id) + return 0; + return a->scope_id > b->scope_id ? 1 : -1; + default: + return -1; + } +} + +/* + * Parse string address 'p' into 'n' + * Returns 0 on success, -1 on failure. + */ +static int +addr_pton(const char *p, struct xaddr *n) +{ + struct addrinfo hints, *ai; + + memset(&hints, '\0', sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST; + + if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) + return -1; + + if (ai == NULL || ai->ai_addr == NULL) + return -1; + + if (n != NULL && + addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) { + freeaddrinfo(ai); + return -1; + } + + freeaddrinfo(ai); + return 0; +} + +/* + * Perform bitwise negation of address + * Returns 0 on success, -1 on failure. + */ +static int +addr_invert(struct xaddr *n) +{ + int i; + + if (n == NULL) + return (-1); + + switch (n->af) { + case AF_INET: + n->v4.s_addr = ~n->v4.s_addr; + return (0); + case AF_INET6: + for (i = 0; i < 4; i++) + n->addr32[i] = ~n->addr32[i]; + return (0); + default: + return (-1); + } +} + +/* + * Calculate a netmask of length 'l' for address family 'af' and + * store it in 'n'. + * Returns 0 on success, -1 on failure. + */ +static int +addr_hostmask(int af, u_int l, struct xaddr *n) +{ + if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) + return (-1); + return (0); +} + +/* + * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::) + * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure. + */ +static int +addr_is_all0s(const struct xaddr *a) +{ + int i; + + switch (a->af) { + case AF_INET: + return (a->v4.s_addr == 0 ? 0 : -1); + case AF_INET6:; + for (i = 0; i < 4; i++) + if (a->addr32[i] != 0) + return (-1); + return (0); + default: + return (-1); + } +} + +/* + * Test whether host portion of address 'a', as determined by 'masklen' + * is all zeros. + * Returns 0 on if host portion of address is all-zeros, + * -1 if not all zeros or on failure. + */ +static int +addr_host_is_all0s(const struct xaddr *a, u_int masklen) +{ + struct xaddr tmp_addr, tmp_mask, tmp_result; + + memcpy(&tmp_addr, a, sizeof(tmp_addr)); + if (addr_hostmask(a->af, masklen, &tmp_mask) == -1) + return (-1); + if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1) + return (-1); + return (addr_is_all0s(&tmp_result)); +} + +/* + * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). + * Return -1 on parse error, -2 on inconsistency or 0 on success. + */ +static int +addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) +{ + struct xaddr tmp; + long unsigned int masklen = 999; + char addrbuf[64], *mp, *cp; + + /* Don't modify argument */ + if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) > sizeof(addrbuf)) + return -1; + + if ((mp = strchr(addrbuf, '/')) != NULL) { + *mp = '\0'; + mp++; + masklen = strtoul(mp, &cp, 10); + if (*mp == '\0' || *cp != '\0' || masklen > 128) + return -1; + } + + if (addr_pton(addrbuf, &tmp) == -1) + return -1; + + if (mp == NULL) + masklen = addr_unicast_masklen(tmp.af); + if (masklen_valid(tmp.af, masklen) == -1) + return -2; + if (addr_host_is_all0s(&tmp, masklen) != 0) + return -2; + + if (n != NULL) + memcpy(n, &tmp, sizeof(*n)); + if (l != NULL) + *l = masklen; + + return 0; +} + +static int +addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen) +{ + struct xaddr tmp_mask, tmp_result; + + if (host->af != net->af) + return -1; + + if (addr_netmask(host->af, masklen, &tmp_mask) == -1) + return -1; + if (addr_and(&tmp_result, host, &tmp_mask) == -1) + return -1; + return addr_cmp(&tmp_result, net); +} + +/* + * Match "addr" against list pattern list "_list", which may contain a + * mix of CIDR addresses and old-school wildcards. + * + * If addr is NULL, then no matching is performed, but _list is parsed + * and checked for well-formedness. + * + * Returns 1 on match found (never returned when addr == NULL). + * Returns 0 on if no match found, or no errors found when addr == NULL. + * Returns -1 on negated match found (never returned when addr == NULL). + * Returns -2 on invalid list entry. + */ +int +addr_match_list(const char *addr, const char *_list) +{ + char *list, *cp, *o; + struct xaddr try_addr, match_addr; + u_int masklen, neg; + int ret = 0, r; + + if (addr != NULL && addr_pton(addr, &try_addr) != 0) { + debug2("%s: couldn't parse address %.100s", __func__, addr); + return 0; + } + if ((o = list = strdup(_list)) == NULL) + return -1; + while ((cp = strsep(&list, ",")) != NULL) { + neg = *cp == '!'; + if (neg) + cp++; + if (*cp == '\0') { + ret = -2; + break; + } + /* Prefer CIDR address matching */ + r = addr_pton_cidr(cp, &match_addr, &masklen); + if (r == -2) { + error("Inconsistent mask length for " + "network \"%.100s\"", cp); + ret = -2; + break; + } else if (r == 0) { + if (addr != NULL && addr_netmatch(&try_addr, + &match_addr, masklen) == 0) { + foundit: + if (neg) { + ret = -1; + break; + } + ret = 1; + } + continue; + } else { + /* If CIDR parse failed, try wildcard string match */ + if (addr != NULL && match_pattern(addr, cp) == 1) + goto foundit; + } + } + free(o); + + return ret; +} diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c index f651a29..a6b2d12 100644 --- a/crypto/openssh/atomicio.c +++ b/crypto/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,15 @@ #include <sys/uio.h> #include <errno.h> +#ifdef HAVE_POLL_H +#include <poll.h> +#else +# ifdef HAVE_SYS_POLL_H +# include <sys/poll.h> +# endif +#endif #include <string.h> +#include <unistd.h> #include "atomicio.h" @@ -45,17 +53,20 @@ 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) -#else - if (errno == EINTR || errno == EAGAIN) -#endif + if (errno == EINTR) + continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) { + (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)); +#ifndef BROKEN_READV_COMPARISON + pfd.fd = fd; + pfd.events = f == readv ? POLLIN : POLLOUT; +#endif for (; iovcnt > 0 && iov[0].iov_len > 0;) { res = (f) (fd, iov, iovcnt); switch (res) { case -1: - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR) continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) { +#ifndef BROKEN_READV_COMPARISON + (void)poll(&pfd, 1, -1); +#endif + continue; + } return 0; case 0: errno = EPIPE; diff --git a/crypto/openssh/audit-bsm.c b/crypto/openssh/audit-bsm.c index c26b4ca..2c417bc 100644 --- a/crypto/openssh/audit-bsm.c +++ b/crypto/openssh/audit-bsm.c @@ -1,4 +1,4 @@ -/* $Id: audit-bsm.c,v 1.5 2006/09/30 22:09:50 dtucker Exp $ */ +/* $Id: audit-bsm.c,v 1.6 2008/02/25 10:05:04 dtucker Exp $ */ /* * TODO @@ -40,7 +40,9 @@ #include <sys/types.h> #include <errno.h> +#include <netdb.h> #include <stdarg.h> +#include <string.h> #include <unistd.h> #include "ssh.h" @@ -62,8 +64,6 @@ #if defined(HAVE_GETAUDIT_ADDR) #define AuditInfoStruct auditinfo_addr #define AuditInfoTermID au_tid_addr_t -#define GetAuditFunc(a,b) getaudit_addr((a),(b)) -#define GetAuditFuncText "getaudit_addr" #define SetAuditFunc(a,b) setaudit_addr((a),(b)) #define SetAuditFuncText "setaudit_addr" #define AUToSubjectFunc au_to_subject_ex @@ -71,18 +71,16 @@ #else #define AuditInfoStruct auditinfo #define AuditInfoTermID au_tid_t -#define GetAuditFunc(a,b) getaudit(a) -#define GetAuditFuncText "getaudit" #define SetAuditFunc(a,b) setaudit(a) #define SetAuditFuncText "setaudit" #define AUToSubjectFunc au_to_subject #define AUToReturnFunc(a,b) au_to_return((a), (u_int)(b)) #endif +#ifndef cannot_audit extern int cannot_audit(int); +#endif extern void aug_init(void); -extern dev_t aug_get_port(void); -extern int aug_get_machine(char *, u_int32_t *, u_int32_t *); extern void aug_save_auid(au_id_t); extern void aug_save_uid(uid_t); extern void aug_save_euid(uid_t); @@ -119,6 +117,51 @@ static AuditInfoTermID ssh_bsm_tid; /* Below is the low-level BSM interface code */ /* + * aug_get_machine is only required on IPv6 capable machines, we use a + * different mechanism in audit_connection_from() for IPv4-only machines. + * getaudit_addr() is only present on IPv6 capable machines. + */ +#if defined(HAVE_AUG_GET_MACHINE) || !defined(HAVE_GETAUDIT_ADDR) +extern int aug_get_machine(char *, u_int32_t *, u_int32_t *); +#else +static int +aug_get_machine(char *host, u_int32_t *addr, u_int32_t *type) +{ + struct addrinfo *ai; + struct sockaddr_in *in4; + struct sockaddr_in6 *in6; + int ret = 0, r; + + if ((r = getaddrinfo(host, NULL, NULL, &ai)) != 0) { + error("BSM audit: getaddrinfo failed for %.100s: %.100s", host, + r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); + return -1; + } + + switch (ai->ai_family) { + case AF_INET: + in4 = (struct sockaddr_in *)ai->ai_addr; + *type = AU_IPv4; + memcpy(addr, &in4->sin_addr, sizeof(struct in_addr)); + break; +#ifdef AU_IPv6 + case AF_INET6: + in6 = (struct sockaddr_in6 *)ai->ai_addr; + *type = AU_IPv6; + memcpy(addr, &in6->sin6_addr, sizeof(struct in6_addr)); + break; +#endif + default: + error("BSM audit: unknown address family for %.100s: %d", + host, ai->ai_family); + ret = -1; + } + freeaddrinfo(ai); + return ret; +} +#endif + +/* * Check if the specified event is selected (enabled) for auditing. * Returns 1 if the event is selected, 0 if not and -1 on failure. */ diff --git a/crypto/openssh/auth-bsdauth.c b/crypto/openssh/auth-bsdauth.c index 37d527d..0b3262b 100644 --- a/crypto/openssh/auth-bsdauth.c +++ b/crypto/openssh/auth-bsdauth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-bsdauth.c,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth-bsdauth.c,v 1.11 2007/09/21 08:15:29 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c index ca5e1c9..2536145 100644 --- a/crypto/openssh/auth-options.c +++ b/crypto/openssh/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -20,6 +20,7 @@ #include <stdio.h> #include <stdarg.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "match.h" #include "log.h" @@ -42,6 +43,7 @@ int no_port_forwarding_flag = 0; int no_agent_forwarding_flag = 0; int no_x11_forwarding_flag = 0; int no_pty_flag = 0; +int no_user_rc = 0; /* "command=" option. */ char *forced_command = NULL; @@ -61,6 +63,7 @@ auth_clear_options(void) no_port_forwarding_flag = 0; no_pty_flag = 0; no_x11_forwarding_flag = 0; + no_user_rc = 0; while (custom_environment) { struct envstring *ce = custom_environment; custom_environment = ce->next; @@ -121,6 +124,13 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) opts += strlen(cp); goto next_option; } + cp = "no-user-rc"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + auth_debug_add("User rc file execution disabled."); + no_user_rc = 1; + opts += strlen(cp); + goto next_option; + } cp = "command=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { opts += strlen(cp); @@ -216,8 +226,19 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) } patterns[i] = '\0'; opts++; - if (match_host_and_ip(remote_host, remote_ip, - patterns) != 1) { + switch (match_host_and_ip(remote_host, remote_ip, + patterns)) { + case 1: + xfree(patterns); + /* Host name matches. */ + goto next_option; + case -1: + debug("%.100s, line %lu: invalid criteria", + file, linenum); + auth_debug_add("%.100s, line %lu: " + "invalid criteria", file, linenum); + /* FALLTHROUGH */ + case 0: xfree(patterns); logit("Authentication tried for %.100s with " "correct key but not from a permitted " @@ -226,12 +247,10 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) auth_debug_add("Your host '%.200s' is not " "permitted to use this key for login.", remote_host); - /* deny access */ - return 0; + break; } - xfree(patterns); - /* Host name matches. */ - goto next_option; + /* deny access */ + return 0; } cp = "permitopen=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h index 853f8b5..14488f7 100644 --- a/crypto/openssh/auth-options.h +++ b/crypto/openssh/auth-options.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.h,v 1.16 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth-options.h,v 1.17 2008/03/26 21:28:14 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -26,6 +26,7 @@ extern int no_port_forwarding_flag; extern int no_agent_forwarding_flag; extern int no_x11_forwarding_flag; extern int no_pty_flag; +extern int no_user_rc; extern char *forced_command; extern struct envstring *custom_environment; extern int forced_tun_device; diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c index c08d472..ccdb993 100644 --- a/crypto/openssh/auth-pam.c +++ b/crypto/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 */ @@ -598,15 +598,17 @@ static struct pam_conv store_conv = { sshpam_store_conv, NULL }; void sshpam_cleanup(void) { - debug("PAM: cleanup"); - if (sshpam_handle == NULL) + if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor())) return; + debug("PAM: cleanup"); pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); if (sshpam_cred_established) { + debug("PAM: deleting credentials"); pam_setcred(sshpam_handle, PAM_DELETE_CRED); sshpam_cred_established = 0; } if (sshpam_session_open) { + debug("PAM: closing session"); pam_close_session(sshpam_handle, PAM_SILENT); sshpam_session_open = 0; } @@ -686,8 +688,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 +986,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 +1132,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/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c index be62837..bdfced0 100644 --- a/crypto/openssh/auth-passwd.c +++ b/crypto/openssh/auth-passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-passwd.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth-passwd.c,v 1.43 2007/09/21 08:15:29 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c index cd0a796..5c12967 100644 --- a/crypto/openssh/auth-rhosts.c +++ b/crypto/openssh/auth-rhosts.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rhosts.c,v 1.41 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth-rhosts.c,v 1.43 2008/06/13 14:18:51 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -26,6 +26,8 @@ #include <stdio.h> #include <string.h> #include <stdarg.h> +#include <fcntl.h> +#include <unistd.h> #include "packet.h" #include "buffer.h" @@ -37,6 +39,7 @@ #include "key.h" #include "hostfile.h" #include "auth.h" +#include "misc.h" /* import */ extern ServerOptions options; @@ -55,12 +58,27 @@ check_rhosts_file(const char *filename, const char *hostname, { FILE *f; char buf[1024]; /* Must not be larger than host, user, dummy below. */ + int fd; + struct stat st; /* Open the .rhosts file, deny if unreadable */ - f = fopen(filename, "r"); - if (!f) + if ((fd = open(filename, O_RDONLY|O_NONBLOCK)) == -1) return 0; - + if (fstat(fd, &st) == -1) { + close(fd); + return 0; + } + if (!S_ISREG(st.st_mode)) { + logit("User %s hosts file %s is not a regular file", + server_user, filename); + close(fd); + return 0; + } + unset_nonblock(fd); + if ((f = fdopen(fd, "r")) == NULL) { + close(fd); + return 0; + } while (fgets(buf, sizeof(buf), f)) { /* All three must be at least as big as buf to avoid overflows. */ char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c index 69f9a58..bf54620 100644 --- a/crypto/openssh/auth-rsa.c +++ b/crypto/openssh/auth-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rsa.c,v 1.72 2006/11/06 21:25:27 markus Exp $ */ +/* $OpenBSD: auth-rsa.c,v 1.73 2008/07/02 12:03:51 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -173,7 +173,6 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) u_int bits; FILE *f; u_long linenum = 0; - struct stat st; Key *key; /* Temporarily use the user's uid. */ @@ -182,27 +181,9 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) /* The authorized keys. */ file = authorized_keys_file(pw); debug("trying public RSA key file %s", file); - - /* Fail quietly if file does not exist */ - if (stat(file, &st) < 0) { - /* Restore the privileged uid. */ - restore_uid(); - xfree(file); - return (0); - } - /* Open the file containing the authorized keys. */ - f = fopen(file, "r"); + f = auth_openkeyfile(file, pw, options.strict_modes); if (!f) { - /* Restore the privileged uid. */ - restore_uid(); - xfree(file); - return (0); - } - if (options.strict_modes && - secure_filename(f, file, pw, line, sizeof(line)) != 0) { xfree(file); - fclose(f); - logit("Authentication refused: %s", line); restore_uid(); return (0); } diff --git a/crypto/openssh/auth-shadow.c b/crypto/openssh/auth-shadow.c index 8b3160a..2190916 100644 --- a/crypto/openssh/auth-shadow.c +++ b/crypto/openssh/auth-shadow.c @@ -28,6 +28,7 @@ #include <shadow.h> #include <stdarg.h> #include <string.h> +#include <time.h> #include "key.h" #include "hostfile.h" diff --git a/crypto/openssh/auth-sia.c b/crypto/openssh/auth-sia.c index a9e1c25..debf302 100644 --- a/crypto/openssh/auth-sia.c +++ b/crypto/openssh/auth-sia.c @@ -34,6 +34,10 @@ #include <unistd.h> #include <stdarg.h> #include <string.h> +#include <sys/types.h> +#include <sys/security.h> +#include <prot.h> +#include <time.h> #include "ssh.h" #include "key.h" @@ -49,6 +53,52 @@ extern ServerOptions options; extern int saved_argc; extern char **saved_argv; +static int +sia_password_change_required(const char *user) +{ + struct es_passwd *acct; + time_t pw_life; + time_t pw_date; + + set_auth_parameters(saved_argc, saved_argv); + + if ((acct = getespwnam(user)) == NULL) { + error("Couldn't access protected database entry for %s", user); + endprpwent(); + return (0); + } + + /* If forced password change flag is set, honor it */ + if (acct->uflg->fg_psw_chg_reqd && acct->ufld->fd_psw_chg_reqd) { + endprpwent(); + return (1); + } + + /* Obtain password lifetime; if none, it can't have expired */ + if (acct->uflg->fg_expire) + pw_life = acct->ufld->fd_expire; + else if (acct->sflg->fg_expire) + pw_life = acct->sfld->fd_expire; + else { + endprpwent(); + return (0); + } + + /* Offset from last change; if none, it must be expired */ + if (acct->uflg->fg_schange) + pw_date = acct->ufld->fd_schange + pw_life; + else { + endprpwent(); + return (1); + } + + endprpwent(); + + /* If expiration date is prior to now, change password */ + + return (pw_date <= time((time_t *) NULL)); +} + int sys_auth_passwd(Authctxt *authctxt, const char *pass) { @@ -76,6 +126,9 @@ sys_auth_passwd(Authctxt *authctxt, const char *pass) sia_ses_release(&ent); + authctxt->force_pwchange = sia_password_change_required( + authctxt->user); + return (1); } diff --git a/crypto/openssh/auth-skey.c b/crypto/openssh/auth-skey.c index 25073db..cb43dba 100644 --- a/crypto/openssh/auth-skey.c +++ b/crypto/openssh/auth-skey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-skey.c,v 1.26 2006/08/05 08:28:24 dtucker Exp $ */ +/* $OpenBSD: auth-skey.c,v 1.27 2007/01/21 01:41:54 stevesk Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * @@ -59,8 +59,8 @@ skey_query(void *ctx, char **name, char **infotxt, sizeof(challenge)) == -1) return -1; - *name = xstrdup(""); - *infotxt = xstrdup(""); + *name = xstrdup(""); + *infotxt = xstrdup(""); *numprompts = 1; *prompts = xcalloc(*numprompts, sizeof(char *)); *echo_on = xcalloc(*numprompts, sizeof(u_int)); diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 2b6e09a..06ca760 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth.c,v 1.79 2008/07/02 12:03:51 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -33,6 +33,7 @@ __RCSID("$FreeBSD$"); #include <netinet/in.h> #include <errno.h> +#include <fcntl.h> #ifdef HAVE_PATHS_H # include <paths.h> #endif @@ -49,6 +50,7 @@ __RCSID("$FreeBSD$"); #include <stdarg.h> #include <stdio.h> #include <string.h> +#include <unistd.h> #include "xmalloc.h" #include "match.h" @@ -114,15 +116,14 @@ allowed_user(struct passwd * pw) #endif /* USE_SHADOW */ /* grab passwd field for locked account check */ + passwd = pw->pw_passwd; #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 */ -#else - passwd = pw->pw_passwd; +#endif /* USE_LIBIAF */ #endif /* check for locked account */ @@ -142,9 +143,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); @@ -411,7 +412,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, * * Returns 0 on success and -1 on failure */ -int +static int secure_filename(FILE *f, const char *file, struct passwd *pw, char *err, size_t errlen) { @@ -471,6 +472,46 @@ secure_filename(FILE *f, const char *file, struct passwd *pw, return 0; } +FILE * +auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) +{ + char line[1024]; + struct stat st; + int fd; + FILE *f; + + /* + * Open the file containing the authorized keys + * Fail quietly if file does not exist + */ + if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) + return NULL; + + if (fstat(fd, &st) < 0) { + close(fd); + return NULL; + } + if (!S_ISREG(st.st_mode)) { + logit("User %s authorized keys %s is not a regular file", + pw->pw_name, file); + close(fd); + return NULL; + } + unset_nonblock(fd); + if ((f = fdopen(fd, "r")) == NULL) { + close(fd); + return NULL; + } + if (options.strict_modes && + secure_filename(f, file, pw, line, sizeof(line)) != 0) { + fclose(f); + logit("Authentication refused: %s", line); + return NULL; + } + + return f; +} + struct passwd * getpwnamallow(const char *user) { @@ -570,8 +611,8 @@ fakepw(void) fake.pw_passwd = "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; fake.pw_gecos = "NOUSER"; - fake.pw_uid = privsep_pw->pw_uid; - fake.pw_gid = privsep_pw->pw_gid; + fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; + fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; #ifdef HAVE_PW_CLASS_IN_PASSWD fake.pw_class = ""; #endif diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h index 8c554b6..6a70f0e 100644 --- a/crypto/openssh/auth.h +++ b/crypto/openssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.61 2008/07/02 12:03:51 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -166,8 +166,7 @@ void abandon_challenge_response(Authctxt *); char *authorized_keys_file(struct passwd *); char *authorized_keys_file2(struct passwd *); -int -secure_filename(FILE *, const char *, struct passwd *, char *, size_t); +FILE *auth_openkeyfile(const char *, struct passwd *, int); HostStatus check_key_in_hostfiles(struct passwd *, Key *, const char *, diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c index b9d6b11..b8a2558 100644 --- a/crypto/openssh/auth1.c +++ b/crypto/openssh/auth1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth1.c,v 1.73 2008/07/04 23:30:16 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -20,6 +20,7 @@ #include <unistd.h> #include <pwd.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "rsa.h" #include "ssh1.h" @@ -283,6 +284,8 @@ do_authloop(Authctxt *authctxt) type != SSH_CMSG_AUTH_TIS_RESPONSE) abandon_challenge_response(authctxt); + if (authctxt->failures >= options.max_authtries) + goto skip; if ((meth = lookup_authmethod1(type)) == NULL) { logit("Unknown message during authentication: " "type %d", type); @@ -351,7 +354,7 @@ do_authloop(Authctxt *authctxt) msg[len] = '\0'; else msg = "Access denied."; - packet_disconnect(msg); + packet_disconnect("%s", msg); } #endif @@ -367,7 +370,7 @@ do_authloop(Authctxt *authctxt) if (authenticated) return; - if (authctxt->failures++ > options.max_authtries) { + if (++authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); #endif diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c index b78b739..d816578 100644 --- a/crypto/openssh/auth2-chall.c +++ b/crypto/openssh/auth2-chall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-chall.c,v 1.31 2006/08/05 08:28:24 dtucker Exp $ */ +/* $OpenBSD: auth2-chall.c,v 1.33 2007/09/21 08:15:29 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Per Allansson. All rights reserved. @@ -206,7 +206,7 @@ auth2_challenge_stop(Authctxt *authctxt) { /* unregister callback */ dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); - if (authctxt->kbdintctxt != NULL) { + if (authctxt->kbdintctxt != NULL) { kbdint_free(authctxt->kbdintctxt); authctxt->kbdintctxt = NULL; } diff --git a/crypto/openssh/auth2-gss.c b/crypto/openssh/auth2-gss.c index c77c841..0e08d88 100644 --- a/crypto/openssh/auth2-gss.c +++ b/crypto/openssh/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c index 663dec5..041051c 100644 --- a/crypto/openssh/auth2-hostbased.c +++ b/crypto/openssh/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.11 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.12 2008/07/17 08:51:07 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -151,15 +151,16 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", chost, resolvedname, ipaddr); + if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { + debug2("stripping trailing dot from chost %s", chost); + chost[len - 1] = '\0'; + } + if (options.hostbased_uses_name_from_packet_only) { if (auth_rhosts2(pw, cuser, chost, chost) == 0) return 0; lookup = chost; } else { - if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { - debug2("stripping trailing dot from chost %s", chost); - chost[len - 1] = '\0'; - } if (strcasecmp(resolvedname, chost) != 0) logit("userauth_hostbased mismatch: " "client sends %s, but we resolve %s to %s", diff --git a/crypto/openssh/auth2-none.c b/crypto/openssh/auth2-none.c index 952b448..10accfe 100644 --- a/crypto/openssh/auth2-none.c +++ b/crypto/openssh/auth2-none.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-none.c,v 1.13 2006/08/05 07:52:52 dtucker Exp $ */ +/* $OpenBSD: auth2-none.c,v 1.15 2008/07/02 12:36:39 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -31,8 +31,10 @@ #include <fcntl.h> #include <stdarg.h> +#include <string.h> #include <unistd.h> +#include "atomicio.h" #include "xmalloc.h" #include "key.h" #include "hostfile.h" @@ -41,7 +43,6 @@ #include "log.h" #include "buffer.h" #include "servconf.h" -#include "atomicio.h" #include "compat.h" #include "ssh2.h" #ifdef GSSAPI @@ -55,75 +56,11 @@ extern ServerOptions options; /* "none" is allowed only one time */ static int none_enabled = 1; -char * -auth2_read_banner(void) -{ - struct stat st; - char *banner = NULL; - size_t len, n; - int fd; - - if ((fd = open(options.banner, O_RDONLY)) == -1) - return (NULL); - if (fstat(fd, &st) == -1) { - close(fd); - return (NULL); - } - if (st.st_size > 1*1024*1024) { - close(fd); - return (NULL); - } - - len = (size_t)st.st_size; /* truncate */ - banner = xmalloc(len + 1); - n = atomicio(read, fd, banner, len); - close(fd); - - if (n != len) { - xfree(banner); - return (NULL); - } - banner[n] = '\0'; - - return (banner); -} - -void -userauth_send_banner(const char *msg) -{ - if (datafellows & SSH_BUG_BANNER) - return; - - packet_start(SSH2_MSG_USERAUTH_BANNER); - packet_put_cstring(msg); - packet_put_cstring(""); /* language, unused */ - packet_send(); - debug("%s: sent", __func__); -} - -static void -userauth_banner(void) -{ - char *banner = NULL; - - if (options.banner == NULL || (datafellows & SSH_BUG_BANNER)) - return; - - if ((banner = PRIVSEP(auth2_read_banner())) == NULL) - goto done; - userauth_send_banner(banner); - -done: - if (banner) - xfree(banner); -} - static int userauth_none(Authctxt *authctxt) { none_enabled = 0; packet_check_eom(); - userauth_banner(); #ifdef HAVE_CYGWIN if (check_nt_auth(1, authctxt->pw) == 0) return (0); diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c index 9863cd9..b1e38e5 100644 --- a/crypto/openssh/auth2-pubkey.c +++ b/crypto/openssh/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.19 2008/07/03 21:46:58 otto Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -28,9 +28,11 @@ #include <sys/types.h> #include <sys/stat.h> +#include <fcntl.h> #include <pwd.h> #include <stdio.h> #include <stdarg.h> +#include <unistd.h> #include "xmalloc.h" #include "ssh.h" @@ -183,7 +185,6 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) int found_key = 0; FILE *f; u_long linenum = 0; - struct stat st; Key *found; char *fp; @@ -191,24 +192,9 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) temporarily_use_uid(pw); debug("trying public key file %s", file); + f = auth_openkeyfile(file, pw, options.strict_modes); - /* Fail quietly if file does not exist */ - if (stat(file, &st) < 0) { - /* Restore the privileged uid. */ - restore_uid(); - return 0; - } - /* Open the file containing the authorized keys. */ - f = fopen(file, "r"); if (!f) { - /* Restore the privileged uid. */ - restore_uid(); - return 0; - } - if (options.strict_modes && - secure_filename(f, file, pw, line, sizeof(line)) != 0) { - fclose(f); - logit("Authentication refused: %s", line); restore_uid(); return 0; } diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 8261e35..500764a 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.113 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: auth2.c,v 1.119 2008/07/04 23:30:16 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -27,12 +27,17 @@ __RCSID("$FreeBSD$"); #include <sys/types.h> +#include <sys/stat.h> +#include <sys/uio.h> +#include <fcntl.h> #include <pwd.h> #include <stdarg.h> #include <string.h> +#include <unistd.h> #include "xmalloc.h" +#include "atomicio.h" #include "ssh2.h" #include "packet.h" #include "log.h" @@ -89,19 +94,78 @@ static void input_userauth_request(int, u_int32_t, void *); /* helper */ static Authmethod *authmethod_lookup(const char *); static char *authmethods_get(void); -int user_key_allowed(struct passwd *, Key *); + +char * +auth2_read_banner(void) +{ + struct stat st; + char *banner = NULL; + size_t len, n; + int fd; + + if ((fd = open(options.banner, O_RDONLY)) == -1) + return (NULL); + if (fstat(fd, &st) == -1) { + close(fd); + return (NULL); + } + if (st.st_size > 1*1024*1024) { + close(fd); + return (NULL); + } + + len = (size_t)st.st_size; /* truncate */ + banner = xmalloc(len + 1); + n = atomicio(read, fd, banner, len); + close(fd); + + if (n != len) { + xfree(banner); + return (NULL); + } + banner[n] = '\0'; + + return (banner); +} + +void +userauth_send_banner(const char *msg) +{ + if (datafellows & SSH_BUG_BANNER) + return; + + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(msg); + packet_put_cstring(""); /* language, unused */ + packet_send(); + debug("%s: sent", __func__); +} + +static void +userauth_banner(void) +{ + char *banner = NULL; + + if (options.banner == NULL || + strcasecmp(options.banner, "none") == 0 || + (datafellows & SSH_BUG_BANNER) != 0) + return; + + if ((banner = PRIVSEP(auth2_read_banner())) == NULL) + goto done; + userauth_send_banner(banner); + +done: + if (banner) + xfree(banner); +} /* * loop until authctxt->success == TRUE */ - void do_authentication2(Authctxt *authctxt) { - /* challenge-response is implemented via keyboard interactive */ - if (options.challenge_response_authentication) - options.kbd_interactive_authentication = 1; - dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt); @@ -193,6 +257,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) authctxt->style = style ? xstrdup(style) : NULL; if (use_privsep) mm_inform_authserv(service, style); + userauth_banner(); } else if (strcmp(user, authctxt->user) != 0 || strcmp(service, authctxt->service) != 0) { packet_disconnect("Change of username or service not allowed: " @@ -232,7 +297,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) /* try to authenticate user */ m = authmethod_lookup(method); - if (m != NULL) { + if (m != NULL && authctxt->failures < options.max_authtries) { debug2("input_userauth_request: try method %s", method); authenticated = m->userauth(authctxt); } @@ -299,7 +364,11 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) /* now we can break out */ authctxt->success = 1; } else { - if (authctxt->failures++ > options.max_authtries) { + + /* Allow initial try of "none" auth without failure penalty */ + if (authctxt->attempt > 1 || strcmp(method, "none") != 0) + authctxt->failures++; + if (authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); #endif @@ -315,8 +384,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) } } -#define DELIM "," - static char * authmethods_get(void) { @@ -357,3 +424,4 @@ authmethod_lookup(const char *name) name ? name : "NULL"); return NULL; } + diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c index cbdc22c..cd9a35d 100644 --- a/crypto/openssh/bufaux.c +++ b/crypto/openssh/bufaux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufaux.c,v 1.44 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: bufaux.c,v 1.46 2008/06/10 23:21:34 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -180,7 +180,7 @@ buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) return (NULL); } /* Append a null character to make processing easier. */ - value[len] = 0; + value[len] = '\0'; /* Optionally return the length of the string. */ if (length_ptr) *length_ptr = len; @@ -197,6 +197,22 @@ buffer_get_string(Buffer *buffer, u_int *length_ptr) return (ret); } +void * +buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) +{ + void *ptr; + u_int len; + + len = buffer_get_int(buffer); + if (len > 256 * 1024) + fatal("buffer_get_string_ptr: bad string length %u", len); + ptr = buffer_ptr(buffer); + buffer_consume(buffer, len); + if (length_ptr) + *length_ptr = len; + return (ptr); +} + /* * Stores and arbitrary binary string in the buffer. */ diff --git a/crypto/openssh/bufbn.c b/crypto/openssh/bufbn.c index 9706ba8..251cd09 100644 --- a/crypto/openssh/bufbn.c +++ b/crypto/openssh/bufbn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bufbn.c,v 1.4 2006/11/06 21:25:28 markus Exp $*/ +/* $OpenBSD: bufbn.c,v 1.6 2007/06/02 09:04:58 djm Exp $*/ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -93,7 +93,7 @@ buffer_put_bignum(Buffer *buffer, const BIGNUM *value) } /* - * Retrieves an BIGNUM from the buffer. + * Retrieves a BIGNUM from the buffer. */ int buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) @@ -101,7 +101,7 @@ buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) u_int bits, bytes; u_char buf[2], *bin; - /* Get the number for bits. */ + /* Get the number of bits. */ if (buffer_get_ret(buffer, (char *) buf, 2) == -1) { error("buffer_get_bignum_ret: invalid length"); return (-1); @@ -137,7 +137,7 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value) } /* - * Stores an BIGNUM in the buffer in SSH2 format. + * Stores a BIGNUM in the buffer in SSH2 format. */ int buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) @@ -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/crypto/openssh/buffer.h b/crypto/openssh/buffer.h index ecc4aea..d0f354e 100644 --- a/crypto/openssh/buffer.h +++ b/crypto/openssh/buffer.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.h,v 1.16 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: buffer.h,v 1.17 2008/05/08 06:59:01 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -66,6 +66,7 @@ int buffer_get_char(Buffer *); void buffer_put_char(Buffer *, int); void *buffer_get_string(Buffer *, u_int *); +void *buffer_get_string_ptr(Buffer *, u_int *); void buffer_put_string(Buffer *, const void *, u_int); void buffer_put_cstring(Buffer *, const char *); diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c index 2345cc3..42011fd 100644 --- a/crypto/openssh/canohost.c +++ b/crypto/openssh/canohost.c @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.c,v 1.61 2006/08/03 03:34:41 deraadt Exp $ */ +/* $OpenBSD: canohost.c,v 1.63 2008/06/12 00:03:49 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -32,6 +32,7 @@ #include "packet.h" #include "log.h" #include "canohost.h" +#include "misc.h" static void check_ip_options(int, char *); @@ -88,7 +89,7 @@ get_remote_hostname(int sock, int use_dns) memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; /*dummy*/ hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(name, "0", &hints, &ai) == 0) { + if (getaddrinfo(name, NULL, &hints, &ai) == 0) { logit("Nasty PTR record \"%s\" is set up for %s, ignoring", name, ntop); freeaddrinfo(ai); @@ -271,7 +272,7 @@ get_socket_address(int sock, int remote, int flags) if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop), NULL, 0, flags)) != 0) { error("get_socket_address: getnameinfo %d failed: %s", flags, - r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); + ssh_gai_strerror(r)); return NULL; } return xstrdup(ntop); @@ -372,7 +373,7 @@ get_sock_port(int sock, int local) if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, strport, sizeof(strport), NI_NUMERICSERV)) != 0) fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s", - r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r)); + ssh_gai_strerror(r)); return atoi(strport); } diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c index 26b63a1..69c99c9 100644 --- a/crypto/openssh/channels.c +++ b/crypto/openssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.266 2006/08/29 10:40:18 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.286 2008/07/16 11:52:19 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -61,6 +61,7 @@ #include <unistd.h> #include <stdarg.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" @@ -164,6 +165,10 @@ static int IPv4or6 = AF_UNSPEC; /* helper */ static void port_open_helper(Channel *c, char *rtype); +/* non-blocking connect helpers */ +static int connect_next(struct channel_connect *); +static void channel_connect_ctx_free(struct channel_connect *); + /* -- channel core */ Channel * @@ -216,7 +221,7 @@ channel_lookup(int id) */ static void channel_register_fds(Channel *c, int rfd, int wfd, int efd, - int extusage, int nonblock) + int extusage, int nonblock, int is_tty) { /* Update the maximum file descriptor value. */ channel_max_fd = MAX(channel_max_fd, rfd); @@ -232,18 +237,9 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, c->efd = efd; c->extended_usage = extusage; - /* XXX ugly hack: nonblock is only set by the server */ - if (nonblock && isatty(c->rfd)) { + if ((c->isatty = is_tty) != 0) debug2("channel %d: rfd %d isatty", c->self, c->rfd); - c->isatty = 1; - if (!isatty(c->wfd)) { - error("channel %d: wfd %d is not a tty?", - c->self, c->wfd); - } - } else { - c->isatty = 0; - } - c->wfd_isatty = isatty(c->wfd); + c->wfd_isatty = is_tty || isatty(c->wfd); /* enable nonblocking mode */ if (nonblock) { @@ -303,7 +299,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->ostate = CHAN_OUTPUT_OPEN; c->istate = CHAN_INPUT_OPEN; c->flags = 0; - channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); + channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, 0); c->self = found; c->type = type; c->ctype = ctype; @@ -319,10 +315,13 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->single_connection = 0; c->detach_user = NULL; c->detach_close = 0; - c->confirm = NULL; - c->confirm_ctx = NULL; + c->open_confirm = NULL; + c->open_confirm_ctx = NULL; c->input_filter = NULL; c->output_filter = NULL; + c->filter_ctx = NULL; + c->filter_cleanup = NULL; + TAILQ_INIT(&c->status_confirms); debug("channel %d: new [%s]", found, remote_name); return c; } @@ -379,6 +378,7 @@ channel_free(Channel *c) { char *s; u_int i, n; + struct channel_confirm *cc; for (n = 0, i = 0; i < channels_alloc; i++) if (channels[i]) @@ -402,6 +402,15 @@ channel_free(Channel *c) xfree(c->remote_name); c->remote_name = NULL; } + while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { + if (cc->abandon_cb != NULL) + cc->abandon_cb(c, cc->ctx); + TAILQ_REMOVE(&c->status_confirms, cc, entry); + bzero(cc, sizeof(*cc)); + xfree(cc); + } + if (c->filter_cleanup != NULL && c->filter_ctx != NULL) + c->filter_cleanup(c->self, c->filter_ctx); channels[c->self] = NULL; xfree(c); } @@ -660,16 +669,33 @@ channel_request_start(int id, char *service, int wantconfirm) } void -channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) +channel_register_status_confirm(int id, channel_confirm_cb *cb, + channel_confirm_abandon_cb *abandon_cb, void *ctx) +{ + struct channel_confirm *cc; + Channel *c; + + if ((c = channel_lookup(id)) == NULL) + fatal("channel_register_expect: %d: bad id", id); + + cc = xmalloc(sizeof(*cc)); + cc->cb = cb; + cc->abandon_cb = abandon_cb; + cc->ctx = ctx; + TAILQ_INSERT_TAIL(&c->status_confirms, cc, entry); +} + +void +channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx) { Channel *c = channel_lookup(id); if (c == NULL) { - logit("channel_register_comfirm: %d: bad id", id); + logit("channel_register_open_comfirm: %d: bad id", id); return; } - c->confirm = fn; - c->confirm_ctx = ctx; + c->open_confirm = fn; + c->open_confirm_ctx = ctx; } void @@ -700,7 +726,7 @@ channel_cancel_cleanup(int id) void channel_register_filter(int id, channel_infilter_fn *ifn, - channel_outfilter_fn *ofn) + channel_outfilter_fn *ofn, channel_filter_cleanup_fn *cfn, void *ctx) { Channel *c = channel_lookup(id); @@ -710,17 +736,19 @@ channel_register_filter(int id, channel_infilter_fn *ifn, } c->input_filter = ifn; c->output_filter = ofn; + c->filter_ctx = ctx; + c->filter_cleanup = cfn; } void channel_set_fds(int id, int rfd, int wfd, int efd, - int extusage, int nonblock, u_int window_max) + int extusage, int nonblock, int is_tty, u_int window_max) { Channel *c = channel_lookup(id); if (c == NULL || c->type != SSH_CHANNEL_LARVAL) fatal("channel_activate for non-larval channel %d.", id); - channel_register_fds(c, rfd, wfd, efd, extusage, nonblock); + channel_register_fds(c, rfd, wfd, efd, extusage, nonblock, is_tty); c->type = SSH_CHANNEL_OPEN; c->local_window = c->local_window_max = window_max; packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); @@ -788,7 +816,8 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset) } } /** XXX check close conditions, too */ - if (compat20 && c->efd != -1) { + if (compat20 && c->efd != -1 && + !(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) { if (c->extended_usage == CHAN_EXTENDED_WRITE && buffer_len(&c->extended) > 0) FD_SET(c->efd, writeset); @@ -1052,7 +1081,7 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) if (have < nmethods + 2) return 0; /* look for method: "NO AUTHENTICATION REQUIRED" */ - for (found = 0, i = 2 ; i < nmethods + 2; i++) { + for (found = 0, i = 2; i < nmethods + 2; i++) { if (p[i] == SSH_SOCKS5_NOAUTH) { found = 1; break; @@ -1181,7 +1210,7 @@ static void channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; - struct sockaddr addr; + struct sockaddr_storage addr; int newsock; socklen_t addrlen; char buf[16384], *remote_ipaddr; @@ -1190,7 +1219,7 @@ channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset) if (FD_ISSET(c->sock, readset)) { debug("X11 connection requested."); addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); + newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); if (c->single_connection) { debug2("single_connection: closing X11 listener."); channel_close_fd(&c->sock); @@ -1307,7 +1336,7 @@ static void channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; - struct sockaddr addr; + struct sockaddr_storage addr; int newsock, nextstate; socklen_t addrlen; char *rtype; @@ -1331,7 +1360,7 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) } addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); + newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); if (newsock < 0) { error("accept: %.100s", strerror(errno)); return; @@ -1366,12 +1395,12 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset) { Channel *nc; int newsock; - struct sockaddr addr; + struct sockaddr_storage addr; socklen_t addrlen; if (FD_ISSET(c->sock, readset)) { addrlen = sizeof(addr); - newsock = accept(c->sock, &addr, &addrlen); + newsock = accept(c->sock, (struct sockaddr *)&addr, &addrlen); if (newsock < 0) { error("accept from auth socket: %.100s", strerror(errno)); return; @@ -1398,7 +1427,7 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset) static void channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) { - int err = 0; + int err = 0, sock; socklen_t sz = sizeof(err); if (FD_ISSET(c->sock, writeset)) { @@ -1407,7 +1436,9 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) error("getsockopt SO_ERROR failed"); } if (err == 0) { - debug("channel %d: connected", c->self); + debug("channel %d: connected to %s port %d", + c->self, c->connect_ctx.host, c->connect_ctx.port); + channel_connect_ctx_free(&c->connect_ctx); c->type = SSH_CHANNEL_OPEN; if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); @@ -1421,8 +1452,19 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset) packet_put_int(c->self); } } else { - debug("channel %d: not connected: %s", + debug("channel %d: connection failed: %s", c->self, strerror(err)); + /* Try next address, if any */ + if ((sock = connect_next(&c->connect_ctx)) > 0) { + close(c->sock); + c->sock = c->rfd = c->wfd = sock; + channel_max_fd = channel_find_maxfd(); + return; + } + /* Exhausted all addresses */ + error("connect_to %.100s port %d: failed.", + c->connect_ctx.host, c->connect_ctx.port); + channel_connect_ctx_free(&c->connect_ctx); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(c->remote_id); @@ -1446,13 +1488,14 @@ 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 && - 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)) + if (len < 0 && (errno == EINTR || + ((errno == EAGAIN || errno == EWOULDBLOCK) && !force))) return 1; #ifndef PTY_ZEROREAD if (len <= 0) { @@ -1523,7 +1566,8 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset) c->local_consumed += dlen + 4; len = write(c->wfd, buf, dlen); xfree(data); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) + if (len < 0 && (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK)) return 1; if (len <= 0) { if (c->type != SSH_CHANNEL_OPEN) @@ -1541,7 +1585,8 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset) #endif len = write(c->wfd, buf, dlen); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) + if (len < 0 && + (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) return 1; if (len <= 0) { if (c->type != SSH_CHANNEL_OPEN) { @@ -1593,7 +1638,8 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) buffer_len(&c->extended)); debug2("channel %d: written %d to efd %d", c->self, len, c->efd); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) + if (len < 0 && (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK)) return 1; if (len <= 0) { debug2("channel %d: closing write-efd %d", @@ -1604,11 +1650,12 @@ channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) c->local_consumed += len; } } else if (c->extended_usage == CHAN_EXTENDED_READ && - FD_ISSET(c->efd, readset)) { + (c->detach_close || FD_ISSET(c->efd, readset))) { len = read(c->efd, buf, sizeof(buf)); debug2("channel %d: read %d from efd %d", c->self, len, c->efd); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) + if (len < 0 && (errno == EINTR || ((errno == EAGAIN || + errno == EWOULDBLOCK) && !c->detach_close))) return 1; if (len <= 0) { debug2("channel %d: closing read-efd %d", @@ -1632,7 +1679,8 @@ channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset) /* Monitor control fd to detect if the slave client exits */ if (c->ctl_fd != -1 && FD_ISSET(c->ctl_fd, readset)) { len = read(c->ctl_fd, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) + if (len < 0 && + (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) return 1; if (len <= 0) { debug2("channel %d: ctl read<=0", c->self); @@ -1656,7 +1704,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); @@ -2009,7 +2059,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) return; /* Get the data. */ - data = packet_get_string(&data_len); + data = packet_get_string_ptr(&data_len); /* * Ignore data for protocol > 1.3 if output end is no longer open. @@ -2023,7 +2073,6 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) c->local_window -= data_len; c->local_consumed += data_len; } - xfree(data); return; } @@ -2035,17 +2084,15 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) if (data_len > c->local_window) { logit("channel %d: rcvd too much data %d, win %d", c->self, data_len, c->local_window); - xfree(data); return; } c->local_window -= data_len; } - packet_check_eom(); if (c->datagram) buffer_put_string(&c->output, data, data_len); else buffer_append(&c->output, data, data_len); - xfree(data); + packet_check_eom(); } /* ARGSUSED */ @@ -2209,9 +2256,9 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) if (compat20) { c->remote_window = packet_get_int(); c->remote_maxpacket = packet_get_int(); - if (c->confirm) { + if (c->open_confirm) { debug2("callback start"); - c->confirm(c->self, c->confirm_ctx); + c->open_confirm(c->self, c->open_confirm_ctx); debug2("callback done"); } debug2("channel %d: open confirm rwindow %u rmax %u", c->self, @@ -2300,7 +2347,7 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt) Channel *c = NULL; u_short host_port; char *host, *originator_string; - int remote_id, sock = -1; + int remote_id; remote_id = packet_get_int(); host = packet_get_string(NULL); @@ -2312,22 +2359,46 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt) originator_string = xstrdup("unknown (remote did not supply name)"); } packet_check_eom(); - sock = channel_connect_to(host, host_port); - if (sock != -1) { - c = channel_new("connected socket", - SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0, - originator_string, 1); - c->remote_id = remote_id; - } + c = channel_connect_to(host, host_port, + "connected socket", originator_string); xfree(originator_string); + xfree(host); if (c == NULL) { packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); packet_send(); - } - xfree(host); + } else + c->remote_id = remote_id; } +/* ARGSUSED */ +void +channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) +{ + Channel *c; + struct channel_confirm *cc; + int remote_id; + + /* Reset keepalive timeout */ + keep_alive_timeouts = 0; + + remote_id = packet_get_int(); + packet_check_eom(); + + debug2("channel_input_confirm: type %d id %d", type, remote_id); + + if ((c = channel_lookup(remote_id)) == NULL) { + logit("channel_input_success_failure: %d: unknown", remote_id); + return; + } + ; + if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) + return; + cc->cb(type, c, cc->ctx); + TAILQ_REMOVE(&c->status_confirms, cc, entry); + bzero(cc, sizeof(*cc)); + xfree(cc); +} /* -- tcp forwarding */ @@ -2382,7 +2453,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por wildcard = 1; } else if (gateway_ports || is_client) { if (((datafellows & SSH_OLD_FORWARD_ADDR) && - strcmp(listen_addr, "0.0.0.0") == 0) || + strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || (!is_client && gateway_ports == 1)) wildcard = 1; @@ -2406,10 +2477,11 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por if (addr == NULL) { /* This really shouldn't happen */ packet_disconnect("getaddrinfo: fatal error: %s", - gai_strerror(r)); + ssh_gai_strerror(r)); } else { error("channel_setup_fwd_listener: " - "getaddrinfo(%.64s): %s", addr, gai_strerror(r)); + "getaddrinfo(%.64s): %s", addr, + ssh_gai_strerror(r)); } return 0; } @@ -2525,11 +2597,18 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port, /* Send the forward request to the remote side. */ if (compat20) { const char *address_to_bind; - if (listen_host == NULL) - address_to_bind = "localhost"; - else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) - address_to_bind = ""; - else + if (listen_host == NULL) { + if (datafellows & SSH_BUG_RFWD_ADDR) + address_to_bind = "127.0.0.1"; + else + address_to_bind = "localhost"; + } else if (*listen_host == '\0' || + strcmp(listen_host, "*") == 0) { + if (datafellows & SSH_BUG_RFWD_ADDR) + address_to_bind = "0.0.0.0"; + else + address_to_bind = ""; + } else address_to_bind = listen_host; packet_start(SSH2_MSG_GLOBAL_REQUEST); @@ -2707,35 +2786,37 @@ channel_clear_adm_permitted_opens(void) num_adm_permitted_opens = 0; } -/* return socket to remote host, port */ +void +channel_print_adm_permitted_opens(void) +{ + int i; + + for (i = 0; i < num_adm_permitted_opens; i++) + if (permitted_adm_opens[i].host_to_connect != NULL) + printf(" %s:%d", permitted_adm_opens[i].host_to_connect, + permitted_adm_opens[i].port_to_connect); +} + +/* Try to start non-blocking connect to next host in cctx list */ static int -connect_to(const char *host, u_short port) +connect_next(struct channel_connect *cctx) { - struct addrinfo hints, *ai, *aitop; + int sock, saved_errno; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int gaierr; - int sock = -1; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = IPv4or6; - hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%d", port); - if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) { - error("connect_to %.100s: unknown host (%s)", host, - gai_strerror(gaierr)); - return -1; - } - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { + if (cctx->ai->ai_family != AF_INET && + cctx->ai->ai_family != AF_INET6) continue; - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), - strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("connect_to: getnameinfo failed"); + if (getnameinfo(cctx->ai->ai_addr, cctx->ai->ai_addrlen, + ntop, sizeof(ntop), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + error("connect_next: getnameinfo failed"); continue; } - sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sock < 0) { - if (ai->ai_next == NULL) + if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, + cctx->ai->ai_protocol)) == -1) { + if (cctx->ai->ai_next == NULL) error("socket: %.100s", strerror(errno)); else verbose("socket: %.100s", strerror(errno)); @@ -2743,45 +2824,95 @@ connect_to(const char *host, u_short port) } if (set_nonblock(sock) == -1) fatal("%s: set_nonblock(%d)", __func__, sock); - if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0 && - errno != EINPROGRESS) { - error("connect_to %.100s port %s: %.100s", ntop, strport, + if (connect(sock, cctx->ai->ai_addr, + cctx->ai->ai_addrlen) == -1 && errno != EINPROGRESS) { + debug("connect_next: host %.100s ([%.100s]:%s): " + "%.100s", cctx->host, ntop, strport, strerror(errno)); + saved_errno = errno; close(sock); + errno = saved_errno; continue; /* fail -- try next */ } - break; /* success */ + debug("connect_next: host %.100s ([%.100s]:%s) " + "in progress, fd=%d", cctx->host, ntop, strport, sock); + cctx->ai = cctx->ai->ai_next; + set_nodelay(sock); + return sock; + } + return -1; +} +static void +channel_connect_ctx_free(struct channel_connect *cctx) +{ + xfree(cctx->host); + if (cctx->aitop) + freeaddrinfo(cctx->aitop); + bzero(cctx, sizeof(*cctx)); + cctx->host = NULL; + cctx->ai = cctx->aitop = NULL; +} + +/* Return CONNECTING channel to remote host, port */ +static Channel * +connect_to(const char *host, u_short port, char *ctype, char *rname) +{ + struct addrinfo hints; + int gaierr; + int sock = -1; + char strport[NI_MAXSERV]; + struct channel_connect cctx; + Channel *c; + + memset(&cctx, 0, sizeof(cctx)); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &cctx.aitop)) != 0) { + error("connect_to %.100s: unknown host (%s)", host, + ssh_gai_strerror(gaierr)); + return NULL; } - freeaddrinfo(aitop); - if (!ai) { - error("connect_to %.100s port %d: failed.", host, port); - return -1; + + cctx.host = xstrdup(host); + cctx.port = port; + cctx.ai = cctx.aitop; + + if ((sock = connect_next(&cctx)) == -1) { + error("connect to %.100s port %d failed: %s", + host, port, strerror(errno)); + channel_connect_ctx_free(&cctx); + return NULL; } - /* success */ - set_nodelay(sock); - return sock; + c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1); + c->connect_ctx = cctx; + return c; } -int -channel_connect_by_listen_address(u_short listen_port) +Channel * +channel_connect_by_listen_address(u_short listen_port, char *ctype, char *rname) { int i; - for (i = 0; i < num_permitted_opens; i++) + for (i = 0; i < num_permitted_opens; i++) { if (permitted_opens[i].host_to_connect != NULL && - permitted_opens[i].listen_port == listen_port) + permitted_opens[i].listen_port == listen_port) { return connect_to( permitted_opens[i].host_to_connect, - permitted_opens[i].port_to_connect); + permitted_opens[i].port_to_connect, ctype, rname); + } + } error("WARNING: Server requests forwarding for unknown listen_port %d", listen_port); - return -1; + return NULL; } /* Check if connecting to that port is permitted and connect. */ -int -channel_connect_to(const char *host, u_short port) +Channel * +channel_connect_to(const char *host, u_short port, char *ctype, char *rname) { int i, permit, permit_adm = 1; @@ -2807,9 +2938,9 @@ channel_connect_to(const char *host, u_short port) if (!permit || !permit_adm) { logit("Received request to connect to host %.100s port %d, " "but the request was denied.", host, port); - return -1; + return NULL; } - return connect_to(host, port); + return connect_to(host, port, ctype, rname); } void @@ -2864,7 +2995,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%d", port); if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { - error("getaddrinfo: %.100s", gai_strerror(gaierr)); + error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr)); return -1; } for (ai = aitop; ai; ai = ai->ai_next) { @@ -2890,14 +3021,12 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); } #endif - channel_set_reuseaddr(sock); + if (x11_use_localhost) + channel_set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("bind port %d: %.100s", port, strerror(errno)); close(sock); - if (ai->ai_next) - continue; - for (n = 0; n < num_socks; n++) { close(socks[n]); } @@ -2905,17 +3034,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, break; } socks[num_socks++] = sock; -#ifndef DONT_TRY_OTHER_AF if (num_socks == NUM_SOCKS) break; -#else - if (x11_use_localhost) { - if (num_socks == NUM_SOCKS) - break; - } else { - break; - } -#endif } freeaddrinfo(aitop); if (num_socks > 0) @@ -3037,7 +3157,8 @@ x11_connect_display(void) hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%u", 6000 + display_number); if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { - error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr)); + error("%.100s: unknown host. (%s)", buf, + ssh_gai_strerror(gaierr)); return -1; } for (ai = aitop; ai; ai = ai->ai_next) { diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h index 2674f09..108b360 100644 --- a/crypto/openssh/channels.h +++ b/crypto/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.96 2008/06/15 20:06:26 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -62,8 +62,27 @@ typedef struct Channel Channel; typedef void channel_callback_fn(int, void *); typedef int channel_infilter_fn(struct Channel *, char *, int); +typedef void channel_filter_cleanup_fn(int, void *); typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); +/* Channel success/failure callbacks */ +typedef void channel_confirm_cb(int, struct Channel *, void *); +typedef void channel_confirm_abandon_cb(struct Channel *, void *); +struct channel_confirm { + TAILQ_ENTRY(channel_confirm) entry; + channel_confirm_cb *cb; + channel_confirm_abandon_cb *abandon_cb; + void *ctx; +}; +TAILQ_HEAD(channel_confirms, channel_confirm); + +/* Context for non-blocking connects */ +struct channel_connect { + char *host; + int port; + struct addrinfo *ai, *aitop; +}; + struct Channel { int type; /* channel type/state */ int self; /* my own channel identifier */ @@ -104,16 +123,23 @@ struct Channel { char *ctype; /* type */ /* callback */ - channel_callback_fn *confirm; - void *confirm_ctx; + channel_callback_fn *open_confirm; + void *open_confirm_ctx; channel_callback_fn *detach_user; int detach_close; + struct channel_confirms status_confirms; /* filter */ channel_infilter_fn *input_filter; channel_outfilter_fn *output_filter; + void *filter_ctx; + channel_filter_cleanup_fn *filter_cleanup; + + /* keep boundaries */ + int datagram; - int datagram; /* keep boundaries */ + /* non-blocking connect */ + struct channel_connect connect_ctx; }; #define CHAN_EXTENDED_IGNORE 0 @@ -122,9 +148,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) @@ -162,7 +188,7 @@ struct Channel { Channel *channel_by_id(int); Channel *channel_lookup(int); Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); -void channel_set_fds(int, int, int, int, int, int, u_int); +void channel_set_fds(int, int, int, int, int, int, int, u_int); void channel_free(Channel *); void channel_free_all(void); void channel_stop_listening(void); @@ -170,8 +196,11 @@ void channel_stop_listening(void); void channel_send_open(int); void channel_request_start(int, char *, int); void channel_register_cleanup(int, channel_callback_fn *, int); -void channel_register_confirm(int, channel_callback_fn *, void *); -void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *); +void channel_register_open_confirm(int, channel_callback_fn *, void *); +void channel_register_filter(int, channel_infilter_fn *, + channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); +void channel_register_status_confirm(int, channel_confirm_cb *, + channel_confirm_abandon_cb *, void *); void channel_cancel_cleanup(int); int channel_close_fd(int *); void channel_send_window_changes(void); @@ -188,6 +217,7 @@ void channel_input_open_confirmation(int, u_int32_t, void *); void channel_input_open_failure(int, u_int32_t, void *); void channel_input_port_open(int, u_int32_t, void *); void channel_input_window_adjust(int, u_int32_t, void *); +void channel_input_status_confirm(int, u_int32_t, void *); /* file descriptor handling (read/write) */ @@ -208,9 +238,10 @@ void channel_add_permitted_opens(char *, int); int channel_add_adm_permitted_opens(char *, int); void channel_clear_permitted_opens(void); void channel_clear_adm_permitted_opens(void); +void channel_print_adm_permitted_opens(void); int channel_input_port_forward_request(int, int); -int channel_connect_to(const char *, u_short); -int channel_connect_by_listen_address(u_short); +Channel *channel_connect_to(const char *, u_short, char *, char *); +Channel *channel_connect_by_listen_address(u_short, char *, char *); int channel_request_remote_forwarding(const char *, u_short, const char *, u_short); int channel_setup_local_fwd_listener(const char *, u_short, @@ -225,7 +256,7 @@ int x11_connect_display(void); int x11_create_display_inet(int, int, int, u_int *, int **); void x11_input_open(int, u_int32_t, void *); void x11_request_forwarding_with_spoofing(int, const char *, const char *, - const char *); + const char *); void deny_input_open(int, u_int32_t, void *); /* agent forwarding */ @@ -240,6 +271,7 @@ void chan_mark_dead(Channel *); /* channel events */ void chan_rcvd_oclose(Channel *); +void chan_rcvd_eow(Channel *); /* SSH2-only */ void chan_read_failed(Channel *); void chan_ibuf_empty(Channel *); diff --git a/crypto/openssh/cipher-3des1.c b/crypto/openssh/cipher-3des1.c index fc16e20..17a13a1 100644 --- a/crypto/openssh/cipher-3des1.c +++ b/crypto/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/crypto/openssh/cipher-bf1.c b/crypto/openssh/cipher-bf1.c index 292488c..e0e33b4 100644 --- a/crypto/openssh/cipher-bf1.c +++ b/crypto/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/crypto/openssh/cipher-ctr.c b/crypto/openssh/cipher-ctr.c index b24f3a4..3b86cc1 100644 --- a/crypto/openssh/cipher-ctr.c +++ b/crypto/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 <openssl/aes.h> #endif diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c index 4c51081..f10fab7 100644 --- a/crypto/openssh/clientloop.c +++ b/crypto/openssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.176 2006/10/11 12:38:03 markus Exp $ */ +/* $OpenBSD: clientloop.c,v 1.201 2008/07/16 11:51:14 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -86,6 +86,7 @@ #include <pwd.h> #include <unistd.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" @@ -120,7 +121,7 @@ extern int stdin_null_flag; extern int no_shell_flag; /* Control socket */ -extern int control_fd; +extern int muxserver_sock; /* * Name of the host we are connecting to. This is the name given on the @@ -143,36 +144,46 @@ static int in_non_blocking_mode = 0; /* Common data for the client loop code. */ static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ -static int escape_char; /* Escape character. */ -static int escape_pending; /* Last character was the escape character */ +static int escape_char1; /* Escape character. (proto1 only) */ +static int escape_pending1; /* Last character was an escape (proto1 only) */ static int last_was_cr; /* Last character was a newline. */ -static int exit_status; /* Used to store the exit status of the command. */ -static int stdin_eof; /* EOF has been encountered on standard error. */ +static int exit_status; /* Used to store the command exit status. */ +static int stdin_eof; /* EOF has been encountered on stderr. */ static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ static Buffer stderr_buffer; /* Buffer for stderr data. */ -static u_long stdin_bytes, stdout_bytes, stderr_bytes; static u_int buffer_high;/* Soft max buffer size. */ static int connection_in; /* Connection to server (input). */ static int connection_out; /* Connection to server (output). */ static int need_rekeying; /* Set to non-zero if rekeying is requested. */ static int session_closed = 0; /* In SSH2: login session closed. */ -static int server_alive_timeouts = 0; static void client_init_dispatch(void); int session_ident = -1; -struct confirm_ctx { - int want_tty; - int want_subsys; - int want_x_fwd; - int want_agent_fwd; - Buffer cmd; - char *term; - struct termios tio; - char **env; +/* Track escape per proto2 channel */ +struct escape_filter_ctx { + int escape_pending; + int escape_char; }; +/* Context for channel confirmation replies */ +struct channel_reply_ctx { + const char *request_type; + int id, do_close; +}; + +/* Global request success/failure callbacks */ +struct global_confirm { + TAILQ_ENTRY(global_confirm) entry; + global_confirm_cb *cb; + void *ctx; + int ref_count; +}; +TAILQ_HEAD(global_confirms, global_confirm); +static struct global_confirms global_confirms = + TAILQ_HEAD_INITIALIZER(global_confirms); + /*XXX*/ extern Kex *xxx_kex; @@ -290,19 +301,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) { @@ -370,7 +391,10 @@ client_check_initial_eof_on_stdin(void) /* Check for immediate EOF on stdin. */ len = read(fileno(stdin), buf, 1); if (len == 0) { - /* EOF. Record that we have seen it and send EOF to server. */ + /* + * EOF. Record that we have seen it and send + * EOF to server. + */ debug("Sending eof."); stdin_eof = 1; packet_start(SSH_CMSG_EOF); @@ -381,8 +405,8 @@ client_check_initial_eof_on_stdin(void) * and also process it as an escape character if * appropriate. */ - if ((u_char) buf[0] == escape_char) - escape_pending = 1; + if ((u_char) buf[0] == escape_char1) + escape_pending1 = 1; else buffer_append(&stdin_buffer, buf, 1); } @@ -412,7 +436,6 @@ client_make_packets_from_stdin_data(void) packet_put_string(buffer_ptr(&stdin_buffer), len); packet_send(); buffer_consume(&stdin_buffer, len); - stdin_bytes += len; /* If we have a pending EOF, send it now. */ if (stdin_eof && buffer_len(&stdin_buffer) == 0) { packet_start(SSH_CMSG_EOF); @@ -457,14 +480,25 @@ client_check_window_change(void) static void client_global_request_reply(int type, u_int32_t seq, void *ctxt) { - server_alive_timeouts = 0; - client_global_request_reply_fwd(type, seq, ctxt); + struct global_confirm *gc; + + if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) + return; + if (gc->cb != NULL) + gc->cb(type, seq, gc->ctx); + if (--gc->ref_count <= 0) { + TAILQ_REMOVE(&global_confirms, gc, entry); + bzero(gc, sizeof(*gc)); + xfree(gc); + } + + keep_alive_timeouts = 0; } static void server_alive_check(void) { - if (++server_alive_timeouts > options.server_alive_count_max) { + if (++keep_alive_timeouts > options.server_alive_count_max) { logit("Timeout, server not responding."); cleanup_exit(255); } @@ -472,6 +506,8 @@ server_alive_check(void) packet_put_cstring("keepalive@openssh.com"); packet_put_char(1); /* boolean: want reply */ packet_send(); + /* Insert an empty placeholder to maintain ordering */ + client_register_global_confirm(NULL, NULL); } /* @@ -523,8 +559,8 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, if (packet_have_data_to_write()) FD_SET(connection_out, *writesetp); - if (control_fd != -1) - FD_SET(control_fd, *readsetp); + if (muxserver_sock != -1) + FD_SET(muxserver_sock, *readsetp); /* * Wait for something to happen. This will suspend the process until @@ -566,9 +602,11 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) { /* Flush stdout and stderr buffers. */ if (buffer_len(bout) > 0) - atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); + atomicio(vwrite, fileno(stdout), buffer_ptr(bout), + buffer_len(bout)); if (buffer_len(berr) > 0) - atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); + atomicio(vwrite, fileno(stderr), buffer_ptr(berr), + buffer_len(berr)); leave_raw_mode(); @@ -608,9 +646,13 @@ client_process_net_input(fd_set *readset) /* Read as much as possible. */ len = read(connection_in, buf, sizeof(buf)); if (len == 0) { - /* Received EOF. The remote host has closed the connection. */ - snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", - host); + /* + * Received EOF. The remote host has closed the + * connection. + */ + snprintf(buf, sizeof buf, + "Connection to %.300s closed by remote host.\r\n", + host); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; return; @@ -619,13 +661,18 @@ client_process_net_input(fd_set *readset) * There is a kernel bug on Solaris that causes select to * sometimes wake up even though there is no data available. */ - if (len < 0 && (errno == EAGAIN || errno == EINTR)) + if (len < 0 && + (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) len = 0; if (len < 0) { - /* An error has encountered. Perhaps there is a network problem. */ - snprintf(buf, sizeof buf, "Read from remote host %.300s: %.100s\r\n", - host, strerror(errno)); + /* + * An error has encountered. Perhaps there is a + * network problem. + */ + snprintf(buf, sizeof buf, + "Read from remote host %.300s: %.100s\r\n", + host, strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; return; @@ -635,283 +682,81 @@ client_process_net_input(fd_set *readset) } static void -client_subsystem_reply(int type, u_int32_t seq, void *ctxt) +client_status_confirm(int type, Channel *c, void *ctx) { - int id; - Channel *c; - - id = packet_get_int(); - packet_check_eom(); - - if ((c = channel_lookup(id)) == NULL) { - error("%s: no channel for id %d", __func__, id); - return; - } - - if (type == SSH2_MSG_CHANNEL_SUCCESS) - debug2("Request suceeded on channel %d", id); - else if (type == SSH2_MSG_CHANNEL_FAILURE) { - error("Request failed on channel %d", id); - channel_free(c); + struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx; + char errmsg[256]; + int tochan; + + /* XXX supress on mux _client_ quietmode */ + tochan = options.log_level >= SYSLOG_LEVEL_ERROR && + c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE; + + if (type == SSH2_MSG_CHANNEL_SUCCESS) { + debug2("%s request accepted on channel %d", + cr->request_type, c->self); + } else if (type == SSH2_MSG_CHANNEL_FAILURE) { + if (tochan) { + snprintf(errmsg, sizeof(errmsg), + "%s request failed\r\n", cr->request_type); + } else { + snprintf(errmsg, sizeof(errmsg), + "%s request failed on channel %d", + cr->request_type, c->self); + } + /* If error occurred on primary session channel, then exit */ + if (cr->do_close && c->self == session_ident) + fatal("%s", errmsg); + /* If error occurred on mux client, append to their stderr */ + if (tochan) + buffer_append(&c->extended, errmsg, strlen(errmsg)); + else + error("%s", errmsg); + if (cr->do_close) { + chan_read_failed(c); + chan_write_failed(c); + } } + xfree(cr); } static void -client_extra_session2_setup(int id, void *arg) +client_abandon_status_confirm(Channel *c, void *ctx) { - struct confirm_ctx *cctx = arg; - const char *display; - Channel *c; - int i; - - if (cctx == NULL) - fatal("%s: cctx == NULL", __func__); - if ((c = channel_lookup(id)) == NULL) - fatal("%s: no channel for id %d", __func__, id); - - display = getenv("DISPLAY"); - if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { - char *proto, *data; - /* Get reasonable local authentication information. */ - client_x11_get_proto(display, options.xauth_location, - options.forward_x11_trusted, &proto, &data); - /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); - x11_request_forwarding_with_spoofing(id, display, proto, data); - /* XXX wait for reply */ - } - - if (cctx->want_agent_fwd && options.forward_agent) { - debug("Requesting authentication agent forwarding."); - channel_request_start(id, "auth-agent-req@openssh.com", 0); - packet_send(); - } - - client_session2_setup(id, cctx->want_tty, cctx->want_subsys, - cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env, - client_subsystem_reply); - - c->confirm_ctx = NULL; - buffer_free(&cctx->cmd); - xfree(cctx->term); - if (cctx->env != NULL) { - for (i = 0; cctx->env[i] != NULL; i++) - xfree(cctx->env[i]); - xfree(cctx->env); - } - xfree(cctx); + xfree(ctx); } static void -client_process_control(fd_set *readset) +client_expect_confirm(int id, const char *request, int do_close) { - Buffer m; - Channel *c; - int client_fd, new_fd[3], ver, allowed; - socklen_t addrlen; - struct sockaddr_storage addr; - struct confirm_ctx *cctx; - char *cmd; - u_int i, len, env_len, command, flags; - uid_t euid; - gid_t egid; - - /* - * Accept connection on control socket - */ - if (control_fd == -1 || !FD_ISSET(control_fd, readset)) - return; - - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - if ((client_fd = accept(control_fd, - (struct sockaddr*)&addr, &addrlen)) == -1) { - error("%s accept: %s", __func__, strerror(errno)); - return; - } - - if (getpeereid(client_fd, &euid, &egid) < 0) { - error("%s getpeereid failed: %s", __func__, strerror(errno)); - close(client_fd); - return; - } - if ((euid != 0) && (getuid() != euid)) { - error("control mode uid mismatch: peer euid %u != uid %u", - (u_int) euid, (u_int) getuid()); - close(client_fd); - return; - } - - unset_nonblock(client_fd); - - /* Read command */ - buffer_init(&m); - if (ssh_msg_recv(client_fd, &m) == -1) { - error("%s: client msg_recv failed", __func__); - close(client_fd); - buffer_free(&m); - return; - } - if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { - error("%s: wrong client version %d", __func__, ver); - buffer_free(&m); - close(client_fd); - return; - } + struct channel_reply_ctx *cr = xmalloc(sizeof(*cr)); - allowed = 1; - command = buffer_get_int(&m); - flags = buffer_get_int(&m); - - buffer_clear(&m); - - switch (command) { - case SSHMUX_COMMAND_OPEN: - if (options.control_master == SSHCTL_MASTER_ASK || - options.control_master == SSHCTL_MASTER_AUTO_ASK) - allowed = ask_permission("Allow shared connection " - "to %s? ", host); - /* continue below */ - break; - case SSHMUX_COMMAND_TERMINATE: - if (options.control_master == SSHCTL_MASTER_ASK || - options.control_master == SSHCTL_MASTER_AUTO_ASK) - allowed = ask_permission("Terminate shared connection " - "to %s? ", host); - if (allowed) - quit_pending = 1; - /* FALLTHROUGH */ - case SSHMUX_COMMAND_ALIVE_CHECK: - /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ - buffer_clear(&m); - buffer_put_int(&m, allowed); - buffer_put_int(&m, getpid()); - if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { - error("%s: client msg_send failed", __func__); - close(client_fd); - buffer_free(&m); - return; - } - buffer_free(&m); - close(client_fd); - return; - default: - error("Unsupported command %d", command); - buffer_free(&m); - close(client_fd); - return; - } + cr->request_type = request; + cr->do_close = do_close; - /* Reply for SSHMUX_COMMAND_OPEN */ - buffer_clear(&m); - buffer_put_int(&m, allowed); - buffer_put_int(&m, getpid()); - if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { - error("%s: client msg_send failed", __func__); - close(client_fd); - buffer_free(&m); - return; - } - - if (!allowed) { - error("Refused control connection"); - close(client_fd); - buffer_free(&m); - return; - } - - buffer_clear(&m); - if (ssh_msg_recv(client_fd, &m) == -1) { - error("%s: client msg_recv failed", __func__); - close(client_fd); - buffer_free(&m); - return; - } - if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { - error("%s: wrong client version %d", __func__, ver); - buffer_free(&m); - close(client_fd); - return; - } - - cctx = xcalloc(1, sizeof(*cctx)); - cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; - cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; - cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; - cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; - cctx->term = buffer_get_string(&m, &len); - - cmd = buffer_get_string(&m, &len); - buffer_init(&cctx->cmd); - buffer_append(&cctx->cmd, cmd, strlen(cmd)); - - env_len = buffer_get_int(&m); - env_len = MIN(env_len, 4096); - debug3("%s: receiving %d env vars", __func__, env_len); - if (env_len != 0) { - cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env)); - for (i = 0; i < env_len; i++) - cctx->env[i] = buffer_get_string(&m, &len); - cctx->env[i] = NULL; - } + channel_register_status_confirm(id, client_status_confirm, + client_abandon_status_confirm, cr); +} - debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, - cctx->want_tty, cctx->want_subsys, cmd); - xfree(cmd); - - /* Gather fds from client */ - new_fd[0] = mm_receive_fd(client_fd); - new_fd[1] = mm_receive_fd(client_fd); - new_fd[2] = mm_receive_fd(client_fd); - - debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, - new_fd[0], new_fd[1], new_fd[2]); - - /* Try to pick up ttymodes from client before it goes raw */ - if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) - error("%s: tcgetattr: %s", __func__, strerror(errno)); - - /* This roundtrip is just for synchronisation of ttymodes */ - buffer_clear(&m); - if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { - error("%s: client msg_send failed", __func__); - close(client_fd); - close(new_fd[0]); - close(new_fd[1]); - close(new_fd[2]); - buffer_free(&m); - xfree(cctx->term); - if (env_len != 0) { - for (i = 0; i < env_len; i++) - xfree(cctx->env[i]); - xfree(cctx->env); - } +void +client_register_global_confirm(global_confirm_cb *cb, void *ctx) +{ + struct global_confirm *gc, *last_gc; + + /* Coalesce identical callbacks */ + last_gc = TAILQ_LAST(&global_confirms, global_confirms); + if (last_gc && last_gc->cb == cb && last_gc->ctx == ctx) { + if (++last_gc->ref_count >= INT_MAX) + fatal("%s: last_gc->ref_count = %d", + __func__, last_gc->ref_count); return; } - buffer_free(&m); - - /* enable nonblocking unless tty */ - if (!isatty(new_fd[0])) - set_nonblock(new_fd[0]); - if (!isatty(new_fd[1])) - set_nonblock(new_fd[1]); - if (!isatty(new_fd[2])) - set_nonblock(new_fd[2]); - - set_nonblock(client_fd); - c = channel_new("session", SSH_CHANNEL_OPENING, - new_fd[0], new_fd[1], new_fd[2], - CHAN_SES_WINDOW_DEFAULT, CHAN_SES_PACKET_DEFAULT, - CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); - - /* XXX */ - c->ctl_fd = client_fd; - - debug3("%s: channel_new: %d", __func__, c->self); - - channel_send_open(c->self); - channel_register_confirm(c->self, client_extra_session2_setup, cctx); + gc = xmalloc(sizeof(*gc)); + gc->cb = cb; + gc->ctx = ctx; + gc->ref_count = 1; + TAILQ_INSERT_TAIL(&global_confirms, gc, entry); } static void @@ -924,12 +769,15 @@ process_cmdline(void) u_short cancel_port; Forward fwd; + bzero(&fwd, sizeof(fwd)); + fwd.listen_host = fwd.connect_host = NULL; + leave_raw_mode(); handler = signal(SIGINT, SIG_IGN); 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 */ @@ -976,9 +824,8 @@ process_cmdline(void) goto out; } - s++; - while (*s && isspace(*s)) - s++; + while (isspace(*++s)) + ; if (delete) { cancel_port = 0; @@ -1024,11 +871,18 @@ out: enter_raw_mode(); if (cmd) xfree(cmd); + if (fwd.listen_host != NULL) + xfree(fwd.listen_host); + if (fwd.connect_host != NULL) + xfree(fwd.connect_host); } -/* process the characters one by one */ +/* + * Process the characters one by one, call with c==NULL for proto1 case. + */ static int -process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) +process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, + char *buf, int len) { char string[1024]; pid_t pid; @@ -1036,7 +890,20 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) u_int i; u_char ch; char *s; + int *escape_pendingp, escape_char; + struct escape_filter_ctx *efc; + if (c == NULL) { + escape_pendingp = &escape_pending1; + escape_char = escape_char1; + } else { + if (c->filter_ctx == NULL) + return 0; + efc = (struct escape_filter_ctx *)c->filter_ctx; + escape_pendingp = &efc->escape_pending; + escape_char = efc->escape_char; + } + if (len <= 0) return (0); @@ -1044,25 +911,42 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) /* Get one character at a time. */ ch = buf[i]; - if (escape_pending) { + if (*escape_pendingp) { /* We have previously seen an escape character. */ /* Clear the flag now. */ - escape_pending = 0; + *escape_pendingp = 0; /* Process the escaped character. */ switch (ch) { case '.': /* Terminate the connection. */ - snprintf(string, sizeof string, "%c.\r\n", escape_char); + snprintf(string, sizeof string, "%c.\r\n", + escape_char); buffer_append(berr, string, strlen(string)); - quit_pending = 1; + if (c && c->ctl_fd != -1) { + chan_read_failed(c); + chan_write_failed(c); + return 0; + } else + quit_pending = 1; return -1; case 'Z' - 64: - /* Suspend the program. */ - /* Print a message to that effect to the user. */ - snprintf(string, sizeof string, "%c^Z [suspend ssh]\r\n", escape_char); + /* XXX support this for mux clients */ + if (c && c->ctl_fd != -1) { + noescape: + snprintf(string, sizeof string, + "%c%c escape not available to " + "multiplexed sessions\r\n", + escape_char, ch); + buffer_append(berr, string, + strlen(string)); + continue; + } + /* Suspend the program. Inform the user */ + snprintf(string, sizeof string, + "%c^Z [suspend ssh]\r\n", escape_char); buffer_append(berr, string, strlen(string)); /* Restore terminal modes and suspend. */ @@ -1087,16 +971,20 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) case 'R': if (compat20) { if (datafellows & SSH_BUG_NOREKEY) - logit("Server does not support re-keying"); + logit("Server does not " + "support re-keying"); else need_rekeying = 1; } continue; case '&': + if (c && c->ctl_fd != -1) + goto noescape; /* - * Detach the program (continue to serve connections, - * but put in background and no more new connections). + * Detach the program (continue to serve + * connections, but put in background and no + * more new connections). */ /* Restore tty modes. */ leave_raw_mode(); @@ -1125,9 +1013,9 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) return -1; } else if (!stdin_eof) { /* - * Sending SSH_CMSG_EOF alone does not always appear - * to be enough. So we try to send an EOF character - * first. + * Sending SSH_CMSG_EOF alone does not + * always appear to be enough. So we + * try to send an EOF character first. */ packet_start(SSH_CMSG_STDIN_DATA); packet_put_string("\004", 1); @@ -1142,27 +1030,50 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) continue; case '?': - snprintf(string, sizeof string, + if (c && c->ctl_fd != -1) { + snprintf(string, sizeof string, +"%c?\r\n\ +Supported escape sequences:\r\n\ + %c. - terminate session\r\n\ + %cB - send a BREAK to the remote system\r\n\ + %cC - open a command line\r\n\ + %cR - Request rekey (SSH protocol 2 only)\r\n\ + %c# - list forwarded connections\r\n\ + %c? - this message\r\n\ + %c%c - send the escape character by typing it twice\r\n\ +(Note that escapes are only recognized immediately after newline.)\r\n", + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char); + } else { + snprintf(string, sizeof string, "%c?\r\n\ Supported escape sequences:\r\n\ -%c. - terminate connection\r\n\ -%cB - send a BREAK to the remote system\r\n\ -%cC - open a command line\r\n\ -%cR - Request rekey (SSH protocol 2 only)\r\n\ -%c^Z - suspend ssh\r\n\ -%c# - list forwarded connections\r\n\ -%c& - background ssh (when waiting for connections to terminate)\r\n\ -%c? - this message\r\n\ -%c%c - send the escape character by typing it twice\r\n\ + %c. - terminate connection (and any multiplexed sessions)\r\n\ + %cB - send a BREAK to the remote system\r\n\ + %cC - open a command line\r\n\ + %cR - Request rekey (SSH protocol 2 only)\r\n\ + %c^Z - suspend ssh\r\n\ + %c# - list forwarded connections\r\n\ + %c& - background ssh (when waiting for connections to terminate)\r\n\ + %c? - this message\r\n\ + %c%c - send the escape character by typing it twice\r\n\ (Note that escapes are only recognized immediately after newline.)\r\n", - escape_char, escape_char, escape_char, escape_char, - escape_char, escape_char, escape_char, escape_char, - escape_char, escape_char, escape_char); + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char); + } buffer_append(berr, string, strlen(string)); continue; case '#': - snprintf(string, sizeof string, "%c#\r\n", escape_char); + snprintf(string, sizeof string, "%c#\r\n", + escape_char); buffer_append(berr, string, strlen(string)); s = channel_open_message(); buffer_append(berr, s, strlen(s)); @@ -1183,12 +1094,15 @@ Supported escape sequences:\r\n\ } } else { /* - * The previous character was not an escape char. Check if this - * is an escape. + * The previous character was not an escape char. + * Check if this is an escape. */ if (last_was_cr && ch == escape_char) { - /* It is. Set the flag and continue to next character. */ - escape_pending = 1; + /* + * It is. Set the flag and continue to + * next character. + */ + *escape_pendingp = 1; continue; } } @@ -1214,7 +1128,8 @@ client_process_input(fd_set *readset) if (FD_ISSET(fileno(stdin), readset)) { /* Read as much as possible. */ len = read(fileno(stdin), buf, sizeof(buf)); - if (len < 0 && (errno == EAGAIN || errno == EINTR)) + if (len < 0 && + (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) return; /* we'll try again later */ if (len <= 0) { /* @@ -1223,7 +1138,8 @@ client_process_input(fd_set *readset) * if it was an error condition. */ if (len < 0) { - snprintf(buf, sizeof buf, "read: %.100s\r\n", strerror(errno)); + snprintf(buf, sizeof buf, "read: %.100s\r\n", + strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); } /* Mark that we have seen EOF. */ @@ -1239,7 +1155,7 @@ client_process_input(fd_set *readset) packet_start(SSH_CMSG_EOF); packet_send(); } - } else if (escape_char == SSH_ESCAPECHAR_NONE) { + } else if (escape_char1 == SSH_ESCAPECHAR_NONE) { /* * Normal successful read, and no escape character. * Just append the data to buffer. @@ -1247,11 +1163,12 @@ client_process_input(fd_set *readset) buffer_append(&stdin_buffer, buf, len); } else { /* - * Normal, successful read. But we have an escape character - * and have to process the characters one by one. + * Normal, successful read. But we have an escape + * character and have to process the characters one + * by one. */ - if (process_escapes(&stdin_buffer, &stdout_buffer, - &stderr_buffer, buf, len) == -1) + if (process_escapes(NULL, &stdin_buffer, + &stdout_buffer, &stderr_buffer, buf, len) == -1) return; } } @@ -1269,14 +1186,16 @@ client_process_output(fd_set *writeset) len = write(fileno(stdout), buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer)); if (len <= 0) { - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK) len = 0; else { /* * An error or EOF was encountered. Put an * error message to stderr buffer. */ - snprintf(buf, sizeof buf, "write stdout: %.50s\r\n", strerror(errno)); + snprintf(buf, sizeof buf, + "write stdout: %.50s\r\n", strerror(errno)); buffer_append(&stderr_buffer, buf, strlen(buf)); quit_pending = 1; return; @@ -1284,7 +1203,6 @@ client_process_output(fd_set *writeset) } /* Consume printed data from the buffer. */ buffer_consume(&stdout_buffer, len); - stdout_bytes += len; } /* Write buffered output to stderr. */ if (FD_ISSET(fileno(stderr), writeset)) { @@ -1292,17 +1210,20 @@ client_process_output(fd_set *writeset) len = write(fileno(stderr), buffer_ptr(&stderr_buffer), buffer_len(&stderr_buffer)); if (len <= 0) { - if (errno == EINTR || errno == EAGAIN) + if (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK) len = 0; else { - /* EOF or error, but can't even print error message. */ + /* + * EOF or error, but can't even print + * error message. + */ quit_pending = 1; return; } } /* Consume printed characters from the buffer. */ buffer_consume(&stderr_buffer, len); - stderr_bytes += len; } } @@ -1321,16 +1242,39 @@ client_process_output(fd_set *writeset) static void client_process_buffered_input_packets(void) { - dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL); + dispatch_run(DISPATCH_NONBLOCK, &quit_pending, + compat20 ? xxx_kex : NULL); } /* scan buf[] for '~' before sending data to the peer */ -static int -simple_escape_filter(Channel *c, char *buf, int len) +/* Helper: allocate a new escape_filter_ctx and fill in its escape char */ +void * +client_new_escape_filter_ctx(int escape_char) +{ + struct escape_filter_ctx *ret; + + ret = xmalloc(sizeof(*ret)); + ret->escape_pending = 0; + ret->escape_char = escape_char; + return (void *)ret; +} + +/* Free the escape filter context on channel free */ +void +client_filter_cleanup(int cid, void *ctx) { - /* XXX we assume c->extended is writeable */ - return process_escapes(&c->input, &c->output, &c->extended, buf, len); + xfree(ctx); +} + +int +client_simple_escape_filter(Channel *c, char *buf, int len) +{ + if (c->extended_usage != CHAN_EXTENDED_WRITE) + return 0; + + return process_escapes(c, &c->input, &c->output, &c->extended, + buf, len); } static void @@ -1354,6 +1298,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) fd_set *readset = NULL, *writeset = NULL; double start_time, total_time; int max_fd = 0, max_fd2 = 0, len, rekeying = 0; + u_int64_t ibytes, obytes; u_int nalloc = 0; char buf[100]; @@ -1362,7 +1307,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) start_time = get_current_time(); /* Initialize variables. */ - escape_pending = 0; + escape_pending1 = 0; last_was_cr = 1; exit_status = -1; stdin_eof = 0; @@ -1370,8 +1315,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); max_fd = MAX(connection_in, connection_out); - if (control_fd != -1) - max_fd = MAX(max_fd, control_fd); + if (muxserver_sock != -1) + max_fd = MAX(max_fd, muxserver_sock); if (!compat20) { /* enable nonblocking unless tty */ @@ -1385,11 +1330,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) max_fd = MAX(max_fd, fileno(stdout)); max_fd = MAX(max_fd, fileno(stderr)); } - stdin_bytes = 0; - stdout_bytes = 0; - stderr_bytes = 0; quit_pending = 0; - escape_char = escape_char_arg; + escape_char1 = escape_char_arg; /* Initialize buffers. */ buffer_init(&stdin_buffer); @@ -1417,9 +1359,11 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) if (compat20) { session_ident = ssh2_chan_id; - if (escape_char != SSH_ESCAPECHAR_NONE) + if (escape_char_arg != SSH_ESCAPECHAR_NONE) channel_register_filter(session_ident, - simple_escape_filter, NULL); + client_simple_escape_filter, NULL, + client_filter_cleanup, + client_new_escape_filter_ctx(escape_char_arg)); if (session_ident != -1) channel_register_cleanup(session_ident, client_channel_closed, 0); @@ -1491,7 +1435,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) client_process_net_input(readset); /* Accept control connections. */ - client_process_control(readset); + if (muxserver_sock != -1 &&FD_ISSET(muxserver_sock, readset)) { + if (muxserver_accept_control()) + quit_pending = 1; + } if (quit_pending) break; @@ -1506,7 +1453,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) client_process_output(writeset); } - /* Send as much buffered packet data as possible to the sender. */ + /* + * Send as much buffered packet data as possible to the + * sender. + */ if (FD_ISSET(connection_out, writeset)) packet_write_poll(); } @@ -1551,7 +1501,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) * that the connection has been closed. */ if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) { - snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host); + snprintf(buf, sizeof buf, + "Connection to %.64s closed.\r\n", host); buffer_append(&stderr_buffer, buf, strlen(buf)); } @@ -1564,7 +1515,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) break; } buffer_consume(&stdout_buffer, len); - stdout_bytes += len; } /* Output any buffered data for stderr. */ @@ -1576,7 +1526,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) break; } buffer_consume(&stderr_buffer, len); - stderr_bytes += len; } /* Clear and free any buffers. */ @@ -1587,13 +1536,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Report bytes transferred, and transfer rates. */ total_time = get_current_time() - start_time; - debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds", - stdin_bytes, stdout_bytes, stderr_bytes, total_time); + packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); + packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); + verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", + obytes, ibytes, total_time); if (total_time > 0) - debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f", - stdin_bytes / total_time, stdout_bytes / total_time, - stderr_bytes / total_time); - + verbose("Bytes per second: sent %.1f, received %.1f", + obytes / total_time, ibytes / total_time); /* Return the exit status of the program. */ debug("Exit status %d", exit_status); return exit_status; @@ -1684,7 +1633,6 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) Channel *c = NULL; char *listen_address, *originator_address; int listen_port, originator_port; - int sock; /* Get rest of the packet */ listen_address = packet_get_string(NULL); @@ -1693,19 +1641,13 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) originator_port = packet_get_int(); packet_check_eom(); - debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d", - listen_address, listen_port, originator_address, originator_port); + debug("client_request_forwarded_tcpip: listen %s port %d, " + "originator %s port %d", listen_address, listen_port, + originator_address, originator_port); + + c = channel_connect_by_listen_address(listen_port, + "forwarded-tcpip", originator_address); - sock = channel_connect_by_listen_address(listen_port); - if (sock < 0) { - xfree(originator_address); - xfree(listen_address); - return NULL; - } - c = channel_new("forwarded-tcpip", - SSH_CHANNEL_CONNECTING, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - originator_address, 1); xfree(originator_address); xfree(listen_address); return c; @@ -1721,7 +1663,8 @@ client_request_x11(const char *request_type, int rchan) if (!options.forward_x11) { error("Warning: ssh server tried X11 forwarding."); - error("Warning: this is probably a break-in attempt by a malicious server."); + error("Warning: this is probably a break-in attempt by a " + "malicious server."); return NULL; } originator = packet_get_string(NULL); @@ -1754,20 +1697,65 @@ client_request_agent(const char *request_type, int rchan) if (!options.forward_agent) { error("Warning: ssh server tried agent forwarding."); - error("Warning: this is probably a break-in attempt by a malicious server."); + error("Warning: this is probably a break-in attempt by a " + "malicious server."); return NULL; } - sock = ssh_get_authentication_socket(); + sock = ssh_get_authentication_socket(); if (sock < 0) return NULL; c = channel_new("authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, - CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, + CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "authentication agent connection", 1); c->force_drain = 1; 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, NULL, NULL); +#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) @@ -1836,7 +1824,11 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) if (id == -1) { error("client_input_channel_req: request for channel -1"); } else if ((c = channel_lookup(id)) == NULL) { - error("client_input_channel_req: channel %d: unknown channel", id); + error("client_input_channel_req: channel %d: " + "unknown channel", id); + } else if (strcmp(rtype, "eow@openssh.com") == 0) { + packet_check_eom(); + chan_rcvd_eow(c); } else if (strcmp(rtype, "exit-status") == 0) { exitval = packet_get_int(); if (id == session_ident) { @@ -1881,8 +1873,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt) void client_session2_setup(int id, int want_tty, int want_subsystem, - const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env, - dispatch_fn *subsys_repl) + const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env) { int len; Channel *c = NULL; @@ -1894,20 +1885,21 @@ client_session2_setup(int id, int want_tty, int want_subsystem, if (want_tty) { struct winsize ws; - struct termios tio; /* Store window size in the packet. */ if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) memset(&ws, 0, sizeof(ws)); - channel_request_start(id, "pty-req", 0); + channel_request_start(id, "pty-req", 1); + client_expect_confirm(id, "PTY allocation", 0); packet_put_cstring(term != NULL ? term : ""); packet_put_int((u_int)ws.ws_col); packet_put_int((u_int)ws.ws_row); packet_put_int((u_int)ws.ws_xpixel); packet_put_int((u_int)ws.ws_ypixel); - tio = get_saved_tio(); - tty_make_modes(-1, tiop != NULL ? tiop : &tio); + if (tiop == NULL) + tiop = get_saved_tio(); + tty_make_modes(-1, tiop); packet_send(); /* XXX wait for reply */ c->client_tty = 1; @@ -1955,22 +1947,21 @@ client_session2_setup(int id, int want_tty, int want_subsystem, if (len > 900) len = 900; if (want_subsystem) { - debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd)); - channel_request_start(id, "subsystem", subsys_repl != NULL); - if (subsys_repl != NULL) { - /* register callback for reply */ - /* XXX we assume that client_loop has already been called */ - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl); - dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl); - } + debug("Sending subsystem: %.*s", + len, (u_char*)buffer_ptr(cmd)); + channel_request_start(id, "subsystem", 1); + client_expect_confirm(id, "subsystem", 1); } else { - debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd)); - channel_request_start(id, "exec", 0); + debug("Sending command: %.*s", + len, (u_char*)buffer_ptr(cmd)); + channel_request_start(id, "exec", 1); + client_expect_confirm(id, "exec", 1); } packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); packet_send(); } else { - channel_request_start(id, "shell", 0); + channel_request_start(id, "shell", 1); + client_expect_confirm(id, "shell", 1); packet_send(); } } @@ -1989,6 +1980,8 @@ client_init_dispatch_20(void) dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); + dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); /* rekeying */ @@ -1998,6 +1991,7 @@ client_init_dispatch_20(void) dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); } + static void client_init_dispatch_13(void) { @@ -2017,6 +2011,7 @@ client_init_dispatch_13(void) dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ? &x11_input_open : &deny_input_open); } + static void client_init_dispatch_15(void) { @@ -2024,6 +2019,7 @@ client_init_dispatch_15(void) dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof); dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose); } + static void client_init_dispatch(void) { @@ -2041,7 +2037,7 @@ cleanup_exit(int i) { leave_raw_mode(); leave_non_blocking(); - if (options.control_path != NULL && control_fd != -1) + if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); _exit(i); } diff --git a/crypto/openssh/clientloop.h b/crypto/openssh/clientloop.h index beec62f..8bb874b 100644 --- a/crypto/openssh/clientloop.h +++ b/crypto/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.22 2008/06/12 15:19:17 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -43,10 +43,20 @@ void client_x11_get_proto(const char *, const char *, u_int, char **, char **); void client_global_request_reply_fwd(int, u_int32_t, void *); void client_session2_setup(int, int, int, const char *, struct termios *, - int, Buffer *, char **, dispatch_fn *); + int, Buffer *, char **); +int client_request_tun_fwd(int, int, int); + +/* Escape filter for protocol 2 sessions */ +void *client_new_escape_filter_ctx(int); +void client_filter_cleanup(int, void *); +int client_simple_escape_filter(Channel *, char *, int); + +/* Global request confirmation callbacks */ +typedef void global_confirm_cb(int, u_int32_t seq, void *); +void client_register_global_confirm(global_confirm_cb *, void *); /* Multiplexing protocol version */ -#define SSHMUX_VER 1 +#define SSHMUX_VER 2 /* Multiplexing control protocol flags */ #define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ @@ -57,3 +67,7 @@ void client_session2_setup(int, int, int, const char *, struct termios *, #define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */ #define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */ #define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */ + +void muxserver_listen(void); +int muxserver_accept_control(void); +void muxclient(const char *); diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c index da67f94..bc11315 100644 --- a/crypto/openssh/compat.c +++ b/crypto/openssh/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.76 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: compat.c,v 1.77 2006/12/12 03:58:42 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -133,7 +133,8 @@ compat_datafellows(const char *version) { "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5| SSH_BUG_FIRSTKEX }, { "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */ - { "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX }, + { "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX| + SSH_BUG_RFWD_ADDR }, { "3.0.*", SSH_BUG_DEBUG }, { "3.0 SecureCRT*", SSH_OLD_SESSIONID }, { "1.7 SecureFX*", SSH_OLD_SESSIONID }, diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h index 83d469d..4d8ebc9 100644 --- a/crypto/openssh/compat.h +++ b/crypto/openssh/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.40 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: compat.h,v 1.41 2006/12/12 03:58:42 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -56,6 +56,7 @@ #define SSH_BUG_PROBE 0x00400000 #define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_OLD_FORWARD_ADDR 0x01000000 +#define SSH_BUG_RFWD_ADDR 0x02000000 void enable_compat13(void); void enable_compat20(void); diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index d135826..f54e5a8 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -1,4 +1,4 @@ -/* config.h. Generated by configure. */ +/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address @@ -8,6 +8,9 @@ /* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ /* #undef AIX_LOGINFAILED_4ARG */ +/* System only supports IPv4 audit records */ +/* #undef AU_IPv4 */ + /* Define if your resolver libs need this for getrrsetbyname */ /* #undef BIND_8_COMPAT */ @@ -20,6 +23,9 @@ /* getgroups(0,NULL) will return -1 */ /* #undef BROKEN_GETGROUPS */ +/* FreeBSD glob does not do what we need */ +#define BROKEN_GLOB 1 + /* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ /* #undef BROKEN_INET_NTOA */ @@ -33,6 +39,9 @@ */ /* #undef BROKEN_ONE_BYTE_DIRENT_D_NAME */ +/* Can't do comparisons on readv */ +/* #undef BROKEN_READV_COMPARISON */ + /* Define if you have a broken realpath. */ /* #undef BROKEN_REALPATH */ @@ -54,6 +63,9 @@ /* LynxOS has broken setvbuf() implementation */ /* #undef BROKEN_SETVBUF */ +/* QNX shadow support is broken */ +/* #undef BROKEN_SHADOW_EXPIRE */ + /* Define if your snprintf is busted */ /* #undef BROKEN_SNPRINTF */ @@ -108,12 +120,12 @@ /* Define if you don't want to use wtmpx */ #define DISABLE_WTMPX 1 -/* Workaround more Linux IPv6 quirks */ -/* #undef DONT_TRY_OTHER_AF */ - /* Builtin PRNG command timeout */ #define ENTROPY_TIMEOUT_MSEC 200 +/* f_fsid has members */ +/* #undef FSID_HAS_VAL */ + /* Define to 1 if the `getpgrp' function requires zero arguments. */ #define GETPGRP_VOID 1 @@ -150,15 +162,27 @@ /* Define to 1 if you have the `arc4random' function. */ #define HAVE_ARC4RANDOM 1 +/* Define to 1 if you have the `arc4random_buf' function. */ +#define HAVE_ARC4RANDOM_BUF 1 + +/* Define to 1 if you have the `arc4random_uniform' function. */ +#define HAVE_ARC4RANDOM_UNIFORM 1 + /* Define to 1 if you have the `asprintf' function. */ #define HAVE_ASPRINTF 1 /* OpenBSD's gcc has bounded */ /* #undef HAVE_ATTRIBUTE__BOUNDED__ */ +/* Have attribute nonnull */ +#define HAVE_ATTRIBUTE__NONNULL__ 1 + /* OpenBSD's gcc has sentinel */ /* #undef HAVE_ATTRIBUTE__SENTINEL__ */ +/* Define to 1 if you have the `aug_get_machine' function. */ +/* #undef HAVE_AUG_GET_MACHINE */ + /* Define to 1 if you have the `b64_ntop' function. */ /* #undef HAVE_B64_NTOP */ @@ -231,6 +255,14 @@ don't. */ /* #undef HAVE_DECL_LOGINSUCCESS */ +/* Define to 1 if you have the declaration of `MAXSYMLINKS', and to 0 if you + don't. */ +#define HAVE_DECL_MAXSYMLINKS 1 + +/* Define to 1 if you have the declaration of `offsetof', and to 0 if you + don't. */ +#define HAVE_DECL_OFFSETOF 1 + /* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you don't. */ #define HAVE_DECL_O_NONBLOCK 1 @@ -310,9 +342,21 @@ /* Define to 1 if you have the <floatingpoint.h> header file. */ #define HAVE_FLOATINGPOINT_H 1 +/* Define to 1 if you have the `fmt_scaled' function. */ +/* #undef HAVE_FMT_SCALED */ + /* Define to 1 if you have the `freeaddrinfo' function. */ #define HAVE_FREEADDRINFO 1 +/* Define to 1 if the system has the type `fsblkcnt_t'. */ +#define HAVE_FSBLKCNT_T 1 + +/* Define to 1 if the system has the type `fsfilcnt_t'. */ +#define HAVE_FSFILCNT_T 1 + +/* Define to 1 if you have the `fstatvfs' function. */ +#define HAVE_FSTATVFS 1 + /* Define to 1 if you have the `futimes' function. */ #define HAVE_FUTIMES 1 @@ -334,6 +378,9 @@ /* Define to 1 if you have the `getgrouplist' function. */ #define HAVE_GETGROUPLIST 1 +/* Define to 1 if you have the `getgrset' function. */ +/* #undef HAVE_GETGRSET */ + /* Define to 1 if you have the `getluid' function. */ /* #undef HAVE_GETLUID */ @@ -355,6 +402,9 @@ /* Define to 1 if you have the `getpeereid' function. */ #define HAVE_GETPEEREID 1 +/* Define to 1 if you have the `getpeerucred' function. */ +/* #undef HAVE_GETPEERUCRED */ + /* Define to 1 if you have the `getpwanam' function. */ /* #undef HAVE_GETPWANAM */ @@ -481,7 +531,7 @@ /* Define to 1 if you have the <libgen.h> header file. */ #define HAVE_LIBGEN_H 1 -/* Define to 1 if you have the `iaf' library (-liaf). */ +/* Define if system has libiaf that supports set_id */ /* #undef HAVE_LIBIAF */ /* Define to 1 if you have the `nsl' library (-lnsl). */ @@ -620,6 +670,12 @@ /* define if you have pid_t data type */ #define HAVE_PID_T 1 +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the <poll.h> header file. */ +#define HAVE_POLL_H 1 + /* Define to 1 if you have the `prctl' function. */ /* #undef HAVE_PRCTL */ @@ -737,6 +793,9 @@ /* Define to 1 if you have the `setvbuf' function. */ #define HAVE_SETVBUF 1 +/* Define to 1 if you have the `set_id' function. */ +/* #undef HAVE_SET_ID */ + /* Define to 1 if you have the `SHA256_Update' function. */ #define HAVE_SHA256_UPDATE 1 @@ -773,6 +832,12 @@ /* Fields in struct sockaddr_storage */ #define HAVE_SS_FAMILY_IN_SS 1 +/* Define to 1 if you have the `statfs' function. */ +#define HAVE_STATFS 1 + +/* Define to 1 if you have the `statvfs' function. */ +#define HAVE_STATVFS 1 + /* Define to 1 if you have the <stddef.h> header file. */ #define HAVE_STDDEF_H 1 @@ -845,6 +910,9 @@ /* define if you have struct timeval */ #define HAVE_STRUCT_TIMEVAL 1 +/* Define to 1 if you have the `swap32' function. */ +/* #undef HAVE_SWAP32 */ + /* Define to 1 if you have the `sysconf' function. */ #define HAVE_SYSCONF 1 @@ -872,12 +940,18 @@ /* Define to 1 if you have the <sys/mman.h> header file. */ #define HAVE_SYS_MMAN_H 1 +/* Define to 1 if you have the <sys/mount.h> header file. */ +#define HAVE_SYS_MOUNT_H 1 + /* Define to 1 if you have the <sys/ndir.h> header file. */ /* #undef HAVE_SYS_NDIR_H */ /* Define if your system defines sys_nerr */ #define HAVE_SYS_NERR 1 +/* Define to 1 if you have the <sys/poll.h> header file. */ +#define HAVE_SYS_POLL_H 1 + /* Define to 1 if you have the <sys/prctl.h> header file. */ /* #undef HAVE_SYS_PRCTL_H */ @@ -890,6 +964,9 @@ /* Define to 1 if you have the <sys/select.h> header file. */ #define HAVE_SYS_SELECT_H 1 +/* Define to 1 if you have the <sys/statvfs.h> header file. */ +#define HAVE_SYS_STATVFS_H 1 + /* Define to 1 if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 @@ -959,6 +1036,9 @@ /* Define if you have ut_type in utmpx.h */ /* #undef HAVE_TYPE_IN_UTMPX */ +/* Define to 1 if you have the <ucred.h> header file. */ +/* #undef HAVE_UCRED_H */ + /* define if you have uintxx_t data type */ #define HAVE_UINTXX_T 1 @@ -1040,6 +1120,9 @@ /* Define to 1 if you have the `_getshort' function. */ #define HAVE__GETSHORT 1 +/* Define if you have struct __res_state _res as an extern */ +#define HAVE__RES_EXTERN 1 + /* Define to 1 if you have the `__b64_ntop' function. */ #define HAVE___B64_NTOP 1 @@ -1056,7 +1139,7 @@ /* #undef HAVE___SS_FAMILY_IN_SS */ /* Define if __va_copy exists */ -/* #undef HAVE___VA_COPY */ +#define HAVE___VA_COPY 1 /* Define if compiler implements __func__ */ #define HAVE___func__ 1 @@ -1178,19 +1261,19 @@ /* Define if your platform breaks doing a seteuid before a setuid */ /* #undef SETEUID_BREAKS_SETUID */ -/* The size of a `char', as computed by sizeof. */ +/* The size of `char', as computed by sizeof. */ #define SIZEOF_CHAR 1 -/* The size of a `int', as computed by sizeof. */ +/* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 -/* The size of a `long int', as computed by sizeof. */ -#define SIZEOF_LONG_INT 4 +/* The size of `long int', as computed by sizeof. */ +#define SIZEOF_LONG_INT 8 -/* The size of a `long long int', as computed by sizeof. */ -#define SIZEOF_LONG_LONG_INT 8 +/* The size of `long long int', as computed by sizeof. */ +#define SIZEOF_LONG_LONG_INT 4 -/* The size of a `short int', as computed by sizeof. */ +/* The size of `short int', as computed by sizeof. */ #define SIZEOF_SHORT_INT 2 /* Define if you want S/Key support */ diff --git a/crypto/openssh/config.h.in b/crypto/openssh/config.h.in new file mode 100644 index 0000000..a650bdb --- /dev/null +++ b/crypto/openssh/config.h.in @@ -0,0 +1,1423 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address + */ +#undef AIX_GETNAMEINFO_HACK + +/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ +#undef AIX_LOGINFAILED_4ARG + +/* System only supports IPv4 audit records */ +#undef AU_IPv4 + +/* Define if your resolver libs need this for getrrsetbyname */ +#undef BIND_8_COMPAT + +/* Define if cmsg_type is not passed correctly */ +#undef BROKEN_CMSG_TYPE + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* getgroups(0,NULL) will return -1 */ +#undef BROKEN_GETGROUPS + +/* FreeBSD glob does not do what we need */ +#undef BROKEN_GLOB + +/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ +#undef BROKEN_INET_NTOA + +/* ia_uinfo routines not supported by OS yet */ +#undef BROKEN_LIBIAF + +/* Ultrix mmap can't map files */ +#undef BROKEN_MMAP + +/* Define if your struct dirent expects you to allocate extra space for d_name + */ +#undef BROKEN_ONE_BYTE_DIRENT_D_NAME + +/* Can't do comparisons on readv */ +#undef BROKEN_READV_COMPARISON + +/* Define if you have a broken realpath. */ +#undef BROKEN_REALPATH + +/* Needed for NeXT */ +#undef BROKEN_SAVED_UIDS + +/* Define if your setregid() is broken */ +#undef BROKEN_SETREGID + +/* Define if your setresgid() is broken */ +#undef BROKEN_SETRESGID + +/* Define if your setresuid() is broken */ +#undef BROKEN_SETRESUID + +/* Define if your setreuid() is broken */ +#undef BROKEN_SETREUID + +/* LynxOS has broken setvbuf() implementation */ +#undef BROKEN_SETVBUF + +/* QNX shadow support is broken */ +#undef BROKEN_SHADOW_EXPIRE + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* updwtmpx is broken (if present) */ +#undef BROKEN_UPDWTMPX + +/* Define if you have BSD auth support */ +#undef BSD_AUTH + +/* Define if you want to specify the path to your lastlog file */ +#undef CONF_LASTLOG_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your utmp file */ +#undef CONF_UTMP_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define if you want to specify the path to your wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if your platform needs to skip post auth file descriptor passing */ +#undef DISABLE_FD_PASSING + +/* Define if you don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use your system's login() call */ +#undef DISABLE_LOGIN + +/* Define if you don't want to use pututline() etc. to write [uw]tmp */ +#undef DISABLE_PUTUTLINE + +/* Define if you don't want to use pututxline() etc. to write [uw]tmpx */ +#undef DISABLE_PUTUTXLINE + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you don't want to use utmp */ +#undef DISABLE_UTMP + +/* Define if you don't want to use utmpx */ +#undef DISABLE_UTMPX + +/* Define if you don't want to use wtmp */ +#undef DISABLE_WTMP + +/* Define if you don't want to use wtmpx */ +#undef DISABLE_WTMPX + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* f_fsid has members */ +#undef FSID_HAS_VAL + +/* Define to 1 if the `getpgrp' function requires zero arguments. */ +#undef GETPGRP_VOID + +/* Conflicting defs for getspnam */ +#undef GETSPNAM_CONFLICTING_DEFS + +/* Define if your system glob() function has the GLOB_ALTDIRFUNC extension */ +#undef GLOB_HAS_ALTDIRFUNC + +/* Define if your system glob() function has gl_matchc options in glob_t */ +#undef GLOB_HAS_GL_MATCHC + +/* Define this if you want GSSAPI support in the version 2 protocol */ +#undef GSSAPI + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if your system uses access rights style file descriptor passing */ +#undef HAVE_ACCRIGHTS_IN_MSGHDR + +/* Define if you have ut_addr in utmp.h */ +#undef HAVE_ADDR_IN_UTMP + +/* Define if you have ut_addr in utmpx.h */ +#undef HAVE_ADDR_IN_UTMPX + +/* Define if you have ut_addr_v6 in utmp.h */ +#undef HAVE_ADDR_V6_IN_UTMP + +/* Define if you have ut_addr_v6 in utmpx.h */ +#undef HAVE_ADDR_V6_IN_UTMPX + +/* Define to 1 if you have the `arc4random' function. */ +#undef HAVE_ARC4RANDOM + +/* Define to 1 if you have the `arc4random_buf' function. */ +#undef HAVE_ARC4RANDOM_BUF + +/* Define to 1 if you have the `arc4random_uniform' function. */ +#undef HAVE_ARC4RANDOM_UNIFORM + +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + +/* OpenBSD's gcc has bounded */ +#undef HAVE_ATTRIBUTE__BOUNDED__ + +/* Have attribute nonnull */ +#undef HAVE_ATTRIBUTE__NONNULL__ + +/* OpenBSD's gcc has sentinel */ +#undef HAVE_ATTRIBUTE__SENTINEL__ + +/* Define to 1 if you have the `aug_get_machine' function. */ +#undef HAVE_AUG_GET_MACHINE + +/* Define to 1 if you have the `b64_ntop' function. */ +#undef HAVE_B64_NTOP + +/* Define to 1 if you have the `b64_pton' function. */ +#undef HAVE_B64_PTON + +/* Define if you have the basename function. */ +#undef HAVE_BASENAME + +/* Define to 1 if you have the `bcopy' function. */ +#undef HAVE_BCOPY + +/* Define to 1 if you have the `bindresvport_sa' function. */ +#undef HAVE_BINDRESVPORT_SA + +/* Define to 1 if you have the <bsm/audit.h> header file. */ +#undef HAVE_BSM_AUDIT_H + +/* Define to 1 if you have the <bstring.h> header file. */ +#undef HAVE_BSTRING_H + +/* Define to 1 if you have the `clock' function. */ +#undef HAVE_CLOCK + +/* define if you have clock_t data type */ +#undef HAVE_CLOCK_T + +/* Define to 1 if you have the `closefrom' function. */ +#undef HAVE_CLOSEFROM + +/* Define if gai_strerror() returns const char * */ +#undef HAVE_CONST_GAI_STRERROR_PROTO + +/* Define if your system uses ancillary data style file descriptor passing */ +#undef HAVE_CONTROL_IN_MSGHDR + +/* Define to 1 if you have the <crypto/sha2.h> header file. */ +#undef HAVE_CRYPTO_SHA2_H + +/* Define to 1 if you have the <crypt.h> header file. */ +#undef HAVE_CRYPT_H + +/* Define if you are on Cygwin */ +#undef HAVE_CYGWIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define to 1 if you have the declaration of `authenticate', and to 0 if you + don't. */ +#undef HAVE_DECL_AUTHENTICATE + +/* Define to 1 if you have the declaration of `GLOB_NOMATCH', and to 0 if you + don't. */ +#undef HAVE_DECL_GLOB_NOMATCH + +/* Define to 1 if you have the declaration of `h_errno', and to 0 if you + don't. */ +#undef HAVE_DECL_H_ERRNO + +/* Define to 1 if you have the declaration of `loginfailed', and to 0 if you + don't. */ +#undef HAVE_DECL_LOGINFAILED + +/* Define to 1 if you have the declaration of `loginrestrictions', and to 0 if + you don't. */ +#undef HAVE_DECL_LOGINRESTRICTIONS + +/* Define to 1 if you have the declaration of `loginsuccess', and to 0 if you + don't. */ +#undef HAVE_DECL_LOGINSUCCESS + +/* Define to 1 if you have the declaration of `MAXSYMLINKS', and to 0 if you + don't. */ +#undef HAVE_DECL_MAXSYMLINKS + +/* Define to 1 if you have the declaration of `offsetof', and to 0 if you + don't. */ +#undef HAVE_DECL_OFFSETOF + +/* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you + don't. */ +#undef HAVE_DECL_O_NONBLOCK + +/* Define to 1 if you have the declaration of `passwdexpired', and to 0 if you + don't. */ +#undef HAVE_DECL_PASSWDEXPIRED + +/* Define to 1 if you have the declaration of `setauthdb', and to 0 if you + don't. */ +#undef HAVE_DECL_SETAUTHDB + +/* Define to 1 if you have the declaration of `SHUT_RD', and to 0 if you + don't. */ +#undef HAVE_DECL_SHUT_RD + +/* Define to 1 if you have the declaration of `writev', and to 0 if you don't. + */ +#undef HAVE_DECL_WRITEV + +/* Define to 1 if you have the declaration of `_getlong', and to 0 if you + don't. */ +#undef HAVE_DECL__GETLONG + +/* Define to 1 if you have the declaration of `_getshort', and to 0 if you + don't. */ +#undef HAVE_DECL__GETSHORT + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define to 1 if you have the <dirent.h> header file. */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the `dirfd' function. */ +#undef HAVE_DIRFD + +/* Define to 1 if you have the `dirname' function. */ +#undef HAVE_DIRNAME + +/* Define to 1 if you have the <endian.h> header file. */ +#undef HAVE_ENDIAN_H + +/* Define to 1 if you have the `endutent' function. */ +#undef HAVE_ENDUTENT + +/* Define to 1 if you have the `endutxent' function. */ +#undef HAVE_ENDUTXENT + +/* Define if your system has /etc/default/login */ +#undef HAVE_ETC_DEFAULT_LOGIN + +/* Define to 1 if you have the `EVP_sha256' function. */ +#undef HAVE_EVP_SHA256 + +/* Define if you have ut_exit in utmp.h */ +#undef HAVE_EXIT_IN_UTMP + +/* Define to 1 if you have the `fchmod' function. */ +#undef HAVE_FCHMOD + +/* Define to 1 if you have the `fchown' function. */ +#undef HAVE_FCHOWN + +/* Use F_CLOSEM fcntl for closefrom */ +#undef HAVE_FCNTL_CLOSEM + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the <features.h> header file. */ +#undef HAVE_FEATURES_H + +/* Define to 1 if you have the <floatingpoint.h> header file. */ +#undef HAVE_FLOATINGPOINT_H + +/* Define to 1 if you have the `fmt_scaled' function. */ +#undef HAVE_FMT_SCALED + +/* Define to 1 if you have the `freeaddrinfo' function. */ +#undef HAVE_FREEADDRINFO + +/* Define to 1 if the system has the type `fsblkcnt_t'. */ +#undef HAVE_FSBLKCNT_T + +/* Define to 1 if the system has the type `fsfilcnt_t'. */ +#undef HAVE_FSFILCNT_T + +/* Define to 1 if you have the `fstatvfs' function. */ +#undef HAVE_FSTATVFS + +/* Define to 1 if you have the `futimes' function. */ +#undef HAVE_FUTIMES + +/* Define to 1 if you have the `gai_strerror' function. */ +#undef HAVE_GAI_STRERROR + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if you have the `getaudit' function. */ +#undef HAVE_GETAUDIT + +/* Define to 1 if you have the `getaudit_addr' function. */ +#undef HAVE_GETAUDIT_ADDR + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the `getgrouplist' function. */ +#undef HAVE_GETGROUPLIST + +/* Define to 1 if you have the `getgrset' function. */ +#undef HAVE_GETGRSET + +/* Define to 1 if you have the `getluid' function. */ +#undef HAVE_GETLUID + +/* Define to 1 if you have the `getnameinfo' function. */ +#undef HAVE_GETNAMEINFO + +/* Define to 1 if you have the `getopt' function. */ +#undef HAVE_GETOPT + +/* Define to 1 if you have the <getopt.h> header file. */ +#undef HAVE_GETOPT_H + +/* Define if your getopt(3) defines and uses optreset */ +#undef HAVE_GETOPT_OPTRESET + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `getpeereid' function. */ +#undef HAVE_GETPEEREID + +/* Define to 1 if you have the `getpeerucred' function. */ +#undef HAVE_GETPEERUCRED + +/* Define to 1 if you have the `getpwanam' function. */ +#undef HAVE_GETPWANAM + +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + +/* Define if getrrsetbyname() exists */ +#undef HAVE_GETRRSETBYNAME + +/* Define to 1 if you have the `getrusage' function. */ +#undef HAVE_GETRUSAGE + +/* Define to 1 if you have the `getseuserbyname' function. */ +#undef HAVE_GETSEUSERBYNAME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `getttyent' function. */ +#undef HAVE_GETTTYENT + +/* Define to 1 if you have the `getutent' function. */ +#undef HAVE_GETUTENT + +/* Define to 1 if you have the `getutid' function. */ +#undef HAVE_GETUTID + +/* Define to 1 if you have the `getutline' function. */ +#undef HAVE_GETUTLINE + +/* Define to 1 if you have the `getutxent' function. */ +#undef HAVE_GETUTXENT + +/* Define to 1 if you have the `getutxid' function. */ +#undef HAVE_GETUTXID + +/* Define to 1 if you have the `getutxline' function. */ +#undef HAVE_GETUTXLINE + +/* Define to 1 if you have the `get_default_context_with_level' function. */ +#undef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL + +/* Define to 1 if you have the `glob' function. */ +#undef HAVE_GLOB + +/* Define to 1 if you have the <glob.h> header file. */ +#undef HAVE_GLOB_H + +/* Define to 1 if you have the <gssapi_generic.h> header file. */ +#undef HAVE_GSSAPI_GENERIC_H + +/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_GENERIC_H + +/* Define to 1 if you have the <gssapi/gssapi.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_H + +/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_KRB5_H + +/* Define to 1 if you have the <gssapi.h> header file. */ +#undef HAVE_GSSAPI_H + +/* Define to 1 if you have the <gssapi_krb5.h> header file. */ +#undef HAVE_GSSAPI_KRB5_H + +/* Define if HEADER.ad exists in arpa/nameser.h */ +#undef HAVE_HEADER_AD + +/* Define if you have ut_host in utmp.h */ +#undef HAVE_HOST_IN_UTMP + +/* Define if you have ut_host in utmpx.h */ +#undef HAVE_HOST_IN_UTMPX + +/* Define to 1 if you have the <iaf.h> header file. */ +#undef HAVE_IAF_H + +/* Define to 1 if you have the <ia.h> header file. */ +#undef HAVE_IA_H + +/* Define if you have ut_id in utmp.h */ +#undef HAVE_ID_IN_UTMP + +/* Define if you have ut_id in utmpx.h */ +#undef HAVE_ID_IN_UTMPX + +/* Define to 1 if you have the `inet_aton' function. */ +#undef HAVE_INET_ATON + +/* Define to 1 if you have the `inet_ntoa' function. */ +#undef HAVE_INET_NTOA + +/* Define to 1 if you have the `inet_ntop' function. */ +#undef HAVE_INET_NTOP + +/* Define to 1 if you have the `innetgr' function. */ +#undef HAVE_INNETGR + +/* define if you have int64_t data type */ +#undef HAVE_INT64_T + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* define if you have intxx_t data type */ +#undef HAVE_INTXX_T + +/* Define to 1 if the system has the type `in_addr_t'. */ +#undef HAVE_IN_ADDR_T + +/* Define to 1 if you have the <lastlog.h> header file. */ +#undef HAVE_LASTLOG_H + +/* Define to 1 if you have the `bsm' library (-lbsm). */ +#undef HAVE_LIBBSM + +/* Define to 1 if you have the `crypt' library (-lcrypt). */ +#undef HAVE_LIBCRYPT + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the <libgen.h> header file. */ +#undef HAVE_LIBGEN_H + +/* Define if system has libiaf that supports set_id */ +#undef HAVE_LIBIAF + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `pam' library (-lpam). */ +#undef HAVE_LIBPAM + +/* Define to 1 if you have the `sectok' library (-lsectok). */ +#undef HAVE_LIBSECTOK + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the <libutil.h> header file. */ +#undef HAVE_LIBUTIL_H + +/* Define to 1 if you have the `xnet' library (-lxnet). */ +#undef HAVE_LIBXNET + +/* Define to 1 if you have the `z' library (-lz). */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <linux/if_tun.h> header file. */ +#undef HAVE_LINUX_IF_TUN_H + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define to 1 if you have the <login_cap.h> header file. */ +#undef HAVE_LOGIN_CAP_H + +/* Define to 1 if you have the `login_getcapbool' function. */ +#undef HAVE_LOGIN_GETCAPBOOL + +/* Define to 1 if you have the <login.h> header file. */ +#undef HAVE_LOGIN_H + +/* Define to 1 if you have the `logout' function. */ +#undef HAVE_LOGOUT + +/* Define to 1 if you have the `logwtmp' function. */ +#undef HAVE_LOGWTMP + +/* Define to 1 if the system has the type `long double'. */ +#undef HAVE_LONG_DOUBLE + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if you have the <maillock.h> header file. */ +#undef HAVE_MAILLOCK_H + +/* Define to 1 if you have the `md5_crypt' function. */ +#undef HAVE_MD5_CRYPT + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkdtemp' function. */ +#undef HAVE_MKDTEMP + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* define if you have mode_t data type */ +#undef HAVE_MODE_T + +/* Some systems put nanosleep outside of libc */ +#undef HAVE_NANOSLEEP + +/* Define to 1 if you have the <ndir.h> header file. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the <netdb.h> header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the <netgroup.h> header file. */ +#undef HAVE_NETGROUP_H + +/* Define to 1 if you have the <net/if_tun.h> header file. */ +#undef HAVE_NET_IF_TUN_H + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define to 1 if you have the `ngetaddrinfo' function. */ +#undef HAVE_NGETADDRINFO + +/* Define to 1 if you have the `nsleep' function. */ +#undef HAVE_NSLEEP + +/* Define to 1 if you have the `ogetaddrinfo' function. */ +#undef HAVE_OGETADDRINFO + +/* Define if you have an old version of PAM which takes only one argument to + pam_strerror */ +#undef HAVE_OLD_PAM + +/* Define to 1 if you have the `openlog_r' function. */ +#undef HAVE_OPENLOG_R + +/* Define to 1 if you have the `openpty' function. */ +#undef HAVE_OPENPTY + +/* Define if your ssl headers are included with #include <openssl/header.h> */ +#undef HAVE_OPENSSL + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define to 1 if you have the `pam_getenvlist' function. */ +#undef HAVE_PAM_GETENVLIST + +/* Define to 1 if you have the <pam/pam_appl.h> header file. */ +#undef HAVE_PAM_PAM_APPL_H + +/* Define to 1 if you have the `pam_putenv' function. */ +#undef HAVE_PAM_PUTENV + +/* Define to 1 if you have the <paths.h> header file. */ +#undef HAVE_PATHS_H + +/* Define if you have ut_pid in utmp.h */ +#undef HAVE_PID_IN_UTMP + +/* define if you have pid_t data type */ +#undef HAVE_PID_T + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the <poll.h> header file. */ +#undef HAVE_POLL_H + +/* Define to 1 if you have the `prctl' function. */ +#undef HAVE_PRCTL + +/* Define if you have /proc/$pid/fd */ +#undef HAVE_PROC_PID + +/* Define to 1 if you have the `pstat' function. */ +#undef HAVE_PSTAT + +/* Define to 1 if you have the <pty.h> header file. */ +#undef HAVE_PTY_H + +/* Define to 1 if you have the `pututline' function. */ +#undef HAVE_PUTUTLINE + +/* Define to 1 if you have the `pututxline' function. */ +#undef HAVE_PUTUTXLINE + +/* Define if your password has a pw_change field */ +#undef HAVE_PW_CHANGE_IN_PASSWD + +/* Define if your password has a pw_class field */ +#undef HAVE_PW_CLASS_IN_PASSWD + +/* Define if your password has a pw_expire field */ +#undef HAVE_PW_EXPIRE_IN_PASSWD + +/* Define to 1 if you have the `readpassphrase' function. */ +#undef HAVE_READPASSPHRASE + +/* Define to 1 if you have the <readpassphrase.h> header file. */ +#undef HAVE_READPASSPHRASE_H + +/* Define to 1 if you have the `realpath' function. */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the `recvmsg' function. */ +#undef HAVE_RECVMSG + +/* Define to 1 if you have the <rpc/types.h> header file. */ +#undef HAVE_RPC_TYPES_H + +/* Define to 1 if you have the `rresvport_af' function. */ +#undef HAVE_RRESVPORT_AF + +/* define if you have sa_family_t data type */ +#undef HAVE_SA_FAMILY_T + +/* Define to 1 if you have the <sectok.h> header file. */ +#undef HAVE_SECTOK_H + +/* Define if you have SecureWare-based protected password database */ +#undef HAVE_SECUREWARE + +/* Define to 1 if you have the <security/pam_appl.h> header file. */ +#undef HAVE_SECURITY_PAM_APPL_H + +/* Define to 1 if you have the `sendmsg' function. */ +#undef HAVE_SENDMSG + +/* Define to 1 if you have the `setauthdb' function. */ +#undef HAVE_SETAUTHDB + +/* Define to 1 if you have the `setdtablesize' function. */ +#undef HAVE_SETDTABLESIZE + +/* Define to 1 if you have the `setegid' function. */ +#undef HAVE_SETEGID + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `seteuid' function. */ +#undef HAVE_SETEUID + +/* Define to 1 if you have the `setgroups' function. */ +#undef HAVE_SETGROUPS + +/* Define to 1 if you have the `setlogin' function. */ +#undef HAVE_SETLOGIN + +/* Define to 1 if you have the `setluid' function. */ +#undef HAVE_SETLUID + +/* Define to 1 if you have the `setpcred' function. */ +#undef HAVE_SETPCRED + +/* Define to 1 if you have the `setproctitle' function. */ +#undef HAVE_SETPROCTITLE + +/* Define to 1 if you have the `setregid' function. */ +#undef HAVE_SETREGID + +/* Define to 1 if you have the `setresgid' function. */ +#undef HAVE_SETRESGID + +/* Define to 1 if you have the `setresuid' function. */ +#undef HAVE_SETRESUID + +/* Define to 1 if you have the `setreuid' function. */ +#undef HAVE_SETREUID + +/* Define to 1 if you have the `setrlimit' function. */ +#undef HAVE_SETRLIMIT + +/* Define to 1 if you have the `setsid' function. */ +#undef HAVE_SETSID + +/* Define to 1 if you have the `setutent' function. */ +#undef HAVE_SETUTENT + +/* Define to 1 if you have the `setutxent' function. */ +#undef HAVE_SETUTXENT + +/* Define to 1 if you have the `setvbuf' function. */ +#undef HAVE_SETVBUF + +/* Define to 1 if you have the `set_id' function. */ +#undef HAVE_SET_ID + +/* Define to 1 if you have the `SHA256_Update' function. */ +#undef HAVE_SHA256_UPDATE + +/* Define to 1 if you have the <sha2.h> header file. */ +#undef HAVE_SHA2_H + +/* Define to 1 if you have the <shadow.h> header file. */ +#undef HAVE_SHADOW_H + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sigvec' function. */ +#undef HAVE_SIGVEC + +/* Define to 1 if the system has the type `sig_atomic_t'. */ +#undef HAVE_SIG_ATOMIC_T + +/* define if you have size_t data type */ +#undef HAVE_SIZE_T + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `socketpair' function. */ +#undef HAVE_SOCKETPAIR + +/* Have PEERCRED socket option */ +#undef HAVE_SO_PEERCRED + +/* define if you have ssize_t data type */ +#undef HAVE_SSIZE_T + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS + +/* Define to 1 if you have the `statfs' function. */ +#undef HAVE_STATFS + +/* Define to 1 if you have the `statvfs' function. */ +#undef HAVE_STATVFS + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Silly mkstemp() */ +#undef HAVE_STRICT_MKSTEMP + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcat' function. */ +#undef HAVE_STRLCAT + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strmode' function. */ +#undef HAVE_STRMODE + +/* Define to 1 if you have the `strnvis' function. */ +#undef HAVE_STRNVIS + +/* Define to 1 if you have the `strsep' function. */ +#undef HAVE_STRSEP + +/* Define to 1 if you have the `strtoll' function. */ +#undef HAVE_STRTOLL + +/* Define to 1 if you have the `strtonum' function. */ +#undef HAVE_STRTONUM + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* define if you have struct addrinfo data type */ +#undef HAVE_STRUCT_ADDRINFO + +/* define if you have struct in6_addr data type */ +#undef HAVE_STRUCT_IN6_ADDR + +/* define if you have struct sockaddr_in6 data type */ +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* define if you have struct sockaddr_storage data type */ +#undef HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if `st_blksize' is member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_BLKSIZE + +/* Define to 1 if the system has the type `struct timespec'. */ +#undef HAVE_STRUCT_TIMESPEC + +/* define if you have struct timeval */ +#undef HAVE_STRUCT_TIMEVAL + +/* Define to 1 if you have the `swap32' function. */ +#undef HAVE_SWAP32 + +/* Define to 1 if you have the `sysconf' function. */ +#undef HAVE_SYSCONF + +/* Define if you have syslen in utmpx.h */ +#undef HAVE_SYSLEN_IN_UTMPX + +/* Define to 1 if you have the <sys/audit.h> header file. */ +#undef HAVE_SYS_AUDIT_H + +/* Define to 1 if you have the <sys/bitypes.h> header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the <sys/bsdtty.h> header file. */ +#undef HAVE_SYS_BSDTTY_H + +/* Define to 1 if you have the <sys/cdefs.h> header file. */ +#undef HAVE_SYS_CDEFS_H + +/* Define to 1 if you have the <sys/dir.h> header file. */ +#undef HAVE_SYS_DIR_H + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define to 1 if you have the <sys/mman.h> header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the <sys/mount.h> header file. */ +#undef HAVE_SYS_MOUNT_H + +/* Define to 1 if you have the <sys/ndir.h> header file. */ +#undef HAVE_SYS_NDIR_H + +/* Define if your system defines sys_nerr */ +#undef HAVE_SYS_NERR + +/* Define to 1 if you have the <sys/poll.h> header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the <sys/prctl.h> header file. */ +#undef HAVE_SYS_PRCTL_H + +/* Define to 1 if you have the <sys/pstat.h> header file. */ +#undef HAVE_SYS_PSTAT_H + +/* Define to 1 if you have the <sys/ptms.h> header file. */ +#undef HAVE_SYS_PTMS_H + +/* Define to 1 if you have the <sys/select.h> header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the <sys/statvfs.h> header file. */ +#undef HAVE_SYS_STATVFS_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/stream.h> header file. */ +#undef HAVE_SYS_STREAM_H + +/* Define to 1 if you have the <sys/stropts.h> header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define to 1 if you have the <sys/strtio.h> header file. */ +#undef HAVE_SYS_STRTIO_H + +/* Force use of sys/syslog.h on Ultrix */ +#undef HAVE_SYS_SYSLOG_H + +/* Define to 1 if you have the <sys/sysmacros.h> header file. */ +#undef HAVE_SYS_SYSMACROS_H + +/* Define to 1 if you have the <sys/timers.h> header file. */ +#undef HAVE_SYS_TIMERS_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the `tcgetpgrp' function. */ +#undef HAVE_TCGETPGRP + +/* Define to 1 if you have the `tcsendbreak' function. */ +#undef HAVE_TCSENDBREAK + +/* Define to 1 if you have the `time' function. */ +#undef HAVE_TIME + +/* Define to 1 if you have the <time.h> header file. */ +#undef HAVE_TIME_H + +/* Define if you have ut_time in utmp.h */ +#undef HAVE_TIME_IN_UTMP + +/* Define if you have ut_time in utmpx.h */ +#undef HAVE_TIME_IN_UTMPX + +/* Define to 1 if you have the <tmpdir.h> header file. */ +#undef HAVE_TMPDIR_H + +/* Define to 1 if you have the `truncate' function. */ +#undef HAVE_TRUNCATE + +/* Define to 1 if you have the <ttyent.h> header file. */ +#undef HAVE_TTYENT_H + +/* Define if you have ut_tv in utmp.h */ +#undef HAVE_TV_IN_UTMP + +/* Define if you have ut_tv in utmpx.h */ +#undef HAVE_TV_IN_UTMPX + +/* Define if you have ut_type in utmp.h */ +#undef HAVE_TYPE_IN_UTMP + +/* Define if you have ut_type in utmpx.h */ +#undef HAVE_TYPE_IN_UTMPX + +/* Define to 1 if you have the <ucred.h> header file. */ +#undef HAVE_UCRED_H + +/* define if you have uintxx_t data type */ +#undef HAVE_UINTXX_T + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `unsetenv' function. */ +#undef HAVE_UNSETENV + +/* Define to 1 if the system has the type `unsigned long long'. */ +#undef HAVE_UNSIGNED_LONG_LONG + +/* Define to 1 if you have the `updwtmp' function. */ +#undef HAVE_UPDWTMP + +/* Define to 1 if you have the `updwtmpx' function. */ +#undef HAVE_UPDWTMPX + +/* Define to 1 if you have the <usersec.h> header file. */ +#undef HAVE_USERSEC_H + +/* Define to 1 if you have the <util.h> header file. */ +#undef HAVE_UTIL_H + +/* Define to 1 if you have the `utimes' function. */ +#undef HAVE_UTIMES + +/* Define to 1 if you have the <utime.h> header file. */ +#undef HAVE_UTIME_H + +/* Define to 1 if you have the `utmpname' function. */ +#undef HAVE_UTMPNAME + +/* Define to 1 if you have the `utmpxname' function. */ +#undef HAVE_UTMPXNAME + +/* Define to 1 if you have the <utmpx.h> header file. */ +#undef HAVE_UTMPX_H + +/* Define to 1 if you have the <utmp.h> header file. */ +#undef HAVE_UTMP_H + +/* define if you have u_char data type */ +#undef HAVE_U_CHAR + +/* define if you have u_int data type */ +#undef HAVE_U_INT + +/* define if you have u_int64_t data type */ +#undef HAVE_U_INT64_T + +/* define if you have u_intxx_t data type */ +#undef HAVE_U_INTXX_T + +/* Define to 1 if you have the `vasprintf' function. */ +#undef HAVE_VASPRINTF + +/* Define if va_copy exists */ +#undef HAVE_VA_COPY + +/* Define to 1 if you have the `vhangup' function. */ +#undef HAVE_VHANGUP + +/* Define to 1 if you have the <vis.h> header file. */ +#undef HAVE_VIS_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the `waitpid' function. */ +#undef HAVE_WAITPID + +/* Define to 1 if you have the `_getlong' function. */ +#undef HAVE__GETLONG + +/* Define to 1 if you have the `_getpty' function. */ +#undef HAVE__GETPTY + +/* Define to 1 if you have the `_getshort' function. */ +#undef HAVE__GETSHORT + +/* Define if you have struct __res_state _res as an extern */ +#undef HAVE__RES_EXTERN + +/* Define to 1 if you have the `__b64_ntop' function. */ +#undef HAVE___B64_NTOP + +/* Define to 1 if you have the `__b64_pton' function. */ +#undef HAVE___B64_PTON + +/* Define if compiler implements __FUNCTION__ */ +#undef HAVE___FUNCTION__ + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Fields in struct sockaddr_storage */ +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if __va_copy exists */ +#undef HAVE___VA_COPY + +/* Define if compiler implements __func__ */ +#undef HAVE___func__ + +/* Define this if you are using the Heimdal version of Kerberos V5 */ +#undef HEIMDAL + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you want Kerberos 5 support */ +#undef KRB5 + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define to whatever link() returns for "not supported" if it doesn't return + EOPNOTSUPP. */ +#undef LINK_OPNOTSUPP_ERRNO + +/* max value of long long calculated by configure */ +#undef LLONG_MAX + +/* min value of long long calculated by configure */ +#undef LLONG_MIN + +/* Account locked with pw(1) */ +#undef LOCKED_PASSWD_PREFIX + +/* String used in /etc/passwd to denote locked account */ +#undef LOCKED_PASSWD_STRING + +/* String used in /etc/passwd to denote locked account */ +#undef LOCKED_PASSWD_SUBSTR + +/* Some versions of /bin/login need the TERM supplied on the commandline */ +#undef LOGIN_NEEDS_TERM + +/* Some systems need a utmpx entry for /bin/login to work */ +#undef LOGIN_NEEDS_UTMPX + +/* Define if your login program cannot handle end of options ("--") */ +#undef LOGIN_NO_ENDOPT + +/* If your header files don't define LOGIN_PROGRAM, then use this (detected) + from environment and PATH */ +#undef LOGIN_PROGRAM_FALLBACK + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Define on *nto-qnx systems */ +#undef MISSING_FD_MASK + +/* Define on *nto-qnx systems */ +#undef MISSING_HOWMANY + +/* Define on *nto-qnx systems */ +#undef MISSING_NFDBITS + +/* Need setpgrp to acquire controlling tty */ +#undef NEED_SETPGRP + +/* Define if the concept of ports only accessible to superusers isn't known */ +#undef NO_IPPORT_RESERVED_CONCEPT + +/* Define if you don't want to use lastlog in session.c */ +#undef NO_SSH_LASTLOG + +/* Define if X11 doesn't support AF_UNIX sockets on that system */ +#undef NO_X11_UNIX_SOCKETS + +/* libcrypto is missing AES 192 and 256 bit functions */ +#undef OPENSSL_LOBOTOMISED_AES + +/* Define if you want OpenSSL's internally seeded PRNG only */ +#undef OPENSSL_PRNG_ONLY + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define if you are using Solaris-derived PAM which passes pam_messages to + the conversation function with an extra level of indirection */ +#undef PAM_SUN_CODEBASE + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* must supply username to passwd */ +#undef PASSWD_NEEDS_USERNAME + +/* Port number of PRNGD/EGD random number socket */ +#undef PRNGD_PORT + +/* Location of PRNGD/EGD random number socket */ +#undef PRNGD_SOCKET + +/* read(1) can return 0 for a non-closed fd */ +#undef PTY_ZEROREAD + +/* Define if your platform breaks doing a seteuid before a setuid */ +#undef SETEUID_BREAKS_SETUID + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long int', as computed by sizeof. */ +#undef SIZEOF_LONG_INT + +/* The size of `long long int', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG_INT + +/* The size of `short int', as computed by sizeof. */ +#undef SIZEOF_SHORT_INT + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if your skeychallenge() function takes 4 arguments (NetBSD) */ +#undef SKEYCHALLENGE_4ARG + +/* Define if you want smartcard support */ +#undef SMARTCARD + +/* Define as const if snprintf() can declare const char *fmt */ +#undef SNPRINTF_CONST + +/* Define to a Set Process Title type if your system is supported by + bsd-setproctitle.c */ +#undef SPT_TYPE + +/* Define if sshd somehow reacquires a controlling TTY after setsid() */ +#undef SSHD_ACQUIRES_CTTY + +/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ +#undef SSHPAM_CHAUTHTOK_NEEDS_RUID + +/* Use audit debugging module */ +#undef SSH_AUDIT_EVENTS + +/* non-privileged user for privilege separation */ +#undef SSH_PRIVSEP_USER + +/* Use tunnel device compatibility to OpenBSD */ +#undef SSH_TUN_COMPAT_AF + +/* Open tunnel devices the FreeBSD way */ +#undef SSH_TUN_FREEBSD + +/* Open tunnel devices the Linux tun/tap way */ +#undef SSH_TUN_LINUX + +/* No layer 2 tunnel support */ +#undef SSH_TUN_NO_L2 + +/* Open tunnel devices the OpenBSD way */ +#undef SSH_TUN_OPENBSD + +/* Prepend the address family to IP tunnel traffic */ +#undef SSH_TUN_PREPEND_AF + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you want a different $PATH for the superuser */ +#undef SUPERUSER_PATH + +/* syslog_r function is safe to use in in a signal handler */ +#undef SYSLOG_R_SAFE_IN_SIGHAND + +/* Support passwords > 8 chars */ +#undef UNIXWARE_LONG_PASSWORDS + +/* Specify default $PATH */ +#undef USER_PATH + +/* Define this if you want to use libkafs' AFS support */ +#undef USE_AFS + +/* Use BSM audit module */ +#undef USE_BSM_AUDIT + +/* Use btmp to log bad logins */ +#undef USE_BTMP + +/* Use libedit for sftp */ +#undef USE_LIBEDIT + +/* Define if you want smartcard support using OpenSC */ +#undef USE_OPENSC + +/* Enable OpenSSL engine support */ +#undef USE_OPENSSL_ENGINE + +/* Define if you want to enable PAM support */ +#undef USE_PAM + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if you want smartcard support using sectok */ +#undef USE_SECTOK + +/* Define if you have Solaris process contracts */ +#undef USE_SOLARIS_PROCESS_CONTRACTS + +/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */ +#undef WITH_ABBREV_NO_TTY + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if you have/want arrays (cluster-wide session managment, not C + arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Define if you want IRIX kernel jobs */ +#undef WITH_IRIX_JOBS + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want SELinux support. */ +#undef WITH_SELINUX + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* log for bad login attempts */ +#undef _PATH_BTMP + +/* Full path of your "passwd" program */ +#undef _PATH_PASSWD_PROG + +/* Specify location of ssh.pid */ +#undef _PATH_SSH_PIDDIR + +/* Define if we don't have struct __res_state in resolv.h */ +#undef __res_state + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* type to use in place of socklen_t if not defined */ +#undef socklen_t diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h index 8a4e2c7..a8203eb 100644 --- a/crypto/openssh/defines.h +++ b/crypto/openssh/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.138 2006/09/21 13:13:30 dtucker Exp $ */ +/* $Id: defines.h,v 1.151 2008/07/04 13:10:49 djm Exp $ */ /* Constants */ @@ -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 @@ -437,10 +431,6 @@ struct winsize { # define __attribute__(x) #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ -#ifndef __dead -# define __dead __attribute__((noreturn)) -#endif - #if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__) # define __sentinel__ #endif @@ -449,6 +439,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 +481,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 @@ -542,6 +536,10 @@ struct winsize { # undef HAVE_UPDWTMPX #endif +#if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE) +# undef HAS_SHADOW_EXPIRE +#endif + #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \ defined(SYSLOG_R_SAFE_IN_SIGHAND) # define DO_LOG_SAFE_IN_SIGHAND @@ -565,11 +563,6 @@ struct winsize { # define CUSTOM_SSH_AUDIT_EVENTS #endif -/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */ -#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f) -# define OPENSSL_free(x) Free(x) -#endif - #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) # define __func__ __FUNCTION__ #elif !defined(HAVE___func__) @@ -593,6 +586,15 @@ struct winsize { # define SSH_SYSFDMAX 10000 #endif +#ifdef FSID_HAS_VAL +/* encode f_fsid into a 64 bit value */ +#define FSID_TO_ULONG(f) \ + ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \ + ((f).val[1] & 0xffffffffUL)) +#else +# define FSID_TO_ULONG(f) ((f)) +#endif + #if defined(__Lynx__) /* * LynxOS defines these in param.h which we do not want to include since @@ -696,9 +698,12 @@ struct winsize { # define CUSTOM_SYS_AUTH_PASSWD 1 #endif -#ifdef HAVE_LIBIAF +#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) # define CUSTOM_SYS_AUTH_PASSWD 1 #endif +#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF) +# define USE_LIBIAF +#endif /* HP-UX 11.11 */ #ifdef BTMP_FILE @@ -729,4 +734,8 @@ struct winsize { # endif #endif +#ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN +#endif + #endif /* _DEFINES_H */ diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c index 02b9a40..b766053 100644 --- a/crypto/openssh/dh.c +++ b/crypto/openssh/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.43 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: dh.c,v 1.47 2008/06/26 09:19:39 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -46,6 +46,7 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) char *cp, *arg; char *strsize, *gen, *prime; const char *errstr = NULL; + long long n; cp = line; if ((arg = strdelim(&cp)) == NULL) @@ -62,12 +63,24 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg) arg = strsep(&cp, " "); /* type */ if (cp == NULL || *arg == '\0') goto fail; + /* Ensure this is a safe prime */ + n = strtonum(arg, 0, 5, &errstr); + if (errstr != NULL || n != MODULI_TYPE_SAFE) + goto fail; arg = strsep(&cp, " "); /* tests */ if (cp == NULL || *arg == '\0') goto fail; + /* Ensure prime has been tested and is not composite */ + n = strtonum(arg, 0, 0x1f, &errstr); + if (errstr != NULL || + (n & MODULI_TESTS_COMPOSITE) || !(n & ~MODULI_TESTS_COMPOSITE)) + goto fail; arg = strsep(&cp, " "); /* tries */ if (cp == NULL || *arg == '\0') goto fail; + n = strtonum(arg, 0, 1<<30, &errstr); + if (errstr != NULL || n == 0) + goto fail; strsize = strsep(&cp, " "); /* size */ if (cp == NULL || *strsize == '\0' || (dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || @@ -153,7 +166,7 @@ choose_dh(int min, int wantbits, int max) } linenum = 0; - which = arc4random() % bestcount; + which = arc4random_uniform(bestcount); while (fgets(line, sizeof(line), f)) { if (!parse_prime(linenum, line, &dhg)) continue; @@ -185,7 +198,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) BIGNUM *tmp; if (dh_pub->neg) { - logit("invalid public DH value: negativ"); + logit("invalid public DH value: negative"); return 0; } if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */ @@ -193,8 +206,10 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) return 0; } - if ((tmp = BN_new()) == NULL) - return (-1); + if ((tmp = BN_new()) == NULL) { + error("%s: BN_new failed", __func__); + return 0; + } if (!BN_sub(tmp, dh->p, BN_value_one()) || BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ BN_clear_free(tmp); diff --git a/crypto/openssh/dh.h b/crypto/openssh/dh.h index 8e580ee..dfc1480 100644 --- a/crypto/openssh/dh.h +++ b/crypto/openssh/dh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.h,v 1.9 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. @@ -46,4 +46,28 @@ int dh_estimate(int); #define DH_GRP_MIN 1024 #define DH_GRP_MAX 8192 +/* + * Values for "type" field of moduli(5) + * Specifies the internal structure of the prime modulus. + */ +#define MODULI_TYPE_UNKNOWN (0) +#define MODULI_TYPE_UNSTRUCTURED (1) +#define MODULI_TYPE_SAFE (2) +#define MODULI_TYPE_SCHNORR (3) +#define MODULI_TYPE_SOPHIE_GERMAIN (4) +#define MODULI_TYPE_STRONG (5) + +/* + * Values for "tests" field of moduli(5) + * Specifies the methods used in checking for primality. + * Usually, more than one test is used. + */ +#define MODULI_TESTS_UNTESTED (0x00) +#define MODULI_TESTS_COMPOSITE (0x01) +#define MODULI_TESTS_SIEVE (0x02) +#define MODULI_TESTS_MILLER_RABIN (0x04) +#define MODULI_TESTS_JACOBI (0x08) +#define MODULI_TESTS_ELLIPTIC (0x10) + + #endif diff --git a/crypto/openssh/dns.c b/crypto/openssh/dns.c index 92623de..a7da03f 100644 --- a/crypto/openssh/dns.c +++ b/crypto/openssh/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: dns.c,v 1.25 2008/06/12 00:03:49 dtucker Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -145,11 +145,20 @@ is_numeric_hostname(const char *hostname) { struct addrinfo hints, *ai; + /* + * We shouldn't ever get a null host but if we do then log an error + * and return -1 which stops DNS key fingerprint processing. + */ + if (hostname == NULL) { + error("is_numeric_hostname called with NULL hostname"); + return -1; + } + memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(hostname, "0", &hints, &ai) == 0) { + if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) { freeaddrinfo(ai); return -1; } @@ -217,7 +226,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, if (fingerprints->rri_nrdatas) *flags |= DNS_VERIFY_FOUND; - for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) { + for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) { /* * Extract the key from the answer. Ignore any badly * formatted fingerprints. diff --git a/crypto/openssh/entropy.c b/crypto/openssh/entropy.c index ccabb13..8b70539 100644 --- a/crypto/openssh/entropy.c +++ b/crypto/openssh/entropy.c @@ -35,8 +35,9 @@ # include <fcntl.h> #endif #include <stdarg.h> -#include <unistd.h> +#include <string.h> #include <signal.h> +#include <unistd.h> #include <openssl/rand.h> #include <openssl/crypto.h> diff --git a/crypto/openssh/groupaccess.c b/crypto/openssh/groupaccess.c index e73f62b..2381aeb 100644 --- a/crypto/openssh/groupaccess.c +++ b/crypto/openssh/groupaccess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: groupaccess.c,v 1.13 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. * @@ -31,6 +31,7 @@ #include <grp.h> #include <unistd.h> #include <stdarg.h> +#include <string.h> #include "xmalloc.h" #include "groupaccess.h" @@ -88,6 +89,30 @@ ga_match(char * const *groups, int n) } /* + * Return 1 if one of user's groups matches group_pattern list. + * Return 0 on negated or no match. + */ +int +ga_match_pattern_list(const char *group_pattern) +{ + int i, found = 0; + size_t len = strlen(group_pattern); + + for (i = 0; i < ngroups; i++) { + switch (match_pattern_list(groups_byname[i], + group_pattern, len, 0)) { + case -1: + return 0; /* Negated match wins */ + case 0: + continue; + case 1: + found = 1; + } + } + return found; +} + +/* * Free memory allocated for group access list. */ void diff --git a/crypto/openssh/groupaccess.h b/crypto/openssh/groupaccess.h index 04b4498..000578e 100644 --- a/crypto/openssh/groupaccess.h +++ b/crypto/openssh/groupaccess.h @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.h,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: groupaccess.h,v 1.8 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. @@ -29,6 +29,7 @@ int ga_init(const char *, gid_t); int ga_match(char * const *, int); +int ga_match_pattern_list(const char *); void ga_free(void); #endif diff --git a/crypto/openssh/gss-genr.c b/crypto/openssh/gss-genr.c index 57f12a2..e919057 100644 --- a/crypto/openssh/gss-genr.c +++ b/crypto/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/crypto/openssh/gss-serv.c b/crypto/openssh/gss-serv.c index e8191a8..2ec7ea1 100644 --- a/crypto/openssh/gss-serv.c +++ b/crypto/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.22 2008/05/08 12:02:23 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -29,11 +29,13 @@ #ifdef GSSAPI #include <sys/types.h> +#include <sys/param.h> #include <stdarg.h> #include <string.h> #include <unistd.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "buffer.h" #include "key.h" @@ -64,6 +66,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/crypto/openssh/includes.h b/crypto/openssh/includes.h index 967fcc2..f1b47f6 100644 --- a/crypto/openssh/includes.h +++ b/crypto/openssh/includes.h @@ -49,7 +49,7 @@ #ifdef HAVE_NEXT # include <libc.h> #endif -#ifdef HAVE_PATHS +#ifdef HAVE_PATHS_H # include <paths.h> #endif @@ -149,6 +149,8 @@ # include <sys/syslog.h> #endif +#include <errno.h> + /* * On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations * of getspnam when _INCLUDE__STDC__ is defined, so we unset it here. diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c index bfc1c11..332fadf 100644 --- a/crypto/openssh/kex.c +++ b/crypto/openssh/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.76 2006/08/03 03:34:42 deraadt 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; @@ -552,7 +557,7 @@ dump_digest(char *msg, u_char *digest, int len) u_int i; fprintf(stderr, "%s\n", msg); - for (i = 0; i< len; i++) { + for (i = 0; i < len; i++) { fprintf(stderr, "%02x", digest[i]); if (i%32 == 31) fprintf(stderr, "\n"); diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h index b1b20f5..8e29c90 100644 --- a/crypto/openssh/kex.h +++ b/crypto/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 <signal.h> #include <openssl/evp.h> +#include <openssl/hmac.h> #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/crypto/openssh/key.c b/crypto/openssh/key.c index 93b2d41..2ea13d2 100644 --- a/crypto/openssh/key.c +++ b/crypto/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.78 2008/07/07 23:32:51 stevesk Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -11,6 +11,7 @@ * * * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * Copyright (c) 2008 Alexander von Gernler. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,9 +36,11 @@ #include "includes.h" +#include <sys/param.h> #include <sys/types.h> #include <openssl/evp.h> +#include <openbsd-compat/openssl-compat.h> #include <stdarg.h> #include <stdio.h> @@ -170,9 +173,8 @@ 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; + /* NOTREACHED */ } u_char* @@ -296,6 +298,114 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) return retval; } +/* + * Draw an ASCII-Art representing the fingerprint so human brain can + * profit from its built-in pattern recognition ability. + * This technique is called "random art" and can be found in some + * scientific publications like this original paper: + * + * "Hash Visualization: a New Technique to improve Real-World Security", + * Perrig A. and Song D., 1999, International Workshop on Cryptographic + * Techniques and E-Commerce (CrypTEC '99) + * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf + * + * The subject came up in a talk by Dan Kaminsky, too. + * + * If you see the picture is different, the key is different. + * If the picture looks the same, you still know nothing. + * + * The algorithm used here is a worm crawling over a discrete plane, + * leaving a trace (augmenting the field) everywhere it goes. + * Movement is taken from dgst_raw 2bit-wise. Bumping into walls + * makes the respective movement vector be ignored for this turn. + * Graphs are not unambiguous, because circles in graphs can be + * walked in either direction. + */ + +/* + * Field sizes for the random art. Have to be odd, so the starting point + * can be in the exact middle of the picture, and FLDBASE should be >=8 . + * Else pictures would be too dense, and drawing the frame would + * fail, too, because the key type would not fit in anymore. + */ +#define FLDBASE 8 +#define FLDSIZE_Y (FLDBASE + 1) +#define FLDSIZE_X (FLDBASE * 2 + 1) +static char * +key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) +{ + /* + * Chars to be used after each other every time the worm + * intersects with itself. Matter of taste. + */ + char *augmentation_string = " .o+=*BOX@%&#/^SE"; + char *retval, *p; + u_char field[FLDSIZE_X][FLDSIZE_Y]; + u_int i, b; + int x, y; + size_t len = strlen(augmentation_string) - 1; + + retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); + + /* initialize field */ + memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); + x = FLDSIZE_X / 2; + y = FLDSIZE_Y / 2; + + /* process raw key */ + for (i = 0; i < dgst_raw_len; i++) { + int input; + /* each byte conveys four 2-bit move commands */ + input = dgst_raw[i]; + for (b = 0; b < 4; b++) { + /* evaluate 2 bit, rest is shifted later */ + x += (input & 0x1) ? 1 : -1; + y += (input & 0x2) ? 1 : -1; + + /* assure we are still in bounds */ + x = MAX(x, 0); + y = MAX(y, 0); + x = MIN(x, FLDSIZE_X - 1); + y = MIN(y, FLDSIZE_Y - 1); + + /* augment the field */ + field[x][y]++; + input = input >> 2; + } + } + + /* mark starting point and end point*/ + field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; + field[x][y] = len; + + /* fill in retval */ + snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); + p = strchr(retval, '\0'); + + /* output upper border */ + for (i = p - retval - 1; i < FLDSIZE_X; i++) + *p++ = '-'; + *p++ = '+'; + *p++ = '\n'; + + /* output content */ + for (y = 0; y < FLDSIZE_Y; y++) { + *p++ = '|'; + for (x = 0; x < FLDSIZE_X; x++) + *p++ = augmentation_string[MIN(field[x][y], len)]; + *p++ = '|'; + *p++ = '\n'; + } + + /* output lower border */ + *p++ = '+'; + for (i = 0; i < FLDSIZE_X; i++) + *p++ = '-'; + *p++ = '+'; + + return retval; +} + char * key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) { @@ -313,6 +423,9 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) case SSH_FP_BUBBLEBABBLE: retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); break; + case SSH_FP_RANDOMART: + retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); + break; default: fatal("key_fingerprint_ex: bad digest representation %d", dgst_rep); diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h index 6873dd7..14aac79 100644 --- a/crypto/openssh/key.h +++ b/crypto/openssh/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: key.h,v 1.27 2008/06/11 21:01:35 grunk Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -42,7 +42,8 @@ enum fp_type { }; enum fp_rep { SSH_FP_HEX, - SSH_FP_BUBBLEBABBLE + SSH_FP_BUBBLEBABBLE, + SSH_FP_RANDOMART }; /* key is stored in external hardware */ diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c index 7f88674..4a8239b 100644 --- a/crypto/openssh/log.c +++ b/crypto/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.41 2008/06/10 04:50:25 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -44,6 +44,7 @@ #include <string.h> #include <syslog.h> #include <unistd.h> +#include <errno.h> #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) # include <vis.h> #endif @@ -113,6 +114,17 @@ log_facility_number(char *name) return SYSLOG_FACILITY_NOT_SET; } +const char * +log_facility_name(SyslogFacility facility) +{ + u_int i; + + for (i = 0; log_facilities[i].name; i++) + if (log_facilities[i].val == facility) + return log_facilities[i].name; + return NULL; +} + LogLevel log_level_number(char *name) { @@ -125,6 +137,17 @@ log_level_number(char *name) return SYSLOG_LEVEL_NOT_SET; } +const char * +log_level_name(LogLevel level) +{ + u_int i; + + for (i = 0; log_levels[i].name != NULL; i++) + if (log_levels[i].val == level) + return log_levels[i].name; + return NULL; +} + /* Error messages that should be logged. */ void @@ -313,6 +336,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 +397,5 @@ do_log(LogLevel level, const char *fmt, va_list args) closelog(); #endif } + errno = saved_errno; } diff --git a/crypto/openssh/log.h b/crypto/openssh/log.h index 7a8c570..6505827 100644 --- a/crypto/openssh/log.h +++ b/crypto/openssh/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.15 2006/08/18 09:13:25 deraadt Exp $ */ +/* $OpenBSD: log.h,v 1.17 2008/06/13 00:12:02 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -49,11 +49,15 @@ typedef enum { void log_init(char *, LogLevel, SyslogFacility, int); SyslogFacility log_facility_number(char *); -LogLevel log_level_number(char *); +const char * log_facility_name(SyslogFacility); +LogLevel log_level_number(char *); +const char * log_level_name(LogLevel); -void fatal(const char *, ...) __dead __attribute__((format(printf, 1, 2))); +void fatal(const char *, ...) __attribute__((noreturn)) + __attribute__((format(printf, 1, 2))); void error(const char *, ...) __attribute__((format(printf, 1, 2))); -void sigdie(const char *, ...) __attribute__((format(printf, 1, 2))); +void sigdie(const char *, ...) __attribute__((noreturn)) + __attribute__((format(printf, 1, 2))); void logit(const char *, ...) __attribute__((format(printf, 1, 2))); void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); void debug(const char *, ...) __attribute__((format(printf, 1, 2))); @@ -61,5 +65,5 @@ void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); void do_log(LogLevel, const char *, va_list); -void cleanup_exit(int) __dead; +void cleanup_exit(int) __attribute__((noreturn)); #endif diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c index 1d5907a..6d90160 100644 --- a/crypto/openssh/loginrec.c +++ b/crypto/openssh/loginrec.c @@ -162,6 +162,7 @@ __RCSID("$FreeBSD$"); #include <pwd.h> #include <stdarg.h> #include <string.h> +#include <time.h> #include <unistd.h> #include "xmalloc.h" diff --git a/crypto/openssh/mac.c b/crypto/openssh/mac.c index e5d5bfa..fabc3ed 100644 --- a/crypto/openssh/mac.c +++ b/crypto/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.15 2008/06/13 00:51:47 dtucker 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, (u_long)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/crypto/openssh/mac.h b/crypto/openssh/mac.h index 960cc5c..39f564d 100644 --- a/crypto/openssh/mac.h +++ b/crypto/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/crypto/openssh/match.c b/crypto/openssh/match.c index e3c9930..2389477 100644 --- a/crypto/openssh/match.c +++ b/crypto/openssh/match.c @@ -1,4 +1,4 @@ -/* $OpenBSD: match.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: match.c,v 1.27 2008/06/10 23:06:19 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -183,7 +183,8 @@ match_hostname(const char *host, const char *pattern, u_int len) /* * returns 0 if we get a negative match for the hostname or the ip - * or if we get no match at all. returns 1 otherwise. + * or if we get no match at all. returns -1 on error, or 1 on + * successful match. */ int match_host_and_ip(const char *host, const char *ipaddr, @@ -191,9 +192,12 @@ match_host_and_ip(const char *host, const char *ipaddr, { int mhost, mip; - /* negative ipaddr match */ - if ((mip = match_hostname(ipaddr, patterns, strlen(patterns))) == -1) + /* error in ipaddr match */ + if ((mip = addr_match_list(ipaddr, patterns)) == -2) + return -1; + else if (mip == -1) /* negative ip address match */ return 0; + /* negative hostname match */ if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1) return 0; diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h index d1d5386..18f6830 100644 --- a/crypto/openssh/match.h +++ b/crypto/openssh/match.h @@ -1,4 +1,4 @@ -/* $OpenBSD: match.h,v 1.13 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: match.h,v 1.14 2008/06/10 03:57:27 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -21,4 +21,7 @@ int match_host_and_ip(const char *, const char *, const char *); int match_user(const char *, const char *, const char *, const char *); char *match_list(const char *, const char *, u_int *); +/* addrmatch.c */ +int addr_match_list(const char *, const char *); + #endif diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c index 78bca2f..8b303f1 100644 --- a/crypto/openssh/misc.c +++ b/crypto/openssh/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.64 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: misc.c,v 1.69 2008/06/13 01:38:23 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -42,6 +42,7 @@ #include <errno.h> #include <fcntl.h> +#include <netdb.h> #ifdef HAVE_PATHS_H # include <paths.h> #include <pwd.h> @@ -120,6 +121,14 @@ unset_nonblock(int fd) return (0); } +const char * +ssh_gai_strerror(int gaierr) +{ + if (gaierr == EAI_SYSTEM) + return strerror(errno); + return gai_strerror(gaierr); +} + /* disable nagle on socket */ void set_nodelay(int fd) @@ -525,7 +534,7 @@ tilde_expand_filename(const char *filename, uid_t uid) if ((pw = getpwnam(user)) == NULL) fatal("tilde_expand_filename: No such user %s", user); } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ - fatal("tilde_expand_filename: No such uid %d", uid); + fatal("tilde_expand_filename: No such uid %ld", (long)uid); if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) fatal("tilde_expand_filename: Path too long"); @@ -616,6 +625,8 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, u_long *lineno) { while (fgets(buf, bufsz, f) != NULL) { + if (buf[0] == '\0') + continue; (*lineno)++; if (buf[strlen(buf) - 1] == '\n' || feof(f)) { return 0; @@ -821,3 +832,23 @@ put_u16(void *vp, u_int16_t v) p[0] = (u_char)(v >> 8) & 0xff; p[1] = (u_char)v & 0xff; } + +void +ms_subtract_diff(struct timeval *start, int *ms) +{ + struct timeval diff, finish; + + gettimeofday(&finish, NULL); + timersub(&finish, start, &diff); + *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); +} + +void +ms_to_timeval(struct timeval *tv, int ms) +{ + if (ms < 0) + ms = 0; + tv->tv_sec = ms / 1000; + tv->tv_usec = (ms % 1000) * 1000; +} + diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h index f175b44..5da170d 100644 --- a/crypto/openssh/misc.h +++ b/crypto/openssh/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.36 2006/08/18 10:27:16 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.38 2008/06/12 20:38:28 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -33,8 +33,11 @@ char *tilde_expand_filename(const char *, uid_t); char *percent_expand(const char *, ...) __attribute__((__sentinel__)); char *tohex(const void *, size_t); void sanitise_stdfd(void); +void ms_subtract_diff(struct timeval *, int *); +void ms_to_timeval(struct timeval *, int); struct passwd *pwcopy(struct passwd *); +const char *ssh_gai_strerror(int); typedef struct arglist arglist; struct arglist { diff --git a/crypto/openssh/moduli b/crypto/openssh/moduli index a12de21..65d2814 100644 --- a/crypto/openssh/moduli +++ b/crypto/openssh/moduli @@ -1,189 +1,174 @@ -# $OpenBSD: moduli,v 1.3 2005/01/24 10:29:06 dtucker Exp $ +# $OpenBSD: moduli,v 1.4 2008/01/01 08:51:20 dtucker Exp $ # Time Type Tests Tries Size Generator Modulus -20040225025212 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7AFFE86A7 -20040225025304 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B01F83CB -20040225025357 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B03F2B73 -20040225025411 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B041C8C7 -20040225025444 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0546E93 -20040225025458 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0573767 -20040225025522 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0629E73 -20040225025545 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B06CD95B -20040225025616 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B07C93A3 -20040225025655 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B093C72B -20040225025710 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B096450B -20040225025750 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0AF2C83 -20040225025830 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0C7F1FF -20040225025845 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0CB565B -20040225025858 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0CD8557 -20040225025915 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0D20473 -20040225025934 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0D924F7 -20040225025952 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0DFD8BB -20040225030015 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0E8E59F -20040225030039 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0F43B0B -20040225030104 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B0FEB103 -20040225030130 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B10AC3DB -20040225030149 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1122527 -20040225030214 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B11E494B -20040225030245 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B12E727B -20040225030319 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1416743 -20040225030347 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1507F2B -20040225030404 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1560FE3 -20040225030418 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1591CF7 -20040225030432 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B15B57FF -20040225030455 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B165D0AF -20040225030511 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B169C97F -20040225030551 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B182715B -20040225030621 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1920737 -20040225030648 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B19FB54B -20040225030718 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1AFAE87 -20040225030736 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1B5A7AF -20040225030753 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1BC3C47 -20040225030815 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1C6AF33 -20040225030831 2 6 100 1023 2 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1CAD9FB -20040225030902 2 6 100 1023 5 CAADDDEC1667FC68B5FA15D53C4E1532DD24561A1A2D47A12C01ABEA1E00731F6921AAC40742311FDF9E634BB7131BEE1AF240261554389A910425E044E88C8359B010F5AD2B80E29CB1A5B027B19D9E01A6F63A6F45E5D7ED2FF6A2A0085050A7D0CF307C3DB51D2490355907B4427C23A98DF1EB8ABEF2BA209BB7B1DC6A8F -20040225035226 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844800C47CAB -20040225035359 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844800D3866B -20040225035635 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844800F43DFF -20040225035846 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448010B4D93 -20040225040147 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448013094F3 -20040225040301 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448013AA0FB -20040225040619 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480163EC83 -20040225040718 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448016AEB8F -20040225041023 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480190871F -20040225041328 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844801B5F1B3 -20040225041740 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844801ED6FBB -20040225041921 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844801FEC44F -20040225042229 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802245FF7 -20040225042513 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480246F93B -20040225042547 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802473F4F -20040225042707 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480253B03B -20040225043111 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480287CD9B -20040225043513 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802BC32FB -20040225043609 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802C2125B -20040225043847 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802E1B733 -20040225043925 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844802E2E963 -20040225044335 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448031AC423 -20040225045303 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803A10E07 -20040225045443 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803B0EF43 -20040225045518 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803B15033 -20040225045923 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803E58317 -20040225050120 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844803F9EB4F -20040225050333 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448041304B3 -20040225050524 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804279B2F -20040225050559 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804281047 -20040225050810 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF8448043F454F -20040225051113 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804672F1F -20040225051335 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804809CB3 -20040225051442 2 6 100 1535 5 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF84480489545F -20040225052303 2 6 100 1535 2 FC4601920ABD76FF37FDC717EDFFEC0E539D5F7697882432A53085C95B040175503AEBD8A0FDF38D5F4EAA8EB1A22389D2CF2070F4DD47E2E8F89F4DD4ACACE4593F762DB92C479EBF1BBD4EF450A7FFAA15F75FB921B42B62466C29A993E7C7D8FD8412A4869D867E2765C2CBA0BC0F31E625B9BE1FF5421FDC2E097E0EF66F1CC9FF04AEB9341327D3468630C4E049530EF12350D51A71FDF9B6DB3CE56ED8C9FE61148F8098722A43C4F0AE29855BC9E06068D3898146ACFF844804FE918B -20040225062215 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6B9F68B3E7 -20040225063823 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6B9FD47307 -20040225064402 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6B9FF43C0F -20040225065646 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA04740DB -20040225065825 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA04B01BF -20040225070116 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA056DD47 -20040225074027 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA172E1B3 -20040225080343 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA217422F -20040225081159 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA24927DB -20040225081331 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA24C058B -20040225082528 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA2993EBF -20040225084537 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3242BE3 -20040225085012 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA33EF643 -20040225085829 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3729D77 -20040225090710 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3AC0143 -20040225091002 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA3B8AE6B -20040225092648 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA42B65D7 -20040225093120 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA4442793 -20040225093517 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA459441F -20040225094409 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA491BE4B -20040225095209 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA4C4E437 -20040225095548 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA4D5D7AB -20040225100531 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA51404EB -20040225100644 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5145C87 -20040225101834 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5609CBB -20040225102317 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA57AC86F -20040225103220 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5B631A3 -20040225103355 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5B98D2F -20040225103756 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5CEBAFB -20040225104020 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5D77CDF -20040225104557 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA5F6FD9F -20040225110302 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA66A70DF -20040225110515 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA6721A43 -20040225110913 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA6879A53 -20040225111338 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA69FE2FB -20040225111911 2 6 100 2047 5 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA6C04F47 -20040225112902 2 6 100 2047 2 F8F54DA4E1F232A9D05104B807DCBEA553C1E606FEB1CF149DEBB99243AAA7A354616FD95368EBCC1A58C8BCB87FB993F731400A413E07E35B1ADDD6484973E1734835FEFDC214DACA8C0844285A670D03BB3E1A5B5E14DC6F3B20EAAC8F18EB6C48AA5604F21EBEEA3C867F6CFA010858DFD589DCDEFBE8996A42F5BA00BEDFF6743F4D4E2808806965258C4E17D1B2BF371814696A2CC7C5C6548ED480AA7491A9DE16D2B12F15471B192295AA27F6D047EC2BA7547ED70674F52B4934D846712B1EA87E7FE12C5A210DEF5B3A14DBC8E712AA7192D877B4E6479F3CD69F82127E7352C19191B036A86BCF2D7D7CC687C25C5E4620295F10DCCE6BA7007CD3 -20040225143208 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8968A91B -20040225144922 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8987DF6B -20040225150309 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD899E0F8B -20040225161716 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8A3A91CF -20040225163012 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8A4CED2B -20040225175457 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8B02C5DB -20040225182539 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8B3E9D13 -20040225194030 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8BDE269B -20040225201420 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C203553 -20040225203219 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C40B747 -20040225203908 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C46ED83 -20040225210230 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8C72586B -20040225212746 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8CA15F2F -20040225214624 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8CC34833 -20040225223007 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8D1B23AB -20040225234913 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8DC36C9B -20040226001353 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8DF174B3 -20040226004101 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8E24518B -20040226010652 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8E543397 -20040226015415 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8EB6152F -20040226022931 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8EFD1773 -20040226025740 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD8F3376D7 -20040226053010 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD90786CE3 -20040226054156 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD908AC36B -20040226081600 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD91D61A43 -20040226083039 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD91ED4AE3 -20040226092910 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9265F7DB -20040226112913 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD93696533 -20040226115826 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD93A210A3 -20040226135326 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD949596D7 -20040226145128 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD95096CCF -20040226153142 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD95582C7B -20040226164905 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD95FACE7B -20040226171921 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9633F443 -20040226182347 2 6 100 3071 5 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD96BAC3A7 -20040226200555 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD97972EFB -20040226202801 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD97C0B5C3 -20040226214755 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9868011B -20040226215843 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD9876E7FB -20040226220422 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD987B4983 -20040226222346 2 6 100 3071 2 EDDA2E6520E6A915FE821EA06B4E19C95EBA8092F521CDE778B7B6CCA0FD89E935C904E2FA83E37DD49C1C52120C0958B85AAEE0B1A0E36C89836CE6C5509D50ABA58C154289C129B4A12A9249589496A5381CEA2105D818DB8790C4913BAD3C4C5ADB6BE036BD44B8AFB9F607017277FA36C971E5F10D7D062354FAB31BA97B376D723451478D1BA7D2C213A2E377E6826FF2F0695A2EDF9F8107DE4FF78DD0C2EF3A715084592623C58D2B2775FC7C0CF8F745EA1C75BEA8E574B9747207357DE143B0A803829E418B8F4BB44C40481CBB086B8AC6B93CC0E989E1336A010529F5D0FC4E077F778672646C62B7371965D60822C871F97C03913DB5CE080F67A348DD1722DD7BFA0761B2BF16A925FB9FCB6DCD1BC959A8794ACAEA984E1E9AE7BB2276B9C866CC890D8A8C51A17C479DA689DAA065C019CF9B082ED67D9CF1C9753E2A4030CCC27BE34280F042384597CEA223D5FA6631E109D5A23C60312F1D4783C3403D67A0D67665F7C5BEABF0BC30514DB07D7EF2A8E07CDD989D61D3 -20040227091438 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC5737ECF -20040227101541 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC5AE7363 -20040227160657 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC7295F4F -20040227180410 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC7A46573 -20040227225950 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC8E6D5E3 -20040227233727 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFC9079B33 -20040228032633 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCA006227 -20040228060859 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCAAE6E63 -20040228101703 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCBBC54FB -20040228192850 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFCE191D13 -20040229084451 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD1804AF3 -20040229164933 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD3887E07 -20040229210220 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD49457B7 -20040229222958 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD4EA3223 -20040301003324 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD566C79B -20040301030228 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD6032D8F -20040301040042 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD63B1113 -20040301073501 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD71C4A67 -20040301133631 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD8A0BBD3 -20040301165652 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD96E4053 -20040301184021 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFD9D662FB -20040302045553 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDC5FE8E3 -20040302112648 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDDFE9D13 -20040302120026 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDE1A5AD3 -20040302130757 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDE5E4073 -20040302142004 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDEA4AA9B -20040302145603 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFDEC2C32B -20040302212946 2 6 100 4095 5 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFE0652EC7 -20040303003544 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFE127CF63 -20040303072925 2 6 100 4095 2 C7FE661FF2675517258B6E893FE81DFC29EDFB28FFE325C4F929BFAF5D0203DF5D75D966B0886A4197CC8F2EE339349DF88E73C54A315C402DF609DA61A237435167524F8EA37E5AB33E8A0C80E36DF4F6B9D6141958CC784CDDB6E2543038C9966D62AC2474786F2E2890E4935AD47BB005A6FC309817807EC9597B69858F1FBD6A1B28E897EFB6219F9FF83BEAFFD448C9F2F8C33CEA7C08242428FD75D218411E41523B688BF3D9311374E43D8963C821611BBBC91CA23968E60FB143FA0B36120657734D5C83C1C58A5A229CCDDC27875E51C358F0C8FEDDE4A11C50E0A154C80127B6FF92F496F7F2FA41D601A3EA88A3A53569AA3F3ABA5761757AC553CF57578800379C5F06082DD6088841D7BA48A58D1422B0DEC088279655C2D6380CF7097CD39565E9998785CBEB300AFFADEACA285201CBB27F48456EF7E49DE75380D0D1B4CCC28ADB8E12903473548D74A8847DAADC34315F157351C4CD507FF9B03CA6DD1C954BB75C9FD3C425FEFA76FC03FB346BE11E61B67A3AD374C1843ECA636CC7454249AB2A08B645DADCBFB48A470B1206ED20020FF0A0F5C2253187BBC2BC7F449AD58D35746E5A47B4A7BB404592C0A1F4E3BA34938C1E3C32464E1A52D3E722FA1165B72E8B438C11CFD0DB42A4081ED09F468A2E17C8D3F2BB689DC0CC831F889D7BAFC39D2A7F6C9A362E9BAE48B12FBACF34F9DFE2D793F3 +20060827013849 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE261778F3 +20060827013906 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE261CC47B +20060827013924 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2621AFA3 +20060827014045 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26551B8B +20060827014056 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26556A27 +20060827014115 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE265B7273 +20060827014137 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26644D77 +20060827014203 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26717773 +20060827014214 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26722EBB +20060827014312 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26961C8B +20060827014407 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26BA7BBF +20060827014418 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26BAC107 +20060827014436 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26C05207 +20060827014515 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26D48C73 +20060827014527 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26D65CD7 +20060827014538 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26D7096F +20060827014607 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26E3760B +20060827014626 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26EAF29F +20060827014637 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26EBCF4F +20060827014653 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE26F0D6BB +20060827014732 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27088963 +20060827014835 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27320A73 +20060827014915 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27486FA3 +20060827014926 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2748FD9F +20060827014940 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE274BB323 +20060827014956 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE274F8F7F +20060827015028 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE275C008F +20060827015112 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2776D9EF +20060827015134 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27809AA3 +20060827015146 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27826DFB +20060827015200 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2785363F +20060827015231 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27951F4F +20060827015246 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27991903 +20060827015300 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE279C7B37 +20060827015329 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27AB4843 +20060827015347 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27B0F9D7 +20060827015359 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27B24D5B +20060827015430 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27C2CE27 +20060827015449 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27CA3BA3 +20060827015546 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27E90A07 +20060827015607 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27F116BF +20060827015630 2 6 100 1023 5 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE27FBB66F +20060827015649 2 6 100 1023 2 DE49FC9069994C379D2B6563EFD37EFAE6785EEB1DD0A12B090AAC272B22DF8C64A4A2AB7B99CE0B77A9A52E0833D52D53B258CEDFFD175DC8A3766A9B9807362646DC9215628C3F4AF0E08D00AB60A3B9E55BAE47E82651DA0C15A27355DDB06365CAE1DDDE4C0C97DC9942FD65E9867FA50E72E1C785411EDD28DE2803E313 +20060827024302 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AD6C361B +20060827024350 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AD6F7E93 +20060827024537 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AD7DE4BB +20060827025000 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6ADB6D4D7 +20060827025429 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6ADEF2D8B +20060827025612 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6ADFCCB13 +20060827030138 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AE41E89B +20060827030223 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AE44A263 +20060827030555 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AE6FD2A7 +20060827031244 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AECC68C3 +20060827031437 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AEDFB4EB +20060827031602 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AEEB07E7 +20060827032434 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AF5B1533 +20060827032933 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AF99D5D3 +20060827033028 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AF9CF037 +20060827033120 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFA14BBF +20060827033331 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFB9FD2B +20060827033555 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFD32F8B +20060827033806 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6AFEBB7DB +20060827034045 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B009C8D3 +20060827034214 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0177447 +20060827034316 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B01EFC27 +20060827034514 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0313F9B +20060827035109 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B07D542B +20060827035412 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0A3485F +20060827035525 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0AAF3BB +20060827035829 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0CFE04F +20060827040101 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B0E988E7 +20060827040504 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B11D001B +20060827040746 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B13A45DF +20060827041350 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B188B89F +20060827041513 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B193B2EB +20060827041621 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B19B9807 +20060827041657 2 6 100 1535 5 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B19C0107 +20060827041817 2 6 100 1535 2 DF09936D6567325CD4EDE975CB3B9BFFB26C5EC31A71ABA0931BE89AEEB81A531708540B7EA03875E5DF4935ED021F3955D5C941BB682DBDA5425F4EF84DD1F42C6DCC5E313D64DE5B658682A51785102358771DDB6C2B86079C3D0A4EB0DA149E7B2CAC0AC254FFBCD82DF11D74A4E0BBE3FA0AD0675B8A3C6E794E943B7F3799BA8C0F80D602F85D3032D206A96EB16DAFD2C036F8D4F3DA1CCDB2178F08BD851D7BB1C2E964F48F91B2546916E76A80D8E16F700E1FC194308DD6B1A6BE4B +20060827052122 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C77E8ED3 +20060827055248 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8549C07 +20060827055453 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C85B17DF +20060827060456 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C899BBE7 +20060827061203 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8C362B3 +20060827061433 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8CC69F7 +20060827061904 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8E44BC7 +20060827062255 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C8F6B23F +20060827063052 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C926C817 +20060827063354 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9351ABF +20060827063925 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9541A43 +20060827064904 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C98CFAE7 +20060827070314 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9E30823 +20060827070806 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532C9F90C33 +20060827071119 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA04D477 +20060827072534 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA5A1ADB +20060827073212 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA7E88A3 +20060827073641 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA93A193 +20060827073850 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CA999B57 +20060827080040 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CB21505F +20060827080817 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CB4C2F97 +20060827083711 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC0FAA7F +20060827084308 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC30FD83 +20060827084830 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC4EFB67 +20060827085653 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CC8152FB +20060827090522 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CCB5AE6B +20060827092253 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CD252FCB +20060827095916 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CE117E2F +20060827100246 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CE2087CB +20060827102041 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CE925537 +20060827102556 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CEAF2A27 +20060827103749 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CEF9826F +20060827103917 2 6 100 2047 5 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CEFBC467 +20060827104611 2 6 100 2047 2 C038282DE061BE1AD34F31325EFE9B1D8520DB14276CEB61FE3A2CB8D77FFE3B9A067505205BBA8353847FD2EA1E2471E4294862A5D4C4F9A2B80F9DA0619327CDBF2EB608B0B5549294A955972AA3512821B24782DD8AB97B53AAB04B48180394ABFBC4DCF9B819FC0CB5AC1275AC5F16EC378163501E4B27D49C67F660333888F1D503B96FA9C6C880543D8B5F04D70FE508FFCA161798AD32015145B8E9AD43AAB48ADA81FD1E5A8EA7711A8FF57EC7C4C081B47FAB0C2E9FA468E70DD6700F3412224890D5E99527A596CE635195F3A6D35E563BF4892DF2C79C809704411018D919102D12CB112CE1E66EBF5DB9F409F6C82A6A6E1E21E23532CF24A6E3 +20060827130320 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFA80B3F +20060827132001 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFC2F2A3 +20060827132659 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFC83DE3 +20060827133231 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFCAE263 +20060827134212 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFD5D943 +20060827135606 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084EFEAD4AB +20060827142452 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F01CBFBB +20060827185212 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F24CFF67 +20060827190158 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F2599507 +20060827202730 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F305315B +20060827213252 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F38A5B63 +20060827214322 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F3987FC7 +20060827214825 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F39A3CDB +20060827232520 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F46375AB +20060828030405 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F62B17EB +20060828043230 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F6E0BB4F +20060828081338 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F8A9B0EF +20060828083613 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F8D164EF +20060828090529 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F906488B +20060828100621 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084F97FF4CB +20060828121421 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FA80824B +20060828141024 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FB659087 +20060828142059 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FB739E8F +20060828170552 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FCC5CE57 +20060828171327 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FCCCF9D3 +20060828185943 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDA67727 +20060828190537 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDAAC673 +20060828191202 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDAFC737 +20060828192613 2 6 100 3071 2 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDC50FBB +20060828193738 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FDD6023F +20060828204936 2 6 100 3071 5 D3230D237572ECE9F92358715EBAC3A4D89F2D6B4DC39F056450263BEF1665FBD7B93916ABC867B7064802159D273C7EB01C5F9281A3D6DCCB7CF997D385998EC0E1FA3319AFE771A90ADBACEB414A020630D7C7F161FAFEC6C9FC06D3205C712AAE8848A1B2C21DFF301C7FFC0B75D13F060A313C32AFEEAF1493F641760EBEF38829B3371699D2A3264D0ECEB4E5C19581ED8C57699F559B9828BBFE147952E289F0E171C9C60335DD2F492CB409A4DB97BDF86E2DBA605064DB040A3DF5678E24F66718CA115C95C892FF7AEDFAABC2E6414716298CEC1A604270FEADF191B7C8A59C238C395A65442C0B963BF83025BED3951A271B7440EC7687C31DE63355DA7FEAC15DC962C7BF7614EB59B077B9889AD8703DFE98AC99615B722A0ABE89956D1058E025C7733420CB51D7E1608EFF2C0A30C9A5EB77CCA02C6B00CE781B172001C6C458630890062E27CE307D513A7686A69D1D548DE8334B13136D9E842A5E17FD67522C93823E03F08AEE8024AF5D88B2EE01D4D9980084FE68405F +20060829063416 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE57DE9222B +20060829082327 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE57E5385E7 +20060829092010 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE57E8501A3 +20060830004204 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5825F180F +20060830013522 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5828DFA2B +20060830124707 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58555C9EB +20060830180312 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE586989437 +20060831041205 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5891334BF +20060831102341 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58A8F8B27 +20060831234001 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58DD7278B +20060901032352 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58EBE93EB +20060901061345 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE58F693A3F +20060901123055 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE590F80AE7 +20060901191922 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE592994C63 +20060901203957 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE592E5D92F +20060901210250 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE592F4A5F3 +20060901225047 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5935D124B +20060902020657 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE5942520CB +20060902070624 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59553E03F +20060902095300 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE595F6EC6B +20060902113306 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE596599BEF +20060902142302 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59703582B +20060902210839 2 6 100 4095 5 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE598A695F7 +20060903073325 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59B315E9B +20060903095626 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59BBD7153 +20060903162601 2 6 100 4095 2 DA110847314B537539F2A20681212A0B2ED264BF1F2595B817CC516D5AA4211585948B248F77277B11AB206738C71B5FB2FCC4041927B40B985282795A89EF66BDB111E1D07D790AC487DA5841B66FC407ED5DD8612703136422C442139C12040CE776FEB6C8B59B95408F31FB50073AD54B03F97113E61BE577E76D13AA971BA82CEE621C31C4770A7E076245A16689A9FE3E9190FB617FB330AA70AAC623B447D1858C24993D486C2B9A3C63FFCB3F230E7185F163C1EED434C24EE11EAC5B2369FEAF790523BD8BF7E8F9C87467ED6C89E5596974DCA6960E537259EA3AA587BF5198B26CE37638BC57012851903BB4CC0E2A28EC741EECB6220556EC5C118AE0142E5374AE2A3D1CEF165C09C0988A37877BCA6BBCAE28D52DA6701BF077307195C3618D4CAC58DDF64B6A8C2BF8E2FDCC0840973A8ED1F8413689BE05EA54AB6CD30464F94DD926D8CEC6B56704F534C6D8329A27ECAD9836721BC0C283E63CDA54FCEA851C0203E747BB02B75C92036928EFC201FFCBB747A2E093CCED157C3C3F74258D5607B6B8AA330DECCF42A73A6F81D300BAFCA921BAFF635DFC90824938F7454B258C1967FF90C1D828E028F9FA86AA7B287A87EC750EDCECEEEC223EAEA78511CB3C0130043950478737FDF6D56EA2B705D5E4C57701E955A9C862DBCAF36D0624D2F2C20616AA3E0478A4A722BBA577BC02578EE59D48AEE3 20040305011518 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E4CE974B 20040305043124 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E5050933 20040305084728 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080E54C7783 @@ -198,3 +183,6 @@ 20040319025848 2 6 100 6143 2 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C7080FD81741B 20040323194658 2 6 100 6143 5 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C708105AF04AF 20040324041535 2 6 100 6143 5 E95A4131F86234D27EE1E51791599559EEDB618912E4FE36B81B80CDA4D497959DBFAEE929317A66BE64A328BAB6183EA5A5CBB3581490B4B613B225ADD00EFD38540356E0F4716229CDDB260283AF044FDAF1EF9248BB0CE9031C117CF15D3259B3E7B0301CA1AAC91AFA7A57CCDEED2DA4EFC2DBC7A9FC53BB4D3CB2D57D209D5DDEF25DE14F8226404296BD504EC14F6340F0AA2A1A943B9552C4B91D3EB48C08A13671C36EE5042857625DD2CB58965C0975EB775057FF82BC2B8B69D0BF26E2F80115B3E1A984D1D73D9D02AD69C3A1AF90EC915DE6FC9F574BD755B2EF6BBE62F3717E128DC797A06FE35C1C28CED57A0F64F61A4439ACFE7A7B95A1A948417A5B8B69916A32989B00E2C3FB7C74139A4DA9E533C439E59FC7C4F90780D2BBCDF012C499C15A1E0B5C318F84FB17DF97AB3EC356FD0072CFA3884EFBED319009DE6DBF2A5C7C87A93DEB04CCD9147EF8C9BEC2FD713793E4F0BF8C4EFCEBFBF95D555E523AB5D742808C4E425979A1C216C8CB2B42C7715B8CA5907E84E6FBC35DA7BFBFC892870B659C882C6E3697E0DCC6C24771F26D51A890786DA516DBC2D161680B134F1715B32F734E667650398EC2241AF78877BB3D61D83D0158DDE894862EE6E1BEE278724EA7B34C74F0A5D6B7F79F1322E20AD5757E11D9AC31BFE27C56ABB23A275130533433DC41DDBA1081E3A018E0D0B55DF33ECAE104909DC74F1CA2256CFD423A859B0AC2112A0AE684396C0029AD07D0D30AC84FFD2C2E80B74DE29310FCAFE7D0CB8864729B6FD1F86052D7DD9A9CB085A186259A67C175B3F81C5DA19AFED1BF9C5C07F40A29ED47ED4F1C7DE878B8411E3239ED15AC0E4CCC1D7F8842E9FD9C989F301E2689F800C3D14A38810906A36EEA34207014E99C843C599D56FCFBC14278A2A009C13B6E4AC7460B54D2C7EF38D72AC450540097D2AF609D3FFF874D14582FA8FF21027DEC92844BD22A9A7EC14C66BCC8DB1E058B95AF87ACB60A5725767A76C9185744E483BCCD9278ED9FF15A04061D0F6E32D98B6853A39AA498673C7DD012982B1913B3C3CE2C70810643E737 +20061002171426 2 6 100 8191 2 D2D64D8CC6FDFA9897C8AE805EA7CB972D7A10F5A268EB5B33B0CCE2C75E480365A49070185D8B316872BAF0F3AAF94498A8E0007A13D574C905441F19D4B0D55A83E2A70C09F7B3E353DEA76F5FEB4191E31F4A52D0BC643B9FD1959BDF8B99C13F245B5D9E8589D6C18A844814486F25A8E189B964A9E72675DDE4D759C901C09F7C24CB3E939B54D2009AE9331446C1EDE5FA9D0A33B36F6A6C9B55E956A94169FBE9C1A24EC9A3E497371F4131F2B1E4FB25A1BB27B23A6661155F37C6EC913E5CB207AD894C2319852C556CA040C6B72DE6E913BCF419E5914507119F771206FAB25B1D6BAD57AFEAF74D807CC576549CD979B0AAC13F5D2B637CCF4A54D2D903A4B29C16B9E8BEE8AD6200D24E4E3E97EB25B2DD13C31AE2A4F27D6EFBFA113F9334F92204FCFFCAA5EBDCCBA986C5B6E665FE71D6654ACA3C8051424133597FD65A18BB2AA24FFDD8B09A8758D984E09BE1F55B16A37B36B058295B1E9942A89D386D4B4DB58C516429248052D97DE42BFC32AB14F13D7F963E86867B8B7245062061C9F315EA94C38FCC0E118373BEFC41D1004CF0FA6D951E20BAC5D2C15F5796163469B88A75FE5F5D2C69C949DA47DAC75D22869F37FAB2490791FA5A5854360EAA13701CEE40EC371797272A12746ABA9CB303224B82F8CCE3F62C0D3EA0D62BF3B2C387E015B1A96A4C4A2A73ADA521B0536B81A536A5119EC559D524BA7F2B25A094A164A4EEBB8ADA886DCBA9647FC4D2D4A91BA0DB32805EDA75B61E09F44BC49862D70B8F28C8E630CD6F0DF245535D79DCD75ECBDE51B29AA6DD3F59736E5028E3AB1E75CFCDA1FF9E6F8D52027A4BC218FC9A9E660BF7EB14D300F4199C04B24725405AFA6535DF0837FEF33C0F8B57B9BDFFB1D956E7B40E822FF40603FB5417523B115FE5864094001CEF2526395C19532F153C4630B95E9835FAC985E1C9DF62188DBA12D5B8BEEB414FFD90AFEDF8F986DF33EF5BC7F7C16ACDC4D40A00822CE17A9724066EED89127195BB9D037CB7FB74AA7178A1A4CBECC5D9F67747AA74156C70E54BABA8641A55B93637385A0D1D56E5220867B5A11ED44CFC405AC238DC39690A966A2DE238FFA1E3B3C859D988DE14916C32AB2A2CB35C57F3609C34F1E8E4B5FAC2F446E0EB78CFD64DD7A3570677D373E8FEC6FF47D5471577D92F22B115D03F302C8CD1A43FCDCEBBA823EE942D7733FF7F78672BEAACCEA279744CC14D60E3912E81A14421989CF5B2C10FD1CDB6CA95E2CA8C574AA6C4F3856602A0D32A9978697752878C0DCB50EF5463EE61C83F776AB9D8098755AF00D2972D3E5E502C39A9CE52C8588472C1D3242CA658290F472D48CB0876752643C2F63CFEB66DF6E93C8BE2404DFA10AB3D8EEF214C371DC0EC29755C086574B1AA92A892B517F6E01056DD5EFEB2437E23100E487E3D4B +20061005090403 2 6 100 8191 5 D2D64D8CC6FDFA9897C8AE805EA7CB972D7A10F5A268EB5B33B0CCE2C75E480365A49070185D8B316872BAF0F3AAF94498A8E0007A13D574C905441F19D4B0D55A83E2A70C09F7B3E353DEA76F5FEB4191E31F4A52D0BC643B9FD1959BDF8B99C13F245B5D9E8589D6C18A844814486F25A8E189B964A9E72675DDE4D759C901C09F7C24CB3E939B54D2009AE9331446C1EDE5FA9D0A33B36F6A6C9B55E956A94169FBE9C1A24EC9A3E497371F4131F2B1E4FB25A1BB27B23A6661155F37C6EC913E5CB207AD894C2319852C556CA040C6B72DE6E913BCF419E5914507119F771206FAB25B1D6BAD57AFEAF74D807CC576549CD979B0AAC13F5D2B637CCF4A54D2D903A4B29C16B9E8BEE8AD6200D24E4E3E97EB25B2DD13C31AE2A4F27D6EFBFA113F9334F92204FCFFCAA5EBDCCBA986C5B6E665FE71D6654ACA3C8051424133597FD65A18BB2AA24FFDD8B09A8758D984E09BE1F55B16A37B36B058295B1E9942A89D386D4B4DB58C516429248052D97DE42BFC32AB14F13D7F963E86867B8B7245062061C9F315EA94C38FCC0E118373BEFC41D1004CF0FA6D951E20BAC5D2C15F5796163469B88A75FE5F5D2C69C949DA47DAC75D22869F37FAB2490791FA5A5854360EAA13701CEE40EC371797272A12746ABA9CB303224B82F8CCE3F62C0D3EA0D62BF3B2C387E015B1A96A4C4A2A73ADA521B0536B81A536A5119EC559D524BA7F2B25A094A164A4EEBB8ADA886DCBA9647FC4D2D4A91BA0DB32805EDA75B61E09F44BC49862D70B8F28C8E630CD6F0DF245535D79DCD75ECBDE51B29AA6DD3F59736E5028E3AB1E75CFCDA1FF9E6F8D52027A4BC218FC9A9E660BF7EB14D300F4199C04B24725405AFA6535DF0837FEF33C0F8B57B9BDFFB1D956E7B40E822FF40603FB5417523B115FE5864094001CEF2526395C19532F153C4630B95E9835FAC985E1C9DF62188DBA12D5B8BEEB414FFD90AFEDF8F986DF33EF5BC7F7C16ACDC4D40A00822CE17A9724066EED89127195BB9D037CB7FB74AA7178A1A4CBECC5D9F67747AA74156C70E54BABA8641A55B93637385A0D1D56E5220867B5A11ED44CFC405AC238DC39690A966A2DE238FFA1E3B3C859D988DE14916C32AB2A2CB35C57F3609C34F1E8E4B5FAC2F446E0EB78CFD64DD7A3570677D373E8FEC6FF47D5471577D92F22B115D03F302C8CD1A43FCDCEBBA823EE942D7733FF7F78672BEAACCEA279744CC14D60E3912E81A14421989CF5B2C10FD1CDB6CA95E2CA8C574AA6C4F3856602A0D32A9978697752878C0DCB50EF5463EE61C83F776AB9D8098755AF00D2972D3E5E502C39A9CE52C8588472C1D3242CA658290F472D48CB0876752643C2F63CFEB66DF6E93C8BE2404DFA10AB3D8EEF214C371DC0EC29755C086574B1AA92A892B517F6E01056DD5EFEB2437E23100E4A242A2F +20061005152228 2 6 100 8191 2 D2D64D8CC6FDFA9897C8AE805EA7CB972D7A10F5A268EB5B33B0CCE2C75E480365A49070185D8B316872BAF0F3AAF94498A8E0007A13D574C905441F19D4B0D55A83E2A70C09F7B3E353DEA76F5FEB4191E31F4A52D0BC643B9FD1959BDF8B99C13F245B5D9E8589D6C18A844814486F25A8E189B964A9E72675DDE4D759C901C09F7C24CB3E939B54D2009AE9331446C1EDE5FA9D0A33B36F6A6C9B55E956A94169FBE9C1A24EC9A3E497371F4131F2B1E4FB25A1BB27B23A6661155F37C6EC913E5CB207AD894C2319852C556CA040C6B72DE6E913BCF419E5914507119F771206FAB25B1D6BAD57AFEAF74D807CC576549CD979B0AAC13F5D2B637CCF4A54D2D903A4B29C16B9E8BEE8AD6200D24E4E3E97EB25B2DD13C31AE2A4F27D6EFBFA113F9334F92204FCFFCAA5EBDCCBA986C5B6E665FE71D6654ACA3C8051424133597FD65A18BB2AA24FFDD8B09A8758D984E09BE1F55B16A37B36B058295B1E9942A89D386D4B4DB58C516429248052D97DE42BFC32AB14F13D7F963E86867B8B7245062061C9F315EA94C38FCC0E118373BEFC41D1004CF0FA6D951E20BAC5D2C15F5796163469B88A75FE5F5D2C69C949DA47DAC75D22869F37FAB2490791FA5A5854360EAA13701CEE40EC371797272A12746ABA9CB303224B82F8CCE3F62C0D3EA0D62BF3B2C387E015B1A96A4C4A2A73ADA521B0536B81A536A5119EC559D524BA7F2B25A094A164A4EEBB8ADA886DCBA9647FC4D2D4A91BA0DB32805EDA75B61E09F44BC49862D70B8F28C8E630CD6F0DF245535D79DCD75ECBDE51B29AA6DD3F59736E5028E3AB1E75CFCDA1FF9E6F8D52027A4BC218FC9A9E660BF7EB14D300F4199C04B24725405AFA6535DF0837FEF33C0F8B57B9BDFFB1D956E7B40E822FF40603FB5417523B115FE5864094001CEF2526395C19532F153C4630B95E9835FAC985E1C9DF62188DBA12D5B8BEEB414FFD90AFEDF8F986DF33EF5BC7F7C16ACDC4D40A00822CE17A9724066EED89127195BB9D037CB7FB74AA7178A1A4CBECC5D9F67747AA74156C70E54BABA8641A55B93637385A0D1D56E5220867B5A11ED44CFC405AC238DC39690A966A2DE238FFA1E3B3C859D988DE14916C32AB2A2CB35C57F3609C34F1E8E4B5FAC2F446E0EB78CFD64DD7A3570677D373E8FEC6FF47D5471577D92F22B115D03F302C8CD1A43FCDCEBBA823EE942D7733FF7F78672BEAACCEA279744CC14D60E3912E81A14421989CF5B2C10FD1CDB6CA95E2CA8C574AA6C4F3856602A0D32A9978697752878C0DCB50EF5463EE61C83F776AB9D8098755AF00D2972D3E5E502C39A9CE52C8588472C1D3242CA658290F472D48CB0876752643C2F63CFEB66DF6E93C8BE2404DFA10AB3D8EEF214C371DC0EC29755C086574B1AA92A892B517F6E01056DD5EFEB2437E23100E4A4C3B0B diff --git a/crypto/openssh/moduli.5 b/crypto/openssh/moduli.5 new file mode 100644 index 0000000..4a99439 --- /dev/null +++ b/crypto/openssh/moduli.5 @@ -0,0 +1,124 @@ +.\" $OpenBSD: moduli.5,v 1.12 2008/06/26 05:57:54 djm Exp $ +.\" +.\" Copyright (c) 2008 Damien Miller <djm@mindrot.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.Dd $Mdocdate: June 26 2008 $ +.Dt MODULI 5 +.Os +.Sh NAME +.Nm moduli +.Nd Diffie Hellman moduli +.Sh DESCRIPTION +The +.Pa /etc/moduli +file contains prime numbers and generators for use by +.Xr sshd 8 +in the Diffie-Hellman Group Exchange key exchange method. +.Pp +New moduli may be generated with +.Xr ssh-keygen 1 +using a two-step process. +An initial +.Em candidate generation +pass, using +.Ic ssh-keygen -G , +calculates numbers that are likely to be useful. +A second +.Em primality testing +pass, using +.Ic ssh-keygen -T +provides a high degree of assurance that the numbers are prime and are +safe for use in Diffie Hellman operations by +.Xr sshd 8 . +This +.Nm +format is used as the output from each pass. +.Pp +The file consists of newline-separated records, one per modulus, +containing seven space separated fields. +These fields are as follows: +.Pp +.Bl -tag -width Description -offset indent +.It timestamp +The time that the modulus was last processed as YYYYMMDDHHMMSS. +.It type +Decimal number specifying the internal structure of the prime modulus. +Supported types are: +.Pp +.Bl -tag -width 0x00 -compact +.It 0 +Unknown, not tested +.It 2 +"Safe" prime; (p-1)/2 is also prime. +.It 4 +Sophie Germain; (p+1)*2 is also prime. +.El +.Pp +Moduli candidates initially produced by +.Xr ssh-keygen 1 +are Sophie Germain primes (type 4). +Futher primality testing with +.Xr ssh-keygen 1 +produces safe prime moduli (type 2) that are ready for use in +.Xr sshd 8 . +Other types are not used by OpenSSH. +.It tests +Decimal number indicating the type of primality tests that the number +has been subjected to represented as a bitmask of the following values: +.Pp +.Bl -tag -width 0x00 -compact +.It 0x00 +Not tested +.It 0x01 +Composite number - not prime. +.It 0x02 +Sieve of Eratosthenes +.It 0x04 +Probabalistic Miller-Rabin primality tests. +.El +.Pp +The +.Xr ssh-keygen 1 +moduli candidate generation uses the Sieve of Eratosthenes (flag 0x02). +Subsequent +.Xr ssh-keygen 1 +primality tests are Miller-Rabin tests (flag 0x04). +.It trials +Decimal number indicating of primaility trials that have been performed +on the modulus. +.It size +Decimal number indicating the size of the prime in bits. +.It generator +The recommended generator for use with this modulus (hexadecimal). +.It modulus +The modulus itself in hexadecimal. +.El +.Pp +When performing Diffie Hellman Group Exchange, +.Xr sshd 8 +first estimates the size of the modulus required to produce enough +Diffie Hellman output to sufficiently key the selected symmetric cipher. +.Xr sshd 8 +then randomly selects a modulus from +.Fa /etc/moduli +that best meets the size requirement. +.Pp +.Sh SEE ALSO +.Xr ssh-keygen 1 , +.Xr sshd 8 , +.Rs +.%R RFC 4419 +.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol" +.%D 2006 +.Re diff --git a/crypto/openssh/moduli.c b/crypto/openssh/moduli.c index 44e5ddf..f737cb3 100644 --- a/crypto/openssh/moduli.c +++ b/crypto/openssh/moduli.c @@ -1,4 +1,4 @@ -/* $OpenBSD: moduli.c,v 1.19 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: moduli.c,v 1.21 2008/06/26 09:19:40 djm Exp $ */ /* * Copyright 1994 Phil Karn <karn@qualcomm.com> * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> @@ -42,6 +42,7 @@ #include <sys/types.h> #include <openssl/bn.h> +#include <openssl/dh.h> #include <stdio.h> #include <stdlib.h> @@ -50,6 +51,7 @@ #include <time.h> #include "xmalloc.h" +#include "dh.h" #include "log.h" /* @@ -59,27 +61,6 @@ /* need line long enough for largest moduli plus headers */ #define QLINESIZE (100+8192) -/* Type: decimal. - * Specifies the internal structure of the prime modulus. - */ -#define QTYPE_UNKNOWN (0) -#define QTYPE_UNSTRUCTURED (1) -#define QTYPE_SAFE (2) -#define QTYPE_SCHNORR (3) -#define QTYPE_SOPHIE_GERMAIN (4) -#define QTYPE_STRONG (5) - -/* Tests: decimal (bit field). - * Specifies the methods used in checking for primality. - * Usually, more than one test is used. - */ -#define QTEST_UNTESTED (0x00) -#define QTEST_COMPOSITE (0x01) -#define QTEST_SIEVE (0x02) -#define QTEST_MILLER_RABIN (0x04) -#define QTEST_JACOBI (0x08) -#define QTEST_ELLIPTIC (0x10) - /* * Size: decimal. * Specifies the number of the most significant bit (0 to M). @@ -434,8 +415,9 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start) fatal("BN_set_word failed"); if (BN_add(q, q, largebase) == 0) fatal("BN_add failed"); - if (qfileout(out, QTYPE_SOPHIE_GERMAIN, QTEST_SIEVE, - largetries, (power - 1) /* MSB */, (0), q) == -1) { + if (qfileout(out, MODULI_TYPE_SOPHIE_GERMAIN, + MODULI_TESTS_SIEVE, largetries, + (power - 1) /* MSB */, (0), q) == -1) { ret = -1; break; } @@ -490,11 +472,9 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) res = 0; lp = xmalloc(QLINESIZE + 1); - while (fgets(lp, QLINESIZE, in) != NULL) { - int ll = strlen(lp); - + while (fgets(lp, QLINESIZE + 1, in) != NULL) { count_in++; - if (ll < 14 || *lp == '!' || *lp == '#') { + if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { debug2("%10u: comment or short line", count_in); continue; } @@ -509,7 +489,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) /* tests */ in_tests = strtoul(cp, &cp, 10); - if (in_tests & QTEST_COMPOSITE) { + if (in_tests & MODULI_TESTS_COMPOSITE) { debug2("%10u: known composite", count_in); continue; } @@ -528,7 +508,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) /* modulus (hex) */ switch (in_type) { - case QTYPE_SOPHIE_GERMAIN: + case MODULI_TYPE_SOPHIE_GERMAIN: debug2("%10u: (%u) Sophie-Germain", count_in, in_type); a = q; if (BN_hex2bn(&a, cp) == 0) @@ -541,11 +521,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) in_size += 1; generator_known = 0; break; - case QTYPE_UNSTRUCTURED: - case QTYPE_SAFE: - case QTYPE_SCHNORR: - case QTYPE_STRONG: - case QTYPE_UNKNOWN: + case MODULI_TYPE_UNSTRUCTURED: + case MODULI_TYPE_SAFE: + case MODULI_TYPE_SCHNORR: + case MODULI_TYPE_STRONG: + case MODULI_TYPE_UNKNOWN: debug2("%10u: (%u)", count_in, in_type); a = p; if (BN_hex2bn(&a, cp) == 0) @@ -572,7 +552,7 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) continue; } - if (in_tests & QTEST_MILLER_RABIN) + if (in_tests & MODULI_TESTS_MILLER_RABIN) in_tries += trials; else in_tries = trials; @@ -646,7 +626,8 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted) } debug("%10u: q is almost certainly prime", count_in); - if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), + if (qfileout(out, MODULI_TYPE_SAFE, + in_tests | MODULI_TESTS_MILLER_RABIN, in_tries, in_size, generator_known, p)) { res = -1; break; diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c index 48ae46c..73cf6bc 100644 --- a/crypto/openssh/monitor.c +++ b/crypto/openssh/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.89 2006/11/07 10:31:31 markus Exp $ */ +/* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -51,6 +51,7 @@ #include <openssl/dh.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "key.h" @@ -409,6 +410,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; @@ -644,6 +646,9 @@ mm_answer_pwnamallow(int sock, Buffer *m) buffer_put_cstring(m, pwent->pw_shell); out: + buffer_put_string(m, &options, sizeof(options)); + if (options.banner != NULL) + buffer_put_cstring(m, options.banner); debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); mm_request_send(sock, MONITOR_ANS_PWNAM, m); @@ -1010,6 +1015,8 @@ mm_answer_keyallowed(int sock, Buffer *m) allowed = options.pubkey_authentication && user_key_allowed(authctxt->pw, key); auth_method = "publickey"; + if (options.pubkey_authentication && allowed != 1) + auth_clear_options(); break; case MM_HOSTKEY: allowed = options.hostbased_authentication && @@ -1022,6 +1029,8 @@ mm_answer_keyallowed(int sock, Buffer *m) allowed = options.rhosts_rsa_authentication && auth_rhosts_rsa_key_allowed(authctxt->pw, cuser, chost, key); + if (options.rhosts_rsa_authentication && allowed != 1) + auth_clear_options(); auth_method = "rsa"; break; default: @@ -1051,7 +1060,7 @@ mm_answer_keyallowed(int sock, Buffer *m) } debug3("%s: key %p is %s", - __func__, key, allowed ? "allowed" : "disallowed"); + __func__, key, allowed ? "allowed" : "not allowed"); buffer_clear(m); buffer_put_int(m, allowed); @@ -1268,7 +1277,7 @@ mm_session_close(Session *s) debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); session_pty_cleanup2(s); } - s->used = 0; + session_unused(s->self); } int @@ -1310,8 +1319,9 @@ mm_answer_pty(int sock, Buffer *m) mm_request_send(sock, MONITOR_ANS_PTY, m); - mm_send_fd(sock, s->ptyfd); - mm_send_fd(sock, s->ttyfd); + if (mm_send_fd(sock, s->ptyfd) == -1 || + mm_send_fd(sock, s->ttyfd) == -1) + fatal("%s: send fds failed", __func__); /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) @@ -1542,6 +1552,11 @@ mm_answer_term(int sock, Buffer *req) /* The child is terminating */ session_destroy_all(&mm_session_close); +#ifdef USE_PAM + if (options.use_pam) + sshpam_cleanup(); +#endif + while (waitpid(pmonitor->m_pid, &status, 0) == -1) if (errno != EINTR) exit(1); @@ -1690,7 +1705,7 @@ mm_get_keystate(struct monitor *pmonitor) u_char *blob, *p; u_int bloblen, plen; u_int32_t seqnr, packets; - u_int64_t blocks; + u_int64_t blocks, bytes; debug3("%s: Waiting for new keys", __func__); @@ -1723,11 +1738,13 @@ mm_get_keystate(struct monitor *pmonitor) seqnr = buffer_get_int(&m); blocks = buffer_get_int64(&m); packets = buffer_get_int(&m); - packet_set_state(MODE_OUT, seqnr, blocks, packets); + bytes = buffer_get_int64(&m); + packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes); seqnr = buffer_get_int(&m); blocks = buffer_get_int64(&m); packets = buffer_get_int(&m); - packet_set_state(MODE_IN, seqnr, blocks, packets); + bytes = buffer_get_int64(&m); + packet_set_state(MODE_IN, seqnr, blocks, packets, bytes); skip: /* Get the key context */ diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c index 6eb55c6..cab538b 100644 --- a/crypto/openssh/monitor_fdpass.c +++ b/crypto/openssh/monitor_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.17 2008/03/24 16:11:07 deraadt Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -40,7 +40,7 @@ #include "log.h" #include "monitor_fdpass.h" -void +int mm_send_fd(int sock, int fd) { #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) @@ -51,6 +51,7 @@ mm_send_fd(int sock, int fd) #ifndef HAVE_ACCRIGHTS_IN_MSGHDR union { struct cmsghdr hdr; + char tmp[CMSG_SPACE(sizeof(int))]; char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct cmsghdr *cmsg; @@ -75,15 +76,21 @@ mm_send_fd(int sock, int fd) msg.msg_iov = &vec; msg.msg_iovlen = 1; - if ((n = sendmsg(sock, &msg, 0)) == -1) - fatal("%s: sendmsg(%d): %s", __func__, fd, + if ((n = sendmsg(sock, &msg, 0)) == -1) { + error("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); - if (n != 1) - fatal("%s: sendmsg: expected sent 1 got %ld", + return -1; + } + + if (n != 1) { + error("%s: sendmsg: expected sent 1 got %ld", __func__, (long)n); + return -1; + } + return 0; #else - fatal("%s: UsePrivilegeSeparation=yes not supported", - __func__); + error("%s: file descriptor passing not supported", __func__); + return -1; #endif } @@ -117,29 +124,39 @@ mm_receive_fd(int sock) msg.msg_controllen = sizeof(cmsgbuf.buf); #endif - if ((n = recvmsg(sock, &msg, 0)) == -1) - fatal("%s: recvmsg: %s", __func__, strerror(errno)); - if (n != 1) - fatal("%s: recvmsg: expected received 1 got %ld", + if ((n = recvmsg(sock, &msg, 0)) == -1) { + error("%s: recvmsg: %s", __func__, strerror(errno)); + return -1; + } + if (n != 1) { + error("%s: recvmsg: expected received 1 got %ld", __func__, (long)n); + return -1; + } #ifdef HAVE_ACCRIGHTS_IN_MSGHDR - if (msg.msg_accrightslen != sizeof(fd)) - fatal("%s: no fd", __func__); + if (msg.msg_accrightslen != sizeof(fd)) { + error("%s: no fd", __func__); + return -1; + } #else cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg == NULL) - fatal("%s: no message header", __func__); + if (cmsg == NULL) { + error("%s: no message header", __func__); + return -1; + } #ifndef BROKEN_CMSG_TYPE - if (cmsg->cmsg_type != SCM_RIGHTS) - fatal("%s: expected type %d got %d", __func__, + if (cmsg->cmsg_type != SCM_RIGHTS) { + error("%s: expected type %d got %d", __func__, SCM_RIGHTS, cmsg->cmsg_type); + return -1; + } #endif fd = (*(int *)CMSG_DATA(cmsg)); #endif return fd; #else - fatal("%s: UsePrivilegeSeparation=yes not supported", - __func__); + error("%s: file descriptor passing not supported", __func__); + return -1; #endif } diff --git a/crypto/openssh/monitor_fdpass.h b/crypto/openssh/monitor_fdpass.h index 12c67ec..a4b1f63 100644 --- a/crypto/openssh/monitor_fdpass.h +++ b/crypto/openssh/monitor_fdpass.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.h,v 1.3 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> @@ -28,7 +28,7 @@ #ifndef _MM_FDPASS_H_ #define _MM_FDPASS_H_ -void mm_send_fd(int, int); +int mm_send_fd(int, int); int mm_receive_fd(int); #endif /* _MM_FDPASS_H_ */ diff --git a/crypto/openssh/monitor_mm.h b/crypto/openssh/monitor_mm.h index 36a07a0..c890f77 100644 --- a/crypto/openssh/monitor_mm.h +++ b/crypto/openssh/monitor_mm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_mm.h,v 1.4 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: monitor_mm.h,v 1.5 2008/04/29 11:20:31 otto Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> @@ -41,9 +41,6 @@ struct mm_master { size_t size; struct mm_master *mmalloc; /* Used to completely share */ - - int write; /* used to writing to other party */ - int read; /* used for reading from other party */ }; RB_PROTOTYPE(mmtree, mm_share, next, mm_compare) diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c index 3865539..40463d0 100644 --- a/crypto/openssh/monitor_wrap.c +++ b/crypto/openssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.54 2006/08/12 20:46:46 miod Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -41,6 +41,7 @@ #include <openssl/bn.h> #include <openssl/dh.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "dh.h" @@ -73,6 +74,7 @@ #include "channels.h" #include "session.h" +#include "servconf.h" /* Imports */ extern int compat20; @@ -207,7 +209,8 @@ mm_getpwnamallow(const char *username) { Buffer m; struct passwd *pw; - u_int pwlen; + u_int len; + ServerOptions *newopts; debug3("%s entering", __func__); @@ -220,11 +223,11 @@ mm_getpwnamallow(const char *username) mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); if (buffer_get_char(&m) == 0) { - buffer_free(&m); - return (NULL); + pw = NULL; + goto out; } - pw = buffer_get_string(&m, &pwlen); - if (pwlen != sizeof(struct passwd)) + pw = buffer_get_string(&m, &len); + if (len != sizeof(struct passwd)) fatal("%s: struct passwd size mismatch", __func__); pw->pw_name = buffer_get_string(&m, NULL); pw->pw_passwd = buffer_get_string(&m, NULL); @@ -234,6 +237,17 @@ mm_getpwnamallow(const char *username) #endif pw->pw_dir = buffer_get_string(&m, NULL); pw->pw_shell = buffer_get_string(&m, NULL); + +out: + /* copy options block as a Match directive may have changed some */ + newopts = buffer_get_string(&m, &len); + if (len != sizeof(*newopts)) + fatal("%s: option block size mismatch", __func__); + if (newopts->banner != NULL) + newopts->banner = buffer_get_string(&m, NULL); + copy_set_server_options(&options, newopts, 1); + xfree(newopts); + buffer_free(&m); return (pw); @@ -464,8 +478,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) @@ -559,7 +573,7 @@ mm_send_keystate(struct monitor *monitor) u_char *blob, *p; u_int bloblen, plen; u_int32_t seqnr, packets; - u_int64_t blocks; + u_int64_t blocks, bytes; buffer_init(&m); @@ -608,14 +622,16 @@ mm_send_keystate(struct monitor *monitor) buffer_put_string(&m, blob, bloblen); xfree(blob); - packet_get_state(MODE_OUT, &seqnr, &blocks, &packets); + packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); buffer_put_int(&m, seqnr); buffer_put_int64(&m, blocks); buffer_put_int(&m, packets); - packet_get_state(MODE_IN, &seqnr, &blocks, &packets); + buffer_put_int64(&m, bytes); + packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes); buffer_put_int(&m, seqnr); buffer_put_int64(&m, blocks); buffer_put_int(&m, packets); + buffer_put_int64(&m, bytes); debug3("%s: New keys have been sent", __func__); skip: @@ -652,7 +668,20 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) { Buffer m; char *p, *msg; - int success = 0; + int success = 0, tmp1 = -1, tmp2 = -1; + + /* Kludge: ensure there are fds free to receive the pty/tty */ + if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || + (tmp2 = dup(pmonitor->m_recvfd)) == -1) { + error("%s: cannot allocate fds for pty", __func__); + if (tmp1 > 0) + close(tmp1); + if (tmp2 > 0) + close(tmp2); + return 0; + } + close(tmp1); + close(tmp2); buffer_init(&m); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); @@ -676,8 +705,9 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) buffer_append(&loginmsg, msg, strlen(msg)); xfree(msg); - *ptyfd = mm_receive_fd(pmonitor->m_recvfd); - *ttyfd = mm_receive_fd(pmonitor->m_recvfd); + if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || + (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) + fatal("%s: receive fds failed", __func__); /* Success */ return (1); @@ -696,8 +726,9 @@ mm_session_pty_cleanup2(Session *s) buffer_free(&m); /* closed dup'ed master */ - if (close(s->ptymaster) < 0) - error("close(s->ptymaster): %s", strerror(errno)); + if (s->ptymaster != -1 && close(s->ptymaster) < 0) + error("close(s->ptymaster/%d): %s", + s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; diff --git a/crypto/openssh/mux.c b/crypto/openssh/mux.c new file mode 100644 index 0000000..79f8376 --- /dev/null +++ b/crypto/openssh/mux.c @@ -0,0 +1,728 @@ +/* $OpenBSD: mux.c,v 1.7 2008/06/13 17:21:20 dtucker Exp $ */ +/* + * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ssh session multiplexing support */ + +#include "includes.h" + +/* + * TODO: + * 1. partial reads in muxserver_accept_control (maybe make channels + * from accepted connections) + * 2. Better signalling from master to slave, especially passing of + * error messages + * 3. Better fall-back from mux slave error to new connection. + * 3. Add/delete forwardings via slave + * 4. ExitOnForwardingFailure (after #3 obviously) + * 5. Maybe extension mechanisms for multi-X11/multi-agent forwarding + * 6. Document the mux mini-protocol somewhere. + * 7. Support ~^Z in mux slaves. + * 8. Inspect or control sessions in master. + * 9. If we ever support the "signal" channel request, send signals on + * sessions in master. + */ + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif + +#ifdef HAVE_UTIL_H +# include <util.h> +#endif + +#ifdef HAVE_LIBUTIL_H +# include <libutil.h> +#endif + +#include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" +#include "log.h" +#include "ssh.h" +#include "pathnames.h" +#include "misc.h" +#include "match.h" +#include "buffer.h" +#include "channels.h" +#include "msg.h" +#include "packet.h" +#include "monitor_fdpass.h" +#include "sshpty.h" +#include "key.h" +#include "readconf.h" +#include "clientloop.h" + +/* from ssh.c */ +extern int tty_flag; +extern Options options; +extern int stdin_null_flag; +extern char *host; +int subsystem_flag; +extern Buffer command; + +/* Context for session open confirmation callback */ +struct mux_session_confirm_ctx { + int want_tty; + int want_subsys; + int want_x_fwd; + int want_agent_fwd; + Buffer cmd; + char *term; + struct termios tio; + char **env; +}; + +/* fd to control socket */ +int muxserver_sock = -1; + +/* Multiplexing control command */ +u_int muxclient_command = 0; + +/* Set when signalled. */ +static volatile sig_atomic_t muxclient_terminate = 0; + +/* PID of multiplex server */ +static u_int muxserver_pid = 0; + + +/* ** Multiplexing master support */ + +/* Prepare a mux master to listen on a Unix domain socket. */ +void +muxserver_listen(void) +{ + struct sockaddr_un addr; + mode_t old_umask; + int addr_len; + + if (options.control_path == NULL || + options.control_master == SSHCTL_MASTER_NO) + return; + + debug("setting up multiplex master socket"); + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + addr_len = offsetof(struct sockaddr_un, sun_path) + + strlen(options.control_path) + 1; + + if (strlcpy(addr.sun_path, options.control_path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((muxserver_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s", __func__, strerror(errno)); + + old_umask = umask(0177); + if (bind(muxserver_sock, (struct sockaddr *)&addr, addr_len) == -1) { + muxserver_sock = -1; + if (errno == EINVAL || errno == EADDRINUSE) { + error("ControlSocket %s already exists, " + "disabling multiplexing", options.control_path); + close(muxserver_sock); + muxserver_sock = -1; + xfree(options.control_path); + options.control_path = NULL; + options.control_master = SSHCTL_MASTER_NO; + return; + } else + fatal("%s bind(): %s", __func__, strerror(errno)); + } + umask(old_umask); + + if (listen(muxserver_sock, 64) == -1) + fatal("%s listen(): %s", __func__, strerror(errno)); + + set_nonblock(muxserver_sock); +} + +/* Callback on open confirmation in mux master for a mux client session. */ +static void +mux_session_confirm(int id, void *arg) +{ + struct mux_session_confirm_ctx *cctx = arg; + const char *display; + Channel *c; + int i; + + if (cctx == NULL) + fatal("%s: cctx == NULL", __func__); + if ((c = channel_lookup(id)) == NULL) + fatal("%s: no channel for id %d", __func__, id); + + display = getenv("DISPLAY"); + if (cctx->want_x_fwd && options.forward_x11 && display != NULL) { + char *proto, *data; + /* Get reasonable local authentication information. */ + client_x11_get_proto(display, options.xauth_location, + options.forward_x11_trusted, &proto, &data); + /* Request forwarding with authentication spoofing. */ + debug("Requesting X11 forwarding with authentication spoofing."); + x11_request_forwarding_with_spoofing(id, display, proto, data); + /* XXX wait for reply */ + } + + if (cctx->want_agent_fwd && options.forward_agent) { + debug("Requesting authentication agent forwarding."); + channel_request_start(id, "auth-agent-req@openssh.com", 0); + packet_send(); + } + + client_session2_setup(id, cctx->want_tty, cctx->want_subsys, + cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env); + + c->open_confirm_ctx = NULL; + buffer_free(&cctx->cmd); + xfree(cctx->term); + if (cctx->env != NULL) { + for (i = 0; cctx->env[i] != NULL; i++) + xfree(cctx->env[i]); + xfree(cctx->env); + } + xfree(cctx); +} + +/* + * Accept a connection on the mux master socket and process the + * client's request. Returns flag indicating whether mux master should + * begin graceful close. + */ +int +muxserver_accept_control(void) +{ + Buffer m; + Channel *c; + int client_fd, new_fd[3], ver, allowed, window, packetmax; + socklen_t addrlen; + struct sockaddr_storage addr; + struct mux_session_confirm_ctx *cctx; + char *cmd; + u_int i, j, len, env_len, mux_command, flags, escape_char; + uid_t euid; + gid_t egid; + int start_close = 0; + + /* + * Accept connection on control socket + */ + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + if ((client_fd = accept(muxserver_sock, + (struct sockaddr*)&addr, &addrlen)) == -1) { + error("%s accept: %s", __func__, strerror(errno)); + return 0; + } + + if (getpeereid(client_fd, &euid, &egid) < 0) { + error("%s getpeereid failed: %s", __func__, strerror(errno)); + close(client_fd); + return 0; + } + if ((euid != 0) && (getuid() != euid)) { + error("control mode uid mismatch: peer euid %u != uid %u", + (u_int) euid, (u_int) getuid()); + close(client_fd); + return 0; + } + + /* XXX handle asynchronously */ + unset_nonblock(client_fd); + + /* Read command */ + buffer_init(&m); + if (ssh_msg_recv(client_fd, &m) == -1) { + error("%s: client msg_recv failed", __func__); + close(client_fd); + buffer_free(&m); + return 0; + } + if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { + error("%s: wrong client version %d", __func__, ver); + buffer_free(&m); + close(client_fd); + return 0; + } + + allowed = 1; + mux_command = buffer_get_int(&m); + flags = buffer_get_int(&m); + + buffer_clear(&m); + + switch (mux_command) { + case SSHMUX_COMMAND_OPEN: + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) + allowed = ask_permission("Allow shared connection " + "to %s? ", host); + /* continue below */ + break; + case SSHMUX_COMMAND_TERMINATE: + if (options.control_master == SSHCTL_MASTER_ASK || + options.control_master == SSHCTL_MASTER_AUTO_ASK) + allowed = ask_permission("Terminate shared connection " + "to %s? ", host); + if (allowed) + start_close = 1; + /* FALLTHROUGH */ + case SSHMUX_COMMAND_ALIVE_CHECK: + /* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */ + buffer_clear(&m); + buffer_put_int(&m, allowed); + buffer_put_int(&m, getpid()); + if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + buffer_free(&m); + return start_close; + } + buffer_free(&m); + close(client_fd); + return start_close; + default: + error("Unsupported command %d", mux_command); + buffer_free(&m); + close(client_fd); + return 0; + } + + /* Reply for SSHMUX_COMMAND_OPEN */ + buffer_clear(&m); + buffer_put_int(&m, allowed); + buffer_put_int(&m, getpid()); + if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + buffer_free(&m); + return 0; + } + + if (!allowed) { + error("Refused control connection"); + close(client_fd); + buffer_free(&m); + return 0; + } + + buffer_clear(&m); + if (ssh_msg_recv(client_fd, &m) == -1) { + error("%s: client msg_recv failed", __func__); + close(client_fd); + buffer_free(&m); + return 0; + } + if ((ver = buffer_get_char(&m)) != SSHMUX_VER) { + error("%s: wrong client version %d", __func__, ver); + buffer_free(&m); + close(client_fd); + return 0; + } + + cctx = xcalloc(1, sizeof(*cctx)); + cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0; + cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0; + cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0; + cctx->want_agent_fwd = (flags & SSHMUX_FLAG_AGENT_FWD) != 0; + cctx->term = buffer_get_string(&m, &len); + escape_char = buffer_get_int(&m); + + cmd = buffer_get_string(&m, &len); + buffer_init(&cctx->cmd); + buffer_append(&cctx->cmd, cmd, strlen(cmd)); + + env_len = buffer_get_int(&m); + env_len = MIN(env_len, 4096); + debug3("%s: receiving %d env vars", __func__, env_len); + if (env_len != 0) { + cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env)); + for (i = 0; i < env_len; i++) + cctx->env[i] = buffer_get_string(&m, &len); + cctx->env[i] = NULL; + } + + debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__, + cctx->want_tty, cctx->want_subsys, cmd); + xfree(cmd); + + /* Gather fds from client */ + for(i = 0; i < 3; i++) { + if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) { + error("%s: failed to receive fd %d from slave", + __func__, i); + for (j = 0; j < i; j++) + close(new_fd[j]); + for (j = 0; j < env_len; j++) + xfree(cctx->env[j]); + if (env_len > 0) + xfree(cctx->env); + xfree(cctx->term); + buffer_free(&cctx->cmd); + close(client_fd); + xfree(cctx); + return 0; + } + } + + debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, + new_fd[0], new_fd[1], new_fd[2]); + + /* Try to pick up ttymodes from client before it goes raw */ + if (cctx->want_tty && tcgetattr(new_fd[0], &cctx->tio) == -1) + error("%s: tcgetattr: %s", __func__, strerror(errno)); + + /* This roundtrip is just for synchronisation of ttymodes */ + buffer_clear(&m); + if (ssh_msg_send(client_fd, SSHMUX_VER, &m) == -1) { + error("%s: client msg_send failed", __func__); + close(client_fd); + close(new_fd[0]); + close(new_fd[1]); + close(new_fd[2]); + buffer_free(&m); + xfree(cctx->term); + if (env_len != 0) { + for (i = 0; i < env_len; i++) + xfree(cctx->env[i]); + xfree(cctx->env); + } + return 0; + } + buffer_free(&m); + + /* enable nonblocking unless tty */ + if (!isatty(new_fd[0])) + set_nonblock(new_fd[0]); + if (!isatty(new_fd[1])) + set_nonblock(new_fd[1]); + if (!isatty(new_fd[2])) + set_nonblock(new_fd[2]); + + set_nonblock(client_fd); + + window = CHAN_SES_WINDOW_DEFAULT; + packetmax = CHAN_SES_PACKET_DEFAULT; + if (cctx->want_tty) { + window >>= 1; + packetmax >>= 1; + } + + c = channel_new("session", SSH_CHANNEL_OPENING, + new_fd[0], new_fd[1], new_fd[2], window, packetmax, + CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0); + + c->ctl_fd = client_fd; + if (cctx->want_tty && escape_char != 0xffffffff) { + channel_register_filter(c->self, + client_simple_escape_filter, NULL, + client_filter_cleanup, + client_new_escape_filter_ctx((int)escape_char)); + } + + debug3("%s: channel_new: %d", __func__, c->self); + + channel_send_open(c->self); + channel_register_open_confirm(c->self, mux_session_confirm, cctx); + return 0; +} + +/* ** Multiplexing client support */ + +/* Exit signal handler */ +static void +control_client_sighandler(int signo) +{ + muxclient_terminate = signo; +} + +/* + * Relay signal handler - used to pass some signals from mux client to + * mux master. + */ +static void +control_client_sigrelay(int signo) +{ + int save_errno = errno; + + if (muxserver_pid > 1) + kill(muxserver_pid, signo); + + errno = save_errno; +} + +/* Check mux client environment variables before passing them to mux master. */ +static int +env_permitted(char *env) +{ + int i, ret; + char name[1024], *cp; + + if ((cp = strchr(env, '=')) == NULL || cp == env) + return (0); + ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env); + if (ret <= 0 || (size_t)ret >= sizeof(name)) + fatal("env_permitted: name '%.100s...' too long", env); + + for (i = 0; i < options.num_send_env; i++) + if (match_pattern(name, options.send_env[i])) + return (1); + + return (0); +} + +/* Multiplex client main loop. */ +void +muxclient(const char *path) +{ + struct sockaddr_un addr; + int i, r, fd, sock, exitval[2], num_env, addr_len; + Buffer m; + char *term; + extern char **environ; + u_int allowed, flags; + + if (muxclient_command == 0) + muxclient_command = SSHMUX_COMMAND_OPEN; + + switch (options.control_master) { + case SSHCTL_MASTER_AUTO: + case SSHCTL_MASTER_AUTO_ASK: + debug("auto-mux: Trying existing master"); + /* FALLTHROUGH */ + case SSHCTL_MASTER_NO: + break; + default: + return; + } + + memset(&addr, '\0', sizeof(addr)); + addr.sun_family = AF_UNIX; + addr_len = offsetof(struct sockaddr_un, sun_path) + + strlen(path) + 1; + + if (strlcpy(addr.sun_path, path, + sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) + fatal("ControlPath too long"); + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) + fatal("%s socket(): %s", __func__, strerror(errno)); + + if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) { + if (muxclient_command != SSHMUX_COMMAND_OPEN) { + fatal("Control socket connect(%.100s): %s", path, + strerror(errno)); + } + if (errno == ENOENT) + debug("Control socket \"%.100s\" does not exist", path); + else { + error("Control socket connect(%.100s): %s", path, + strerror(errno)); + } + close(sock); + return; + } + + if (stdin_null_flag) { + if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) + fatal("open(/dev/null): %s", strerror(errno)); + if (dup2(fd, STDIN_FILENO) == -1) + fatal("dup2: %s", strerror(errno)); + if (fd > STDERR_FILENO) + close(fd); + } + + term = getenv("TERM"); + + flags = 0; + if (tty_flag) + flags |= SSHMUX_FLAG_TTY; + if (subsystem_flag) + flags |= SSHMUX_FLAG_SUBSYS; + if (options.forward_x11) + flags |= SSHMUX_FLAG_X11_FWD; + if (options.forward_agent) + flags |= SSHMUX_FLAG_AGENT_FWD; + + signal(SIGPIPE, SIG_IGN); + + buffer_init(&m); + + /* Send our command to server */ + buffer_put_int(&m, muxclient_command); + buffer_put_int(&m, flags); + if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { + error("%s: msg_send", __func__); + muxerr: + close(sock); + buffer_free(&m); + if (muxclient_command != SSHMUX_COMMAND_OPEN) + cleanup_exit(255); + logit("Falling back to non-multiplexed connection"); + xfree(options.control_path); + options.control_path = NULL; + options.control_master = SSHCTL_MASTER_NO; + return; + } + buffer_clear(&m); + + /* Get authorisation status and PID of controlee */ + if (ssh_msg_recv(sock, &m) == -1) { + error("%s: Did not receive reply from master", __func__); + goto muxerr; + } + if (buffer_get_char(&m) != SSHMUX_VER) { + error("%s: Master replied with wrong version", __func__); + goto muxerr; + } + if (buffer_get_int_ret(&allowed, &m) != 0) { + error("%s: bad server reply", __func__); + goto muxerr; + } + if (allowed != 1) { + error("Connection to master denied"); + goto muxerr; + } + muxserver_pid = buffer_get_int(&m); + + buffer_clear(&m); + + switch (muxclient_command) { + case SSHMUX_COMMAND_ALIVE_CHECK: + fprintf(stderr, "Master running (pid=%d)\r\n", + muxserver_pid); + exit(0); + case SSHMUX_COMMAND_TERMINATE: + fprintf(stderr, "Exit request sent.\r\n"); + exit(0); + case SSHMUX_COMMAND_OPEN: + buffer_put_cstring(&m, term ? term : ""); + if (options.escape_char == SSH_ESCAPECHAR_NONE) + buffer_put_int(&m, 0xffffffff); + else + buffer_put_int(&m, options.escape_char); + buffer_append(&command, "\0", 1); + buffer_put_cstring(&m, buffer_ptr(&command)); + + if (options.num_send_env == 0 || environ == NULL) { + buffer_put_int(&m, 0); + } else { + /* Pass environment */ + num_env = 0; + for (i = 0; environ[i] != NULL; i++) { + if (env_permitted(environ[i])) + num_env++; /* Count */ + } + buffer_put_int(&m, num_env); + for (i = 0; environ[i] != NULL && num_env >= 0; i++) { + if (env_permitted(environ[i])) { + num_env--; + buffer_put_cstring(&m, environ[i]); + } + } + } + break; + default: + fatal("unrecognised muxclient_command %d", muxclient_command); + } + + if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) { + error("%s: msg_send", __func__); + goto muxerr; + } + + if (mm_send_fd(sock, STDIN_FILENO) == -1 || + mm_send_fd(sock, STDOUT_FILENO) == -1 || + mm_send_fd(sock, STDERR_FILENO) == -1) { + error("%s: send fds failed", __func__); + goto muxerr; + } + + /* + * Mux errors are non-recoverable from this point as the master + * has ownership of the session now. + */ + + /* Wait for reply, so master has a chance to gather ttymodes */ + buffer_clear(&m); + if (ssh_msg_recv(sock, &m) == -1) + fatal("%s: msg_recv", __func__); + if (buffer_get_char(&m) != SSHMUX_VER) + fatal("%s: wrong version", __func__); + buffer_free(&m); + + signal(SIGHUP, control_client_sighandler); + signal(SIGINT, control_client_sighandler); + signal(SIGTERM, control_client_sighandler); + signal(SIGWINCH, control_client_sigrelay); + + if (tty_flag) + enter_raw_mode(); + + /* + * 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; !muxclient_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 == -1) { + if (errno == EINTR) + continue; + fatal("%s: read %s", __func__, strerror(errno)); + } + i += r; + } + + close(sock); + leave_raw_mode(); + if (i > (int)sizeof(int)) + fatal("%s: master returned too much data (%d > %lu)", + __func__, i, (u_long)sizeof(int)); + if (muxclient_terminate) { + debug2("Exiting on signal %d", muxclient_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, "Shared connection to %s closed.\r\n", host); + + exit(exitval[0]); +} diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h index 707af00..87a9e58 100644 --- a/crypto/openssh/myproposal.h +++ b/crypto/openssh/myproposal.h @@ -1,5 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.21 2006/03/25 22:22:43 djm Exp $ */ -/* $FreeBSD$ */ +/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -41,14 +40,14 @@ "diffie-hellman-group1-sha1" #endif -#define KEX_DEFAULT_PK_ALG "ssh-dss,ssh-rsa" +#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" #define KEX_DEFAULT_ENCRYPT \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ "arcfour128,arcfour256,arcfour," \ "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/crypto/openssh/nchan.c b/crypto/openssh/nchan.c index ad461f4..e0ebf43 100644 --- a/crypto/openssh/nchan.c +++ b/crypto/openssh/nchan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nchan.c,v 1.57 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: nchan.c,v 1.60 2008/06/30 12:16:02 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -32,6 +32,7 @@ #include <string.h> #include <stdarg.h> +#include "openbsd-compat/sys-queue.h" #include "ssh1.h" #include "ssh2.h" #include "buffer.h" @@ -77,6 +78,7 @@ static void chan_send_ieof1(Channel *); static void chan_send_oclose1(Channel *); static void chan_send_close2(Channel *); static void chan_send_eof2(Channel *); +static void chan_send_eow2(Channel *); /* helper */ static void chan_shutdown_write(Channel *); @@ -305,6 +307,17 @@ chan_rcvd_close2(Channel *c) break; } } +void +chan_rcvd_eow(Channel *c) +{ + debug2("channel %d: rcvd eow", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + chan_shutdown_read(c); + chan_set_istate(c, CHAN_INPUT_CLOSED); + break; + } +} static void chan_rcvd_eof2(Channel *c) { @@ -321,6 +334,8 @@ chan_write_failed2(Channel *c) case CHAN_OUTPUT_OPEN: case CHAN_OUTPUT_WAIT_DRAIN: chan_shutdown_write(c); + if (strcmp(c->ctype, "session") == 0) + chan_send_eow2(c); chan_set_ostate(c, CHAN_OUTPUT_CLOSED); break; default: @@ -363,6 +378,21 @@ chan_send_close2(Channel *c) c->flags |= CHAN_CLOSE_SENT; } } +static void +chan_send_eow2(Channel *c) +{ + debug2("channel %d: send eow", c->self); + if (c->ostate == CHAN_OUTPUT_CLOSED) { + error("channel %d: must not sent eow on closed output", + c->self); + return; + } + packet_start(SSH2_MSG_CHANNEL_REQUEST); + packet_put_int(c->remote_id); + packet_put_cstring("eow@openssh.com"); + packet_put_char(0); + packet_send(); +} /* shared */ diff --git a/crypto/openssh/openbsd-compat/base64.c b/crypto/openssh/openbsd-compat/base64.c index 9a60f58..9e74667 100644 --- a/crypto/openssh/openbsd-compat/base64.c +++ b/crypto/openssh/openbsd-compat/base64.c @@ -1,4 +1,4 @@ -/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */ +/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */ /* * Copyright (c) 1996 by Internet Software Consortium. @@ -62,9 +62,6 @@ #include "base64.h" -/* XXX abort illegal in library */ -#define Assert(Cond) if (!(Cond)) abort() - static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; @@ -151,10 +148,6 @@ b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; - Assert(output[0] < 64); - Assert(output[1] < 64); - Assert(output[2] < 64); - Assert(output[3] < 64); if (datalength + 4 > targsize) return (-1); @@ -174,9 +167,6 @@ b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); - Assert(output[0] < 64); - Assert(output[1] < 64); - Assert(output[2] < 64); if (datalength + 4 > targsize) return (-1); diff --git a/crypto/openssh/openbsd-compat/bindresvport.c b/crypto/openssh/openbsd-compat/bindresvport.c index 65afed1..c0d5bdb 100644 --- a/crypto/openssh/openbsd-compat/bindresvport.c +++ b/crypto/openssh/openbsd-compat/bindresvport.c @@ -1,6 +1,6 @@ /* This file has be substantially modified from the original OpenBSD source */ -/* $OpenBSD: bindresvport.c,v 1.16 2005/04/01 07:44:03 otto Exp $ */ +/* $OpenBSD: bindresvport.c,v 1.17 2005/12/21 01:40:22 millert Exp $ */ /* * Copyright 1996, Jason Downs. All rights reserved. @@ -54,8 +54,8 @@ bindresvport_sa(int sd, struct sockaddr *sa) { int error, af; struct sockaddr_storage myaddr; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; + struct sockaddr_in *in; + struct sockaddr_in6 *in6; u_int16_t *portp; u_int16_t port; socklen_t salen; @@ -74,13 +74,13 @@ bindresvport_sa(int sd, struct sockaddr *sa) af = sa->sa_family; if (af == AF_INET) { - sin = (struct sockaddr_in *)sa; + in = (struct sockaddr_in *)sa; salen = sizeof(struct sockaddr_in); - portp = &sin->sin_port; + portp = &in->sin_port; } else if (af == AF_INET6) { - sin6 = (struct sockaddr_in6 *)sa; + in6 = (struct sockaddr_in6 *)sa; salen = sizeof(struct sockaddr_in6); - portp = &sin6->sin6_port; + portp = &in6->sin6_port; } else { errno = EPFNOSUPPORT; return (-1); diff --git a/crypto/openssh/openbsd-compat/bsd-arc4random.c b/crypto/openssh/openbsd-compat/bsd-arc4random.c index d45fb18..9d4c869 100644 --- a/crypto/openssh/openbsd-compat/bsd-arc4random.c +++ b/crypto/openssh/openbsd-compat/bsd-arc4random.c @@ -19,6 +19,7 @@ #include <sys/types.h> #include <string.h> +#include <stdlib.h> #include <stdarg.h> #include "log.h" @@ -82,3 +83,68 @@ arc4random_stir(void) rc4_ready = REKEY_BYTES; } #endif /* !HAVE_ARC4RANDOM */ + +#ifndef ARC4RANDOM_BUF +void +arc4random_buf(void *_buf, size_t n) +{ + size_t i; + u_int32_t r = 0; + char *buf = (char *)_buf; + + for (i = 0; i < n; i++) { + if (i % 4 == 0) + r = arc4random(); + buf[i] = r & 0xff; + r >>= 8; + } + i = r = 0; +} +#endif /* !HAVE_ARC4RANDOM_BUF */ + +#ifndef ARC4RANDOM_UNIFORM +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +u_int32_t +arc4random_uniform(u_int32_t upper_bound) +{ + u_int32_t r, min; + + if (upper_bound < 2) + return 0; + +#if (ULONG_MAX > 0xffffffffUL) + min = 0x100000000UL % upper_bound; +#else + /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ + if (upper_bound > 0x80000000) + min = 1 + ~upper_bound; /* 2**32 - upper_bound */ + else { + /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ + min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; + } +#endif + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return r % upper_bound; +} +#endif /* !HAVE_ARC4RANDOM_UNIFORM */ diff --git a/crypto/openssh/openbsd-compat/bsd-asprintf.c b/crypto/openssh/openbsd-compat/bsd-asprintf.c index 6748013..3368195 100644 --- a/crypto/openssh/openbsd-compat/bsd-asprintf.c +++ b/crypto/openssh/openbsd-compat/bsd-asprintf.c @@ -39,7 +39,8 @@ #define INIT_SZ 128 -int vasprintf(char **str, const char *fmt, va_list ap) +int +vasprintf(char **str, const char *fmt, va_list ap) { int ret = -1; va_list ap2; @@ -53,7 +54,8 @@ int vasprintf(char **str, const char *fmt, va_list ap) ret = vsnprintf(string, INIT_SZ, fmt, ap2); if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ *str = string; - } else if (ret == INT_MAX) { /* shouldn't happen */ + } else if (ret == INT_MAX || ret < 0) { /* Bad length */ + free(string); goto fail; } else { /* bigger than initial, realloc allowing for nul */ len = (size_t)ret + 1; diff --git a/crypto/openssh/openbsd-compat/bsd-cray.c b/crypto/openssh/openbsd-compat/bsd-cray.c index 1532c99..f1bbd7d 100644 --- a/crypto/openssh/openbsd-compat/bsd-cray.c +++ b/crypto/openssh/openbsd-compat/bsd-cray.c @@ -1,5 +1,5 @@ /* - * $Id: bsd-cray.c,v 1.16 2006/09/01 05:38:41 djm Exp $ + * $Id: bsd-cray.c,v 1.17 2007/08/15 09:17:43 dtucker Exp $ * * 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/crypto/openssh/openbsd-compat/bsd-cygwin_util.c b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c index dbf8176..38be7e3 100644 --- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c +++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c @@ -175,45 +175,7 @@ check_nt_auth(int pwd_authenticated, struct passwd *pw) int check_ntsec(const char *filename) { - char *cygwin; - int allow_ntea = 0, allow_ntsec = 0; - struct statfs fsstat; - - /* Windows 95/98/ME don't support file system security at all. */ - if (!is_winnt) - return (0); - - /* Evaluate current CYGWIN settings. */ - cygwin = getenv("CYGWIN"); - allow_ntea = ntea_on(cygwin); - allow_ntsec = ntsec_on(cygwin) || - (has_capability(HAS_NTSEC_BY_DEFAULT) && !ntsec_off(cygwin)); - - /* - * `ntea' is an emulation of POSIX attributes. It doesn't support - * real file level security as ntsec on NTFS file systems does - * but it supports FAT filesystems. `ntea' is minimum requirement - * for security checks. - */ - if (allow_ntea) - return (1); - - /* - * Retrieve file system flags. In Cygwin, file system flags are - * copied to f_type which has no meaning in Win32 itself. - */ - if (statfs(filename, &fsstat)) - return (1); - - /* - * Only file systems supporting ACLs are able to set permissions. - * `ntsec' is the setting in Cygwin which switches using of NTFS - * ACLs to support POSIX permissions on files. - */ - if (fsstat.f_type & FS_PERSISTENT_ACLS) - return (allow_ntsec); - - return (0); + return (pathconf(filename, _PC_POSIX_PERMISSIONS)); } void diff --git a/crypto/openssh/openbsd-compat/bsd-getpeereid.c b/crypto/openssh/openbsd-compat/bsd-getpeereid.c index bdae8b6..5f7e677 100644 --- a/crypto/openssh/openbsd-compat/bsd-getpeereid.c +++ b/crypto/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 <ucred.h> +#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/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c index 17d731b..55f100a 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.c +++ b/crypto/openssh/openbsd-compat/bsd-misc.c @@ -17,6 +17,7 @@ #include "includes.h" +#include <sys/types.h> #ifdef HAVE_SYS_SELECT_H # include <sys/select.h> #endif @@ -27,6 +28,7 @@ #include <string.h> #include <signal.h> #include <stdlib.h> +#include <unistd.h> #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/crypto/openssh/openbsd-compat/bsd-poll.c b/crypto/openssh/openbsd-compat/bsd-poll.c new file mode 100644 index 0000000..284db3a --- /dev/null +++ b/crypto/openssh/openbsd-compat/bsd-poll.c @@ -0,0 +1,118 @@ +/* $Id: bsd-poll.c,v 1.3 2008/04/04 05:16:36 djm Exp $ */ + +/* + * 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) + +#ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +#endif + +#include <stdlib.h> +#include <errno.h> +#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/crypto/openssh/openbsd-compat/bsd-poll.h b/crypto/openssh/openbsd-compat/bsd-poll.h new file mode 100644 index 0000000..dcbb9ca --- /dev/null +++ b/crypto/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/crypto/openssh/openbsd-compat/bsd-snprintf.c b/crypto/openssh/openbsd-compat/bsd-snprintf.c index 04651e1..41d2be23 100644 --- a/crypto/openssh/openbsd-compat/bsd-snprintf.c +++ b/crypto/openssh/openbsd-compat/bsd-snprintf.c @@ -85,6 +85,11 @@ * * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even * if the C library has some snprintf functions already. + * + * Damien Miller (djm@mindrot.org) Jan 2007 + * Fix integer overflows in return value. + * Make formatting quite a bit faster by inlining dopr_outch() + * **************************************************************/ #include "includes.h" @@ -112,6 +117,8 @@ #include <stdarg.h> #include <stdlib.h> #include <string.h> +#include <limits.h> +#include <errno.h> #ifdef HAVE_LONG_DOUBLE # define LDOUBLE long double @@ -159,17 +166,28 @@ # define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif -static size_t dopr(char *buffer, size_t maxlen, const char *format, - va_list args_in); -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max); -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags); -static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags); -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); - -static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) +#define DOPR_OUTCH(buf, pos, buflen, thechar) \ + do { \ + if (pos + 1 >= INT_MAX) { \ + errno = ERANGE; \ + return -1; \ + } \ + if (pos < buflen) \ + buf[pos] = thechar; \ + (pos)++; \ + } while (0) + +static int dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +static int fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static int fmtint(char *buffer, size_t *currlen, size_t maxlen, + LLONG value, int base, int min, int max, int flags); +static int fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); + +static int +dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) { char ch; LLONG value; @@ -198,8 +216,8 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args case DP_S_DEFAULT: if (ch == '%') state = DP_S_FLAGS; - else - dopr_outch (buffer, &currlen, maxlen, ch); + else + DOPR_OUTCH(buffer, currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: @@ -298,7 +316,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = va_arg (args, LLONG); else value = va_arg (args, int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, + value, 10, min, max, flags) == -1) + return -1; break; case 'o': flags |= DP_F_UNSIGNED; @@ -310,7 +330,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (long)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, value, + 8, min, max, flags) == -1) + return -1; break; case 'u': flags |= DP_F_UNSIGNED; @@ -322,7 +344,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, value, + 10, min, max, flags) == -1) + return -1; break; case 'X': flags |= DP_F_UP; @@ -336,15 +360,18 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args value = (LLONG)va_arg (args, unsigned LLONG); else value = (long)va_arg (args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, value, + 16, min, max, flags) == -1) + return -1; break; case 'f': if (cflags == DP_C_LDOUBLE) fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); - /* um, floating point? */ - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; break; case 'E': flags |= DP_F_UP; @@ -353,7 +380,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; break; case 'G': flags |= DP_F_UP; @@ -362,10 +391,13 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args fvalue = va_arg (args, LDOUBLE); else fvalue = va_arg (args, double); - fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + if (fmtfp(buffer, &currlen, maxlen, fvalue, + min, max, flags) == -1) + return -1; break; case 'c': - dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + DOPR_OUTCH(buffer, currlen, maxlen, + va_arg (args, int)); break; case 's': strvalue = va_arg (args, char *); @@ -374,11 +406,15 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args max = strlen(strvalue); } if (min > 0 && max >= 0 && min > max) max = min; - fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + if (fmtstr(buffer, &currlen, maxlen, + strvalue, flags, min, max) == -1) + return -1; break; case 'p': strvalue = va_arg (args, void *); - fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + if (fmtint(buffer, &currlen, maxlen, + (long) strvalue, 16, min, max, flags) == -1) + return -1; break; case 'n': if (cflags == DP_C_SHORT) { @@ -400,7 +436,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args } break; case '%': - dopr_outch (buffer, &currlen, maxlen, ch); + DOPR_OUTCH(buffer, currlen, maxlen, ch); break; case 'w': /* not supported yet, treat as next char */ @@ -429,11 +465,12 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args buffer[maxlen - 1] = '\0'; } - return currlen; + return currlen < INT_MAX ? (int)currlen : -1; } -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) +static int +fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) { int padlen, strln; /* amount to pad */ int cnt = 0; @@ -453,24 +490,27 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, padlen = -padlen; /* Left Justify */ while ((padlen > 0) && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --padlen; ++cnt; } while (*value && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, *value++); + DOPR_OUTCH(buffer, *currlen, maxlen, *value); + *value++; ++cnt; } while ((padlen < 0) && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++padlen; ++cnt; } + return 0; } /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, +static int +fmtint(char *buffer, size_t *currlen, size_t maxlen, LLONG value, int base, int min, int max, int flags) { int signvalue = 0; @@ -527,31 +567,34 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, /* Spaces */ while (spadlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --spadlen; } /* Sign */ if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); /* Zeros */ if (zpadlen > 0) { while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --zpadlen; } } /* Digits */ - while (place > 0) - dopr_outch (buffer, currlen, maxlen, convert[--place]); + while (place > 0) { + --place; + DOPR_OUTCH(buffer, *currlen, maxlen, convert[place]); + } /* Left Justified spaces */ while (spadlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++spadlen; } + return 0; } static LDOUBLE abs_val(LDOUBLE value) @@ -564,13 +607,13 @@ static LDOUBLE abs_val(LDOUBLE value) return result; } -static LDOUBLE POW10(int exp) +static LDOUBLE POW10(int val) { LDOUBLE result = 1; - while (exp) { + while (val) { result *= 10; - exp--; + val--; } return result; @@ -604,7 +647,10 @@ static double my_modf(double x0, double *iptr) } if (i == 100) { - /* yikes! the number is beyond what we can handle. What do we do? */ + /* + * yikes! the number is beyond what we can handle. + * What do we do? + */ (*iptr) = 0; return 0; } @@ -623,8 +669,9 @@ static double my_modf(double x0, double *iptr) } -static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags) +static int +fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) { int signvalue = 0; double ufvalue; @@ -729,24 +776,26 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, if ((flags & DP_F_ZERO) && (padlen > 0)) { if (signvalue) { - dopr_outch (buffer, currlen, maxlen, signvalue); + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); --padlen; signvalue = 0; } while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --padlen; } } while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); --padlen; } if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); + DOPR_OUTCH(buffer, *currlen, maxlen, signvalue); - while (iplace > 0) - dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + while (iplace > 0) { + --iplace; + DOPR_OUTCH(buffer, *currlen, maxlen, iconvert[iplace]); + } #ifdef DEBUG_SNPRINTF printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); @@ -757,41 +806,38 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, * char to print out. */ if (max > 0) { - dopr_outch (buffer, currlen, maxlen, '.'); + DOPR_OUTCH(buffer, *currlen, maxlen, '.'); while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); + DOPR_OUTCH(buffer, *currlen, maxlen, '0'); --zpadlen; } - while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + while (fplace > 0) { + --fplace; + DOPR_OUTCH(buffer, *currlen, maxlen, fconvert[fplace]); + } } while (padlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); + DOPR_OUTCH(buffer, *currlen, maxlen, ' '); ++padlen; } -} - -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) -{ - if (*currlen < maxlen) { - buffer[(*currlen)] = c; - } - (*currlen)++; + return 0; } #endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ #if !defined(HAVE_VSNPRINTF) -int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +int +vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif #if !defined(HAVE_SNPRINTF) -int snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) +int +snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) { size_t ret; va_list ap; @@ -802,4 +848,3 @@ int snprintf(char *str, size_t count, SNPRINTF_CONST char *fmt, ...) return ret; } #endif - diff --git a/crypto/openssh/openbsd-compat/bsd-statvfs.c b/crypto/openssh/openbsd-compat/bsd-statvfs.c new file mode 100644 index 0000000..844d5b4 --- /dev/null +++ b/crypto/openssh/openbsd-compat/bsd-statvfs.c @@ -0,0 +1,37 @@ +/* $Id: bsd-statvfs.c,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */ + +/* + * Copyright (c) 2008 Darren Tucker <dtucker@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 MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <errno.h> + +#ifndef HAVE_STATVFS +int statvfs(const char *path, struct statvfs *buf) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_FSTATVFS +int fstatvfs(int fd, struct statvfs *buf) +{ + errno = ENOSYS; + return -1; +} +#endif diff --git a/crypto/openssh/openbsd-compat/bsd-statvfs.h b/crypto/openssh/openbsd-compat/bsd-statvfs.h new file mode 100644 index 0000000..da215ff --- /dev/null +++ b/crypto/openssh/openbsd-compat/bsd-statvfs.h @@ -0,0 +1,68 @@ +/* $Id: bsd-statvfs.h,v 1.1 2008/06/08 17:32:29 dtucker Exp $ */ + +/* + * Copyright (c) 2008 Darren Tucker <dtucker@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 MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#ifdef HAVE_SYS_STATFS_H +#include <sys/statfs.h> +#endif + +#ifndef HAVE_STATVFS + +#ifndef HAVE_FSBLKCNT_T +typedef unsigned long fsblkcnt_t; +#endif +#ifndef HAVE_FSFILCNT_T +typedef unsigned long fsfilcnt_t; +#endif + +#ifndef ST_RDONLY +#define ST_RDONLY 1 +#endif +#ifndef ST_NOSUID +#define ST_NOSUID 2 +#endif + + /* as defined in IEEE Std 1003.1, 2004 Edition */ +struct statvfs { + unsigned long f_bsize; /* File system block size. */ + unsigned long f_frsize; /* Fundamental file system block size. */ + fsblkcnt_t f_blocks; /* Total number of blocks on file system in */ + /* units of f_frsize. */ + fsblkcnt_t f_bfree; /* Total number of free blocks. */ + fsblkcnt_t f_bavail; /* Number of free blocks available to */ + /* non-privileged process. */ + fsfilcnt_t f_files; /* Total number of file serial numbers. */ + fsfilcnt_t f_ffree; /* Total number of free file serial numbers. */ + fsfilcnt_t f_favail; /* Number of file serial numbers available to */ + /* non-privileged process. */ + unsigned long f_fsid; /* File system ID. */ + unsigned long f_flag; /* BBit mask of f_flag values. */ + unsigned long f_namemax;/* Maximum filename length. */ +}; +#endif + +#ifndef HAVE_STATVFS +int statvfs(const char *, struct statvfs *); +#endif + +#ifndef HAVE_FSTATVFS +int fstatvfs(int, struct statvfs *); +#endif diff --git a/crypto/openssh/openbsd-compat/fake-rfc2553.c b/crypto/openssh/openbsd-compat/fake-rfc2553.c index b6ea3d2..096d9e0 100644 --- a/crypto/openssh/openbsd-compat/fake-rfc2553.c +++ b/crypto/openssh/openbsd-compat/fake-rfc2553.c @@ -51,6 +51,8 @@ int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, struct hostent *hp; char tmpserv[16]; + if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) + return (EAI_FAMILY); if (serv != NULL) { snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); if (strlcpy(serv, tmpserv, servlen) >= servlen) @@ -95,6 +97,8 @@ gai_strerror(int err) return ("memory allocation failure."); case EAI_NONAME: return ("nodename nor servname provided, or not known"); + case EAI_FAMILY: + return ("ai_family not supported"); default: return ("unknown/invalid error."); } @@ -159,6 +163,9 @@ getaddrinfo(const char *hostname, const char *servname, u_long addr; port = 0; + if (hints && hints->ai_family != AF_UNSPEC && + hints->ai_family != AF_INET) + return (EAI_FAMILY); if (servname != NULL) { char *cp; diff --git a/crypto/openssh/openbsd-compat/fake-rfc2553.h b/crypto/openssh/openbsd-compat/fake-rfc2553.h index 5c2ce5b..3e9090f 100644 --- a/crypto/openssh/openbsd-compat/fake-rfc2553.h +++ b/crypto/openssh/openbsd-compat/fake-rfc2553.h @@ -1,4 +1,4 @@ -/* $Id: fake-rfc2553.h,v 1.13 2006/07/24 03:51:52 djm Exp $ */ +/* $Id: fake-rfc2553.h,v 1.16 2008/07/14 11:37:37 djm Exp $ */ /* * Copyright (C) 2000-2003 Damien Miller. All rights reserved. @@ -77,6 +77,7 @@ struct sockaddr_in6 { u_int16_t sin6_port; u_int32_t sin6_flowinfo; struct in6_addr sin6_addr; + u_int32_t sin6_scope_id; }; #endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ @@ -128,6 +129,9 @@ struct sockaddr_in6 { #ifndef EAI_SYSTEM # define EAI_SYSTEM (INT_MAX - 4) #endif +#ifndef EAI_FAMILY +# define EAI_FAMILY (INT_MAX - 5) +#endif #ifndef HAVE_STRUCT_ADDRINFO struct addrinfo { @@ -152,7 +156,7 @@ int getaddrinfo(const char *, const char *, #endif /* !HAVE_GETADDRINFO */ #if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO) -#define gai_strerror(a) (ssh_gai_strerror(a)) +#define gai_strerror(a) (_ssh_compat_gai_strerror(a)) char *gai_strerror(int); #endif /* !HAVE_GAI_STRERROR */ diff --git a/crypto/openssh/openbsd-compat/fmt_scaled.c b/crypto/openssh/openbsd-compat/fmt_scaled.c new file mode 100644 index 0000000..edd682a --- /dev/null +++ b/crypto/openssh/openbsd-compat/fmt_scaled.c @@ -0,0 +1,274 @@ +/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */ + +/* + * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: lib/libutil/fmt_scaled.c */ + +/* + * fmt_scaled: Format numbers scaled for human comprehension + * scan_scaled: Scan numbers in this format. + * + * "Human-readable" output uses 4 digits max, and puts a unit suffix at + * the end. Makes output compact and easy-to-read esp. on huge disks. + * Formatting code was originally in OpenBSD "df", converted to library routine. + * Scanning code written for OpenBSD libutil. + */ + +#include "includes.h" + +#ifndef HAVE_FMT_SCALED + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <limits.h> + +typedef enum { + NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 6 +} unit_type; + +/* These three arrays MUST be in sync! XXX make a struct */ +static unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA }; +static char scale_chars[] = "BKMGTPE"; +static long long scale_factors[] = { + 1LL, + 1024LL, + 1024LL*1024, + 1024LL*1024*1024, + 1024LL*1024*1024*1024, + 1024LL*1024*1024*1024*1024, + 1024LL*1024*1024*1024*1024*1024, +}; +#define SCALE_LENGTH (sizeof(units)/sizeof(units[0])) + +#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */ + +/** Convert the given input string "scaled" into numeric in "result". + * Return 0 on success, -1 and errno set on error. + */ +int +scan_scaled(char *scaled, long long *result) +{ + char *p = scaled; + int sign = 0; + unsigned int i, ndigits = 0, fract_digits = 0; + long long scale_fact = 1, whole = 0, fpart = 0; + + /* Skip leading whitespace */ + while (isascii(*p) && isspace(*p)) + ++p; + + /* Then at most one leading + or - */ + while (*p == '-' || *p == '+') { + if (*p == '-') { + if (sign) { + errno = EINVAL; + return -1; + } + sign = -1; + ++p; + } else if (*p == '+') { + if (sign) { + errno = EINVAL; + return -1; + } + sign = +1; + ++p; + } + } + + /* Main loop: Scan digits, find decimal point, if present. + * We don't allow exponentials, so no scientific notation + * (but note that E for Exa might look like e to some!). + * Advance 'p' to end, to get scale factor. + */ + for (; isascii(*p) && (isdigit(*p) || *p=='.'); ++p) { + if (*p == '.') { + if (fract_digits > 0) { /* oops, more than one '.' */ + errno = EINVAL; + return -1; + } + fract_digits = 1; + continue; + } + + i = (*p) - '0'; /* whew! finally a digit we can use */ + if (fract_digits > 0) { + if (fract_digits >= MAX_DIGITS-1) + /* ignore extra fractional digits */ + continue; + fract_digits++; /* for later scaling */ + fpart *= 10; + fpart += i; + } else { /* normal digit */ + if (++ndigits >= MAX_DIGITS) { + errno = ERANGE; + return -1; + } + whole *= 10; + whole += i; + } + } + + if (sign) { + whole *= sign; + fpart *= sign; + } + + /* If no scale factor given, we're done. fraction is discarded. */ + if (!*p) { + *result = whole; + return 0; + } + + /* Validate scale factor, and scale whole and fraction by it. */ + for (i = 0; i < SCALE_LENGTH; i++) { + + /** Are we there yet? */ + if (*p == scale_chars[i] || + *p == tolower(scale_chars[i])) { + + /* If it ends with alphanumerics after the scale char, bad. */ + if (isalnum(*(p+1))) { + errno = EINVAL; + return -1; + } + scale_fact = scale_factors[i]; + + /* scale whole part */ + whole *= scale_fact; + + /* truncate fpart so it does't overflow. + * then scale fractional part. + */ + while (fpart >= LLONG_MAX / scale_fact) { + fpart /= 10; + fract_digits--; + } + fpart *= scale_fact; + if (fract_digits > 0) { + for (i = 0; i < fract_digits -1; i++) + fpart /= 10; + } + whole += fpart; + *result = whole; + return 0; + } + } + errno = ERANGE; + return -1; +} + +/* Format the given "number" into human-readable form in "result". + * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE. + * Return 0 on success, -1 and errno set if error. + */ +int +fmt_scaled(long long number, char *result) +{ + long long abval, fract = 0; + unsigned int i; + unit_type unit = NONE; + + abval = (number < 0LL) ? -number : number; /* no long long_abs yet */ + + /* Not every negative long long has a positive representation. + * Also check for numbers that are just too darned big to format + */ + if (abval < 0 || abval / 1024 >= scale_factors[SCALE_LENGTH-1]) { + errno = ERANGE; + return -1; + } + + /* scale whole part; get unscaled fraction */ + for (i = 0; i < SCALE_LENGTH; i++) { + if (abval/1024 < scale_factors[i]) { + unit = units[i]; + fract = (i == 0) ? 0 : abval % scale_factors[i]; + number /= scale_factors[i]; + if (i > 0) + fract /= scale_factors[i - 1]; + break; + } + } + + fract = (10 * fract + 512) / 1024; + /* if the result would be >= 10, round main number */ + if (fract == 10) { + if (number >= 0) + number++; + else + number--; + fract = 0; + } + + if (number == 0) + strlcpy(result, "0B", FMT_SCALED_STRSIZE); + else if (unit == NONE || number >= 100 || number <= -100) { + if (fract >= 5) { + if (number >= 0) + number++; + else + number--; + } + (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c", + number, scale_chars[unit]); + } else + (void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c", + number, fract, scale_chars[unit]); + + return 0; +} + +#ifdef MAIN +/* + * This is the original version of the program in the man page. + * Copy-and-paste whatever you need from it. + */ +int +main(int argc, char **argv) +{ + char *cinput = "1.5K", buf[FMT_SCALED_STRSIZE]; + long long ninput = 10483892, result; + + if (scan_scaled(cinput, &result) == 0) + printf("\"%s\" -> %lld\n", cinput, result); + else + perror(cinput); + + if (fmt_scaled(ninput, buf) == 0) + printf("%lld -> \"%s\"\n", ninput, buf); + else + fprintf(stderr, "%lld invalid (%s)\n", ninput, strerror(errno)); + + return 0; +} +#endif + +#endif /* HAVE_FMT_SCALED */ diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname.c b/crypto/openssh/openbsd-compat/getrrsetbyname.c index 6c86e02..785b225 100644 --- a/crypto/openssh/openbsd-compat/getrrsetbyname.c +++ b/crypto/openssh/openbsd-compat/getrrsetbyname.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ +/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */ /* * Copyright (c) 2001 Jakob Schlyter. All rights reserved. @@ -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 */ @@ -292,7 +288,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, rrset->rri_rdtype); rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, - T_SIG); + T_RRSIG); /* allocate memory for answers */ rrset->rri_rdatas = calloc(rrset->rri_nrdatas, @@ -303,10 +299,12 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, } /* allocate memory for signatures */ - rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); - if (rrset->rri_sigs == NULL) { - result = ERRSET_NOMEMORY; - goto fail; + if (rrset->rri_nsigs > 0) { + rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } } /* copy answers & signatures */ @@ -320,7 +318,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, rdata = &rrset->rri_rdatas[index_ans++]; if (rr->class == rrset->rri_rdclass && - rr->type == T_SIG) + rr->type == T_RRSIG) rdata = &rrset->rri_sigs[index_sig++]; if (rdata) { diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname.h b/crypto/openssh/openbsd-compat/getrrsetbyname.h index 39995b6..1283f55 100644 --- a/crypto/openssh/openbsd-compat/getrrsetbyname.h +++ b/crypto/openssh/openbsd-compat/getrrsetbyname.h @@ -62,8 +62,8 @@ #define HFIXEDSZ 12 #endif -#ifndef T_SIG -#define T_SIG 24 +#ifndef T_RRSIG +#define T_RRSIG 46 #endif /* diff --git a/crypto/openssh/openbsd-compat/glob.c b/crypto/openssh/openbsd-compat/glob.c index b3dd2b1..74b5064 100644 --- a/crypto/openssh/openbsd-compat/glob.c +++ b/crypto/openssh/openbsd-compat/glob.c @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.c,v 1.25 2005/08/08 08:05:34 espie Exp $ */ +/* $OpenBSD: glob.c,v 1.26 2005/11/28 17:50:12 deraadt Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -48,7 +48,8 @@ #if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ !defined(GLOB_HAS_GL_MATCHC) || \ - !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 + !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ + defined(BROKEN_GLOB) static long get_arg_max(void) @@ -149,7 +150,7 @@ static int glob0(const Char *, glob_t *); static int glob1(Char *, Char *, glob_t *, size_t *); static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); -static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, +static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); static int globextend(const Char *, glob_t *, size_t *); static const Char * @@ -571,16 +572,16 @@ glob2(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, } else /* Need expansion, recurse. */ return(glob3(pathbuf, pathbuf_last, pathend, - pathend_last, pattern, pattern_last, - p, pattern_last, pglob, limitp)); + pathend_last, pattern, p, pattern_last, + pglob, limitp)); } /* NOTREACHED */ } static int glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last, - Char *pattern, Char *pattern_last, Char *restpattern, - Char *restpattern_last, glob_t *pglob, size_t *limitp) + Char *pattern, Char *restpattern, Char *restpattern_last, glob_t *pglob, + size_t *limitp) { struct dirent *dp; DIR *dirp; diff --git a/crypto/openssh/openbsd-compat/glob.h b/crypto/openssh/openbsd-compat/glob.h index 9ba07f7..a2b36f9 100644 --- a/crypto/openssh/openbsd-compat/glob.h +++ b/crypto/openssh/openbsd-compat/glob.h @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.h,v 1.9 2004/10/07 16:56:11 millert Exp $ */ +/* $OpenBSD: glob.h,v 1.10 2005/12/13 00:35:22 millert Exp $ */ /* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ /* @@ -39,7 +39,8 @@ #if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ !defined(GLOB_HAS_GL_MATCHC) || \ - !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 + !defined(HAVE_DECL_GLOB_NOMATCH) || HAVE_DECL_GLOB_NOMATCH == 0 || \ + defined(BROKEN_GLOB) #ifndef _GLOB_H_ #define _GLOB_H_ @@ -66,7 +67,6 @@ typedef struct { int (*gl_stat)(const char *, struct stat *); } glob_t; -/* Flags */ #define GLOB_APPEND 0x0001 /* Append to output from previous call. */ #define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ #define GLOB_ERR 0x0004 /* Return on error. */ @@ -75,6 +75,13 @@ typedef struct { #define GLOB_NOSORT 0x0020 /* Don't sort. */ #define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ +/* Error values returned by glob(3) */ +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ +#define GLOB_NOSYS (-4) /* Function not supported. */ +#define GLOB_ABEND GLOB_ABORTED + #define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ #define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ #define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ @@ -83,13 +90,6 @@ typedef struct { #define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ #define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ -/* Error values returned by glob(3) */ -#define GLOB_NOSPACE (-1) /* Malloc call failed. */ -#define GLOB_ABORTED (-2) /* Unignored error. */ -#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ -#define GLOB_NOSYS (-4) /* Function not supported. */ -#define GLOB_ABEND GLOB_ABORTED - int glob(const char *, int, int (*)(const char *, int), glob_t *); void globfree(glob_t *); diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h index aac2e6c..50c6d99 100644 --- a/crypto/openssh/openbsd-compat/openbsd-compat.h +++ b/crypto/openssh/openbsd-compat/openbsd-compat.h @@ -1,4 +1,4 @@ -/* $Id: openbsd-compat.h,v 1.42 2006/09/03 12:44:50 dtucker Exp $ */ +/* $Id: openbsd-compat.h,v 1.46 2008/06/08 17:32:29 dtucker Exp $ */ /* * Copyright (c) 1999-2003 Damien Miller. All rights reserved. @@ -101,6 +101,11 @@ int daemon(int nochdir, int noclose); char *dirname(const char *path); #endif +#ifndef HAVE_FMT_SCALED +#define FMT_SCALED_STRSIZE 7 +int fmt_scaled(long long number, char *result); +#endif + #if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) char *inet_ntoa(struct in_addr in); #endif @@ -139,7 +144,9 @@ int writev(int, struct iovec *, int); /* Home grown routines */ #include "bsd-misc.h" +#include "bsd-statvfs.h" #include "bsd-waitpid.h" +#include "bsd-poll.h" #ifndef HAVE_GETPEEREID int getpeereid(int , uid_t *, gid_t *); @@ -150,6 +157,14 @@ unsigned int arc4random(void); void arc4random_stir(void); #endif /* !HAVE_ARC4RANDOM */ +#ifndef HAVE_ARC4RANDOM_BUF +void arc4random_buf(void *, size_t); +#endif + +#ifndef HAVE_ARC4RANDOM_UNIFORM +u_int32_t arc4random_uniform(u_int32_t); +#endif + #ifndef HAVE_ASPRINTF int asprintf(char **, const char *, ...); #endif diff --git a/crypto/openssh/openbsd-compat/openssl-compat.c b/crypto/openssh/openbsd-compat/openssl-compat.c index 45ebd3f..49238ba 100644 --- a/crypto/openssh/openbsd-compat/openssl-compat.c +++ b/crypto/openssh/openbsd-compat/openssl-compat.c @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.c,v 1.4 2006/02/22 11:24:47 dtucker Exp $ */ +/* $Id: openssl-compat.c,v 1.6 2008/02/28 08:13:52 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> diff --git a/crypto/openssh/openbsd-compat/openssl-compat.h b/crypto/openssh/openbsd-compat/openssl-compat.h index c582cd2..6a1bed5 100644 --- a/crypto/openssh/openbsd-compat/openssl-compat.h +++ b/crypto/openssh/openbsd-compat/openssl-compat.h @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.h,v 1.6 2006/02/22 11:24:47 dtucker Exp $ */ +/* $Id: openssl-compat.h,v 1.12 2008/02/28 08:22:04 dtucker Exp $ */ /* * Copyright (c) 2005 Darren Tucker <dtucker@zip.com.au> @@ -19,6 +19,11 @@ #include "includes.h" #include <openssl/evp.h> +/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */ +#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f) +# define OPENSSL_free(x) Free(x) +#endif + #if OPENSSL_VERSION_NUMBER < 0x00906000L # define SSH_OLD_EVP # define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) @@ -29,6 +34,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 @@ -46,6 +56,11 @@ extern const EVP_CIPHER *evp_acss(void); # endif #endif +/* OpenSSL 0.9.8e returns cipher key len not context key len */ +#if (OPENSSL_VERSION_NUMBER == 0x0090805fL) +# define EVP_CIPHER_CTX_key_length(c) ((c)->key_len) +#endif + /* * We overload some of the OpenSSL crypto functions with ssh_* equivalents * which cater for older and/or less featureful OpenSSL version. @@ -69,8 +84,8 @@ extern const EVP_CIPHER *evp_acss(void); # ifdef SSLeay_add_all_algorithms # undef SSLeay_add_all_algorithms # endif -# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms() -#endif +# define SSLeay_add_all_algorithms() ssh_SSLeay_add_all_algorithms() +# endif int ssh_EVP_CipherInit(EVP_CIPHER_CTX *, const EVP_CIPHER *, unsigned char *, unsigned char *, int); diff --git a/crypto/openssh/openbsd-compat/port-aix.c b/crypto/openssh/openbsd-compat/port-aix.c index b9fabf6..5b1cb73 100644 --- a/crypto/openssh/openbsd-compat/port-aix.c +++ b/crypto/openssh/openbsd-compat/port-aix.c @@ -1,7 +1,7 @@ /* * * Copyright (c) 2001 Gert Doering. All rights reserved. - * Copyright (c) 2003,2004,2005 Darren Tucker. All rights reserved. + * Copyright (c) 2003,2004,2005,2006 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -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) { @@ -394,4 +394,47 @@ sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, } # endif /* AIX_GETNAMEINFO_HACK */ +# if defined(USE_GETGRSET) +# include <stdlib.h> +int +getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt) +{ + char *cp, *grplist, *grp; + gid_t gid; + int ret = 0, ngroups = 0, maxgroups; + long l; + + maxgroups = *grpcnt; + + if ((cp = grplist = getgrset(user)) == NULL) + return -1; + + /* handle zero-length case */ + if (maxgroups <= 0) { + *grpcnt = 0; + return -1; + } + + /* copy primary group */ + groups[ngroups++] = pgid; + + /* copy each entry from getgrset into group list */ + while ((grp = strsep(&grplist, ",")) != NULL) { + l = strtol(grp, NULL, 10); + if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) { + ret = -1; + goto out; + } + gid = (gid_t)l; + if (gid == pgid) + continue; /* we have already added primary gid */ + groups[ngroups++] = gid; + } +out: + free(cp); + *grpcnt = ngroups; + return ret; +} +# endif /* USE_GETGRSET */ + #endif /* _AIX */ diff --git a/crypto/openssh/openbsd-compat/port-aix.h b/crypto/openssh/openbsd-compat/port-aix.h index 5a04bed..ecb9fea 100644 --- a/crypto/openssh/openbsd-compat/port-aix.h +++ b/crypto/openssh/openbsd-compat/port-aix.h @@ -1,9 +1,9 @@ -/* $Id: port-aix.h,v 1.27 2006/09/18 13:54:33 dtucker Exp $ */ +/* $Id: port-aix.h,v 1.29 2008/03/09 05:36:55 dtucker Exp $ */ /* * * Copyright (c) 2001 Gert Doering. All rights reserved. - * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. + * Copyright (c) 2004,2005,2006 Darren Tucker. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -103,4 +103,14 @@ int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t, # define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g)) #endif +/* + * We use getgrset in preference to multiple getgrent calls for efficiency + * plus it supports NIS and LDAP groups. + */ +#if !defined(HAVE_GETGROUPLIST) && defined(HAVE_GETGRSET) +# define HAVE_GETGROUPLIST +# define USE_GETGRSET +int getgrouplist(const char *, gid_t, gid_t *, int *); +#endif + #endif /* _AIX */ diff --git a/crypto/openssh/openbsd-compat/port-linux.c b/crypto/openssh/openbsd-compat/port-linux.c index 77f3a1c..ad26275 100644 --- a/crypto/openssh/openbsd-compat/port-linux.c +++ b/crypto/openssh/openbsd-compat/port-linux.c @@ -1,4 +1,4 @@ -/* $Id: port-linux.c,v 1.3 2006/09/01 05:38:41 djm Exp $ */ +/* $Id: port-linux.c,v 1.5 2008/03/26 20:27:21 dtucker Exp $ */ /* * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com> @@ -36,7 +36,7 @@ #include <selinux/get_context_list.h> /* Wrapper around is_selinux_enabled() to log its return value once only */ -static int +int ssh_selinux_enabled(void) { static int enabled = -1; @@ -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/crypto/openssh/openbsd-compat/port-linux.h b/crypto/openssh/openbsd-compat/port-linux.h index 05e520e..5cd39bf 100644 --- a/crypto/openssh/openbsd-compat/port-linux.h +++ b/crypto/openssh/openbsd-compat/port-linux.h @@ -1,4 +1,4 @@ -/* $Id: port-linux.h,v 1.1 2006/04/22 11:26:08 djm Exp $ */ +/* $Id: port-linux.h,v 1.2 2008/03/26 20:27:21 dtucker Exp $ */ /* * Copyright (c) 2006 Damien Miller <djm@openbsd.org> @@ -20,6 +20,7 @@ #define _PORT_LINUX_H #ifdef WITH_SELINUX +int ssh_selinux_enabled(void); void ssh_selinux_setup_pty(char *, const char *); void ssh_selinux_setup_exec_context(char *); #endif diff --git a/crypto/openssh/openbsd-compat/port-tun.c b/crypto/openssh/openbsd-compat/port-tun.c index 276474d..ddc92d0 100644 --- a/crypto/openssh/openbsd-compat/port-tun.c +++ b/crypto/openssh/openbsd-compat/port-tun.c @@ -29,6 +29,7 @@ #include <string.h> #include <unistd.h> +#include "openbsd-compat/sys-queue.h" #include "log.h" #include "misc.h" #include "buffer.h" diff --git a/crypto/openssh/openbsd-compat/port-uw.c b/crypto/openssh/openbsd-compat/port-uw.c index 6f35239..ebc229a 100644 --- a/crypto/openssh/openbsd-compat/port-uw.c +++ b/crypto/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/crypto/openssh/openbsd-compat/port-uw.h b/crypto/openssh/openbsd-compat/port-uw.h index 3589b2e..263d8b5 100644 --- a/crypto/openssh/openbsd-compat/port-uw.h +++ b/crypto/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/crypto/openssh/openbsd-compat/rresvport.c b/crypto/openssh/openbsd-compat/rresvport.c index 5b0275c..1cd61e5 100644 --- a/crypto/openssh/openbsd-compat/rresvport.c +++ b/crypto/openssh/openbsd-compat/rresvport.c @@ -44,6 +44,7 @@ #include <errno.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #if 0 int diff --git a/crypto/openssh/openbsd-compat/setenv.c b/crypto/openssh/openbsd-compat/setenv.c index b52a99c..e2a8b6d 100644 --- a/crypto/openssh/openbsd-compat/setenv.c +++ b/crypto/openssh/openbsd-compat/setenv.c @@ -47,7 +47,7 @@ extern char **environ; * Explicitly removes '=' in argument name. */ static char * -__findenv(const char *name, int *offset) +__findenv(const char *name, size_t *offset) { extern char **environ; int len, i; @@ -82,7 +82,7 @@ setenv(const char *name, const char *value, int rewrite) { static char **lastenv; /* last value of environ */ char *C; - int l_value, offset; + size_t l_value, offset; if (*value == '=') /* no `=' in value */ ++value; @@ -133,7 +133,7 @@ void unsetenv(const char *name) { char **P; - int offset; + size_t offset; while (__findenv(name, &offset)) /* if set multiple times */ for (P = &environ[offset];; ++P) diff --git a/crypto/openssh/openbsd-compat/setproctitle.c b/crypto/openssh/openbsd-compat/setproctitle.c index b511f66..2965f68 100644 --- a/crypto/openssh/openbsd-compat/setproctitle.c +++ b/crypto/openssh/openbsd-compat/setproctitle.c @@ -43,6 +43,8 @@ #endif #include <string.h> +#include <vis.h> + #define SPT_NONE 0 /* don't use it at all */ #define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ #define SPT_REUSEARGV 2 /* cover argv with title information */ @@ -121,7 +123,7 @@ setproctitle(const char *fmt, ...) { #if SPT_TYPE != SPT_NONE va_list ap; - char buf[1024]; + char buf[1024], ptitle[1024]; size_t len; extern char *__progname; #if SPT_TYPE == SPT_PSTAT @@ -142,14 +144,16 @@ setproctitle(const char *fmt, ...) vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); } va_end(ap); + strnvis(ptitle, buf, sizeof(ptitle), + VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); #if SPT_TYPE == SPT_PSTAT - pst.pst_command = buf; - pstat(PSTAT_SETCMD, pst, strlen(buf), 0, 0); + pst.pst_command = ptitle; + pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); #elif SPT_TYPE == SPT_REUSEARGV /* debug("setproctitle: copy \"%s\" into len %d", buf, argv_env_len); */ - len = strlcpy(argv_start, buf, argv_env_len); + len = strlcpy(argv_start, ptitle, argv_env_len); for(; len < argv_env_len; len++) argv_start[len] = SPT_PADCHAR; #endif diff --git a/crypto/openssh/openbsd-compat/sigact.c b/crypto/openssh/openbsd-compat/sigact.c index 8b8e4dd..d67845c 100644 --- a/crypto/openssh/openbsd-compat/sigact.c +++ b/crypto/openssh/openbsd-compat/sigact.c @@ -36,6 +36,7 @@ /* OPENBSD ORIGINAL: lib/libcurses/base/sigaction.c */ #include "includes.h" +#include <errno.h> #include <signal.h> #include "sigact.h" @@ -47,28 +48,39 @@ int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) { - return sigvec(sig, &(sigact->sv), &(osigact->sv)); + return sigvec(sig, sigact ? &sigact->sv : NULL, + osigact ? &osigact->sv : NULL); } int -sigemptyset (sigset_t * mask) +sigemptyset (sigset_t *mask) { + if (!mask) { + errno = EINVAL; + return -1; + } *mask = 0; return 0; } int -sigprocmask (int mode, sigset_t * mask, sigset_t * omask) +sigprocmask (int mode, sigset_t *mask, sigset_t *omask) { sigset_t current = sigsetmask(0); - if (omask) *omask = current; + if (!mask) { + errno = EINVAL; + return -1; + } - if (mode==SIG_BLOCK) + if (omask) + *omask = current; + + if (mode == SIG_BLOCK) current |= *mask; - else if (mode==SIG_UNBLOCK) + else if (mode == SIG_UNBLOCK) current &= ~*mask; - else if (mode==SIG_SETMASK) + else if (mode == SIG_SETMASK) current = *mask; sigsetmask(current); @@ -76,28 +88,44 @@ sigprocmask (int mode, sigset_t * mask, sigset_t * omask) } int -sigsuspend (sigset_t * mask) +sigsuspend (sigset_t *mask) { + if (!mask) { + errno = EINVAL; + return -1; + } return sigpause(*mask); } int -sigdelset (sigset_t * mask, int sig) +sigdelset (sigset_t *mask, int sig) { + if (!mask) { + errno = EINVAL; + return -1; + } *mask &= ~sigmask(sig); return 0; } int -sigaddset (sigset_t * mask, int sig) +sigaddset (sigset_t *mask, int sig) { + if (!mask) { + errno = EINVAL; + return -1; + } *mask |= sigmask(sig); return 0; } int -sigismember (sigset_t * mask, int sig) +sigismember (sigset_t *mask, int sig) { + if (!mask) { + errno = EINVAL; + return -1; + } return (*mask & sigmask(sig)) != 0; } diff --git a/crypto/openssh/openbsd-compat/sys-queue.h b/crypto/openssh/openbsd-compat/sys-queue.h index 4023433..5cf0587 100644 --- a/crypto/openssh/openbsd-compat/sys-queue.h +++ b/crypto/openssh/openbsd-compat/sys-queue.h @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.h,v 1.25 2004/04/08 16:08:21 henning Exp $ */ +/* $OpenBSD: queue.h,v 1.32 2007/04/30 18:42:34 pedro Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ /* @@ -167,6 +167,12 @@ * For details on the use of these macros, see the queue(3) manual page. */ +#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) +#define _Q_INVALIDATE(a) (a) = ((void *)-1) +#else +#define _Q_INVALIDATE(a) +#endif + /* * Singly-linked List definitions. */ @@ -229,13 +235,14 @@ struct { \ #define SLIST_REMOVE(head, elm, type, field) do { \ if ((head)->slh_first == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ + } else { \ struct type *curelm = (head)->slh_first; \ - while( curelm->field.sle_next != (elm) ) \ + \ + while (curelm->field.sle_next != (elm)) \ curelm = curelm->field.sle_next; \ curelm->field.sle_next = \ curelm->field.sle_next->field.sle_next; \ + _Q_INVALIDATE((elm)->field.sle_next); \ } \ } while (0) @@ -303,6 +310,8 @@ struct { \ (elm)->field.le_next->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = (elm)->field.le_next; \ + _Q_INVALIDATE((elm)->field.le_prev); \ + _Q_INVALIDATE((elm)->field.le_next); \ } while (0) #define LIST_REPLACE(elm, elm2, field) do { \ @@ -311,6 +320,8 @@ struct { \ &(elm2)->field.le_next; \ (elm2)->field.le_prev = (elm)->field.le_prev; \ *(elm2)->field.le_prev = (elm2); \ + _Q_INVALIDATE((elm)->field.le_prev); \ + _Q_INVALIDATE((elm)->field.le_next); \ } while (0) /* @@ -369,8 +380,8 @@ struct { \ (listelm)->field.sqe_next = (elm); \ } while (0) -#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ - if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ (head)->sqh_last = &(head)->sqh_first; \ } while (0) @@ -465,6 +476,8 @@ struct { \ else \ (head)->tqh_last = (elm)->field.tqe_prev; \ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ + _Q_INVALIDATE((elm)->field.tqe_prev); \ + _Q_INVALIDATE((elm)->field.tqe_next); \ } while (0) #define TAILQ_REPLACE(head, elm, elm2, field) do { \ @@ -475,6 +488,8 @@ struct { \ (head)->tqh_last = &(elm2)->field.tqe_next; \ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ *(elm2)->field.tqe_prev = (elm2); \ + _Q_INVALIDATE((elm)->field.tqe_prev); \ + _Q_INVALIDATE((elm)->field.tqe_next); \ } while (0) /* @@ -575,6 +590,8 @@ struct { \ else \ (elm)->field.cqe_prev->field.cqe_next = \ (elm)->field.cqe_next; \ + _Q_INVALIDATE((elm)->field.cqe_prev); \ + _Q_INVALIDATE((elm)->field.cqe_next); \ } while (0) #define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ @@ -588,6 +605,8 @@ struct { \ (head).cqh_first = (elm2); \ else \ (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ + _Q_INVALIDATE((elm)->field.cqe_prev); \ + _Q_INVALIDATE((elm)->field.cqe_next); \ } while (0) #endif /* !_FAKE_QUEUE_H_ */ diff --git a/crypto/openssh/openbsd-compat/sys-tree.h b/crypto/openssh/openbsd-compat/sys-tree.h index c80b90b2..d4949b5 100644 --- a/crypto/openssh/openbsd-compat/sys-tree.h +++ b/crypto/openssh/openbsd-compat/sys-tree.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ +/* $OpenBSD: tree.h,v 1.10 2007/10/29 23:49:41 djm Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -289,7 +289,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \ (x) != NULL; \ (x) = SPLAY_NEXT(name, head, x)) -/* Macros that define a red-back tree */ +/* Macros that define a red-black tree */ #define RB_HEAD(name, type) \ struct name { \ struct type *rbh_root; /* root of the tree */ \ @@ -381,9 +381,9 @@ void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ struct type *name##_RB_REMOVE(struct name *, struct type *); \ struct type *name##_RB_INSERT(struct name *, struct type *); \ struct type *name##_RB_FIND(struct name *, struct type *); \ -struct type *name##_RB_NEXT(struct name *, struct type *); \ -struct type *name##_RB_MINMAX(struct name *, int); \ - \ +struct type *name##_RB_NEXT(struct type *); \ +struct type *name##_RB_MINMAX(struct name *, int); + /* Main rb operation. * Moves node close to the key of elm to top @@ -626,7 +626,7 @@ name##_RB_FIND(struct name *head, struct type *elm) \ } \ \ struct type * \ -name##_RB_NEXT(struct name *head, struct type *elm) \ +name##_RB_NEXT(struct type *elm) \ { \ if (RB_RIGHT(elm, field)) { \ elm = RB_RIGHT(elm, field); \ @@ -667,13 +667,13 @@ name##_RB_MINMAX(struct name *head, int val) \ #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) #define RB_FOREACH(x, name, head) \ for ((x) = RB_MIN(name, head); \ (x) != NULL; \ - (x) = name##_RB_NEXT(head, x)) + (x) = name##_RB_NEXT(x)) #endif /* _SYS_TREE_H_ */ diff --git a/crypto/openssh/openbsd-compat/xcrypt.c b/crypto/openssh/openbsd-compat/xcrypt.c index 1489932..d8636bb 100644 --- a/crypto/openssh/openbsd-compat/xcrypt.c +++ b/crypto/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/crypto/openssh/openbsd-compat/xmmap.c b/crypto/openssh/openbsd-compat/xmmap.c index 0fb2326..23efe38 100644 --- a/crypto/openssh/openbsd-compat/xmmap.c +++ b/crypto/openssh/openbsd-compat/xmmap.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: xmmap.c,v 1.12 2006/08/24 09:58:36 dtucker Exp $ */ +/* $Id: xmmap.c,v 1.14 2007/06/11 02:52:24 djm Exp $ */ #include "includes.h" @@ -38,12 +38,14 @@ #endif #include <errno.h> #include <stdarg.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include "log.h" -void *xmmap(size_t size) +void * +xmmap(size_t size) { #ifdef HAVE_MMAP void *address; diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index ab5a010..8abd43e 100644 --- a/crypto/openssh/packet.c +++ b/crypto/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.157 2008/07/10 18:08:11 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -47,7 +47,6 @@ # include <sys/time.h> #endif -#include <netinet/in_systm.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> @@ -137,12 +136,18 @@ static int server_side = 0; /* Set to true if we are authenticated. */ static int after_authentication = 0; +int keep_alive_timeouts = 0; + +/* Set to the maximum time that we will wait to send or receive a packet */ +static int packet_timeout_ms = -1; + /* Session key information for Encryption and MAC */ Newkeys *newkeys[MODE_MAX]; static struct packet_state { u_int32_t seqnr; u_int32_t packets; u_int64_t blocks; + u_int64_t bytes; } p_read, p_send; static u_int64_t max_blocks_in, max_blocks_out; @@ -187,7 +192,21 @@ packet_set_connection(int fd_in, int fd_out) buffer_init(&outgoing_packet); buffer_init(&incoming_packet); TAILQ_INIT(&outgoing); + p_send.packets = p_read.packets = 0; + } +} + +void +packet_set_timeout(int timeout, int count) +{ + if (timeout == 0 || count == 0) { + packet_timeout_ms = -1; + return; } + if ((INT_MAX / 1000) / count < timeout) + packet_timeout_ms = INT_MAX; + else + packet_timeout_ms = timeout * count * 1000; } /* Returns 1 if remote host is connected via socket, 0 if not. */ @@ -294,18 +313,25 @@ packet_get_ssh1_cipher(void) } void -packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets) +packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets, + u_int64_t *bytes) { struct packet_state *state; state = (mode == MODE_IN) ? &p_read : &p_send; - *seqnr = state->seqnr; - *blocks = state->blocks; - *packets = state->packets; + if (seqnr) + *seqnr = state->seqnr; + if (blocks) + *blocks = state->blocks; + if (packets) + *packets = state->packets; + if (bytes) + *bytes = state->bytes; } void -packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets) +packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets, + u_int64_t bytes) { struct packet_state *state; @@ -313,6 +339,7 @@ packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets) state->seqnr = seqnr; state->blocks = blocks; state->packets = packets; + state->bytes = bytes; } /* returns 1 if connection is via ipv4 */ @@ -591,7 +618,8 @@ packet_send1(void) fprintf(stderr, "encrypted: "); buffer_dump(&output); #endif - + p_send.packets++; + p_send.bytes += len + buffer_len(&outgoing_packet); buffer_clear(&outgoing_packet); /* @@ -630,7 +658,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); @@ -645,14 +673,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) { @@ -816,6 +845,7 @@ packet_send2_wrapped(void) if (!(datafellows & SSH_BUG_NOREKEY)) fatal("XXX too many packets with same key"); p_send.blocks += (packet_length + 4) / block_size; + p_send.bytes += packet_length + 4; buffer_clear(&outgoing_packet); if (type == SSH2_MSG_NEWKEYS) @@ -889,9 +919,11 @@ packet_send(void) int packet_read_seqnr(u_int32_t *seqnr_p) { - int type, len; + int type, len, ret, ms_remain; fd_set *setp; char buf[8192]; + struct timeval timeout, start, *timeoutp = NULL; + DBG(debug("packet_read()")); setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), @@ -923,11 +955,35 @@ packet_read_seqnr(u_int32_t *seqnr_p) sizeof(fd_mask)); FD_SET(connection_in, setp); + if (packet_timeout_ms > 0) { + ms_remain = packet_timeout_ms; + timeoutp = &timeout; + } /* Wait for some data to arrive. */ - while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 && - (errno == EAGAIN || errno == EINTR)) - ; - + for (;;) { + if (packet_timeout_ms != -1) { + ms_to_timeval(&timeout, ms_remain); + gettimeofday(&start, NULL); + } + if ((ret = select(connection_in + 1, setp, NULL, + NULL, timeoutp)) >= 0) + break; + if (errno != EAGAIN && errno != EINTR && + errno != EWOULDBLOCK) + break; + if (packet_timeout_ms == -1) + continue; + ms_subtract_diff(&start, &ms_remain); + if (ms_remain <= 0) { + ret = 0; + break; + } + } + if (ret == 0) { + logit("Connection to %.200s timed out while " + "waiting to read", get_remote_ipaddr()); + cleanup_exit(255); + } /* Read data from the socket. */ len = read(connection_in, buf, sizeof(buf)); if (len == 0) { @@ -1052,6 +1108,8 @@ packet_read_poll1(void) buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), buffer_len(&compression_buffer)); } + p_read.packets++; + p_read.bytes += padded_len + 4; type = buffer_get_char(&incoming_packet); if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) packet_disconnect("Invalid ssh1 packet type: %d", type); @@ -1140,6 +1198,7 @@ packet_read_poll2(u_int32_t *seqnr_p) if (!(datafellows & SSH_BUG_NOREKEY)) fatal("XXX too many packets with same key"); p_read.blocks += (packet_length + 4) / block_size; + p_read.bytes += packet_length + 4; /* get padlen */ cp = buffer_ptr(&incoming_packet); @@ -1192,10 +1251,13 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) for (;;) { if (compat20) { type = packet_read_poll2(seqnr_p); - if (type) + if (type) { + keep_alive_timeouts = 0; DBG(debug("received packet type %d", type)); + } switch (type) { case SSH2_MSG_IGNORE: + debug3("Received SSH2_MSG_IGNORE"); break; case SSH2_MSG_DEBUG: packet_get_char(); @@ -1236,7 +1298,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) @@ -1329,6 +1390,12 @@ packet_get_string(u_int *length_ptr) return buffer_get_string(&incoming_packet, length_ptr); } +void * +packet_get_string_ptr(u_int *length_ptr) +{ + return buffer_get_string_ptr(&incoming_packet, length_ptr); +} + /* * Sends a diagnostic message from the server to the client. This message * can be sent at any time (but not while constructing another message). The @@ -1423,16 +1490,19 @@ packet_write_poll(void) if (len > 0) { len = write(connection_out, buffer_ptr(&output), len); - if (len <= 0) { - if (errno == EAGAIN) + if (len == -1) { + if (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK) return; - else - fatal("Write failed: %.100s", strerror(errno)); + fatal("Write failed: %.100s", strerror(errno)); } + if (len == 0) + fatal("Write connection closed"); buffer_consume(&output, len); } } + /* * Calls packet_write_poll repeatedly until all pending output data has been * written. @@ -1442,6 +1512,8 @@ void packet_write_wait(void) { fd_set *setp; + int ret, ms_remain; + struct timeval start, timeout, *timeoutp = NULL; setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), sizeof(fd_mask)); @@ -1450,9 +1522,35 @@ packet_write_wait(void) memset(setp, 0, howmany(connection_out + 1, NFDBITS) * sizeof(fd_mask)); FD_SET(connection_out, setp); - while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 && - (errno == EAGAIN || errno == EINTR)) - ; + + if (packet_timeout_ms > 0) { + ms_remain = packet_timeout_ms; + timeoutp = &timeout; + } + for (;;) { + if (packet_timeout_ms != -1) { + ms_to_timeval(&timeout, ms_remain); + gettimeofday(&start, NULL); + } + if ((ret = select(connection_out + 1, NULL, setp, + NULL, timeoutp)) >= 0) + break; + if (errno != EAGAIN && errno != EINTR && + errno != EWOULDBLOCK) + break; + if (packet_timeout_ms == -1) + continue; + ms_subtract_diff(&start, &ms_remain); + if (ms_remain <= 0) { + ret = 0; + break; + } + } + if (ret == 0) { + logit("Connection to %.200s timed out while " + "waiting to write", get_remote_ipaddr()); + cleanup_exit(255); + } packet_write_poll(); } xfree(setp); diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h index 21ff450..03bb87c 100644 --- a/crypto/openssh/packet.h +++ b/crypto/openssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.45 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.49 2008/07/10 18:08:11 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -21,6 +21,7 @@ #include <openssl/bn.h> void packet_set_connection(int, int); +void packet_set_timeout(int, int); void packet_set_nonblocking(void); int packet_get_connection_in(void); int packet_get_connection_out(void); @@ -58,6 +59,7 @@ void packet_get_bignum(BIGNUM * value); void packet_get_bignum2(BIGNUM * value); void *packet_get_raw(u_int *length_ptr); void *packet_get_string(u_int *length_ptr); +void *packet_get_string_ptr(u_int *length_ptr); void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1, 2))); void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2))); @@ -66,8 +68,8 @@ int packet_get_keyiv_len(int); void packet_get_keyiv(int, u_char *, u_int); int packet_get_keycontext(int, u_char *); void packet_set_keycontext(int, u_char *); -void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *); -void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t); +void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *, u_int64_t *); +void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t); int packet_get_ssh1_cipher(void); void packet_set_iv(int, u_char *); @@ -86,6 +88,7 @@ void tty_make_modes(int, struct termios *); void tty_parse_modes(int, int *); extern u_int max_packet_size; +extern int keep_alive_timeouts; int packet_set_maxsize(u_int); #define packet_get_maxsize() max_packet_size diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c index 1fde2c5..e87cc4d 100644 --- a/crypto/openssh/readconf.c +++ b/crypto/openssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.159 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: readconf.c,v 1.167 2008/06/26 11:46:31 grunk Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -131,6 +131,7 @@ typedef enum { oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, + oVisualHostKey, oVersionAddendum, oDeprecated, oUnsupported } OpCodes; @@ -228,6 +229,7 @@ static struct { { "tunneldevice", oTunnelDevice }, { "localcommand", oLocalCommand }, { "permitlocalcommand", oPermitLocalCommand }, + { "visualhostkey", oVisualHostKey }, { "versionaddendum", oVersionAddendum }, { NULL, oBadOption } }; @@ -329,6 +331,7 @@ process_config_line(Options *options, const char *host, { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; int opcode, *intptr, value, value2, scale; + LogLevel *log_level_ptr; long long orig, val64; size_t len; Forward fwd; @@ -367,7 +370,7 @@ parse_time: if ((value = convtime(arg)) == -1) fatal("%s line %d: invalid time value.", filename, linenum); - if (*intptr == -1) + if (*activep && *intptr == -1) *intptr = value; break; @@ -501,7 +504,6 @@ parse_yesnoask: goto parse_int; case oRekeyLimit: - intptr = &options->rekey_limit; arg = strdelim(&s); if (!arg || *arg == '\0') fatal("%.200s line %d: Missing argument.", filename, linenum); @@ -529,14 +531,14 @@ parse_yesnoask: } val64 *= scale; /* detect integer wrap and too-large limits */ - if ((val64 / scale) != orig || val64 > INT_MAX) + if ((val64 / scale) != orig || val64 > UINT_MAX) fatal("%.200s line %d: RekeyLimit too large", filename, linenum); if (val64 < 16) fatal("%.200s line %d: RekeyLimit too small", filename, linenum); - if (*activep && *intptr == -1) - *intptr = (int)val64; + if (*activep && options->rekey_limit == -1) + options->rekey_limit = (u_int32_t)val64; break; case oIdentityFile: @@ -548,7 +550,7 @@ parse_yesnoask: if (*intptr >= SSH_MAX_IDENTITY_FILES) fatal("%.200s line %d: Too many identity files specified (max %d).", filename, linenum, SSH_MAX_IDENTITY_FILES); - charptr = &options->identity_files[*intptr]; + charptr = &options->identity_files[*intptr]; *charptr = xstrdup(arg); *intptr = *intptr + 1; } @@ -695,14 +697,14 @@ parse_int: break; case oLogLevel: - intptr = (int *) &options->log_level; + log_level_ptr = &options->log_level; arg = strdelim(&s); value = log_level_number(arg); if (value == SYSLOG_LEVEL_NOT_SET) fatal("%.200s line %d: unsupported log level '%s'", filename, linenum, arg ? arg : "<NONE>"); - if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET) - *intptr = (LogLevel) value; + if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET) + *log_level_ptr = (LogLevel) value; break; case oLocalForward: @@ -918,6 +920,10 @@ parse_int: intptr = &options->permit_local_command; goto parse_flag; + case oVisualHostKey: + intptr = &options->visual_host_key; + goto parse_flag; + case oVersionAddendum: ssh_version_set_addendum(strtok(s, "\n")); do { @@ -1075,6 +1081,7 @@ initialize_options(Options * options) options->tun_remote = -1; options->local_command = NULL; options->permit_local_command = -1; + options->visual_host_key = -1; } /* @@ -1209,6 +1216,8 @@ fill_default_options(Options * options) options->tun_remote = SSH_TUNID_ANY; if (options->permit_local_command == -1) options->permit_local_command = 0; + if (options->visual_host_key == -1) + options->visual_host_key = 0; /* options->local_command should not be set by default */ /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ @@ -1234,7 +1243,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) @@ -1265,7 +1274,7 @@ parse_forward(Forward *fwd, const char *fwdspec) xfree(p); - if (fwd->listen_port == 0 && fwd->connect_port == 0) + if (fwd->listen_port == 0 || fwd->connect_port == 0) goto fail_free; if (fwd->connect_host != NULL && diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h index d484f25..47c7aef 100644 --- a/crypto/openssh/readconf.h +++ b/crypto/openssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.71 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: readconf.h,v 1.74 2008/06/26 11:46:31 grunk Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -100,7 +100,7 @@ typedef struct { int clear_forwardings; int enable_ssh_keysign; - int rekey_limit; + int64_t rekey_limit; int no_host_authentication_for_localhost; int identities_only; int server_alive_interval; @@ -120,6 +120,7 @@ typedef struct { char *local_command; int permit_local_command; + int visual_host_key; } Options; diff --git a/crypto/openssh/scard-opensc.c b/crypto/openssh/scard-opensc.c index 4751ea2..36dae05 100644 --- a/crypto/openssh/scard-opensc.c +++ b/crypto/openssh/scard-opensc.c @@ -32,6 +32,7 @@ #include <openssl/x509.h> #include <stdarg.h> +#include <string.h> #include <opensc/opensc.h> #include <opensc/pkcs15.h> diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1 index 43662ab..5033d84 100644 --- a/crypto/openssh/scp.1 +++ b/crypto/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.46 2008/07/12 05:33:41 djm Exp $ .\" -.Dd September 25, 1999 +.Dd $Mdocdate: July 12 2008 $ .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 @ @@ -56,9 +56,15 @@ Unlike will ask for passwords or passphrases if they are needed for authentication. .Pp -Any file name may contain a host and user specification to indicate +File names may contain a user and host specification to indicate that the file is to be copied to/from that host. -Copies between two remote hosts are permitted. +Local file names can be made explicit using absolute or relative pathnames +to avoid +.Nm +treating file names containing +.Sq :\& +as host specifiers. +Copies between two remote hosts are also permitted. .Pp The options are as follows: .Bl -tag -width Ds @@ -98,7 +104,7 @@ per-user configuration file for This option is directly passed to .Xr ssh 1 . .It Fl i Ar identity_file -Selects the file from which the identity (private key) for RSA +Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to .Xr ssh 1 . @@ -178,9 +184,14 @@ is already reserved for preserving the times and modes of the file in Preserves modification times, access times, and modes from the original file. .It Fl q -Disables the progress meter. +Quiet mode: disables the progress meter as well as warning and diagnostic +messages from +.Xr ssh 1 . .It Fl r Recursively copy entire directories. +Note that +.Nm +follows symbolic links encountered in the tree traversal. .It Fl S Ar program Name of .Ar program diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c index 56a3e79..9f8b7a1 100644 --- a/crypto/openssh/scp.c +++ b/crypto/openssh/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.155 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: scp.c,v 1.163 2008/06/13 18:55:22 dtucker Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -78,6 +78,13 @@ #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif +#ifdef HAVE_POLL_H +#include <poll.h> +#else +# ifdef HAVE_SYS_POLL_H +# include <sys/poll.h> +# endif +#endif #ifdef HAVE_SYS_TIME_H # include <sys/time.h> #endif @@ -96,6 +103,9 @@ #include <string.h> #include <time.h> #include <unistd.h> +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +#include <vis.h> +#endif #include "xmalloc.h" #include "atomicio.h" @@ -106,6 +116,8 @@ extern char *__progname; +#define COPY_BUFLEN 16384 + int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); void bwlimit(int); @@ -279,6 +291,7 @@ void sink(int, char *[]); void source(int, char *[]); void tolocal(int, char *[]); void toremote(char *, int, char *[]); +size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *); void usage(void); int @@ -380,7 +393,7 @@ main(int argc, char **argv) if ((pwd = getpwuid(userid = getuid())) == NULL) fatal("unknown user %u", (u_int) userid); - if (!isatty(STDERR_FILENO)) + if (!isatty(STDOUT_FILENO)) showprogress = 0; remin = STDIN_FILENO; @@ -438,6 +451,43 @@ main(int argc, char **argv) exit(errs != 0); } +/* + * atomicio-like wrapper that also applies bandwidth limits and updates + * the progressmeter counter. + */ +size_t +scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c) +{ + u_char *p = (u_char *)_p; + size_t offset; + ssize_t r; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; + for (offset = 0; offset < l;) { + r = f(fd, p + offset, l - offset); + if (r == 0) { + errno = EPIPE; + return offset; + } + if (r < 0) { + if (errno == EINTR) + continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) { + (void)poll(&pfd, 1, -1); /* Ignore errors */ + continue; + } + return offset; + } + offset += (size_t)r; + *c += (off_t)r; + if (limit_rate) + bwlimit(r); + } + return offset; +} + void toremote(char *targ, int argc, char **argv) { @@ -579,10 +629,10 @@ source(int argc, char **argv) struct stat stb; static BUF buffer; BUF *bp; - off_t i, amt, statbytes; - size_t result; + off_t i, statbytes; + size_t amt; 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 +641,21 @@ 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; } + if (stb.st_size < 0) { + run_err("%s: %s", name, "Negative file size"); + goto next; + } + unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: break; @@ -626,8 +680,14 @@ syserr: run_err("%s: %s", name, strerror(errno)); * versions expecting microseconds. */ (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", - (u_long) stb.st_mtime, - (u_long) stb.st_atime); + (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime), + (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime)); + if (verbose_mode) { + fprintf(stderr, "File mtime %ld atime %ld\n", + (long)stb.st_mtime, (long)stb.st_atime); + fprintf(stderr, "Sending file timestamps: %s", + buf); + } (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; @@ -642,7 +702,7 @@ syserr: run_err("%s: %s", name, strerror(errno)); (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; - if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { + if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); fd = -1; @@ -651,27 +711,25 @@ next: if (fd != -1) { } if (showprogress) start_progress_meter(curfile, stb.st_size, &statbytes); - /* Keep writing after an error so that we stay sync'd up. */ + set_nonblock(remout); for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { amt = bp->cnt; - if (i + amt > stb.st_size) + if (i + (off_t)amt > stb.st_size) amt = stb.st_size - i; if (!haderr) { - result = atomicio(read, fd, bp->buf, amt); - if (result != amt) + if (atomicio(read, fd, bp->buf, amt) != amt) haderr = errno; } - if (haderr) - (void) atomicio(vwrite, remout, bp->buf, amt); - else { - result = atomicio(vwrite, remout, bp->buf, amt); - if (result != amt) - haderr = errno; - statbytes += result; + /* Keep writing after error to retain sync */ + if (haderr) { + (void)atomicio(vwrite, remout, bp->buf, amt); + continue; } - if (limit_rate) - bwlimit(amt); + if (scpio(vwrite, remout, bp->buf, amt, + &statbytes) != amt) + haderr = errno; } + unset_nonblock(remout); if (showprogress) stop_progress_meter(); @@ -777,10 +835,10 @@ bwlimit(int amount) thresh /= 2; if (thresh < 2048) thresh = 2048; - } else if (bwend.tv_usec < 100) { + } else if (bwend.tv_usec < 10000) { thresh *= 2; - if (thresh > 32768) - thresh = 32768; + if (thresh > COPY_BUFLEN * 4) + thresh = COPY_BUFLEN * 4; } TIMEVAL_TO_TIMESPEC(&bwend, &ts); @@ -971,7 +1029,7 @@ bad: run_err("%s: %s", np, strerror(errno)); continue; } (void) atomicio(vwrite, remout, "", 1); - if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { + if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; } @@ -981,26 +1039,24 @@ bad: run_err("%s: %s", np, strerror(errno)); statbytes = 0; if (showprogress) start_progress_meter(curfile, size, &statbytes); - for (count = i = 0; i < size; i += 4096) { - amt = 4096; + set_nonblock(remin); + for (count = i = 0; i < size; i += bp->cnt) { + amt = bp->cnt; if (i + amt > size) amt = size - i; count += amt; do { - j = atomicio(read, remin, cp, amt); + j = scpio(read, remin, cp, amt, &statbytes); if (j == 0) { - run_err("%s", j ? strerror(errno) : + run_err("%s", j != EPIPE ? + strerror(errno) : "dropped connection"); exit(1); } amt -= j; cp += j; - statbytes += j; } while (amt > 0); - if (limit_rate) - bwlimit(4096); - if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { @@ -1014,6 +1070,7 @@ bad: run_err("%s: %s", np, strerror(errno)); cp = bp->buf; } } + unset_nonblock(remin); if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && @@ -1021,7 +1078,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 +1174,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/crypto/openssh/servconf.c b/crypto/openssh/servconf.c index 5ffa7ce..4ce6ff0 100644 --- a/crypto/openssh/servconf.c +++ b/crypto/openssh/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.165 2006/08/14 12:40:25 dtucker Exp $ */ +/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -24,7 +24,9 @@ __RCSID("$FreeBSD$"); #include <signal.h> #include <unistd.h> #include <stdarg.h> +#include <errno.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "log.h" @@ -100,6 +102,7 @@ initialize_server_options(ServerOptions *options) options->use_login = -1; options->compression = -1; options->allow_tcp_forwarding = -1; + options->allow_agent_forwarding = -1; options->num_allow_users = 0; options->num_deny_users = 0; options->num_allow_groups = 0; @@ -113,6 +116,7 @@ initialize_server_options(ServerOptions *options) options->max_startups_rate = -1; options->max_startups = -1; options->max_authtries = -1; + options->max_sessions = -1; options->banner = NULL; options->use_dns = -1; options->client_alive_interval = -1; @@ -123,6 +127,7 @@ initialize_server_options(ServerOptions *options) options->permit_tun = -1; options->num_permitted_opens = -1; options->adm_forced_command = NULL; + options->chroot_directory = NULL; } void @@ -142,6 +147,8 @@ fill_default_server_options(ServerOptions *options) _PATH_HOST_KEY_FILE; if (options->protocol & SSH_PROTO_2) { options->host_key_files[options->num_host_key_files++] = + _PATH_HOST_RSA_KEY_FILE; + options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE; } } @@ -152,7 +159,7 @@ fill_default_server_options(ServerOptions *options) if (options->pid_file == NULL) options->pid_file = _PATH_SSH_DAEMON_PID_FILE; if (options->server_key_bits == -1) - options->server_key_bits = 768; + options->server_key_bits = 1024; if (options->login_grace_time == -1) options->login_grace_time = 120; if (options->key_regeneration_time == -1) @@ -206,11 +213,7 @@ fill_default_server_options(ServerOptions *options) if (options->gss_cleanup_creds == -1) options->gss_cleanup_creds = 1; if (options->password_authentication == -1) -#ifdef USE_PAM options->password_authentication = 0; -#else - options->password_authentication = 1; -#endif if (options->kbd_interactive_authentication == -1) options->kbd_interactive_authentication = 0; if (options->challenge_response_authentication == -1) @@ -225,6 +228,8 @@ fill_default_server_options(ServerOptions *options) options->compression = COMP_DELAYED; if (options->allow_tcp_forwarding == -1) options->allow_tcp_forwarding = 1; + if (options->allow_agent_forwarding == -1) + options->allow_agent_forwarding = 1; if (options->gateway_ports == -1) options->gateway_ports = 0; if (options->max_startups == -1) @@ -235,6 +240,8 @@ fill_default_server_options(ServerOptions *options) options->max_startups_begin = options->max_startups; if (options->max_authtries == -1) options->max_authtries = DEFAULT_AUTH_FAIL_MAX; + if (options->max_sessions == -1) + options->max_sessions = DEFAULT_SESSIONS_MAX; if (options->use_dns == -1) options->use_dns = 1; if (options->client_alive_interval == -1) @@ -289,13 +296,13 @@ typedef enum { sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, - sMaxStartups, sMaxAuthTries, + sMaxStartups, sMaxAuthTries, sMaxSessions, sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, - sMatch, sPermitOpen, sForceCommand, - sUsePrivilegeSeparation, + sMatch, sPermitOpen, sForceCommand, sChrootDirectory, + sUsePrivilegeSeparation, sAllowAgentForwarding, sVersionAddendum, sDeprecated, sUnsupported } ServerOpCodes; @@ -325,18 +332,18 @@ static struct { { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL }, { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL }, - { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL }, + { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, { "loglevel", sLogLevel, SSHCFG_GLOBAL }, { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, - { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL }, - { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL }, + { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL }, + { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL }, - { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL }, - { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, + { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL }, + { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ #ifdef KRB5 - { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL }, + { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL }, #ifdef USE_AFS @@ -345,7 +352,7 @@ static struct { { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, #endif #else - { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL }, + { "kerberosauthentication", sUnsupported, SSHCFG_ALL }, { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL }, { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL }, { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL }, @@ -353,14 +360,14 @@ static struct { { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL }, { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL }, #ifdef GSSAPI - { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL }, + { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, #else - { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL }, + { "gssapiauthentication", sUnsupported, SSHCFG_ALL }, { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL }, #endif - { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL }, - { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL }, + { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, + { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ { "checkmail", sDeprecated, SSHCFG_GLOBAL }, @@ -382,6 +389,7 @@ static struct { { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */ { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL }, + { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL }, { "allowusers", sAllowUsers, SSHCFG_GLOBAL }, { "denyusers", sDenyUsers, SSHCFG_GLOBAL }, { "allowgroups", sAllowGroups, SSHCFG_GLOBAL }, @@ -392,8 +400,9 @@ static struct { { "gatewayports", sGatewayPorts, SSHCFG_ALL }, { "subsystem", sSubsystem, SSHCFG_GLOBAL }, { "maxstartups", sMaxStartups, SSHCFG_GLOBAL }, - { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL }, - { "banner", sBanner, SSHCFG_GLOBAL }, + { "maxauthtries", sMaxAuthTries, SSHCFG_ALL }, + { "maxsessions", sMaxSessions, SSHCFG_ALL }, + { "banner", sBanner, SSHCFG_ALL }, { "usedns", sUseDNS, SSHCFG_GLOBAL }, { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL }, { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL }, @@ -407,10 +416,22 @@ static struct { { "match", sMatch, SSHCFG_ALL }, { "permitopen", sPermitOpen, SSHCFG_ALL }, { "forcecommand", sForceCommand, SSHCFG_ALL }, + { "chrootdirectory", sChrootDirectory, SSHCFG_ALL }, { "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; +static struct { + int val; + char *text; +} tunmode_desc[] = { + { SSH_TUNMODE_NO, "no" }, + { SSH_TUNMODE_POINTOPOINT, "point-to-point" }, + { SSH_TUNMODE_ETHERNET, "ethernet" }, + { SSH_TUNMODE_YES, "yes" }, + { -1, NULL } +}; + /* * Returns the number of the token pointed to by cp or sBadOption. */ @@ -463,7 +484,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port) if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) fatal("bad addr or host: %s (%s)", addr ? addr : "<NULL>", - gai_strerror(gaierr)); + ssh_gai_strerror(gaierr)); for (ai = aitop; ai->ai_next; ai = ai->ai_next) ; ai->ai_next = options->listen_addrs; @@ -507,24 +528,8 @@ static int match_cfg_line_group(const char *grps, int line, const char *user) { int result = 0; - u_int ngrps = 0; - char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS]; struct passwd *pw; - /* - * Even if we do not have a user yet, we still need to check for - * valid syntax. - */ - arg = cp = xstrdup(grps); - while ((p = strsep(&cp, ",")) != NULL && *p != '\0') { - if (ngrps >= MAX_MATCH_GROUPS) { - error("line %d: too many groups in Match Group", line); - result = -1; - goto out; - } - grplist[ngrps++] = p; - } - if (user == NULL) goto out; @@ -534,17 +539,16 @@ match_cfg_line_group(const char *grps, int line, const char *user) } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) { debug("Can't Match group because user %.100s not in any group " "at line %d", user, line); - } else if (ga_match(grplist, ngrps) != 1) { - debug("user %.100s does not match group %.100s at line %d", - user, arg, line); + } else if (ga_match_pattern_list(grps) != 1) { + debug("user %.100s does not match group list %.100s at line %d", + user, grps, line); } else { - debug("user %.100s matched group %.100s at line %d", user, - arg, line); + debug("user %.100s matched group list %.100s at line %d", user, + grps, line); result = 1; } out: ga_free(); - xfree(arg); return result; } @@ -597,16 +601,18 @@ 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; - } - if (match_hostname(address, arg, len) != 1) - result = 0; - else + switch (addr_match_list(address, arg)) { + case 1: debug("connection from %.100s matched 'Address " "%.100s' at line %d", address, arg, line); + break; + case 0: + case -1: + result = 0; + break; + case -2: + return -1; + } } else { error("Unsupported Match attribute %s", attrib); return -1; @@ -627,6 +633,8 @@ process_server_config_line(ServerOptions *options, char *line, { char *cp, **charptr, *arg, *p; int cmdline = 0, *intptr, value, n; + SyslogFacility *log_facility_ptr; + LogLevel *log_level_ptr; ServerOpCodes opcode; u_short port; u_int i, flags = 0; @@ -692,7 +700,7 @@ process_server_config_line(ServerOptions *options, char *line, case sServerKeyBits: intptr = &options->server_key_bits; -parse_int: + parse_int: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing integer value.", @@ -704,7 +712,7 @@ parse_int: case sLoginGraceTime: intptr = &options->login_grace_time; -parse_time: + parse_time: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing time value.", @@ -773,7 +781,7 @@ parse_time: fatal("%s line %d: too many host keys specified (max %d).", filename, linenum, MAX_HOSTKEYS); charptr = &options->host_key_files[*intptr]; -parse_filename: + parse_filename: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing file name.", @@ -810,13 +818,13 @@ parse_filename: fatal("%s line %d: Bad yes/" "without-password/forced-commands-only/no " "argument: %s", filename, linenum, arg); - if (*intptr == -1) + if (*activep && *intptr == -1) *intptr = value; break; case sIgnoreRhosts: intptr = &options->ignore_rhosts; -parse_flag: + parse_flag: arg = strdelim(&cp); if (!arg || *arg == '\0') fatal("%s line %d: missing yes/no argument.", @@ -973,7 +981,7 @@ parse_flag: else fatal("%s line %d: Bad yes/no/clientspecified " "argument: %s", filename, linenum, arg); - if (*intptr == -1) + if (*activep && *intptr == -1) *intptr = value; break; @@ -982,31 +990,35 @@ parse_flag: goto parse_flag; case sLogFacility: - intptr = (int *) &options->log_facility; + log_facility_ptr = &options->log_facility; arg = strdelim(&cp); value = log_facility_number(arg); if (value == SYSLOG_FACILITY_NOT_SET) fatal("%.200s line %d: unsupported log facility '%s'", filename, linenum, arg ? arg : "<NONE>"); - if (*intptr == -1) - *intptr = (SyslogFacility) value; + if (*log_facility_ptr == -1) + *log_facility_ptr = (SyslogFacility) value; break; case sLogLevel: - intptr = (int *) &options->log_level; + log_level_ptr = &options->log_level; arg = strdelim(&cp); value = log_level_number(arg); if (value == SYSLOG_LEVEL_NOT_SET) fatal("%.200s line %d: unsupported log level '%s'", filename, linenum, arg ? arg : "<NONE>"); - if (*intptr == -1) - *intptr = (LogLevel) value; + if (*log_level_ptr == -1) + *log_level_ptr = (LogLevel) value; break; case sAllowTcpForwarding: intptr = &options->allow_tcp_forwarding; goto parse_flag; + case sAllowAgentForwarding: + intptr = &options->allow_agent_forwarding; + goto parse_flag; + case sUsePrivilegeSeparation: intptr = &use_privsep; goto parse_flag; @@ -1148,9 +1160,14 @@ parse_flag: intptr = &options->max_authtries; goto parse_int; + case sMaxSessions: + intptr = &options->max_sessions; + goto parse_int; + case sBanner: charptr = &options->banner; goto parse_filename; + /* * These options can contain %X options expanded at * connect time, so that you can specify paths like: @@ -1193,16 +1210,13 @@ parse_flag: if (!arg || *arg == '\0') fatal("%s line %d: Missing yes/point-to-point/" "ethernet/no argument.", filename, linenum); - value = 0; /* silence compiler */ - if (strcasecmp(arg, "ethernet") == 0) - value = SSH_TUNMODE_ETHERNET; - else if (strcasecmp(arg, "point-to-point") == 0) - value = SSH_TUNMODE_POINTOPOINT; - else if (strcasecmp(arg, "yes") == 0) - value = SSH_TUNMODE_YES; - else if (strcasecmp(arg, "no") == 0) - value = SSH_TUNMODE_NO; - else + value = -1; + for (i = 0; tunmode_desc[i].val != -1; i++) + if (strcmp(tunmode_desc[i].text, arg) == 0) { + value = tunmode_desc[i].val; + break; + } + if (value == -1) fatal("%s line %d: Bad yes/point-to-point/ethernet/" "no argument: %s", filename, linenum, arg); if (*intptr == -1) @@ -1225,13 +1239,16 @@ parse_flag: if (!arg || *arg == '\0') fatal("%s line %d: missing PermitOpen specification", filename, linenum); + n = options->num_permitted_opens; /* modified later */ if (strcmp(arg, "any") == 0) { - if (*activep) { + if (*activep && n == -1) { channel_clear_adm_permitted_opens(); options->num_permitted_opens = 0; } break; } + if (*activep && n == -1) + channel_clear_adm_permitted_opens(); for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) { p = hpdelim(&arg); if (p == NULL) @@ -1241,11 +1258,9 @@ parse_flag: if (arg == NULL || (port = a2port(arg)) == 0) fatal("%s line %d: bad port number in " "PermitOpen", filename, linenum); - if (*activep && options->num_permitted_opens == -1) { - channel_clear_adm_permitted_opens(); + if (*activep && n == -1) options->num_permitted_opens = channel_add_adm_permitted_opens(p, port); - } } break; @@ -1258,6 +1273,17 @@ parse_flag: options->adm_forced_command = xstrdup(cp + len); return 0; + case sChrootDirectory: + charptr = &options->chroot_directory; + + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: missing file name.", + filename, linenum); + if (*activep && *charptr == NULL) + *charptr = xstrdup(arg); + break; + case sVersionAddendum: ssh_version_set_addendum(strtok(cp, "\n")); do { @@ -1328,30 +1354,60 @@ parse_server_match_config(ServerOptions *options, const char *user, initialize_server_options(&mo); parse_server_config(&mo, "reprocess config", &cfg, user, host, address); - copy_set_server_options(options, &mo); + copy_set_server_options(options, &mo, 0); } -/* Copy any (supported) values that are set */ +/* Helper macros */ +#define M_CP_INTOPT(n) do {\ + if (src->n != -1) \ + dst->n = src->n; \ +} while (0) +#define M_CP_STROPT(n) do {\ + if (src->n != NULL) { \ + if (dst->n != NULL) \ + xfree(dst->n); \ + dst->n = src->n; \ + } \ +} while(0) + +/* + * Copy any supported values that are set. + * + * If the preauth flag is set, we do not bother copying the the string or + * array values that are not used pre-authentication, because any that we + * do use must be explictly sent in mm_getpwnamallow(). + */ void -copy_set_server_options(ServerOptions *dst, ServerOptions *src) +copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) { - if (src->allow_tcp_forwarding != -1) - dst->allow_tcp_forwarding = src->allow_tcp_forwarding; - if (src->gateway_ports != -1) - dst->gateway_ports = src->gateway_ports; - if (src->adm_forced_command != NULL) { - if (dst->adm_forced_command != NULL) - xfree(dst->adm_forced_command); - dst->adm_forced_command = src->adm_forced_command; - } - if (src->x11_display_offset != -1) - dst->x11_display_offset = src->x11_display_offset; - if (src->x11_forwarding != -1) - dst->x11_forwarding = src->x11_forwarding; - if (src->x11_use_localhost != -1) - dst->x11_use_localhost = src->x11_use_localhost; + M_CP_INTOPT(password_authentication); + M_CP_INTOPT(gss_authentication); + M_CP_INTOPT(rsa_authentication); + M_CP_INTOPT(pubkey_authentication); + M_CP_INTOPT(kerberos_authentication); + M_CP_INTOPT(hostbased_authentication); + M_CP_INTOPT(kbd_interactive_authentication); + M_CP_INTOPT(permit_root_login); + + M_CP_INTOPT(allow_tcp_forwarding); + M_CP_INTOPT(allow_agent_forwarding); + M_CP_INTOPT(gateway_ports); + M_CP_INTOPT(x11_display_offset); + M_CP_INTOPT(x11_forwarding); + M_CP_INTOPT(x11_use_localhost); + M_CP_INTOPT(max_sessions); + M_CP_INTOPT(max_authtries); + + M_CP_STROPT(banner); + if (preauth) + return; + M_CP_STROPT(adm_forced_command); + M_CP_STROPT(chroot_directory); } +#undef M_CP_INTOPT +#undef M_CP_STROPT + void parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, const char *user, const char *host, const char *address) @@ -1374,3 +1430,213 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, fatal("%s: terminating, %d bad configuration options", filename, bad_options); } + +static const char * +fmt_intarg(ServerOpCodes code, int val) +{ + if (code == sAddressFamily) { + switch (val) { + case AF_INET: + return "inet"; + case AF_INET6: + return "inet6"; + case AF_UNSPEC: + return "any"; + default: + return "UNKNOWN"; + } + } + if (code == sPermitRootLogin) { + switch (val) { + case PERMIT_NO_PASSWD: + return "without-passord"; + case PERMIT_FORCED_ONLY: + return "forced-commands-only"; + case PERMIT_YES: + return "yes"; + } + } + if (code == sProtocol) { + switch (val) { + case SSH_PROTO_1: + return "1"; + case SSH_PROTO_2: + return "2"; + case (SSH_PROTO_1|SSH_PROTO_2): + return "2,1"; + default: + return "UNKNOWN"; + } + } + if (code == sGatewayPorts && val == 2) + return "clientspecified"; + if (code == sCompression && val == COMP_DELAYED) + return "delayed"; + switch (val) { + case -1: + return "unset"; + case 0: + return "no"; + case 1: + return "yes"; + } + return "UNKNOWN"; +} + +static const char * +lookup_opcode_name(ServerOpCodes code) +{ + u_int i; + + for (i = 0; keywords[i].name != NULL; i++) + if (keywords[i].opcode == code) + return(keywords[i].name); + return "UNKNOWN"; +} + +static void +dump_cfg_int(ServerOpCodes code, int val) +{ + printf("%s %d\n", lookup_opcode_name(code), val); +} + +static void +dump_cfg_fmtint(ServerOpCodes code, int val) +{ + printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val)); +} + +static void +dump_cfg_string(ServerOpCodes code, const char *val) +{ + if (val == NULL) + return; + printf("%s %s\n", lookup_opcode_name(code), val); +} + +static void +dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) +{ + u_int i; + + for (i = 0; i < count; i++) + printf("%s %s\n", lookup_opcode_name(code), vals[i]); +} + +void +dump_config(ServerOptions *o) +{ + u_int i; + int ret; + struct addrinfo *ai; + char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL; + + /* these are usually at the top of the config */ + for (i = 0; i < o->num_ports; i++) + printf("port %d\n", o->ports[i]); + dump_cfg_fmtint(sProtocol, o->protocol); + dump_cfg_fmtint(sAddressFamily, o->address_family); + + /* ListenAddress must be after Port */ + for (ai = o->listen_addrs; ai; ai = ai->ai_next) { + if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, + sizeof(addr), port, sizeof(port), + NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { + error("getnameinfo failed: %.100s", + (ret != EAI_SYSTEM) ? gai_strerror(ret) : + strerror(errno)); + } else { + if (ai->ai_family == AF_INET6) + printf("listenaddress [%s]:%s\n", addr, port); + else + printf("listenaddress %s:%s\n", addr, port); + } + } + + /* integer arguments */ + dump_cfg_int(sServerKeyBits, o->server_key_bits); + dump_cfg_int(sLoginGraceTime, o->login_grace_time); + dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); + dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); + dump_cfg_int(sMaxAuthTries, o->max_authtries); + dump_cfg_int(sClientAliveInterval, o->client_alive_interval); + dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); + + /* formatted integer arguments */ + dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login); + dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts); + dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts); + dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication); + dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication); + dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, + o->hostbased_uses_name_from_packet_only); + dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); + dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); + dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); + dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); + dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); + dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); + dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); + dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); + dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); + dump_cfg_fmtint(sKbdInteractiveAuthentication, + o->kbd_interactive_authentication); + dump_cfg_fmtint(sChallengeResponseAuthentication, + o->challenge_response_authentication); + dump_cfg_fmtint(sPrintMotd, o->print_motd); + dump_cfg_fmtint(sPrintLastLog, o->print_lastlog); + dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding); + dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost); + dump_cfg_fmtint(sStrictModes, o->strict_modes); + dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive); + dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd); + dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env); + dump_cfg_fmtint(sUseLogin, o->use_login); + dump_cfg_fmtint(sCompression, o->compression); + dump_cfg_fmtint(sGatewayPorts, o->gateway_ports); + dump_cfg_fmtint(sUseDNS, o->use_dns); + dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding); + dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep); + + /* string arguments */ + dump_cfg_string(sPidFile, o->pid_file); + dump_cfg_string(sXAuthLocation, o->xauth_location); + dump_cfg_string(sCiphers, o->ciphers); + dump_cfg_string(sMacs, o->macs); + dump_cfg_string(sBanner, o->banner); + dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file); + dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2); + dump_cfg_string(sForceCommand, o->adm_forced_command); + + /* string arguments requiring a lookup */ + dump_cfg_string(sLogLevel, log_level_name(o->log_level)); + dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); + + /* string array arguments */ + dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, + o->host_key_files); + dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users); + dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users); + dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups); + dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups); + dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env); + + /* other arguments */ + for (i = 0; i < o->num_subsystems; i++) + printf("subsystem %s %s\n", o->subsystem_name[i], + o->subsystem_args[i]); + + printf("maxstartups %d:%d:%d\n", o->max_startups_begin, + o->max_startups_rate, o->max_startups); + + for (i = 0; tunmode_desc[i].val != -1; i++) + if (tunmode_desc[i].val == o->permit_tun) { + s = tunmode_desc[i].text; + break; + } + dump_cfg_string(sPermitTunnel, s); + + printf("permitopen"); + channel_print_adm_permitted_opens(); + printf("\n"); +} diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h index ad496f6..40ac64f 100644 --- a/crypto/openssh/servconf.h +++ b/crypto/openssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.79 2006/08/14 12:40:25 dtucker Exp $ */ +/* $OpenBSD: servconf.h,v 1.85 2008/06/10 04:50:25 dtucker Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -35,6 +35,10 @@ #define PERMIT_YES 3 #define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */ +#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */ + +/* Magic name for internal sftp-server */ +#define INTERNAL_SFTP_NAME "internal-sftp" typedef struct { u_int num_ports; @@ -98,6 +102,7 @@ typedef struct { int use_login; /* If true, login(1) is used */ int compression; /* If true, compression is allowed */ int allow_tcp_forwarding; + int allow_agent_forwarding; u_int num_allow_users; char *allow_users[MAX_ALLOW_USERS]; u_int num_deny_users; @@ -119,6 +124,7 @@ typedef struct { int max_startups_rate; int max_startups; int max_authtries; + int max_sessions; char *banner; /* SSH-2 banner message */ int use_dns; int client_alive_interval; /* @@ -141,6 +147,8 @@ typedef struct { int permit_tun; int num_permitted_opens; + + char *chroot_directory; } ServerOptions; void initialize_server_options(ServerOptions *); @@ -152,6 +160,7 @@ void parse_server_config(ServerOptions *, const char *, Buffer *, const char *, const char *, const char *); void parse_server_match_config(ServerOptions *, const char *, const char *, const char *); -void copy_set_server_options(ServerOptions *, ServerOptions *); +void copy_set_server_options(ServerOptions *, ServerOptions *, int); +void dump_config(ServerOptions *); #endif /* SERVCONF_H */ diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index 69304b5..77d9dee 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.145 2006/10/11 12:38:03 markus Exp $ */ +/* $OpenBSD: serverloop.c,v 1.153 2008/06/30 12:15:39 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -56,6 +56,7 @@ #include <unistd.h> #include <stdarg.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "packet.h" #include "buffer.h" @@ -104,7 +105,7 @@ static int connection_in; /* Connection to client (input). */ static int connection_out; /* Connection to client (output). */ static int connection_closed = 0; /* Connection to client closed. */ static u_int buffer_high; /* "Soft" max buffer size. */ -static int client_alive_timeouts = 0; +static int no_more_sessions = 0; /* Disallow further sessions. */ /* * This SIGCHLD kludge is used to detect when the child exits. The server @@ -248,7 +249,7 @@ client_alive_check(void) int channel_id; /* timeout, check to see how many we have had */ - if (++client_alive_timeouts > options.client_alive_count_max) { + if (++keep_alive_timeouts > options.client_alive_count_max) { logit("Timeout, client not responding."); cleanup_exit(255); } @@ -280,6 +281,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, struct timeval tv, *tvp; int ret; int client_alive_scheduled = 0; + int program_alive_scheduled = 0; /* * if using client_alive, set the max timeout accordingly, @@ -317,6 +319,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, * the client, try to get some more data from the program. */ if (packet_not_very_much_data_to_write()) { + program_alive_scheduled = child_terminated; if (!fdout_eof) FD_SET(fdout, *readsetp); if (!fderr_eof) @@ -362,8 +365,16 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, memset(*writesetp, 0, *nallocp); if (errno != EINTR) error("select: %.100s", strerror(errno)); - } else if (ret == 0 && client_alive_scheduled) - client_alive_check(); + } else { + if (ret == 0 && client_alive_scheduled) + client_alive_check(); + if (!compat20 && program_alive_scheduled && fdin_is_tty) { + if (!fdout_eof) + FD_SET(fdout, *readsetp); + if (!fderr_eof) + FD_SET(fderr, *readsetp); + } + } notify_done(*readsetp); } @@ -389,7 +400,8 @@ process_input(fd_set *readset) return; cleanup_exit(255); } else if (len < 0) { - if (errno != EINTR && errno != EAGAIN) { + if (errno != EINTR && errno != EAGAIN && + errno != EWOULDBLOCK) { verbose("Read error from remote host " "%.100s: %.100s", get_remote_ipaddr(), strerror(errno)); @@ -407,7 +419,8 @@ process_input(fd_set *readset) if (!fdout_eof && FD_ISSET(fdout, readset)) { errno = 0; len = read(fdout, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + if (len < 0 && (errno == EINTR || ((errno == EAGAIN || + errno == EWOULDBLOCK) && !child_terminated))) { /* do nothing */ #ifndef PTY_ZEROREAD } else if (len <= 0) { @@ -425,7 +438,8 @@ process_input(fd_set *readset) if (!fderr_eof && FD_ISSET(fderr, readset)) { errno = 0; len = read(fderr, buf, sizeof(buf)); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + if (len < 0 && (errno == EINTR || ((errno == EAGAIN || + errno == EWOULDBLOCK) && !child_terminated))) { /* do nothing */ #ifndef PTY_ZEROREAD } else if (len <= 0) { @@ -456,7 +470,8 @@ process_output(fd_set *writeset) data = buffer_ptr(&stdin_buffer); dlen = buffer_len(&stdin_buffer); len = write(fdin, data, dlen); - if (len < 0 && (errno == EINTR || errno == EAGAIN)) { + if (len < 0 && + (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) { /* do nothing */ } else if (len <= 0) { if (fdin != fdout) @@ -875,7 +890,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt) * even if this was generated by something other than * the bogus CHANNEL_REQUEST we send for keepalives. */ - client_alive_timeouts = 0; + keep_alive_timeouts = 0; } static void @@ -926,7 +941,6 @@ static Channel * server_request_direct_tcpip(void) { Channel *c; - int sock; char *target, *originator; int target_port, originator_port; @@ -936,18 +950,16 @@ server_request_direct_tcpip(void) originator_port = packet_get_int(); packet_check_eom(); - debug("server_request_direct_tcpip: originator %s port %d, target %s port %d", - originator, originator_port, target, target_port); + debug("server_request_direct_tcpip: originator %s port %d, target %s " + "port %d", originator, originator_port, target, target_port); /* XXX check permission */ - sock = channel_connect_to(target, target_port); - xfree(target); + c = channel_connect_to(target, target_port, + "direct-tcpip", "direct-tcpip"); + xfree(originator); - if (sock < 0) - return NULL; - c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING, - sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, - CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1); + xfree(target); + return c; } @@ -988,7 +1000,7 @@ server_request_tun(void) #if defined(SSH_TUN_FILTER) if (mode == SSH_TUNMODE_POINTOPOINT) channel_register_filter(c->self, sys_tun_infilter, - sys_tun_outfilter); + sys_tun_outfilter, NULL, NULL); #endif done: @@ -1004,6 +1016,12 @@ server_request_session(void) debug("input_session_request"); packet_check_eom(); + + if (no_more_sessions) { + packet_disconnect("Possible attack: attempt to open a session " + "after additional sessions disabled"); + } + /* * A server session has no fd to read or write until a * CHANNEL_REQUEST for a shell is made, so we set the type to @@ -1124,6 +1142,9 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) success = channel_cancel_rport_listener(cancel_address, cancel_port); xfree(cancel_address); + } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { + no_more_sessions = 1; + success = 1; } if (want_reply) { packet_start(success ? @@ -1151,7 +1172,11 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt) if ((c = channel_lookup(id)) == NULL) packet_disconnect("server_input_channel_req: " "unknown channel %d", id); - if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) + if (!strcmp(rtype, "eow@openssh.com")) { + packet_check_eom(); + chan_rcvd_eow(c); + } else if ((c->type == SSH_CHANNEL_LARVAL || + c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) success = session_input_channel_req(c, rtype); if (reply) { packet_start(success ? @@ -1177,8 +1202,9 @@ server_init_dispatch_20(void) dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); + dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); /* client_alive */ - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive); dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive); dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive); /* rekeying */ diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c index a752e72..4dd390b 100644 --- a/crypto/openssh/session.c +++ b/crypto/openssh/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.220 2006/10/09 23:36:11 djm Exp $ */ +/* $OpenBSD: session.c,v 1.241 2008/06/16 13:22:53 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * All rights reserved @@ -60,6 +60,7 @@ __RCSID("$FreeBSD$"); #include <string.h> #include <unistd.h> +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" #include "ssh1.h" @@ -85,9 +86,11 @@ __RCSID("$FreeBSD$"); #include "sshlogin.h" #include "serverloop.h" #include "canohost.h" +#include "misc.h" #include "session.h" #include "kex.h" #include "monitor_wrap.h" +#include "sftp.h" #if defined(KRB5) && defined(USE_AFS) #include <kafs.h> @@ -96,13 +99,13 @@ __RCSID("$FreeBSD$"); /* func */ Session *session_new(void); -void session_set_fds(Session *, int, int, int); +void session_set_fds(Session *, int, int, int, int); void session_pty_cleanup(Session *); void session_proctitle(Session *); int session_setup_x11fwd(Session *); -void do_exec_pty(Session *, const char *); -void do_exec_no_pty(Session *, const char *); -void do_exec(Session *, const char *); +int do_exec_pty(Session *, const char *); +int do_exec_no_pty(Session *, const char *); +int do_exec(Session *, const char *); void do_login(Session *, const char *); #ifdef LOGIN_NEEDS_UTMPX static void do_pre_login(Session *s); @@ -130,8 +133,13 @@ extern Buffer loginmsg; const char *original_command = NULL; /* data */ -#define MAX_SESSIONS 10 -Session sessions[MAX_SESSIONS]; +static int sessions_first_unused = -1; +static int sessions_nalloc = 0; +static Session *sessions = NULL; + +#define SUBSYSTEM_NONE 0 +#define SUBSYSTEM_EXT 1 +#define SUBSYSTEM_INT_SFTP 2 #ifdef HAVE_LOGIN_CAP login_cap_t *lc; @@ -161,7 +169,7 @@ static int auth_input_request_forwarding(struct passwd * pw) { Channel *nc; - int sock; + int sock = -1; struct sockaddr_un sunaddr; if (auth_sock_name != NULL) { @@ -173,43 +181,48 @@ auth_input_request_forwarding(struct passwd * pw) temporarily_use_uid(pw); /* Allocate a buffer for the socket name, and format the name. */ - auth_sock_name = xmalloc(MAXPATHLEN); - auth_sock_dir = xmalloc(MAXPATHLEN); - strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN); + auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX"); /* Create private directory for socket */ if (mkdtemp(auth_sock_dir) == NULL) { packet_send_debug("Agent forwarding disabled: " "mkdtemp() failed: %.100s", strerror(errno)); restore_uid(); - xfree(auth_sock_name); xfree(auth_sock_dir); - auth_sock_name = NULL; auth_sock_dir = NULL; - return 0; + goto authsock_err; } - snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld", - auth_sock_dir, (long) getpid()); + + xasprintf(&auth_sock_name, "%s/agent.%ld", + auth_sock_dir, (long) getpid()); /* Create the socket. */ sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) - packet_disconnect("socket: %.100s", strerror(errno)); + if (sock < 0) { + error("socket: %.100s", strerror(errno)); + restore_uid(); + goto authsock_err; + } /* Bind it to the name. */ memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); - if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) - packet_disconnect("bind: %.100s", strerror(errno)); + if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { + error("bind: %.100s", strerror(errno)); + restore_uid(); + goto authsock_err; + } /* Restore the privileged uid. */ restore_uid(); /* Start listening on the socket. */ - if (listen(sock, SSH_LISTEN_BACKLOG) < 0) - packet_disconnect("listen: %.100s", strerror(errno)); + if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { + error("listen: %.100s", strerror(errno)); + goto authsock_err; + } /* Allocate a channel for the authentication agent socket. */ nc = channel_new("auth socket", @@ -218,6 +231,19 @@ auth_input_request_forwarding(struct passwd * pw) 0, "auth socket", 1); strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); return 1; + + authsock_err: + if (auth_sock_name != NULL) + xfree(auth_sock_name); + if (auth_sock_dir != NULL) { + rmdir(auth_sock_dir); + xfree(auth_sock_dir); + } + if (sock != -1) + close(sock); + auth_sock_name = NULL; + auth_sock_dir = NULL; + return 0; } static void @@ -330,7 +356,8 @@ do_authenticated1(Authctxt *authctxt) break; case SSH_CMSG_AGENT_REQUEST_FORWARDING: - if (no_agent_forwarding_flag || compat13) { + if (!options.allow_agent_forwarding || + no_agent_forwarding_flag || compat13) { debug("Authentication agent forwarding not permitted for this authentication."); break; } @@ -366,10 +393,14 @@ do_authenticated1(Authctxt *authctxt) if (type == SSH_CMSG_EXEC_CMD) { command = packet_get_string(&dlen); debug("Exec command '%.500s'", command); - do_exec(s, command); + if (do_exec(s, command) != 0) + packet_disconnect( + "command execution failed"); xfree(command); } else { - do_exec(s, NULL); + if (do_exec(s, NULL) != 0) + packet_disconnect( + "shell execution failed"); } packet_check_eom(); session_close(s); @@ -394,46 +425,84 @@ do_authenticated1(Authctxt *authctxt) } } +#define USE_PIPES /* * This is called to fork and execute a command when we have no tty. This * will call do_child from the child, and server_loop from the parent after * setting up file descriptors and such. */ -void +int do_exec_no_pty(Session *s, const char *command) { pid_t pid; #ifdef USE_PIPES int pin[2], pout[2], perr[2]; + /* Allocate pipes for communicating with the program. */ - if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0) - packet_disconnect("Could not create pipes: %.100s", - strerror(errno)); -#else /* USE_PIPES */ + if (pipe(pin) < 0) { + error("%s: pipe in: %.100s", __func__, strerror(errno)); + return -1; + } + if (pipe(pout) < 0) { + error("%s: pipe out: %.100s", __func__, strerror(errno)); + close(pin[0]); + close(pin[1]); + return -1; + } + if (pipe(perr) < 0) { + error("%s: pipe err: %.100s", __func__, strerror(errno)); + close(pin[0]); + close(pin[1]); + close(pout[0]); + close(pout[1]); + return -1; + } +#else int inout[2], err[2]; + /* Uses socket pairs to communicate with the program. */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 || - socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) - packet_disconnect("Could not create socket pairs: %.100s", - strerror(errno)); -#endif /* USE_PIPES */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) { + error("%s: socketpair #1: %.100s", __func__, strerror(errno)); + return -1; + } + if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) { + error("%s: socketpair #2: %.100s", __func__, strerror(errno)); + close(inout[0]); + close(inout[1]); + return -1; + } +#endif + if (s == NULL) fatal("do_exec_no_pty: no session"); session_proctitle(s); -#if defined(USE_PAM) - if (options.use_pam && !use_privsep) - do_pam_setcred(1); -#endif /* USE_PAM */ - /* Fork the child. */ - if ((pid = fork()) == 0) { + switch ((pid = fork())) { + case -1: + error("%s: fork: %.100s", __func__, strerror(errno)); +#ifdef USE_PIPES + close(pin[0]); + close(pin[1]); + close(pout[0]); + close(pout[1]); + close(perr[0]); + close(perr[1]); +#else + close(inout[0]); + close(inout[1]); + close(err[0]); + close(err[1]); +#endif + return -1; + case 0: is_child = 1; /* Child. Reinitialize the log since the pid has changed. */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); + log_init(__progname, options.log_level, + options.log_facility, log_stderr); /* * Create a new session and process group since the 4.4BSD @@ -463,7 +532,7 @@ do_exec_no_pty(Session *s, const char *command) if (dup2(perr[1], 2) < 0) perror("dup2 stderr"); close(perr[1]); -#else /* USE_PIPES */ +#else /* * Redirect stdin, stdout, and stderr. Stdin and stdout will * use the same socket, as some programs (particularly rdist) @@ -473,11 +542,14 @@ do_exec_no_pty(Session *s, const char *command) close(err[1]); if (dup2(inout[0], 0) < 0) /* stdin */ perror("dup2 stdin"); - if (dup2(inout[0], 1) < 0) /* stdout. Note: same socket as stdin. */ + if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ perror("dup2 stdout"); + close(inout[0]); if (dup2(err[0], 2) < 0) /* stderr */ perror("dup2 stderr"); -#endif /* USE_PIPES */ + close(err[0]); +#endif + #ifdef _UNICOS cray_init_job(s->pw); /* set up cray jid and tmpdir */ @@ -486,7 +558,10 @@ do_exec_no_pty(Session *s, const char *command) /* Do processing for the child (exec command etc). */ do_child(s, command); /* NOTREACHED */ + default: + break; } + #ifdef _UNICOS signal(WJSIGNAL, cray_job_termination_handler); #endif /* _UNICOS */ @@ -494,11 +569,18 @@ do_exec_no_pty(Session *s, const char *command) if (is_winnt) cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); #endif - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; /* Set interactive/non-interactive mode. */ packet_set_interactive(s->display != NULL); + + /* + * Clear loginmsg, since it's the child's responsibility to display + * it to the user, otherwise multiple sessions may accumulate + * multiple copies of the login messages. + */ + buffer_clear(&loginmsg); + #ifdef USE_PIPES /* We are the parent. Close the child sides of the pipes. */ close(pin[0]); @@ -510,35 +592,32 @@ do_exec_no_pty(Session *s, const char *command) close(perr[0]); perr[0] = -1; } - session_set_fds(s, pin[1], pout[0], perr[0]); + session_set_fds(s, pin[1], pout[0], perr[0], 0); } else { /* Enter the interactive session. */ server_loop(pid, pin[1], pout[0], perr[0]); /* server_loop has closed pin[1], pout[0], and perr[0]. */ } -#else /* USE_PIPES */ +#else /* We are the parent. Close the child sides of the socket pairs. */ close(inout[0]); close(err[0]); /* - * Clear loginmsg, since it's the child's responsibility to display - * it to the user, otherwise multiple sessions may accumulate - * multiple copies of the login messages. - */ - buffer_clear(&loginmsg); - - /* * Enter the interactive session. Note: server_loop must be able to * handle the case that fdin and fdout are the same. */ if (compat20) { - session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]); + session_set_fds(s, inout[1], inout[1], + s->is_subsystem ? -1 : err[1], 0); + if (s->is_subsystem) + close(err[1]); } else { server_loop(pid, inout[1], inout[1], err[1]); /* server_loop has closed inout[1] and err[1]. */ } -#endif /* USE_PIPES */ +#endif + return 0; } /* @@ -547,7 +626,7 @@ do_exec_no_pty(Session *s, const char *command) * setting up file descriptors, controlling tty, updating wtmp, utmp, * lastlog, and other such operations. */ -void +int do_exec_pty(Session *s, const char *command) { int fdout, ptyfd, ttyfd, ptymaster; @@ -558,20 +637,46 @@ do_exec_pty(Session *s, const char *command) ptyfd = s->ptyfd; ttyfd = s->ttyfd; -#if defined(USE_PAM) - if (options.use_pam) { - do_pam_set_tty(s->tty); - if (!use_privsep) - do_pam_setcred(1); + /* + * Create another descriptor of the pty master side for use as the + * standard input. We could use the original descriptor, but this + * simplifies code in server_loop. The descriptor is bidirectional. + * Do this before forking (and cleanup in the child) so as to + * detect and gracefully fail out-of-fd conditions. + */ + if ((fdout = dup(ptyfd)) < 0) { + error("%s: dup #1: %s", __func__, strerror(errno)); + close(ttyfd); + close(ptyfd); + return -1; + } + /* we keep a reference to the pty master */ + if ((ptymaster = dup(ptyfd)) < 0) { + error("%s: dup #2: %s", __func__, strerror(errno)); + close(ttyfd); + close(ptyfd); + close(fdout); + return -1; } -#endif /* Fork the child. */ - if ((pid = fork()) == 0) { + switch ((pid = fork())) { + case -1: + error("%s: fork: %.100s", __func__, strerror(errno)); + close(fdout); + close(ptymaster); + close(ttyfd); + close(ptyfd); + return -1; + case 0: is_child = 1; + close(fdout); + close(ptymaster); + /* Child. Reinitialize the log because the pid has changed. */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); + log_init(__progname, options.log_level, + options.log_facility, log_stderr); /* Close the master side of the pseudo tty. */ close(ptyfd); @@ -602,11 +707,16 @@ do_exec_pty(Session *s, const char *command) do_pre_login(s); # endif #endif - - /* Do common processing for the child, such as execing the command. */ - do_child(s, command); - /* NOTREACHED */ + /* + * Do common processing for the child, such as execing + * the command. + */ + do_child(s, command); + /* NOTREACHED */ + default: + break; } + #ifdef _UNICOS signal(WJSIGNAL, cray_job_termination_handler); #endif /* _UNICOS */ @@ -614,36 +724,22 @@ do_exec_pty(Session *s, const char *command) if (is_winnt) cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); #endif - if (pid < 0) - packet_disconnect("fork failed: %.100s", strerror(errno)); + s->pid = pid; /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); - /* - * Create another descriptor of the pty master side for use as the - * standard input. We could use the original descriptor, but this - * simplifies code in server_loop. The descriptor is bidirectional. - */ - fdout = dup(ptyfd); - if (fdout < 0) - packet_disconnect("dup #1 failed: %.100s", strerror(errno)); - - /* we keep a reference to the pty master */ - ptymaster = dup(ptyfd); - if (ptymaster < 0) - packet_disconnect("dup #2 failed: %.100s", strerror(errno)); - s->ptymaster = ptymaster; - /* Enter interactive session. */ + s->ptymaster = ptymaster; packet_set_interactive(1); if (compat20) { - session_set_fds(s, ptyfd, fdout, -1); + session_set_fds(s, ptyfd, fdout, -1, 1); } else { server_loop(pid, ptyfd, fdout, -1); /* server_loop _has_ closed ptyfd and fdout. */ } + return 0; } #ifdef LOGIN_NEEDS_UTMPX @@ -678,16 +774,26 @@ do_pre_login(Session *s) * This is called to fork and execute a command. If another command is * to be forced, execute that instead. */ -void +int do_exec(Session *s, const char *command) { + int ret; + if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; + if (strcmp(INTERNAL_SFTP_NAME, command) == 0) + s->is_subsystem = SUBSYSTEM_INT_SFTP; + else if (s->is_subsystem) + s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (config) '%.900s'", command); } else if (forced_command) { original_command = command; command = forced_command; + if (strcmp(INTERNAL_SFTP_NAME, command) == 0) + s->is_subsystem = SUBSYSTEM_INT_SFTP; + else if (s->is_subsystem) + s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (key option) '%.900s'", command); } @@ -702,11 +808,10 @@ do_exec(Session *s, const char *command) PRIVSEP(audit_run_command(shell)); } #endif - if (s->ttyfd != -1) - do_exec_pty(s, command); + ret = do_exec_pty(s, command); else - do_exec_no_pty(s, command); + ret = do_exec_no_pty(s, command); original_command = NULL; @@ -716,6 +821,8 @@ do_exec(Session *s, const char *command) * multiple copies of the login messages. */ buffer_clear(&loginmsg); + + return ret; } /* administrative, login(1)-like work */ @@ -916,8 +1023,9 @@ read_environment_file(char ***env, u_int *envsize, ; if (!*cp || *cp == '#' || *cp == '\n') continue; - if (strchr(cp, '\n')) - *strchr(cp, '\n') = '\0'; + + cp[strcspn(cp, "\n")] = '\0'; + value = strchr(cp, '='); if (value == NULL) { fprintf(stderr, "Bad line %u in %.100s\n", lineno, @@ -1231,8 +1339,9 @@ do_rc_files(Session *s, const char *shell) do_xauth = s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; - /* ignore _PATH_SSH_USER_RC for subsystems */ - if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) { + /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */ + if (!s->is_subsystem && options.adm_forced_command == NULL && + !no_user_rc && stat(_PATH_SSH_USER_RC, &st) >= 0) { snprintf(cmd, sizeof cmd, "%s -c '%s %s'", shell, _PATH_BSHELL, _PATH_SSH_USER_RC); if (debug_flag) @@ -1313,10 +1422,72 @@ do_nologin(struct passwd *pw) } } +/* + * Chroot into a directory after checking it for safety: all path components + * must be root-owned directories with strict permissions. + */ +static void +safely_chroot(const char *path, uid_t uid) +{ + const char *cp; + char component[MAXPATHLEN]; + struct stat st; + + if (*path != '/') + fatal("chroot path does not begin at root"); + if (strlen(path) >= sizeof(component)) + fatal("chroot path too long"); + + /* + * Descend the path, checking that each component is a + * root-owned directory with strict permissions. + */ + for (cp = path; cp != NULL;) { + if ((cp = strchr(cp, '/')) == NULL) + strlcpy(component, path, sizeof(component)); + else { + cp++; + memcpy(component, path, cp - path); + component[cp - path] = '\0'; + } + + debug3("%s: checking '%s'", __func__, component); + + if (stat(component, &st) != 0) + fatal("%s: stat(\"%s\"): %s", __func__, + component, strerror(errno)); + if (st.st_uid != 0 || (st.st_mode & 022) != 0) + fatal("bad ownership or modes for chroot " + "directory %s\"%s\"", + cp == NULL ? "" : "component ", component); + if (!S_ISDIR(st.st_mode)) + fatal("chroot path %s\"%s\" is not a directory", + cp == NULL ? "" : "component ", component); + + } + + if (chdir(path) == -1) + fatal("Unable to chdir to chroot path \"%s\": " + "%s", path, strerror(errno)); + if (chroot(path) == -1) + fatal("chroot(\"%s\"): %s", path, strerror(errno)); + if (chdir("/") == -1) + fatal("%s: chdir(/) after chroot: %s", + __func__, strerror(errno)); + verbose("Changed root directory to \"%s\"", path); +} + /* Set login name, uid, gid, and groups. */ void do_setusercontext(struct passwd *pw) { + char *chroot_path, *tmp; + +#ifdef WITH_SELINUX + /* Cache selinux status for later use */ + (void)ssh_selinux_enabled(); +#endif + #ifndef HAVE_CYGWIN if (getuid() == 0 || geteuid() == 0) #endif /* HAVE_CYGWIN */ @@ -1330,21 +1501,13 @@ do_setusercontext(struct passwd *pw) # ifdef __bsdi__ setpgid(0, 0); # endif -#ifdef GSSAPI - if (options.gss_authentication) { - temporarily_use_uid(pw); - ssh_gssapi_storecreds(); - restore_uid(); - } -#endif # 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, - (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH))) < 0) { + (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { perror("unable to set user context"); exit(1); } @@ -1367,13 +1530,6 @@ do_setusercontext(struct passwd *pw) exit(1); } endgrent(); -#ifdef GSSAPI - if (options.gss_authentication) { - temporarily_use_uid(pw); - ssh_gssapi_storecreds(); - restore_uid(); - } -#endif # ifdef USE_PAM /* * PAM credentials may take the form of supplementary groups. @@ -1381,21 +1537,39 @@ do_setusercontext(struct passwd *pw) * Reestablish them here. */ 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) irix_setusercontext(pw); -# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ +# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ # 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 */ +#endif + + if (options.chroot_directory != NULL && + strcasecmp(options.chroot_directory, "none") != 0) { + tmp = tilde_expand_filename(options.chroot_directory, + pw->pw_uid); + chroot_path = percent_expand(tmp, "h", pw->pw_dir, + "u", pw->pw_name, (char *)NULL); + safely_chroot(chroot_path, pw->pw_uid); + free(tmp); + free(chroot_path); + } + +#ifdef HAVE_LOGIN_CAP + if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { + perror("unable to set user context (setuser)"); + exit(1); + } +#else /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif @@ -1494,17 +1668,16 @@ child_close_fds(void) * environment, closing extra file descriptors, setting the user and group * ids, and executing the command or shell. */ +#define ARGV_MAX 10 void do_child(Session *s, const char *command) { extern char **environ; char **env; - char *argv[10]; + char *argv[ARGV_MAX]; const char *shell, *shell0, *hostname = NULL; struct passwd *pw = s->pw; -#ifdef HAVE_LOGIN_CAP - int lc_requirehome; -#endif + int r = 0; /* remove hostkey from the child's memory */ destroy_sensitive_data(); @@ -1592,10 +1765,6 @@ do_child(Session *s, const char *command) */ environ = env; -#ifdef HAVE_LOGIN_CAP - lc_requirehome = login_getcapbool(lc, "requirehome", 0); - login_close(lc); -#endif #if defined(KRB5) && defined(USE_AFS) /* * At this point, we check to see if AFS is active and if we have @@ -1624,20 +1793,42 @@ do_child(Session *s, const char *command) /* Change current directory to the user's home directory. */ if (chdir(pw->pw_dir) < 0) { - fprintf(stderr, "Could not chdir to home directory %s: %s\n", - pw->pw_dir, strerror(errno)); + /* Suppress missing homedir warning for chroot case */ #ifdef HAVE_LOGIN_CAP - if (lc_requirehome) - exit(1); + r = login_getcapbool(lc, "requirehome", 0); #endif + if (r || options.chroot_directory == NULL) + fprintf(stderr, "Could not chdir to home " + "directory %s: %s\n", pw->pw_dir, + strerror(errno)); + if (r) + exit(1); } + closefrom(STDERR_FILENO + 1); + if (!options.use_login) do_rc_files(s, shell); /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); + if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { + extern int optind, optreset; + int i; + char *p, *args; + + setproctitle("%s@internal-sftp-server", s->pw->pw_name); + args = strdup(command ? command : "sftp-server"); + for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) + if (i < ARGV_MAX - 1) + argv[i++] = p; + argv[i] = NULL; + optind = optreset = 1; + __progname = argv[0]; + exit(sftp_server_main(i, argv, s->pw)); + } + if (options.use_login) { launch_login(pw, hostname); /* NEVERREACHED */ @@ -1689,43 +1880,79 @@ do_child(Session *s, const char *command) exit(1); } +void +session_unused(int id) +{ + debug3("%s: session id %d unused", __func__, id); + if (id >= options.max_sessions || + id >= sessions_nalloc) { + fatal("%s: insane session id %d (max %d nalloc %d)", + __func__, id, options.max_sessions, sessions_nalloc); + } + bzero(&sessions[id], sizeof(*sessions)); + sessions[id].self = id; + sessions[id].used = 0; + sessions[id].chanid = -1; + sessions[id].ptyfd = -1; + sessions[id].ttyfd = -1; + sessions[id].ptymaster = -1; + sessions[id].x11_chanids = NULL; + sessions[id].next_unused = sessions_first_unused; + sessions_first_unused = id; +} + Session * session_new(void) { - int i; - static int did_init = 0; - if (!did_init) { - debug("session_new: init"); - for (i = 0; i < MAX_SESSIONS; i++) { - sessions[i].used = 0; + Session *s, *tmp; + + if (sessions_first_unused == -1) { + if (sessions_nalloc >= options.max_sessions) + return NULL; + debug2("%s: allocate (allocated %d max %d)", + __func__, sessions_nalloc, options.max_sessions); + tmp = xrealloc(sessions, sessions_nalloc + 1, + sizeof(*sessions)); + if (tmp == NULL) { + error("%s: cannot allocate %d sessions", + __func__, sessions_nalloc + 1); + return NULL; } - did_init = 1; + sessions = tmp; + session_unused(sessions_nalloc++); } - for (i = 0; i < MAX_SESSIONS; i++) { - Session *s = &sessions[i]; - if (! s->used) { - memset(s, 0, sizeof(*s)); - s->chanid = -1; - s->ptyfd = -1; - s->ttyfd = -1; - s->used = 1; - s->self = i; - s->x11_chanids = NULL; - debug("session_new: session %d", i); - return s; - } + + if (sessions_first_unused >= sessions_nalloc || + sessions_first_unused < 0) { + fatal("%s: insane first_unused %d max %d nalloc %d", + __func__, sessions_first_unused, options.max_sessions, + sessions_nalloc); } - return NULL; + + s = &sessions[sessions_first_unused]; + if (s->used) { + fatal("%s: session %d already used", + __func__, sessions_first_unused); + } + sessions_first_unused = s->next_unused; + s->used = 1; + s->next_unused = -1; + debug("session_new: session %d", s->self); + + return s; } static void session_dump(void) { int i; - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; - debug("dump: used %d session %d %p channel %d pid %ld", + + debug("dump: used %d next_unused %d session %d %p " + "channel %d pid %ld", s->used, + s->next_unused, s->self, s, s->chanid, @@ -1755,7 +1982,7 @@ Session * session_by_tty(char *tty) { int i; - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { debug("session_by_tty: session %d tty %s", i, tty); @@ -1771,10 +1998,11 @@ static Session * session_by_channel(int id) { int i; - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->chanid == id) { - debug("session_by_channel: session %d channel %d", i, id); + debug("session_by_channel: session %d channel %d", + i, id); return s; } } @@ -1788,7 +2016,7 @@ session_by_x11_channel(int id) { int i, j; - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->x11_chanids == NULL || !s->used) @@ -1811,7 +2039,7 @@ session_by_pid(pid_t pid) { int i; debug("session_by_pid: pid %ld", (long)pid); - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->pid == pid) return s; @@ -1867,7 +2095,8 @@ session_pty_req(Session *s) /* Allocate a pty and open it. */ debug("Allocating pty."); - if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { + if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, + sizeof(s->tty)))) { if (s->term) xfree(s->term); s->term = NULL; @@ -1910,15 +2139,17 @@ session_subsystem_req(Session *s) if (strcmp(subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; - if (stat(prog, &st) < 0) { + if (!strcmp(INTERNAL_SFTP_NAME, prog)) { + s->is_subsystem = SUBSYSTEM_INT_SFTP; + } else if (stat(prog, &st) < 0) { error("subsystem: cannot stat %s: %s", prog, strerror(errno)); break; + } else { + s->is_subsystem = SUBSYSTEM_EXT; } debug("subsystem: exec() %s", cmd); - s->is_subsystem = 1; - do_exec(s, cmd); - success = 1; + success = do_exec(s, cmd) == 0; break; } } @@ -1961,19 +2192,19 @@ static int session_shell_req(Session *s) { packet_check_eom(); - do_exec(s, NULL); - return 1; + return do_exec(s, NULL) == 0; } static int session_exec_req(Session *s) { - u_int len; + u_int len, success; + char *command = packet_get_string(&len); packet_check_eom(); - do_exec(s, command); + success = do_exec(s, command) == 0; xfree(command); - return 1; + return success; } static int @@ -1983,8 +2214,7 @@ session_break_req(Session *s) packet_get_int(); /* ignored */ packet_check_eom(); - if (s->ttyfd == -1 || - tcsendbreak(s->ttyfd, 0) < 0) + if (s->ttyfd == -1 || tcsendbreak(s->ttyfd, 0) < 0) return 0; return 1; } @@ -2029,7 +2259,7 @@ session_auth_agent_req(Session *s) { static int called = 0; packet_check_eom(); - if (no_agent_forwarding_flag) { + if (no_agent_forwarding_flag || !options.allow_agent_forwarding) { debug("session_auth_agent_req: no_agent_forwarding_flag"); return 0; } @@ -2064,7 +2294,7 @@ session_input_channel_req(Channel *c, const char *rtype) } else if (strcmp(rtype, "exec") == 0) { success = session_exec_req(s); } else if (strcmp(rtype, "pty-req") == 0) { - success = session_pty_req(s); + success = session_pty_req(s); } else if (strcmp(rtype, "x11-req") == 0) { success = session_x11_req(s); } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { @@ -2085,7 +2315,7 @@ session_input_channel_req(Channel *c, const char *rtype) } void -session_set_fds(Session *s, int fdin, int fdout, int fderr) +session_set_fds(Session *s, int fdin, int fdout, int fderr, int is_tty) { if (!compat20) fatal("session_set_fds: called for proto != 2.0"); @@ -2098,8 +2328,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr) channel_set_fds(s->chanid, fdout, fdin, fderr, fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, - 1, - CHAN_SES_WINDOW_DEFAULT); + 1, is_tty, CHAN_SES_WINDOW_DEFAULT); } /* @@ -2131,8 +2360,9 @@ session_pty_cleanup2(Session *s) * the pty cleanup, so that another process doesn't get this pty * while we're still cleaning up. */ - if (close(s->ptymaster) < 0) - error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); + if (s->ptymaster != -1 && close(s->ptymaster) < 0) + error("close(s->ptymaster/%d): %s", + s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; @@ -2189,7 +2419,7 @@ session_close_single_x11(int id, void *arg) debug3("session_close_single_x11: channel %d", id); channel_cancel_cleanup(id); - if ((s = session_by_x11_channel(id)) == NULL) + if ((s = session_by_x11_channel(id)) == NULL) fatal("session_close_single_x11: no x11 channel %d", id); for (i = 0; s->x11_chanids[i] != -1; i++) { debug("session_close_single_x11: session %d: " @@ -2240,7 +2470,7 @@ session_exit_message(Session *s, int status) channel_request_start(s->chanid, "exit-signal", 0); packet_put_cstring(sig2name(WTERMSIG(status))); #ifdef WCOREDUMP - packet_put_char(WCOREDUMP(status)); + packet_put_char(WCOREDUMP(status)? 1 : 0); #else /* WCOREDUMP */ packet_put_char(0); #endif /* WCOREDUMP */ @@ -2292,7 +2522,6 @@ session_close(Session *s) xfree(s->auth_data); if (s->auth_proto) xfree(s->auth_proto); - s->used = 0; if (s->env != NULL) { for (i = 0; i < s->num_env; i++) { xfree(s->env[i].name); @@ -2301,6 +2530,7 @@ session_close(Session *s) xfree(s->env); } session_proctitle(s); + session_unused(s->self); } void @@ -2364,7 +2594,7 @@ void session_destroy_all(void (*closefunc)(Session *)) { int i; - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used) { if (closefunc != NULL) @@ -2383,7 +2613,7 @@ session_tty_list(void) char *cp; buf[0] = '\0'; - for (i = 0; i < MAX_SESSIONS; i++) { + for (i = 0; i < sessions_nalloc; i++) { Session *s = &sessions[i]; if (s->used && s->ttyfd != -1) { @@ -2515,8 +2745,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) @@ -2528,13 +2769,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/crypto/openssh/session.h b/crypto/openssh/session.h index ee9338e..cbb8e3a 100644 --- a/crypto/openssh/session.h +++ b/crypto/openssh/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: session.h,v 1.30 2008/05/08 12:21:16 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -31,6 +31,7 @@ typedef struct Session Session; struct Session { int used; int self; + int next_unused; struct passwd *pw; Authctxt *authctxt; pid_t pid; @@ -65,6 +66,7 @@ void do_authenticated(Authctxt *); void do_cleanup(Authctxt *); int session_open(Authctxt *, int); +void session_unused(int); int session_input_channel_req(Channel *, const char *); void session_close_by_pid(pid_t, int); void session_close_by_channel(int, void *); diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c index 42eb2b4..5e39aa7 100644 --- a/crypto/openssh/sftp-client.c +++ b/crypto/openssh/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.75 2006/10/22 02:25:50 djm Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.86 2008/06/26 06:10:09 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> * @@ -24,6 +24,9 @@ #include <sys/types.h> #include <sys/param.h> +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#endif #include "openbsd-compat/sys-queue.h" #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> @@ -65,6 +68,10 @@ struct sftp_conn { u_int num_requests; u_int version; u_int msg_id; +#define SFTP_EXT_POSIX_RENAME 0x00000001 +#define SFTP_EXT_STATVFS 0x00000002 +#define SFTP_EXT_FSTATVFS 0x00000004 + u_int exts; }; static void @@ -236,10 +243,61 @@ get_decode_stat(int fd, u_int expected_id, int quiet) return(a); } +static int +get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id, + int quiet) +{ + Buffer msg; + u_int type, id, flag; + + buffer_init(&msg); + get_msg(fd, &msg); + + type = buffer_get_char(&msg); + id = buffer_get_int(&msg); + + debug3("Received statvfs reply T:%u I:%u", type, id); + if (id != expected_id) + fatal("ID mismatch (%u != %u)", id, expected_id); + if (type == SSH2_FXP_STATUS) { + int status = buffer_get_int(&msg); + + if (quiet) + debug("Couldn't statvfs: %s", fx2txt(status)); + else + error("Couldn't statvfs: %s", fx2txt(status)); + buffer_free(&msg); + return -1; + } else if (type != SSH2_FXP_EXTENDED_REPLY) { + fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", + SSH2_FXP_EXTENDED_REPLY, type); + } + + bzero(st, sizeof(*st)); + st->f_bsize = buffer_get_int64(&msg); + st->f_frsize = buffer_get_int64(&msg); + st->f_blocks = buffer_get_int64(&msg); + st->f_bfree = buffer_get_int64(&msg); + st->f_bavail = buffer_get_int64(&msg); + st->f_files = buffer_get_int64(&msg); + st->f_ffree = buffer_get_int64(&msg); + st->f_favail = buffer_get_int64(&msg); + st->f_fsid = buffer_get_int64(&msg); + flag = buffer_get_int64(&msg); + st->f_namemax = buffer_get_int64(&msg); + + st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; + st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; + + buffer_free(&msg); + + return 0; +} + struct sftp_conn * do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) { - u_int type; + u_int type, exts = 0; int version; Buffer msg; struct sftp_conn *ret; @@ -268,8 +326,27 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) while (buffer_len(&msg) > 0) { char *name = buffer_get_string(&msg, NULL); char *value = buffer_get_string(&msg, NULL); - - debug2("Init extension: \"%s\"", name); + int known = 0; + + if (strcmp(name, "posix-rename@openssh.com") == 0 && + strcmp(value, "1") == 0) { + exts |= SFTP_EXT_POSIX_RENAME; + known = 1; + } else if (strcmp(name, "statvfs@openssh.com") == 0 && + strcmp(value, "2") == 0) { + exts |= SFTP_EXT_STATVFS; + known = 1; + } if (strcmp(name, "fstatvfs@openssh.com") == 0 && + strcmp(value, "2") == 0) { + exts |= SFTP_EXT_FSTATVFS; + known = 1; + } + if (known) { + debug2("Server supports extension \"%s\" revision %s", + name, value); + } else { + debug2("Unrecognised server extension \"%s\"", name); + } xfree(name); xfree(value); } @@ -283,6 +360,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) ret->num_requests = num_requests; ret->version = version; ret->msg_id = 1; + ret->exts = exts; /* Some filexfer v.0 servers don't support large packets */ if (version == 0) @@ -534,6 +612,7 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) return(get_decode_stat(conn->fd_in, id, quiet)); } +#ifdef notyet Attrib * do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) { @@ -545,6 +624,7 @@ do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet) return(get_decode_stat(conn->fd_in, id, quiet)); } +#endif int do_setstat(struct sftp_conn *conn, char *path, Attrib *a) @@ -637,13 +717,20 @@ do_rename(struct sftp_conn *conn, char *oldpath, char *newpath) /* Send rename request */ id = conn->msg_id++; - buffer_put_char(&msg, SSH2_FXP_RENAME); - buffer_put_int(&msg, id); + if ((conn->exts & SFTP_EXT_POSIX_RENAME)) { + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "posix-rename@openssh.com"); + } else { + buffer_put_char(&msg, SSH2_FXP_RENAME); + buffer_put_int(&msg, id); + } buffer_put_cstring(&msg, oldpath); buffer_put_cstring(&msg, newpath); send_msg(conn->fd_out, &msg); - debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath, - newpath); + debug3("Sent message %s \"%s\" -> \"%s\"", + (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" : + "SSH2_FXP_RENAME", oldpath, newpath); buffer_free(&msg); status = get_status(conn->fd_in, id); @@ -686,6 +773,7 @@ do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath) return(status); } +#ifdef notyet char * do_readlink(struct sftp_conn *conn, char *path) { @@ -732,6 +820,61 @@ do_readlink(struct sftp_conn *conn, char *path) return(filename); } +#endif + +int +do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, + int quiet) +{ + Buffer msg; + u_int id; + + if ((conn->exts & SFTP_EXT_STATVFS) == 0) { + error("Server does not support statvfs@openssh.com extension"); + return -1; + } + + id = conn->msg_id++; + + buffer_init(&msg); + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "statvfs@openssh.com"); + buffer_put_cstring(&msg, path); + send_msg(conn->fd_out, &msg); + buffer_free(&msg); + + return get_decode_statvfs(conn->fd_in, st, id, quiet); +} + +#ifdef notyet +int +do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, + struct sftp_statvfs *st, int quiet) +{ + Buffer msg; + u_int id; + + if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) { + error("Server does not support fstatvfs@openssh.com extension"); + return -1; + } + + id = conn->msg_id++; + + buffer_init(&msg); + buffer_clear(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED); + buffer_put_int(&msg, id); + buffer_put_cstring(&msg, "fstatvfs@openssh.com"); + buffer_put_string(&msg, handle, handle_len); + send_msg(conn->fd_out, &msg); + buffer_free(&msg); + + return get_decode_statvfs(conn->fd_in, st, id, quiet); +} +#endif static void send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, @@ -777,7 +920,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, if (a == NULL) return(-1); - /* XXX: should we preserve set[ug]id? */ + /* Do not preserve set[ug]id here, as we do not preserve ownership */ if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) mode = a->perm & 0777; else @@ -819,6 +962,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, if (local_fd == -1) { error("Couldn't open local file \"%s\" for writing: %s", local_path, strerror(errno)); + do_close(conn, handle, handle_len); buffer_free(&msg); xfree(handle); return(-1); @@ -992,9 +1136,10 @@ int do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, int pflag) { - int local_fd, status; + int local_fd; + int status = SSH2_FX_OK; u_int handle_len, id, type; - u_int64_t offset; + off_t offset; char *handle, *data; Buffer msg; struct stat sb; @@ -1004,7 +1149,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, struct outstanding_ack { u_int id; u_int len; - u_int64_t offset; + off_t offset; TAILQ_ENTRY(outstanding_ack) tq; }; TAILQ_HEAD(ackhead, outstanding_ack) acks; @@ -1054,7 +1199,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, if (handle == NULL) { close(local_fd); buffer_free(&msg); - return(-1); + return -1; } startid = ackid = id + 1; @@ -1074,11 +1219,12 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, * Simulate an EOF on interrupt, allowing ACKs from the * server to drain. */ - if (interrupted) + if (interrupted || status != SSH2_FX_OK) len = 0; else do len = read(local_fd, data, conn->transfer_buflen); - while ((len == -1) && (errno == EINTR || errno == EAGAIN)); + while ((len == -1) && + (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)); if (len == -1) fatal("Couldn't read from \"%s\": %s", local_path, @@ -1130,45 +1276,40 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path, if (ack == NULL) fatal("Can't find request for ID %u", r_id); TAILQ_REMOVE(&acks, ack, tq); - - if (status != SSH2_FX_OK) { - error("Couldn't write to remote file \"%s\": %s", - remote_path, fx2txt(status)); - if (showprogress) - stop_progress_meter(); - do_close(conn, handle, handle_len); - close(local_fd); - xfree(data); - xfree(ack); - goto done; - } - debug3("In write loop, ack for %u %u bytes at %llu", - ack->id, ack->len, (unsigned long long)ack->offset); + debug3("In write loop, ack for %u %u bytes at %lld", + ack->id, ack->len, (long long)ack->offset); ++ackid; xfree(ack); } offset += len; + if (offset < 0) + fatal("%s: offset < 0", __func__); } + buffer_free(&msg); + if (showprogress) stop_progress_meter(); xfree(data); + if (status != SSH2_FX_OK) { + error("Couldn't write to remote file \"%s\": %s", + remote_path, fx2txt(status)); + status = -1; + } + if (close(local_fd) == -1) { error("Couldn't close local file \"%s\": %s", local_path, strerror(errno)); - do_close(conn, handle, handle_len); status = -1; - goto done; } /* Override umask and utimes if asked */ if (pflag) do_fsetstat(conn, handle, handle_len, &a); - status = do_close(conn, handle, handle_len); - -done: + if (do_close(conn, handle, handle_len) != SSH2_FX_OK) + status = -1; xfree(handle); - buffer_free(&msg); - return(status); + + return status; } diff --git a/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h index c8a41f3..edb4679 100644 --- a/crypto/openssh/sftp-client.h +++ b/crypto/openssh/sftp-client.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.h,v 1.14 2005/04/26 12:59:02 jmc Exp $ */ +/* $OpenBSD: sftp-client.h,v 1.17 2008/06/08 20:15:29 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> @@ -30,6 +30,24 @@ struct SFTP_DIRENT { }; /* + * Used for statvfs responses on the wire from the server, because the + * server's native format may be larger than the client's. + */ +struct sftp_statvfs { + u_int64_t f_bsize; + u_int64_t f_frsize; + u_int64_t f_blocks; + u_int64_t f_bfree; + u_int64_t f_bavail; + u_int64_t f_files; + u_int64_t f_ffree; + u_int64_t f_favail; + u_int64_t f_fsid; + u_int64_t f_flag; + u_int64_t f_namemax; +}; + +/* * Initialise a SSH filexfer connection. Returns NULL on error or * a pointer to a initialized sftp_conn struct on success. */ @@ -61,9 +79,6 @@ Attrib *do_stat(struct sftp_conn *, char *, int); /* Get file attributes of 'path' (does not follow symlinks) */ Attrib *do_lstat(struct sftp_conn *, char *, int); -/* Get file attributes of open file 'handle' */ -Attrib *do_fstat(struct sftp_conn *, char *, u_int, int); - /* Set file attributes of 'path' */ int do_setstat(struct sftp_conn *, char *, Attrib *); @@ -73,15 +88,15 @@ int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *); /* Canonicalise 'path' - caller must free result */ char *do_realpath(struct sftp_conn *, char *); +/* Get statistics for filesystem hosting file at "path" */ +int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int); + /* Rename 'oldpath' to 'newpath' */ int do_rename(struct sftp_conn *, char *, char *); /* Rename 'oldpath' to 'newpath' */ int do_symlink(struct sftp_conn *, char *, char *); -/* Return target of symlink 'path' - caller must free result */ -char *do_readlink(struct sftp_conn *, char *); - /* XXX: add callbacks to do_download/do_upload so we can do progress meter */ /* diff --git a/crypto/openssh/sftp-server-main.c b/crypto/openssh/sftp-server-main.c new file mode 100644 index 0000000..2b14569 --- /dev/null +++ b/crypto/openssh/sftp-server-main.c @@ -0,0 +1,50 @@ +/* $OpenBSD: sftp-server-main.c,v 1.3 2008/03/26 23:44:41 djm Exp $ */ +/* + * Copyright (c) 2008 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <pwd.h> +#include <stdarg.h> +#include <stdio.h> +#include <unistd.h> + +#include "log.h" +#include "sftp.h" +#include "misc.h" + +void +cleanup_exit(int i) +{ + sftp_server_cleanup_exit(i); +} + +int +main(int argc, char **argv) +{ + struct passwd *user_pw; + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + if ((user_pw = getpwuid(getuid())) == NULL) { + fprintf(stderr, "No user found for uid %lu", (u_long)getuid()); + return 1; + } + + return (sftp_server_main(argc, argv, user_pw)); +} diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8 index 199c4f3..74c1e4b 100644 --- a/crypto/openssh/sftp-server.8 +++ b/crypto/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.14 2008/07/18 22:51:01 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: July 18 2008 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -72,6 +72,16 @@ DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. .El +.Pp +For logging to work, +.Nm +must be able to access +.Pa /dev/log . +Use of +.Nm +in a chroot configuation therefore requires that +.Xr syslogd 8 +establish a logging socket inside the chroot directory. .Sh SEE ALSO .Xr sftp 1 , .Xr ssh 1 , diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c index c57958b..24c4ff7 100644 --- a/crypto/openssh/sftp-server.c +++ b/crypto/openssh/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.70 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.84 2008/06/26 06:10:09 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -23,6 +23,12 @@ #ifdef HAVE_SYS_TIME_H # include <sys/time.h> #endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#endif #include <dirent.h> #include <errno.h> @@ -98,6 +104,9 @@ errno_to_portable(int unixerrno) case EINVAL: ret = SSH2_FX_BAD_MESSAGE; break; + case ENOSYS: + ret = SSH2_FX_OP_UNSUPPORTED; + break; default: ret = SSH2_FX_FAILURE; break; @@ -169,6 +178,7 @@ struct Handle { int fd; char *name; u_int64_t bytes_read, bytes_write; + int next_unused; }; enum { @@ -177,40 +187,46 @@ enum { HANDLE_FILE }; -Handle handles[100]; +Handle *handles = NULL; +u_int num_handles = 0; +int first_unused_handle = -1; -static void -handle_init(void) +static void handle_unused(int i) { - u_int i; - - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) - handles[i].use = HANDLE_UNUSED; + handles[i].use = HANDLE_UNUSED; + handles[i].next_unused = first_unused_handle; + first_unused_handle = i; } static int handle_new(int use, const char *name, int fd, DIR *dirp) { - u_int i; + int i; - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) { - if (handles[i].use == HANDLE_UNUSED) { - handles[i].use = use; - handles[i].dirp = dirp; - handles[i].fd = fd; - handles[i].name = xstrdup(name); - handles[i].bytes_read = handles[i].bytes_write = 0; - return i; - } + if (first_unused_handle == -1) { + if (num_handles + 1 <= num_handles) + return -1; + num_handles++; + handles = xrealloc(handles, num_handles, sizeof(Handle)); + handle_unused(num_handles - 1); } - return -1; + + i = first_unused_handle; + first_unused_handle = handles[i].next_unused; + + handles[i].use = use; + handles[i].dirp = dirp; + handles[i].fd = fd; + handles[i].name = xstrdup(name); + handles[i].bytes_read = handles[i].bytes_write = 0; + + return i; } static int handle_is_ok(int i, int type) { - return i >= 0 && (u_int)i < sizeof(handles)/sizeof(Handle) && - handles[i].use == type; + return i >= 0 && (u_int)i < num_handles && handles[i].use == type; } static int @@ -300,12 +316,12 @@ handle_close(int handle) if (handle_is_ok(handle, HANDLE_FILE)) { ret = close(handles[handle].fd); - handles[handle].use = HANDLE_UNUSED; xfree(handles[handle].name); + handle_unused(handle); } else if (handle_is_ok(handle, HANDLE_DIR)) { ret = closedir(handles[handle].dirp); - handles[handle].use = HANDLE_UNUSED; xfree(handles[handle].name); + handle_unused(handle); } else { errno = ENOENT; } @@ -319,7 +335,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 ? "" : " ", @@ -332,7 +349,7 @@ handle_log_exit(void) { u_int i; - for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) + for (i = 0; i < num_handles; i++) if (handles[i].use != HANDLE_UNUSED) handle_log_close(i, "forced"); } @@ -467,6 +484,33 @@ send_attrib(u_int32_t id, const Attrib *a) buffer_free(&msg); } +static void +send_statvfs(u_int32_t id, struct statvfs *st) +{ + Buffer msg; + u_int64_t flag; + + flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; + flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); + buffer_put_int(&msg, id); + buffer_put_int64(&msg, st->f_bsize); + buffer_put_int64(&msg, st->f_frsize); + buffer_put_int64(&msg, st->f_blocks); + buffer_put_int64(&msg, st->f_bfree); + buffer_put_int64(&msg, st->f_bavail); + buffer_put_int64(&msg, st->f_files); + buffer_put_int64(&msg, st->f_ffree); + buffer_put_int64(&msg, st->f_favail); + buffer_put_int64(&msg, FSID_TO_ULONG(st->f_fsid)); + buffer_put_int64(&msg, flag); + buffer_put_int64(&msg, st->f_namemax); + send_msg(&msg); + buffer_free(&msg); +} + /* parse incoming */ static void @@ -479,6 +523,15 @@ process_init(void) buffer_init(&msg); buffer_put_char(&msg, SSH2_FXP_VERSION); buffer_put_int(&msg, SSH2_FILEXFER_VERSION); + /* POSIX rename extension */ + buffer_put_cstring(&msg, "posix-rename@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ + /* statvfs extension */ + buffer_put_cstring(&msg, "statvfs@openssh.com"); + buffer_put_cstring(&msg, "2"); /* version */ + /* fstatvfs extension */ + buffer_put_cstring(&msg, "fstatvfs@openssh.com"); + buffer_put_cstring(&msg, "2"); /* version */ send_msg(&msg); buffer_free(&msg); } @@ -663,7 +716,7 @@ process_fstat(void) debug("request %u: fstat \"%s\" (handle %u)", id, handle_to_name(handle), handle); fd = handle_to_fd(handle); - if (fd >= 0) { + if (fd >= 0) { ret = fstat(fd, &st); if (ret < 0) { status = errno_to_portable(errno); @@ -702,14 +755,15 @@ 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); } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a->perm); - ret = chmod(name, a->perm & 0777); + ret = chmod(name, a->perm & 07777); if (ret == -1) status = errno_to_portable(errno); } @@ -754,7 +808,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); @@ -762,9 +817,9 @@ process_fsetstat(void) if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { logit("set \"%s\" mode %04o", name, a->perm); #ifdef HAVE_FCHMOD - ret = fchmod(fd, a->perm & 0777); + ret = fchmod(fd, a->perm & 07777); #else - ret = chmod(name, a->perm & 0777); + ret = chmod(name, a->perm & 07777); #endif if (ret == -1) status = errno_to_portable(errno); @@ -915,7 +970,7 @@ process_mkdir(void) name = get_string(NULL); a = get_attrib(); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? - a->perm & 0777 : 0777; + a->perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); ret = mkdir(name, mode); @@ -987,6 +1042,9 @@ process_rename(void) /* Race-free rename of regular files */ if (link(oldpath, newpath) == -1) { if (errno == EOPNOTSUPP +#ifdef EXDEV + || errno == EXDEV +#endif #ifdef LINK_OPNOTSUPP_ERRNO || errno == LINK_OPNOTSUPP_ERRNO #endif @@ -1070,6 +1128,59 @@ process_symlink(void) } static void +process_extended_posix_rename(u_int32_t id) +{ + char *oldpath, *newpath; + + oldpath = get_string(NULL); + newpath = get_string(NULL); + debug3("request %u: posix-rename", id); + logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); + if (rename(oldpath, newpath) == -1) + send_status(id, errno_to_portable(errno)); + else + send_status(id, SSH2_FX_OK); + xfree(oldpath); + xfree(newpath); +} + +static void +process_extended_statvfs(u_int32_t id) +{ + char *path; + struct statvfs st; + + path = get_string(NULL); + debug3("request %u: statfs", id); + logit("statfs \"%s\"", path); + + if (statvfs(path, &st) != 0) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); + xfree(path); +} + +static void +process_extended_fstatvfs(u_int32_t id) +{ + int handle, fd; + struct statvfs st; + + handle = get_handle(); + debug("request %u: fstatvfs \"%s\" (handle %u)", + id, handle_to_name(handle), handle); + if ((fd = handle_to_fd(handle)) < 0) { + send_status(id, SSH2_FX_FAILURE); + return; + } + if (fstatvfs(fd, &st) != 0) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); +} + +static void process_extended(void) { u_int32_t id; @@ -1077,7 +1188,14 @@ process_extended(void) id = get_int(); request = get_string(NULL); - send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ + if (strcmp(request, "posix-rename@openssh.com") == 0) + process_extended_posix_rename(id); + else if (strcmp(request, "statvfs@openssh.com") == 0) + process_extended_statvfs(id); + else if (strcmp(request, "fstatvfs@openssh.com") == 0) + process_extended_fstatvfs(id); + else + send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); } @@ -1100,7 +1218,7 @@ process(void) if (msg_len > SFTP_MAX_MSG_LENGTH) { error("bad message from %s local user %s", client_addr, pw->pw_name); - cleanup_exit(11); + sftp_server_cleanup_exit(11); } if (buf_len < msg_len + 4) return; @@ -1173,18 +1291,22 @@ process(void) break; } /* discard the remaining bytes from the current packet */ - if (buf_len < buffer_len(&iqueue)) - fatal("iqueue grew unexpectedly"); + if (buf_len < buffer_len(&iqueue)) { + error("iqueue grew unexpectedly"); + sftp_server_cleanup_exit(255); + } consumed = buf_len - buffer_len(&iqueue); - if (msg_len < consumed) - fatal("msg_len %d < consumed %d", msg_len, consumed); + if (msg_len < consumed) { + error("msg_len %d < consumed %d", msg_len, consumed); + sftp_server_cleanup_exit(255); + } if (msg_len > consumed) buffer_consume(&iqueue, msg_len - consumed); } /* Cleanup handler that logs active handles upon normal exit */ void -cleanup_exit(int i) +sftp_server_cleanup_exit(int i) { if (pw != NULL && client_addr != NULL) { handle_log_exit(); @@ -1195,7 +1317,7 @@ cleanup_exit(int i) } static void -usage(void) +sftp_server_usage(void) { extern char *__progname; @@ -1205,20 +1327,17 @@ usage(void) } int -main(int argc, char **argv) +sftp_server_main(int argc, char **argv, struct passwd *user_pw) { fd_set *rset, *wset; 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; - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); @@ -1241,12 +1360,12 @@ main(int argc, char **argv) break; case 'f': log_facility = log_facility_number(optarg); - if (log_level == SYSLOG_FACILITY_NOT_SET) + if (log_facility == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; case 'h': default: - usage(); + sftp_server_usage(); } } @@ -1254,22 +1373,20 @@ main(int argc, char **argv) if ((cp = getenv("SSH_CONNECTION")) != NULL) { client_addr = xstrdup(cp); - if ((cp = strchr(client_addr, ' ')) == NULL) - fatal("Malformed SSH_CONNECTION variable: \"%s\"", + if ((cp = strchr(client_addr, ' ')) == NULL) { + error("Malformed SSH_CONNECTION variable: \"%s\"", getenv("SSH_CONNECTION")); + sftp_server_cleanup_exit(255); + } *cp = '\0'; } else client_addr = xstrdup("UNKNOWN"); - if ((pw = getpwuid(getuid())) == NULL) - fatal("No user found for uid %lu", (u_long)getuid()); - pw = pwcopy(pw); + pw = pwcopy(user_pw); logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); - handle_init(); - in = dup(STDIN_FILENO); out = dup(STDOUT_FILENO); @@ -1295,7 +1412,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); @@ -1304,19 +1429,18 @@ main(int argc, char **argv) if (errno == EINTR) continue; error("select: %s", strerror(errno)); - cleanup_exit(2); + sftp_server_cleanup_exit(2); } /* 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"); - cleanup_exit(0); + sftp_server_cleanup_exit(0); } else if (len < 0) { error("read: %s", strerror(errno)); - cleanup_exit(1); + sftp_server_cleanup_exit(1); } else { buffer_append(&iqueue, buf, len); } @@ -1326,12 +1450,18 @@ main(int argc, char **argv) len = write(out, buffer_ptr(&oqueue), olen); if (len < 0) { error("write: %s", strerror(errno)); - cleanup_exit(1); + sftp_server_cleanup_exit(1); } else { 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/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1 index 47aafa8..b4f9a68 100644 --- a/crypto/openssh/sftp.1 +++ b/crypto/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.67 2008/07/15 02:23:14 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd February 4, 2001 +.Dd $Mdocdate: July 15 2008 $ .Dt SFTP 1 .Os .Sh NAME @@ -112,7 +112,8 @@ will abort if any of the following commands fail: .Ic get , put , rename , ln , .Ic rm , mkdir , chdir , ls , -.Ic lchdir , chmod , chown , chgrp , lpwd +.Ic lchdir , chmod , chown , +.Ic chgrp , lpwd , df , and .Ic lmkdir . Termination on error can be suppressed on a command by command basis by @@ -203,7 +204,7 @@ This option may be useful in debugging the client and server. Specify how many requests may be outstanding at any one time. Increasing this may slightly improve file transfer speed but will increase memory usage. -The default is 16 outstanding requests. +The default is 64 outstanding requests. .It Fl S Ar program Name of the .Ar program @@ -272,6 +273,24 @@ may contain characters and may match multiple files. .Ar own must be a numeric UID. +.It Xo Ic df +.Op Fl hi +.Op Ar path +.Xc +Display usage information for the filesystem holding the current directory +(or +.Ar path +if specified). +If the +.Fl h +flag is specified, the capacity information will be displayed using +"human-readable" suffixes. +The +.Fl i +flag requests display of inode information in addition to capacity information. +This command is only supported on servers that implement the +.Dq statvfs@openssh.com +extension. .It Ic exit Quit .Nm sftp . diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c index a39c782..e1aa49d 100644 --- a/crypto/openssh/sftp.c +++ b/crypto/openssh/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.93 2006/09/30 17:48:22 ray Exp $ */ +/* $OpenBSD: sftp.c,v 1.103 2008/07/13 22:16:03 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> * @@ -25,7 +25,11 @@ #include <sys/param.h> #include <sys/socket.h> #include <sys/wait.h> +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#endif +#include <ctype.h> #include <errno.h> #ifdef HAVE_PATHS_H @@ -43,6 +47,14 @@ typedef void EditLine; #include <unistd.h> #include <stdarg.h> +#ifdef HAVE_UTIL_H +# include <util.h> +#endif + +#ifdef HAVE_LIBUTIL_H +# include <libutil.h> +#endif + #include "xmalloc.h" #include "log.h" #include "pathnames.h" @@ -63,7 +75,7 @@ int batchmode = 0; size_t copy_buffer_len = 32768; /* Number of concurrent outstanding requests */ -size_t num_requests = 16; +size_t num_requests = 64; /* PID of ssh transport process */ static pid_t sshpid = -1; @@ -103,6 +115,7 @@ extern char *__progname; #define I_CHGRP 2 #define I_CHMOD 3 #define I_CHOWN 4 +#define I_DF 24 #define I_GET 5 #define I_HELP 6 #define I_LCHDIR 7 @@ -135,6 +148,7 @@ static const struct CMD cmds[] = { { "chgrp", I_CHGRP }, { "chmod", I_CHMOD }, { "chown", I_CHOWN }, + { "df", I_DF }, { "dir", I_LS }, { "exit", I_QUIT }, { "get", I_GET }, @@ -166,6 +180,7 @@ static const struct CMD cmds[] = { int interactive_loop(int fd_in, int fd_out, char *file1, char *file2); +/* ARGSUSED */ static void killchild(int signo) { @@ -177,6 +192,7 @@ killchild(int signo) _exit(1); } +/* ARGSUSED */ static void cmd_interrupt(int signo) { @@ -197,6 +213,8 @@ help(void) printf("chgrp grp path Change group of file 'path' to 'grp'\n"); printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); printf("chown own path Change owner of file 'path' to 'own'\n"); + printf("df [path] Display statistics for current directory or\n"); + printf(" filesystem containing 'path'\n"); printf("help Display this help text\n"); printf("get remote-path [local-path] Download file\n"); printf("lls [ls-options [path]] Display local directory listing\n"); @@ -298,11 +316,11 @@ static char * path_append(char *p1, char *p2) { char *ret; - int len = strlen(p1) + strlen(p2) + 2; + size_t len = strlen(p1) + strlen(p2) + 2; ret = xmalloc(len); strlcpy(ret, p1, len); - if (p1[strlen(p1) - 1] != '/') + if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/') strlcat(ret, "/", len); strlcat(ret, p2, len); @@ -344,144 +362,105 @@ infer_path(const char *p, char **ifp) } static int -parse_getput_flags(const char **cpp, int *pflag) +parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag) { - const char *cp = *cpp; + extern int opterr, optind, optopt, optreset; + int ch; - /* Check for flags */ - if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) { - switch (cp[1]) { + optind = optreset = 1; + opterr = 0; + + *pflag = 0; + while ((ch = getopt(argc, argv, "Pp")) != -1) { + switch (ch) { case 'p': case 'P': *pflag = 1; break; default: - error("Invalid flag -%c", cp[1]); - return(-1); + error("%s: Invalid flag -%c", cmd, optopt); + return -1; } - cp += 2; - *cpp = cp + strspn(cp, WHITESPACE); } - return(0); + return optind; } static int -parse_ls_flags(const char **cpp, int *lflag) +parse_ls_flags(char **argv, int argc, int *lflag) { - const char *cp = *cpp; + extern int opterr, optind, optopt, optreset; + int ch; - /* Defaults */ - *lflag = LS_NAME_SORT; + optind = optreset = 1; + opterr = 0; - /* Check for flags */ - if (cp++[0] == '-') { - for (; strchr(WHITESPACE, *cp) == NULL; cp++) { - switch (*cp) { - case 'l': - *lflag &= ~VIEW_FLAGS; - *lflag |= LS_LONG_VIEW; - break; - case '1': - *lflag &= ~VIEW_FLAGS; - *lflag |= LS_SHORT_VIEW; - break; - case 'n': - *lflag &= ~VIEW_FLAGS; - *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; - break; - case 'S': - *lflag &= ~SORT_FLAGS; - *lflag |= LS_SIZE_SORT; - break; - case 't': - *lflag &= ~SORT_FLAGS; - *lflag |= LS_TIME_SORT; - break; - case 'r': - *lflag |= LS_REVERSE_SORT; - break; - case 'f': - *lflag &= ~SORT_FLAGS; - break; - case 'a': - *lflag |= LS_SHOW_ALL; - break; - default: - error("Invalid flag -%c", *cp); - return(-1); - } + *lflag = LS_NAME_SORT; + while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) { + switch (ch) { + case '1': + *lflag &= ~VIEW_FLAGS; + *lflag |= LS_SHORT_VIEW; + break; + case 'S': + *lflag &= ~SORT_FLAGS; + *lflag |= LS_SIZE_SORT; + break; + case 'a': + *lflag |= LS_SHOW_ALL; + break; + case 'f': + *lflag &= ~SORT_FLAGS; + break; + case 'l': + *lflag &= ~VIEW_FLAGS; + *lflag |= LS_LONG_VIEW; + break; + case 'n': + *lflag &= ~VIEW_FLAGS; + *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; + break; + case 'r': + *lflag |= LS_REVERSE_SORT; + break; + case 't': + *lflag &= ~SORT_FLAGS; + *lflag |= LS_TIME_SORT; + break; + default: + error("ls: Invalid flag -%c", optopt); + return -1; } - *cpp = cp + strspn(cp, WHITESPACE); } - return(0); + return optind; } static int -get_pathname(const char **cpp, char **path) +parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag) { - const char *cp = *cpp, *end; - char quot; - u_int i, j; - - cp += strspn(cp, WHITESPACE); - if (!*cp) { - *cpp = cp; - *path = NULL; - return (0); - } - - *path = xmalloc(strlen(cp) + 1); - - /* Check for quoted filenames */ - if (*cp == '\"' || *cp == '\'') { - quot = *cp++; + extern int opterr, optind, optopt, optreset; + int ch; - /* Search for terminating quote, unescape some chars */ - for (i = j = 0; i <= strlen(cp); i++) { - if (cp[i] == quot) { /* Found quote */ - i++; - (*path)[j] = '\0'; - break; - } - if (cp[i] == '\0') { /* End of string */ - error("Unterminated quote"); - goto fail; - } - if (cp[i] == '\\') { /* Escaped characters */ - i++; - if (cp[i] != '\'' && cp[i] != '\"' && - cp[i] != '\\') { - error("Bad escaped character '\\%c'", - cp[i]); - goto fail; - } - } - (*path)[j++] = cp[i]; - } + optind = optreset = 1; + opterr = 0; - if (j == 0) { - error("Empty quotes"); - goto fail; + *hflag = *iflag = 0; + while ((ch = getopt(argc, argv, "hi")) != -1) { + switch (ch) { + case 'h': + *hflag = 1; + break; + case 'i': + *iflag = 1; + break; + default: + error("%s: Invalid flag -%c", cmd, optopt); + return -1; } - *cpp = cp + i + strspn(cp + i, WHITESPACE); - } else { - /* Read to end of filename */ - end = strpbrk(cp, WHITESPACE); - if (end == NULL) - end = strchr(cp, '\0'); - *cpp = end + strspn(end, WHITESPACE); - - memcpy(*path, cp, end - cp); - (*path)[end - cp] = '\0'; } - return (0); - fail: - xfree(*path); - *path = NULL; - return (-1); + return optind; } static int @@ -497,17 +476,6 @@ is_dir(char *path) } static int -is_reg(char *path) -{ - struct stat sb; - - if (stat(path, &sb) == -1) - fatal("stat %s: %s", path, strerror(errno)); - - return(S_ISREG(sb.st_mode)); -} - -static int remote_is_dir(struct sftp_conn *conn, char *path) { Attrib *a; @@ -595,6 +563,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) glob_t g; int err = 0; int i; + struct stat sb; if (dst) { tmp_dst = xstrdup(dst); @@ -603,7 +572,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) memset(&g, 0, sizeof(g)); debug3("Looking up %s", src); - if (glob(src, 0, NULL, &g)) { + if (glob(src, GLOB_NOCHECK, NULL, &g)) { error("File \"%s\" not found.", src); err = -1; goto out; @@ -618,7 +587,13 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) } for (i = 0; g.gl_pathv[i] && !interrupted; i++) { - if (!is_reg(g.gl_pathv[i])) { + if (stat(g.gl_pathv[i], &sb) == -1) { + err = -1; + error("stat %s: %s", g.gl_pathv[i], strerror(errno)); + continue; + } + + if (!S_ISREG(sb.st_mode)) { error("skipping non-regular file %s", g.gl_pathv[i]); continue; @@ -865,14 +840,238 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, } static int -parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, +do_df(struct sftp_conn *conn, char *path, int hflag, int iflag) +{ + struct sftp_statvfs st; + char s_used[FMT_SCALED_STRSIZE]; + char s_avail[FMT_SCALED_STRSIZE]; + char s_root[FMT_SCALED_STRSIZE]; + char s_total[FMT_SCALED_STRSIZE]; + + if (do_statvfs(conn, path, &st, 1) == -1) + return -1; + if (iflag) { + printf(" Inodes Used Avail " + "(root) %%Capacity\n"); + printf("%11llu %11llu %11llu %11llu %3llu%%\n", + (unsigned long long)st.f_files, + (unsigned long long)(st.f_files - st.f_ffree), + (unsigned long long)st.f_favail, + (unsigned long long)st.f_ffree, + (unsigned long long)(100 * (st.f_files - st.f_ffree) / + st.f_files)); + } else if (hflag) { + strlcpy(s_used, "error", sizeof(s_used)); + strlcpy(s_avail, "error", sizeof(s_avail)); + strlcpy(s_root, "error", sizeof(s_root)); + strlcpy(s_total, "error", sizeof(s_total)); + fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used); + fmt_scaled(st.f_bavail * st.f_frsize, s_avail); + fmt_scaled(st.f_bfree * st.f_frsize, s_root); + fmt_scaled(st.f_blocks * st.f_frsize, s_total); + printf(" Size Used Avail (root) %%Capacity\n"); + printf("%7sB %7sB %7sB %7sB %3llu%%\n", + s_total, s_used, s_avail, s_root, + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } else { + printf(" Size Used Avail " + "(root) %%Capacity\n"); + printf("%12llu %12llu %12llu %12llu %3llu%%\n", + (unsigned long long)(st.f_frsize * st.f_blocks / 1024), + (unsigned long long)(st.f_frsize * + (st.f_blocks - st.f_bfree) / 1024), + (unsigned long long)(st.f_frsize * st.f_bavail / 1024), + (unsigned long long)(st.f_frsize * st.f_bfree / 1024), + (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / + st.f_blocks)); + } + return 0; +} + +/* + * Undo escaping of glob sequences in place. Used to undo extra escaping + * applied in makeargv() when the string is destined for a function that + * does not glob it. + */ +static void +undo_glob_escape(char *s) +{ + size_t i, j; + + for (i = j = 0;;) { + if (s[i] == '\0') { + s[j] = '\0'; + return; + } + if (s[i] != '\\') { + s[j++] = s[i++]; + continue; + } + /* s[i] == '\\' */ + ++i; + switch (s[i]) { + case '?': + case '[': + case '*': + case '\\': + s[j++] = s[i++]; + break; + case '\0': + s[j++] = '\\'; + s[j] = '\0'; + return; + default: + s[j++] = '\\'; + s[j++] = s[i++]; + break; + } + } +} + +/* + * Split a string into an argument vector using sh(1)-style quoting, + * comment and escaping rules, but with some tweaks to handle glob(3) + * wildcards. + * Returns NULL on error or a NULL-terminated array of arguments. + */ +#define MAXARGS 128 +#define MAXARGLEN 8192 +static char ** +makeargv(const char *arg, int *argcp) +{ + int argc, quot; + size_t i, j; + static char argvs[MAXARGLEN]; + static char *argv[MAXARGS + 1]; + enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q; + + *argcp = argc = 0; + if (strlen(arg) > sizeof(argvs) - 1) { + args_too_longs: + error("string too long"); + return NULL; + } + state = MA_START; + i = j = 0; + for (;;) { + if (isspace(arg[i])) { + if (state == MA_UNQUOTED) { + /* Terminate current argument */ + argvs[j++] = '\0'; + argc++; + state = MA_START; + } else if (state != MA_START) + argvs[j++] = arg[i]; + } else if (arg[i] == '"' || arg[i] == '\'') { + q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE; + if (state == MA_START) { + argv[argc] = argvs + j; + state = q; + } else if (state == MA_UNQUOTED) + state = q; + else if (state == q) + state = MA_UNQUOTED; + else + argvs[j++] = arg[i]; + } else if (arg[i] == '\\') { + if (state == MA_SQUOTE || state == MA_DQUOTE) { + quot = state == MA_SQUOTE ? '\'' : '"'; + /* Unescape quote we are in */ + /* XXX support \n and friends? */ + if (arg[i + 1] == quot) { + i++; + argvs[j++] = arg[i]; + } else if (arg[i + 1] == '?' || + arg[i + 1] == '[' || arg[i + 1] == '*') { + /* + * Special case for sftp: append + * double-escaped glob sequence - + * glob will undo one level of + * escaping. NB. string can grow here. + */ + if (j >= sizeof(argvs) - 5) + goto args_too_longs; + argvs[j++] = '\\'; + argvs[j++] = arg[i++]; + argvs[j++] = '\\'; + argvs[j++] = arg[i]; + } else { + argvs[j++] = arg[i++]; + argvs[j++] = arg[i]; + } + } else { + if (state == MA_START) { + argv[argc] = argvs + j; + state = MA_UNQUOTED; + } + if (arg[i + 1] == '?' || arg[i + 1] == '[' || + arg[i + 1] == '*' || arg[i + 1] == '\\') { + /* + * Special case for sftp: append + * escaped glob sequence - + * glob will undo one level of + * escaping. + */ + argvs[j++] = arg[i++]; + argvs[j++] = arg[i]; + } else { + /* Unescape everything */ + /* XXX support \n and friends? */ + i++; + argvs[j++] = arg[i]; + } + } + } else if (arg[i] == '#') { + if (state == MA_SQUOTE || state == MA_DQUOTE) + argvs[j++] = arg[i]; + else + goto string_done; + } else if (arg[i] == '\0') { + if (state == MA_SQUOTE || state == MA_DQUOTE) { + error("Unterminated quoted argument"); + return NULL; + } + string_done: + if (state == MA_UNQUOTED) { + argvs[j++] = '\0'; + argc++; + } + break; + } else { + if (state == MA_START) { + argv[argc] = argvs + j; + state = MA_UNQUOTED; + } + if ((state == MA_SQUOTE || state == MA_DQUOTE) && + (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) { + /* + * Special case for sftp: escape quoted + * glob(3) wildcards. NB. string can grow + * here. + */ + if (j >= sizeof(argvs) - 3) + goto args_too_longs; + argvs[j++] = '\\'; + argvs[j++] = arg[i]; + } else + argvs[j++] = arg[i]; + } + i++; + } + *argcp = argc; + return argv; +} + +static int +parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag, unsigned long *n_arg, char **path1, char **path2) { const char *cmd, *cp = *cpp; - char *cp2; + char *cp2, **argv; int base = 0; long l; - int i, cmdnum; + int i, cmdnum, optidx, argc; /* Skip leading whitespace */ cp = cp + strspn(cp, WHITESPACE); @@ -888,17 +1087,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, cp++; } + if ((argv = makeargv(cp, &argc)) == NULL) + return -1; + /* Figure out which command we have */ - for (i = 0; cmds[i].c; i++) { - int cmdlen = strlen(cmds[i].c); - - /* Check for command followed by whitespace */ - if (!strncasecmp(cp, cmds[i].c, cmdlen) && - strchr(WHITESPACE, cp[cmdlen])) { - cp += cmdlen; - cp = cp + strspn(cp, WHITESPACE); + for (i = 0; cmds[i].c != NULL; i++) { + if (strcasecmp(cmds[i].c, argv[0]) == 0) break; - } } cmdnum = cmds[i].n; cmd = cmds[i].c; @@ -909,40 +1104,44 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, cmdnum = I_SHELL; } else if (cmdnum == -1) { error("Invalid command."); - return (-1); + return -1; } /* Get arguments and parse flags */ - *lflag = *pflag = *n_arg = 0; + *lflag = *pflag = *hflag = *n_arg = 0; *path1 = *path2 = NULL; + optidx = 1; switch (cmdnum) { case I_GET: case I_PUT: - if (parse_getput_flags(&cp, pflag)) - return(-1); + if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1) + return -1; /* Get first pathname (mandatory) */ - if (get_pathname(&cp, path1)) - return(-1); - if (*path1 == NULL) { + if (argc - optidx < 1) { error("You must specify at least one path after a " "%s command.", cmd); - return(-1); + return -1; + } + *path1 = xstrdup(argv[optidx]); + /* Get second pathname (optional) */ + if (argc - optidx > 1) { + *path2 = xstrdup(argv[optidx + 1]); + /* Destination is not globbed */ + undo_glob_escape(*path2); } - /* Try to get second pathname (optional) */ - if (get_pathname(&cp, path2)) - return(-1); break; case I_RENAME: case I_SYMLINK: - if (get_pathname(&cp, path1)) - return(-1); - if (get_pathname(&cp, path2)) - return(-1); - if (!*path1 || !*path2) { + if (argc - optidx < 2) { error("You must specify two paths after a %s " "command.", cmd); - return(-1); + return -1; } + *path1 = xstrdup(argv[optidx]); + *path2 = xstrdup(argv[optidx + 1]); + /* Paths are not globbed */ + undo_glob_escape(*path1); + undo_glob_escape(*path2); break; case I_RM: case I_MKDIR: @@ -951,59 +1150,69 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, case I_LCHDIR: case I_LMKDIR: /* Get pathname (mandatory) */ - if (get_pathname(&cp, path1)) - return(-1); - if (*path1 == NULL) { + if (argc - optidx < 1) { error("You must specify a path after a %s command.", cmd); - return(-1); + return -1; + } + *path1 = xstrdup(argv[optidx]); + /* Only "rm" globs */ + if (cmdnum != I_RM) + undo_glob_escape(*path1); + break; + case I_DF: + if ((optidx = parse_df_flags(cmd, argv, argc, hflag, + iflag)) == -1) + return -1; + /* Default to current directory if no path specified */ + if (argc - optidx < 1) + *path1 = NULL; + else { + *path1 = xstrdup(argv[optidx]); + undo_glob_escape(*path1); } break; case I_LS: - if (parse_ls_flags(&cp, lflag)) + if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1) return(-1); /* Path is optional */ - if (get_pathname(&cp, path1)) - return(-1); + if (argc - optidx > 0) + *path1 = xstrdup(argv[optidx]); break; case I_LLS: + /* Skip ls command and following whitespace */ + cp = cp + strlen(cmd) + strspn(cp, WHITESPACE); case I_SHELL: /* Uses the rest of the line */ break; case I_LUMASK: - base = 8; case I_CHMOD: base = 8; case I_CHOWN: case I_CHGRP: /* Get numeric arg (mandatory) */ + if (argc - optidx < 1) + goto need_num_arg; errno = 0; - l = strtol(cp, &cp2, base); - if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) && - errno == ERANGE) || l < 0) { + l = strtol(argv[optidx], &cp2, base); + if (cp2 == argv[optidx] || *cp2 != '\0' || + ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) || + l < 0) { + need_num_arg: error("You must supply a numeric argument " "to the %s command.", cmd); - return(-1); + return -1; } - cp = cp2; *n_arg = l; - if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp)) + if (cmdnum == I_LUMASK) break; - if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) { - error("You must supply a numeric argument " - "to the %s command.", cmd); - return(-1); - } - cp += strspn(cp, WHITESPACE); - /* Get pathname (mandatory) */ - if (get_pathname(&cp, path1)) - return(-1); - if (*path1 == NULL) { + if (argc - optidx < 2) { error("You must specify a path after a %s command.", cmd); - return(-1); + return -1; } + *path1 = xstrdup(argv[optidx + 1]); break; case I_QUIT: case I_PWD: @@ -1025,7 +1234,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int pflag, lflag, iflag, cmdnum, i; + int pflag, lflag, iflag, hflag, cmdnum, i; unsigned long n_arg; Attrib a, *aa; char path_buf[MAXPATHLEN]; @@ -1033,7 +1242,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, glob_t g; path1 = path2 = NULL; - cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg, + cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg, &path1, &path2); if (iflag != 0) @@ -1127,6 +1336,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, path1 = make_absolute(path1, *pwd); err = do_globbed_ls(conn, path1, tmp, lflag); break; + case I_DF: + /* Default to current directory if no path specified */ + if (path1 == NULL) + path1 = xstrdup(*pwd); + path1 = make_absolute(path1, *pwd); + err = do_df(conn, path1, hflag, iflag); + break; case I_LCHDIR: if (chdir(path1) == -1) { error("Couldn't change local directory to " @@ -1566,7 +1782,7 @@ main(int argc, char **argv) fprintf(stderr, "Missing username\n"); usage(); } - addargs(&args, "-l%s",userhost); + addargs(&args, "-l%s", userhost); } if ((cp = colon(host)) != NULL) { diff --git a/crypto/openssh/sftp.h b/crypto/openssh/sftp.h index 610c0b7..2bde8bb 100644 --- a/crypto/openssh/sftp.h +++ b/crypto/openssh/sftp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.h,v 1.5 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: sftp.h,v 1.9 2008/06/13 00:12:02 dtucker Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -79,6 +79,10 @@ #define SSH2_FXF_TRUNC 0x00000010 #define SSH2_FXF_EXCL 0x00000020 +/* statvfs@openssh.com f_flag flags */ +#define SSH2_FXE_STATVFS_ST_RDONLY 0x00000001 +#define SSH2_FXE_STATVFS_ST_NOSUID 0x00000002 + /* status messages */ #define SSH2_FX_OK 0 #define SSH2_FX_EOF 1 @@ -90,3 +94,8 @@ #define SSH2_FX_CONNECTION_LOST 7 #define SSH2_FX_OP_UNSUPPORTED 8 #define SSH2_FX_MAX 8 + +struct passwd; + +int sftp_server_main(int, char **, struct passwd *); +void sftp_server_cleanup_exit(int) __attribute__((noreturn)); diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 index 327fcdd..005041b 100644 --- a/crypto/openssh/ssh-add.1 +++ b/crypto/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/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c index 4dc46f6..7a43282 100644 --- a/crypto/openssh/ssh-add.c +++ b/crypto/openssh/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.89 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.90 2007/09/09 11:38:01 sobrado Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -42,6 +42,7 @@ #include <sys/param.h> #include <openssl/evp.h> +#include "openbsd-compat/openssl-compat.h" #include <fcntl.h> #include <pwd.h> @@ -309,7 +310,7 @@ do_file(AuthenticationConnection *ac, int deleting, char *file) static void usage(void) { - fprintf(stderr, "Usage: %s [options] [file ...]\n", __progname); + fprintf(stderr, "usage: %s [options] [file ...]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -l List fingerprints of all identities.\n"); fprintf(stderr, " -L List public key parameters of all identities.\n"); diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 index f1b8777..6a5dc62 100644 --- a/crypto/openssh/ssh-agent.1 +++ b/crypto/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.46 2007/09/09 11:38:01 sobrado Exp $ .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 @@ -42,11 +42,11 @@ .Nd authentication agent .Sh SYNOPSIS .Nm ssh-agent -.Op Fl a Ar bind_address .Op Fl c Li | Fl s -.Op Fl t Ar life .Op Fl d -.Op Ar command Op Ar args ... +.Op Fl a Ar bind_address +.Op Fl t Ar life +.Op Ar command Op Ar arg ... .Nm ssh-agent .Op Fl c Li | Fl s .Fl k @@ -77,16 +77,21 @@ Generate C-shell commands on This is the default if .Ev SHELL looks like it's a csh style of shell. +.It Fl d +Debug mode. +When this option is specified +.Nm +will not fork. +.It Fl k +Kill the current agent (given by the +.Ev SSH_AGENT_PID +environment variable). .It Fl s Generate Bourne shell commands on .Dv stdout . This is the default if .Ev SHELL does not look like it's a csh style of shell. -.It Fl k -Kill the current agent (given by the -.Ev SSH_AGENT_PID -environment variable). .It Fl t Ar life Set a default value for the maximum lifetime of identities added to the agent. The lifetime may be specified in seconds or in a time format specified in @@ -95,11 +100,6 @@ A lifetime specified for an identity with .Xr ssh-add 1 overrides this value. Without this option the default maximum lifetime is forever. -.It Fl d -Debug mode. -When this option is specified -.Nm -will not fork. .El .Pp If a commandline is given, this is executed as a subprocess of the agent. diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index 29a4e5a..ef62f19 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.153 2006/10/06 02:29:19 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.159 2008/06/28 14:05:15 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -52,6 +52,7 @@ __RCSID("$FreeBSD$"); #include <openssl/evp.h> #include <openssl/md5.h> +#include "openbsd-compat/openssl-compat.h" #include <errno.h> #include <fcntl.h> @@ -121,6 +122,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]; @@ -311,6 +313,7 @@ process_sign_request2(SocketEntry *e) u_char *blob, *data, *signature = NULL; u_int blen, dlen, slen = 0; extern int datafellows; + int odatafellows; int ok = -1, flags; Buffer msg; Key *key; @@ -321,6 +324,7 @@ process_sign_request2(SocketEntry *e) data = buffer_get_string(&e->request, &dlen); flags = buffer_get_int(&e->request); + odatafellows = datafellows; if (flags & SSH_AGENT_OLD_SIGNATURE) datafellows = SSH_BUG_SIGBLOB; @@ -346,6 +350,7 @@ process_sign_request2(SocketEntry *e) xfree(blob); if (signature != NULL) xfree(signature); + datafellows = odatafellows; } /* shared */ @@ -422,10 +427,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; @@ -434,19 +440,29 @@ 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 process_add_identity(SocketEntry *e, int version) { Idtab *tab = idtab_lookup(version); + Identity *id; int type, success = 0, death = 0, confirm = 0; char *type_name, *comment; Key *k = NULL; @@ -514,9 +530,8 @@ process_add_identity(SocketEntry *e, int version) xfree(comment); goto send; } - success = 1; while (buffer_len(&e->request)) { - switch (buffer_get_char(&e->request)) { + switch ((type = buffer_get_char(&e->request))) { case SSH_AGENT_CONSTRAIN_LIFETIME: death = time(NULL) + buffer_get_int(&e->request); break; @@ -524,24 +539,29 @@ process_add_identity(SocketEntry *e, int version) confirm = 1; break; default: - break; + error("process_add_identity: " + "Unknown constraint type %d", type); + xfree(comment); + key_free(k); + goto send; } } + success = 1; if (lifetime && !death) death = time(NULL) + lifetime; - if (lookup_identity(k, version) == NULL) { - Identity *id = xmalloc(sizeof(Identity)); + if ((id = lookup_identity(k, version)) == NULL) { + id = xmalloc(sizeof(Identity)); id->key = k; - id->comment = comment; - id->death = death; - id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); /* Increment the number of identities. */ tab->nentries++; } else { key_free(k); - xfree(comment); + xfree(id->comment); } + id->comment = comment; + id->death = death; + id->confirm = confirm; send: buffer_put_int(&e->output, 1); buffer_put_char(&e->output, @@ -592,10 +612,10 @@ no_identities(SocketEntry *e, u_int type) #ifdef SMARTCARD static void -process_add_smartcard_key (SocketEntry *e) +process_add_smartcard_key(SocketEntry *e) { char *sc_reader_id = NULL, *pin; - int i, version, success = 0, death = 0, confirm = 0; + int i, type, version, success = 0, death = 0, confirm = 0; Key **keys, *k; Identity *id; Idtab *tab; @@ -604,7 +624,7 @@ process_add_smartcard_key (SocketEntry *e) pin = buffer_get_string(&e->request, NULL); while (buffer_len(&e->request)) { - switch (buffer_get_char(&e->request)) { + switch ((type = buffer_get_char(&e->request))) { case SSH_AGENT_CONSTRAIN_LIFETIME: death = time(NULL) + buffer_get_int(&e->request); break; @@ -612,7 +632,11 @@ process_add_smartcard_key (SocketEntry *e) confirm = 1; break; default: - break; + error("process_add_smartcard_key: " + "Unknown constraint type %d", type); + xfree(sc_reader_id); + xfree(pin); + goto send; } } if (lifetime && !death) @@ -699,9 +723,6 @@ process_message(SocketEntry *e) u_int msg_len, type; u_char *cp; - /* kill dead keys */ - reaper(); - if (buffer_len(&e->input) < 5) return; /* Incomplete message. */ cp = buffer_ptr(&e->input); @@ -829,10 +850,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) { @@ -876,6 +899,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); } @@ -928,7 +962,8 @@ after_select(fd_set *readset, fd_set *writeset) buffer_ptr(&sockets[i].output), buffer_len(&sockets[i].output)); if (len == -1 && (errno == EAGAIN || - errno == EINTR)) + errno == EINTR || + errno == EWOULDBLOCK)) continue; break; } while (1); @@ -942,7 +977,8 @@ after_select(fd_set *readset, fd_set *writeset) do { len = read(sockets[i].fd, buf, sizeof(buf)); if (len == -1 && (errno == EAGAIN || - errno == EINTR)) + errno == EINTR || + errno == EWOULDBLOCK)) continue; break; } while (1); @@ -983,25 +1019,20 @@ 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 usage(void) { - fprintf(stderr, "Usage: %s [options] [command [args ...]]\n", + fprintf(stderr, "usage: %s [options] [command [arg ...]]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); @@ -1017,7 +1048,7 @@ int main(int ac, char **av) { int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; - int sock, fd, ch; + int sock, fd, ch, result, saved_errno; u_int nalloc; char *shell, *format, *pidstr, *agentsocket = NULL; fd_set *readsetp = NULL, *writesetp = NULL; @@ -1030,6 +1061,7 @@ main(int ac, char **av) extern char *optarg; pid_t pid; char pidstrbuf[1 + 3 * sizeof pid]; + struct timeval *tvp = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -1231,10 +1263,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); @@ -1244,13 +1274,18 @@ skip: nalloc = 0; while (1) { - prepare_select(&readsetp, &writesetp, &max_fd, &nalloc); - if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) { - if (errno == EINTR) + prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); + result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); + saved_errno = errno; + if (parent_alive_interval != 0) + check_parent_exists(); + (void) reaper(); /* remove expired keys */ + if (result < 0) { + if (saved_errno == EINTR) continue; - fatal("select: %s", strerror(errno)); - } - after_select(readsetp, writesetp); + fatal("select: %s", strerror(saved_errno)); + } else if (result > 0) + after_select(readsetp, writesetp); } /* NOTREACHED */ } diff --git a/crypto/openssh/ssh-gss.h b/crypto/openssh/ssh-gss.h index 1ef66e4..c29a1b7 100644 --- a/crypto/openssh/ssh-gss.h +++ b/crypto/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/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1 index ab16bcd..3fff59e 100644 --- a/crypto/openssh/ssh-keygen.1 +++ b/crypto/openssh/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.72 2005/11/28 05:16:53 dtucker Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.78 2008/06/12 19:10:09 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 2008 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -205,8 +205,8 @@ Download the RSA public key stored in the smartcard in .Ar reader . .It Fl e This option will read a private or public OpenSSH key file and -print the key in a -.Sq SECSH Public Key File Format +print the key in +RFC 4716 SSH Public Key File Format to stdout. This option allows exporting keys for use by several commercial SSH implementations. @@ -253,7 +253,7 @@ in SSH2-compatible format and print an OpenSSH compatible private (or public) key to stdout. .Nm also reads the -.Sq SECSH Public Key File Format . +RFC 4716 SSH Public Key File Format. This option allows importing keys from several commercial SSH implementations. .It Fl l @@ -262,6 +262,9 @@ Private RSA1 keys are also supported. For RSA and DSA keys .Nm tries to find the matching public key file and prints its fingerprint. +If combined with +.Fl v , +an ASCII art representation of the key is supplied with the fingerprint. .It Fl M Ar memory Specify the amount of memory to use (in megabytes) when generating candidate moduli for DH-GEX. @@ -450,12 +453,9 @@ The file format is described in .Xr moduli 5 , .Xr sshd 8 .Rs -.%A J. Galbraith -.%A R. Thayer -.%T "SECSH Public Key File Format" -.%N draft-ietf-secsh-publickeyfile-01.txt -.%D March 2001 -.%O work in progress material +.%R RFC 4716 +.%T "The Secure Shell (SSH) Public Key File Format" +.%D 2006 .Re .Sh AUTHORS OpenSSH is a derivative of the original and free diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c index 1f42b93..f7e2840 100644 --- a/crypto/openssh/ssh-keygen.c +++ b/crypto/openssh/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.155 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -21,6 +21,7 @@ #include <openssl/evp.h> #include <openssl/pem.h> +#include "openbsd-compat/openssl-compat.h" #include <errno.h> #include <fcntl.h> @@ -71,6 +72,8 @@ int change_comment = 0; int quiet = 0; +int log_level = SYSLOG_LEVEL_INFO; + /* Flag indicating that we want to hash a known_hosts file */ int hash_hosts = 0; /* Flag indicating that we want lookup a host in known_hosts file */ @@ -141,8 +144,7 @@ ask_filename(struct passwd *pw, const char *prompt) fprintf(stderr, "%s (%s): ", prompt, identity_file); if (fgets(buf, sizeof(buf), stdin) == NULL) exit(1); - if (strchr(buf, '\n')) - *strchr(buf, '\n') = 0; + buf[strcspn(buf, "\n")] = '\0'; if (strcmp(buf, "") != 0) strlcpy(identity_file, buf, sizeof(identity_file)); have_identity = 1; @@ -241,7 +243,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) buffer_init(&b); buffer_append(&b, blob, blen); - magic = buffer_get_int(&b); + magic = buffer_get_int(&b); if (magic != SSH_COM_PRIVATE_KEY_MAGIC) { error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC); buffer_free(&b); @@ -253,7 +255,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) i2 = buffer_get_int(&b); i3 = buffer_get_int(&b); i4 = buffer_get_int(&b); - debug("ignore (%d %d %d %d)", i1,i2,i3,i4); + debug("ignore (%d %d %d %d)", i1, i2, i3, i4); if (strcmp(cipher, "none") != 0) { error("unsupported cipher %s", cipher); xfree(cipher); @@ -284,7 +286,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) buffer_get_bignum_bits(&b, key->dsa->priv_key); break; case KEY_RSA: - e = buffer_get_char(&b); + e = buffer_get_char(&b); debug("e %lx", e); if (e < 30) { e <<= 8; @@ -346,9 +348,8 @@ get_line(FILE *fp, char *line, size_t len) line[pos++] = c; line[pos] = '\0'; } - if (c == EOF) - return -1; - return pos; + /* We reached EOF */ + return -1; } static void @@ -505,8 +506,8 @@ do_fingerprint(struct passwd *pw) { FILE *f; Key *public; - char *comment = NULL, *cp, *ep, line[16*1024], *fp; - int i, skip = 0, num = 1, invalid = 1; + char *comment = NULL, *cp, *ep, line[16*1024], *fp, *ra; + int i, skip = 0, num = 0, invalid = 1; enum fp_rep rep; enum fp_type fptype; struct stat st; @@ -523,9 +524,14 @@ do_fingerprint(struct passwd *pw) public = key_load_public(identity_file, &comment); if (public != NULL) { fp = key_fingerprint(public, fptype, rep); - printf("%u %s %s\n", key_size(public), fp, comment); + ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART); + printf("%u %s %s (%s)\n", key_size(public), fp, comment, + key_type(public)); + if (log_level >= SYSLOG_LEVEL_VERBOSE) + printf("%s\n", ra); key_free(public); xfree(comment); + xfree(ra); xfree(fp); exit(0); } @@ -537,9 +543,9 @@ do_fingerprint(struct passwd *pw) f = fopen(identity_file, "r"); if (f != NULL) { while (fgets(line, sizeof(line), f)) { - i = strlen(line) - 1; - if (line[i] != '\n') { - error("line %d too long: %.40s...", num, line); + if ((cp = strchr(line, '\n')) == NULL) { + error("line %d too long: %.40s...", + num + 1, line); skip = 1; continue; } @@ -548,13 +554,13 @@ do_fingerprint(struct passwd *pw) skip = 0; continue; } - line[i] = '\0'; + *cp = '\0'; /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) ; if (!*cp || *cp == '\n' || *cp == '#') - continue ; + continue; i = strtol(cp, &ep, 10); if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) { int quoted = 0; @@ -583,8 +589,12 @@ do_fingerprint(struct passwd *pw) } comment = *cp ? cp : comment; fp = key_fingerprint(public, fptype, rep); - printf("%u %s %s\n", key_size(public), fp, - comment ? comment : "no comment"); + ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART); + printf("%u %s %s (%s)\n", key_size(public), fp, + comment ? comment : "no comment", key_type(public)); + if (log_level >= SYSLOG_LEVEL_VERBOSE) + printf("%s\n", ra); + xfree(ra); xfree(fp); key_free(public); invalid = 0; @@ -599,14 +609,31 @@ do_fingerprint(struct passwd *pw) } static void -print_host(FILE *f, char *name, Key *public, int hash) +print_host(FILE *f, const char *name, Key *public, int hash) { - if (hash && (name = host_hash(name, NULL, 0)) == NULL) - fatal("hash_host failed"); - fprintf(f, "%s ", name); - if (!key_write(public, f)) - fatal("key_write failed"); - fprintf(f, "\n"); + if (print_fingerprint) { + enum fp_rep rep; + enum fp_type fptype; + char *fp, *ra; + + fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + fp = key_fingerprint(public, fptype, rep); + ra = key_fingerprint(public, fptype, SSH_FP_RANDOMART); + printf("%u %s %s (%s)\n", key_size(public), fp, name, + key_type(public)); + if (log_level >= SYSLOG_LEVEL_VERBOSE) + printf("%s\n", ra); + xfree(ra); + xfree(fp); + } else { + if (hash && (name = host_hash(name, NULL, 0)) == NULL) + fatal("hash_host failed"); + fprintf(f, "%s ", name); + if (!key_write(public, f)) + fatal("key_write failed"); + fprintf(f, "\n"); + } } static void @@ -616,7 +643,7 @@ do_known_hosts(struct passwd *pw, const char *name) Key *public; char *cp, *cp2, *kp, *kp2; char line[16*1024], tmp[MAXPATHLEN], old[MAXPATHLEN]; - int c, i, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; + int c, skip = 0, inplace = 0, num = 0, invalid = 0, has_unhashed = 0; if (!have_identity) { cp = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE, pw->pw_uid); @@ -651,19 +678,18 @@ do_known_hosts(struct passwd *pw, const char *name) } while (fgets(line, sizeof(line), in)) { - num++; - i = strlen(line) - 1; - if (line[i] != '\n') { - error("line %d too long: %.40s...", num, line); + if ((cp = strchr(line, '\n')) == NULL) { + error("line %d too long: %.40s...", num + 1, line); skip = 1; invalid = 1; continue; } + num++; if (skip) { skip = 0; continue; } - line[i] = '\0'; + *cp = '\0'; /* Skip leading whitespace, empty and comment lines. */ for (cp = line; *cp == ' ' || *cp == '\t'; cp++) @@ -727,7 +753,8 @@ do_known_hosts(struct passwd *pw, const char *name) printf("# Host %s found: " "line %d type %s\n", name, num, key_type(public)); - print_host(out, cp, public, hash_hosts); + print_host(out, name, public, + hash_hosts); } if (delete_host && !c) print_host(out, cp, public, 0); @@ -751,7 +778,7 @@ do_known_hosts(struct passwd *pw, const char *name) fclose(in); if (invalid) { - fprintf(stderr, "%s is not a valid known_host file.\n", + fprintf(stderr, "%s is not a valid known_hosts file.\n", identity_file); if (inplace) { fprintf(stderr, "Not replacing existing known_hosts " @@ -963,8 +990,7 @@ do_change_comment(struct passwd *pw) key_free(private); exit(1); } - if (strchr(new_comment, '\n')) - *strchr(new_comment, '\n') = 0; + new_comment[strcspn(new_comment, "\n")] = '\0'; } /* Save the file using the new passphrase. */ @@ -1007,7 +1033,7 @@ do_change_comment(struct passwd *pw) static void usage(void) { - fprintf(stderr, "Usage: %s [options]\n", __progname); + fprintf(stderr, "usage: %s [options]\n", __progname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -a trials Number of trials for screening DH-GEX moduli.\n"); fprintf(stderr, " -B Show bubblebabble digest of key file.\n"); @@ -1017,13 +1043,13 @@ usage(void) #ifdef SMARTCARD fprintf(stderr, " -D reader Download public key from smartcard.\n"); #endif /* SMARTCARD */ - fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n"); + fprintf(stderr, " -e Convert OpenSSH to RFC 4716 key file.\n"); fprintf(stderr, " -F hostname Find hostname in known hosts file.\n"); fprintf(stderr, " -f filename Filename of the key file.\n"); fprintf(stderr, " -G file Generate candidates for DH-GEX moduli.\n"); fprintf(stderr, " -g Use generic DNS resource record format.\n"); fprintf(stderr, " -H Hash names in known_hosts file.\n"); - fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n"); + fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n"); fprintf(stderr, " -l Show fingerprint of key file.\n"); fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); fprintf(stderr, " -N phrase Provide new passphrase.\n"); @@ -1049,7 +1075,7 @@ usage(void) * Main program for key management. */ int -main(int ac, char **av) +main(int argc, char **argv) { char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; char out_file[MAXPATHLEN], *reader_id = NULL; @@ -1060,7 +1086,6 @@ main(int ac, char **av) int opt, type, fd, download = 0; u_int32_t memory = 0, generator_wanted = 0, trials = 100; int do_gen_candidates = 0, do_screen_candidates = 0; - int log_level = SYSLOG_LEVEL_INFO; BIGNUM *start = NULL; FILE *f; const char *errstr; @@ -1071,10 +1096,10 @@ main(int ac, char **av) /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); - __progname = ssh_get_progname(av[0]); + __progname = ssh_get_progname(argv[0]); SSLeay_add_all_algorithms(); - log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); + log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); init_rng(); seed_rng(); @@ -1090,7 +1115,7 @@ main(int ac, char **av) exit(1); } - while ((opt = getopt(ac, av, + while ((opt = getopt(argc, argv, "degiqpclBHvxXyF:b:f:t:U:D:P:N:C:r:g:R:T:G:M:S:a:W:")) != -1) { switch (opt) { case 'b': @@ -1223,9 +1248,9 @@ main(int ac, char **av) } /* reinit */ - log_init(av[0], log_level, SYSLOG_FACILITY_USER, 1); + log_init(argv[0], log_level, SYSLOG_FACILITY_USER, 1); - if (optind < ac) { + if (optind < argc) { printf("Too many arguments.\n"); usage(); } @@ -1233,6 +1258,10 @@ main(int ac, char **av) printf("Can only have one of -p and -c.\n"); usage(); } + if (print_fingerprint && (delete_host || hash_hosts)) { + printf("Cannot use -l with -D or -R.\n"); + usage(); + } if (delete_host || hash_hosts || find_host) do_known_hosts(pw, rr_hostname); if (print_fingerprint || print_bubblebabble) @@ -1437,10 +1466,15 @@ passphrase_again: if (!quiet) { char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); + char *ra = key_fingerprint(public, SSH_FP_MD5, + SSH_FP_RANDOMART); printf("Your public key has been saved in %s.\n", identity_file); printf("The key fingerprint is:\n"); printf("%s %s\n", fp, comment); + printf("The key's randomart image is:\n"); + printf("%s\n", ra); + xfree(ra); xfree(fp); } diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1 index a3656fc..8a4f3bc 100644 --- a/crypto/openssh/ssh-keyscan.1 +++ b/crypto/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.24 2008/04/30 10:14:03 djm Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. .\" @@ -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: April 30 2008 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -94,7 +94,7 @@ or for protocol version 2. Multiple values may be specified by separating them with commas. The default is -.Dq rsa1 . +.Dq rsa . .It Fl v Verbose mode. Causes diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c index b198640..d810777 100644 --- a/crypto/openssh/ssh-keyscan.c +++ b/crypto/openssh/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.74 2006/10/06 02:29:19 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.76 2008/04/30 10:14:03 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. * @@ -56,7 +56,7 @@ int ssh_port = SSH_DEFAULT_PORT; #define KT_DSA 2 #define KT_RSA 4 -int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */ +int get_keytypes = KT_RSA; /* Get only RSA keys by default */ int hash_hosts = 0; /* Hash hostname on output */ @@ -410,7 +410,7 @@ tcpconnect(char *host) hints.ai_family = IPv4or6; hints.ai_socktype = SOCK_STREAM; if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr)); + fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr)); for (ai = aitop; ai; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { @@ -656,7 +656,7 @@ conloop(void) memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask)); while (select(maxfd, r, NULL, e, &seltime) == -1 && - (errno == EAGAIN || errno == EINTR)) + (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK)) ; for (i = 0; i < maxfd; i++) { diff --git a/crypto/openssh/ssh-keysign.8 b/crypto/openssh/ssh-keysign.8 index 4cdcb7a..3ba54b9 100644 --- a/crypto/openssh/ssh-keysign.8 +++ b/crypto/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: May 31 2007 $ .Dt SSH-KEYSIGN 8 .Os .Sh NAME diff --git a/crypto/openssh/ssh-rand-helper.8 b/crypto/openssh/ssh-rand-helper.8 index df559d3..af5a72f 100644 --- a/crypto/openssh/ssh-rand-helper.8 +++ b/crypto/openssh/ssh-rand-helper.8 @@ -1,4 +1,4 @@ -.\" $Id: ssh-rand-helper.8,v 1.2 2003/11/21 12:48:56 djm Exp $ +.\" $Id: ssh-rand-helper.8,v 1.3 2007/01/22 01:44:53 djm Exp $ .\" .\" Copyright (c) 2002 Damien Miller. All rights reserved. .\" @@ -27,7 +27,7 @@ .Os .Sh NAME .Nm ssh-rand-helper -.Nd Random number gatherer for OpenSSH +.Nd random number gatherer for OpenSSH .Sh SYNOPSIS .Nm ssh-rand-hlper .Op Fl vxXh @@ -82,7 +82,7 @@ Force output of a binary seed, even if standard output is a tty Turn on debugging message. Multiple .Fl v options will increase the debugging level. -.Fl h +.It Fl h Display a summary of options. .El .Sh AUTHORS diff --git a/crypto/openssh/ssh-rand-helper.c b/crypto/openssh/ssh-rand-helper.c index 8520c3a..8b1c4b4 100644 --- a/crypto/openssh/ssh-rand-helper.c +++ b/crypto/openssh/ssh-rand-helper.c @@ -32,6 +32,7 @@ #include <stdarg.h> #include <stddef.h> +#include <string.h> #include <netinet/in.h> #include <arpa/inet.h> diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1 index b04616a..7972f4f 100644 --- a/crypto/openssh/ssh.1 +++ b/crypto/openssh/ssh.1 @@ -34,9 +34,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.265 2006/10/28 18:08:10 otto Exp $ +.\" $OpenBSD: ssh.1,v 1.277 2008/07/02 13:47:39 djm Exp $ .\" $FreeBSD$ -.Dd September 25, 1999 +.Dd $Mdocdate: July 2 2008 $ .Dt SSH 1 .Os .Sh NAME @@ -44,7 +44,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\ \& @@ -291,6 +291,15 @@ This implies The recommended way to start X11 programs at a remote site is with something like .Ic ssh -f host xterm . +.Pp +If the +.Cm ExitOnForwardFailure +configuration option is set to +.Dq yes , +then a client started with +.Fl f +will wait for all remote port forwards to be successfully established +before placing itself in the background. .It Fl g Allows remote hosts to connect to local forwarded ports. .It Fl I Ar smartcard_device @@ -316,6 +325,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 @@ -497,6 +509,7 @@ For full details of the options listed below, and their possible values, see .It UserKnownHostsFile .It VerifyHostKeyDNS .It VersionAddendum +.It VisualHostKey .It XAuthLocation .El .It Fl p Ar port @@ -505,7 +518,7 @@ This can be specified on a per-host basis in the configuration file. .It Fl q Quiet mode. -Causes all warning and diagnostic messages to be suppressed. +Causes most warning and diagnostic messages to be suppressed. .It Fl R Xo .Sm off .Oo Ar bind_address : Oc @@ -676,7 +689,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 @@ -1026,9 +1039,31 @@ Fingerprints can be determined using .Pp .Dl $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key .Pp -If the fingerprint is already known, -it can be matched and verified, -and the key can be accepted. +If the fingerprint is already known, it can be matched +and the key can be accepted or rejected. +Because of the difficulty of comparing host keys +just by looking at hex strings, +there is also support to compare host keys visually, +using +.Em random art . +By setting the +.Cm VisualHostKey +option to +.Dq yes , +a small ASCII graphic gets displayed on every login to a server, no matter +if the session itself is interactive or not. +By learning the pattern a known server produces, a user can easily +find out that the host key has changed when a completely different pattern +is displayed. +Because these patterns are not unambiguous however, a pattern that looks +similar to the pattern remembered only gives a good probability that the +host key is the same, not guaranteed proof. +.Pp +To get a listing of the fingerprints along with their random art for +all known hosts, the following command line can be used: +.Pp +.Dl $ ssh-keygen -lv -f ~/.ssh/known_hosts +.Pp If the fingerprint is unknown, an alternative method of verification is available: SSH fingerprints verified by DNS. @@ -1244,6 +1279,13 @@ This file is used in exactly the same way as but allows host-based authentication without permitting login with rlogin/rsh. .Pp +.It ~/.ssh/ +This directory is the default location for all user-specific configuration +and authentication information. +There is no general requirement to keep the entire contents of this directory +secret, but the recommended permissions are read/write/execute for the user, +and not accessible by others. +.Pp .It ~/.ssh/authorized_keys Lists the public keys (RSA/DSA) that can be used for logging in as this user. The format of this file is described in the @@ -1420,6 +1462,18 @@ manual page for more information. .%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol" .%D 2006 .Re +.Rs +.%R RFC 4716 +.%T "The Secure Shell (SSH) Public Key File Format" +.%D 2006 +.Re +.Rs +.%T "Hash Visualization: a New Technique to improve Real-World Security" +.%A A. Perrig +.%A D. Song +.%D 1999 +.%O "International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)" +.Re .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index 67844a9..bfd7979 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.294 2006/10/06 02:29:19 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.318 2008/07/02 13:47:39 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -50,7 +50,6 @@ __RCSID("$FreeBSD$"); #include <sys/resource.h> #include <sys/ioctl.h> #include <sys/socket.h> -#include <sys/un.h> #include <ctype.h> #include <errno.h> @@ -73,6 +72,8 @@ __RCSID("$FreeBSD$"); #include <openssl/evp.h> #include <openssl/err.h> +#include "openbsd-compat/openssl-compat.h" +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "ssh.h" @@ -98,7 +99,6 @@ __RCSID("$FreeBSD$"); #include "sshpty.h" #include "match.h" #include "msg.h" -#include "monitor_fdpass.h" #include "uidswap.h" #include "version.h" @@ -108,7 +108,7 @@ __RCSID("$FreeBSD$"); extern char *__progname; -/* Flag indicating whether debug mode is on. This can be set on the command line. */ +/* Flag indicating whether debug mode is on. May be set on the command line. */ int debug_flag = 0; /* Flag indicating whether a tty should be allocated */ @@ -165,20 +165,14 @@ Buffer command; int subsystem_flag = 0; /* # of replies received for global requests */ -static int client_global_request_id = 0; +static int remote_forward_confirms_received = 0; /* pid of proxycommand child process */ pid_t proxy_command_pid = 0; -/* fd to control socket */ -int control_fd = -1; - -/* Multiplexing control command */ -static u_int mux_command = 0; - -/* Only used in control client mode */ -volatile sig_atomic_t control_client_terminate = 0; -u_int control_server_pid = 0; +/* mux.c */ +extern int muxserver_sock; +extern u_int muxclient_command; /* Prints a help message to the user. This function never returns. */ @@ -186,7 +180,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" @@ -199,7 +193,10 @@ usage(void) static int ssh_session(void); static int ssh_session2(void); static void load_public_identity_files(void); -static void control_client(const char *path); + +/* from muxclient.c */ +void muxclient(const char *); +void muxserver_listen(void); /* * Main program for the ssh client. @@ -211,7 +208,7 @@ main(int ac, char **av) char *p, *cp, *line, buf[256]; struct stat st; struct passwd *pw; - int dummy; + int dummy, timeout_ms; extern int optind, optreset; extern char *optarg; struct servent *sp; @@ -265,15 +262,18 @@ main(int ac, char **av) */ umask(022); - /* Initialize option structure to indicate that no values have been set. */ + /* + * Initialize option structure to indicate that no values have been + * set. + */ initialize_options(&options); /* Parse command-line arguments. */ host = NULL; again: - while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) { + while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" + "ACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -309,9 +309,9 @@ main(int ac, char **av) break; case 'O': if (strcmp(optarg, "check") == 0) - mux_command = SSHMUX_COMMAND_ALIVE_CHECK; + muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK; else if (strcmp(optarg, "exit") == 0) - mux_command = SSHMUX_COMMAND_TERMINATE; + muxclient_command = SSHMUX_COMMAND_TERMINATE; else fatal("Invalid multiplex command."); break; @@ -327,6 +327,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 " @@ -374,7 +378,8 @@ main(int ac, char **av) options.tun_open = SSH_TUNMODE_DEFAULT; options.tun_local = a2tun(optarg, &options.tun_remote); if (options.tun_local == SSH_TUNID_ERR) { - fprintf(stderr, "Bad tun device '%s'\n", optarg); + fprintf(stderr, + "Bad tun device '%s'\n", optarg); exit(255); } break; @@ -477,7 +482,8 @@ main(int ac, char **av) } if (cp != NULL) { fwd.listen_port = a2port(cp); - fwd.listen_host = cleanhostname(fwd.listen_host); + fwd.listen_host = + cleanhostname(fwd.listen_host); } else { fwd.listen_port = a2port(fwd.listen_host); fwd.listen_host = NULL; @@ -583,8 +589,10 @@ main(int ac, char **av) } /* Cannot fork to background if no command. */ - if (fork_after_authentication_flag && buffer_len(&command) == 0 && !no_shell_flag) - fatal("Cannot fork into background without a command to execute."); + if (fork_after_authentication_flag && buffer_len(&command) == 0 && + !no_shell_flag) + fatal("Cannot fork into background without a command " + "to execute."); /* Allocate a tty by default if no command specified. */ if (buffer_len(&command) == 0) @@ -596,7 +604,8 @@ main(int ac, char **av) /* Do not allocate a tty if stdin is not a tty. */ if ((!isatty(fileno(stdin)) || stdin_null_flag) && !force_tty_flag) { if (tty_flag) - logit("Pseudo-terminal will not be allocated because stdin is not a terminal."); + logit("Pseudo-terminal will not be allocated because " + "stdin is not a terminal."); tty_flag = 0; } @@ -604,7 +613,8 @@ main(int ac, char **av) * Initialize "log" output. Since we are the client all output * actually goes to stderr. */ - log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, + log_init(av[0], + options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, SYSLOG_FACILITY_USER, 1); /* @@ -615,7 +625,7 @@ main(int ac, char **av) if (!read_config_file(config, host, &options, 0)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); - } else { + } else { snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); (void)read_config_file(buf, host, &options, 1); @@ -638,6 +648,28 @@ main(int ac, char **av) if (options.user == NULL) options.user = xstrdup(pw->pw_name); + /* Get default port if port has not been set. */ + if (options.port == 0) { + sp = getservbyname(SSH_SERVICE_NAME, "tcp"); + options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; + } + + if (options.local_command != NULL) { + char thishost[NI_MAXHOST]; + + if (gethostname(thishost, sizeof(thishost)) == -1) + fatal("gethostname: %s", strerror(errno)); + snprintf(buf, sizeof(buf), "%d", options.port); + debug3("expanding LocalCommand: %s", options.local_command); + cp = options.local_command; + options.local_command = percent_expand(cp, "d", pw->pw_dir, + "h", options.hostname? options.hostname : host, + "l", thishost, "n", host, "r", options.user, "p", buf, + "u", pw->pw_name, (char *)NULL); + debug3("expanded LocalCommand: %s", options.local_command); + xfree(cp); + } + if (options.hostname != NULL) host = options.hostname; @@ -665,18 +697,16 @@ main(int ac, char **av) *p = (char)tolower(*p); } - /* Get default port if port has not been set. */ - if (options.port == 0) { - sp = getservbyname(SSH_SERVICE_NAME, "tcp"); - options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT; - } - if (options.proxy_command != NULL && - strcmp(options.proxy_command, "none") == 0) + strcmp(options.proxy_command, "none") == 0) { + xfree(options.proxy_command); options.proxy_command = NULL; + } if (options.control_path != NULL && - strcmp(options.control_path, "none") == 0) + strcmp(options.control_path, "none") == 0) { + xfree(options.control_path); options.control_path = NULL; + } if (options.control_path != NULL) { char thishost[NI_MAXHOST]; @@ -686,18 +716,22 @@ main(int ac, char **av) snprintf(buf, sizeof(buf), "%d", options.port); cp = tilde_expand_filename(options.control_path, original_real_uid); + xfree(options.control_path); options.control_path = percent_expand(cp, "p", buf, "h", host, "r", options.user, "l", thishost, (char *)NULL); xfree(cp); } - if (mux_command != 0 && options.control_path == NULL) + if (muxclient_command != 0 && options.control_path == NULL) fatal("No ControlPath specified for \"-O\" command"); if (options.control_path != NULL) - control_client(options.control_path); + muxclient(options.control_path); + + timeout_ms = options.connection_timeout * 1000; /* Open a connection to the remote host. */ if (ssh_connect(host, &hostaddr, options.port, - options.address_family, options.connection_attempts, + options.address_family, options.connection_attempts, &timeout_ms, + options.tcp_keep_alive, #ifdef HAVE_CYGWIN options.use_privileged_port, #else @@ -706,6 +740,9 @@ main(int ac, char **av) options.proxy_command) != 0) exit(255); + if (timeout_ms > 0) + debug3("timeout: %d ms remain after connect", timeout_ms); + /* * If we successfully made the connection, load the host private key * in case we will need it later for combined rsa-rhosts @@ -759,7 +796,8 @@ main(int ac, char **av) * Now that we are back to our own permissions, create ~/.ssh * directory if it doesn't already exist. */ - snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); + snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, + strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); if (stat(buf, &st) < 0) if (mkdir(buf, 0700) < 0) error("Could not create directory '%.200s'.", buf); @@ -780,8 +818,9 @@ main(int ac, char **av) signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ - /* Log into the remote system. This never returns if the login fails. */ - ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw); + /* Log into the remote system. Never returns if the login fails. */ + ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, + pw, timeout_ms); /* We no longer need the private host keys. Clear them now. */ if (sensitive_data.nkeys != 0) { @@ -809,7 +848,7 @@ main(int ac, char **av) exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); - if (options.control_path != NULL && control_fd != -1) + if (options.control_path != NULL && muxserver_sock != -1) unlink(options.control_path); /* @@ -822,6 +861,34 @@ main(int ac, char **av) return exit_status; } +/* Callback for remote forward global requests */ +static void +ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) +{ + Forward *rfwd = (Forward *)ctxt; + + debug("remote forward %s for: listen %d, connect %s:%d", + type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", + rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); + if (type == SSH2_MSG_REQUEST_FAILURE) { + if (options.exit_on_forward_failure) + fatal("Error: remote port forwarding failed for " + "listen port %d", rfwd->listen_port); + else + logit("Warning: remote port forwarding failed for " + "listen port %d", rfwd->listen_port); + } + if (++remote_forward_confirms_received == options.num_remote_forwards) { + debug("All remote forwarding requests processed"); + if (fork_after_authentication_flag) { + fork_after_authentication_flag = 0; + if (daemon(1, 1) < 0) + fatal("daemon() failed: %.200s", + strerror(errno)); + } + } +} + static void ssh_init_forwarding(void) { @@ -870,7 +937,20 @@ ssh_init_forwarding(void) logit("Warning: Could not request remote " "forwarding."); } + client_register_global_confirm(ssh_confirm_remote_forward, + &options.remote_forwards[i]); } + + /* 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 @@ -895,10 +975,13 @@ ssh_session(void) /* Enable compression if requested. */ if (options.compression) { - debug("Requesting compression at level %d.", options.compression_level); + debug("Requesting compression at level %d.", + options.compression_level); - if (options.compression_level < 1 || options.compression_level > 9) - fatal("Compression level must be from 1 (fast) to 9 (slow, best)."); + if (options.compression_level < 1 || + options.compression_level > 9) + fatal("Compression level must be from 1 (fast) to " + "9 (slow, best)."); /* Send the request. */ packet_start(SSH_CMSG_REQUEST_COMPRESSION); @@ -911,7 +994,8 @@ ssh_session(void) else if (type == SSH_SMSG_FAILURE) logit("Warning: Remote host refused compression."); else - packet_disconnect("Protocol error waiting for compression response."); + packet_disconnect("Protocol error waiting for " + "compression response."); } /* Allocate a pseudo tty if appropriate. */ if (tty_flag) { @@ -948,9 +1032,11 @@ ssh_session(void) interactive = 1; have_tty = 1; } else if (type == SSH_SMSG_FAILURE) - logit("Warning: Remote host failed or refused to allocate a pseudo tty."); + logit("Warning: Remote host failed or refused to " + "allocate a pseudo tty."); else - packet_disconnect("Protocol error waiting for pty request response."); + packet_disconnect("Protocol error waiting for pty " + "request response."); } /* Request X11 forwarding if enabled and DISPLAY is set. */ display = getenv("DISPLAY"); @@ -960,7 +1046,8 @@ ssh_session(void) client_x11_get_proto(display, options.xauth_location, options.forward_x11_trusted, &proto, &data); /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); + debug("Requesting X11 forwarding with authentication " + "spoofing."); x11_request_forwarding_with_spoofing(0, display, proto, data); /* Read response from the server. */ @@ -970,7 +1057,8 @@ ssh_session(void) } else if (type == SSH_SMSG_FAILURE) { logit("Warning: Remote host denied X11 forwarding."); } else { - packet_disconnect("Protocol error waiting for X11 forwarding"); + packet_disconnect("Protocol error waiting for X11 " + "forwarding"); } } /* Tell the packet module whether this is an interactive session. */ @@ -993,10 +1081,22 @@ ssh_session(void) /* Initiate port forwardings. */ ssh_init_forwarding(); - /* If requested, let ssh continue in the background. */ - if (fork_after_authentication_flag) + /* Execute a local command */ + if (options.local_command != NULL && + options.permit_local_command) + ssh_local_cmd(options.local_command); + + /* + * If requested and we are not interested in replies to remote + * forwarding requests, then let ssh continue in the background. + */ + if (fork_after_authentication_flag && + (!options.exit_on_forward_failure || + options.num_remote_forwards == 0)) { + fork_after_authentication_flag = 0; if (daemon(1, 1) < 0) fatal("daemon() failed: %.200s", strerror(errno)); + } /* * If a command was specified on the command line, execute the @@ -1006,7 +1106,8 @@ ssh_session(void) int len = buffer_len(&command); if (len > 900) len = 900; - debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command)); + debug("Sending command: %.*s", len, + (u_char *)buffer_ptr(&command)); packet_start(SSH_CMSG_EXEC_CMD); packet_put_string(buffer_ptr(&command), buffer_len(&command)); packet_send(); @@ -1023,88 +1124,6 @@ ssh_session(void) options.escape_char : SSH_ESCAPECHAR_NONE, 0); } -static void -ssh_subsystem_reply(int type, u_int32_t seq, void *ctxt) -{ - int id, len; - - id = packet_get_int(); - len = buffer_len(&command); - if (len > 900) - len = 900; - packet_check_eom(); - if (type == SSH2_MSG_CHANNEL_FAILURE) - fatal("Request for subsystem '%.*s' failed on channel %d", - len, (u_char *)buffer_ptr(&command), id); -} - -void -client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt) -{ - int i; - - i = client_global_request_id++; - if (i >= options.num_remote_forwards) - return; - debug("remote forward %s for: listen %d, connect %s:%d", - type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", - options.remote_forwards[i].listen_port, - options.remote_forwards[i].connect_host, - options.remote_forwards[i].connect_port); - if (type == SSH2_MSG_REQUEST_FAILURE) { - if (options.exit_on_forward_failure) - fatal("Error: remote port forwarding failed for " - "listen port %d", - options.remote_forwards[i].listen_port); - else - logit("Warning: remote port forwarding failed for " - "listen port %d", - options.remote_forwards[i].listen_port); - } -} - -static void -ssh_control_listener(void) -{ - struct sockaddr_un addr; - mode_t old_umask; - int addr_len; - - if (options.control_path == NULL || - options.control_master == SSHCTL_MASTER_NO) - return; - - debug("setting up multiplex master socket"); - - memset(&addr, '\0', sizeof(addr)); - addr.sun_family = AF_UNIX; - addr_len = offsetof(struct sockaddr_un, sun_path) + - strlen(options.control_path) + 1; - - if (strlcpy(addr.sun_path, options.control_path, - sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) - fatal("ControlPath too long"); - - if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - fatal("%s socket(): %s", __func__, strerror(errno)); - - old_umask = umask(0177); - if (bind(control_fd, (struct sockaddr *)&addr, addr_len) == -1) { - control_fd = -1; - if (errno == EINVAL || errno == EADDRINUSE) - fatal("ControlSocket %s already exists", - options.control_path); - else - fatal("%s bind(): %s", __func__, strerror(errno)); - } - umask(old_umask); - - if (listen(control_fd, 64) == -1) - fatal("%s listen(): %s", __func__, strerror(errno)); - - set_nonblock(control_fd); -} - /* request pty/x11/agent/tcpfwd/shell for channel */ static void ssh_session2_setup(int id, void *arg) @@ -1120,7 +1139,8 @@ ssh_session2_setup(int id, void *arg) client_x11_get_proto(display, options.xauth_location, options.forward_x11_trusted, &proto, &data); /* Request forwarding with authentication spoofing. */ - debug("Requesting X11 forwarding with authentication spoofing."); + debug("Requesting X11 forwarding with authentication " + "spoofing."); x11_request_forwarding_with_spoofing(id, display, proto, data); interactive = 1; /* XXX wait for reply */ @@ -1133,35 +1153,8 @@ 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); + NULL, fileno(stdin), &command, environ); packet_set_interactive(interactive); } @@ -1207,7 +1200,8 @@ ssh_session2_open(void) channel_send_open(c->self); if (!no_shell_flag) - channel_register_confirm(c->self, ssh_session2_setup, NULL); + channel_register_open_confirm(c->self, + ssh_session2_setup, NULL); return c->self; } @@ -1219,20 +1213,33 @@ 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(); + /* If we don't expect to open a new session, then disallow it */ + if (options.control_master == SSHCTL_MASTER_NO) { + debug("Requesting no-more-sessions@openssh.com"); + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("no-more-sessions@openssh.com"); + packet_put_char(0); + packet_send(); + } + /* Execute a local command */ if (options.local_command != NULL && options.permit_local_command) ssh_local_cmd(options.local_command); + /* Start listening for multiplex clients */ + muxserver_listen(); + /* If requested, let ssh continue in the background. */ - if (fork_after_authentication_flag) + if (fork_after_authentication_flag) { + fork_after_authentication_flag = 0; if (daemon(1, 1) < 0) fatal("daemon() failed: %.200s", strerror(errno)); + } return client_loop(tty_flag, tty_flag ? options.escape_char : SSH_ESCAPECHAR_NONE, id); @@ -1242,6 +1249,7 @@ static void load_public_identity_files(void) { char *filename, *cp, thishost[NI_MAXHOST]; + char *pwdir = NULL, *pwname = NULL; int i = 0; Key *public; struct passwd *pw; @@ -1254,9 +1262,11 @@ load_public_identity_files(void) int count = 0; for (i = 0; keys[i] != NULL; i++) { count++; - memmove(&options.identity_files[1], &options.identity_files[0], + memmove(&options.identity_files[1], + &options.identity_files[0], sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1)); - memmove(&options.identity_keys[1], &options.identity_keys[0], + memmove(&options.identity_keys[1], + &options.identity_keys[0], sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); options.num_identity_files++; options.identity_keys[0] = keys[i]; @@ -1270,14 +1280,16 @@ load_public_identity_files(void) #endif /* SMARTCARD */ if ((pw = getpwuid(original_real_uid)) == NULL) fatal("load_public_identity_files: getpwuid failed"); + pwname = xstrdup(pw->pw_name); + pwdir = xstrdup(pw->pw_dir); if (gethostname(thishost, sizeof(thishost)) == -1) fatal("load_public_identity_files: gethostname: %s", strerror(errno)); for (; i < options.num_identity_files; i++) { cp = tilde_expand_filename(options.identity_files[i], original_real_uid); - filename = percent_expand(cp, "d", pw->pw_dir, - "u", pw->pw_name, "l", thishost, "h", host, + filename = percent_expand(cp, "d", pwdir, + "u", pwname, "l", thishost, "h", host, "r", options.user, (char *)NULL); xfree(cp); public = key_load_public(filename, NULL); @@ -1287,216 +1299,8 @@ load_public_identity_files(void) options.identity_files[i] = filename; options.identity_keys[i] = public; } -} - -static void -control_client_sighandler(int signo) -{ - control_client_terminate = signo; -} - -static void -control_client_sigrelay(int signo) -{ - if (control_server_pid > 1) - kill(control_server_pid, signo); -} - -static int -env_permitted(char *env) -{ - int i, ret; - char name[1024], *cp; - - if ((cp = strchr(env, '=')) == NULL || cp == env) - return (0); - ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env); - if (ret <= 0 || (size_t)ret >= sizeof(name)) - fatal("env_permitted: name '%.100s...' too long", env); - - for (i = 0; i < options.num_send_env; i++) - if (match_pattern(name, options.send_env[i])) - return (1); - - return (0); -} - -static void -control_client(const char *path) -{ - struct sockaddr_un addr; - int i, r, fd, sock, exitval, num_env, addr_len; - Buffer m; - char *term; - extern char **environ; - u_int flags; - - if (mux_command == 0) - mux_command = SSHMUX_COMMAND_OPEN; - - switch (options.control_master) { - case SSHCTL_MASTER_AUTO: - case SSHCTL_MASTER_AUTO_ASK: - debug("auto-mux: Trying existing master"); - /* FALLTHROUGH */ - case SSHCTL_MASTER_NO: - break; - default: - return; - } - - memset(&addr, '\0', sizeof(addr)); - addr.sun_family = AF_UNIX; - addr_len = offsetof(struct sockaddr_un, sun_path) + - strlen(path) + 1; - - if (strlcpy(addr.sun_path, path, - sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) - fatal("ControlPath too long"); - - if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - fatal("%s socket(): %s", __func__, strerror(errno)); - - if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) { - if (mux_command != SSHMUX_COMMAND_OPEN) { - fatal("Control socket connect(%.100s): %s", path, - strerror(errno)); - } - if (errno == ENOENT) - debug("Control socket \"%.100s\" does not exist", path); - else { - error("Control socket connect(%.100s): %s", path, - strerror(errno)); - } - close(sock); - return; - } - - if (stdin_null_flag) { - if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1) - fatal("open(/dev/null): %s", strerror(errno)); - if (dup2(fd, STDIN_FILENO) == -1) - fatal("dup2: %s", strerror(errno)); - if (fd > STDERR_FILENO) - close(fd); - } - - term = getenv("TERM"); - - flags = 0; - if (tty_flag) - flags |= SSHMUX_FLAG_TTY; - if (subsystem_flag) - flags |= SSHMUX_FLAG_SUBSYS; - if (options.forward_x11) - flags |= SSHMUX_FLAG_X11_FWD; - if (options.forward_agent) - flags |= SSHMUX_FLAG_AGENT_FWD; - - buffer_init(&m); - - /* Send our command to server */ - buffer_put_int(&m, mux_command); - buffer_put_int(&m, flags); - if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) - fatal("%s: msg_send", __func__); - buffer_clear(&m); - - /* Get authorisation status and PID of controlee */ - if (ssh_msg_recv(sock, &m) == -1) - fatal("%s: msg_recv", __func__); - if (buffer_get_char(&m) != SSHMUX_VER) - fatal("%s: wrong version", __func__); - if (buffer_get_int(&m) != 1) - fatal("Connection to master denied"); - control_server_pid = buffer_get_int(&m); - - buffer_clear(&m); - - switch (mux_command) { - case SSHMUX_COMMAND_ALIVE_CHECK: - fprintf(stderr, "Master running (pid=%d)\r\n", - control_server_pid); - exit(0); - case SSHMUX_COMMAND_TERMINATE: - fprintf(stderr, "Exit request sent.\r\n"); - exit(0); - case SSHMUX_COMMAND_OPEN: - /* continue below */ - break; - default: - fatal("silly mux_command %d", mux_command); - } - - /* SSHMUX_COMMAND_OPEN */ - buffer_put_cstring(&m, term ? term : ""); - buffer_append(&command, "\0", 1); - buffer_put_cstring(&m, buffer_ptr(&command)); - - if (options.num_send_env == 0 || environ == NULL) { - buffer_put_int(&m, 0); - } else { - /* Pass environment */ - num_env = 0; - for (i = 0; environ[i] != NULL; i++) - if (env_permitted(environ[i])) - num_env++; /* Count */ - - buffer_put_int(&m, num_env); - - for (i = 0; environ[i] != NULL && num_env >= 0; i++) - if (env_permitted(environ[i])) { - num_env--; - buffer_put_cstring(&m, environ[i]); - } - } - - if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) - fatal("%s: msg_send", __func__); - - mm_send_fd(sock, STDIN_FILENO); - mm_send_fd(sock, STDOUT_FILENO); - mm_send_fd(sock, STDERR_FILENO); - - /* Wait for reply, so master has a chance to gather ttymodes */ - buffer_clear(&m); - if (ssh_msg_recv(sock, &m) == -1) - fatal("%s: msg_recv", __func__); - if (buffer_get_char(&m) != SSHMUX_VER) - fatal("%s: wrong version", __func__); - buffer_free(&m); - - signal(SIGHUP, control_client_sighandler); - signal(SIGINT, control_client_sighandler); - signal(SIGTERM, control_client_sighandler); - signal(SIGWINCH, control_client_sigrelay); - - 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)); - 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) - fatal("%s: read %s", __func__, strerror(errno)); - } - - if (control_client_terminate) - debug2("Exiting on signal %d", control_client_terminate); - - close(sock); - - leave_raw_mode(); - - if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) - fprintf(stderr, "Connection to master closed.\r\n"); - - exit(exitval); + bzero(pwname, strlen(pwname)); + xfree(pwname); + bzero(pwdir, strlen(pwdir)); + xfree(pwdir); } diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config index 07e4086..25dede6 100644 --- a/crypto/openssh/ssh_config +++ b/crypto/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 $ # $FreeBSD$ # This is the ssh client system-wide configuration file. See @@ -39,8 +39,9 @@ # 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 # PermitLocalCommand no -# VersionAddendum FreeBSD-20061110 +# VersionAddendum FreeBSD-20080801 diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5 index dd22ccc..df9f575 100644 --- a/crypto/openssh/ssh_config.5 +++ b/crypto/openssh/ssh_config.5 @@ -34,19 +34,17 @@ .\" (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.97 2006/07/27 08:00:50 jmc Exp $ +.\" $OpenBSD: ssh_config.5,v 1.111 2008/06/26 11:46:31 grunk Exp $ .\" $FreeBSD$ -.Dd September 25, 1999 +.Dd $Mdocdate: June 26 2008 $ .Dt SSH_CONFIG 5 .Os .Sh NAME .Nm ssh_config .Nd OpenSSH SSH client configuration files .Sh SYNOPSIS -.Bl -tag -width Ds -compact -.It Pa ~/.ssh/config -.It Pa /etc/ssh/ssh_config -.El +.Nm ~/.ssh/config +.Nm /etc/ssh/ssh_config .Sh DESCRIPTION .Xr ssh 1 obtains configuration data from the following sources in @@ -106,6 +104,7 @@ Restricts the following declarations (up to the next .Cm Host keyword) to be only for those hosts that match one of the patterns given after the keyword. +If more than one pattern is provided, they should be separated by whitepsace. A single .Ql * as a pattern can be used to provide global @@ -390,7 +389,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 @@ -579,6 +578,14 @@ escape characters: It is possible to have multiple identity files specified in configuration files; all these identities will be tried in sequence. +.It Cm KbdInteractiveAuthentication +Specifies whether to use keyboard-interactive authentication. +The argument to this keyword must be +.Dq yes +or +.Dq no . +The default is +.Dq yes . .It Cm KbdInteractiveDevices Specifies the list of methods to use in keyboard-interactive authentication. Multiple method names must be comma-separated. @@ -594,7 +601,22 @@ and Specifies a command to execute on the local machine after successfully connecting to the server. The command string extends to the end of the line, and is executed with -.Pa /bin/sh . +the user's shell. +The following escape character substitutions will be performed: +.Ql %d +(local user's home directory), +.Ql %h +(remote host name), +.Ql %l +(local host name), +.Ql %n +(host name as provided on the command line), +.Ql %p +(remote port), +.Ql %r +(remote user name) or +.Ql %u +(local user name). This directive is ignored unless .Cm PermitLocalCommand has been enabled. @@ -644,7 +666,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 @@ -715,7 +740,7 @@ if version 2 is not available. Specifies the command to use to connect to the server. The command string extends to the end of the line, and is executed with -.Pa /bin/sh . +the user's shell. In the command string, .Ql %h will be substituted by the host name to @@ -1040,7 +1065,17 @@ in Specifies a string to append to the regular version string to identify OS- or site-specific modifications. The default is -.Dq FreeBSD-20061110 . +.Dq FreeBSD-20080801 . +.It Cm VisualHostKey +If this flag is set to +.Dq yes , +an ASCII art representation of the remote host key fingerprint is +printed additionally to the hex fingerprint string. +If this flag is set to +.Dq no , +only the hex fingerprint string will be printed. +The default is +.Dq no . .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 diff --git a/crypto/openssh/ssh_namespace.h b/crypto/openssh/ssh_namespace.h index 94041b1..71e3c28 100644 --- a/crypto/openssh/ssh_namespace.h +++ b/crypto/openssh/ssh_namespace.h @@ -374,3 +374,31 @@ #define xmmap ssh_xmmap #define xrealloc ssh_xrealloc #define xstrdup ssh_xstrdup +#define fmt_scaled ssh_fmt_scaled +#define scan_scaled ssh_scan_scaled +#define addr_match_list ssh_addr_match_list +#define packet_get_string_ptr ssh_packet_get_string_ptr +#define packet_set_timeout ssh_packet_set_timeout +#define mac_clear ssh_mac_clear +#define mac_setup ssh_mac_setup +#define umac_delete ssh_umac_delete +#define umac_final ssh_umac_final +#define umac_new ssh_umac_new +#define umac_update ssh_umac_update +#define chan_rcvd_eow ssh_chan_rcvd_eow +#define channel_input_status_confirm ssh_channel_input_status_confirm +#define channel_print_adm_permitted_opens ssh_channel_print_adm_permitted_opens +#define channel_register_open_confirm ssh_channel_register_open_confirm +#define channel_register_status_confirm ssh_channel_register_status_confirm +#define buffer_get_string_ptr ssh_buffer_get_string_ptr +#define ms_subtract_diff ssh_ms_subtract_diff +#define ms_to_timeval ssh_ms_to_timeval +#define fatal ssh_fatal +#define debug ssh_debug +#define debug2 ssh_debug2 +#define debug3 ssh_debug3 +#define error ssh_error +#define log_facility_name ssh_log_facility_name +#define log_level_name ssh_log_level_name +#define logit ssh_logit +#define verbose ssh_verbose diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index a222233..52c8b18 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -1,4 +1,5 @@ -/* $OpenBSD: sshconnect.c,v 1.200 2006/10/10 10:12:45 markus Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.211 2008/07/01 07:24:22 dtucker Exp $ */ +/* $FreeBSD$ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -86,7 +87,10 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) char *command_string, *tmp; int pin[2], pout[2]; pid_t pid; - char strport[NI_MAXSERV]; + char *shell, strport[NI_MAXSERV]; + + if ((shell = getenv("SHELL")) == NULL) + shell = _PATH_BSHELL; /* Convert the port number into a string. */ snprintf(strport, sizeof strport, "%hu", port); @@ -132,7 +136,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) /* Stderr is left as it is so that error messages get printed on the user's terminal. */ - argv[0] = _PATH_BSHELL; + argv[0] = shell; argv[1] = "-c"; argv[2] = command_string; argv[3] = NULL; @@ -158,6 +162,8 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) /* Set the connection file descriptors. */ packet_set_connection(pout[0], pin[1]); + packet_set_timeout(options.server_alive_interval, + options.server_alive_count_max); /* Indicate OK return */ return 0; @@ -201,10 +207,10 @@ ssh_create_socket(int privileged, struct addrinfo *ai) hints.ai_socktype = ai->ai_socktype; hints.ai_protocol = ai->ai_protocol; hints.ai_flags = AI_PASSIVE; - gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); + gaierr = getaddrinfo(options.bind_address, NULL, &hints, &res); if (gaierr) { error("getaddrinfo: %s: %s", options.bind_address, - gai_strerror(gaierr)); + ssh_gai_strerror(gaierr)); close(sock); return -1; } @@ -220,30 +226,36 @@ ssh_create_socket(int privileged, struct addrinfo *ai) static int timeout_connect(int sockfd, const struct sockaddr *serv_addr, - socklen_t addrlen, int timeout) + socklen_t addrlen, int *timeoutp) { fd_set *fdset; - struct timeval tv; + struct timeval tv, t_start; socklen_t optlen; int optval, rc, result = -1; - if (timeout <= 0) - return (connect(sockfd, serv_addr, addrlen)); + gettimeofday(&t_start, NULL); + + if (*timeoutp <= 0) { + result = connect(sockfd, serv_addr, addrlen); + goto done; + } set_nonblock(sockfd); rc = connect(sockfd, serv_addr, addrlen); if (rc == 0) { unset_nonblock(sockfd); - return (0); + result = 0; + goto done; + } + if (errno != EINPROGRESS) { + result = -1; + goto done; } - if (errno != EINPROGRESS) - return (-1); fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS), sizeof(fd_mask)); FD_SET(sockfd, fdset); - tv.tv_sec = timeout; - tv.tv_usec = 0; + ms_to_timeval(&tv, *timeoutp); for (;;) { rc = select(sockfd + 1, NULL, fdset, NULL, &tv); @@ -282,6 +294,16 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr, } xfree(fdset); + + done: + if (result == 0 && *timeoutp > 0) { + ms_subtract_diff(&t_start, timeoutp); + if (*timeoutp <= 0) { + errno = ETIMEDOUT; + result = -1; + } + } + return (result); } @@ -298,8 +320,8 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr, */ int ssh_connect(const char *host, struct sockaddr_storage * hostaddr, - u_short port, int family, int connection_attempts, - int needpriv, const char *proxy_command) + u_short port, int family, int connection_attempts, int *timeout_ms, + int want_keepalive, int needpriv, const char *proxy_command) { int gaierr; int on = 1; @@ -320,8 +342,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, hints.ai_socktype = SOCK_STREAM; snprintf(strport, sizeof strport, "%u", port); if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) - fatal("%s: %.100s: %s", __progname, host, - gai_strerror(gaierr)); + fatal("%s: Could not resolve hostname %.100s: %s", __progname, + host, ssh_gai_strerror(gaierr)); for (attempt = 0; attempt < connection_attempts; attempt++) { if (attempt > 0) { @@ -352,7 +374,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, continue; if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, - options.connection_timeout) >= 0) { + timeout_ms) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; @@ -379,13 +401,15 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, debug("Connection established."); /* Set SO_KEEPALIVE if requested. */ - if (options.tcp_keep_alive && + if (want_keepalive && setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)) < 0) error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); /* Set the connection. */ packet_set_connection(sock, sock); + packet_set_timeout(options.server_alive_interval, + options.server_alive_count_max); return 0; } @@ -395,7 +419,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, * identification string. */ static void -ssh_exchange_identification(void) +ssh_exchange_identification(int timeout_ms) { char buf[256], remote_version[256]; /* must be same size! */ int remote_major, remote_minor, mismatch; @@ -403,16 +427,44 @@ ssh_exchange_identification(void) int connection_out = packet_get_connection_out(); int minor1 = PROTOCOL_MINOR_1; u_int i, n; + size_t len; + int fdsetsz, remaining, rc; + struct timeval t_start, t_remaining; + fd_set *fdset; + + fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask); + fdset = xcalloc(1, fdsetsz); /* Read other side's version identification. */ + remaining = timeout_ms; for (n = 0;;) { for (i = 0; i < sizeof(buf) - 1; i++) { - size_t len = atomicio(read, connection_in, &buf[i], 1); + if (timeout_ms > 0) { + gettimeofday(&t_start, NULL); + ms_to_timeval(&t_remaining, remaining); + FD_SET(connection_in, fdset); + rc = select(connection_in + 1, fdset, NULL, + fdset, &t_remaining); + ms_subtract_diff(&t_start, &remaining); + if (rc == 0 || remaining <= 0) + fatal("Connection timed out during " + "banner exchange"); + if (rc == -1) { + if (errno == EINTR) + continue; + fatal("ssh_exchange_identification: " + "select: %s", strerror(errno)); + } + } + + len = atomicio(read, connection_in, &buf[i], 1); if (len != 1 && errno == EPIPE) - fatal("ssh_exchange_identification: Connection closed by remote host"); + fatal("ssh_exchange_identification: " + "Connection closed by remote host"); else if (len != 1) - fatal("ssh_exchange_identification: read: %.100s", strerror(errno)); + fatal("ssh_exchange_identification: " + "read: %.100s", strerror(errno)); if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; @@ -423,7 +475,8 @@ ssh_exchange_identification(void) break; } if (++n > 65536) - fatal("ssh_exchange_identification: No banner received"); + fatal("ssh_exchange_identification: " + "No banner received"); } buf[sizeof(buf) - 1] = 0; if (strncmp(buf, "SSH-", 4) == 0) @@ -431,6 +484,7 @@ ssh_exchange_identification(void) debug("ssh_exchange_identification: %s", buf); } server_version_string = xstrdup(buf); + xfree(fdset); /* * Check that the versions match. In future this might accept @@ -484,10 +538,10 @@ ssh_exchange_identification(void) (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, remote_major); /* Send our own protocol version identification. */ - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, - SSH_VERSION); + SSH_VERSION, compat20 ? "\r\n" : "\n"); if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); @@ -536,14 +590,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, Key *file_key; const char *type = key_type(host_key); char *ip = NULL, *host = NULL; - char hostline[1000], *hostp, *fp; + char hostline[1000], *hostp, *fp, *ra; HostStatus host_status; HostStatus ip_status; int r, local = 0, host_ip_differ = 0; int salen; char ntop[NI_MAXHOST]; char msg[1024]; - int len, host_line, ip_line; + int len, host_line, ip_line, cancelled_forwarding = 0; const char *host_file = NULL, *ip_file = NULL; /* @@ -590,6 +644,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, } else { ip = xstrdup("<no hostip for proxy command>"); } + /* * Turn off check_host_ip if the connection is to localhost, via proxy * command or if we don't have a hostname to compare with @@ -674,6 +729,13 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, logit("Warning: Permanently added the %s host " "key for IP address '%.128s' to the list " "of known hosts.", type, ip); + } else if (options.visual_host_key) { + fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + ra = key_fingerprint(host_key, SSH_FP_MD5, + SSH_FP_RANDOMART); + logit("Host key fingerprint is %s\n%s\n", fp, ra); + xfree(ra); + xfree(fp); } break; case HOST_NEW: @@ -709,6 +771,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, snprintf(msg1, sizeof(msg1), "."); /* The default */ fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + ra = key_fingerprint(host_key, SSH_FP_MD5, + SSH_FP_RANDOMART); msg2[0] = '\0'; if (options.verify_host_key_dns) { if (matching_host_key_dns) @@ -723,10 +787,14 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" - "%s key fingerprint is %s.\n%s" + "%s key fingerprint is %s.%s%s\n%s" "Are you sure you want to continue connecting " "(yes/no)? ", - host, ip, msg1, type, fp, msg2); + host, ip, msg1, type, fp, + options.visual_host_key ? "\n" : "", + options.visual_host_key ? ra : "", + msg2); + xfree(ra); xfree(fp); if (!confirm(msg)) goto fail; @@ -779,7 +847,7 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, error("@ WARNING: POSSIBLE DNS SPOOFING DETECTED! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("The %s host key for %s has changed,", type, host); - error("and the key for the according IP address %s", ip); + error("and the key for the corresponding IP address %s", ip); error("%s. This could either mean that", key_msg); error("DNS SPOOFING is happening or the IP address for the host"); error("and its host key have changed at the same time."); @@ -811,27 +879,32 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, error("Password authentication is disabled to avoid " "man-in-the-middle attacks."); options.password_authentication = 0; + cancelled_forwarding = 1; } if (options.kbd_interactive_authentication) { error("Keyboard-interactive authentication is disabled" " to avoid man-in-the-middle attacks."); options.kbd_interactive_authentication = 0; options.challenge_response_authentication = 0; + cancelled_forwarding = 1; } if (options.challenge_response_authentication) { error("Challenge/response authentication is disabled" " to avoid man-in-the-middle attacks."); options.challenge_response_authentication = 0; + cancelled_forwarding = 1; } if (options.forward_agent) { error("Agent forwarding is disabled to avoid " "man-in-the-middle attacks."); options.forward_agent = 0; + cancelled_forwarding = 1; } if (options.forward_x11) { error("X11 forwarding is disabled to avoid " "man-in-the-middle attacks."); options.forward_x11 = 0; + cancelled_forwarding = 1; } if (options.num_local_forwards > 0 || options.num_remote_forwards > 0) { @@ -839,12 +912,18 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, "man-in-the-middle attacks."); options.num_local_forwards = options.num_remote_forwards = 0; + cancelled_forwarding = 1; } if (options.tun_open != SSH_TUNMODE_NO) { error("Tunnel forwarding is disabled to avoid " "man-in-the-middle attacks."); options.tun_open = SSH_TUNMODE_NO; + cancelled_forwarding = 1; } + if (options.exit_on_forward_failure && cancelled_forwarding) + fatal("Error: forwarding disabled due to host key " + "check failure"); + /* * XXX Should permit the user to change to use the new id. * This could be done by converting the host key to an @@ -943,7 +1022,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) */ void ssh_login(Sensitive *sensitive, const char *orighost, - struct sockaddr *hostaddr, struct passwd *pw) + struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms) { char *host, *cp; char *server_user, *local_user; @@ -958,7 +1037,7 @@ ssh_login(Sensitive *sensitive, const char *orighost, *cp = (char)tolower(*cp); /* Exchange protocol version identification strings with the server. */ - ssh_exchange_identification(); + ssh_exchange_identification(timeout_ms); /* Put the connection into non-blocking mode. */ packet_set_nonblocking(); @@ -997,18 +1076,24 @@ static int show_key_from_file(const char *file, const char *host, int keytype) { Key *found; - char *fp; + char *fp, *ra; int line, ret; found = key_new(keytype); if ((ret = lookup_key_in_hostfile_by_type(file, host, keytype, found, &line))) { fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); + if (options.visual_host_key) + ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART); logit("WARNING: %s key found for host %s\n" "in %s:%d\n" - "%s key fingerprint %s.", + "%s key fingerprint %s.%s%s\n", key_type(found), host, file, line, - key_type(found), fp); + key_type(found), fp, + options.visual_host_key ? "\n" : "", + options.visual_host_key ? ra : ""); + if (options.visual_host_key) + xfree(ra); xfree(fp); } key_free(found); diff --git a/crypto/openssh/sshconnect.h b/crypto/openssh/sshconnect.h index 4e66bbf..75bde1a 100644 --- a/crypto/openssh/sshconnect.h +++ b/crypto/openssh/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.24 2007/09/04 11:15:56 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -33,10 +33,10 @@ struct Sensitive { int ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int, - int, const char *); + int *, int, int, const char *); void -ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *); +ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int); int verify_host_key(char *, struct sockaddr *, Key *); diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index dd971a9..389bec9 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/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.166 2008/07/17 08:48:00 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -31,12 +31,16 @@ #include <sys/stat.h> #include <errno.h> +#include <netdb.h> #include <pwd.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> #include <string.h> #include <unistd.h> +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +#include <vis.h> +#endif #include "openbsd-compat/sys-queue.h" @@ -129,7 +133,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) options.hostkeyalgorithms; if (options.rekey_limit) - packet_set_rekey_limit(options.rekey_limit); + packet_set_rekey_limit((u_int32_t)options.rekey_limit); /* start key exchange */ kex = kex_setup(myproposal); @@ -373,14 +377,21 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) void input_userauth_banner(int type, u_int32_t seq, void *ctxt) { - char *msg, *lang; + char *msg, *raw, *lang; + u_int len; debug3("input_userauth_banner"); - msg = packet_get_string(NULL); + raw = packet_get_string(&len); lang = packet_get_string(NULL); - if (options.log_level >= SYSLOG_LEVEL_INFO) + if (options.log_level >= SYSLOG_LEVEL_INFO) { + if (len > 65536) + len = 65536; + msg = xmalloc(len * 4); /* max expansion from strnvis() */ + strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL); fprintf(stderr, "%s", msg); - xfree(msg); + xfree(msg); + } + xfree(raw); xfree(lang); } @@ -1307,7 +1318,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 +1342,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/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 index 6e283b0..117c970 100644 --- a/crypto/openssh/sshd.8 +++ b/crypto/openssh/sshd.8 @@ -34,9 +34,9 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.234 2006/08/21 08:15:57 dtucker Exp $ +.\" $OpenBSD: sshd.8,v 1.246 2008/07/02 02:24:18 djm Exp $ .\" $FreeBSD$ -.Dd September 25, 1999 +.Dd $Mdocdate: July 2 2008 $ .Dt SSHD 8 .Os .Sh NAME @@ -45,8 +45,9 @@ .Sh SYNOPSIS .Nm sshd .Bk -words -.Op Fl 46Ddeiqt +.Op Fl 46DdeiqTt .Op Fl b Ar bits +.Op Fl C Ar connection_spec .Op Fl f Ar config_file .Op Fl g Ar login_grace_time .Op Fl h Ar host_key_file @@ -59,8 +60,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 @@ -97,7 +101,25 @@ Forces to use IPv6 addresses only. .It Fl b Ar bits Specifies the number of bits in the ephemeral protocol version 1 -server key (default 768). +server key (default 1024). +.It Fl C Ar connection_spec +Specify the connection parameters to use for the +.Fl T +extended test mode. +If provided, any +.Cm Match +directives in the configuration file +that would apply to the specified user, host, and address will be set before +the configuration is written to standard output. +The connection parameters are supplied as keyword=value pairs. +The keywords are +.Dq user , +.Dq host , +and +.Dq addr . +All are required and may be supplied in any order, either with multiple +.Fl C +options or as a comma-separated list. .It Fl D When this option is specified, .Nm @@ -118,7 +140,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 . @@ -139,6 +161,8 @@ host key files are normally not readable by anyone but root). The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and +.Pa /etc/ssh/ssh_host_rsa_key +and .Pa /etc/ssh/ssh_host_dsa_key for protocol version 2. It is possible to have multiple host key files for @@ -187,6 +211,15 @@ Quiet mode. Nothing is sent to the system log. Normally the beginning, authentication, and termination of each connection is logged. +.It Fl T +Extended test mode. +Check the validity of the configuration file, output the effective configuration +to stdout and then exit. +Optionally, +.Cm Match +rules may be applied by specifying the connection parameters using one or more +.Fl C +options. .It Fl t Test mode. Only check the validity of the configuration file and sanity of the keys. @@ -272,7 +305,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 @@ -298,8 +331,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 @@ -500,23 +534,27 @@ This option is automatically disabled if .Cm UseLogin is enabled. .It Cm from="pattern-list" -Specifies that in addition to public key authentication, the canonical name -of the remote host must be present in the comma-separated list of -patterns. -The purpose -of this option is to optionally increase security: public key authentication -by itself does not trust the network or name servers or anything (but -the key); however, if somebody somehow steals the key, the key -permits an intruder to log in from anywhere in the world. -This additional option makes using a stolen key more difficult (name -servers and/or routers would have to be compromised in addition to -just the key). -.Pp +Specifies that in addition to public key authentication, either the canonical +name of the remote host or its IP address must be present in the +comma-separated list of patterns. See .Sx PATTERNS in .Xr ssh_config 5 for more information on patterns. +.Pp +In addition to the wildcard matching that may be applied to hostnames or +addresses, a +.Cm from +stanza may match IP addressess using CIDR address/masklen notation. +.Pp +The purpose of this option is to optionally increase security: public key +authentication by itself does not trust the network or name servers or +anything (but the key); however, if somebody somehow steals the key, the key +permits an intruder to log in from anywhere in the world. +This additional option makes using a stolen key more difficult (name +servers and/or routers would have to be compromised in addition to +just the key). .It Cm no-agent-forwarding Forbids authentication agent forwarding when this key is used for authentication. @@ -528,6 +566,9 @@ This might be used, e.g. in connection with the option. .It Cm no-pty Prevents tty allocation (a request to allocate a pty will fail). +.It Cm no-user-rc +Disables execution of +.Pa ~/.ssh/rc . .It Cm no-X11-forwarding Forbids X11 forwarding when this key is used for authentication. Any X11 forward requests by the client will return an error. @@ -679,6 +720,13 @@ This file is used in exactly the same way as but allows host-based authentication without permitting login with rlogin/rsh. .Pp +.It ~/.ssh/ +This directory is the default location for all user-specific configuration +and authentication information. +There is no general requirement to keep the entire contents of this directory +secret, but the recommended permissions are read/write/execute for the user, +and not accessible by others. +.Pp .It ~/.ssh/authorized_keys Lists the public keys (RSA/DSA) that can be used for logging in as this user. The format of this file is described above. @@ -759,15 +807,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 @@ -791,6 +830,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 . @@ -827,6 +875,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/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 5832526..901615d 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.348 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -55,6 +55,7 @@ __RCSID("$FreeBSD$"); # include <sys/time.h> #endif #include "openbsd-compat/sys-tree.h" +#include "openbsd-compat/sys-queue.h" #include <sys/wait.h> #include <errno.h> @@ -76,6 +77,8 @@ __RCSID("$FreeBSD$"); #include <openssl/bn.h> #include <openssl/md5.h> #include <openssl/rand.h> +#include "openbsd-compat/openssl-compat.h" + #ifdef HAVE_SECUREWARE #include <sys/security.h> #include <prot.h> @@ -130,8 +133,8 @@ __RCSID("$FreeBSD$"); #ifdef LIBWRAP #include <tcpd.h> #include <syslog.h> -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; +int allow_severity; +int deny_severity; #endif /* LIBWRAP */ #ifndef O_NOCTTY @@ -315,6 +318,7 @@ sighup_restart(void) logit("Received SIGHUP; restarting."); close_listen_socks(); close_startup_pipes(); + alarm(0); /* alarm timer persists across exec */ execv(saved_argv[0], saved_argv); logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno)); @@ -375,9 +379,6 @@ grace_alarm_handler(int sig) static void generate_ephemeral_server_key(void) { - u_int32_t rnd = 0; - int i; - verbose("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "", options.server_key_bits); if (sensitive_data.server_key != NULL) @@ -386,12 +387,7 @@ generate_ephemeral_server_key(void) options.server_key_bits); verbose("RSA key generation complete."); - for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { - if (i % 4 == 0) - rnd = arc4random(); - sensitive_data.ssh1_cookie[i] = rnd & 0xff; - rnd >>= 8; - } + arc4random_buf(sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); arc4random_stir(); } @@ -413,7 +409,7 @@ sshd_exchange_identification(int sock_in, int sock_out) int mismatch; int remote_major, remote_minor; int major, minor; - char *s; + char *s, *newline = "\n"; char buf[256]; /* Must not be larger than remote_version. */ char remote_version[256]; /* Must be at least as big as buf. */ @@ -424,11 +420,13 @@ sshd_exchange_identification(int sock_in, int sock_out) } else if (options.protocol & SSH_PROTO_2) { major = PROTOCOL_MAJOR_2; minor = PROTOCOL_MINOR_2; + newline = "\r\n"; } else { major = PROTOCOL_MAJOR_1; minor = PROTOCOL_MINOR_1; } - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); + snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor, + SSH_VERSION, newline); server_version_string = xstrdup(buf); /* Send our protocol version identification. */ @@ -590,15 +588,14 @@ demote_sensitive_data(void) static void privsep_preauth_child(void) { - u_int32_t rnd[256]; + u_int32_t rnd[256]; gid_t gidset[1]; - int i; /* Enable challenge-response authentication for privilege separation */ privsep_challenge_enable(); - for (i = 0; i < 256; i++) - rnd[i] = arc4random(); + arc4random_stir(); + arc4random_buf(rnd, sizeof(rnd)); RAND_seed(rnd, sizeof(rnd)); /* Demote the private keys to public keys. */ @@ -671,6 +668,8 @@ privsep_preauth(Authctxt *authctxt) static void privsep_postauth(Authctxt *authctxt) { + u_int32_t rnd[256]; + #ifdef DISABLE_FD_PASSING if (1) { #else @@ -688,7 +687,7 @@ privsep_postauth(Authctxt *authctxt) if (pmonitor->m_pid == -1) fatal("fork of unprivileged child failed"); else if (pmonitor->m_pid != 0) { - debug2("User child is on pid %ld", (long)pmonitor->m_pid); + verbose("User child is on pid %ld", (long)pmonitor->m_pid); close(pmonitor->m_recvfd); buffer_clear(&loginmsg); monitor_child_postauth(pmonitor); @@ -702,6 +701,10 @@ privsep_postauth(Authctxt *authctxt) /* Demote the private keys to public keys. */ demote_sensitive_data(); + arc4random_stir(); + arc4random_buf(rnd, sizeof(rnd)); + RAND_seed(rnd, sizeof(rnd)); + /* Drop privileges */ do_setusercontext(authctxt->pw); @@ -801,7 +804,7 @@ drop_connection(int startups) p *= startups - options.max_startups_begin; p /= options.max_startups - options.max_startups_begin; p += options.max_startups_rate; - r = arc4random() % 100; + r = arc4random_uniform(100); debug("drop_connection: p %d, r %d", p, r); return (r < p) ? 1 : 0; @@ -813,8 +816,9 @@ usage(void) fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); fprintf(stderr, -"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" -" [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n" +"usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-f config_file]\n" +" [-g login_grace_time] [-h host_key_file] [-k key_gen_time]\n" +" [-o option] [-p port] [-u len]\n" ); exit(1); } @@ -962,8 +966,7 @@ server_listen(void) ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV)) != 0) { error("getnameinfo failed: %.100s", - (ret != EAI_SYSTEM) ? gai_strerror(ret) : - strerror(errno)); + ssh_gai_strerror(ret)); continue; } /* Create socket for listening. */ @@ -986,6 +989,16 @@ server_listen(void) &on, sizeof(on)) == -1) error("setsockopt SO_REUSEADDR: %s", strerror(errno)); +#ifdef IPV6_V6ONLY + /* Only communicate in IPv6 over AF_INET6 sockets. */ + if (ai->ai_family == AF_INET6) { + if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, + &on, sizeof(on)) == -1) + error("setsockopt IPV6_V6ONLY: %s", + strerror(errno)); + } +#endif + debug("Bind to port %s on %s.", strport, ntop); /* Bind the socket to the desired port. */ @@ -1093,7 +1106,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) *newsock = accept(listen_socks[i], (struct sockaddr *)&from, &fromlen); if (*newsock < 0) { - if (errno != EINTR && errno != EWOULDBLOCK) + if (errno != EINTR && errno != EAGAIN && + errno != EWOULDBLOCK) error("accept: %.100s", strerror(errno)); continue; } @@ -1240,9 +1254,12 @@ main(int ac, char **av) int opt, i, on = 1; int sock_in = -1, sock_out = -1, newsock = -1; const char *remote_ip; + char *test_user = NULL, *test_host = NULL, *test_addr = NULL; int remote_port; - char *line; + char *line, *p, *cp; int config_s[2] = { -1 , -1 }; + u_int64_t ibytes, obytes; + mode_t new_umask; Key *key; Authctxt *authctxt; @@ -1276,7 +1293,7 @@ main(int ac, char **av) initialize_server_options(&options); /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) { + while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) { switch (opt) { case '4': options.address_family = AF_INET; @@ -1354,6 +1371,25 @@ main(int ac, char **av) case 't': test_flag = 1; break; + case 'T': + test_flag = 2; + break; + case 'C': + cp = optarg; + while ((p = strsep(&cp, ",")) && *p != '\0') { + if (strncmp(p, "addr=", 5) == 0) + test_addr = xstrdup(p + 5); + else if (strncmp(p, "host=", 5) == 0) + test_host = xstrdup(p + 5); + else if (strncmp(p, "user=", 5) == 0) + test_user = xstrdup(p + 5); + else { + fprintf(stderr, "Invalid test " + "mode specification %s\n", p); + exit(1); + } + } + break; case 'u': utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL); if (utmp_len > MAXHOSTNAMELEN) { @@ -1376,7 +1412,7 @@ main(int ac, char **av) } if (rexeced_flag || inetd_flag) rexec_flag = 0; - if (rexec_flag && (av[0] == NULL || *av[0] != '/')) + if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/'))) fatal("sshd re-exec requires execution with an absolute path"); if (rexeced_flag) closefrom(REEXEC_MIN_FREE_FD); @@ -1415,6 +1451,21 @@ main(int ac, char **av) sensitive_data.have_ssh1_key = 0; sensitive_data.have_ssh2_key = 0; + /* + * If we're doing an extended config test, make sure we have all of + * the parameters we need. If we're not doing an extended test, + * do not silently ignore connection test params. + */ + if (test_flag >= 2 && + (test_user != NULL || test_host != NULL || test_addr != NULL) + && (test_user == NULL || test_host == NULL || test_addr == NULL)) + fatal("user, host and addr are all required when testing " + "Match configs"); + if (test_flag < 2 && (test_user != NULL || test_host != NULL || + test_addr != NULL)) + fatal("Config test connection parameter (-C) provided without " + "test mode (-T)"); + /* Fetch our configuration */ buffer_init(&cfg); if (rexeced_flag) @@ -1430,6 +1481,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); @@ -1539,6 +1594,13 @@ main(int ac, char **av) "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); } + if (test_flag > 1) { + if (test_user != NULL && test_addr != NULL && test_host != NULL) + parse_server_match_config(&options, test_user, + test_host, test_addr); + dump_config(&options); + } + /* Configuration looks good, so exit if in test mode. */ if (test_flag) exit(0); @@ -1563,6 +1625,10 @@ main(int ac, char **av) rexec_argv[rexec_argc + 1] = NULL; } + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; + (void) umask(new_umask); + /* Initialize the log (it is reinitialized below in case we forked). */ if (debug_flag && (!inetd_flag || rexeced_flag)) log_stderr = 1; @@ -1605,10 +1671,6 @@ main(int ac, char **av) /* Get a connection, either from inetd or a listening TCP socket */ if (inetd_flag) { server_accept_inetd(&sock_in, &sock_out); - - if ((options.protocol & SSH_PROTO_1) && - sensitive_data.server_key == NULL) - generate_ephemeral_server_key(); } else { server_listen(); @@ -1768,6 +1830,8 @@ main(int ac, char **av) audit_connection_from(remote_ip, remote_port); #endif #ifdef LIBWRAP + allow_severity = options.log_facility|LOG_INFO; + deny_severity = options.log_facility|LOG_WARNING; /* Check whether logins are denied from this host. */ if (packet_connection_is_on_socket()) { struct request_info req; @@ -1801,6 +1865,10 @@ main(int ac, char **av) sshd_exchange_identification(sock_in, sock_out); + /* In inetd mode, generate ephemeral key only for proto 1 connections */ + if (!compat20 && inetd_flag && sensitive_data.server_key == NULL) + generate_ephemeral_server_key(); + packet_set_nonblocking(); /* allocate authentication context */ @@ -1853,6 +1921,20 @@ main(int ac, char **av) audit_event(SSH_AUTH_SUCCESS); #endif +#ifdef GSSAPI + if (options.gss_authentication) { + temporarily_use_uid(authctxt->pw); + ssh_gssapi_storecreds(); + restore_uid(); + } +#endif +#ifdef USE_PAM + if (options.use_pam) { + do_pam_setcred(1); + do_pam_session(); + } +#endif + /* * In privilege separation, we fork another child and prepare * file descriptor passing. @@ -1864,11 +1946,18 @@ main(int ac, char **av) destroy_sensitive_data(); } + packet_set_timeout(options.client_alive_interval, + options.client_alive_count_max); + /* Start session. */ do_authenticated(authctxt); /* The connection has been terminated. */ - verbose("Closing connection to %.100s", remote_ip); + packet_get_state(MODE_IN, NULL, NULL, NULL, &ibytes); + packet_get_state(MODE_OUT, NULL, NULL, NULL, &obytes); + verbose("Transferred: sent %llu, received %llu bytes", obytes, ibytes); + + verbose("Closing connection to %.500s port %d", remote_ip, remote_port); #ifdef USE_PAM if (options.use_pam) @@ -1948,7 +2037,6 @@ do_ssh1_kex(void) u_char session_key[SSH_SESSION_KEY_LENGTH]; u_char cookie[8]; u_int cipher_type, auth_mask, protocol_flags; - u_int32_t rnd = 0; /* * Generate check bytes that the client must send back in the user @@ -1959,12 +2047,7 @@ do_ssh1_kex(void) * cookie. This only affects rhosts authentication, and this is one * of the reasons why it is inherently insecure. */ - for (i = 0; i < 8; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cookie[i] = rnd & 0xff; - rnd >>= 8; - } + arc4random_buf(cookie, sizeof(cookie)); /* * Send our public key. We include in the packet 64 bits of random diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index e01d240..b5a1a48 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/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.80 2008/07/02 02:24:18 djm Exp $ # $FreeBSD$ # This is the sshd server system-wide configuration file. See @@ -14,7 +14,7 @@ # Note that some of FreeBSD's defaults differ from OpenBSD's, and # FreeBSD has a few additional options. -#VersionAddendum FreeBSD-20061110 +#VersionAddendum FreeBSD-20080801 #Port 22 #Protocol 2 @@ -22,14 +22,20 @@ #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 +#HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key # Lifetime and size of ephemeral version 1 server key #KeyRegenerationInterval 1h -#ServerKeyBits 768 +#ServerKeyBits 1024 # Logging # obsoletes QuietMode and FascistLogging @@ -42,6 +48,7 @@ #PermitRootLogin no #StrictModes yes #MaxAuthTries 6 +#MaxSessions 10 #RSAAuthentication yes #PubkeyAuthentication yes @@ -85,6 +92,7 @@ # and ChallengeResponseAuthentication to 'no'. #UsePAM yes +#AllowAgentForwarding yes #AllowTcpForwarding yes #GatewayPorts no #X11Forwarding yes @@ -103,9 +111,10 @@ #PidFile /var/run/sshd.pid #MaxStartups 10 #PermitTunnel no +#ChrootDirectory none # no default banner path -#Banner /some/path +#Banner none # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5 index ac95f7b..c977ec1 100644 --- a/crypto/openssh/sshd_config.5 +++ b/crypto/openssh/sshd_config.5 @@ -34,18 +34,16 @@ .\" (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.70 2006/08/21 08:14:01 dtucker Exp $ +.\" $OpenBSD: sshd_config.5,v 1.96 2008/07/02 02:24:18 djm Exp $ .\" $FreeBSD$ -.Dd September 25, 1999 +.Dd $Mdocdate: July 2 2008 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME .Nm sshd_config .Nd OpenSSH SSH daemon configuration file .Sh SYNOPSIS -.Bl -tag -width Ds -compact -.It Pa /etc/ssh/sshd_config -.El +.Nm /etc/ssh/sshd_config .Sh DESCRIPTION .Xr sshd 8 reads configuration data from @@ -98,6 +96,15 @@ Valid arguments are (use IPv6 only). The default is .Dq any . +.It Cm AllowAgentForwarding +Specifies whether +.Xr ssh-agent 1 +forwarding is permitted. +The default is +.Dq yes . +Note that disabling agent forwarding does not improve security +unless users are also denied shell access, as they can always install +their own forwarders. .It Cm AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. @@ -162,26 +169,58 @@ directory. The default is .Dq .ssh/authorized_keys . .It Cm Banner -In some jurisdictions, sending a warning message before authentication -may be relevant for getting legal protection. The contents of the specified file are sent to the remote user before authentication is allowed. +If the argument is +.Dq none +then no banner is displayed. This option is only available for protocol version 2. By default, no banner is displayed. .It Cm ChallengeResponseAuthentication Specifies whether challenge-response authentication is allowed. -Specifically, in -.Fx , -this controls the use of PAM (see -.Xr pam 3 ) -for authentication. -Note that this affects the effectiveness of the -.Cm PasswordAuthentication -and -.Cm PermitRootLogin -variables. +See also +.Cm UsePAM . The default is .Dq yes . +.It Cm ChrootDirectory +Specifies a path to +.Xr chroot 2 +to after authentication. +This path, and all its components, must be root-owned directories that are +not writable by any other user or group. +.Pp +The path may contain the following tokens that are expanded at runtime once +the connecting user has been authenticated: %% is replaced by a literal '%', +%h is replaced by the home directory of the user being authenticated, and +%u is replaced by the username of that user. +.Pp +The +.Cm ChrootDirectory +must contain the necessary files and directories to support the +users' session. +For an interactive session this requires at least a shell, typically +.Xr sh 1 , +and basic +.Pa /dev +nodes such as +.Xr null 4 , +.Xr zero 4 , +.Xr stdin 4 , +.Xr stdout 4 , +.Xr stderr 4 , +.Xr arandom 4 +and +.Xr tty 4 +devices. +For file transfer sessions using +.Dq sftp , +no additional configuration of the environment is necessary if the +in-process sftp server is used (see +.Cm Subsystem +for details). +.Pp +The default is not to +.Xr chroot 2 . .It Cm Ciphers Specifies the ciphers allowed for protocol version 2. Multiple ciphers must be comma-separated. @@ -294,7 +333,9 @@ for more information on patterns. .It Cm ForceCommand Forces the execution of the command specified by .Cm ForceCommand , -ignoring any command supplied by the client. +ignoring any command supplied by the client and +.Pa ~/.ssh/rc +if present. The command is invoked by using the user's login shell with the -c option. This applies to shell, command, or subsystem execution. It is most useful inside a @@ -303,6 +344,11 @@ block. The command originally supplied by the client is available in the .Ev SSH_ORIGINAL_COMMAND environment variable. +Specifying a command of +.Dq internal-sftp +will force the use of an in-process sftp server that requires no support +files when used with +.Cm ChrootDirectory . .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to ports forwarded for the client. @@ -366,6 +412,8 @@ used by SSH. The default is .Pa /etc/ssh/ssh_host_key for protocol version 1, and +.Pa /etc/ssh/ssh_host_rsa_key +and .Pa /etc/ssh/ssh_host_dsa_key for protocol version 2. Note that @@ -497,7 +545,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 @@ -506,6 +557,7 @@ line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another .Cm Match line or the end of the file. +.Pp The arguments to .Cm Match are one or more criteria-pattern pairs. @@ -515,14 +567,48 @@ The available criteria are .Cm Host , and .Cm Address . +The match patterns may consist of single entries or comma-separated +lists and may use the wildcard and negation operators described in the +.Sx PATTERNS +section of +.Xr ssh_config 5 . +.Pp +The patterns in an +.Cm Address +criteria may additionally contain addresses to match in CIDR +address/masklen format, e.g.\& +.Dq 192.0.2.0/24 +or +.Dq 3ffe:ffff::/32 . +Note that the mask length provided must be consistent with the address - +it is an error to specify a mask length that is too long for the address +or one with bits set in this host portion of the address. +For example, +.Dq 192.0.2.0/33 +and +.Dq 192.0.2.0/8 +respectively. +.Pp Only a subset of keywords may be used on the lines following a .Cm Match keyword. Available keywords are .Cm AllowTcpForwarding , +.Cm Banner , +.Cm ChrootDirectory , .Cm ForceCommand , .Cm GatewayPorts , +.Cm GSSAPIAuthentication , +.Cm HostbasedAuthentication , +.Cm KbdInteractiveAuthentication , +.Cm KerberosAuthentication , +.Cm MaxAuthTries , +.Cm MaxSessions , +.Cm PasswordAuthentication , .Cm PermitOpen , +.Cm PermitRootLogin , +.Cm RhostsRSAAuthentication , +.Cm RSAAuthentication , .Cm X11DisplayOffset , .Cm X11Forwarding , and @@ -533,6 +619,9 @@ connection. Once the number of failures reaches half this value, additional failures are logged. The default is 6. +.It Cm MaxSessions +Specifies the maximum number of open sessions permitted per network connection. +The default is 10. .It Cm MaxStartups Specifies the maximum number of concurrent unauthenticated connections to the SSH daemon. @@ -559,23 +648,10 @@ are refused if the number of unauthenticated connections reaches (60). .It Cm PasswordAuthentication Specifies whether password authentication is allowed. +See also +.Cm UsePAM . The default is -.Dq no , -unless -.Nm sshd -was built without PAM support, in which case the default is -.Dq yes . -Note that if -.Cm ChallengeResponseAuthentication -is -.Dq yes , -and the PAM authentication policy for -.Nm sshd -includes -.Xr pam_unix 8 , -password authentication will be allowed through the challenge-response -mechanism regardless of the value of -.Cm PasswordAuthentication . +.Dq no . .It Cm PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. @@ -746,7 +822,7 @@ The default is This option applies to protocol version 1 only. .It Cm ServerKeyBits Defines the number of bits in the ephemeral protocol version 1 server key. -The minimum value is 512, and the default is 768. +The minimum value is 512, and the default is 1024. .It Cm StrictModes Specifies whether .Xr sshd 8 @@ -760,11 +836,22 @@ The default is Configures an external subsystem (e.g. file transfer daemon). Arguments should be a subsystem name and a command (with optional arguments) to execute upon subsystem request. +.Pp The command .Xr sftp-server 8 implements the .Dq sftp file transfer subsystem. +.Pp +Alternately the name +.Dq internal-sftp +implements an in-process +.Dq sftp +server. +This may simplify configurations using +.Cm ChrootDirectory +to force a different filesystem root on clients. +.Pp By default no subsystems are defined. Note that this option applies to protocol version 2 only. .It Cm SyslogFacility @@ -860,7 +947,7 @@ The default is Specifies a string to append to the regular version string to identify OS- or site-specific modifications. The default is -.Dq FreeBSD-20061110 . +.Dq FreeBSD-20080801 . .It Cm X11DisplayOffset Specifies the first display number available for .Xr sshd 8 Ns 's diff --git a/crypto/openssh/sshlogin.c b/crypto/openssh/sshlogin.c index 0059ff8..cc35d60 100644 --- a/crypto/openssh/sshlogin.c +++ b/crypto/openssh/sshlogin.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshlogin.c,v 1.25 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sshlogin.c,v 1.26 2007/09/11 15:47:17 gilles Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -98,8 +98,7 @@ store_lastlog_message(const char *user, uid_t uid) if (last_login_time != 0) { time_string = ctime(&last_login_time); - if (strchr(time_string, '\n')) - *strchr(time_string, '\n') = '\0'; + time_string[strcspn(time_string, "\n")] = '\0'; if (strcmp(hostname, "") == 0) snprintf(buf, sizeof(buf), "Last login: %s\r\n", time_string); diff --git a/crypto/openssh/sshpty.c b/crypto/openssh/sshpty.c index 79c62ee..5a0d1a7 100644 --- a/crypto/openssh/sshpty.c +++ b/crypto/openssh/sshpty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshpty.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sshpty.c,v 1.28 2007/09/11 23:49:09 stevesk Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland diff --git a/crypto/openssh/sshpty.h b/crypto/openssh/sshpty.h index 7fac622..ac90035 100644 --- a/crypto/openssh/sshpty.h +++ b/crypto/openssh/sshpty.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshpty.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sshpty.h,v 1.11 2008/05/19 15:45:07 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -16,7 +16,7 @@ #include <termios.h> -struct termios get_saved_tio(void); +struct termios *get_saved_tio(void); void leave_raw_mode(void); void enter_raw_mode(void); diff --git a/crypto/openssh/sshtty.c b/crypto/openssh/sshtty.c index 0456766..21ade4e 100644 --- a/crypto/openssh/sshtty.c +++ b/crypto/openssh/sshtty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshtty.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sshtty.c,v 1.13 2008/05/19 15:45:07 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -47,10 +47,10 @@ static struct termios _saved_tio; static int _in_raw_mode = 0; -struct termios +struct termios * get_saved_tio(void) { - return _saved_tio; + return _in_raw_mode ? &_saved_tio : NULL; } void diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c index d8e2c55..e116b19 100644 --- a/crypto/openssh/ttymodes.c +++ b/crypto/openssh/ttymodes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ttymodes.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: ttymodes.c,v 1.28 2008/07/07 00:31:41 stevesk Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -298,6 +298,10 @@ tty_make_modes(int fd, struct termios *tiop) } if (tiop == NULL) { + if (fd == -1) { + debug("tty_make_modes: no fd or tio"); + goto end; + } if (tcgetattr(fd, &tio) == -1) { logit("tcgetattr: %.100s", strerror(errno)); goto end; @@ -317,12 +321,10 @@ tty_make_modes(int fd, struct termios *tiop) /* Store values of mode flags. */ #define TTYCHAR(NAME, OP) \ - debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \ buffer_put_char(&buf, OP); \ put_arg(&buf, special_char_encode(tio.c_cc[NAME])); #define TTYMODE(NAME, FIELD, OP) \ - debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \ buffer_put_char(&buf, OP); \ put_arg(&buf, ((tio.FIELD & NAME) != 0)); @@ -353,7 +355,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr) int n_bytes = 0; int failure = 0; u_int (*get_arg)(void); - int arg, arg_size; + int arg_size; if (compat20) { *n_bytes_ptr = packet_get_int(); @@ -410,16 +412,14 @@ tty_parse_modes(int fd, int *n_bytes_ptr) case OP: \ n_bytes += arg_size; \ tio.c_cc[NAME] = special_char_decode(get_arg()); \ - debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \ break; #define TTYMODE(NAME, FIELD, OP) \ case OP: \ n_bytes += arg_size; \ - if ((arg = get_arg())) \ + if (get_arg()) \ tio.FIELD |= NAME; \ else \ tio.FIELD &= ~NAME; \ - debug3("tty_parse_modes: %d %d", OP, arg); \ break; #include "ttymodes.h" diff --git a/crypto/openssh/umac.c b/crypto/openssh/umac.c new file mode 100644 index 0000000..92902bc --- /dev/null +++ b/crypto/openssh/umac.c @@ -0,0 +1,1277 @@ +/* $OpenBSD: umac.c,v 1.3 2008/05/12 20:52:20 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 <sys/types.h> + +#include "xmalloc.h" +#include "umac.h" +#include <string.h> +#include <stdlib.h> +#include <stddef.h> + +/* ---------------------------------------------------------------------- */ +/* --- 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; +} + +# if (__LITTLE_ENDIAN__) +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 /* __LITTLE_ENDIAN */ +#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 <openssl/aes.h> +#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 'bufp'. Each distinct + * 'ndx' causes a distinct byte stream. + */ +static void kdf(void *bufp, 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 *)bufp; + 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); +} + +/* ---------------------------------------------------------------------- */ + +#if (__LITTLE_ENDIAN__) +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); + } +} +#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; + UINT64 result_buf[STREAMS]; + UINT8 *nh_result = (UINT8 *)&result_buf; + + 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 */ +{ + UINT64 result_buf[STREAMS]; + UINT8 *nh_result = (UINT8 *)&result_buf; + + 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; + xfree(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 = xmalloc(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/crypto/openssh/umac.h b/crypto/openssh/umac.h new file mode 100644 index 0000000..055c705 --- /dev/null +++ b/crypto/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/crypto/openssh/version.h b/crypto/openssh/version.h index 3976bd1..4be29ed 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -1,12 +1,12 @@ -/* $OpenBSD: version.h,v 1.48 2006/11/07 10:31:31 markus Exp $ */ +/* $OpenBSD: version.h,v 1.54 2008/07/21 08:19:07 djm Exp $ */ /* $FreeBSD$ */ #ifndef SSH_VERSION #define SSH_VERSION (ssh_version_get()) #define SSH_RELEASE (ssh_version_get()) -#define SSH_VERSION_BASE "OpenSSH_4.5p1" -#define SSH_VERSION_ADDENDUM "FreeBSD-20061110" +#define SSH_VERSION_BASE "OpenSSH_5.1p1" +#define SSH_VERSION_ADDENDUM "FreeBSD-20080801" const char *ssh_version_get(void); void ssh_version_set_addendum(const char *add); |