]> andersk Git - gssapi-openssh.git/commitdiff
Import of OpenSSH 3.1p1 OPENSSH_3_1P1
authorjbasney <jbasney>
Wed, 13 Mar 2002 14:49:38 +0000 (14:49 +0000)
committerjbasney <jbasney>
Wed, 13 Mar 2002 14:49:38 +0000 (14:49 +0000)
171 files changed:
openssh/.cvsignore
openssh/CREDITS
openssh/ChangeLog
openssh/INSTALL
openssh/LICENCE
openssh/Makefile.in
openssh/README
openssh/TODO
openssh/acconfig.h
openssh/auth-bsdauth.c
openssh/auth-krb4.c
openssh/auth-krb5.c
openssh/auth-options.c
openssh/auth-options.h
openssh/auth-pam.c
openssh/auth-passwd.c
openssh/auth-rh-rsa.c
openssh/auth-rhosts.c
openssh/auth-rsa.c
openssh/auth-sia.c
openssh/auth-skey.c
openssh/auth.c
openssh/auth.h
openssh/auth1.c
openssh/auth2-chall.c
openssh/auth2-pam.c
openssh/auth2.c
openssh/authfd.c
openssh/authfd.h
openssh/authfile.c
openssh/authfile.h
openssh/bufaux.c
openssh/bufaux.h
openssh/buffer.c
openssh/buffer.h
openssh/canohost.c
openssh/channels.c
openssh/channels.h
openssh/cipher.c
openssh/cipher.h
openssh/clientloop.c
openssh/compat.c
openssh/compat.h
openssh/compress.c
openssh/compress.h
openssh/config.guess
openssh/configure.ac
openssh/contrib/README
openssh/contrib/aix/README [new file with mode: 0644]
openssh/contrib/aix/buildbff.sh [new file with mode: 0755]
openssh/contrib/aix/inventory.sh [new file with mode: 0755]
openssh/contrib/caldera/openssh.spec
openssh/contrib/cygwin/README
openssh/contrib/gnome-ssh-askpass.c
openssh/contrib/redhat/openssh.spec
openssh/contrib/suse/openssh.spec
openssh/crc32.h
openssh/deattack.c
openssh/defines.h
openssh/dh.c
openssh/dispatch.c
openssh/dispatch.h
openssh/entropy.c
openssh/fatal.c [new file with mode: 0644]
openssh/getput.h
openssh/groupaccess.c
openssh/hostfile.c
openssh/hostfile.h
openssh/includes.h
openssh/kex.c
openssh/kex.h
openssh/kexdh.c
openssh/kexgex.c
openssh/key.c
openssh/key.h
openssh/log.c
openssh/log.h
openssh/loginrec.c
openssh/mac.c
openssh/match.c
openssh/match.h
openssh/misc.c
openssh/misc.h
openssh/mpaux.h
openssh/myproposal.h
openssh/nchan.c
openssh/openbsd-compat/Makefile.in
openssh/openbsd-compat/base64.h
openssh/openbsd-compat/bsd-cygwin_util.c
openssh/openbsd-compat/bsd-cygwin_util.h
openssh/openbsd-compat/daemon.c
openssh/openbsd-compat/dirname.c
openssh/openbsd-compat/fake-queue.h
openssh/openbsd-compat/mktemp.c
openssh/openbsd-compat/openbsd-compat.h
openssh/openbsd-compat/port-aix.c [new file with mode: 0644]
openssh/openbsd-compat/port-aix.h [new file with mode: 0644]
openssh/openbsd-compat/port-irix.c [new file with mode: 0644]
openssh/openbsd-compat/port-irix.h [new file with mode: 0644]
openssh/openbsd-compat/readpassphrase.c
openssh/openbsd-compat/realpath.c
openssh/openbsd-compat/setenv.c
openssh/openbsd-compat/setproctitle.c
openssh/packet.c
openssh/packet.h
openssh/pathnames.h
openssh/radix.c
openssh/readconf.c
openssh/readconf.h
openssh/readpass.c
openssh/rijndael.c
openssh/rijndael.h
openssh/rsa.c
openssh/rsa.h
openssh/scard.c
openssh/scard.h
openssh/scard/.cvsignore [new file with mode: 0644]
openssh/scp.1
openssh/scp.c
openssh/servconf.c
openssh/servconf.h
openssh/serverloop.c
openssh/session.c
openssh/session.h
openssh/sftp-client.c
openssh/sftp-client.h
openssh/sftp-common.c
openssh/sftp-glob.c
openssh/sftp-glob.h
openssh/sftp-int.c
openssh/sftp-int.h
openssh/sftp-server.c
openssh/sftp.1
openssh/sftp.c
openssh/sftp.h
openssh/ssh-add.1
openssh/ssh-add.c
openssh/ssh-agent.1
openssh/ssh-agent.c
openssh/ssh-dss.c
openssh/ssh-dss.h
openssh/ssh-keygen.1
openssh/ssh-keygen.c
openssh/ssh-keyscan.1
openssh/ssh-keyscan.c
openssh/ssh-rand-helper.c [new file with mode: 0644]
openssh/ssh-rsa.c
openssh/ssh-rsa.h
openssh/ssh.1
openssh/ssh.c
openssh/ssh.h
openssh/ssh2.h
openssh/ssh_config
openssh/sshconnect.c
openssh/sshconnect1.c
openssh/sshconnect2.c
openssh/sshd.8
openssh/sshd.c
openssh/sshd_config
openssh/sshlogin.c
openssh/sshlogin.h
openssh/sshpty.c
openssh/sshpty.h
openssh/sshtty.c
openssh/ttymodes.c
openssh/ttymodes.h
openssh/uidswap.c
openssh/uuencode.c
openssh/uuencode.h
openssh/version.h
openssh/xmalloc.h

index a473d1fb9cc754d6b4cbf8e48aac2e4e825ecc9a..549c5e498cc703b70795807868927ae1599b1ec7 100644 (file)
@@ -19,3 +19,5 @@ ssh_prng_cmds
 *.out
 *.0
 buildit.sh
+autom4te.cache
+ssh-rand-helper
index c591e5c7da461ae5f2d3fe9878f7c79aa6325b78..bcc0359a10541603a981cf80a7af39cf096d0423 100644 (file)
@@ -26,6 +26,7 @@ Chun-Chung Chen <cjj@u.washington.edu> - RPM fixes
 Corinna Vinschen <vinschen@cygnus.com> - Cygwin support
 Dan Brosemer <odin@linuxfreak.com> - Autoconf support, build fixes
 Darren Hall <dhall@virage.org> - AIX patches
+Darren Tucker <dtucker@zip.com.au> - AIX BFF package scripts
 David Agraz <dagraz@jahoopa.com> - Build fixes
 David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes
 David Hesprich <darkgrue@gue-tech.org> - Configure fixes
@@ -35,7 +36,7 @@ Garrick James <garrick@james.net> - configure fixes
 Gary E. Miller <gem@rellim.com> - SCO support
 Ged Lodder <lodder@yacc.com.au> - HPUX fixes and enhancements
 Gert Doering <gd@hilb1.medat.de> - bug and portability fixes
-HARUYAMA Seigo <haruyama@klab.org> - Translations & doc fixes
+HARUYAMA Seigo <haruyama@unixuser.org> - Translations & doc fixes
 Hideaki YOSHIFUJI <yoshfuji@ecei.tohoku.ac.jp> - IPv6 and bug fixes
 Hiroshi Takekawa <takekawa@sr3.t.u-tokyo.ac.jp> - Configure fixes
 Holger Trapp <Holger.Trapp@Informatik.TU-Chemnitz.DE> - KRB4/AFS config patch
index d79e7fb6d21af1d9e6b3a474679bb1dc70df8925..bd2d9c5f2db531126640361ea3ff5ea8946930fb 100644 (file)
@@ -1,9 +1,904 @@
-20011202
- - (djm) Syn with OpenBSD OpenSSH-3.0.2
-   - markus@cvs.openbsd.org
-     [session.c sshd.8 version.h]
-     Don't allow authorized_keys specified environment variables when 
-     UseLogin in active
+20020307
+ - (djm) OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2002/03/06 00:20:54
+     [compat.c dh.c]
+     compat.c
+   - markus@cvs.openbsd.org 2002/03/06 00:23:27
+     [compat.c dh.c]
+     undo
+   - markus@cvs.openbsd.org 2002/03/06 00:24:39
+     [compat.c]
+     compat.c
+   - markus@cvs.openbsd.org 2002/03/06 00:25:55
+     [version.h]
+     OpenSSH_3.1
+ - (djm) Update RPM spec files with new version number
+
+20020305
+   - stevesk@cvs.openbsd.org 2002/03/02 09:34:42
+     [LICENCE]
+     correct copyright dates for scp license; ok markus@
+
+20020304
+ - OpenBSD CVS Sync
+   - deraadt@cvs.openbsd.org 2002/02/26 18:52:32
+     [sftp.1]
+     Ic cannot have that many arguments; spotted by mouring@etoh.eviladmin.org
+   - mouring@cvs.openbsd.org 2002/02/26 19:04:37
+     [sftp.1]
+     > Ic cannot have that many arguments; spotted by mouring@etoh.eviladmin.org
+     Last Ic on the first line should not have a space between it and the final
+     comma.
+   - deraadt@cvs.openbsd.org 2002/02/26 19:06:43
+     [sftp.1]
+     no, look closely.  the comma was highlighted. split .Ic even more
+   - stevesk@cvs.openbsd.org 2002/02/26 20:03:51
+     [misc.c]
+     use socklen_t
+   - stevesk@cvs.openbsd.org 2002/02/27 21:23:13
+     [canohost.c channels.c packet.c sshd.c]
+     remove unneeded casts in [gs]etsockopt(); ok markus@
+   - markus@cvs.openbsd.org 2002/02/28 15:46:33
+     [authfile.c kex.c kexdh.c kexgex.c key.c ssh-dss.c]
+     add some const EVP_MD for openssl-0.9.7
+   - stevesk@cvs.openbsd.org 2002/02/28 19:36:28
+     [auth.c match.c match.h]
+     delay hostname lookup until we see a ``@'' in DenyUsers and AllowUsers
+     for sshd -u0; ok markus@
+   - stevesk@cvs.openbsd.org 2002/02/28 20:36:42
+     [sshd.8]
+     DenyUsers allows user@host pattern also
+   - stevesk@cvs.openbsd.org 2002/02/28 20:46:10
+     [sshd.8]
+     -u0 DNS for user@host
+   - stevesk@cvs.openbsd.org 2002/02/28 20:56:00
+     [auth.c]
+     log user not allowed details, from dwd@bell-labs.com; ok markus@
+   - markus@cvs.openbsd.org 2002/03/01 13:12:10
+     [auth.c match.c match.h]
+     undo the 'delay hostname lookup' change
+     match.c must not use compress.c (via canonhost.c/packet.c)
+     thanks to wilfried@
+   - markus@cvs.openbsd.org 2002/03/04 12:43:06
+     [auth-passwd.c auth-rh-rsa.c auth-rhosts.c]
+   - markus@cvs.openbsd.org 2002/03/04 13:10:46
+     [misc.c]
+     error-> debug, because O_NONBLOCK for /dev/null causes too many different 
+     errnos; ok stevesk@, deraadt@
+     unused include
+   - stevesk@cvs.openbsd.org 2002/03/04 17:27:39
+     [auth-krb5.c auth-options.h auth.h authfd.h authfile.h bufaux.h buffer.h 
+      channels.h cipher.h compat.h compress.h crc32.h deattack.c getput.h 
+      groupaccess.c misc.c mpaux.h packet.h readconf.h rsa.h scard.h 
+      servconf.h ssh-agent.c ssh.h ssh2.h sshpty.h sshtty.c ttymodes.h 
+      uuencode.c xmalloc.h]
+     $OpenBSD$ and RCSID() cleanup: don't use RCSID() in .h files; add
+     missing RCSID() to .c files and remove dup /*$OpenBSD$*/ from .c
+     files.  ok markus@
+   - stevesk@cvs.openbsd.org 2002/03/04 18:30:23
+     [ssh-keyscan.c]
+     handle connection close during read of protocol version string.
+     fixes erroneous "bad greeting".  ok markus@
+   - markus@cvs.openbsd.org 2002/03/04 19:37:58
+     [channels.c]
+     off by one; thanks to joost@pine.nl
+ - (bal) Added contrib/aix/ to support BFF package generation provided
+   by Darren Tucker <dtucker@zip.com.au>
+20020226
+ - (tim) Bug 12 [configure.ac] add sys/bitypes.h to int64_t tests
+   based on patch by mooney@dogbert.cc.ndsu.nodak.edu (Tim Mooney)
+   Bug 45 [configure.ac] modify skey test to work around conflict with autoconf
+   reported by nolan@naic.edu (Michael Nolan)
+   patch by  Pekka Savola <pekkas@netcore.fi>
+   Bug 74 [configure.ac defines.h] add sig_atomic_t test
+   reported by dwd@bell-labs.com (Dave Dykstra)
+   Bug 102 [defines.h] UNICOS fixes. patch by wendyp@cray.com
+   [configure.ac Makefile.in] link libwrap only with sshd
+   based on patch by Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+   Bug 123 link libpam only with sshd
+   reported by peak@argo.troja.mff.cuni.cz (Pavel Kankovsky)
+   [configure.ac defines.h] modify previous SCO3 fix to not break Solaris 7
+   [acconfig.h] remove unused HAVE_REGCOMP
+   [configure.ac] put back in search for prngd-socket
+ - (stevesk) openbsd-compat/base64.h: typo in comment
+ - (bal) Update sshd_config CVSID
+ - (bal) OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2002/02/15 23:54:10
+     [auth-krb5.c]
+     krb5_get_err_text() does not like context==NULL; he@nordu.net via google; 
+     ok provos@
+   - markus@cvs.openbsd.org 2002/02/22 12:20:34
+     [log.c log.h ssh-keyscan.c]
+     overwrite fatal() in ssh-keyscan.c; fixes pr 2354; ok provos@
+   - markus@cvs.openbsd.org 2002/02/23 17:59:02
+     [kex.c kexdh.c kexgex.c]
+     don't allow garbage after payload.
+   - stevesk@cvs.openbsd.org 2002/02/24 16:09:52
+     [sshd.c]
+     use u_char* here; ok markus@
+   - markus@cvs.openbsd.org 2002/02/24 16:57:19
+     [sftp-client.c]
+     early close(), missing free; ok stevesk@
+   - markus@cvs.openbsd.org 2002/02/24 16:58:32
+     [packet.c]
+     make 'cp' unsigned and merge with 'ucp'; ok stevesk@
+   - markus@cvs.openbsd.org 2002/02/24 18:31:09
+     [uuencode.c]
+     typo in comment
+   - markus@cvs.openbsd.org 2002/02/24 19:14:59
+     [auth2.c authfd.c authfd.h authfile.c kexdh.c kexgex.c key.c key.h 
+      ssh-dss.c ssh-dss.h ssh-keygen.c ssh-rsa.c ssh-rsa.h sshconnect2.c]
+     signed vs. unsigned: make size arguments u_int, ok stevesk@
+   - stevesk@cvs.openbsd.org 2002/02/24 19:59:42
+     [channels.c misc.c]
+     disable Nagle in connect_to() and channel_post_port_listener() (port
+     forwarding endpoints).  the intention is to preserve the on-the-wire
+     appearance to applications at either end; the applications can then
+     enable TCP_NODELAY according to their requirements. ok markus@
+   - markus@cvs.openbsd.org 2002/02/25 16:33:27
+     [ssh-keygen.c sshconnect2.c uuencode.c uuencode.h]
+     more u_* fixes
+ - (bal) Imported missing fatal.c and fixed up Makefile.in
+ - (tim) [configure.ac] correction to Bug 123 fix
+     [configure.ac] correction to sig_atomic_t test
+
+20020225
+ - (bal) Last AIX patch.  Moved aix_usrinfo() outside of do_setuserconext()
+   since we need more session information than provided by that function.
+
+20020224
+ - (bal) Drop Session *s usage in ports-aix.[ch] and pass just what we
+   need to do the jobs (AIX still does not fully compile, but that is
+   coming).
+ - (bal) Part two.. Drop unused AIX header, fix up missing char *cp.  All
+   that is left is handling aix_usrinfo().
+ - (tim) [loginrec.c session.c sshlogin.c sshlogin.h] Bug 84
+   patch by wknox@mitre.org (William Knox).
+   [sshlogin.h] declare record_utmp_only for session.c
+
+20020221
+ - (bal) Minor session.c fixup for cygwin.  mispelt 'is_winnt' variable.
+
+20020219
+ - (djm) OpenBSD CVS Sync
+   - mpech@cvs.openbsd.org 2002/02/13 08:33:47
+     [ssh-keyscan.1]
+     When you give command examples and etc., in a manual page prefix them with:     $ command
+     or
+     # command
+   - markus@cvs.openbsd.org 2002/02/14 23:27:59
+     [channels.c]
+     increase the SSH v2 window size to 4 packets. comsumes a little
+     bit more memory for slow receivers but increases througput.
+   - markus@cvs.openbsd.org 2002/02/14 23:28:00
+     [channels.h session.c ssh.c]
+     increase the SSH v2 window size to 4 packets. comsumes a little
+     bit more memory for slow receivers but increases througput.
+   - markus@cvs.openbsd.org 2002/02/14 23:41:01
+     [authfile.c cipher.c cipher.h kex.c kex.h packet.c]
+     hide some more implementation details of cipher.[ch] and prepares for move
+     to EVP, ok deraadt@
+   - stevesk@cvs.openbsd.org 2002/02/16 14:53:37
+     [ssh-keygen.1]
+     -t required now for key generation
+   - stevesk@cvs.openbsd.org 2002/02/16 20:40:08
+     [ssh-keygen.c]
+     default to rsa keyfile path for non key generation operations where
+     keyfile not specified.  fixes core dump in those cases.  ok markus@
+   - millert@cvs.openbsd.org 2002/02/16 21:27:53
+     [auth.h]
+     Part one of userland __P removal.  Done with a simple regexp with 
+     some minor hand editing to make comments line up correctly.  Another 
+     pass is forthcoming that handles the cases that could not be done 
+     automatically.
+   - millert@cvs.openbsd.org 2002/02/17 19:42:32
+     [auth.h]
+     Manual cleanup of remaining userland __P use (excluding packages 
+     maintained outside the tree)
+   - markus@cvs.openbsd.org 2002/02/18 13:05:32
+     [cipher.c cipher.h]
+     switch to EVP, ok djm@ deraadt@
+   - markus@cvs.openbsd.org 2002/02/18 17:55:20
+     [ssh.1]
+     -q: Fatal errors are _not_ displayed.
+   - deraadt@cvs.openbsd.org 2002/02/19 02:50:59
+     [sshd_config]
+     stategy is not an english word
+ - (bal) Migrated IRIX jobs/projects/audit/etc code to 
+   openbsd-compat/port-irix.[ch] to improve readiblity of do_child()
+ - (bal) Migrated AIX getuserattr and usrinfo code to 
+   openbsd-compat/port-aix.[c] to improve readilbity of do_child() and
+   simplify our diffs against upstream source.
+ - (bal) OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2002/02/15 23:11:26
+     [session.c]
+     split do_child(), ok mouring@
+   - markus@cvs.openbsd.org 2002/02/16 00:51:44
+     [session.c]
+     typo
+ - (bal) CVS ID sync since the last two patches were merged mistakenly
+
+20020218
+ - (tim) newer config.guess from ftp://ftp.gnu.org/gnu/config/config.guess
+
+20020213
+ - (djm) Don't use system sys/queue.h on AIX. Report from 
+   gert@greenie.muc.de
+ - (djm) Bug #114 - not starting PAM for SSH protocol 1 invalid users
+
+20020213
+ - (djm) OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2002/02/11 16:10:15
+     [kex.c]
+     restore kexinit handler if we reset the dispatcher, this unbreaks
+     rekeying s/kex_clear_dispatch/kex_reset_dispatch/
+   - markus@cvs.openbsd.org 2002/02/11 16:15:46
+     [sshconnect1.c]
+     include md5.h, not evp.h
+   - markus@cvs.openbsd.org 2002/02/11 16:17:55
+     [sshd.c]
+     do not complain about port > 1024 if rhosts-auth is disabled
+   - markus@cvs.openbsd.org 2002/02/11 16:19:39
+     [sshd.c]
+     include md5.h not hmac.h
+   - markus@cvs.openbsd.org 2002/02/11 16:21:42
+     [match.c]
+     support up to 40 algorithms per proposal
+   - djm@cvs.openbsd.org 2002/02/12 12:32:27
+     [sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c]
+     Perform multiple overlapping read/write requests in file transfer. Mostly
+     done by Tobias Ringstrom <tori@ringstrom.mine.nu>; ok markus@
+   - djm@cvs.openbsd.org 2002/02/12 12:44:46
+     [sftp-client.c]
+     Let overlapped upload path handle servers which reorder ACKs. This may be
+     permitted by the protocol spec; ok markus@
+   - markus@cvs.openbsd.org 2002/02/13 00:28:13
+     [sftp-server.c]
+     handle SSH2_FILEXFER_ATTR_SIZE in SSH2_FXP_(F)SETSTAT; ok djm@
+   - markus@cvs.openbsd.org 2002/02/13 00:39:15
+     [readpass.c]
+     readpass.c is not longer from UCB, since we now use readpassphrase(3)
+   - djm@cvs.openbsd.org 2002/02/13 00:59:23
+     [sftp-client.c sftp-client.h sftp-glob.c sftp-glob.h sftp.h]
+     [sftp-int.c sftp-int.h]
+     API cleanup and backwards compat for filexfer v.0 servers; ok markus@
+ - (djm) Sync openbsd-compat with OpenBSD CVS too
+ - (djm) Bug #106: Add --without-rpath configure option. Patch from 
+   Nicolas.Williams@ubsw.com
+ - (tim) [configure.ac, defines.h ] add rpc/rpc.h for INADDR_LOOPBACK
+    on SCO OSR3
+
+20020210
+ - (djm) OpenBSD CVS Sync
+   - deraadt@cvs.openbsd.org 2002/02/09 17:37:34
+     [pathnames.h session.c ssh.1 sshd.8 sshd_config ssh-keyscan.1]
+     move ssh config files to /etc/ssh
+ - (djm) Adjust portable Makefile.in tnd ssh-rand-helper.c o match
+   - deraadt@cvs.openbsd.org 2002/02/10 01:07:05
+     [readconf.h sshd.8]
+     more /etc/ssh; openbsd@davidkrause.com
+
+20020208
+ - (djm) OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2002/02/04 12:15:25
+     [sshd.c]
+     add SYSLOG_FACILITY_NOT_SET = -1, SYSLOG_LEVEL_NOT_SET = -1,
+     fixes arm/netbsd; based on patch from bjh21@netbsd.org; ok djm@
+   - stevesk@cvs.openbsd.org 2002/02/04 20:41:16
+     [ssh-agent.1]
+     more sync for default ssh-add identities; ok markus@
+   - djm@cvs.openbsd.org 2002/02/05 00:00:46
+     [sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c]
+     Add "-B" option to specify copy buffer length (default 32k); ok markus@
+   - markus@cvs.openbsd.org 2002/02/05 14:32:55
+     [channels.c channels.h ssh.c]
+     merge channel_request() into channel_request_start()
+   - markus@cvs.openbsd.org 2002/02/06 14:22:42
+     [sftp.1]
+     sort options; ok mpech@, stevesk@
+   - mpech@cvs.openbsd.org 2002/02/06 14:27:23
+     [sftp.c]
+     sync usage() with manual.
+   - markus@cvs.openbsd.org 2002/02/06 14:37:22
+     [session.c]
+     minor KNF
+   - markus@cvs.openbsd.org 2002/02/06 14:55:16
+     [channels.c clientloop.c serverloop.c ssh.c]
+     channel_new never returns NULL, mouring@; ok djm@
+   - markus@cvs.openbsd.org 2002/02/07 09:35:39
+     [ssh.c]
+     remove bogus comments
+
+20020205
+ - (djm) Cleanup after sync:
+   - :%s/reverse_mapping_check/verify_reverse_mapping/g
+ - (djm) OpenBSD CVS Sync
+   - stevesk@cvs.openbsd.org 2002/01/24 21:09:25
+     [channels.c misc.c misc.h packet.c]
+     add set_nodelay() to set TCP_NODELAY on a socket (prep for nagle tuning).
+     no nagle changes just yet; ok djm@ markus@
+   - stevesk@cvs.openbsd.org 2002/01/24 21:13:23
+     [packet.c]
+     need misc.h for set_nodelay()
+   - markus@cvs.openbsd.org 2002/01/25 21:00:24
+     [sshconnect2.c]
+     unused include
+   - markus@cvs.openbsd.org 2002/01/25 21:42:11
+     [ssh-dss.c ssh-rsa.c]
+     use static EVP_MAX_MD_SIZE buffers for EVP_DigestFinal; ok stevesk@
+     don't use evp_md->md_size, it's not public.
+   - markus@cvs.openbsd.org 2002/01/25 22:07:40
+     [kex.c kexdh.c kexgex.c key.c mac.c]
+     use EVP_MD_size(evp_md) and not evp_md->md_size; ok steveks@
+   - stevesk@cvs.openbsd.org 2002/01/26 16:44:22
+     [includes.h session.c]
+     revert code to add x11 localhost display authorization entry for
+     hostname/unix:d and uts.nodename/unix:d if nodename was different than
+     hostname.  just add entry for unix:d instead.  ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/27 14:57:46
+     [channels.c servconf.c servconf.h session.c sshd.8 sshd_config]
+     add X11UseLocalhost; ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/27 18:08:17
+     [ssh.c]
+     handle simple case to identify FamilyLocal display; ok markus@
+   - markus@cvs.openbsd.org 2002/01/29 14:27:57
+     [ssh-add.c]
+     exit 2 if no agent, exit 1 if list fails; debian#61078; ok djm@
+   - markus@cvs.openbsd.org 2002/01/29 14:32:03
+     [auth2.c auth.c auth-options.c auth-rhosts.c auth-rh-rsa.c canohost.c]
+     [servconf.c servconf.h session.c sshd.8 sshd_config]
+     s/ReverseMappingCheck/VerifyReverseMapping/ and avoid confusion; 
+     ok stevesk@
+   - stevesk@cvs.openbsd.org 2002/01/29 16:29:02
+     [session.c]
+     limit subsystem length in log; ok markus@
+   - markus@cvs.openbsd.org 2002/01/29 16:41:19
+     [ssh-add.1]
+     add DIAGNOSTICS; ok stevesk@
+   - markus@cvs.openbsd.org 2002/01/29 22:46:41
+     [session.c]
+     don't depend on servconf.c; ok djm@
+   - markus@cvs.openbsd.org 2002/01/29 23:50:37
+     [scp.1 ssh.1]
+     mention exit status; ok stevesk@
+   - markus@cvs.openbsd.org 2002/01/31 13:35:11
+     [kexdh.c kexgex.c]
+     cross check announced key type and type from key blob
+   - markus@cvs.openbsd.org 2002/01/31 15:00:05
+     [serverloop.c]
+     no need for WNOHANG; ok stevesk@
+   - markus@cvs.openbsd.org 2002/02/03 17:53:25
+     [auth1.c serverloop.c session.c session.h]
+     don't use channel_input_channel_request and callback
+     use new server_input_channel_req() instead:
+       server_input_channel_req does generic request parsing on server side
+       session_input_channel_req handles just session specific things now
+     ok djm@
+   - markus@cvs.openbsd.org 2002/02/03 17:55:55
+     [channels.c channels.h]
+     remove unused channel_input_channel_request
+   - markus@cvs.openbsd.org 2002/02/03 17:58:21
+     [channels.c channels.h ssh.c]
+     generic callbacks are not really used, remove and
+     add a callback for msg of type SSH2_MSG_CHANNEL_OPEN_CONFIRMATION
+     ok djm@
+   - markus@cvs.openbsd.org 2002/02/03 17:59:23
+     [sshconnect2.c]
+     more cross checking if announced vs. used key type; ok stevesk@
+   - stevesk@cvs.openbsd.org 2002/02/03 22:35:57
+     [ssh.1 sshd.8]
+     some KeepAlive cleanup/clarify; ok markus@
+   - stevesk@cvs.openbsd.org 2002/02/03 23:22:59
+     [ssh-agent.1]
+     ssh-add also adds $HOME/.ssh/id_rsa and $HOME/.ssh/id_dsa now.
+   - stevesk@cvs.openbsd.org 2002/02/04 00:53:39
+     [ssh-agent.c]
+     unneeded includes
+   - markus@cvs.openbsd.org 2002/02/04 11:58:10
+     [auth2.c]
+     cross checking of announced vs actual pktype in pubkey/hostbaed auth; 
+     ok stevesk@
+   - markus@cvs.openbsd.org 2002/02/04 12:15:25
+     [log.c log.h readconf.c servconf.c]
+     add SYSLOG_FACILITY_NOT_SET = -1, SYSLOG_LEVEL_NOT_SET = -1,
+     fixes arm/netbsd; based on patch from bjh21@netbsd.org; ok djm@
+   - stevesk@cvs.openbsd.org 2002/02/04 20:41:16
+     [ssh-add.1]
+     more sync for default ssh-add identities; ok markus@
+   - djm@cvs.openbsd.org 2002/02/04 21:53:12
+     [sftp.1 sftp.c]
+     Add "-P" option to directly connect to a local sftp-server. Should be 
+     useful for regression testing; ok markus@
+   - djm@cvs.openbsd.org 2002/02/05 00:00:46
+     [sftp.1 sftp.c sftp-client.c sftp-client.h sftp-int.c]
+     Add "-B" option to specify copy buffer length (default 32k); ok markus@
+
+20020130
+ - (djm) Delay PRNG seeding until we need it in ssh-keygen, from markus@
+ - (tim) [configure.ac] fix logic on when ssh-rand-helper is installed.
+   [sshd_config] put back in line that tells what PATH was compiled into sshd.
+
+20020125
+ - (djm) Don't grab Xserver or pointer by default. x11-ssh-askpass doesn't 
+   and grabbing can cause deadlocks with kinput2. 
+
+20020124
+ - (stevesk) Makefile.in: bug #61; delete commented line for now.
+
+20020123
+ - (djm) Fix non-standard shell syntax in autoconf. Patch from 
+   Dave Dykstra <dwd@bell-labs.com>
+ - (stevesk) fix --with-zlib=
+ - (djm) Use case statements in autoconf to clean up some tests
+ - (bal) reverted out of 5/2001 change to atexit().  I assume I
+   did it to handle SonyOS.  If that is the case than we will
+   do a special case for them.
+
+20020122
+ - (djm) autoconf hacking:
+   - We don't support --without-zlib currently, so don't allow it.
+   - Rework cryptographic random number support detection. We now detect 
+     whether OpenSSL seeds itself. If it does, then we don't bother with 
+     the ssh-rand-helper program. You can force the use of ssh-rand-helper
+     using the --with-rand-helper configure argument
+   - Simplify and clean up ssh-rand-helper configuration
+   - Add OpenSSL sanity check: verify that header version matches version
+     reported by library
+ - (djm) Fix some bugs I introduced into ssh-rand-helper yesterday
+ - OpenBSD CVS Sync
+   - djm@cvs.openbsd.org 2001/12/21 08:52:22
+     [ssh-keygen.1 ssh-keygen.c]
+     Remove default (rsa1) key type; ok markus@
+   - djm@cvs.openbsd.org 2001/12/21 08:53:45
+     [readpass.c]
+     Avoid interruptable passphrase read; ok markus@
+   - djm@cvs.openbsd.org 2001/12/21 10:06:43
+     [ssh-add.1 ssh-add.c]
+     Try all standard key files (id_rsa, id_dsa, identity) when invoked with
+     no arguments; ok markus@
+   - markus@cvs.openbsd.org 2001/12/21 12:17:33
+     [serverloop.c]
+     remove ifdef for USE_PIPES since fdin != fdout; ok djm@
+   - deraadt@cvs.openbsd.org 2001/12/24 07:29:43
+     [ssh-add.c]
+     try all listed keys.. how did this get broken?
+   - markus@cvs.openbsd.org 2001/12/25 18:49:56
+     [key.c]
+     be more careful on allocation
+   - markus@cvs.openbsd.org 2001/12/25 18:53:00
+     [auth1.c]
+     be more carefull on allocation
+   - markus@cvs.openbsd.org 2001/12/27 18:10:29
+     [ssh-keygen.c]
+     -t is only needed for key generation (unbreaks -i, -e, etc).
+   - markus@cvs.openbsd.org 2001/12/27 18:22:16
+     [auth1.c authfile.c auth-rsa.c dh.c kexdh.c kexgex.c key.c rsa.c]
+     [scard.c ssh-agent.c sshconnect1.c sshd.c ssh-dss.c]
+     call fatal() for openssl allocation failures
+   - stevesk@cvs.openbsd.org 2001/12/27 18:22:53
+     [sshd.8]
+     clarify -p; ok markus@
+   - markus@cvs.openbsd.org 2001/12/27 18:26:13
+     [authfile.c]
+     missing include
+   - markus@cvs.openbsd.org 2001/12/27 19:37:23
+     [dh.c kexdh.c kexgex.c]
+     always use BN_clear_free instead of BN_free
+   - markus@cvs.openbsd.org 2001/12/27 19:54:53
+     [auth1.c auth.h auth-rh-rsa.c]
+     auth_rhosts_rsa now accept generic keys.
+   - markus@cvs.openbsd.org 2001/12/27 20:39:58
+     [auth1.c auth-rsa.c channels.c clientloop.c packet.c packet.h]
+     [serverloop.c session.c ssh.c sshconnect1.c sshd.c ttymodes.c]
+     get rid of packet_integrity_check, use packet_done() instead.
+   - markus@cvs.openbsd.org 2001/12/28 12:14:27
+     [auth1.c auth2.c auth2-chall.c auth-rsa.c channels.c clientloop.c]
+     [kex.c kexdh.c kexgex.c packet.c packet.h serverloop.c session.c]
+     [ssh.c sshconnect1.c sshconnect2.c sshd.c]
+     s/packet_done/packet_check_eom/ (end-of-message); ok djm@
+   - markus@cvs.openbsd.org 2001/12/28 13:57:33
+     [auth1.c kexdh.c kexgex.c packet.c packet.h sshconnect1.c sshd.c]
+     packet_get_bignum* no longer returns a size
+   - markus@cvs.openbsd.org 2001/12/28 14:13:13
+     [bufaux.c bufaux.h packet.c]
+     buffer_get_bignum: int -> void
+   - markus@cvs.openbsd.org 2001/12/28 14:50:54
+     [auth1.c auth-rsa.c channels.c dispatch.c kex.c kexdh.c kexgex.c]
+     [packet.c packet.h serverloop.c session.c ssh.c sshconnect1.c]
+     [sshconnect2.c sshd.c]
+     packet_read* no longer return the packet length, since it's not used.
+   - markus@cvs.openbsd.org 2001/12/28 15:06:00
+     [auth2.c auth2-chall.c channels.c channels.h clientloop.c dispatch.c]
+     [dispatch.h kex.c kex.h serverloop.c ssh.c sshconnect2.c]
+     remove plen from the dispatch fn. it's no longer used.
+   - stevesk@cvs.openbsd.org 2001/12/28 22:37:48
+     [ssh.1 sshd.8]
+     document LogLevel DEBUG[123]; ok markus@
+   - stevesk@cvs.openbsd.org 2001/12/29 21:56:01
+     [authfile.c channels.c compress.c packet.c sftp-server.c]
+     [ssh-agent.c ssh-keygen.c]
+     remove unneeded casts and some char->u_char cleanup; ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/03 04:11:08
+     [ssh_config]
+     grammar in comment
+   - stevesk@cvs.openbsd.org 2002/01/04 17:59:17
+     [readconf.c servconf.c]
+     remove #ifdef _PATH_XAUTH/#endif; ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/04 18:14:16
+     [servconf.c sshd.8]
+     protocol 2 HostKey code default is now /etc/ssh_host_rsa_key and
+     /etc/ssh_host_dsa_key like we have in sshd_config.  ok markus@
+   - markus@cvs.openbsd.org 2002/01/05 10:43:40
+     [channels.c]
+     fix hanging x11 channels for rejected cookies (e.g. 
+     XAUTHORITY=/dev/null xbiff) bug #36, based on patch from
+     djast@cs.toronto.edu
+   - stevesk@cvs.openbsd.org 2002/01/05 21:51:56
+     [ssh.1 sshd.8]
+     some missing and misplaced periods
+   - markus@cvs.openbsd.org 2002/01/09 13:49:27
+     [ssh-keygen.c]
+     append \n only for public keys
+   - markus@cvs.openbsd.org 2002/01/09 17:16:00
+     [channels.c]
+     merge channel_pre_open_15/channel_pre_open_20; ok provos@
+   - markus@cvs.openbsd.org 2002/01/09 17:26:35
+     [channels.c nchan.c]
+     replace buffer_consume(b, buffer_len(b)) with buffer_clear(b); 
+     ok provos@
+   - markus@cvs.openbsd.org 2002/01/10 11:13:29
+     [serverloop.c]
+     skip client_alive_check until there are channels; ok beck@
+   - markus@cvs.openbsd.org 2002/01/10 11:24:04
+     [clientloop.c]
+     handle SSH2_MSG_GLOBAL_REQUEST (just reply with failure); ok djm@
+   - markus@cvs.openbsd.org 2002/01/10 12:38:26
+     [nchan.c]
+     remove dead code (skip drain)
+   - markus@cvs.openbsd.org 2002/01/10 12:47:59
+     [nchan.c]
+     more unused code (with channels.c:1.156)
+   - markus@cvs.openbsd.org 2002/01/11 10:31:05
+     [packet.c]
+     handle received SSH2_MSG_UNIMPLEMENTED messages; ok djm@
+   - markus@cvs.openbsd.org 2002/01/11 13:36:43
+     [ssh2.h]
+     add defines for msg type ranges
+   - markus@cvs.openbsd.org 2002/01/11 13:39:36
+     [auth2.c dispatch.c dispatch.h kex.c]
+     a single dispatch_protocol_error() that sends a message of 
+     type 'UNIMPLEMENTED'
+     dispatch_range(): set handler for a ranges message types
+     use dispatch_protocol_ignore() for authentication requests after
+     successful authentication (the drafts requirement).
+     serverloop/clientloop now send a 'UNIMPLEMENTED' message instead 
+     of exiting.
+   - markus@cvs.openbsd.org 2002/01/11 20:14:11
+     [auth2-chall.c auth-skey.c]
+     use strlcpy not strlcat; mouring@
+   - markus@cvs.openbsd.org 2002/01/11 23:02:18
+     [readpass.c]
+     use _PATH_TTY
+   - markus@cvs.openbsd.org 2002/01/11 23:02:51
+     [auth2-chall.c]
+     use snprintf; mouring@
+   - markus@cvs.openbsd.org 2002/01/11 23:26:30
+     [auth-skey.c]
+     use snprintf; mouring@
+   - markus@cvs.openbsd.org 2002/01/12 13:10:29
+     [auth-skey.c]
+     undo local change
+   - provos@cvs.openbsd.org 2002/01/13 17:27:07
+     [ssh-agent.c]
+     change to use queue.h macros; okay markus@
+   - markus@cvs.openbsd.org 2002/01/13 17:57:37
+     [auth2.c auth2-chall.c compat.c sshconnect2.c sshd.c]
+     use buffer API and avoid static strings of fixed size; 
+     ok provos@/mouring@
+   - markus@cvs.openbsd.org 2002/01/13 21:31:20
+     [channels.h nchan.c]
+     add chan_set_[io]state(), order states, state is now an u_int,
+     simplifies debugging messages; ok provos@
+   - markus@cvs.openbsd.org 2002/01/14 13:22:35
+     [nchan.c]
+     chan_send_oclose1() no longer calls chan_shutdown_write(); ok provos@
+   - markus@cvs.openbsd.org 2002/01/14 13:34:07
+     [nchan.c]
+     merge chan_[io]buf_empty[12]; ok provos@
+   - markus@cvs.openbsd.org 2002/01/14 13:40:10
+     [nchan.c]
+     correct fn names for ssh2, do not switch from closed to closed; 
+     ok provos@
+   - markus@cvs.openbsd.org 2002/01/14 13:41:13
+     [nchan.c]
+     remove duplicated code; ok provos@
+   - markus@cvs.openbsd.org 2002/01/14 13:55:55
+     [channels.c channels.h nchan.c]
+     remove function pointers for events, remove chan_init*; ok provos@
+   - markus@cvs.openbsd.org 2002/01/14 13:57:03
+     [channels.h nchan.c]
+     (c) 2002
+   - markus@cvs.openbsd.org 2002/01/16 13:17:51
+     [channels.c channels.h serverloop.c ssh.c]
+     wrapper for channel_setup_fwd_listener
+   - stevesk@cvs.openbsd.org 2002/01/16 17:40:23
+     [sshd_config]
+     The stategy now used for options in the default sshd_config shipped
+     with OpenSSH is to specify options with their default value where
+     possible, but leave them commented.  Uncommented options change a
+     default value.  Subsystem is currently the only default option
+     changed.  ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/16 17:42:33
+     [ssh.1]
+     correct defaults for -i/IdentityFile; ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/16 17:55:33
+     [ssh_config]
+     correct some commented defaults.  add Ciphers default.  ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/17 04:27:37
+     [log.c]
+     casts to silence enum type warnings for bugzilla bug 37; ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/18 17:14:16
+     [sshd.8]
+     correct Ciphers default; paola.mannaro@ubs.com
+   - stevesk@cvs.openbsd.org 2002/01/18 18:14:17
+     [authfd.c bufaux.c buffer.c cipher.c packet.c ssh-agent.c ssh-keygen.c]
+     unneeded cast cleanup; ok markus@
+   - stevesk@cvs.openbsd.org 2002/01/18 20:46:34
+     [sshd.8]
+     clarify Allow(Groups|Users) and Deny(Groups|Users); suggestion from
+     allard@oceanpark.com; ok markus@
+   - markus@cvs.openbsd.org 2002/01/21 15:13:51
+     [sshconnect.c]
+     use read_passphrase+ECHO in confirm(), allows use of ssh-askpass
+     for hostkey confirm.
+   - markus@cvs.openbsd.org 2002/01/21 22:30:12
+     [cipher.c compat.c myproposal.h]
+     remove "rijndael-*", just use "aes-" since this how rijndael is called
+     in the drafts; ok stevesk@
+   - markus@cvs.openbsd.org 2002/01/21 23:27:10
+     [channels.c nchan.c]
+     cleanup channels faster if the are empty and we are in drain-state; 
+     ok deraadt@
+   - stevesk@cvs.openbsd.org 2002/01/22 02:52:41
+     [servconf.c]
+     typo in error message; from djast@cs.toronto.edu
+ - (djm) Make auth2-pam.c compile again after dispatch.h and packet.h 
+   changes
+ - (djm) Recent Glibc includes an incompatible sys/queue.h. Treat it as 
+   bogus in configure
+ - (djm) Use local sys/queue.h if necessary in ssh-agent.c
+
+20020121
+ - (djm) Rework ssh-rand-helper:
+   - Reduce quantity of ifdef code, in preparation for ssh_rand_conf
+   - Always seed from system calls, even when doing PRNGd seeding
+   - Tidy and comment #define knobs
+   - Remove unused facility for multiple runs through command list
+   - KNF, cleanup, update copyright
+
+20020114
+ - (djm) Bug #50 - make autoconf entropy path checks more robust
+
+20020108
+ - (djm) Merge Cygwin copy_environment with do_pam_environment, removing 
+   fixed env var size limit in the process. Report from Corinna Vinschen 
+   <vinschen@redhat.com>
+ - (stevesk) defines.h: use "/var/spool/sockets/X11/%u" for HP-UX.  does
+   not depend on transition links.  from Lutz Jaenicke.
+
+20020106
+ - (stevesk) defines.h: determine _PATH_UNIX_X; currently "/tmp/.X11-unix/X%u"
+   for all platforms except HP-UX, which is "/usr/spool/sockets/X11/%u".
+
+20020105
+ - (bal) NCR requies use_pipes to operate correctly.
+ - (stevesk) fix spurious ; from NCR change.
+
+20020103
+ - (djm) Use bigcrypt() on systems with SCO_PROTECTED_PW. Patch from 
+   Roger Cornelius <rac@tenzing.org>
+
+20011229
+ - (djm) Apply Cygwin pointer deref fix from Corinna Vinschen 
+   <vinschen@redhat.com> Could be abused to guess valid usernames
+ - (djm) Typo in contrib/cygwin/README Fix from Corinna Vinschen
+   <vinschen@redhat.com>
+
+20011228
+ - (djm) Remove recommendation to use GNU make, we should support most
+   make programs.
+
+20011225
+ - (stevesk) [Makefile.in ssh-rand-helper.c]
+   portable lib and __progname support for ssh-rand-helper; ok djm@
+
+20011223
+ - (bal) Removed contrib/chroot.diff and noted in contrib/README that it
+   was not being maintained.
+
+20011222
+ - (djm) Ignore fix & patchlevel in OpenSSL version check. Patch from 
+   solar@openwall.com
+ - (djm) Rework entropy code. If the OpenSSL PRNG is has not been 
+   internally seeded, execute a subprogram "ssh-rand-helper" to obtain
+   some entropy for us. Rewrite the old in-process entropy collecter as
+   an example ssh-rand-helper.
+ - (djm) Always perform ssh_prng_cmds path lookups in configure, even if
+   we don't end up using ssh_prng_cmds (so we always get a valid file) 
+      
+20011221
+ - (djm) Add option to gnome-ssh-askpass to stop it from grabbing the X
+   server. I have found this necessary to avoid server hangs with X input
+   extensions (e.g. kinput2). Enable by setting the environment variable
+   "GNOME_SSH_ASKPASS_NOGRAB"
+  - OpenBSD CVS Sync
+   - stevesk@cvs.openbsd.org 2001/12/08 17:49:28
+     [channels.c pathnames.h]
+     use only one path to X11 UNIX domain socket vs. an array of paths
+     to try.  report from djast@cs.toronto.edu.  ok markus@
+   - markus@cvs.openbsd.org 2001/12/09 18:45:56
+     [auth2.c auth2-chall.c auth.h]
+     add auth2_challenge_stop(), simplifies cleanup of kbd-int sessions,
+     fixes memleak.
+   - stevesk@cvs.openbsd.org 2001/12/10 16:45:04
+     [sshd.c]
+     possible fd leak on error; ok markus@
+   - markus@cvs.openbsd.org 2001/12/10 20:34:31
+     [ssh-keyscan.c]
+     check that server supports v1 for -t rsa1, report from wirth@dfki.de
+   - jakob@cvs.openbsd.org 2001/12/18 10:04:21
+     [auth.h hostfile.c hostfile.h]
+     remove auth_rsa_read_key, make hostfile_ready_key non static; ok markus@
+   - jakob@cvs.openbsd.org 2001/12/18 10:05:15
+     [auth2.c]
+     log fingerprint on successful public key authentication; ok markus@
+   - jakob@cvs.openbsd.org 2001/12/18 10:06:24
+     [auth-rsa.c]
+     log fingerprint on successful public key authentication, simplify 
+     usage of key structs; ok markus@
+   - deraadt@cvs.openbsd.org 2001/12/19 07:18:56
+     [auth1.c auth2.c auth2-chall.c auth-bsdauth.c auth.c authfile.c auth.h]
+     [auth-krb4.c auth-rhosts.c auth-skey.c bufaux.c canohost.c channels.c]
+     [cipher.c clientloop.c compat.c compress.c deattack.c key.c log.c mac.c]
+     [match.c misc.c nchan.c packet.c readconf.c rijndael.c rijndael.h scard.c]
+     [servconf.c servconf.h serverloop.c session.c sftp.c sftp-client.c]
+     [sftp-glob.c sftp-int.c sftp-server.c ssh-add.c ssh-agent.c ssh.c]
+     [sshconnect1.c sshconnect2.c sshconnect.c sshd.8 sshd.c sshd_config]
+     [ssh-keygen.c sshlogin.c sshpty.c sshtty.c ttymodes.c uidswap.c]
+     basic KNF done while i was looking for something else
+   - markus@cvs.openbsd.org 2001/12/19 16:09:39
+     [serverloop.c]
+     fix race between SIGCHLD and select with an additional pipe.  writing
+     to the pipe on SIGCHLD wakes up select(). using pselect() is not
+     portable and siglongjmp() ugly. W. R. Stevens suggests similar solution.
+     initial idea by pmenage@ensim.com; ok deraadt@, djm@
+   - stevesk@cvs.openbsd.org 2001/12/19 17:16:13
+     [authfile.c bufaux.c bufaux.h buffer.c buffer.h packet.c packet.h ssh.c]
+     change the buffer/packet interface to use void* vs. char*; ok markus@
+   - markus@cvs.openbsd.org 2001/12/20 16:37:29
+     [channels.c channels.h session.c]
+     setup x11 listen socket for just one connect if the client requests so.
+     (v2 only, but the openssh client does not support this feature).
+   - djm@cvs.openbsd.org 2001/12/20 22:50:24
+     [auth2.c auth2-chall.c channels.c channels.h clientloop.c dispatch.c]
+     [dispatch.h kex.c kex.h packet.c packet.h serverloop.c ssh.c]
+     [sshconnect2.c]
+     Conformance fix: we should send failing packet sequence number when
+     responding with a SSH_MSG_UNIMPLEMENTED message. Spotted by
+     yakk@yakk.dot.net; ok markus@
+
+20011219
+ - (stevesk) OpenBSD CVS sync X11 localhost display
+   - stevesk@cvs.openbsd.org 2001/11/29 14:10:51
+     [channels.h channels.c session.c]
+     sshd X11 fake server will now listen on localhost by default:
+     $ echo $DISPLAY
+     localhost:12.0
+     $ netstat -an|grep 6012
+     tcp        0      0  127.0.0.1.6012         *.*                    LISTEN
+     tcp6       0      0  ::1.6012               *.*                    LISTEN
+     sshd_config gatewayports=yes can be used to revert back to the old
+     behavior.  will control this with another option later.  ok markus@
+   - stevesk@cvs.openbsd.org 2001/12/19 08:43:11
+     [includes.h session.c]
+     handle utsname.nodename case for FamilyLocal X authorization; ok markus@
+       
+20011207
+ - (bal) PCRE no longer required.  Banished from the source along with
+   fake-regex.h
+ - (bal) OpenBSD CVS Sync
+   - stevesk@cvs.openbsd.org 2001/12/06 18:02:32
+     [channels.c sshconnect.c]
+     shutdown(sock, SHUT_RDWR) not needed here; ok markus@
+   - stevesk@cvs.openbsd.org 2001/12/06 18:09:23
+     [channels.c session.c]
+     strncpy->strlcpy.  remaining strncpy's are necessary.  ok markus@
+   - stevesk@cvs.openbsd.org 2001/12/06 18:20:32
+     [channels.c]
+     disable nagle for X11 fake server and client TCPs.  from netbsd.
+     ok markus@
+
+20011206
+ - (bal) OpenBSD CVS Sync
+   - deraadt@cvs.openbsd.org 2001/11/14 20:45:08
+     [sshd.c]
+     errno saving wrapping in a signal handler
+   - markus@cvs.openbsd.org 2001/11/16 12:46:13
+     [ssh-keyscan.c]
+     handle empty lines instead of dumping core; report from sha@sha-1.net
+   - stevesk@cvs.openbsd.org 2001/11/17 19:14:34
+     [auth2.c auth.c readconf.c servconf.c ssh-agent.c ssh-keygen.c]
+     enum/int type cleanup where it made sense to do so; ok markus@
+   - markus@cvs.openbsd.org 2001/11/19 11:20:21
+     [sshd.c]
+     fd leak on HUP; ok stevesk@
+   - stevesk@cvs.openbsd.org 2001/11/19 18:40:46
+     [ssh-agent.1]
+     clarify/state that private keys are not exposed to clients using the 
+     agent; ok markus@
+   - mpech@cvs.openbsd.org 2001/11/19 19:02:16
+     [deattack.c radix.c]
+     kill more registers
+     millert@ ok
+   - markus@cvs.openbsd.org 2001/11/21 15:51:24
+     [key.c]
+     mem leak
+   - stevesk@cvs.openbsd.org 2001/11/21 18:49:14
+     [ssh-keygen.1]
+     more on passphrase construction; ok markus@
+   - stevesk@cvs.openbsd.org 2001/11/22 05:27:29
+     [ssh-keyscan.c]
+     don't use "\n" in fatal()
+   - markus@cvs.openbsd.org 2001/11/22 12:34:22
+     [clientloop.c serverloop.c sshd.c]
+     volatile sig_atomic_t
+   - stevesk@cvs.openbsd.org 2001/11/29 19:06:39
+     [channels.h]
+     remove dead function prototype; ok markus@
+   - markus@cvs.openbsd.org 2001/11/29 22:08:48
+     [auth-rsa.c]
+     fix protocol error: send 'failed' message instead of a 2nd challenge
+     (happens if the same key is in authorized_keys twice).
+     reported Ralf_Meister@genua.de; ok djm@
+   - stevesk@cvs.openbsd.org 2001/11/30 20:39:28
+     [ssh.c]
+     sscanf() length dependencies are clearer now; can also shrink proto
+     and data if desired, but i have not done that.  ok markus@
+   - markus@cvs.openbsd.org 2001/12/01 21:41:48
+     [session.c sshd.8]
+     don't pass user defined variables to /usr/bin/login
+   - deraadt@cvs.openbsd.org 2001/12/02 02:08:32
+     [sftp-common.c]
+     zap };
+   - itojun@cvs.openbsd.org 2001/12/05 03:50:01
+     [clientloop.c serverloop.c sshd.c]
+     deal with LP64 printf issue with sig_atomic_t.  from thorpej
+   - itojun@cvs.openbsd.org 2001/12/05 03:56:39
+     [auth1.c auth2.c canohost.c channels.c deattack.c packet.c scp.c 
+      sshconnect2.c]
+     make it compile with more strict prototype checking
+   - deraadt@cvs.openbsd.org 2001/12/05 10:06:12
+     [authfd.c authfile.c bufaux.c channels.c compat.c kex.c kexgex.c 
+      key.c misc.c packet.c servconf.c ssh-agent.c sshconnect2.c 
+      sshconnect.c sshd.c ssh-dss.c ssh-keygen.c ssh-rsa.c]
+     minor KNF
+   - markus@cvs.openbsd.org 2001/12/05 15:04:48
+     [version.h]
+     post 3.0.2
+   - markus@cvs.openbsd.org 2001/12/05 16:54:51
+     [compat.c match.c match.h]
+     make theo and djm happy: bye bye regexp
+   - markus@cvs.openbsd.org 2001/12/06 13:30:06
+     [servconf.c servconf.h sshd.8 sshd.c]
+     add -o to sshd, too. ok deraadt@
+ - (bal) Minor white space fix up in servconf.c
+
+20011126
+ - (tim) [contrib/cygwin/README, openbsd-compat/bsd-cygwin_util.c,
+   openbsd-compat/bsd-cygwin_util.h, openbsd-compat/daemon.c]
+   Allow SSHD to install as service under WIndows 9x/Me
+   [configure.ac] Fix to allow linking against PCRE on Cygwin
+   Patches by Corinna Vinschen <vinschen@redhat.com>
 
 20011115
  - (djm) Fix IPv4 default in ssh-keyscan. Spotted by Dan Astoorian 
index 777bdfe3854b1bd18bb89f489667f8ce2a3a507f..c6ee3c89063816be2df7b26aba09464c9d3c0bf8 100644 (file)
@@ -45,18 +45,6 @@ lacks /dev/random and don't want to use OpenSSH's internal entropy collection.
 
 http://www.lothar.com/tech/crypto/
 
-GNU Make:
-ftp://ftp.gnu.org/gnu/make/
-
-OpenSSH has only been tested with GNU make. It may work with other
-'make' programs, but you are on your own.
-
-PCRE (PERL-compatible Regular Expression library):
-ftp://ftp.cus.cam.ac.uk/pub/software/programing/pcre/
-
-Most platforms do not require this.  However older Unices may not have a 
-posix regex library. PCRE provides a POSIX interface.
-
 S/Key Libraries:
 http://www.sparc.spb.su/solaris/skey/
 
index b229fcdf6847f71e50ef9d4d0828b549719341e9..1c98a1d621b7952847a36edd6832bbdefad5eed2 100644 (file)
@@ -140,8 +140,46 @@ OpenSSH contains no GPL code.
      * 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.
-    
+
 6)
+    One component of the ssh source code is under a 4-clause BSD license,
+    held by the University of California, since we pulled these parts from
+    original Berkeley code.  The Regents of the University of California
+    have declared that term 3 is no longer enforceable on their source code,
+    but we retain that license as is.
+
+     * Copyright (c) 1983, 1990, 1992, 1993, 1995
+     *      The Regents of the University of California.  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. All advertising materials mentioning features or use of this software
+     *    must display the following acknowledgement:
+     *      This product includes software developed by the University of
+     *      California, Berkeley and its contributors.
+     * 4. Neither the name of the University nor the names of its contributors
+     *    may be used to endorse or promote products derived from this software
+     *    without specific prior written permission.
+     *
+     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+
+7)
     Remaining components of the software are provided under a standard
     2-term BSD licence with the following names as copyright holders:
 
index d20bfca54efa0b60b0ef483b0827bd5d3ce96378..5bc3cb0fd31d9a6efcae08ea88e2428b6e7950ba 100644 (file)
@@ -19,17 +19,20 @@ SSH_PROGRAM=@bindir@/ssh
 ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
 SFTP_SERVER=$(libexecdir)/sftp-server
 
-PATHS= -DETCDIR=\"$(sysconfdir)\" \
+PATHS= -DSSHDIR=\"$(sysconfdir)\" \
        -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
        -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
        -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \
-       -D_PATH_SSH_PIDDIR=\"$(piddir)\"
+       -D_PATH_SSH_PIDDIR=\"$(piddir)\" \
+       -DSSH_RAND_HELPER=\"$(libexecdir)/ssh-rand-helper\"
 
 CC=@CC@
 LD=@LD@
 CFLAGS=@CFLAGS@
 CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
 LIBS=@LIBS@
+LIBPAM=@LIBPAM@
+LIBWRAP=@LIBWRAP@
 AR=@AR@
 RANLIB=@RANLIB@
 INSTALL=@INSTALL@
@@ -41,12 +44,13 @@ EXEEXT=@EXEEXT@
 SSH_MODE= @SSHMODE@
 
 INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
+INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
 
 @NO_SFTP@SFTP_PROGS=sftp-server$(EXEEXT) sftp$(EXEEXT)
 
-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) $(SFTP_PROGS)
+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} $(SFTP_PROGS)
 
-LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o scard.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 
+LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o dh.o dispatch.o fatal.o mac.o hostfile.o key.o kex.o kexdh.o kexgex.o log.o match.o misc.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o scard.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o uuencode.o xmalloc.o 
 
 SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
 
@@ -60,17 +64,17 @@ CONFIGFILES=sshd_config.out ssh_config.out moduli.out
 CONFIGFILES_IN=sshd_config ssh_config moduli
 
 PATHSUBS       = \
-       -D/etc/ssh_config=$(sysconfdir)/ssh_config \
-       -D/etc/ssh_known_hosts=$(sysconfdir)/ssh_known_hosts \
-       -D/etc/sshd_config=$(sysconfdir)/sshd_config \
+       -D/etc/ssh/ssh_config=$(sysconfdir)/ssh_config \
+       -D/etc/ssh/ssh_known_hosts=$(sysconfdir)/ssh_known_hosts \
+       -D/etc/ssh/sshd_config=$(sysconfdir)/sshd_config \
        -D/usr/libexec=$(libexecdir) \
        -D/etc/shosts.equiv=$(sysconfdir)/shosts.equiv \
-       -D/etc/ssh_host_key=$(sysconfdir)/ssh_host_key \
-       -D/etc/ssh_host_dsa_key=$(sysconfdir)/ssh_host_dsa_key \
-       -D/etc/ssh_host_rsa_key=$(sysconfdir)/ssh_host_rsa_key \
+       -D/etc/ssh/ssh_host_key=$(sysconfdir)/ssh_host_key \
+       -D/etc/ssh/ssh_host_dsa_key=$(sysconfdir)/ssh_host_dsa_key \
+       -D/etc/ssh/ssh_host_rsa_key=$(sysconfdir)/ssh_host_rsa_key \
        -D/var/run/sshd.pid=$(piddir)/sshd.pid \
-       -D/etc/moduli=$(sysconfdir)/moduli \
-       -D/etc/sshrc=$(sysconfdir)/sshrc \
+       -D/etc/ssh/moduli=$(sysconfdir)/moduli \
+       -D/etc/ssh/sshrc=$(sysconfdir)/sshrc \
        -D/usr/X11R6/bin/xauth=$(XAUTH_PATH) \
        -D/usr/bin:/bin:/usr/sbin:/sbin=@user_path@
 
@@ -98,7 +102,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
        $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 sshd$(EXEEXT): libssh.a        $(LIBCOMPAT) $(SSHDOBJS)
-       $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+       $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS)
 
 scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o
        $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
@@ -121,6 +125,9 @@ sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o
 sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o
        $(LD) -o $@ sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
+ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
+       $(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+
 # test driver for the loginrec code - not built by default
 logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
        $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
@@ -197,6 +204,9 @@ install-files: scard-install
        $(INSTALL) -m 0755 -s ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen
        $(INSTALL) -m 0755 -s ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan
        $(INSTALL) -m 0755 -s sshd $(DESTDIR)$(sbindir)/sshd
+       if test ! -z "$(INSTALL_SSH_RAND_HELPER)" ; then \
+               $(INSTALL) -m 0755 -s ssh-rand-helper $(DESTDIR)$(libexecdir)/ssh-rand-helper ; \
+       fi
        @NO_SFTP@$(INSTALL) -m 0755 -s sftp $(DESTDIR)$(bindir)/sftp
        @NO_SFTP@$(INSTALL) -m 0755 -s sftp-server $(DESTDIR)$(SFTP_SERVER)
        $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
@@ -212,7 +222,6 @@ install-files: scard-install
        ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
        ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
-       #@FILEPRIV@ -f dev,filesys,driver $(DESTDIR)$(bindir)/ssh $(DESTDIR)$(bindir)/slogin
        if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
                $(srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir); \
        fi
index 979d1d5b0e1b105fca8e3c0ac56916e1abd61048..75269c81ff380a5c1f32e6232403fff3bb1f8db1 100644 (file)
@@ -1,6 +1,6 @@
 - A Japanese translation of this document and of the OpenSSH FAQ is 
 - available at http://www.unixuser.org/~haruyama/security/openssh/index.html
-- Thanks to HARUYAMA Seigo <haruyama@klab.org>
+- Thanks to HARUYAMA Seigo <haruyama@unixuser.org>
 
 This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other
 Unices.
index 3c89852087958640fca963daab510203a64b2b73..11abaf67122c75c9da7c91823cc9eb8da2f1e825 100644 (file)
@@ -75,6 +75,10 @@ Clean up configure/makefiles:
 - Consider splitting the u_intXX_t test for sys/bitype.h  into seperate test
   to allow people to (right/wrongfully) link against Bind directly.
 
+- Consider splitting configure.ac into seperate files which do logically
+  similar tests. E.g move all the type detection stuff into one file, 
+  entropy related stuff into another.
+
 Packaging:
 - Solaris: Update packaging scripts and build new sysv startup scripts
   Ideally the package metadata should be generated by autoconf.
index 436d72ed1732aa3e8b0535b3b11af29b4e37b5ee..8382c85489ad7a0b4861285dd652d91c461a2b1d 100644 (file)
@@ -59,9 +59,6 @@
 /* Define if you are on Cygwin */
 #undef HAVE_CYGWIN
 
-/* Define if you lack native POSIX regex and you are using PCRE */
-#undef HAVE_LIBPCRE
-
 /* Define if you have a broken realpath. */
 #undef BROKEN_REALPATH
 
@@ -89,9 +86,6 @@
 /* Define if you want IRIX kernel jobs */
 #undef WITH_IRIX_JOBS
 
-/* Location of random number pool  */
-#undef RANDOM_POOL
-
 /* Location of PRNGD/EGD random number socket */
 #undef PRNGD_SOCKET
 
 #undef HAVE_SS_FAMILY_IN_SS
 #undef HAVE___SS_FAMILY_IN_SS
 
-/* Define if you have a regcomp() function */
-#undef HAVE_REGCOMP
-
 /* Define if you have /dev/ptmx */
 #undef HAVE_DEV_PTMX
 
 /* Define if you want smartcard support */
 #undef SMARTCARD
 
+/* Define if you want to use OpenSSL's internally seeded PRNG only */
+#undef OPENSSL_PRNG_ONLY
+
 @BOTTOM@
 
 /* ******************* Shouldn't need to edit below this line ************** */
index 3732477deb0e3ddf034d545e7ae16c5d53682cb9..b70d48f20e02f1024ae93e2c94691d7f03d9b7b2 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: auth-bsdauth.c,v 1.1 2001/05/18 14:13:28 markus Exp $");
+RCSID("$OpenBSD: auth-bsdauth.c,v 1.2 2001/12/19 07:18:56 deraadt Exp $");
 
 #ifdef BSD_AUTH
 #include "xmalloc.h"
@@ -36,74 +36,74 @@ bsdauth_init_ctx(Authctxt *authctxt)
 }
 
 static int
-bsdauth_query(void *ctx, char **name, char **infotxt, 
+bsdauth_query(void *ctx, char **name, char **infotxt,
    u_int *numprompts, char ***prompts, u_int **echo_on)
 {
-        Authctxt *authctxt = ctx;
-        char *challenge = NULL;
-
-        if (authctxt->as != NULL) {
-                debug2("bsdauth_query: try reuse session");
-                challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
-                if (challenge == NULL) {
-                        auth_close(authctxt->as);
-                        authctxt->as = NULL;
-                }
-        }
-
-        if (challenge == NULL) {
-                debug2("bsdauth_query: new bsd auth session");
-                debug3("bsdauth_query: style %s",
+       Authctxt *authctxt = ctx;
+       char *challenge = NULL;
+
+       if (authctxt->as != NULL) {
+               debug2("bsdauth_query: try reuse session");
+               challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
+               if (challenge == NULL) {
+                       auth_close(authctxt->as);
+                       authctxt->as = NULL;
+               }
+       }
+
+       if (challenge == NULL) {
+               debug2("bsdauth_query: new bsd auth session");
+               debug3("bsdauth_query: style %s",
                    authctxt->style ? authctxt->style : "<default>");
-                authctxt->as = auth_userchallenge(authctxt->user,
+               authctxt->as = auth_userchallenge(authctxt->user,
                     authctxt->style, "auth-ssh", &challenge);
-                if (authctxt->as == NULL)
-                        challenge = NULL;
-                debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
-        }
-        
-        if (challenge == NULL)
-                return -1;
-
-        *name       = xstrdup("");
-        *infotxt    = xstrdup("");
-        *numprompts = 1;
-        *prompts = xmalloc(*numprompts * sizeof(char*));
-        *echo_on = xmalloc(*numprompts * sizeof(u_int));
-        (*echo_on)[0] = 0;
-        (*prompts)[0] = xstrdup(challenge);
-
-        return 0;
+               if (authctxt->as == NULL)
+                       challenge = NULL;
+               debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
+       }
+
+       if (challenge == NULL)
+               return -1;
+
+       *name       = xstrdup("");
+       *infotxt    = xstrdup("");
+       *numprompts = 1;
+       *prompts = xmalloc(*numprompts * sizeof(char*));
+       *echo_on = xmalloc(*numprompts * sizeof(u_int));
+       (*echo_on)[0] = 0;
+       (*prompts)[0] = xstrdup(challenge);
+
+       return 0;
 }
 
 static int
 bsdauth_respond(void *ctx, u_int numresponses, char **responses)
 {
-        Authctxt *authctxt = ctx;
-        int authok;
-        
-        if (authctxt->as == 0)
-                error("bsdauth_respond: no bsd auth session");
+       Authctxt *authctxt = ctx;
+       int authok;
+
+       if (authctxt->as == 0)
+               error("bsdauth_respond: no bsd auth session");
 
-        if (numresponses != 1)
-                return -1;
+       if (numresponses != 1)
+               return -1;
 
-        authok = auth_userresponse(authctxt->as, responses[0], 0);
-        authctxt->as = NULL;
-        debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
+       authok = auth_userresponse(authctxt->as, responses[0], 0);
+       authctxt->as = NULL;
+       debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
 
-        return (authok == 0) ? -1 : 0;
+       return (authok == 0) ? -1 : 0;
 }
 
 static void
 bsdauth_free_ctx(void *ctx)
 {
-        Authctxt *authctxt = ctx;
+       Authctxt *authctxt = ctx;
 
-        if (authctxt && authctxt->as) {
-                auth_close(authctxt->as);
-                authctxt->as = NULL;
-        }
+       if (authctxt && authctxt->as) {
+               auth_close(authctxt->as);
+               authctxt->as = NULL;
+       }
 }
 
 KbdintDevice bsdauth_device = {
index 031dcd30126172745470ff06c874dfa94a9f1da4..f7a144f9d6e7c111f8f06a1e4b243e96b491710a 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-krb4.c,v 1.24 2001/06/26 16:15:22 dugsong Exp $");
+RCSID("$OpenBSD: auth-krb4.c,v 1.25 2001/12/19 07:18:56 deraadt Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -49,7 +49,7 @@ krb4_init(void *context)
        const char *tkt_root = TKT_ROOT;
        struct stat st;
        int fd;
-       
+
        if (!authctxt->krb4_ticket_file) {
                /* Set unique ticket string manually since we're still root. */
                authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN);
@@ -79,13 +79,13 @@ krb4_init(void *context)
        }
        /* Failure - cancel cleanup function, leaving ticket for inspection. */
        log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file);
-       
+
        fatal_remove_cleanup(krb4_cleanup_proc, authctxt);
        cleanup_registered = 0;
-       
+
        xfree(authctxt->krb4_ticket_file);
        authctxt->krb4_ticket_file = NULL;
-       
+
        return (0);
 }
 
@@ -103,10 +103,10 @@ auth_krb4_password(Authctxt *authctxt, const char *password)
        char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ];
        u_int32_t faddr;
        int r;
-       
+
        if ((pw = authctxt->pw) == NULL)
                return (0);
-       
+
        /*
         * Try Kerberos password authentication only for non-root
         * users and only if Kerberos is installed.
@@ -128,7 +128,7 @@ auth_krb4_password(Authctxt *authctxt, const char *password)
                }
                /* Successful authentication. */
                chown(tkt_string(), pw->pw_uid, pw->pw_gid);
-               
+
                /*
                 * Now that we have a TGT, try to get a local
                 * "rcmd" ticket to ensure that we are not talking
@@ -138,7 +138,7 @@ auth_krb4_password(Authctxt *authctxt, const char *password)
                strlcpy(phost, (char *)krb_get_phost(localhost),
                    sizeof(phost));
                r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
-               
+
                if (r == KSUCCESS) {
                        if ((hp = gethostbyname(localhost)) == NULL) {
                                log("Couldn't get local host address!");
@@ -146,7 +146,7 @@ auth_krb4_password(Authctxt *authctxt, const char *password)
                        }
                        memmove((void *)&faddr, (void *)hp->h_addr,
                            sizeof(faddr));
-                       
+
                        /* Verify our "rcmd" ticket. */
                        r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
                            faddr, &adata, "");
@@ -186,13 +186,13 @@ auth_krb4_password(Authctxt *authctxt, const char *password)
        } else
                /* Logging in as root or no local Kerberos realm. */
                debug("Unable to authenticate to Kerberos.");
-       
+
  failure:
        krb4_cleanup_proc(authctxt);
-       
+
        if (!options.kerberos_or_local_passwd)
                return (0);
-       
+
        /* Fall back to ordinary passwd authentication. */
        return (-1);
 }
@@ -220,9 +220,9 @@ auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
        socklen_t slen;
        u_int cksum;
        int r, s;
-       
+
        s = packet_get_connection_in();
-       
+
        slen = sizeof(local);
        memset(&local, 0, sizeof(local));
        if (getsockname(s, (struct sockaddr *) & local, &slen) < 0)
@@ -235,7 +235,7 @@ auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
        }
        instance[0] = '*';
        instance[1] = 0;
-       
+
        /* Get the encrypted request, challenge, and session key. */
        if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance,
            0, &adat, ""))) {
@@ -243,11 +243,11 @@ auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
                return (0);
        }
        des_key_sched((des_cblock *) adat.session, schedule);
-       
+
        *client = xmalloc(MAX_K_NAME_SZ);
        (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
            *adat.pinst ? "." : "", adat.pinst, adat.prealm);
-       
+
        /* Check ~/.klogin authorization now. */
        if (kuserok(&adat, authctxt->user) != KSUCCESS) {
                log("Kerberos v4 .klogin authorization failed for %s to "
@@ -259,7 +259,7 @@ auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
           session key. */
        cksum = adat.checksum + 1;
        cksum = htonl(cksum);
-       
+
        /* If we can't successfully encrypt the checksum, we send back an
           empty message, admitting our failure. */
        if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1,
@@ -269,10 +269,10 @@ auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
                reply.length = 0;
        } else
                reply.length = r;
-       
+
        /* Clear session key. */
        memset(&adat.session, 0, sizeof(&adat.session));
-       
+
        packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
        packet_put_string((char *) reply.dat, reply.length);
        packet_send();
@@ -287,19 +287,19 @@ auth_krb4_tgt(Authctxt *authctxt, const char *string)
 {
        CREDENTIALS creds;
        struct passwd *pw;
-       
+
        if ((pw = authctxt->pw) == NULL)
                goto failure;
-       
+
        temporarily_use_uid(pw);
-       
+
        if (!radix_to_creds(string, &creds)) {
                log("Protocol error decoding Kerberos v4 TGT");
                goto failure;
        }
        if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
                strlcpy(creds.service, "krbtgt", sizeof creds.service);
-       
+
        if (strcmp(creds.service, "krbtgt")) {
                log("Kerberos v4 TGT (%s%s%s@%s) rejected for %s",
                    creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
@@ -308,10 +308,10 @@ auth_krb4_tgt(Authctxt *authctxt, const char *string)
        }
        if (!krb4_init(authctxt))
                goto failure;
-       
+
        if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
                goto failure;
-       
+
        if (save_credentials(creds.service, creds.instance, creds.realm,
            creds.session, creds.lifetime, creds.kvno, &creds.ticket_st,
            creds.issue_date) != KSUCCESS) {
@@ -320,20 +320,20 @@ auth_krb4_tgt(Authctxt *authctxt, const char *string)
        }
        /* Successful authentication, passed all checks. */
        chown(tkt_string(), pw->pw_uid, pw->pw_gid);
-       
+
        debug("Kerberos v4 TGT accepted (%s%s%s@%s)",
            creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
        memset(&creds, 0, sizeof(creds));
-       
+
        restore_uid();
-       
+
        return (1);
-       
+
  failure:
        krb4_cleanup_proc(authctxt);
        memset(&creds, 0, sizeof(creds));
        restore_uid();
-       
+
        return (0);
 }
 
@@ -343,22 +343,22 @@ auth_afs_token(Authctxt *authctxt, const char *token_string)
        CREDENTIALS creds;
        struct passwd *pw;
        uid_t uid;
-       
+
        if ((pw = authctxt->pw) == NULL)
                return (0);
-       
+
        if (!radix_to_creds(token_string, &creds)) {
                log("Protocol error decoding AFS token");
                return (0);
        }
        if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
                strlcpy(creds.service, "afs", sizeof creds.service);
-       
+
        if (strncmp(creds.pname, "AFS ID ", 7) == 0)
                uid = atoi(creds.pname + 7);
        else
                uid = pw->pw_uid;
-       
+
        if (kafs_settoken(creds.realm, uid, &creds)) {
                log("AFS token (%s@%s) rejected for %s",
                    creds.pname, creds.realm, pw->pw_name);
@@ -367,7 +367,7 @@ auth_afs_token(Authctxt *authctxt, const char *token_string)
        }
        debug("AFS token accepted (%s@%s)", creds.pname, creds.realm);
        memset(&creds, 0, sizeof(creds));
-       
+
        return (1);
 }
 #endif /* AFS */
index b56f43a92388f6a82e952136907866180bab3feb..2da0669ae629f7e1153a970f03447e0853960c7c 100644 (file)
@@ -2,10 +2,11 @@
  *    Kerberos v5 authentication and ticket-passing routines.
  * 
  * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
- * $OpenBSD: auth-krb5.c,v 1.2 2001/11/12 01:47:09 dugsong Exp $
  */
 
 #include "includes.h"
+RCSID("$OpenBSD: auth-krb5.c,v 1.6 2002/03/04 17:27:39 stevesk Exp $");
+
 #include "ssh.h"
 #include "ssh1.h"
 #include "packet.h"
@@ -26,7 +27,7 @@ krb5_init(void *context)
        Authctxt *authctxt = (Authctxt *)context;
        krb5_error_code problem;
        static int cleanup_registered = 0;
-       
+
        if (authctxt->krb5_ctx == NULL) {
                problem = krb5_init_context(&authctxt->krb5_ctx);
                if (problem)
@@ -45,7 +46,7 @@ krb5_init(void *context)
  * only, in auth is received ticket, in client is returned principal
  * from the ticket
  */
-int 
+int
 auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
 {
        krb5_error_code problem;
@@ -58,52 +59,52 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
        server = NULL;
        ticket = NULL;
        reply.length = 0;
-       
+
        problem = krb5_init(authctxt);
-       if (problem) 
+       if (problem)
                goto err;
-       
+
        problem = krb5_auth_con_init(authctxt->krb5_ctx,
            &authctxt->krb5_auth_ctx);
        if (problem)
                goto err;
-       
+
        fd = packet_get_connection_in();
        problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
            authctxt->krb5_auth_ctx, &fd);
        if (problem)
                goto err;
-       
+
        problem = krb5_sname_to_principal(authctxt->krb5_ctx,  NULL, NULL ,
            KRB5_NT_SRV_HST, &server);
        if (problem)
                goto err;
-       
+
        problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
            auth, server, NULL, NULL, &ticket);
        if (problem)
                goto err;
-       
+
        problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
            &authctxt->krb5_user);
        if (problem)
                goto err;
-       
+
        /* if client wants mutual auth */
        problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
            &reply);
        if (problem)
                goto err;
-       
+
        /* Check .k5login authorization now. */
        if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
            authctxt->pw->pw_name))
                goto err;
-       
+
        if (client)
                krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    client);
-       
+
        packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
        packet_put_string((char *) reply.data, reply.length);
        packet_send();
@@ -117,10 +118,15 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
                krb5_free_ticket(authctxt->krb5_ctx, ticket);
        if (reply.length)
                xfree(reply.data);
-       
-       if (problem)
-               debug("Kerberos v5 authentication failed: %s",
-                   krb5_get_err_text(authctxt->krb5_ctx, problem));
+
+       if (problem) {
+               if (authctxt->krb5_ctx != NULL)
+                       debug("Kerberos v5 authentication failed: %s",
+                           krb5_get_err_text(authctxt->krb5_ctx, problem));
+               else
+                       debug("Kerberos v5 authentication failed: %d",
+                           problem);
+       }
 
        return (ret);
 }
@@ -131,51 +137,51 @@ auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
        krb5_error_code problem;
        krb5_ccache ccache = NULL;
        char *pname;
-       
+
        if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
                return (0);
-       
+
        temporarily_use_uid(authctxt->pw);
-       
+
        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
        if (problem)
                goto fail;
-       
+
        problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
            authctxt->krb5_user);
        if (problem)
                goto fail;
-       
+
        problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
            ccache, tgt);
        if (problem)
                goto fail;
-       
+
        authctxt->krb5_fwd_ccache = ccache;
        ccache = NULL;
-       
+
        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
-       
+
        problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
            &pname);
        if (problem)
                goto fail;
-       
+
        debug("Kerberos v5 TGT accepted (%s)", pname);
-       
+
        restore_uid();
-       
+
        return (1);
-       
+
  fail:
        if (problem)
                debug("Kerberos v5 TGT passing failed: %s",
                    krb5_get_err_text(authctxt->krb5_ctx, problem));
        if (ccache)
                krb5_cc_destroy(authctxt->krb5_ctx, ccache);
-       
+
        restore_uid();
-       
+
        return (0);
 }
 
@@ -183,47 +189,54 @@ int
 auth_krb5_password(Authctxt *authctxt, const char *password)
 {
        krb5_error_code problem;
-       
+
        if (authctxt->pw == NULL)
                return (0);
-       
+
        temporarily_use_uid(authctxt->pw);
-       
+
        problem = krb5_init(authctxt);
        if (problem)
                goto out;
-       
+
        problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
                    &authctxt->krb5_user);
        if (problem)
                goto out;
-       
+
        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
            &authctxt->krb5_fwd_ccache);
        if (problem)
                goto out;
-       
+
        problem = krb5_cc_initialize(authctxt->krb5_ctx,
            authctxt->krb5_fwd_ccache, authctxt->krb5_user);
        if (problem)
                goto out;
-       
+
+       restore_uid();
        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
            authctxt->krb5_fwd_ccache, password, 1, NULL);
+       temporarily_use_uid(authctxt->pw);
+
        if (problem)
                goto out;
-       
+
        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
-       
+
  out:
        restore_uid();
-       
+
        if (problem) {
-               debug("Kerberos password authentication failed: %s",
-                   krb5_get_err_text(authctxt->krb5_ctx, problem));
-               
+               if (authctxt->krb5_ctx != NULL)
+                       debug("Kerberos password authentication failed: %s",
+                           krb5_get_err_text(authctxt->krb5_ctx, problem));
+               else
+                       debug("Kerberos password authentication failed: %d",
+                           problem);
+
                krb5_cleanup_proc(authctxt);
-               
+
                if (options.kerberos_or_local_passwd)
                        return (-1);
                else
@@ -236,7 +249,7 @@ void
 krb5_cleanup_proc(void *context)
 {
        Authctxt *authctxt = (Authctxt *)context;
-       
+
        debug("krb5_cleanup_proc called");
        if (authctxt->krb5_fwd_ccache) {
                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
index 9f90437ca37447fae2d3d326812e2c94e6e0efd7..8df6a6dfcabbd910313e620f770503c02432b2ed 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-options.c,v 1.20 2001/08/30 20:36:34 stevesk Exp $");
+RCSID("$OpenBSD: auth-options.c,v 1.21 2002/01/29 14:32:03 markus Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -170,7 +170,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
                if (strncasecmp(opts, cp, strlen(cp)) == 0) {
                        const char *remote_ip = get_remote_ipaddr();
                        const char *remote_host = get_canonical_hostname(
-                           options.reverse_mapping_check);
+                           options.verify_reverse_mapping);
                        char *patterns = xmalloc(strlen(opts) + 1);
 
                        opts += strlen(cp);
index 3b2ce344b0f34a3c31b7730ac696d1c0e509a30e..aa6270fd62ef0aab69ec8cb3396f17dc68e6a6c9 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: auth-options.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $       */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* $OpenBSD: auth-options.h,v 1.10 2001/06/26 17:27:22 markus Exp $ */
-
 #ifndef AUTH_OPTIONS_H
 #define AUTH_OPTIONS_H
 
index 801c9eb64b4c8d6c9e0dbc9bdccb59da77146085..687c95ccd0cbfea5e484159e9829e1046adf46fb 100644 (file)
@@ -360,7 +360,7 @@ void start_pam(const char *user)
                fatal("PAM initialisation failed[%d]: %.200s",
                    pam_retval, PAM_STRERROR(__pamh, pam_retval));
 
-       rhost = get_remote_name_or_ip(utmp_len, options.reverse_mapping_check);
+       rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping);
        debug("PAM setting rhost to \"%.200s\"", rhost);
 
        pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost);
index 988297cb464a4bbd01a681bf17cf2771eab44665..095b9ba27c9b43e7eba6c5bd2c9de28cbb10b704 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-passwd.c,v 1.23 2001/06/26 16:15:23 dugsong Exp $");
+RCSID("$OpenBSD: auth-passwd.c,v 1.24 2002/03/04 12:43:06 markus Exp $");
 
 #if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
 
 #include "packet.h"
-#include "xmalloc.h"
 #include "log.h"
 #include "servconf.h"
 #include "auth.h"
@@ -212,7 +211,11 @@ auth_password(Authctxt *authctxt, const char *password)
        else
                encrypted_password = crypt(password, salt);
 # else
+#  ifdef HAVE_SCO_PROTECTED_PW
+       encrypted_password = bigcrypt(password, salt);
+#  else
        encrypted_password = crypt(password, salt);
+#  endif /* HAVE_SCO_PROTECTED_PW */
 # endif /* __hpux */
 #endif /* HAVE_MD5_PASSWORDS */
 
index 8a486b330a0bab62554210fc0382ac0ed36687da..d1b7ae996d50947a5aa46b572ec8bd018b74541d 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-rh-rsa.c,v 1.26 2001/11/07 22:41:51 markus Exp $");
+RCSID("$OpenBSD: auth-rh-rsa.c,v 1.29 2002/03/04 12:43:06 markus Exp $");
 
 #include "packet.h"
-#include "xmalloc.h"
 #include "uidswap.h"
 #include "log.h"
 #include "servconf.h"
@@ -32,16 +31,15 @@ RCSID("$OpenBSD: auth-rh-rsa.c,v 1.26 2001/11/07 22:41:51 markus Exp $");
  */
 
 int
-auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key)
+auth_rhosts_rsa(struct passwd *pw, const char *client_user, Key *client_host_key)
 {
        extern ServerOptions options;
        const char *canonical_hostname;
        HostStatus host_status;
-       Key *client_key;
 
        debug("Trying rhosts with RSA host authentication for client user %.100s", client_user);
 
-       if (pw == NULL || client_host_key == NULL)
+       if (pw == NULL || client_host_key == NULL || client_host_key->rsa == NULL)
                return 0;
 
        /* Check if we would accept it using rhosts authentication. */
@@ -49,21 +47,14 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
                return 0;
 
        canonical_hostname = get_canonical_hostname(
-           options.reverse_mapping_check);
+           options.verify_reverse_mapping);
 
        debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname);
 
-       /* wrap the RSA key into a 'generic' key */
-       client_key = key_new(KEY_RSA1);
-       BN_copy(client_key->rsa->e, client_host_key->e);
-       BN_copy(client_key->rsa->n, client_host_key->n);
-
-       host_status = check_key_in_hostfiles(pw, client_key, canonical_hostname,
-           _PATH_SSH_SYSTEM_HOSTFILE,
+       host_status = check_key_in_hostfiles(pw, client_host_key,
+           canonical_hostname, _PATH_SSH_SYSTEM_HOSTFILE,
            options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
 
-       key_free(client_key);
-
        if (host_status != HOST_OK) {
                debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
                packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
@@ -72,7 +63,7 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
        /* A matching host key was found and is known. */
 
        /* Perform the challenge-response dialog with the client for the host key. */
-       if (!auth_rsa_challenge_dialog(client_host_key)) {
+       if (!auth_rsa_challenge_dialog(client_host_key->rsa)) {
                log("Client on %.800s failed to respond correctly to host authentication.",
                    canonical_hostname);
                return 0;
index 9ba64dbc3a9d729bd008d1cf77ab3e28ae4adc82..bd15261f705946054ca1a9def56e1051792dc511 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-rhosts.c,v 1.24 2001/06/23 15:12:17 itojun Exp $");
+RCSID("$OpenBSD: auth-rhosts.c,v 1.27 2002/03/04 12:43:06 markus Exp $");
 
 #include "packet.h"
-#include "xmalloc.h"
 #include "uidswap.h"
 #include "pathnames.h"
 #include "log.h"
@@ -156,7 +155,7 @@ auth_rhosts(struct passwd *pw, const char *client_user)
        const char *hostname, *ipaddr;
        int ret;
 
-       hostname = get_canonical_hostname(options.reverse_mapping_check);
+       hostname = get_canonical_hostname(options.verify_reverse_mapping);
        ipaddr = get_remote_ipaddr();
        ret = auth_rhosts2(pw, client_user, hostname, ipaddr);
        return ret;
@@ -186,7 +185,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
         * servers.
         */
        for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
-            rhosts_file_index++) {
+           rhosts_file_index++) {
                /* Check users .rhosts or .shosts. */
                snprintf(buf, sizeof buf, "%.500s/%.100s",
                         pw->pw_dir, rhosts_files[rhosts_file_index]);
@@ -204,16 +203,16 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
 
        /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
        if (pw->pw_uid != 0) {
-               if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, client_user,
-                                     pw->pw_name)) {
+               if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
+                   client_user, pw->pw_name)) {
                        packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
-                                         hostname, ipaddr);
+                           hostname, ipaddr);
                        return 1;
                }
-               if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr, client_user,
-                                     pw->pw_name)) {
+               if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
+                   client_user, pw->pw_name)) {
                        packet_send_debug("Accepted for %.100s [%.100s] by %.100s.",
-                                     hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
+                           hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
                        return 1;
                }
        }
@@ -230,7 +229,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
        }
        if (options.strict_modes &&
            ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-            (st.st_mode & 022) != 0)) {
+           (st.st_mode & 022) != 0)) {
                log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
                    pw->pw_name);
                packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
@@ -242,7 +241,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
 
        /* Check all .rhosts files (currently .shosts and .rhosts). */
        for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
-            rhosts_file_index++) {
+           rhosts_file_index++) {
                /* Check users .rhosts or .shosts. */
                snprintf(buf, sizeof buf, "%.500s/%.100s",
                         pw->pw_dir, rhosts_files[rhosts_file_index]);
@@ -257,7 +256,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
                 */
                if (options.strict_modes &&
                    ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-                    (st.st_mode & 022) != 0)) {
+                   (st.st_mode & 022) != 0)) {
                        log("Rhosts authentication refused for %.100s: bad modes for %.200s",
                            pw->pw_name, buf);
                        packet_send_debug("Bad file modes for %.200s", buf);
index 701d8bd5317da247a31ad566cfce98d4b960815a..f7ae03cfdaf13009c5b28b2e5fc6d5dd92a86aa6 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-rsa.c,v 1.44 2001/07/23 18:14:58 stevesk Exp $");
+RCSID("$OpenBSD: auth-rsa.c,v 1.50 2001/12/28 14:50:54 markus Exp $");
 
 #include <openssl/rsa.h>
 #include <openssl/md5.h>
@@ -31,6 +31,7 @@ RCSID("$OpenBSD: auth-rsa.c,v 1.44 2001/07/23 18:14:58 stevesk Exp $");
 #include "log.h"
 #include "servconf.h"
 #include "auth.h"
+#include "hostfile.h"
 
 /* import */
 extern ServerOptions options;
@@ -65,14 +66,17 @@ auth_rsa_challenge_dialog(RSA *pk)
        u_char buf[32], mdbuf[16], response[16];
        MD5_CTX md;
        u_int i;
-       int plen, len;
+       int len;
 
-       encrypted_challenge = BN_new();
-       challenge = BN_new();
+       if ((encrypted_challenge = BN_new()) == NULL)
+               fatal("auth_rsa_challenge_dialog: BN_new() failed");
+       if ((challenge = BN_new()) == NULL)
+               fatal("auth_rsa_challenge_dialog: BN_new() failed");
 
        /* Generate a random challenge. */
        BN_rand(challenge, 256, 0, 0);
-       ctx = BN_CTX_new();
+       if ((ctx = BN_CTX_new()) == NULL)
+               fatal("auth_rsa_challenge_dialog: BN_CTX_new() failed");
        BN_mod(challenge, challenge, pk->n, ctx);
        BN_CTX_free(ctx);
 
@@ -87,10 +91,10 @@ auth_rsa_challenge_dialog(RSA *pk)
        packet_write_wait();
 
        /* Wait for a response. */
-       packet_read_expect(&plen, SSH_CMSG_AUTH_RSA_RESPONSE);
-       packet_integrity_check(plen, 16, SSH_CMSG_AUTH_RSA_RESPONSE);
+       packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE);
        for (i = 0; i < 16; i++)
                response[i] = packet_get_char();
+       packet_check_eom();
 
        /* The response is MD5 of decrypted challenge plus session id. */
        len = BN_num_bytes(challenge);
@@ -128,7 +132,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
        FILE *f;
        u_long linenum = 0;
        struct stat st;
-       RSA *pk;
+       Key *key;
+       char *fp;
 
        /* no user given */
        if (pw == NULL)
@@ -170,9 +175,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
        /* Flag indicating whether authentication has succeeded. */
        authenticated = 0;
 
-       pk = RSA_new();
-       pk->e = BN_new();
-       pk->n = BN_new();
+       key = key_new(KEY_RSA1);
 
        /*
         * Go though the accepted keys, looking for the current key.  If
@@ -210,7 +213,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
                        options = NULL;
 
                /* Parse the key from the line. */
-               if (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) {
+               if (hostfile_read_key(&cp, &bits, key) == 0) {
                        debug("%.100s, line %lu: non ssh1 key syntax",
                            file, linenum);
                        continue;
@@ -218,14 +221,14 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
                /* cp now points to the comment part. */
 
                /* Check if the we have found the desired key (identified by its modulus). */
-               if (BN_cmp(pk->n, client_n) != 0)
+               if (BN_cmp(key->rsa->n, client_n) != 0)
                        continue;
 
                /* check the real bits  */
-               if (bits != BN_num_bits(pk->n))
+               if (bits != BN_num_bits(key->rsa->n))
                        log("Warning: %s, line %lu: keysize mismatch: "
                            "actual %d vs. announced %d.",
-                           file, linenum, BN_num_bits(pk->n), bits);
+                           file, linenum, BN_num_bits(key->rsa->n), bits);
 
                /* We have found the desired key. */
                /*
@@ -236,11 +239,15 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
                        continue;
 
                /* Perform the challenge-response dialog for this key. */
-               if (!auth_rsa_challenge_dialog(pk)) {
+               if (!auth_rsa_challenge_dialog(key->rsa)) {
                        /* Wrong response. */
                        verbose("Wrong response to RSA authentication challenge.");
                        packet_send_debug("Wrong response to RSA authentication challenge.");
-                       continue;
+                       /*
+                        * Break out of the loop. Otherwise we might send
+                        * another challenge and break the protocol.
+                        */
+                       break;
                }
                /*
                 * Correct response.  The client has been successfully
@@ -251,6 +258,12 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
                 * otherwise continue searching.
                 */
                authenticated = 1;
+
+               fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+               verbose("Found matching %s key: %s",
+                   key_type(key), fp);
+               xfree(fp);
+
                break;
        }
 
@@ -261,7 +274,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
        xfree(file);
        fclose(f);
 
-       RSA_free(pk);
+       key_free(key);
 
        if (authenticated)
                packet_send_debug("RSA authentication accepted.");
index 4e947cd4ed1dc428c0afcea00bbe5f4876ecb7e6..8585f5d6b6fb4ba541eda0a9d0f4d7a24326ea78 100644 (file)
@@ -29,7 +29,7 @@ auth_sia_password(char *user, char *pass)
        SIAENTITY *ent = NULL;
        const char *host;
 
-       host = get_canonical_hostname(options.reverse_mapping_check);
+       host = get_canonical_hostname(options.verify_reverse_mapping);
 
        if (!user || !pass)
                return(0);
@@ -58,7 +58,7 @@ session_setup_sia(char *user, char *tty)
        SIAENTITY *ent = NULL;
        const char *host;
 
-       host = get_canonical_hostname (options.reverse_mapping_check);
+       host = get_canonical_hostname (options.verify_reverse_mapping);
 
        if (sia_ses_init(&ent, saved_argc, saved_argv, host, user, tty, 0,
            NULL) != SIASUCCESS) {
index f921fc1bb70d8473b4527dc6d0ab10c8ff136d72..df19f75072d17190f078f22fc10de50a6406ad05 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: auth-skey.c,v 1.12 2001/05/18 14:13:28 markus Exp $");
+RCSID("$OpenBSD: auth-skey.c,v 1.16 2002/01/12 13:10:29 markus Exp $");
 
 #ifdef SKEY
 
@@ -40,7 +40,7 @@ skey_init_ctx(Authctxt *authctxt)
 #define PROMPT "\nS/Key Password: "
 
 static int
-skey_query(void *ctx, char **name, char **infotxt, 
+skey_query(void *ctx, char **name, char **infotxt,
     u_int* numprompts, char ***prompts, u_int **echo_on)
 {
        Authctxt *authctxt = ctx;
@@ -60,8 +60,7 @@ skey_query(void *ctx, char **name, char **infotxt,
 
        len = strlen(challenge) + strlen(PROMPT) + 1;
        p = xmalloc(len);
-       p[0] = '\0';
-       strlcat(p, challenge, len);
+       strlcpy(p, challenge, len);
        strlcat(p, PROMPT, len);
        (*prompts)[0] = p;
 
@@ -72,9 +71,9 @@ static int
 skey_respond(void *ctx, u_int numresponses, char **responses)
 {
        Authctxt *authctxt = ctx;
+
        if (authctxt->valid &&
-           numresponses == 1 && 
+           numresponses == 1 &&
            skey_haskey(authctxt->pw->pw_name) == 0 &&
            skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
            return 0;
index 2bf877d1d1bc362c4998dfe81afe0f4a4652c966..26dce5b670ab3792e363d779285586a200a6c7ee 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.29 2001/11/08 20:02:24 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.35 2002/03/01 13:12:10 markus Exp $");
 
 #ifdef HAVE_LOGIN_H
 #include <login.h>
@@ -105,43 +105,60 @@ allowed_user(struct passwd * pw)
        shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
 
        /* deny if shell does not exists or is not executable */
-       if (stat(shell, &st) != 0)
+       if (stat(shell, &st) != 0) {
+               log("User %.100s not allowed because shell %.100s does not exist",
+                   pw->pw_name, shell);
                return 0;
-       if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP))))
+       }
+       if (!((st.st_mode & S_IFREG) && (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)))) {
+               log("User %.100s not allowed because shell %.100s is not executable",
+                   pw->pw_name, shell);
                return 0;
+       }
 
        if (options.num_deny_users > 0 || options.num_allow_users > 0) {
-               hostname = get_canonical_hostname(options.reverse_mapping_check);
+               hostname = get_canonical_hostname(options.verify_reverse_mapping);
                ipaddr = get_remote_ipaddr();
        }
 
        /* Return false if user is listed in DenyUsers */
        if (options.num_deny_users > 0) {
                for (i = 0; i < options.num_deny_users; i++)
-                       if (match_user(pw->pw_name, hostname, ipaddr,
-                           options.deny_users[i]))
+                       if (match_user(pw->pw_name, hostname, ipaddr,
+                           options.deny_users[i])) {
+                               log("User %.100s not allowed because listed in DenyUsers",
+                                   pw->pw_name);
                                return 0;
+                       }
        }
        /* Return false if AllowUsers isn't empty and user isn't listed there */
        if (options.num_allow_users > 0) {
                for (i = 0; i < options.num_allow_users; i++)
-                       if (match_user(pw->pw_name, hostname, ipaddr,
+                       if (match_user(pw->pw_name, hostname, ipaddr,
                            options.allow_users[i]))
                                break;
                /* i < options.num_allow_users iff we break for loop */
-               if (i >= options.num_allow_users)
+               if (i >= options.num_allow_users) {
+                       log("User %.100s not allowed because not listed in AllowUsers",
+                           pw->pw_name);
                        return 0;
+               }
        }
        if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
                /* Get the user's group access list (primary and supplementary) */
-               if (ga_init(pw->pw_name, pw->pw_gid) == 0)
+               if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
+                       log("User %.100s not allowed because not in any group",
+                           pw->pw_name);
                        return 0;
+               }
 
                /* Return false if one of user's groups is listed in DenyGroups */
                if (options.num_deny_groups > 0)
                        if (ga_match(options.deny_groups,
                            options.num_deny_groups)) {
                                ga_free();
+                               log("User %.100s not allowed because a group is listed in DenyGroups",
+                                   pw->pw_name);
                                return 0;
                        }
                /*
@@ -152,6 +169,8 @@ allowed_user(struct passwd * pw)
                        if (!ga_match(options.allow_groups,
                            options.num_allow_groups)) {
                                ga_free();
+                               log("User %.100s not allowed because none of user's groups are listed in AllowGroups",
+                                   pw->pw_name);
                                return 0;
                        }
                ga_free();
@@ -272,7 +291,7 @@ expand_filename(const char *filename, struct passwd *pw)
                }
                if (cp[0] == '%' && cp[1] == 'u') {
                        buffer_append(&buffer, pw->pw_name,
-                            strlen(pw->pw_name));
+                           strlen(pw->pw_name));
                        cp++;
                        continue;
                }
@@ -315,7 +334,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
        Key *found;
        char *user_hostfile;
        struct stat st;
-       int host_status;
+       HostStatus host_status;
 
        /* Check if we know the host and its host key. */
        found = key_new(key->type);
@@ -326,7 +345,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
                if (options.strict_modes &&
                    (stat(user_hostfile, &st) == 0) &&
                    ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
-                    (st.st_mode & 022) != 0)) {
+                   (st.st_mode & 022) != 0)) {
                        log("Authentication refused for %.100s: "
                            "bad owner or modes for %.200s",
                            pw->pw_name, user_hostfile);
@@ -399,7 +418,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
                if (stat(buf, &st) < 0 ||
                    (st.st_uid != 0 && st.st_uid != uid) ||
                    (st.st_mode & 022) != 0) {
-                       snprintf(err, errlen, 
+                       snprintf(err, errlen,
                            "bad ownership or modes for directory %s", buf);
                        return -1;
                }
index edfc9fb551eeb7e9ddcfaa5adbbb8c4a1c6f98c9..c7175405d83d3e165c0ad95592575267f5ff4c85 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: auth.h,v 1.29 2002/03/04 17:27:39 stevesk Exp $       */
+
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -21,8 +23,8 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $OpenBSD: auth.h,v 1.22 2001/06/26 17:27:22 markus Exp $
  */
+
 #ifndef AUTH_H
 #define AUTH_H
 
@@ -71,30 +73,28 @@ struct Authctxt {
 
 /*
  * Keyboard interactive device:
- * init_ctx    returns: non NULL upon success 
- * query       returns: 0 - success, otherwise failure 
+ * init_ctx    returns: non NULL upon success
+ * query       returns: 0 - success, otherwise failure
  * respond     returns: 0 - success, 1 - need further interaction,
  *             otherwise - failure
  */
 struct KbdintDevice
 {
        const char *name;
-       void*   (*init_ctx)     __P((Authctxt*));
-       int     (*query)        __P((void *ctx, char **name, char **infotxt,
-                               u_int *numprompts, char ***prompts,
-                               u_int **echo_on));
-       int     (*respond)      __P((void *ctx, u_int numresp, char **responses));
-       void    (*free_ctx)     __P((void *ctx));
+       void*   (*init_ctx)(Authctxt*);
+       int     (*query)(void *ctx, char **name, char **infotxt,
+                   u_int *numprompts, char ***prompts, u_int **echo_on);
+       int     (*respond)(void *ctx, u_int numresp, char **responses);
+       void    (*free_ctx)(void *ctx);
 };
 
 int     auth_rhosts(struct passwd *, const char *);
 int
 auth_rhosts2(struct passwd *, const char *, const char *, const char *);
 
-int     auth_rhosts_rsa(struct passwd *, const char *, RSA *);
+int     auth_rhosts_rsa(struct passwd *, const char *, Key *);
 int      auth_password(Authctxt *, const char *);
 int      auth_rsa(struct passwd *, BIGNUM *);
-int      auth_rsa_read_key(char **, u_int *, BIGNUM *, BIGNUM *);
 int      auth_rsa_challenge_dialog(RSA *);
 
 #ifdef KRB4
@@ -130,6 +130,7 @@ void        userauth_finish(Authctxt *, int, char *);
 int    auth_root_allowed(char *);
 
 int    auth2_challenge(Authctxt *, char *);
+void   auth2_challenge_stop(Authctxt *);
 
 int    allowed_user(struct passwd *);
 
index 1fbfad90ae8c0da76590e57724e58b5164898052..c2d99895f430b563bf7d09af9d4bf58248049a45 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.25 2001/06/26 16:15:23 dugsong Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.35 2002/02/03 17:53:25 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -22,6 +22,7 @@ RCSID("$OpenBSD: auth1.c,v 1.25 2001/06/26 16:15:23 dugsong Exp $");
 #include "servconf.h"
 #include "compat.h"
 #include "auth.h"
+#include "channels.h"
 #include "session.h"
 #include "misc.h"
 #include "uidswap.h"
@@ -66,18 +67,17 @@ do_authloop(Authctxt *authctxt)
 {
        int authenticated = 0;
        u_int bits;
-       RSA *client_host_key;
+       Key *client_host_key;
        BIGNUM *n;
        char *client_user, *password;
        char info[1024];
        u_int dlen;
-       int plen, nlen, elen;
        u_int ulen;
        int type = 0;
        struct passwd *pw = authctxt->pw;
 
        debug("Attempting authentication for %s%.100s.",
-            authctxt->valid ? "" : "illegal user ", authctxt->user);
+           authctxt->valid ? "" : "illegal user ", authctxt->user);
 
        /* If the user has no password, accept authentication immediately. */
        if (options.password_authentication &&
@@ -109,7 +109,7 @@ do_authloop(Authctxt *authctxt)
                info[0] = '\0';
 
                /* Get a packet from the client. */
-               type = packet_read(&plen);
+               type = packet_read();
 
                /* Process the packet. */
                switch (type) {
@@ -120,17 +120,16 @@ do_authloop(Authctxt *authctxt)
                                verbose("Kerberos authentication disabled.");
                        } else {
                                char *kdata = packet_get_string(&dlen);
-                               
-                               packet_integrity_check(plen, 4 + dlen, type);
-                               
+                               packet_check_eom();
+
                                if (kdata[0] == 4) { /* KRB_PROT_VERSION */
 #ifdef KRB4
                                        KTEXT_ST tkt;
-                                       
+
                                        tkt.length = dlen;
                                        if (tkt.length < MAX_KTXT_LEN)
                                                memcpy(tkt.dat, kdata, tkt.length);
-                                       
+
                                        if (auth_krb4(authctxt, &tkt, &client_user)) {
                                                authenticated = 1;
                                                snprintf(info, sizeof(info),
@@ -143,7 +142,7 @@ do_authloop(Authctxt *authctxt)
                                        krb5_data tkt;
                                        tkt.length = dlen;
                                        tkt.data = kdata;
-                                       
+
                                        if (auth_krb5(authctxt, &tkt, &client_user)) {
                                                authenticated = 1;
                                                snprintf(info, sizeof(info),
@@ -156,7 +155,7 @@ do_authloop(Authctxt *authctxt)
                        }
                        break;
 #endif /* KRB4 || KRB5 */
-                       
+
 #if defined(AFS) || defined(KRB5)
                        /* XXX - punt on backward compatibility here. */
                case SSH_CMSG_HAVE_KERBEROS_TGT:
@@ -168,7 +167,7 @@ do_authloop(Authctxt *authctxt)
                        break;
 #endif /* AFS */
 #endif /* AFS || KRB5 */
-                       
+
                case SSH_CMSG_AUTH_RHOSTS:
                        if (!options.rhosts_authentication) {
                                verbose("Rhosts authentication disabled.");
@@ -181,7 +180,7 @@ do_authloop(Authctxt *authctxt)
                         * IP-spoofing on a local network.)
                         */
                        client_user = packet_get_string(&ulen);
-                       packet_integrity_check(plen, 4 + ulen, type);
+                       packet_check_eom();
 
                        /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
                        authenticated = auth_rhosts(pw, client_user);
@@ -202,24 +201,20 @@ do_authloop(Authctxt *authctxt)
                        client_user = packet_get_string(&ulen);
 
                        /* Get the client host key. */
-                       client_host_key = RSA_new();
-                       if (client_host_key == NULL)
-                               fatal("RSA_new failed");
-                       client_host_key->e = BN_new();
-                       client_host_key->n = BN_new();
-                       if (client_host_key->e == NULL || client_host_key->n == NULL)
-                               fatal("BN_new failed");
+                       client_host_key = key_new(KEY_RSA1);
                        bits = packet_get_int();
-                       packet_get_bignum(client_host_key->e, &elen);
-                       packet_get_bignum(client_host_key->n, &nlen);
+                       packet_get_bignum(client_host_key->rsa->e);
+                       packet_get_bignum(client_host_key->rsa->n);
 
-                       if (bits != BN_num_bits(client_host_key->n))
+                       if (bits != BN_num_bits(client_host_key->rsa->n))
                                verbose("Warning: keysize mismatch for client_host_key: "
-                                   "actual %d, announced %d", BN_num_bits(client_host_key->n), bits);
-                       packet_integrity_check(plen, (4 + ulen) + 4 + elen + nlen, type);
+                                   "actual %d, announced %d",
+                                    BN_num_bits(client_host_key->rsa->n), bits);
+                       packet_check_eom();
 
-                       authenticated = auth_rhosts_rsa(pw, client_user, client_host_key);
-                       RSA_free(client_host_key);
+                       authenticated = auth_rhosts_rsa(pw, client_user,
+                           client_host_key);
+                       key_free(client_host_key);
 
                        snprintf(info, sizeof info, " ruser %.100s", client_user);
                        break;
@@ -230,9 +225,10 @@ do_authloop(Authctxt *authctxt)
                                break;
                        }
                        /* RSA authentication requested. */
-                       n = BN_new();
-                       packet_get_bignum(n, &nlen);
-                       packet_integrity_check(plen, nlen, type);
+                       if ((n = BN_new()) == NULL)
+                               fatal("do_authloop: BN_new failed");
+                       packet_get_bignum(n);
+                       packet_check_eom();
                        authenticated = auth_rsa(pw, n);
                        BN_clear_free(n);
                        break;
@@ -248,7 +244,7 @@ do_authloop(Authctxt *authctxt)
                         * not visible to an outside observer.
                         */
                        password = packet_get_string(&dlen);
-                       packet_integrity_check(plen, 4 + dlen, type);
+                       packet_check_eom();
 
 #ifdef USE_PAM
                        /* Do PAM auth with password */
@@ -286,7 +282,7 @@ do_authloop(Authctxt *authctxt)
                        if (options.challenge_response_authentication == 1) {
                                char *response = packet_get_string(&dlen);
                                debug("got response '%s'", response);
-                               packet_integrity_check(plen, 4 + dlen, type);
+                               packet_check_eom();
                                authenticated = verify_response(authctxt, response);
                                memset(response, 'r', dlen);
                                xfree(response);
@@ -313,9 +309,9 @@ do_authloop(Authctxt *authctxt)
 
 #ifdef HAVE_CYGWIN
                if (authenticated &&
-                   !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,pw->pw_uid)) {
+                   !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) {
                        packet_disconnect("Authentication rejected for uid %d.",
-                       (int)pw->pw_uid);
+                       pw == NULL ? -1 : pw->pw_uid);
                        authenticated = 0;
                }
 #else
@@ -343,7 +339,7 @@ do_authloop(Authctxt *authctxt)
                if (authctxt->failures++ > AUTH_FAIL_MAX) {
 #ifdef WITH_AIXAUTHENTICATE
                        loginfailed(authctxt->user,
-                           get_canonical_hostname(options.reverse_mapping_check),
+                           get_canonical_hostname(options.verify_reverse_mapping),
                            "ssh");
 #endif /* WITH_AIXAUTHENTICATE */
                        packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
@@ -360,20 +356,19 @@ do_authloop(Authctxt *authctxt)
  * been exchanged and encryption is enabled.
  */
 void
-do_authentication()
+do_authentication(void)
 {
        Authctxt *authctxt;
        struct passwd *pw;
-       int plen;
        u_int ulen;
        char *p, *user, *style = NULL;
 
        /* Get the name of the user that we wish to log in as. */
-       packet_read_expect(&plen, SSH_CMSG_USER);
+       packet_read_expect(SSH_CMSG_USER);
 
        /* Get the user name. */
        user = packet_get_string(&ulen);
-       packet_integrity_check(plen, (4 + ulen), SSH_CMSG_USER);
+       packet_check_eom();
 
        if ((style = strchr(user, ':')) != NULL)
                *style++ = '\0';
@@ -381,7 +376,7 @@ do_authentication()
        /* XXX - SSH.com Kerberos v5 braindeath. */
        if ((p = strchr(user, '@')) != NULL)
                *p = '\0';
-       
+
        authctxt = authctxt_new();
        authctxt->user = user;
        authctxt->style = style;
@@ -400,8 +395,7 @@ do_authentication()
        setproctitle("%s", pw ? user : "unknown");
 
 #ifdef USE_PAM
-       if (pw)
-               start_pam(user);
+       start_pam(pw == NULL ? "NOUSER" : user);
 #endif
 
        /*
index 5e6a691f808920ae778c466b43194953a2e39857..9f1d932756b3283e6a59aa16949c12db438edc34 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: auth2-chall.c,v 1.8 2001/09/27 15:31:17 markus Exp $");
+RCSID("$OpenBSD: auth2-chall.c,v 1.16 2002/01/13 17:57:37 markus Exp $");
 
 #include "ssh2.h"
 #include "auth.h"
+#include "buffer.h"
 #include "packet.h"
 #include "xmalloc.h"
 #include "dispatch.h"
@@ -35,7 +36,7 @@ RCSID("$OpenBSD: auth2-chall.c,v 1.8 2001/09/27 15:31:17 markus Exp $");
 
 static int auth2_challenge_start(Authctxt *);
 static int send_userauth_info_request(Authctxt *);
-static void input_userauth_info_response(int, int, void *);
+static void input_userauth_info_response(int, u_int32_t, void *);
 
 #ifdef BSD_AUTH
 extern KbdintDevice bsdauth_device;
@@ -68,22 +69,25 @@ static KbdintAuthctxt *
 kbdint_alloc(const char *devs)
 {
        KbdintAuthctxt *kbdintctxt;
+       Buffer b;
        int i;
-       char buf[1024];
 
        kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
        if (strcmp(devs, "") == 0) {
-               buf[0] = '\0';
+               buffer_init(&b);
                for (i = 0; devices[i]; i++) {
-                       if (i != 0)
-                               strlcat(buf, ",", sizeof(buf));
-                       strlcat(buf, devices[i]->name, sizeof(buf));
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, devices[i]->name,
+                           strlen(devices[i]->name));
                }
-               debug("kbdint_alloc: devices '%s'", buf);
-               kbdintctxt->devices = xstrdup(buf);
+               buffer_append(&b, "\0", 1);
+               kbdintctxt->devices = xstrdup(buffer_ptr(&b));
+               buffer_free(&b);
        } else {
                kbdintctxt->devices = xstrdup(devs);
        }
+       debug("kbdint_alloc: devices '%s'", kbdintctxt->devices);
        kbdintctxt->ctxt = NULL;
        kbdintctxt->device = NULL;
 
@@ -151,11 +155,23 @@ auth2_challenge(Authctxt *authctxt, char *devs)
 
        if (authctxt->user == NULL || !devs)
                return 0;
-       if (authctxt->kbdintctxt == NULL) 
+       if (authctxt->kbdintctxt == NULL)
                authctxt->kbdintctxt = kbdint_alloc(devs);
        return auth2_challenge_start(authctxt);
 }
 
+/* unregister kbd-int callbacks and context */
+void
+auth2_challenge_stop(Authctxt *authctxt)
+{
+       /* unregister callback */
+       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+       if (authctxt->kbdintctxt != NULL)  {
+               kbdint_free(authctxt->kbdintctxt);
+               authctxt->kbdintctxt = NULL;
+       }
+}
+
 /* side effect: sets authctxt->postponed if a reply was sent*/
 static int
 auth2_challenge_start(Authctxt *authctxt)
@@ -166,21 +182,18 @@ auth2_challenge_start(Authctxt *authctxt)
            kbdintctxt->devices ?  kbdintctxt->devices : "<empty>");
 
        if (kbdint_next_device(kbdintctxt) == 0) {
-               kbdint_free(kbdintctxt);
-               authctxt->kbdintctxt = NULL;
+               auth2_challenge_stop(authctxt);
                return 0;
        }
        debug("auth2_challenge_start: trying authentication method '%s'",
            kbdintctxt->device->name);
 
        if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
-               kbdint_free(kbdintctxt);
-               authctxt->kbdintctxt = NULL;
+               auth2_challenge_stop(authctxt);
                return 0;
        }
        if (send_userauth_info_request(authctxt) == 0) {
-               kbdint_free(kbdintctxt);
-               authctxt->kbdintctxt = NULL;
+               auth2_challenge_stop(authctxt);
                return 0;
        }
        dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
@@ -225,7 +238,7 @@ send_userauth_info_request(Authctxt *authctxt)
 }
 
 static void
-input_userauth_info_response(int type, int plen, void *ctxt)
+input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        KbdintAuthctxt *kbdintctxt;
@@ -248,7 +261,7 @@ input_userauth_info_response(int type, int plen, void *ctxt)
                for (i = 0; i < nresp; i++)
                        response[i] = packet_get_string(NULL);
        }
-       packet_done();
+       packet_check_eom();
 
        if (authctxt->valid) {
                res = kbdintctxt->device->respond(kbdintctxt->ctxt,
@@ -271,10 +284,8 @@ input_userauth_info_response(int type, int plen, void *ctxt)
                break;
        case 1:
                /* Authentication needs further interaction */
-               authctxt->postponed = 1;
-               if (send_userauth_info_request(authctxt) == 0) {
-                       authctxt->postponed = 0;
-               }
+               if (send_userauth_info_request(authctxt) == 1)
+                       authctxt->postponed = 1;
                break;
        default:
                /* Failure! */
@@ -284,18 +295,12 @@ input_userauth_info_response(int type, int plen, void *ctxt)
        len = strlen("keyboard-interactive") + 2 +
                strlen(kbdintctxt->device->name);
        method = xmalloc(len);
-       method[0] = '\0';
-       strlcat(method, "keyboard-interactive", len);
-       strlcat(method, "/", len);
-       strlcat(method, kbdintctxt->device->name, len);
+       snprintf(method, len, "keyboard-interactive/%s",
+           kbdintctxt->device->name);
 
        if (!authctxt->postponed) {
-               /* unregister callback */
-               dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
-
                if (authenticated) {
-                       kbdint_free(kbdintctxt);
-                       authctxt->kbdintctxt = NULL;
+                       auth2_challenge_stop(authctxt);
                } else {
                        /* start next device */
                        /* may set authctxt->postponed */
index b6eaf080232b63b8036844d12b0bb6b79254579b..e442ca208abb429a2140abfcfbc197fd0bc1d976 100644 (file)
@@ -16,7 +16,7 @@ RCSID("$Id$");
 static int do_pam_conversation_kbd_int(int num_msg, 
     const struct pam_message **msg, struct pam_response **resp, 
     void *appdata_ptr);
-void input_userauth_info_response_pam(int type, int plen, void *ctxt);
+void input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt);
 
 struct {
        int finished, num_received, num_expected;
@@ -128,7 +128,7 @@ do_pam_conversation_kbd_int(int num_msg, const struct pam_message **msg,
 }
 
 void
-input_userauth_info_response_pam(int type, int plen, void *ctxt)
+input_userauth_info_response_pam(int type, u_int32_t seqnr, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        unsigned int nresp = 0, rlen = 0, i = 0;
@@ -152,7 +152,7 @@ input_userauth_info_response_pam(int type, int plen, void *ctxt)
 
        context_pam2.finished = 1;
 
-       packet_done();
+       packet_check_eom();
 }
 
 #endif
index 1920eb32e0ad9e14e842201348681ec6d8efaabb..f2a801ecc8207b4dbee68803c9f0cc62b9cfd7e4 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.72 2001/11/07 22:41:51 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.85 2002/02/24 19:14:59 markus Exp $");
 
 #include <openssl/evp.h>
 
@@ -69,9 +69,8 @@ struct Authmethod {
 
 /* protocol */
 
-static void input_service_request(int, int, void *);
-static void input_userauth_request(int, int, void *);
-static void protocol_error(int, int, void *);
+static void input_service_request(int, u_int32_t, void *);
+static void input_userauth_request(int, u_int32_t, void *);
 
 /* helper */
 static Authmethod *authmethod_lookup(const char *);
@@ -111,7 +110,7 @@ Authmethod authmethods[] = {
  */
 
 void
-do_authentication2()
+do_authentication2(void)
 {
        Authctxt *authctxt = authctxt_new();
 
@@ -123,30 +122,20 @@ do_authentication2()
        if (options.pam_authentication_via_kbd_int)
                options.kbd_interactive_authentication = 1;
 
-       dispatch_init(&protocol_error);
+       dispatch_init(&dispatch_protocol_error);
        dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
        dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
        do_authenticated(authctxt);
 }
 
 static void
-protocol_error(int type, int plen, void *ctxt)
-{
-       log("auth: protocol error: type %d plen %d", type, plen);
-       packet_start(SSH2_MSG_UNIMPLEMENTED);
-       packet_put_int(0);
-       packet_send();
-       packet_write_wait();
-}
-
-static void
-input_service_request(int type, int plen, void *ctxt)
+input_service_request(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        u_int len;
        int accept = 0;
        char *service = packet_get_string(&len);
-       packet_done();
+       packet_check_eom();
 
        if (authctxt == NULL)
                fatal("input_service_request: no authctxt");
@@ -173,7 +162,7 @@ input_service_request(int type, int plen, void *ctxt)
 }
 
 static void
-input_userauth_request(int type, int plen, void *ctxt)
+input_userauth_request(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Authmethod *m = NULL;
@@ -220,14 +209,8 @@ input_userauth_request(int type, int plen, void *ctxt)
                    authctxt->user, authctxt->service, user, service);
        }
        /* reset state */
-       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &protocol_error);
+       auth2_challenge_stop(authctxt);
        authctxt->postponed = 0;
-#ifdef BSD_AUTH
-       if (authctxt->as) {
-               auth_close(authctxt->as);
-               authctxt->as = NULL;
-       }
-#endif
 
        /* try to authenticate user */
        m = authmethod_lookup(method);
@@ -271,7 +254,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
        /* XXX todo: check if multiple auth methods are needed */
        if (authenticated == 1) {
                /* turn off userauth */
-               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
+               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
                packet_start(SSH2_MSG_USERAUTH_SUCCESS);
                packet_send();
                packet_write_wait();
@@ -281,7 +264,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
                if (authctxt->failures++ > AUTH_FAIL_MAX) {
 #ifdef WITH_AIXAUTHENTICATE
                        loginfailed(authctxt->user,
-                           get_canonical_hostname(options.reverse_mapping_check),
+                           get_canonical_hostname(options.verify_reverse_mapping),
                            "ssh");
 #endif /* WITH_AIXAUTHENTICATE */
                        packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
@@ -334,14 +317,14 @@ userauth_none(Authctxt *authctxt)
        Authmethod *m = authmethod_lookup("none");
        if (m != NULL)
                m->enabled = NULL;
-       packet_done();
+       packet_check_eom();
        userauth_banner();
 
        if (authctxt->valid == 0)
                return(0);
 
 #ifdef HAVE_CYGWIN
-       if (check_nt_auth(1, authctxt->pw->pw_uid) == 0)
+       if (check_nt_auth(1, authctxt->pw) == 0)
                return(0);
 #endif
 #ifdef USE_PAM
@@ -364,10 +347,10 @@ userauth_passwd(Authctxt *authctxt)
        if (change)
                log("password change not supported");
        password = packet_get_string(&len);
-       packet_done();
+       packet_check_eom();
        if (authctxt->valid &&
 #ifdef HAVE_CYGWIN
-               check_nt_auth(1, authctxt->pw->pw_uid) &&
+           check_nt_auth(1, authctxt->pw) &&
 #endif
 #ifdef USE_PAM
            auth_pam_password(authctxt->pw, password) == 1)
@@ -390,7 +373,7 @@ userauth_kbdint(Authctxt *authctxt)
 
        lang = packet_get_string(NULL);
        devs = packet_get_string(NULL);
-       packet_done();
+       packet_check_eom();
 
        debug("keyboard-interactive devs %s", devs);
 
@@ -404,7 +387,7 @@ userauth_kbdint(Authctxt *authctxt)
        xfree(devs);
        xfree(lang);
 #ifdef HAVE_CYGWIN
-       if (check_nt_auth(0, authctxt->pw->pw_uid) == 0)
+       if (check_nt_auth(0, authctxt->pw) == 0)
                return(0);
 #endif
        return authenticated;
@@ -414,8 +397,9 @@ static int
 userauth_pubkey(Authctxt *authctxt)
 {
        Buffer b;
-       Key *key;
-       char *pkalg, *pkblob, *sig;
+       Key *key = NULL;
+       char *pkalg;
+       u_char *pkblob, *sig;
        u_int alen, blen, slen;
        int have_sig, pktype;
        int authenticated = 0;
@@ -441,76 +425,84 @@ userauth_pubkey(Authctxt *authctxt)
        pktype = key_type_from_name(pkalg);
        if (pktype == KEY_UNSPEC) {
                /* this is perfectly legal */
-               log("userauth_pubkey: unsupported public key algorithm: %s", pkalg);
-               xfree(pkalg);
-               xfree(pkblob);
-               return 0;
+               log("userauth_pubkey: unsupported public key algorithm: %s",
+                   pkalg);
+               goto done;
        }
        key = key_from_blob(pkblob, blen);
-       if (key != NULL) {
-               if (have_sig) {
-                       sig = packet_get_string(&slen);
-                       packet_done();
-                       buffer_init(&b);
-                       if (datafellows & SSH_OLD_SESSIONID) {
-                               buffer_append(&b, session_id2, session_id2_len);
-                       } else {
-                               buffer_put_string(&b, session_id2, session_id2_len);
-                       }
-                       /* reconstruct packet */
-                       buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
-                       buffer_put_cstring(&b, authctxt->user);
-                       buffer_put_cstring(&b,
-                           datafellows & SSH_BUG_PKSERVICE ?
-                           "ssh-userauth" :
-                           authctxt->service);
-                       if (datafellows & SSH_BUG_PKAUTH) {
-                               buffer_put_char(&b, have_sig);
-                       } else {
-                               buffer_put_cstring(&b, "publickey");
-                               buffer_put_char(&b, have_sig);
-                               buffer_put_cstring(&b, pkalg);
-                       }
-                       buffer_put_string(&b, pkblob, blen);
+       if (key == NULL) {
+               error("userauth_pubkey: cannot decode key: %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("userauth_pubkey: type mismatch for decoded key "
+                   "(received %d, expected %d)", key->type, pktype);
+               goto done;
+       }
+       if (have_sig) {
+               sig = packet_get_string(&slen);
+               packet_check_eom();
+               buffer_init(&b);
+               if (datafellows & SSH_OLD_SESSIONID) {
+                       buffer_append(&b, session_id2, session_id2_len);
+               } else {
+                       buffer_put_string(&b, session_id2, session_id2_len);
+               }
+               /* reconstruct packet */
+               buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+               buffer_put_cstring(&b, authctxt->user);
+               buffer_put_cstring(&b,
+                   datafellows & SSH_BUG_PKSERVICE ?
+                   "ssh-userauth" :
+                   authctxt->service);
+               if (datafellows & SSH_BUG_PKAUTH) {
+                       buffer_put_char(&b, have_sig);
+               } else {
+                       buffer_put_cstring(&b, "publickey");
+                       buffer_put_char(&b, have_sig);
+                       buffer_put_cstring(&b, pkalg);
+               }
+               buffer_put_string(&b, pkblob, blen);
 #ifdef DEBUG_PK
-                       buffer_dump(&b);
+               buffer_dump(&b);
 #endif
-                       /* test for correct signature */
-                       if (user_key_allowed(authctxt->pw, key) &&
-                           key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
-                               authenticated = 1;
-                       buffer_clear(&b);
-                       xfree(sig);
-               } else {
-                       debug("test whether pkalg/pkblob are acceptable");
-                       packet_done();
-
-                       /* XXX fake reply and always send PK_OK ? */
-                       /*
-                        * XXX this allows testing whether a user is allowed
-                        * to login: if you happen to have a valid pubkey this
-                        * message is sent. the message is NEVER sent at all
-                        * if a user is not allowed to login. is this an
-                        * issue? -markus
-                        */
-                       if (user_key_allowed(authctxt->pw, key)) {
-                               packet_start(SSH2_MSG_USERAUTH_PK_OK);
-                               packet_put_string(pkalg, alen);
-                               packet_put_string(pkblob, blen);
-                               packet_send();
-                               packet_write_wait();
-                               authctxt->postponed = 1;
-                       }
+               /* test for correct signature */
+               if (user_key_allowed(authctxt->pw, key) &&
+                   key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
+                       authenticated = 1;
+               buffer_clear(&b);
+               xfree(sig);
+       } else {
+               debug("test whether pkalg/pkblob are acceptable");
+               packet_check_eom();
+
+               /* XXX fake reply and always send PK_OK ? */
+               /*
+                * XXX this allows testing whether a user is allowed
+                * to login: if you happen to have a valid pubkey this
+                * message is sent. the message is NEVER sent at all
+                * if a user is not allowed to login. is this an
+                * issue? -markus
+                */
+               if (user_key_allowed(authctxt->pw, key)) {
+                       packet_start(SSH2_MSG_USERAUTH_PK_OK);
+                       packet_put_string(pkalg, alen);
+                       packet_put_string(pkblob, blen);
+                       packet_send();
+                       packet_write_wait();
+                       authctxt->postponed = 1;
                }
-               if (authenticated != 1)
-                       auth_clear_options();
-               key_free(key);
        }
+       if (authenticated != 1)
+               auth_clear_options();
+done:
        debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
+       if (key != NULL)
+               key_free(key);
        xfree(pkalg);
        xfree(pkblob);
 #ifdef HAVE_CYGWIN
-       if (check_nt_auth(0, authctxt->pw->pw_uid) == 0)
+       if (check_nt_auth(0, authctxt->pw) == 0)
                return(0);
 #endif
        return authenticated;
@@ -520,8 +512,9 @@ static int
 userauth_hostbased(Authctxt *authctxt)
 {
        Buffer b;
-       Key *key;
-       char *pkalg, *pkblob, *sig, *cuser, *chost, *service;
+       Key *key = NULL;
+       char *pkalg, *cuser, *chost, *service;
+       u_char *pkblob, *sig;
        u_int alen, blen, slen;
        int pktype;
        int authenticated = 0;
@@ -554,7 +547,12 @@ userauth_hostbased(Authctxt *authctxt)
        }
        key = key_from_blob(pkblob, blen);
        if (key == NULL) {
-               debug("userauth_hostbased: cannot decode key: %s", pkalg);
+               error("userauth_hostbased: cannot decode key: %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("userauth_hostbased: type mismatch for decoded key "
+                   "(received %d, expected %d)", key->type, pktype);
                goto done;
        }
        service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
@@ -579,10 +577,10 @@ userauth_hostbased(Authctxt *authctxt)
                authenticated = 1;
 
        buffer_clear(&b);
-       key_free(key);
-
 done:
        debug2("userauth_hostbased: authenticated %d", authenticated);
+       if (key != NULL)
+               key_free(key);
        xfree(pkalg);
        xfree(pkblob);
        xfree(cuser);
@@ -605,31 +603,22 @@ static char *
 authmethods_get(void)
 {
        Authmethod *method = NULL;
-       u_int size = 0;
+       Buffer b;
        char *list;
 
+       buffer_init(&b);
        for (method = authmethods; method->name != NULL; method++) {
                if (strcmp(method->name, "none") == 0)
                        continue;
                if (method->enabled != NULL && *(method->enabled) != 0) {
-                       if (size != 0)
-                               size += strlen(DELIM);
-                       size += strlen(method->name);
-               }
-       }
-       size++;                 /* trailing '\0' */
-       list = xmalloc(size);
-       list[0] = '\0';
-
-       for (method = authmethods; method->name != NULL; method++) {
-               if (strcmp(method->name, "none") == 0)
-                       continue;
-               if (method->enabled != NULL && *(method->enabled) != 0) {
-                       if (list[0] != '\0')
-                               strlcat(list, DELIM, size);
-                       strlcat(list, method->name, size);
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, method->name, strlen(method->name));
                }
        }
+       buffer_append(&b, "\0", 1);
+       list = xstrdup(buffer_ptr(&b));
+       buffer_free(&b);
        return list;
 }
 
@@ -657,6 +646,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
        u_long linenum = 0;
        struct stat st;
        Key *found;
+       char *fp;
 
        if (pw == NULL)
                return 0;
@@ -724,6 +714,10 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
                        found_key = 1;
                        debug("matching key found: file %s, line %lu",
                            file, linenum);
+                       fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+                       verbose("Found matching %s key: %s",
+                           key_type(found), fp);
+                       xfree(fp);
                        break;
                }
        }
@@ -761,9 +755,10 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
     Key *key)
 {
        const char *resolvedname, *ipaddr, *lookup;
-       int host_status, len;
+       HostStatus host_status;
+       int len;
 
-       resolvedname = get_canonical_hostname(options.reverse_mapping_check);
+       resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
        ipaddr = get_remote_ipaddr();
 
        debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
@@ -801,4 +796,3 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
 
        return (host_status == HOST_OK);
 }
-
index d6366ee36c748dbdfeca54ffd18bf64312a00006..fa764358faccdb7045278552282f5f480e94254e 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: authfd.c,v 1.45 2001/09/19 19:35:30 stevesk Exp $");
+RCSID("$OpenBSD: authfd.c,v 1.48 2002/02/24 19:14:59 markus Exp $");
 
 #include <openssl/evp.h>
 
@@ -217,7 +217,7 @@ ssh_get_num_identities(AuthenticationConnection *auth, int version)
        int type, code1 = 0, code2 = 0;
        Buffer request;
 
-       switch(version){
+       switch (version) {
        case 1:
                code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
                code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
@@ -286,7 +286,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
         * Get the next entry from the packet.  These will abort with a fatal
         * error if the packet is too short or contains corrupt data.
         */
-       switch(version){
+       switch (version) {
        case 1:
                key = key_new(KEY_RSA1);
                bits = buffer_get_int(&auth->identities);
@@ -344,7 +344,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
        buffer_put_bignum(&buffer, key->rsa->e);
        buffer_put_bignum(&buffer, key->rsa->n);
        buffer_put_bignum(&buffer, challenge);
-       buffer_append(&buffer, (char *) session_id, 16);
+       buffer_append(&buffer, session_id, 16);
        buffer_put_int(&buffer, response_type);
 
        if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
@@ -374,8 +374,8 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
 int
 ssh_agent_sign(AuthenticationConnection *auth,
     Key *key,
-    u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+    u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
        extern int datafellows;
        Buffer msg;
@@ -438,7 +438,7 @@ ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
        buffer_clear(b);
        buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY);
        buffer_put_cstring(b, key_ssh_name(key));
-       switch(key->type){
+       switch (key->type) {
        case KEY_RSA:
                buffer_put_bignum2(b, key->rsa->n);
                buffer_put_bignum2(b, key->rsa->e);
index 8075a7ebddf18b9269f889152b56382d6035f98f..0f2ca7a2ecfff35c9e515bd6324a12c548b8f3e3 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: authfd.h,v 1.23 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: authfd.h,v 1.21 2001/08/07 10:37:46 markus Exp $"); */
-
 #ifndef AUTHFD_H
 #define AUTHFD_H
 
@@ -74,7 +74,7 @@ ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
     u_int, u_char[16]);
 
 int
-ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, int *, u_char *,
-    int);
+ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *,
+    u_int);
 
 #endif                         /* AUTHFD_H */
index 135be76b52714f1f64053f4672763da41c0719ce..de8b1022ee4a4232ca9d75798b35526ddd88e1d2 100644 (file)
@@ -36,7 +36,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: authfile.c,v 1.39 2001/10/07 10:29:52 markus Exp $");
+RCSID("$OpenBSD: authfile.c,v 1.48 2002/02/28 15:46:33 markus Exp $");
 
 #include <openssl/err.h>
 #include <openssl/evp.h>
@@ -50,6 +50,7 @@ RCSID("$OpenBSD: authfile.c,v 1.39 2001/10/07 10:29:52 markus Exp $");
 #include "ssh.h"
 #include "log.h"
 #include "authfile.h"
+#include "rsa.h"
 
 /* Version identification string for SSH v1 identity files. */
 static const char authfile_id_string[] =
@@ -67,8 +68,8 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
     const char *comment)
 {
        Buffer buffer, encrypted;
-       char buf[100], *cp;
-       int fd, i;
+       u_char buf[100], *cp;
+       int fd, i, cipher_num;
        CipherContext ciphercontext;
        Cipher *cipher;
        u_int32_t rand;
@@ -77,11 +78,9 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
         * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
         * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
         */
-       if (strcmp(passphrase, "") == 0)
-               cipher = cipher_by_number(SSH_CIPHER_NONE);
-       else
-               cipher = cipher_by_number(SSH_AUTHFILE_CIPHER);
-       if (cipher == NULL)
+       cipher_num = (strcmp(passphrase, "") == 0) ?
+           SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
+       if ((cipher = cipher_by_number(cipher_num)) == NULL)
                fatal("save_private_key_rsa: bad cipher");
 
        /* This buffer is used to built the secret part of the private key. */
@@ -118,7 +117,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
        buffer_put_char(&encrypted, 0);
 
        /* Store cipher type. */
-       buffer_put_char(&encrypted, cipher->number);
+       buffer_put_char(&encrypted, cipher_num);
        buffer_put_int(&encrypted, 0);  /* For future extension */
 
        /* Store public key.  This will be in plain text. */
@@ -128,11 +127,13 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
        buffer_put_cstring(&encrypted, comment);
 
        /* Allocate space for the private part of the key in the buffer. */
-       buffer_append_space(&encrypted, &cp, buffer_len(&buffer));
+       cp = buffer_append_space(&encrypted, buffer_len(&buffer));
 
-       cipher_set_key_string(&ciphercontext, cipher, passphrase);
-       cipher_encrypt(&ciphercontext, (u_char *) cp,
-           (u_char *) buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_set_key_string(&ciphercontext, cipher, passphrase,
+           CIPHER_ENCRYPT);
+       cipher_crypt(&ciphercontext, cp,
+           buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_cleanup(&ciphercontext);
        memset(&ciphercontext, 0, sizeof(ciphercontext));
 
        /* Destroy temporary data. */
@@ -147,7 +148,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
        if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
            buffer_len(&encrypted)) {
                error("write to key file %s failed: %s", filename,
-                     strerror(errno));
+                   strerror(errno));
                buffer_free(&encrypted);
                close(fd);
                unlink(filename);
@@ -167,8 +168,8 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
        int fd;
        int success = 0;
        int len = strlen(_passphrase);
-       char *passphrase = (len > 0) ? (char *)_passphrase : NULL;
-       EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
+       u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
+       const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
 
        if (len > 0 && len <= 4) {
                error("passphrase too short: have %d bytes, need > 4", len);
@@ -239,7 +240,7 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp)
        lseek(fd, (off_t) 0, SEEK_SET);
 
        buffer_init(&buffer);
-       buffer_append_space(&buffer, &cp, len);
+       cp = buffer_append_space(&buffer, len);
 
        if (read(fd, cp, (size_t) len) != (size_t) len) {
                debug("Read from key file %.200s failed: %.100s", filename,
@@ -313,18 +314,16 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
        int i, check1, check2, cipher_type;
        off_t len;
        Buffer buffer, decrypted;
-       char *cp;
+       u_char *cp;
        CipherContext ciphercontext;
        Cipher *cipher;
-       BN_CTX *ctx;
-       BIGNUM *aux;
        Key *prv = NULL;
 
        len = lseek(fd, (off_t) 0, SEEK_END);
        lseek(fd, (off_t) 0, SEEK_SET);
 
        buffer_init(&buffer);
-       buffer_append_space(&buffer, &cp, len);
+       cp = buffer_append_space(&buffer, len);
 
        if (read(fd, cp, (size_t) len) != (size_t) len) {
                debug("Read from key file %.200s failed: %.100s", filename,
@@ -378,12 +377,14 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
        }
        /* Initialize space for decrypted data. */
        buffer_init(&decrypted);
-       buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
+       cp = buffer_append_space(&decrypted, buffer_len(&buffer));
 
        /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
-       cipher_set_key_string(&ciphercontext, cipher, passphrase);
-       cipher_decrypt(&ciphercontext, (u_char *) cp,
-           (u_char *) buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_set_key_string(&ciphercontext, cipher, passphrase,
+           CIPHER_DECRYPT);
+       cipher_crypt(&ciphercontext, cp,
+           buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_cleanup(&ciphercontext);
        memset(&ciphercontext, 0, sizeof(ciphercontext));
        buffer_free(&buffer);
 
@@ -406,17 +407,7 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
        buffer_get_bignum(&decrypted, prv->rsa->p);             /* q */
 
        /* calculate p-1 and q-1 */
-       ctx = BN_CTX_new();
-       aux = BN_new();
-
-       BN_sub(aux, prv->rsa->q, BN_value_one());
-       BN_mod(prv->rsa->dmq1, prv->rsa->d, aux, ctx);
-
-       BN_sub(aux, prv->rsa->p, BN_value_one());
-       BN_mod(prv->rsa->dmp1, prv->rsa->d, aux, ctx);
-
-       BN_clear_free(aux);
-       BN_CTX_free(ctx);
+       rsa_generate_additional_parameters(prv->rsa);
 
        buffer_free(&decrypted);
        close(fd);
@@ -450,7 +441,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
                debug("PEM_read_PrivateKey failed");
                (void)ERR_get_error();
        } else if (pk->type == EVP_PKEY_RSA &&
-            (type == KEY_UNSPEC||type==KEY_RSA)) {
+           (type == KEY_UNSPEC||type==KEY_RSA)) {
                prv = key_new(KEY_UNSPEC);
                prv->rsa = EVP_PKEY_get1_RSA(pk);
                prv->type = KEY_RSA;
@@ -459,7 +450,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
                RSA_print_fp(stderr, prv->rsa, 8);
 #endif
        } else if (pk->type == EVP_PKEY_DSA &&
-            (type == KEY_UNSPEC||type==KEY_DSA)) {
+           (type == KEY_UNSPEC||type==KEY_DSA)) {
                prv = key_new(KEY_UNSPEC);
                prv->dsa = EVP_PKEY_get1_DSA(pk);
                prv->type = KEY_DSA;
@@ -586,7 +577,7 @@ key_try_load_public(Key *k, const char *filename, char **commentp)
                while (fgets(line, sizeof(line), f)) {
                        line[sizeof(line)-1] = '\0';
                        cp = line;
-                       switch(*cp){
+                       switch (*cp) {
                        case '#':
                        case '\n':
                        case '\0':
index c8b31fbe66e36d43987758e240bcac132641d5e8..c614ca12ce899168d73fbad529d7260459c66d02 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: authfile.h,v 1.9 2002/03/04 17:27:39 stevesk Exp $    */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -10,8 +12,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* $OpenBSD: authfile.h,v 1.8 2001/06/26 17:27:22 markus Exp $ */
-
 #ifndef AUTHFILE_H
 #define AUTHFILE_H
 
index b17256db66b1b37fe0ea34d9cc9c7a42af5f2b3d..23bc0c814d229cd685fd3952d5028b542362eb60 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: bufaux.c,v 1.17 2001/01/21 19:05:45 markus Exp $");
+RCSID("$OpenBSD: bufaux.c,v 1.22 2002/01/18 18:14:17 stevesk Exp $");
 
 #include <openssl/bn.h>
 #include "bufaux.h"
@@ -62,7 +62,7 @@ buffer_put_bignum(Buffer *buffer, BIGNUM *value)
        oi = BN_bn2bin(value, buf);
        if (oi != bin_size)
                fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
-                     oi, bin_size);
+                   oi, bin_size);
 
        /* Store the number of bits in the buffer in two bytes, msb first. */
        PUT_16BIT(msg, bits);
@@ -77,7 +77,7 @@ buffer_put_bignum(Buffer *buffer, BIGNUM *value)
 /*
  * Retrieves an BIGNUM from the buffer.
  */
-int
+void
 buffer_get_bignum(Buffer *buffer, BIGNUM *value)
 {
        int bits, bytes;
@@ -90,11 +90,9 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value)
        bytes = (bits + 7) / 8;
        if (buffer_len(buffer) < bytes)
                fatal("buffer_get_bignum: input buffer too small");
-       bin = (u_char *) buffer_ptr(buffer);
+       bin = buffer_ptr(buffer);
        BN_bin2bn(bin, bytes, value);
        buffer_consume(buffer, bytes);
-
-       return 2 + bytes;
 }
 
 /*
@@ -112,16 +110,16 @@ buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
        oi = BN_bn2bin(value, buf+1);
        if (oi != bytes-1)
                fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
-                     oi, bytes);
+                   oi, bytes);
        hasnohigh = (buf[1] & 0x80) ? 0 : 1;
        if (value->neg) {
                /**XXX should be two's-complement */
                int i, carry;
                u_char *uc = buf;
                log("negativ!");
-               for(i = bytes-1, carry = 1; i>=0; i--) {
+               for (i = bytes-1, carry = 1; i>=0; i--) {
                        uc[i] ^= 0xff;
-                       if(carry)
+                       if (carry)
                                carry = !++uc[i];
                }
        }
@@ -130,15 +128,14 @@ buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
        xfree(buf);
 }
 
-int
+void
 buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
 {
        /**XXX should be two's-complement */
        int len;
-       u_char *bin = (u_char *)buffer_get_string(buffer, (u_int *)&len);
+       u_char *bin = buffer_get_string(buffer, (u_int *)&len);
        BN_bin2bn(bin, len, value);
        xfree(bin);
-       return len;
 }
 
 /*
@@ -191,11 +188,11 @@ buffer_put_int64(Buffer *buffer, u_int64_t value)
  * will be stored there.  A null character will be automatically appended
  * to the returned string, and is not counted in length.
  */
-char *
+void *
 buffer_get_string(Buffer *buffer, u_int *length_ptr)
 {
        u_int len;
-       char *value;
+       u_char *value;
        /* Get the length. */
        len = buffer_get_int(buffer);
        if (len > 256 * 1024)
index d1af09881b1e95715833ccc0aea570cacadb3c29..400013490d287741511f0e2da7df1a6cab439b37 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: bufaux.h,v 1.16 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -10,8 +12,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: bufaux.h,v 1.13 2001/06/26 17:27:22 markus Exp $"); */
-
 #ifndef BUFAUX_H
 #define BUFAUX_H
 
 
 void    buffer_put_bignum(Buffer *, BIGNUM *);
 void    buffer_put_bignum2(Buffer *, BIGNUM *);
+void   buffer_get_bignum(Buffer *, BIGNUM *);
+void   buffer_get_bignum2(Buffer *, BIGNUM *);
 
-int     buffer_get_bignum(Buffer *, BIGNUM *);
-int    buffer_get_bignum2(Buffer *, BIGNUM *);
-
-u_int buffer_get_int(Buffer *);
+u_int  buffer_get_int(Buffer *);
 void    buffer_put_int(Buffer *, u_int);
 
 #ifdef HAVE_U_INT64_T
@@ -33,11 +32,9 @@ void buffer_put_int64(Buffer *, u_int64_t);
 #endif
 
 int     buffer_get_char(Buffer *);
-
 void    buffer_put_char(Buffer *, int);
 
-char   *buffer_get_string(Buffer *, u_int *);
-
+void   *buffer_get_string(Buffer *, u_int *);
 void    buffer_put_string(Buffer *, const void *, u_int);
 void   buffer_put_cstring(Buffer *, const char *);
 
index 044caafb5d73b653d5d985b46afbf10d6d1e979e..40572e5ac30e5c4e5e6ee8ced39b025377b78a8f 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: buffer.c,v 1.13 2001/04/12 19:15:24 markus Exp $");
+RCSID("$OpenBSD: buffer.c,v 1.15 2002/01/18 18:14:17 stevesk Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -53,11 +53,11 @@ buffer_clear(Buffer *buffer)
 /* Appends data to the buffer, expanding it if necessary. */
 
 void
-buffer_append(Buffer *buffer, const char *data, u_int len)
+buffer_append(Buffer *buffer, const void *data, u_int len)
 {
-       char *cp;
-       buffer_append_space(buffer, &cp, len);
-       memcpy(cp, data, len);
+       void *p;
+       p = buffer_append_space(buffer, len);
+       memcpy(p, data, len);
 }
 
 /*
@@ -66,9 +66,11 @@ buffer_append(Buffer *buffer, const char *data, u_int len)
  * to the allocated region.
  */
 
-void
-buffer_append_space(Buffer *buffer, char **datap, u_int len)
+void *
+buffer_append_space(Buffer *buffer, u_int len)
 {
+       void *p;
+
        /* If the buffer is empty, start using it from the beginning. */
        if (buffer->offset == buffer->end) {
                buffer->offset = 0;
@@ -77,9 +79,9 @@ buffer_append_space(Buffer *buffer, char **datap, u_int len)
 restart:
        /* If there is enough space to store all data, store it now. */
        if (buffer->end + len < buffer->alloc) {
-               *datap = buffer->buf + buffer->end;
+               p = buffer->buf + buffer->end;
                buffer->end += len;
-               return;
+               return p;
        }
        /*
         * If the buffer is quite empty, but all data is at the end, move the
@@ -96,6 +98,7 @@ restart:
        buffer->alloc += len + 32768;
        buffer->buf = xrealloc(buffer->buf, buffer->alloc);
        goto restart;
+       /* NOTREACHED */
 }
 
 /* Returns the number of bytes of data in the buffer. */
@@ -109,7 +112,7 @@ buffer_len(Buffer *buffer)
 /* Gets data from the beginning of the buffer. */
 
 void
-buffer_get(Buffer *buffer, char *buf, u_int len)
+buffer_get(Buffer *buffer, void *buf, u_int len)
 {
        if (len > buffer->end - buffer->offset)
                fatal("buffer_get: trying to get more bytes %d than in buffer %d",
@@ -140,7 +143,7 @@ buffer_consume_end(Buffer *buffer, u_int bytes)
 
 /* Returns a pointer to the first used byte in the buffer. */
 
-char *
+void *
 buffer_ptr(Buffer *buffer)
 {
        return buffer->buf + buffer->offset;
@@ -152,7 +155,7 @@ void
 buffer_dump(Buffer *buffer)
 {
        int i;
-       u_char *ucp = (u_char *) buffer->buf;
+       u_char *ucp = buffer->buf;
 
        for (i = buffer->offset; i < buffer->end; i++) {
                fprintf(stderr, "%02x", ucp[i]);
index 845bfb69707c4445bbae5cd2e4fdb5846f7a217b..5e4c41244230c6cd209e50feaaff15394bc64698 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: buffer.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: buffer.h,v 1.9 2001/06/26 17:27:23 markus Exp $"); */
-
 #ifndef BUFFER_H
 #define BUFFER_H
 
 typedef struct {
-       char    *buf;           /* Buffer for data. */
+       u_char  *buf;           /* Buffer for data. */
        u_int    alloc;         /* Number of bytes allocated for data. */
        u_int    offset;        /* Offset of first byte containing data. */
        u_int    end;           /* Offset of last byte containing data. */
@@ -28,12 +28,12 @@ void         buffer_clear(Buffer *);
 void    buffer_free(Buffer *);
 
 u_int   buffer_len(Buffer *);
-char   *buffer_ptr(Buffer *);
+void   *buffer_ptr(Buffer *);
 
-void    buffer_append(Buffer *, const char *, u_int);
-void    buffer_append_space(Buffer *, char **, u_int);
+void    buffer_append(Buffer *, const void *, u_int);
+void   *buffer_append_space(Buffer *, u_int);
 
-void    buffer_get(Buffer *, char *, u_int);
+void    buffer_get(Buffer *, void *, u_int);
 
 void    buffer_consume(Buffer *, u_int);
 void    buffer_consume_end(Buffer *, u_int);
index 6e6a04505e97c2244342baca4cd8a81aed33975c..03005aa29c8c9da023f2d90406987e77602f3bcd 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.27 2001/06/23 15:12:17 itojun Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.31 2002/02/27 21:23:13 stevesk Exp $");
 
 #include "packet.h"
 #include "xmalloc.h"
@@ -27,7 +27,7 @@ static void check_ip_options(int, char *);
  */
 
 static char *
-get_remote_hostname(int socket, int reverse_mapping_check)
+get_remote_hostname(int socket, int verify_reverse_mapping)
 {
        struct sockaddr_storage from;
        int i;
@@ -68,13 +68,13 @@ get_remote_hostname(int socket, int reverse_mapping_check)
                check_ip_options(socket, ntop);
 
        if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
-            NULL, 0, NI_NUMERICHOST) != 0)
+           NULL, 0, NI_NUMERICHOST) != 0)
                fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
 
        debug3("Trying to reverse map address %.100s.", ntop);
        /* Map the IP address to a host name. */
        if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
-            NULL, 0, NI_NAMEREQD) != 0) {
+           NULL, 0, NI_NAMEREQD) != 0) {
                /* Host name not found.  Use ip address. */
                log("Could not reverse map address %.100s.", ntop);
                return xstrdup(ntop);
@@ -90,7 +90,7 @@ get_remote_hostname(int socket, int reverse_mapping_check)
                if (isupper(name[i]))
                        name[i] = tolower(name[i]);
 
-       if (!reverse_mapping_check)
+       if (!verify_reverse_mapping)
                return xstrdup(name);
        /*
         * Map it back to an IP address and check that the given
@@ -154,7 +154,7 @@ check_ip_options(int socket, char *ipaddr)
        else
                ipproto = IPPROTO_IP;
        option_size = sizeof(options);
-       if (getsockopt(socket, ipproto, IP_OPTIONS, (void *)options,
+       if (getsockopt(socket, ipproto, IP_OPTIONS, options,
            &option_size) >= 0 && option_size != 0) {
                text[0] = '\0';
                for (i = 0; i < option_size; i++)
@@ -174,14 +174,14 @@ check_ip_options(int socket, char *ipaddr)
  */
 
 const char *
-get_canonical_hostname(int reverse_mapping_check)
+get_canonical_hostname(int verify_reverse_mapping)
 {
        static char *canonical_host_name = NULL;
-       static int reverse_mapping_checked = 0;
+       static int verify_reverse_mapping_done = 0;
 
        /* Check if we have previously retrieved name with same option. */
        if (canonical_host_name != NULL) {
-               if (reverse_mapping_checked != reverse_mapping_check)
+               if (verify_reverse_mapping_done != verify_reverse_mapping)
                        xfree(canonical_host_name);
                else
                        return canonical_host_name;
@@ -190,11 +190,11 @@ get_canonical_hostname(int reverse_mapping_check)
        /* Get the real hostname if socket; otherwise return UNKNOWN. */
        if (packet_connection_is_on_socket())
                canonical_host_name = get_remote_hostname(
-                   packet_get_connection_in(), reverse_mapping_check);
+                   packet_get_connection_in(), verify_reverse_mapping);
        else
                canonical_host_name = xstrdup("UNKNOWN");
 
-       reverse_mapping_checked = reverse_mapping_check;
+       verify_reverse_mapping_done = verify_reverse_mapping;
        return canonical_host_name;
 }
 
@@ -230,7 +230,7 @@ get_socket_address(int socket, int remote, int flags)
        }
        /* Get the address in ascii. */
        if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
-            NULL, 0, flags) != 0) {
+           NULL, 0, flags) != 0) {
                error("get_socket_ipaddr: getnameinfo %d failed", flags);
                return NULL;
        }
@@ -261,7 +261,7 @@ get_local_name(int socket)
  */
 
 const char *
-get_remote_ipaddr()
+get_remote_ipaddr(void)
 {
        static char *canonical_host_ip = NULL;
 
@@ -281,11 +281,11 @@ get_remote_ipaddr()
 }
 
 const char *
-get_remote_name_or_ip(u_int utmp_len, int reverse_mapping_check)
+get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping)
 {
        static const char *remote = "";
        if (utmp_len > 0)
-               remote = get_canonical_hostname(reverse_mapping_check);
+               remote = get_canonical_hostname(verify_reverse_mapping);
        if (utmp_len == 0 || strlen(remote) > utmp_len)
                remote = get_remote_ipaddr();
        return remote;
@@ -316,7 +316,7 @@ get_sock_port(int sock, int local)
        }
        /* Return port number. */
        if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
-            strport, sizeof(strport), NI_NUMERICSERV) != 0)
+           strport, sizeof(strport), NI_NUMERICSERV) != 0)
                fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed");
        return atoi(strport);
 }
@@ -344,13 +344,13 @@ get_peer_port(int sock)
 }
 
 int
-get_remote_port()
+get_remote_port(void)
 {
        return get_port(0);
 }
 
 int
-get_local_port()
+get_local_port(void)
 {
        return get_port(1);
 }
index 62fd73d74aac2f06423442bac4839a5b382f4c7b..2b1f33f34792d474387854accef728fbe1794d6c 100644 (file)
@@ -13,7 +13,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  *
  * SSH2 support added by Markus Friedl.
- * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  * Copyright (c) 1999 Dug Song.  All rights reserved.
  * Copyright (c) 1999 Theo de Raadt.  All rights reserved.
  *
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.140 2001/10/10 22:18:47 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.171 2002/03/04 19:37:58 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -54,6 +54,7 @@ RCSID("$OpenBSD: channels.c,v 1.140 2001/10/10 22:18:47 markus Exp $");
 #include "canohost.h"
 #include "key.h"
 #include "authfd.h"
+#include "pathnames.h"
 
 
 /* -- channel core */
@@ -145,7 +146,7 @@ channel_lookup(int id)
 {
        Channel *c;
 
-       if (id < 0 || id > channels_alloc) {
+       if (id < 0 || id >= channels_alloc) {
                log("channel_lookup: %d: bad id", id);
                return NULL;
        }
@@ -216,7 +217,6 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
 
        /* Do initial allocation if this is the first call. */
        if (channels_alloc == 0) {
-               chan_init();
                channels_alloc = 10;
                channels = xmalloc(channels_alloc * sizeof(Channel *));
                for (i = 0; i < channels_alloc; i++)
@@ -245,7 +245,9 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
        buffer_init(&c->input);
        buffer_init(&c->output);
        buffer_init(&c->extended);
-       chan_init_iostates(c);
+       c->ostate = CHAN_OUTPUT_OPEN;
+       c->istate = CHAN_INPUT_OPEN;
+       c->flags = 0;
        channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
        c->self = found;
        c->type = type;
@@ -258,11 +260,10 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
        c->remote_name = remote_name;
        c->remote_window = 0;
        c->remote_maxpacket = 0;
-       c->cb_fn = NULL;
-       c->cb_arg = NULL;
-       c->cb_event = 0;
        c->force_drain = 0;
+       c->single_connection = 0;
        c->detach_user = NULL;
+       c->confirm = NULL;
        c->input_filter = NULL;
        debug("channel %d: new [%s]", found, remote_name);
        return c;
@@ -361,7 +362,7 @@ channel_free_all(void)
  */
 
 void
-channel_close_all()
+channel_close_all(void)
 {
        int i;
 
@@ -402,7 +403,7 @@ channel_stop_listening(void)
  */
 
 int
-channel_not_very_much_buffered_data()
+channel_not_very_much_buffered_data(void)
 {
        u_int i;
        Channel *c;
@@ -432,7 +433,7 @@ channel_not_very_much_buffered_data()
 /* Returns true if any channel is still open. */
 
 int
-channel_still_open()
+channel_still_open(void)
 {
        int i;
        Channel *c;
@@ -475,7 +476,7 @@ channel_still_open()
 /* Returns the id of an open channel suitable for keepaliving */
 
 int
-channel_find_open()
+channel_find_open(void)
 {
        int i;
        Channel *c;
@@ -520,7 +521,7 @@ channel_find_open()
  */
 
 char *
-channel_open_message()
+channel_open_message(void)
 {
        Buffer buffer;
        Channel *c;
@@ -587,36 +588,28 @@ channel_send_open(int id)
 }
 
 void
-channel_request(int id, char *service, int wantconfirm)
+channel_request_start(int local_id, char *service, int wantconfirm)
 {
-       channel_request_start(id, service, wantconfirm);
-       packet_send();
-       debug("channel request %d: %s", id, service) ;
-}
-void
-channel_request_start(int id, char *service, int wantconfirm)
-{
-       Channel *c = channel_lookup(id);
+       Channel *c = channel_lookup(local_id);
        if (c == NULL) {
-               log("channel_request: %d: bad id", id);
+               log("channel_request_start: %d: unknown channel id", local_id);
                return;
        }
+       debug("channel request %d: %s", local_id, service) ;
        packet_start(SSH2_MSG_CHANNEL_REQUEST);
        packet_put_int(c->remote_id);
        packet_put_cstring(service);
        packet_put_char(wantconfirm);
 }
 void
-channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg)
+channel_register_confirm(int id, channel_callback_fn *fn)
 {
        Channel *c = channel_lookup(id);
        if (c == NULL) {
-               log("channel_register_callback: %d: bad id", id);
+               log("channel_register_comfirm: %d: bad id", id);
                return;
        }
-       c->cb_event = mtype;
-       c->cb_fn = fn;
-       c->cb_arg = arg;
+       c->confirm = fn;
 }
 void
 channel_register_cleanup(int id, channel_callback_fn *fn)
@@ -651,15 +644,14 @@ channel_register_filter(int id, channel_filter_fn *fn)
 
 void
 channel_set_fds(int id, int rfd, int wfd, int efd,
-    int extusage, int nonblock)
+    int extusage, int nonblock, 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);
        c->type = SSH_CHANNEL_OPEN;
-       /* XXX window size? */
-       c->local_window = c->local_window_max = c->local_maxpacket * 2;
+       c->local_window = c->local_window_max = window_max;
        packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
        packet_put_int(c->remote_id);
        packet_put_int(c->local_window);
@@ -701,28 +693,13 @@ channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
 }
 
 static void
-channel_pre_open_15(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
 {
-       /* test whether sockets are 'alive' for read/write */
-       if (c->istate == CHAN_INPUT_OPEN)
-               if (buffer_len(&c->input) < packet_get_maxsize())
-                       FD_SET(c->sock, readset);
-       if (c->ostate == CHAN_OUTPUT_OPEN ||
-           c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
-               if (buffer_len(&c->output) > 0) {
-                       FD_SET(c->sock, writeset);
-               } else if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
-                       chan_obuf_empty(c);
-               }
-       }
-}
+       u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
 
-static void
-channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset)
-{
        if (c->istate == CHAN_INPUT_OPEN &&
-           c->remote_window > 0 &&
-           buffer_len(&c->input) < c->remote_window)
+           limit > 0 &&
+           buffer_len(&c->input) < limit)
                FD_SET(c->rfd, readset);
        if (c->ostate == CHAN_OUTPUT_OPEN ||
            c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
@@ -733,7 +710,7 @@ channel_pre_open_20(Channel *c, fd_set * readset, fd_set * writeset)
                }
        }
        /** XXX check close conditions, too */
-       if (c->efd != -1) {
+       if (compat20 && c->efd != -1) {
                if (c->extended_usage == CHAN_EXTENDED_WRITE &&
                    buffer_len(&c->extended) > 0)
                        FD_SET(c->efd, writeset);
@@ -784,7 +761,7 @@ x11_open_helper(Buffer *b)
                return 0;
 
        /* Parse the lengths of variable-length fields. */
-       ucp = (u_char *) buffer_ptr(b);
+       ucp = buffer_ptr(b);
        if (ucp[0] == 0x42) {   /* Byte order MSB first. */
                proto_len = 256 * ucp[6] + ucp[7];
                data_len = 256 * ucp[8] + ucp[9];
@@ -793,7 +770,7 @@ x11_open_helper(Buffer *b)
                data_len = ucp[8] + 256 * ucp[9];
        } else {
                debug("Initial X11 packet contains bad byte order byte: 0x%x",
-                     ucp[0]);
+                   ucp[0]);
                return -1;
        }
 
@@ -865,14 +842,19 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
 
        if (ret == 1) {
                c->type = SSH_CHANNEL_OPEN;
-               if (compat20)
-                       channel_pre_open_20(c, readset, writeset);
-               else
-                       channel_pre_open_15(c, readset, writeset);
+               channel_pre_open(c, readset, writeset);
        } else if (ret == -1) {
+               log("X11 connection rejected because of wrong authentication.");
                debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
-               chan_read_failed(c);    /** force close? */
-               chan_write_failed(c);
+               chan_read_failed(c);
+               buffer_clear(&c->input);
+               chan_ibuf_empty(c);
+               buffer_clear(&c->output);
+               /* for proto v1, the peer will send an IEOF */
+               if (compat20)
+                       chan_write_failed(c);
+               else
+                       c->type = SSH_CHANNEL_OPEN;
                debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
        }
 }
@@ -883,7 +865,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
 {
        u_char *p, *host;
        int len, have, i, found;
-       char username[256];     
+       char username[256];
        struct {
                u_int8_t version;
                u_int8_t command;
@@ -930,7 +912,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
        host = inet_ntoa(s4_req.dest_addr);
        strlcpy(c->path, host, sizeof(c->path));
        c->host_port = ntohs(s4_req.dest_port);
-       
+
        debug("channel %d: dynamic request: socks4 host %s port %u command %u",
            c->self, host, c->host_port, s4_req.command);
 
@@ -1002,10 +984,16 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
                debug("X11 connection requested.");
                addrlen = sizeof(addr);
                newsock = accept(c->sock, &addr, &addrlen);
+               if (c->single_connection) {
+                       debug("single_connection: closing X11 listener.");
+                       channel_close_fd(&c->sock);
+                       chan_mark_dead(c);
+               }
                if (newsock < 0) {
                        error("accept: %.100s", strerror(errno));
                        return;
                }
+               set_nodelay(newsock);
                remote_ipaddr = get_peer_ipaddr(newsock);
                remote_port = get_peer_port(newsock);
                snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
@@ -1015,17 +1003,12 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
                    SSH_CHANNEL_OPENING, newsock, newsock, -1,
                    c->local_window_max, c->local_maxpacket,
                    0, xstrdup(buf), 1);
-               if (nc == NULL) {
-                       close(newsock);
-                       xfree(remote_ipaddr);
-                       return;
-               }
                if (compat20) {
                        packet_start(SSH2_MSG_CHANNEL_OPEN);
                        packet_put_cstring("x11");
                        packet_put_int(nc->self);
-                       packet_put_int(c->local_window_max);
-                       packet_put_int(c->local_maxpacket);
+                       packet_put_int(nc->local_window_max);
+                       packet_put_int(nc->local_maxpacket);
                        /* originator ipaddr and port */
                        packet_put_cstring(remote_ipaddr);
                        if (datafellows & SSH_BUG_X11FWD) {
@@ -1133,15 +1116,11 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
                        error("accept: %.100s", strerror(errno));
                        return;
                }
+               set_nodelay(newsock);
                nc = channel_new(rtype,
                    nextstate, newsock, newsock, -1,
                    c->local_window_max, c->local_maxpacket,
                    0, xstrdup(rtype), 1);
-               if (nc == NULL) {
-                       error("channel_post_port_listener: no new channel:");
-                       close(newsock);
-                       return;
-               }
                nc->listening_port = c->listening_port;
                nc->host_port = c->host_port;
                strlcpy(nc->path, c->path, sizeof(nc->path));
@@ -1184,11 +1163,6 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
                    SSH_CHANNEL_OPENING, newsock, newsock, -1,
                    c->local_window_max, c->local_maxpacket,
                    0, name, 1);
-               if (nc == NULL) {
-                       error("channel_post_auth_listener: channel_new failed");
-                       xfree(name);
-                       close(newsock);
-               }
                if (compat20) {
                        packet_start(SSH2_MSG_CHANNEL_OPEN);
                        packet_put_cstring("auth-agent@openssh.com");
@@ -1210,8 +1184,7 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
        socklen_t sz = sizeof(err);
 
        if (FD_ISSET(c->sock, writeset)) {
-               if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, (char *)&err,
-                   &sz) < 0) {
+               if (getsockopt(c->sock, SOL_SOCKET, SO_ERROR, &err, &sz) < 0) {
                        err = errno;
                        error("getsockopt SO_ERROR failed");
                }
@@ -1269,7 +1242,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
                                chan_mark_dead(c);
                                return -1;
                        } else if (compat13) {
-                               buffer_consume(&c->output, buffer_len(&c->output));
+                               buffer_clear(&c->output);
                                c->type = SSH_CHANNEL_INPUT_DRAINING;
                                debug("channel %d: input draining.", c->self);
                        } else {
@@ -1277,7 +1250,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
                        }
                        return -1;
                }
-               if(c->input_filter != NULL) {
+               if (c->input_filter != NULL) {
                        if (c->input_filter(c, buf, len) == -1) {
                                debug("channel %d: filter stops", c->self);
                                chan_read_failed(c);
@@ -1311,7 +1284,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
                                chan_mark_dead(c);
                                return -1;
                        } else if (compat13) {
-                               buffer_consume(&c->output, buffer_len(&c->output));
+                               buffer_clear(&c->output);
                                debug("channel %d: input draining.", c->self);
                                c->type = SSH_CHANNEL_INPUT_DRAINING;
                        } else {
@@ -1368,7 +1341,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
                    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);
+                           c->self, len, c->efd);
                        if (len < 0 && (errno == EINTR || errno == EAGAIN))
                                return 1;
                        if (len <= 0) {
@@ -1403,23 +1376,15 @@ channel_check_window(Channel *c)
 }
 
 static void
-channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
 {
        if (c->delayed)
                return;
        channel_handle_rfd(c, readset, writeset);
        channel_handle_wfd(c, readset, writeset);
-}
-
-static void
-channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset)
-{
-       if (c->delayed)
+       if (!compat20)
                return;
-       channel_handle_rfd(c, readset, writeset);
-       channel_handle_wfd(c, readset, writeset);
        channel_handle_efd(c, readset, writeset);
-
        channel_check_window(c);
 }
 
@@ -1432,7 +1397,7 @@ channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
                len = write(c->sock, buffer_ptr(&c->output),
                            buffer_len(&c->output));
                if (len <= 0)
-                       buffer_consume(&c->output, buffer_len(&c->output));
+                       buffer_clear(&c->output);
                else
                        buffer_consume(&c->output, len);
        }
@@ -1441,7 +1406,7 @@ channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
 static void
 channel_handler_init_20(void)
 {
-       channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open_20;
+       channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open;
        channel_pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;
        channel_pre[SSH_CHANNEL_PORT_LISTENER] =        &channel_pre_listener;
        channel_pre[SSH_CHANNEL_RPORT_LISTENER] =       &channel_pre_listener;
@@ -1450,13 +1415,13 @@ channel_handler_init_20(void)
        channel_pre[SSH_CHANNEL_CONNECTING] =           &channel_pre_connecting;
        channel_pre[SSH_CHANNEL_DYNAMIC] =              &channel_pre_dynamic;
 
-       channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open_2;
+       channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open;
        channel_post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
        channel_post[SSH_CHANNEL_RPORT_LISTENER] =      &channel_post_port_listener;
        channel_post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
        channel_post[SSH_CHANNEL_AUTH_SOCKET] =         &channel_post_auth_listener;
        channel_post[SSH_CHANNEL_CONNECTING] =          &channel_post_connecting;
-       channel_post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open_2;
+       channel_post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open;
 }
 
 static void
@@ -1472,19 +1437,19 @@ channel_handler_init_13(void)
        channel_pre[SSH_CHANNEL_CONNECTING] =           &channel_pre_connecting;
        channel_pre[SSH_CHANNEL_DYNAMIC] =              &channel_pre_dynamic;
 
-       channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open_1;
+       channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open;
        channel_post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
        channel_post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
        channel_post[SSH_CHANNEL_AUTH_SOCKET] =         &channel_post_auth_listener;
        channel_post[SSH_CHANNEL_OUTPUT_DRAINING] =     &channel_post_output_drain_13;
        channel_post[SSH_CHANNEL_CONNECTING] =          &channel_post_connecting;
-       channel_post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open_1;
+       channel_post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open;
 }
 
 static void
 channel_handler_init_15(void)
 {
-       channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open_15;
+       channel_pre[SSH_CHANNEL_OPEN] =                 &channel_pre_open;
        channel_pre[SSH_CHANNEL_X11_OPEN] =             &channel_pre_x11_open;
        channel_pre[SSH_CHANNEL_X11_LISTENER] =         &channel_pre_listener;
        channel_pre[SSH_CHANNEL_PORT_LISTENER] =        &channel_pre_listener;
@@ -1495,16 +1460,16 @@ channel_handler_init_15(void)
        channel_post[SSH_CHANNEL_X11_LISTENER] =        &channel_post_x11_listener;
        channel_post[SSH_CHANNEL_PORT_LISTENER] =       &channel_post_port_listener;
        channel_post[SSH_CHANNEL_AUTH_SOCKET] =         &channel_post_auth_listener;
-       channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open_1;
+       channel_post[SSH_CHANNEL_OPEN] =                &channel_post_open;
        channel_post[SSH_CHANNEL_CONNECTING] =          &channel_post_connecting;
-       channel_post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open_1;
+       channel_post[SSH_CHANNEL_DYNAMIC] =             &channel_post_open;
 }
 
 static void
 channel_handler_init(void)
 {
        int i;
-       for(i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
+       for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
                channel_pre[i] = NULL;
                channel_post[i] = NULL;
        }
@@ -1601,7 +1566,7 @@ channel_after_select(fd_set * readset, fd_set * writeset)
 /* If there is data to send to the connection, enqueue some of it now. */
 
 void
-channel_output_poll()
+channel_output_poll(void)
 {
        int len, i;
        Channel *c;
@@ -1699,7 +1664,7 @@ channel_output_poll()
 /* -- protocol input */
 
 void
-channel_input_data(int type, int plen, void *ctxt)
+channel_input_data(int type, u_int32_t seq, void *ctxt)
 {
        int id;
        char *data;
@@ -1723,9 +1688,8 @@ channel_input_data(int type, int plen, void *ctxt)
 
        /* Get the data. */
        data = packet_get_string(&data_len);
-       packet_done();
 
-       if (compat20){
+       if (compat20) {
                if (data_len > c->local_maxpacket) {
                        log("channel %d: rcvd big packet %d, maxpack %d",
                            c->self, data_len, c->local_maxpacket);
@@ -1737,15 +1701,14 @@ channel_input_data(int type, int plen, void *ctxt)
                        return;
                }
                c->local_window -= data_len;
-       }else{
-               packet_integrity_check(plen, 4 + 4 + data_len, type);
        }
+       packet_check_eom();
        buffer_append(&c->output, data, data_len);
        xfree(data);
 }
 
 void
-channel_input_extended_data(int type, int plen, void *ctxt)
+channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
 {
        int id;
        int tcode;
@@ -1771,7 +1734,7 @@ channel_input_extended_data(int type, int plen, void *ctxt)
                return;
        }
        data = packet_get_string(&data_len);
-       packet_done();
+       packet_check_eom();
        if (data_len > c->local_window) {
                log("channel %d: rcvd too much extended_data %d, win %d",
                    c->self, data_len, c->local_window);
@@ -1785,36 +1748,36 @@ channel_input_extended_data(int type, int plen, void *ctxt)
 }
 
 void
-channel_input_ieof(int type, int plen, void *ctxt)
+channel_input_ieof(int type, u_int32_t seq, void *ctxt)
 {
        int id;
        Channel *c;
 
-       packet_integrity_check(plen, 4, type);
-
        id = packet_get_int();
+       packet_check_eom();
        c = channel_lookup(id);
        if (c == NULL)
                packet_disconnect("Received ieof for nonexistent channel %d.", id);
        chan_rcvd_ieof(c);
 
        /* XXX force input close */
-       if (c->force_drain) {
+       if (c->force_drain && c->istate == CHAN_INPUT_OPEN) {
                debug("channel %d: FORCE input drain", c->self);
                c->istate = CHAN_INPUT_WAIT_DRAIN;
+               if (buffer_len(&c->input) == 0)
+                       chan_ibuf_empty(c);
        }
 
 }
 
 void
-channel_input_close(int type, int plen, void *ctxt)
+channel_input_close(int type, u_int32_t seq, void *ctxt)
 {
        int id;
        Channel *c;
 
-       packet_integrity_check(plen, 4, type);
-
        id = packet_get_int();
+       packet_check_eom();
        c = channel_lookup(id);
        if (c == NULL)
                packet_disconnect("Received close for nonexistent channel %d.", id);
@@ -1839,30 +1802,31 @@ channel_input_close(int type, int plen, void *ctxt)
                 * Not a closed channel - mark it as draining, which will
                 * cause it to be freed later.
                 */
-               buffer_consume(&c->input, buffer_len(&c->input));
+               buffer_clear(&c->input);
                c->type = SSH_CHANNEL_OUTPUT_DRAINING;
        }
 }
 
 /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
 void
-channel_input_oclose(int type, int plen, void *ctxt)
+channel_input_oclose(int type, u_int32_t seq, void *ctxt)
 {
        int id = packet_get_int();
        Channel *c = channel_lookup(id);
-       packet_integrity_check(plen, 4, type);
+
+       packet_check_eom();
        if (c == NULL)
                packet_disconnect("Received oclose for nonexistent channel %d.", id);
        chan_rcvd_oclose(c);
 }
 
 void
-channel_input_close_confirmation(int type, int plen, void *ctxt)
+channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
 {
        int id = packet_get_int();
        Channel *c = channel_lookup(id);
 
-       packet_done();
+       packet_check_eom();
        if (c == NULL)
                packet_disconnect("Received close confirmation for "
                    "out-of-range channel %d.", id);
@@ -1873,14 +1837,11 @@ channel_input_close_confirmation(int type, int plen, void *ctxt)
 }
 
 void
-channel_input_open_confirmation(int type, int plen, void *ctxt)
+channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
 {
        int id, remote_id;
        Channel *c;
 
-       if (!compat20)
-               packet_integrity_check(plen, 4 + 4, type);
-
        id = packet_get_int();
        c = channel_lookup(id);
 
@@ -1895,21 +1856,21 @@ channel_input_open_confirmation(int type, int plen, void *ctxt)
        if (compat20) {
                c->remote_window = packet_get_int();
                c->remote_maxpacket = packet_get_int();
-               packet_done();
-               if (c->cb_fn != NULL && c->cb_event == type) {
+               if (c->confirm) {
                        debug2("callback start");
-                       c->cb_fn(c->self, c->cb_arg);
+                       c->confirm(c->self, NULL);
                        debug2("callback done");
                }
                debug("channel %d: open confirm rwindow %d rmax %d", c->self,
                    c->remote_window, c->remote_maxpacket);
        }
+       packet_check_eom();
 }
 
 static char *
 reason2txt(int reason)
 {
-       switch(reason) {
+       switch (reason) {
        case SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED:
                return "administratively prohibited";
        case SSH2_OPEN_CONNECT_FAILED:
@@ -1923,15 +1884,12 @@ reason2txt(int reason)
 }
 
 void
-channel_input_open_failure(int type, int plen, void *ctxt)
+channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
 {
        int id, reason;
        char *msg = NULL, *lang = NULL;
        Channel *c;
 
-       if (!compat20)
-               packet_integrity_check(plen, 4, type);
-
        id = packet_get_int();
        c = channel_lookup(id);
 
@@ -1944,7 +1902,6 @@ channel_input_open_failure(int type, int plen, void *ctxt)
                        msg  = packet_get_string(NULL);
                        lang = packet_get_string(NULL);
                }
-               packet_done();
                log("channel %d: open failed: %s%s%s", id,
                    reason2txt(reason), msg ? ": ": "", msg ? msg : "");
                if (msg != NULL)
@@ -1952,37 +1909,13 @@ channel_input_open_failure(int type, int plen, void *ctxt)
                if (lang != NULL)
                        xfree(lang);
        }
+       packet_check_eom();
        /* Free the channel.  This will also close the socket. */
        channel_free(c);
 }
 
 void
-channel_input_channel_request(int type, int plen, void *ctxt)
-{
-       int id;
-       Channel *c;
-
-       id = packet_get_int();
-       c = channel_lookup(id);
-
-       if (c == NULL ||
-           (c->type != SSH_CHANNEL_OPEN && c->type != SSH_CHANNEL_LARVAL))
-               packet_disconnect("Received request for "
-                   "non-open channel %d.", id);
-       if (c->cb_fn != NULL && c->cb_event == type) {
-               debug2("callback start");
-               c->cb_fn(c->self, c->cb_arg);
-               debug2("callback done");
-       } else {
-               char *service = packet_get_string(NULL);
-               debug("channel %d: rcvd request for %s", c->self, service);
-               debug("cb_fn %p cb_event %d", c->cb_fn , c->cb_event);
-               xfree(service);
-       }
-}
-
-void
-channel_input_window_adjust(int type, int plen, void *ctxt)
+channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c;
        int id, adjust;
@@ -2000,13 +1933,13 @@ channel_input_window_adjust(int type, int plen, void *ctxt)
                return;
        }
        adjust = packet_get_int();
-       packet_done();
+       packet_check_eom();
        debug2("channel %d: rcvd adjust %d", id, adjust);
        c->remote_window += adjust;
 }
 
 void
-channel_input_port_open(int type, int plen, void *ctxt)
+channel_input_port_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
        u_short host_port;
@@ -2022,18 +1955,13 @@ channel_input_port_open(int type, int plen, void *ctxt)
        } else {
                originator_string = xstrdup("unknown (remote did not supply name)");
        }
-       packet_done();
+       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);
-               if (c == NULL) {
-                       error("channel_input_port_open: channel_new failed");
-                       close(sock);
-               } else {
-                       c->remote_id = remote_id;
-               }
+               c->remote_id = remote_id;
        }
        if (c == NULL) {
                packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
@@ -2052,53 +1980,30 @@ channel_set_af(int af)
        IPv4or6 = af;
 }
 
-/*
- * Initiate forwarding of connections to local port "port" through the secure
- * channel to host:port from remote side.
- */
-int
-channel_request_local_forwarding(u_short listen_port, const char *host_to_connect,
-    u_short port_to_connect, int gateway_ports)
-{
-       return channel_request_forwarding(
-           NULL, listen_port,
-           host_to_connect, port_to_connect,
-           gateway_ports, /*remote_fwd*/ 0);
-}
-
-/*
- * If 'remote_fwd' is true we have a '-R style' listener for protocol 2
- * (SSH_CHANNEL_RPORT_LISTENER).
- */
-int
-channel_request_forwarding(
-    const char *listen_address, u_short listen_port,
-    const char *host_to_connect, u_short port_to_connect,
-    int gateway_ports, int remote_fwd)
+static int
+channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port,
+    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
 {
        Channel *c;
-       int success, sock, on = 1, type;
+       int success, sock, on = 1;
        struct addrinfo hints, *ai, *aitop;
-       char ntop[NI_MAXHOST], strport[NI_MAXSERV];
        const char *host;
+       char ntop[NI_MAXHOST], strport[NI_MAXSERV];
        struct linger linger;
 
        success = 0;
+       host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
+           listen_addr : host_to_connect;
 
-       if (remote_fwd) {
-               host = listen_address;
-               type = SSH_CHANNEL_RPORT_LISTENER;
-       } else {
-               host = host_to_connect;
-               type = SSH_CHANNEL_PORT_LISTENER;
+       if (host == NULL) {
+               error("No forward host name.");
+               return success;
        }
-
        if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
                error("Forward host name too long.");
                return success;
        }
 
-       /* XXX listen_address is currently ignored */
        /*
         * getaddrinfo returns a loopback address if the hostname is
         * set to NULL and hints.ai_flags is not AI_PASSIVE
@@ -2116,7 +2021,7 @@ channel_request_forwarding(
                        continue;
                if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
                    strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
-                       error("channel_request_forwarding: getnameinfo failed");
+                       error("channel_setup_fwd_listener: getnameinfo failed");
                        continue;
                }
                /* Create a port to listen for the host. */
@@ -2130,10 +2035,10 @@ channel_request_forwarding(
                 * Set socket options.  We would like the socket to disappear
                 * as soon as it has been closed for whatever reason.
                 */
-               setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on));
+               setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
                linger.l_onoff = 1;
                linger.l_linger = 5;
-               setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
+               setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
                debug("Local forwarding listening on %s port %s.", ntop, strport);
 
                /* Bind the socket to the address. */
@@ -2157,23 +2062,36 @@ channel_request_forwarding(
                c = channel_new("port listener", type, sock, sock, -1,
                    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
                    0, xstrdup("port listener"), 1);
-               if (c == NULL) {
-                       error("channel_request_forwarding: channel_new failed");
-                       close(sock);
-                       continue;
-               }
                strlcpy(c->path, host, sizeof(c->path));
                c->host_port = port_to_connect;
                c->listening_port = listen_port;
                success = 1;
        }
        if (success == 0)
-               error("channel_request_forwarding: cannot listen to port: %d",
+               error("channel_setup_fwd_listener: cannot listen to port: %d",
                    listen_port);
        freeaddrinfo(aitop);
        return success;
 }
 
+/* protocol local port fwd, used by ssh (and sshd in v1) */
+int
+channel_setup_local_fwd_listener(u_short listen_port,
+    const char *host_to_connect, u_short port_to_connect, int gateway_ports)
+{
+       return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
+           NULL, listen_port, host_to_connect, port_to_connect, gateway_ports);
+}
+
+/* protocol v2 remote port fwd, used by sshd */
+int
+channel_setup_remote_fwd_listener(const char *listen_address,
+    u_short listen_port, int gateway_ports)
+{
+       return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER,
+           listen_address, listen_port, NULL, 0, gateway_ports);
+}
+
 /*
  * Initiate forwarding of connections to port "port" on remote host through
  * the secure channel to host:port from local side.
@@ -2183,7 +2101,7 @@ void
 channel_request_remote_forwarding(u_short listen_port,
     const char *host_to_connect, u_short port_to_connect)
 {
-       int payload_len, type, success = 0;
+       int type, success = 0;
 
        /* Record locally that connection to this host/port is permitted. */
        if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
@@ -2210,7 +2128,7 @@ channel_request_remote_forwarding(u_short listen_port,
                packet_write_wait();
 
                /* Wait for response from the remote side. */
-               type = packet_read(&payload_len);
+               type = packet_read();
                switch (type) {
                case SSH_SMSG_SUCCESS:
                        success = 1;
@@ -2259,7 +2177,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
                                  port);
 #endif
        /* Initiate forwarding */
-       channel_request_local_forwarding(port, hostname, host_port, gateway_ports);
+       channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
 
        /* Free the argument string. */
        xfree(hostname);
@@ -2271,7 +2189,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
  * anyway, and the server has no way to know but to trust the client anyway.
  */
 void
-channel_permit_all_opens()
+channel_permit_all_opens(void)
 {
        if (num_permitted_opens == 0)
                all_opens_permitted = 1;
@@ -2352,6 +2270,7 @@ connect_to(const char *host, u_short port)
                return -1;
        }
        /* success */
+       set_nodelay(sock);
        return sock;
 }
 
@@ -2396,32 +2315,32 @@ channel_connect_to(const char *host, u_short port)
 
 /*
  * Creates an internet domain socket for listening for X11 connections.
- * Returns a suitable value for the DISPLAY variable, or NULL if an error
- * occurs.
+ * Returns a suitable display number for the DISPLAY variable, or -1 if
+ * an error occurs.
  */
-char *
-x11_create_display_inet(int screen_number, int x11_display_offset)
+int
+x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
+    int single_connection)
 {
+       Channel *nc = NULL;
        int display_number, sock;
        u_short port;
        struct addrinfo hints, *ai, *aitop;
        char strport[NI_MAXSERV];
        int gaierr, n, num_socks = 0, socks[NUM_SOCKS];
-       char display[512];
-       char hostname[MAXHOSTNAMELEN];
 
        for (display_number = x11_display_offset;
-            display_number < MAX_DISPLAYS;
-            display_number++) {
+           display_number < MAX_DISPLAYS;
+           display_number++) {
                port = 6000 + display_number;
                memset(&hints, 0, sizeof(hints));
                hints.ai_family = IPv4or6;
-               hints.ai_flags = AI_PASSIVE;            /* XXX loopback only ? */
+               hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
                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));
-                       return NULL;
+                       return -1;
                }
                for (ai = aitop; ai; ai = ai->ai_next) {
                        if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
@@ -2430,7 +2349,7 @@ x11_create_display_inet(int screen_number, int x11_display_offset)
                        if (sock < 0) {
                                if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) {
                                        error("socket: %.100s", strerror(errno));
-                                       return NULL;
+                                       return -1;
                                } else {
                                        debug("x11_create_display_inet: Socket family %d not supported",
                                                 ai->ai_family);
@@ -2439,14 +2358,12 @@ x11_create_display_inet(int screen_number, int x11_display_offset)
                        }
                        if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
                                debug("bind port %d: %.100s", port, strerror(errno));
-                               shutdown(sock, SHUT_RDWR);
                                close(sock);
 
                                if (ai->ai_next)
                                        continue;
 
                                for (n = 0; n < num_socks; n++) {
-                                       shutdown(socks[n], SHUT_RDWR);
                                        close(socks[n]);
                                }
                                num_socks = 0;
@@ -2466,103 +2383,47 @@ x11_create_display_inet(int screen_number, int x11_display_offset)
        }
        if (display_number >= MAX_DISPLAYS) {
                error("Failed to allocate internet-domain X11 display socket.");
-               return NULL;
+               return -1;
        }
        /* Start listening for connections on the socket. */
        for (n = 0; n < num_socks; n++) {
                sock = socks[n];
                if (listen(sock, 5) < 0) {
                        error("listen: %.100s", strerror(errno));
-                       shutdown(sock, SHUT_RDWR);
                        close(sock);
-                       return NULL;
-               }
-       }
-
-       /* Set up a suitable value for the DISPLAY variable. */
-       if (gethostname(hostname, sizeof(hostname)) < 0)
-               fatal("gethostname: %.100s", strerror(errno));
-
-#ifdef IPADDR_IN_DISPLAY
-       /*
-        * HPUX detects the local hostname in the DISPLAY variable and tries
-        * to set up a shared memory connection to the server, which it
-        * incorrectly supposes to be local.
-        *
-        * The workaround - as used in later $$H and other programs - is
-        * is to set display to the host's IP address.
-        */
-       {
-               struct hostent *he;
-               struct in_addr my_addr;
-
-               he = gethostbyname(hostname);
-               if (he == NULL) {
-                       error("[X11-broken-fwd-hostname-workaround] Could not get "
-                               "IP address for hostname %s.", hostname);
-
-                       packet_send_debug("[X11-broken-fwd-hostname-workaround]"
-                               "Could not get IP address for hostname %s.", hostname);
-
-                       shutdown(sock, SHUT_RDWR);
-                       close(sock);
-
-                       return NULL;
+                       return -1;
                }
-
-               memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
-
-               /* Set DISPLAY to <ip address>:screen.display */
-               snprintf(display, sizeof(display), "%.50s:%d.%d", inet_ntoa(my_addr),
-                        display_number, screen_number);
        }
-#else /* IPADDR_IN_DISPLAY */
-       /* Just set DISPLAY to hostname:screen.display */
-       snprintf(display, sizeof display, "%.400s:%d.%d", hostname,
-                display_number, screen_number);
-#endif /* IPADDR_IN_DISPLAY */
 
        /* Allocate a channel for each socket. */
        for (n = 0; n < num_socks; n++) {
                sock = socks[n];
-               (void) channel_new("x11 listener",
+               nc = channel_new("x11 listener",
                    SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
                    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
                    0, xstrdup("X11 inet listener"), 1);
+               nc->single_connection = single_connection;
        }
 
-       /* Return a suitable value for the DISPLAY environment variable. */
-       return xstrdup(display);
+       /* Return the display number for the DISPLAY environment variable. */
+       return display_number;
 }
 
-#ifndef X_UNIX_PATH
-#define X_UNIX_PATH "/tmp/.X11-unix/X"
-#endif
-
 static int
 connect_local_xsocket(u_int dnr)
 {
-       static const char *const x_sockets[] = {
-               X_UNIX_PATH "%u",
-               "/var/X/.X11-unix/X" "%u",
-               "/usr/spool/sockets/X11/" "%u",
-               NULL
-       };
        int sock;
        struct sockaddr_un addr;
-       const char *const * path;
 
-       for (path = x_sockets; *path; ++path) {
-               sock = socket(AF_UNIX, SOCK_STREAM, 0);
-               if (sock < 0)
-                       error("socket: %.100s", strerror(errno));
-               memset(&addr, 0, sizeof(addr));
-               addr.sun_family = AF_UNIX;
-               snprintf(addr.sun_path, sizeof addr.sun_path, *path, dnr);
-               if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
-                       return sock;
-               close(sock);
-       }
+       sock = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (sock < 0)
+               error("socket: %.100s", strerror(errno));
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
+       if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
+               return sock;
+       close(sock);
        error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
        return -1;
 }
@@ -2597,7 +2458,7 @@ x11_connect_display(void)
                /* Connect to the unix domain socket. */
                if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
                        error("Could not parse display number from DISPLAY: %.100s",
-                             display);
+                           display);
                        return -1;
                }
                /* Create a socket. */
@@ -2612,8 +2473,7 @@ x11_connect_display(void)
         * Connect to an inet socket.  The DISPLAY value is supposedly
         * hostname:d[.s], where hostname may also be numeric IP address.
         */
-       strncpy(buf, display, sizeof(buf));
-       buf[sizeof(buf) - 1] = 0;
+       strlcpy(buf, display, sizeof(buf));
        cp = strchr(buf, ':');
        if (!cp) {
                error("Could not find ':' in DISPLAY: %.100s", display);
@@ -2623,7 +2483,7 @@ x11_connect_display(void)
        /* buf now contains the host name.  But first we parse the display number. */
        if (sscanf(cp + 1, "%d", &display_number) != 1) {
                error("Could not parse display number from DISPLAY: %.100s",
-                     display);
+                   display);
                return -1;
        }
 
@@ -2659,6 +2519,7 @@ x11_connect_display(void)
                    strerror(errno));
                return -1;
        }
+       set_nodelay(sock);
        return sock;
 }
 
@@ -2669,7 +2530,7 @@ x11_connect_display(void)
  */
 
 void
-x11_input_open(int type, int plen, void *ctxt)
+x11_input_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
        int remote_id, sock = 0;
@@ -2684,7 +2545,7 @@ x11_input_open(int type, int plen, void *ctxt)
        } else {
                remote_host = xstrdup("unknown (remote did not supply name)");
        }
-       packet_done();
+       packet_check_eom();
 
        /* Obtain a connection to the real X display. */
        sock = x11_connect_display();
@@ -2693,13 +2554,8 @@ x11_input_open(int type, int plen, void *ctxt)
                c = channel_new("connected x11 socket",
                    SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
                    remote_host, 1);
-               if (c == NULL) {
-                       error("x11_input_open: channel_new failed");
-                       close(sock);
-               } else {
-                       c->remote_id = remote_id;
-                       c->force_drain = 1;
-               }
+               c->remote_id = remote_id;
+               c->force_drain = 1;
        }
        if (c == NULL) {
                /* Send refusal to the remote host. */
@@ -2716,10 +2572,10 @@ x11_input_open(int type, int plen, void *ctxt)
 
 /* dummy protocol handler that denies SSH-1 requests (agent/x11) */
 void
-deny_input_open(int type, int plen, void *ctxt)
+deny_input_open(int type, u_int32_t seq, void *ctxt)
 {
        int rchan = packet_get_int();
-       switch(type){
+       switch (type) {
        case SSH_SMSG_AGENT_OPEN:
                error("Warning: ssh server tried agent forwarding.");
                break;
@@ -2727,7 +2583,7 @@ deny_input_open(int type, int plen, void *ctxt)
                error("Warning: ssh server tried X11 forwarding.");
                break;
        default:
-               error("deny_input_open: type %d plen %d", type, plen);
+               error("deny_input_open: type %d", type);
                break;
        }
        error("Warning: this is probably a break in attempt by a malicious server.");
@@ -2811,7 +2667,7 @@ x11_request_forwarding_with_spoofing(int client_session_id,
 /* Sends a message to the server to request authentication fd forwarding. */
 
 void
-auth_request_forwarding()
+auth_request_forwarding(void)
 {
        packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
        packet_send();
@@ -2825,7 +2681,7 @@ auth_request_forwarding()
  */
 
 char *
-auth_get_socket_name()
+auth_get_socket_name(void)
 {
        return auth_sock_name;
 }
@@ -2896,8 +2752,7 @@ auth_input_request_forwarding(struct passwd * pw)
        /* Bind it to the name. */
        memset(&sunaddr, 0, sizeof(sunaddr));
        sunaddr.sun_family = AF_UNIX;
-       strncpy(sunaddr.sun_path, auth_sock_name,
-               sizeof(sunaddr.sun_path));
+       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));
@@ -2914,13 +2769,6 @@ auth_input_request_forwarding(struct passwd * pw)
            SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
            CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
            0, xstrdup("auth socket"), 1);
-       if (nc == NULL) {
-               error("auth_input_request_forwarding: channel_new failed");
-               auth_sock_cleanup_proc(pw);
-               fatal_remove_cleanup(auth_sock_cleanup_proc, pw);
-               close(sock);
-               return 0;
-       }
        strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
        return 1;
 }
@@ -2928,16 +2776,15 @@ auth_input_request_forwarding(struct passwd * pw)
 /* This is called to process an SSH_SMSG_AGENT_OPEN message. */
 
 void
-auth_input_open_request(int type, int plen, void *ctxt)
+auth_input_open_request(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
        int remote_id, sock;
        char *name;
 
-       packet_integrity_check(plen, 4, type);
-
        /* Read the remote channel number from the message. */
        remote_id = packet_get_int();
+       packet_check_eom();
 
        /*
         * Get a connection to the local authentication agent (this may again
@@ -2955,14 +2802,8 @@ auth_input_open_request(int type, int plen, void *ctxt)
                name = xstrdup("authentication agent connection");
                c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
                    -1, 0, 0, 0, name, 1);
-               if (c == NULL) {
-                       error("auth_input_open_request: channel_new failed");
-                       xfree(name);
-                       close(sock);
-               } else {
-                       c->remote_id = remote_id;
-                       c->force_drain = 1;
-               }
+               c->remote_id = remote_id;
+               c->force_drain = 1;
        }
        if (c == NULL) {
                packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
index 11ebb7b3a558baec037e5702857f833f81a7d23a..707d9a925820f71f9ef4a99426a936093c3a67c4 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: channels.h,v 1.65 2002/03/04 17:27:39 stevesk Exp $   */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -10,7 +12,7 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 /*
- * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,7 +34,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* RCSID("$OpenBSD: channels.h,v 1.51 2001/11/07 22:53:21 markus Exp $"); */
 
 #ifndef CHANNEL_H
 #define CHANNEL_H
@@ -68,8 +69,8 @@ struct Channel {
        int     type;           /* channel type/state */
        int     self;           /* my own channel identifier */
        int     remote_id;      /* channel identifier for remote peer */
-       int     istate;         /* input from channel (state of receive half) */
-       int     ostate;         /* output to channel  (state of transmit half) */
+       u_int   istate;         /* input from channel (state of receive half) */
+       u_int   ostate;         /* output to channel  (state of transmit half) */
        int     flags;          /* close sent/rcvd */
        int     rfd;            /* read fd */
        int     wfd;            /* write fd */
@@ -96,13 +97,12 @@ struct Channel {
        int     local_consumed;
        int     local_maxpacket;
        int     extended_usage;
+       int     single_connection;
 
        char   *ctype;          /* type */
 
        /* callback */
-       channel_callback_fn     *cb_fn;
-       void    *cb_arg;
-       int     cb_event;
+       channel_callback_fn     *confirm;
        channel_callback_fn     *detach_user;
 
        /* filter */
@@ -114,24 +114,24 @@ struct Channel {
 #define CHAN_EXTENDED_WRITE            2
 
 /* default window/packet sizes for tcp/x11-fwd-channel */
-#define CHAN_SES_WINDOW_DEFAULT        (32*1024)
-#define CHAN_SES_PACKET_DEFAULT        (CHAN_SES_WINDOW_DEFAULT/2)
-#define CHAN_TCP_WINDOW_DEFAULT        (32*1024)
-#define CHAN_TCP_PACKET_DEFAULT        (CHAN_TCP_WINDOW_DEFAULT/2)
-#define CHAN_X11_WINDOW_DEFAULT        (4*1024)
-#define CHAN_X11_PACKET_DEFAULT        (CHAN_X11_WINDOW_DEFAULT/2)
+#define CHAN_SES_PACKET_DEFAULT        (32*1024)
+#define CHAN_SES_WINDOW_DEFAULT        (4*CHAN_SES_PACKET_DEFAULT)
+#define CHAN_TCP_PACKET_DEFAULT        (32*1024)
+#define CHAN_TCP_WINDOW_DEFAULT        (4*CHAN_TCP_PACKET_DEFAULT)
+#define CHAN_X11_PACKET_DEFAULT        (16*1024)
+#define CHAN_X11_WINDOW_DEFAULT        (4*CHAN_X11_PACKET_DEFAULT)
 
 /* possible input states */
-#define CHAN_INPUT_OPEN                        0x01
-#define CHAN_INPUT_WAIT_DRAIN          0x02
-#define CHAN_INPUT_WAIT_OCLOSE         0x04
-#define CHAN_INPUT_CLOSED              0x08
+#define CHAN_INPUT_OPEN                        0
+#define CHAN_INPUT_WAIT_DRAIN          1
+#define CHAN_INPUT_WAIT_OCLOSE         2
+#define CHAN_INPUT_CLOSED              3
 
 /* possible output states */
-#define CHAN_OUTPUT_OPEN               0x10
-#define CHAN_OUTPUT_WAIT_DRAIN         0x20
-#define CHAN_OUTPUT_WAIT_IEOF          0x40
-#define CHAN_OUTPUT_CLOSED             0x80
+#define CHAN_OUTPUT_OPEN               0
+#define CHAN_OUTPUT_WAIT_DRAIN         1
+#define CHAN_OUTPUT_WAIT_IEOF          2
+#define CHAN_OUTPUT_CLOSED             3
 
 #define CHAN_CLOSE_SENT                        0x01
 #define CHAN_CLOSE_RCVD                        0x02
@@ -140,33 +140,31 @@ struct Channel {
 
 Channel        *channel_lookup(int);
 Channel *channel_new(char *, int, int, int, int, int, int, int, char *, int);
-void    channel_set_fds(int, int, int, int, int, int);
+void    channel_set_fds(int, int, int, int, int, int, u_int);
 void    channel_free(Channel *);
 void    channel_free_all(void);
 void    channel_stop_listening(void);
 
 void    channel_send_open(int);
-void    channel_request(int, char *, int);
 void    channel_request_start(int, char *, int);
-void    channel_register_callback(int, int mtype, channel_callback_fn *, void *);
 void    channel_register_cleanup(int, channel_callback_fn *);
+void    channel_register_confirm(int, channel_callback_fn *);
 void    channel_register_filter(int, channel_filter_fn *);
 void    channel_cancel_cleanup(int);
 int     channel_close_fd(int *);
 
 /* protocol handler */
 
-void    channel_input_channel_request(int, int, void *);
-void    channel_input_close(int, int, void *);
-void    channel_input_close_confirmation(int, int, void *);
-void    channel_input_data(int, int, void *);
-void    channel_input_extended_data(int, int, void *);
-void    channel_input_ieof(int, int, void *);
-void    channel_input_oclose(int, int, void *);
-void    channel_input_open_confirmation(int, int, void *);
-void    channel_input_open_failure(int, int, void *);
-void    channel_input_port_open(int, int, void *);
-void    channel_input_window_adjust(int, int, void *);
+void    channel_input_close(int, u_int32_t, void *);
+void    channel_input_close_confirmation(int, u_int32_t, void *);
+void    channel_input_data(int, u_int32_t, void *);
+void    channel_input_extended_data(int, u_int32_t, void *);
+void    channel_input_ieof(int, u_int32_t, void *);
+void    channel_input_oclose(int, u_int32_t, void *);
+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 *);
 
 /* file descriptor handling (read/write) */
 
@@ -189,20 +187,16 @@ void     channel_input_port_forward_request(int, int);
 int     channel_connect_to(const char *, u_short);
 int     channel_connect_by_listen_address(u_short);
 void    channel_request_remote_forwarding(u_short, const char *, u_short);
-int     channel_request_local_forwarding(u_short, const char *, u_short, int);
-int
-channel_request_forwarding(const char *, u_short, const char *, u_short, int,
-    int);
+int     channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
+int     channel_setup_remote_fwd_listener(const char *, u_short, int);
 
 /* x11 forwarding */
 
 int     x11_connect_display(void);
-char   *x11_create_display(int);
-char   *x11_create_display_inet(int, int);
-void     x11_input_open(int, int, void *);
-void     x11_request_forwarding(void);
+int     x11_create_display_inet(int, int, int);
+void     x11_input_open(int, u_int32_t, void *);
 void    x11_request_forwarding_with_spoofing(int, const char *, const char *);
-void    deny_input_open(int, int, void *);
+void    deny_input_open(int, u_int32_t, void *);
 
 /* agent forwarding */
 
@@ -210,25 +204,21 @@ void       auth_request_forwarding(void);
 char   *auth_get_socket_name(void);
 void    auth_sock_cleanup_proc(void *);
 int     auth_input_request_forwarding(struct passwd *);
-void    auth_input_open_request(int, int, void *);
+void    auth_input_open_request(int, u_int32_t, void *);
 
 /* channel close */
 
 int     chan_is_dead(Channel *, int);
 void    chan_mark_dead(Channel *);
-void    chan_init_iostates(Channel *);
-void    chan_init(void);
 
-typedef void    chan_event_fn(Channel *);
+/* channel events */
 
-/* for the input state */
-extern chan_event_fn   *chan_rcvd_oclose;
-extern chan_event_fn   *chan_read_failed;
-extern chan_event_fn   *chan_ibuf_empty;
+void    chan_rcvd_oclose(Channel *);
+void    chan_read_failed(Channel *);
+void    chan_ibuf_empty(Channel *);
 
-/* for the output state */
-extern chan_event_fn   *chan_rcvd_ieof;
-extern chan_event_fn   *chan_write_failed;
-extern chan_event_fn   *chan_obuf_empty;
+void    chan_rcvd_ieof(Channel *);
+void    chan_write_failed(Channel *);
+void    chan_obuf_empty(Channel *);
 
 #endif
index de25ff09692bb8d626bd769a0fd6e793020cadd4..ce3f6f3ce2088306a9813d6e88c2357e0485f382 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.47 2001/08/23 11:31:59 markus Exp $");
+RCSID("$OpenBSD: cipher.c,v 1.52 2002/02/18 13:05:32 markus Exp $");
 
 #include "xmalloc.h"
 #include "log.h"
 #include "cipher.h"
 
 #include <openssl/md5.h>
+#include "rijndael.h"
+
+static EVP_CIPHER *evp_ssh1_3des(void);
+static EVP_CIPHER *evp_ssh1_bf(void);
+static EVP_CIPHER *evp_rijndael(void);
+
+struct Cipher {
+       char    *name;
+       int     number;         /* for ssh1 only */
+       u_int   block_size;
+       u_int   key_len;
+       EVP_CIPHER      *(*evptype)(void);
+} ciphers[] = {
+       { "none",               SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
+       { "des",                SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
+       { "3des",               SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
+       { "blowfish",           SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
+
+       { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
+       { "blowfish-cbc",       SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
+       { "cast128-cbc",        SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
+       { "arcfour",            SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
+       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
+       { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
+       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
+
+       { NULL,                 SSH_CIPHER_ILLEGAL, 0, 0, NULL }
+};
 
-/* no encryption */
-static void
-none_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-}
-static void
-none_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
-{
-}
-static void
-none_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       memcpy(dest, src, len);
-}
-
-/* DES */
-static void
-des_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       static int dowarn = 1;
-       if (dowarn) {
-               error("Warning: use of DES is strongly discouraged "
-                   "due to cryptographic weaknesses");
-               dowarn = 0;
-       }
-       des_set_key((void *)key, cc->u.des.key);
-}
-static void
-des_ssh1_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
-{
-       memset(cc->u.des.iv, 0, sizeof(cc->u.des.iv));
-}
-static void
-des_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv,
-           DES_ENCRYPT);
-}
-static void
-des_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       des_ncbc_encrypt(src, dest, len, cc->u.des.key, &cc->u.des.iv,
-           DES_DECRYPT);
-}
-
-/* 3DES */
-static void
-des3_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       des_set_key((void *) key, cc->u.des3.key1);
-       des_set_key((void *) (key+8), cc->u.des3.key2);
-       des_set_key((void *) (key+16), cc->u.des3.key3);
-}
-static void
-des3_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
-{
-       memset(cc->u.des3.iv1, 0, sizeof(cc->u.des3.iv1));
-       memset(cc->u.des3.iv2, 0, sizeof(cc->u.des3.iv2));
-       memset(cc->u.des3.iv3, 0, sizeof(cc->u.des3.iv3));
-       if (iv == NULL)
-               return;
-       memcpy(cc->u.des3.iv3, (char *)iv, 8);
-}
-static void
-des3_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       des_ede3_cbc_encrypt(src, dest, len,
-           cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3,
-           &cc->u.des3.iv3, DES_ENCRYPT);
-}
-static void
-des3_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       des_ede3_cbc_encrypt(src, dest, len,
-           cc->u.des3.key1, cc->u.des3.key2, cc->u.des3.key3,
-           &cc->u.des3.iv3, DES_DECRYPT);
-}
-
-/*
- * This is used by SSH1:
- *
- * What kind of triple DES are these 2 routines?
- *
- * Why is there a redundant initialization vector?
- *
- * If only iv3 was used, then, this would till effect have been
- * outer-cbc. However, there is also a private iv1 == iv2 which
- * perhaps makes differential analysis easier. On the other hand, the
- * private iv1 probably makes the CRC-32 attack ineffective. This is a
- * result of that there is no longer any known iv1 to use when
- * choosing the X block.
- */
-static void
-des3_ssh1_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       des_set_key((void *) key, cc->u.des3.key1);
-       des_set_key((void *) (key+8), cc->u.des3.key2);
-       if (keylen <= 16)
-               des_set_key((void *) key, cc->u.des3.key3);
-       else
-               des_set_key((void *) (key+16), cc->u.des3.key3);
-}
-static void
-des3_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
-    u_int len)
-{
-       des_ncbc_encrypt(src,  dest, len, cc->u.des3.key1, &cc->u.des3.iv1,
-           DES_ENCRYPT);
-       des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, &cc->u.des3.iv2,
-           DES_DECRYPT);
-       des_ncbc_encrypt(dest, dest, len, cc->u.des3.key3, &cc->u.des3.iv3,
-           DES_ENCRYPT);
-}
-static void
-des3_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
-    u_int len)
-{
-       des_ncbc_encrypt(src,  dest, len, cc->u.des3.key3, &cc->u.des3.iv3,
-           DES_DECRYPT);
-       des_ncbc_encrypt(dest, dest, len, cc->u.des3.key2, &cc->u.des3.iv2,
-           DES_ENCRYPT);
-       des_ncbc_encrypt(dest, dest, len, cc->u.des3.key1, &cc->u.des3.iv1,
-           DES_DECRYPT);
-}
-
-/* Blowfish */
-static void
-blowfish_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       BF_set_key(&cc->u.bf.key, keylen, (u_char *)key);
-}
-static void
-blowfish_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
-{
-       if (iv == NULL)
-               memset(cc->u.bf.iv, 0, 8);
-       else
-               memcpy(cc->u.bf.iv, (char *)iv, 8);
-}
-static void
-blowfish_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
-     u_int len)
-{
-       BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv,
-           BF_ENCRYPT);
-}
-static void
-blowfish_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
-     u_int len)
-{
-       BF_cbc_encrypt((void *)src, dest, len, &cc->u.bf.key, cc->u.bf.iv,
-           BF_DECRYPT);
-}
-
-/*
- * SSH1 uses a variation on Blowfish, all bytes must be swapped before
- * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
- */
-static void
-swap_bytes(const u_char *src, u_char *dst, int n)
-{
-       char c[4];
-
-       /* Process 4 bytes every lap. */
-       for (n = n / 4; n > 0; n--) {
-               c[3] = *src++;
-               c[2] = *src++;
-               c[1] = *src++;
-               c[0] = *src++;
-
-               *dst++ = c[0];
-               *dst++ = c[1];
-               *dst++ = c[2];
-               *dst++ = c[3];
-       }
-}
-
-static void
-blowfish_ssh1_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
-    u_int len)
-{
-       swap_bytes(src, dest, len);
-       BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv,
-           BF_ENCRYPT);
-       swap_bytes(dest, dest, len);
-}
-static void
-blowfish_ssh1_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
-    u_int len)
-{
-       swap_bytes(src, dest, len);
-       BF_cbc_encrypt((void *)dest, dest, len, &cc->u.bf.key, cc->u.bf.iv,
-           BF_DECRYPT);
-       swap_bytes(dest, dest, len);
-}
-
-/* alleged rc4 */
-static void
-arcfour_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       RC4_set_key(&cc->u.rc4, keylen, (u_char *)key);
-}
-static void
-arcfour_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       RC4(&cc->u.rc4, len, (u_char *)src, dest);
-}
-
-/* CAST */
-static void
-cast_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       CAST_set_key(&cc->u.cast.key, keylen, (u_char *) key);
-}
-static void
-cast_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
-{
-       if (iv == NULL)
-               fatal("no IV for %s.", cc->cipher->name);
-       memcpy(cc->u.cast.iv, (char *)iv, 8);
-}
-static void
-cast_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv,
-           CAST_ENCRYPT);
-}
-static void
-cast_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
-{
-       CAST_cbc_encrypt(src, dest, len, &cc->u.cast.key, cc->u.cast.iv,
-           CAST_DECRYPT);
-}
-
-/* RIJNDAEL */
+/*--*/
 
-#define RIJNDAEL_BLOCKSIZE 16
-static void
-rijndael_setkey(CipherContext *cc, const u_char *key, u_int keylen)
-{
-       rijndael_set_key(&cc->u.rijndael.enc, (char *)key, 8*keylen, 1);
-       rijndael_set_key(&cc->u.rijndael.dec, (char *)key, 8*keylen, 0);
-}
-static void
-rijndael_setiv(CipherContext *cc, const u_char *iv, u_int ivlen)
-{
-       if (iv == NULL || ivlen != RIJNDAEL_BLOCKSIZE) 
-               fatal("bad/no IV for %s.", cc->cipher->name);
-       memcpy(cc->u.rijndael.iv, iv, RIJNDAEL_BLOCKSIZE);
-}
-static void
-rijndael_cbc_encrypt(CipherContext *cc, u_char *dest, const u_char *src,
-    u_int len)
+u_int  
+cipher_blocksize(Cipher *c)
 {
-       rijndael_ctx *ctx = &cc->u.rijndael.enc;
-       u_char *iv = cc->u.rijndael.iv;
-       u_char in[RIJNDAEL_BLOCKSIZE];
-       u_char *cprev, *cnow, *plain;
-       int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
-
-       if (len == 0)
-               return;
-       if (len % RIJNDAEL_BLOCKSIZE)
-               fatal("rijndael_cbc_encrypt: bad len %d", len);
-       cnow  = dest;
-       plain = (u_char *) src;
-       cprev = iv;
-       for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
-           cnow+=RIJNDAEL_BLOCKSIZE) {
-               for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
-                       in[j] = plain[j] ^ cprev[j];
-               rijndael_encrypt(ctx, in, cnow);
-               cprev = cnow;
-       }
-       memcpy(iv, cprev, RIJNDAEL_BLOCKSIZE);
+       return (c->block_size);
 }
-static void
-rijndael_cbc_decrypt(CipherContext *cc, u_char *dest, const u_char *src,
-    u_int len)
+u_int  
+cipher_keylen(Cipher *c)
 {
-       rijndael_ctx *ctx = &cc->u.rijndael.dec;
-       u_char *iv = cc->u.rijndael.iv;
-       u_char ivsaved[RIJNDAEL_BLOCKSIZE];
-       u_char *cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
-       u_char *plain = dest+len-RIJNDAEL_BLOCKSIZE;
-       u_char *ivp;
-       int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
-
-       if (len == 0)
-               return;
-       if (len % RIJNDAEL_BLOCKSIZE)
-               fatal("rijndael_cbc_decrypt: bad len %d", len);
-       memcpy(ivsaved, cnow, RIJNDAEL_BLOCKSIZE);
-       for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
-           plain-=RIJNDAEL_BLOCKSIZE) {
-               rijndael_decrypt(ctx, cnow, plain);
-               ivp = (i == 1) ? iv : cnow-RIJNDAEL_BLOCKSIZE;
-               for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
-                       plain[j] ^= ivp[j];
-       }
-       memcpy(iv, ivsaved, RIJNDAEL_BLOCKSIZE);
+       return (c->key_len);
 }
 
-Cipher ciphers[] = {
-       { "none",
-               SSH_CIPHER_NONE, 8, 0,
-               none_setkey, none_setiv,
-               none_crypt, none_crypt },
-       { "des",
-               SSH_CIPHER_DES, 8, 8,
-               des_ssh1_setkey, des_ssh1_setiv,
-               des_ssh1_encrypt, des_ssh1_decrypt },
-       { "3des",
-               SSH_CIPHER_3DES, 8, 16,
-               des3_ssh1_setkey, des3_setiv,
-               des3_ssh1_encrypt, des3_ssh1_decrypt },
-       { "blowfish",
-               SSH_CIPHER_BLOWFISH, 8, 16,
-               blowfish_setkey, blowfish_setiv,
-               blowfish_ssh1_encrypt, blowfish_ssh1_decrypt },
-
-       { "3des-cbc",
-               SSH_CIPHER_SSH2, 8, 24,
-               des3_setkey, des3_setiv,
-               des3_cbc_encrypt, des3_cbc_decrypt },
-       { "blowfish-cbc",
-               SSH_CIPHER_SSH2, 8, 16,
-               blowfish_setkey, blowfish_setiv,
-               blowfish_cbc_encrypt, blowfish_cbc_decrypt },
-       { "cast128-cbc",
-               SSH_CIPHER_SSH2, 8, 16,
-               cast_setkey, cast_setiv,
-               cast_cbc_encrypt, cast_cbc_decrypt },
-       { "arcfour",
-               SSH_CIPHER_SSH2, 8, 16,
-               arcfour_setkey, none_setiv,
-               arcfour_crypt, arcfour_crypt },
-       { "aes128-cbc",
-               SSH_CIPHER_SSH2, 16, 16,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { "aes192-cbc",
-               SSH_CIPHER_SSH2, 16, 24,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { "aes256-cbc",
-               SSH_CIPHER_SSH2, 16, 32,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { "rijndael128-cbc",
-               SSH_CIPHER_SSH2, 16, 16,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { "rijndael192-cbc",
-               SSH_CIPHER_SSH2, 16, 24,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { "rijndael256-cbc",
-               SSH_CIPHER_SSH2, 16, 32,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { "rijndael-cbc@lysator.liu.se",
-               SSH_CIPHER_SSH2, 16, 32,
-               rijndael_setkey, rijndael_setiv,
-               rijndael_cbc_encrypt, rijndael_cbc_decrypt },
-       { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL, NULL, NULL, NULL }
-};
-
-/*--*/
-
 u_int
 cipher_mask_ssh1(int client)
 {
        u_int mask = 0;
-       mask |= 1 << SSH_CIPHER_3DES;           /* Mandatory */
+       mask |= 1 << SSH_CIPHER_3DES;           /* Mandatory */
        mask |= 1 << SSH_CIPHER_BLOWFISH;
        if (client) {
                mask |= 1 << SSH_CIPHER_DES;
@@ -457,7 +128,7 @@ ciphers_valid(const char *names)
                return 0;
        ciphers = cp = xstrdup(names);
        for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
-            (p = strsep(&cp, CIPHER_SEP))) {
+           (p = strsep(&cp, CIPHER_SEP))) {
                c = cipher_by_name(p);
                if (c == NULL || c->number != SSH_CIPHER_SSH2) {
                        debug("bad cipher %s [%s]", p, names);
@@ -496,8 +167,24 @@ cipher_name(int id)
 
 void
 cipher_init(CipherContext *cc, Cipher *cipher,
-    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen)
+    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
+    int encrypt)
 {
+       static int dowarn = 1;
+       const EVP_CIPHER *type;
+       int klen;
+
+       if (cipher->number == SSH_CIPHER_DES) {
+               if (dowarn) {
+                       error("Warning: use of DES is strongly discouraged "
+                           "due to cryptographic weaknesses");
+                       dowarn = 0;
+               }
+               if (keylen > 8)
+                       keylen = 8;
+       }
+       cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
+
        if (keylen < cipher->key_len)
                fatal("cipher_init: key length %d is insufficient for %s.",
                    keylen, cipher->name);
@@ -505,24 +192,40 @@ cipher_init(CipherContext *cc, Cipher *cipher,
                fatal("cipher_init: iv length %d is insufficient for %s.",
                    ivlen, cipher->name);
        cc->cipher = cipher;
-       cipher->setkey(cc, key, keylen);
-       cipher->setiv(cc, iv, ivlen);
+
+       type = (*cipher->evptype)();
+
+       EVP_CIPHER_CTX_init(&cc->evp);
+       if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
+           (encrypt == CIPHER_ENCRYPT)) == 0)
+               fatal("cipher_init: EVP_CipherInit failed for %s",
+                   cipher->name);
+       klen = EVP_CIPHER_CTX_key_length(&cc->evp);
+       if (klen > 0 && keylen != klen) {
+               debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
+               if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
+                       fatal("cipher_init: set keylen failed (%d -> %d)",
+                           klen, keylen);
+       }
+       if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
+               fatal("cipher_init: EVP_CipherInit: set key failed for %s",
+                   cipher->name);
 }
 
 void
-cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
+cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
 {
        if (len % cc->cipher->block_size)
                fatal("cipher_encrypt: bad plaintext length %d", len);
-       cc->cipher->encrypt(cc, dest, src, len);
+       if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
+               fatal("evp_crypt: EVP_Cipher failed");
 }
 
 void
-cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
+cipher_cleanup(CipherContext *cc)
 {
-       if (len % cc->cipher->block_size)
-               fatal("cipher_decrypt: bad ciphertext length %d", len);
-       cc->cipher->decrypt(cc, dest, src, len);
+       if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
+               error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
 }
 
 /*
@@ -532,7 +235,7 @@ cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
 
 void
 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
-    const char *passphrase)
+    const char *passphrase, int encrypt)
 {
        MD5_CTX md;
        u_char digest[16];
@@ -541,8 +244,257 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher,
        MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
        MD5_Final(digest, &md);
 
-       cipher_init(cc, cipher, digest, 16, NULL, 0);
+       cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
 
        memset(digest, 0, sizeof(digest));
        memset(&md, 0, sizeof(md));
 }
+
+/* Implementations for other non-EVP ciphers */
+
+/*
+ * This is used by SSH1:
+ *
+ * What kind of triple DES are these 2 routines?
+ *
+ * Why is there a redundant initialization vector?
+ *
+ * If only iv3 was used, then, this would till effect have been
+ * outer-cbc. However, there is also a private iv1 == iv2 which
+ * perhaps makes differential analysis easier. On the other hand, the
+ * private iv1 probably makes the CRC-32 attack ineffective. This is a
+ * result of that there is no longer any known iv1 to use when
+ * choosing the X block.
+ */
+struct ssh1_3des_ctx
+{
+       EVP_CIPHER_CTX  k1, k2, k3;
+};
+static int
+ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
+    int enc)
+{
+       struct ssh1_3des_ctx *c;
+       u_char *k1, *k2, *k3;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+               c = xmalloc(sizeof(*c));
+               EVP_CIPHER_CTX_set_app_data(ctx, c);
+       }
+       if (key == NULL)
+               return (1);
+       if (enc == -1)
+               enc = ctx->encrypt;
+       k1 = k2 = k3 = (u_char *) key;
+       k2 += 8;
+       if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
+               if (enc)
+                       k3 += 16;
+               else
+                       k1 += 16;
+       }
+       EVP_CIPHER_CTX_init(&c->k1);
+       EVP_CIPHER_CTX_init(&c->k2);
+       EVP_CIPHER_CTX_init(&c->k3);
+       if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
+           EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
+           EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
+               memset(c, 0, sizeof(*c));
+               xfree(c);
+               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+               return (0);
+       }
+       return (1);
+}
+static int
+ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
+{
+       struct ssh1_3des_ctx *c;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+               error("ssh1_3des_cbc: no context");
+               return (0);
+       }
+       if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
+           EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
+           EVP_Cipher(&c->k3, dest, dest, len) == 0)
+               return (0);
+       return (1);
+}
+static int
+ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
+{
+       struct ssh1_3des_ctx *c;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+               memset(c, 0, sizeof(*c));
+               xfree(c);
+               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+       }
+       return (1);
+}
+static EVP_CIPHER *
+evp_ssh1_3des(void)
+{
+       static EVP_CIPHER ssh1_3des;
+
+       memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
+       ssh1_3des.nid = NID_undef;
+       ssh1_3des.block_size = 8;
+       ssh1_3des.iv_len = 0;
+       ssh1_3des.key_len = 16;
+       ssh1_3des.init = ssh1_3des_init;
+       ssh1_3des.cleanup = ssh1_3des_cleanup;
+       ssh1_3des.do_cipher = ssh1_3des_cbc;
+       ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
+       return (&ssh1_3des);
+}
+
+/*
+ * SSH1 uses a variation on Blowfish, all bytes must be swapped before
+ * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
+ */
+static void
+swap_bytes(const u_char *src, u_char *dst, int n)
+{
+       u_char c[4];
+
+       /* Process 4 bytes every lap. */
+       for (n = n / 4; n > 0; n--) {
+               c[3] = *src++;
+               c[2] = *src++;
+               c[1] = *src++;
+               c[0] = *src++;
+
+               *dst++ = c[0];
+               *dst++ = c[1];
+               *dst++ = c[2];
+               *dst++ = c[3];
+       }
+}
+static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
+static int
+bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
+{
+       int ret;
+
+       swap_bytes(in, out, len);
+       ret = (*orig_bf)(ctx, out, out, len);
+       swap_bytes(out, out, len);
+       return (ret);
+}
+static EVP_CIPHER *
+evp_ssh1_bf(void)
+{
+       static EVP_CIPHER ssh1_bf;
+
+       memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
+       orig_bf = ssh1_bf.do_cipher;
+       ssh1_bf.nid = NID_undef;
+       ssh1_bf.do_cipher = bf_ssh1_cipher;
+       ssh1_bf.key_len = 32;
+       return (&ssh1_bf);
+}
+
+/* RIJNDAEL */
+#define RIJNDAEL_BLOCKSIZE 16
+struct ssh_rijndael_ctx
+{
+       rijndael_ctx    r_ctx;
+       u_char          r_iv[RIJNDAEL_BLOCKSIZE];
+};
+
+static int
+ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
+    int enc)
+{
+       struct ssh_rijndael_ctx *c;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+               c = xmalloc(sizeof(*c));
+               EVP_CIPHER_CTX_set_app_data(ctx, c);
+       }
+       if (key != NULL) {
+               if (enc == -1)
+                       enc = ctx->encrypt;
+               rijndael_set_key(&c->r_ctx, (u_char *)key,
+                   8*EVP_CIPHER_CTX_key_length(ctx), enc);
+       }
+       if (iv != NULL)
+               memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
+       return (1);
+}
+static int
+ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
+    u_int len)
+{
+       struct ssh_rijndael_ctx *c;
+       u_char buf[RIJNDAEL_BLOCKSIZE];
+       u_char *cprev, *cnow, *plain, *ivp;
+       int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
+
+       if (len == 0)
+               return (1);
+       if (len % RIJNDAEL_BLOCKSIZE)
+               fatal("ssh_rijndael_cbc: bad len %d", len);
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+               error("ssh_rijndael_cbc: no context");
+               return (0);
+       }
+       if (ctx->encrypt) {
+               cnow  = dest;
+               plain = (u_char *)src;
+               cprev = c->r_iv;
+               for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
+                   cnow+=RIJNDAEL_BLOCKSIZE) {
+                       for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
+                               buf[j] = plain[j] ^ cprev[j];
+                       rijndael_encrypt(&c->r_ctx, buf, cnow);
+                       cprev = cnow;
+               }
+               memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
+       } else {
+               cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
+               plain = dest+len-RIJNDAEL_BLOCKSIZE;
+
+               memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
+               for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
+                   plain-=RIJNDAEL_BLOCKSIZE) {
+                       rijndael_decrypt(&c->r_ctx, cnow, plain);
+                       ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
+                       for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
+                               plain[j] ^= ivp[j];
+               }
+               memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
+       }
+       return (1);
+}
+static int
+ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
+{
+       struct ssh_rijndael_ctx *c;
+
+       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+               memset(c, 0, sizeof(*c));
+               xfree(c);
+               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+       }
+       return (1);
+}
+static EVP_CIPHER *
+evp_rijndael(void)
+{
+       static EVP_CIPHER rijndal_cbc;
+
+       memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
+       rijndal_cbc.nid = NID_undef;
+       rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
+       rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
+       rijndal_cbc.key_len = 16;
+       rijndal_cbc.init = ssh_rijndael_init;
+       rijndal_cbc.cleanup = ssh_rijndael_cleanup;
+       rijndal_cbc.do_cipher = ssh_rijndael_cbc;
+       rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
+           EVP_CIPH_ALWAYS_CALL_INIT;
+       return (&rijndal_cbc);
+}
index 4533f5e4c20fd40c6b58ade84f33b089cba0a0a1..b3b0303c7f6079522b585d5d257462cdb6d39f04 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: cipher.h,v 1.32 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* RCSID("$OpenBSD: cipher.h,v 1.29 2001/08/23 11:31:59 markus Exp $"); */
-
 #ifndef CIPHER_H
 #define CIPHER_H
 
-#include <openssl/des.h>
-#include <openssl/blowfish.h>
-#include <openssl/rc4.h>
-#include <openssl/cast.h>
-#include "rijndael.h"
+#include <openssl/evp.h>
 /*
  * Cipher types for SSH-1.  New types can be added, but old types should not
  * be removed for compatibility.  The maximum allowed value is 31.
 #define SSH_CIPHER_RESERVED    7
 #define SSH_CIPHER_MAX         31
 
+#define CIPHER_ENCRYPT         1
+#define CIPHER_DECRYPT         0
+
 typedef struct Cipher Cipher;
 typedef struct CipherContext CipherContext;
 
+struct Cipher;
 struct CipherContext {
-       union {
-               struct {
-                       des_key_schedule key;
-                       des_cblock iv;
-               }       des;
-               struct {
-                       des_key_schedule key1;
-                       des_key_schedule key2;
-                       des_key_schedule key3;
-                       des_cblock iv1;
-                       des_cblock iv2;
-                       des_cblock iv3;
-               }       des3;
-               struct {
-                       struct bf_key_st key;
-                       u_char iv[8];
-               }       bf;
-               struct {
-                       CAST_KEY key;
-                       u_char iv[8];
-               } cast;
-               struct {
-                       u_char iv[16];
-                       rijndael_ctx enc;
-                       rijndael_ctx dec;
-               } rijndael;
-               RC4_KEY rc4;
-       }       u;
+       int     plaintext;
+       EVP_CIPHER_CTX evp;
        Cipher *cipher;
 };
-struct Cipher {
-       char    *name;
-       int     number;         /* for ssh1 only */
-       u_int   block_size;
-       u_int   key_len;
-       void    (*setkey)(CipherContext *, const u_char *, u_int);
-       void    (*setiv)(CipherContext *, const u_char *, u_int);
-       void    (*encrypt)(CipherContext *, u_char *, const u_char *, u_int);
-       void    (*decrypt)(CipherContext *, u_char *, const u_char *, u_int);
-};
 
 u_int   cipher_mask_ssh1(int);
 Cipher *cipher_by_name(const char *);
@@ -111,9 +75,10 @@ int  cipher_number(const char *);
 char   *cipher_name(int);
 int     ciphers_valid(const char *);
 void    cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
-    const u_char *, u_int);
-void    cipher_encrypt(CipherContext *, u_char *, const u_char *, u_int);
-void    cipher_decrypt(CipherContext *, u_char *, const u_char *, u_int);
-void    cipher_set_key_string(CipherContext *, Cipher *, const char *);
-
+    const u_char *, u_int, int);
+void    cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
+void    cipher_cleanup(CipherContext *);
+void    cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
+u_int   cipher_blocksize(Cipher *);
+u_int   cipher_keylen(Cipher *);
 #endif                         /* CIPHER_H */
index cbcb1d1998a26dbebd2f28d3b61277ba12097a6b..65a6682a68e194b7db5c171745316a0a40c8c30c 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.87 2001/11/09 18:59:23 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.96 2002/02/06 14:55:15 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -101,8 +101,8 @@ extern char *host;
  * window size to be sent to the server a little later.  This is volatile
  * because this is updated in a signal handler.
  */
-static volatile int received_window_change_signal = 0;
-static volatile int received_signal = 0;
+static volatile sig_atomic_t received_window_change_signal = 0;
+static volatile sig_atomic_t received_signal = 0;
 
 /* Flag indicating whether the user\'s terminal is in non-blocking mode. */
 static int in_non_blocking_mode = 0;
@@ -254,7 +254,7 @@ client_make_packets_from_stdin_data(void)
 
        /* Send buffered stdin data to the server. */
        while (buffer_len(&stdin_buffer) > 0 &&
-              packet_not_very_much_data_to_write()) {
+           packet_not_very_much_data_to_write()) {
                len = buffer_len(&stdin_buffer);
                /* Keep the packets at reasonable size. */
                if (len > packet_get_maxsize())
@@ -417,9 +417,9 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
        /* Check if the window size has changed. */
        if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 &&
            (oldws.ws_row != newws.ws_row ||
-            oldws.ws_col != newws.ws_col ||
-            oldws.ws_xpixel != newws.ws_xpixel ||
-            oldws.ws_ypixel != newws.ws_ypixel))
+           oldws.ws_col != newws.ws_col ||
+           oldws.ws_xpixel != newws.ws_xpixel ||
+           oldws.ws_ypixel != newws.ws_ypixel))
                received_window_change_signal = 1;
 
        /* OK, we have been continued by the user. Reinitialize buffers. */
@@ -949,7 +949,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
        if (received_signal) {
                if (in_non_blocking_mode)       /* XXX */
                        leave_non_blocking();
-               fatal("Killed by signal %d.", received_signal);
+               fatal("Killed by signal %d.", (int) received_signal);
        }
 
        /*
@@ -994,11 +994,11 @@ 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);
+           stdin_bytes, stdout_bytes, stderr_bytes, 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);
+                   stdin_bytes / total_time, stdout_bytes / total_time,
+                   stderr_bytes / total_time);
 
        /* Return the exit status of the program. */
        debug("Exit status %d", exit_status);
@@ -1008,30 +1008,30 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
 /*********/
 
 static void
-client_input_stdout_data(int type, int plen, void *ctxt)
+client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
 {
        u_int data_len;
        char *data = packet_get_string(&data_len);
-       packet_integrity_check(plen, 4 + data_len, type);
+       packet_check_eom();
        buffer_append(&stdout_buffer, data, data_len);
        memset(data, 0, data_len);
        xfree(data);
 }
 static void
-client_input_stderr_data(int type, int plen, void *ctxt)
+client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
 {
        u_int data_len;
        char *data = packet_get_string(&data_len);
-       packet_integrity_check(plen, 4 + data_len, type);
+       packet_check_eom();
        buffer_append(&stderr_buffer, data, data_len);
        memset(data, 0, data_len);
        xfree(data);
 }
 static void
-client_input_exit_status(int type, int plen, void *ctxt)
+client_input_exit_status(int type, u_int32_t seq, void *ctxt)
 {
-       packet_integrity_check(plen, 4, type);
        exit_status = packet_get_int();
+       packet_check_eom();
        /* Acknowledge the exit. */
        packet_start(SSH_CMSG_EXIT_CONFIRMATION);
        packet_send();
@@ -1057,7 +1057,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
        listen_port = packet_get_int();
        originator_address = packet_get_string(NULL);
        originator_port = packet_get_int();
-       packet_done();
+       packet_check_eom();
 
        debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",
            listen_address, listen_port, originator_address, originator_port);
@@ -1072,10 +1072,6 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
            SSH_CHANNEL_CONNECTING, sock, sock, -1,
            CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
            xstrdup(originator_address), 1);
-       if (c == NULL) {
-               error("client_request_forwarded_tcpip: channel_new failed");
-               close(sock);
-       }
        xfree(originator_address);
        xfree(listen_address);
        return c;
@@ -1101,7 +1097,7 @@ client_request_x11(const char *request_type, int rchan)
        } else {
                originator_port = packet_get_int();
        }
-       packet_done();
+       packet_check_eom();
        /* XXX check permission */
        debug("client_request_x11: request from %s %d", originator,
            originator_port);
@@ -1113,10 +1109,6 @@ client_request_x11(const char *request_type, int rchan)
            SSH_CHANNEL_X11_OPEN, sock, sock, -1,
            CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
            xstrdup("x11"), 1);
-       if (c == NULL) {
-               error("client_request_x11: channel_new failed");
-               close(sock);
-       }
        c->force_drain = 1;
        return c;
 }
@@ -1139,17 +1131,13 @@ client_request_agent(const char *request_type, int rchan)
            SSH_CHANNEL_OPEN, sock, sock, -1,
            CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
            xstrdup("authentication agent connection"), 1);
-       if (c == NULL) {
-               error("client_request_agent: channel_new failed");
-               close(sock);
-       }
        c->force_drain = 1;
        return c;
 }
 
 /* XXXX move to generic input handler */
 static void
-client_input_channel_open(int type, int plen, void *ctxt)
+client_input_channel_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
        char *ctype;
@@ -1201,7 +1189,7 @@ client_input_channel_open(int type, int plen, void *ctxt)
        xfree(ctype);
 }
 static void
-client_input_channel_req(int type, int plen, void *ctxt)
+client_input_channel_req(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
        int id, reply, success = 0;
@@ -1226,7 +1214,7 @@ client_input_channel_req(int type, int plen, void *ctxt)
        } else if (strcmp(rtype, "exit-status") == 0) {
                success = 1;
                exit_status = packet_get_int();
-               packet_done();
+               packet_check_eom();
        }
        if (reply) {
                packet_start(success ?
@@ -1236,6 +1224,24 @@ client_input_channel_req(int type, int plen, void *ctxt)
        }
        xfree(rtype);
 }
+static void
+client_input_global_request(int type, u_int32_t seq, void *ctxt)
+{
+       char *rtype;
+       int want_reply;
+       int success = 0;
+
+       rtype = packet_get_string(NULL);
+       want_reply = packet_get_char();
+       debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply);
+       if (want_reply) {
+               packet_start(success ?
+                   SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
+               packet_send();
+               packet_write_wait();
+       }
+       xfree(rtype);
+}
 
 static void
 client_init_dispatch_20(void)
@@ -1250,6 +1256,7 @@ 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_GLOBAL_REQUEST, &client_input_global_request);
 
        /* rekeying */
        dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
index 1d3e970561ecaad195e103a1e1a3a79f8c9e36ba..74d5ed85ed6bd986dc02172c3dbadc194deac6bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: compat.c,v 1.53 2001/09/20 13:50:40 markus Exp $");
-
-#ifdef HAVE_LIBPCRE
-#  include <pcreposix.h>
-#else /* Use native regex libraries */
-#  ifdef HAVE_REGEX_H
-#    include <regex.h>
-#  else
-#    include "openbsd-compat/fake-regex.h"
-#  endif
-#endif /* HAVE_LIBPCRE */
+RCSID("$OpenBSD: compat.c,v 1.61 2002/03/06 00:24:39 markus Exp $");
 
+#include "buffer.h"
 #include "packet.h"
 #include "xmalloc.h"
 #include "compat.h"
 #include "log.h"
+#include "match.h"
 
 int compat13 = 0;
 int compat20 = 0;
@@ -60,86 +52,97 @@ enable_compat13(void)
 void
 compat_datafellows(const char *version)
 {
-       int i, ret;
-       char ebuf[1024];
-       regex_t reg;
+       int i;
        static struct {
                char    *pat;
                int     bugs;
        } check[] = {
-               { "^OpenSSH[-_]2\\.[012]",
-                                       SSH_OLD_SESSIONID|SSH_BUG_BANNER|
+               { "OpenSSH-2.0*,"
+                 "OpenSSH-2.1*,"
+                 "OpenSSH_2.1*,"
+                 "OpenSSH_2.2*",       SSH_OLD_SESSIONID|SSH_BUG_BANNER|
                                        SSH_OLD_DHGEX|SSH_BUG_NOREKEY },
-               { "^OpenSSH_2\\.3\\.0", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
+               { "OpenSSH_2.3.0*",     SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
                                        SSH_OLD_DHGEX|SSH_BUG_NOREKEY},
-               { "^OpenSSH_2\\.3\\.",  SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
+               { "OpenSSH_2.3.*",      SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
                                        SSH_BUG_NOREKEY},
-               { "^OpenSSH_2\\.5\\.[01]p1",
+               { "OpenSSH_2.5.0p1*,"
+                 "OpenSSH_2.5.1p1*",
                                        SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
                                        SSH_BUG_NOREKEY },
-               { "^OpenSSH_2\\.5\\.[012]",
-                                       SSH_OLD_DHGEX|SSH_BUG_NOREKEY },
-               { "^OpenSSH_2\\.5\\.3",
-                                       SSH_BUG_NOREKEY },
-               { "^OpenSSH",           0 },
-               { "MindTerm",           0 },
-               { "^2\\.1\\.0",         SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
+               { "OpenSSH_2.5.0*,"
+                 "OpenSSH_2.5.1*,"
+                 "OpenSSH_2.5.2*",     SSH_OLD_DHGEX|SSH_BUG_NOREKEY },
+               { "OpenSSH_2.5.3*",     SSH_BUG_NOREKEY },
+               { "Sun_SSH_1.0*",       SSH_BUG_NOREKEY },
+               { "OpenSSH*",           0 },
+               { "*MindTerm*",         0 },
+               { "2.1.0*",             SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
                                        SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
                                        SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
-               { "^2\\.1 ",            SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
+               { "2.1 *",              SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
                                        SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
                                        SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
-               { "^2\\.0\\.1[3-9]",    SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
+               { "2.0.13*,"
+                 "2.0.14*,"
+                 "2.0.15*,"
+                 "2.0.16*,"
+                 "2.0.17*,"
+                 "2.0.18*,"
+                 "2.0.19*",            SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
                                        SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
                                        SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
                                        SSH_BUG_PKOK|SSH_BUG_RSASIGMD5|
                                        SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE|
                                        SSH_BUG_DUMMYCHAN },
-               { "^2\\.0\\.1[1-2]",    SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
+               { "2.0.11*,"
+                 "2.0.12*",            SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
                                        SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
                                        SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
                                        SSH_BUG_PKAUTH|SSH_BUG_PKOK|
                                        SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|
                                        SSH_BUG_DUMMYCHAN },
-               { "^2\\.0\\.",          SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
+               { "2.0.*",              SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
                                        SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
                                        SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
                                        SSH_BUG_PKAUTH|SSH_BUG_PKOK|
                                        SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|
                                        SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN },
-               { "^2\\.[23]\\.0",      SSH_BUG_HMAC|SSH_BUG_DEBUG|
+               { "2.2.0*,"
+                 "2.3.0*",             SSH_BUG_HMAC|SSH_BUG_DEBUG|
                                        SSH_BUG_RSASIGMD5 },
-               { "^2\\.3\\.",          SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5 },
-               { "^2\\.[2-9]\\.",      SSH_BUG_DEBUG },
-               { "^3\\.0\\.",          SSH_BUG_DEBUG },
-               { "^2\\.4$",            SSH_OLD_SESSIONID },    /* Van Dyke */
-               { "^3\\.0 SecureCRT",   SSH_OLD_SESSIONID },
-               { "^1\\.7 SecureFX",    SSH_OLD_SESSIONID },
-               { "^1\\.2\\.1[89]",     SSH_BUG_IGNOREMSG },
-               { "^1\\.2\\.2[012]",    SSH_BUG_IGNOREMSG },
-               { "^1\\.3\\.2",         SSH_BUG_IGNOREMSG },    /* f-secure */
-               { "^SSH Compatible Server",                     /* Netscreen */
+               { "2.3.*",              SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5 },
+               { "2.4",                SSH_OLD_SESSIONID },    /* Van Dyke */
+               { "2.*",                SSH_BUG_DEBUG },
+               { "3.0.*",              SSH_BUG_DEBUG },
+               { "3.0 SecureCRT*",     SSH_OLD_SESSIONID },
+               { "1.7 SecureFX*",      SSH_OLD_SESSIONID },
+               { "1.2.18*,"
+                 "1.2.19*,"
+                 "1.2.20*,"
+                 "1.2.21*,"
+                 "1.2.22*",            SSH_BUG_IGNOREMSG },
+               { "1.3.2*",             SSH_BUG_IGNOREMSG },    /* f-secure */
+               { "*SSH Compatible Server*",                    /* Netscreen */
                                        SSH_BUG_PASSWORDPAD },
-               { "^OSU_0",             SSH_BUG_PASSWORDPAD },
-               { "^OSU_1\\.[0-4]",     SSH_BUG_PASSWORDPAD },
-               { "^OSU_1\\.5alpha[1-3]",
-                                       SSH_BUG_PASSWORDPAD },
-               { "^SSH_Version_Mapper",
+               { "*OSU_0*,"
+                 "OSU_1.0*,"
+                 "OSU_1.1*,"
+                 "OSU_1.2*,"
+                 "OSU_1.3*,"
+                 "OSU_1.4*,"
+                 "OSU_1.5alpha1*,"
+                 "OSU_1.5alpha2*,"
+                 "OSU_1.5alpha3*",     SSH_BUG_PASSWORDPAD },
+               { "*SSH_Version_Mapper*",
                                        SSH_BUG_SCANNER },
                { NULL,                 0 }
        };
+
        /* process table, return first match */
        for (i = 0; check[i].pat; i++) {
-               ret = regcomp(&reg, check[i].pat, REG_EXTENDED|REG_NOSUB);
-               if (ret != 0) {
-                       regerror(ret, &reg, ebuf, sizeof(ebuf));
-                       ebuf[sizeof(ebuf)-1] = '\0';
-                       error("regerror: %s", ebuf);
-                       continue;
-               }
-               ret = regexec(&reg, version, 0, NULL, 0);
-               regfree(&reg);
-               if (ret == 0) {
+               if (match_pattern_list(version, check[i].pat,
+                   strlen(check[i].pat), 0) == 1) {
                        debug("match: %s pat %s", version, check[i].pat);
                        datafellows = check[i].bugs;
                        return;
@@ -159,7 +162,7 @@ proto_spec(const char *spec)
                return ret;
        q = s = xstrdup(spec);
        for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
-               switch(atoi(p)) {
+               switch (atoi(p)) {
                case 1:
                        if (ret == SSH_PROTO_UNKNOWN)
                                ret |= SSH_PROTO_1_PREFERRED;
@@ -180,24 +183,25 @@ proto_spec(const char *spec)
 char *
 compat_cipher_proposal(char *cipher_prop)
 {
+       Buffer b;
        char *orig_prop, *fix_ciphers;
        char *cp, *tmp;
-       size_t len;
 
        if (!(datafellows & SSH_BUG_BIGENDIANAES))
                return(cipher_prop);
 
-       len = strlen(cipher_prop) + 1;
-       fix_ciphers = xmalloc(len);
-       *fix_ciphers = '\0';
+       buffer_init(&b);
        tmp = orig_prop = xstrdup(cipher_prop);
-       while((cp = strsep(&tmp, ",")) != NULL) {
-               if (strncmp(cp, "aes", 3) && strncmp(cp, "rijndael", 8)) {
-                       if (*fix_ciphers)
-                               strlcat(fix_ciphers, ",", len);
-                       strlcat(fix_ciphers, cp, len);
+       while ((cp = strsep(&tmp, ",")) != NULL) {
+               if (strncmp(cp, "aes", 3) != 0) {
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, cp, strlen(cp));
                }
        }
+       buffer_append(&b, "\0", 1);
+       fix_ciphers = xstrdup(buffer_ptr(&b));
+       buffer_free(&b);
        xfree(orig_prop);
        debug2("Original cipher proposal: %s", cipher_prop);
        debug2("Compat cipher proposal: %s", fix_ciphers);
index b6609efb030b7440533f4779c0e27827f9cc0a8d..0eeb782e861ad770163dccd1bf9f07d606be4c35 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: compat.h,v 1.30 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -21,7 +23,6 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* RCSID("$OpenBSD: compat.h,v 1.29 2001/09/20 13:50:40 markus Exp $"); */
 
 #ifndef COMPAT_H
 #define COMPAT_H
index a779af6d7b33eede42187e10af23d7c977444010..3badbf452da28c21c6f8f33a29c0b1f6d63b8bd8 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: compress.c,v 1.15 2001/09/27 11:58:16 markus Exp $");
+RCSID("$OpenBSD: compress.c,v 1.17 2001/12/29 21:56:01 stevesk Exp $");
 
 #include "log.h"
 #include "buffer.h"
@@ -55,13 +55,13 @@ void
 buffer_compress_uninit(void)
 {
        debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f",
-             outgoing_stream.total_in, outgoing_stream.total_out,
-             outgoing_stream.total_in == 0 ? 0.0 :
-             (double) outgoing_stream.total_out / outgoing_stream.total_in);
+           outgoing_stream.total_in, outgoing_stream.total_out,
+           outgoing_stream.total_in == 0 ? 0.0 :
+           (double) outgoing_stream.total_out / outgoing_stream.total_in);
        debug("compress incoming: raw data %lu, compressed %lu, factor %.2f",
-             incoming_stream.total_out, incoming_stream.total_in,
-             incoming_stream.total_out == 0 ? 0.0 :
-             (double) incoming_stream.total_in / incoming_stream.total_out);
+           incoming_stream.total_out, incoming_stream.total_in,
+           incoming_stream.total_out == 0 ? 0.0 :
+           (double) incoming_stream.total_in / incoming_stream.total_out);
        if (compress_init_recv_called == 1)
                inflateEnd(&incoming_stream);
        if (compress_init_send_called == 1)
@@ -80,7 +80,7 @@ buffer_compress_uninit(void)
 void
 buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
 {
-       char buf[4096];
+       u_char buf[4096];
        int status;
 
        /* This case is not handled below. */
@@ -88,13 +88,13 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
                return;
 
        /* Input is the contents of the input buffer. */
-       outgoing_stream.next_in = (u_char *) buffer_ptr(input_buffer);
+       outgoing_stream.next_in = buffer_ptr(input_buffer);
        outgoing_stream.avail_in = buffer_len(input_buffer);
 
        /* Loop compressing until deflate() returns with avail_out != 0. */
        do {
                /* Set up fixed-size output buffer. */
-               outgoing_stream.next_out = (u_char *)buf;
+               outgoing_stream.next_out = buf;
                outgoing_stream.avail_out = sizeof(buf);
 
                /* Compress as much data into the buffer as possible. */
@@ -124,15 +124,15 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
 void
 buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
 {
-       char buf[4096];
+       u_char buf[4096];
        int status;
 
-       incoming_stream.next_in = (u_char *) buffer_ptr(input_buffer);
+       incoming_stream.next_in = buffer_ptr(input_buffer);
        incoming_stream.avail_in = buffer_len(input_buffer);
 
        for (;;) {
                /* Set up fixed-size output buffer. */
-               incoming_stream.next_out = (u_char *) buf;
+               incoming_stream.next_out = buf;
                incoming_stream.avail_out = sizeof(buf);
 
                status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
index 2721d450c53648c72d9b2ec5f9c1af6b56b0f256..e364f4bdc58264012443f36f2a4ff95e3879eae1 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: compress.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $   */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: compress.h,v 1.10 2001/06/26 17:27:23 markus Exp $"); */
-
 #ifndef COMPRESS_H
 #define COMPRESS_H
 
index ba661651615d361468d6b54633a37f57662f8bbe..83c544d9703394b5c4211539a34994d3f574554b 100755 (executable)
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-#   Free Software Foundation, Inc.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002 Free Software Foundation, Inc.
 
-timestamp='2001-04-20'
+timestamp='2002-01-30'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -24,8 +24,9 @@ timestamp='2001-04-20'
 # configuration script generated by Autoconf, you may include it under
 # the same distribution terms that you use for the rest of that program.
 
-# Written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>.
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
 #
 # This script attempts to guess a canonical system name similar to
 # config.sub.  If it succeeds, it prints the system name on stdout, and
@@ -52,7 +53,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
@@ -95,25 +96,25 @@ trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
 # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
 # use `HOST_CC' if defined, but it is deprecated.
 
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int dummy(){}" > $dummy.c
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
        for c in cc gcc c89 ; do
-         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1
+         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
          if test $? = 0 ; then
-            CC_FOR_BUILD="$c"; break
-         fi
-       done
-       rm -f $dummy.c $dummy.o $dummy.rel
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $dummy.c $dummy.o $dummy.rel ;
        if test x"$CC_FOR_BUILD" = x ; then
-         CC_FOR_BUILD=no_compiler_found
+         CC_FOR_BUILD=no_compiler_found ;
        fi
        ;;
  ,,*)   CC_FOR_BUILD=$CC ;;
  ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac
+esac'
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
+# (ghazi@noc.rutgers.edu 1994-08-24)
 if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
        PATH=$PATH:/.attbin ; export PATH
 fi
@@ -127,29 +128,29 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
-       # Netbsd (nbsd) targets should (where applicable) match one or
+       # NetBSD (nbsd) targets should (where applicable) match one or
        # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
        # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
        # switched to ELF, *-*-netbsd* would select the old
        # object file format.  This provides both forward
        # compatibility and a consistent mechanism for selecting the
        # object file format.
-       # Determine the machine/vendor (is the vendor relevant).
-       case "${UNAME_MACHINE}" in
-           amiga) machine=m68k-unknown ;;
-           arm32) machine=arm-unknown ;;
-           atari*) machine=m68k-atari ;;
-           sun3*) machine=m68k-sun ;;
-           mac68k) machine=m68k-apple ;;
-           macppc) machine=powerpc-apple ;;
-           hp3[0-9][05]) machine=m68k-hp ;;
-           ibmrt|romp-ibm) machine=romp-ibm ;;
-           *) machine=${UNAME_MACHINE}-unknown ;;
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       UNAME_MACHINE_ARCH=`(uname -p) 2>/dev/null` || \
+           UNAME_MACHINE_ARCH=unknown
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
        esac
        # The Operating System including object format, if it has switched
        # to ELF recently, or will in the future.
-       case "${UNAME_MACHINE}" in
-           i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
                if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
                        | grep __ELF__ >/dev/null
                then
@@ -171,6 +172,45 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
        echo "${machine}-${os}${release}"
        exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
     alpha:OSF1:*:*)
        if test $UNAME_RELEASE = "V4.0"; then
                UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -204,6 +244,7 @@ main:
        jsr \$26,exit
        .end main
 EOF
+       eval $set_cc_for_build
        $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
        if test "$?" = 0 ; then
                case `./$dummy` in
@@ -225,6 +266,9 @@ EOF
                        2-307)
                                UNAME_MACHINE="alphaev67"
                                ;;
+                       2-1307)
+                               UNAME_MACHINE="alphaev68"
+                               ;;
                esac
        fi
        rm -f $dummy.s $dummy
@@ -242,29 +286,11 @@ EOF
     Amiga*:UNIX_System_V:4.0:*)
        echo m68k-unknown-sysv4
        exit 0;;
-    amiga:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
     *:[Aa]miga[Oo][Ss]:*:*)
        echo ${UNAME_MACHINE}-unknown-amigaos
        exit 0 ;;
-    arc64:OpenBSD:*:*)
-       echo mips64el-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    arc:OpenBSD:*:*)
-       echo mipsel-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    hkmips:OpenBSD:*:*)
-       echo mips-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    pmax:OpenBSD:*:*)
-       echo mipsel-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    sgi:OpenBSD:*:*)
-       echo mips-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    wgrisc:OpenBSD:*:*)
-       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
        exit 0 ;;
     *:OS/390:*:*)
        echo i370-ibm-openedition
@@ -328,9 +354,6 @@ EOF
     aushp:SunOS:*:*)
        echo sparc-auspex-sunos${UNAME_RELEASE}
        exit 0 ;;
-    atari*:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -357,18 +380,6 @@ EOF
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
         echo m68k-unknown-mint${UNAME_RELEASE}
         exit 0 ;;
-    sun3*:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    mac68k:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    mvme68k:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
-    mvme88k:OpenBSD:*:*)
-       echo m88k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
     powerpc:machten:*:*)
        echo powerpc-apple-machten${UNAME_RELEASE}
        exit 0 ;;
@@ -385,6 +396,7 @@ EOF
        echo clipper-intergraph-clix${UNAME_RELEASE}
        exit 0 ;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
        sed 's/^        //' << EOF >$dummy.c
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -475,6 +487,7 @@ EOF
        exit 0 ;;
     *:AIX:2:3)
        if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
                sed 's/^                //' << EOF >$dummy.c
                #include <sys/systemcfg.h>
 
@@ -536,10 +549,8 @@ EOF
            9000/31? )            HP_ARCH=m68000 ;;
            9000/[34]?? )         HP_ARCH=m68k ;;
            9000/[678][0-9][0-9])
-              case "${HPUX_REV}" in
-                11.[0-9][0-9])
-                  if [ -x /usr/bin/getconf ]; then
-                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
                     sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
                     case "${sc_cpu_version}" in
                       523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
@@ -548,12 +559,13 @@ EOF
                         case "${sc_kernel_bits}" in
                           32) HP_ARCH="hppa2.0n" ;;
                           64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
                         esac ;;
                     esac
-                  fi ;;
-              esac
-              if [ "${HP_ARCH}" = "" ]; then
-              sed 's/^              //' << EOF >$dummy.c
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
 
               #define _HPUX_SOURCE
               #include <stdlib.h>
@@ -586,10 +598,10 @@ EOF
                   exit (0);
               }
 EOF
-       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
-       if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
-       rm -f $dummy.c $dummy
-       fi ;;
+                   (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
+                   if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+                   rm -f $dummy.c $dummy
+               fi ;;
        esac
        echo ${HP_ARCH}-hp-hpux${HPUX_REV}
        exit 0 ;;
@@ -598,6 +610,7 @@ EOF
        echo ia64-hp-hpux${HPUX_REV}
        exit 0 ;;
     3050*:HI-UX:*:*)
+       eval $set_cc_for_build
        sed 's/^        //' << EOF >$dummy.c
        #include <unistd.h>
        int
@@ -633,7 +646,7 @@ EOF
     9000/8??:4.3bsd:*:*)
        echo hppa1.0-hp-bsd
        exit 0 ;;
-    *9??*:MPE/iX:*:*)
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
        echo hppa1.0-hp-mpeix
        exit 0 ;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
@@ -652,9 +665,6 @@ EOF
     parisc*:Lites*:*:*)
        echo hppa1.1-hp-lites
        exit 0 ;;
-    hppa*:OpenBSD:*:*)
-       echo hppa-unknown-openbsd
-       exit 0 ;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
        echo c1-convex-bsd
         exit 0 ;;
@@ -677,12 +687,13 @@ EOF
        echo xmp-cray-unicos
         exit 0 ;;
     CRAY*Y-MP:*:*:*)
-       echo ymp-cray-unicos${UNAME_RELEASE}
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
        exit 0 ;;
     CRAY*[A-Z]90:*:*:*)
        echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
        | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
        exit 0 ;;
     CRAY*TS:*:*:*)
        echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
@@ -705,9 +716,6 @@ EOF
         FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
         echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
         exit 0 ;;
-    hp300:OpenBSD:*:*)
-       echo m68k-unknown-openbsd${UNAME_RELEASE}
-       exit 0 ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
        echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
        exit 0 ;;
@@ -720,9 +728,6 @@ EOF
     *:FreeBSD:*:*)
        echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
        exit 0 ;;
-    *:OpenBSD:*:*)
-       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
-       exit 0 ;;
     i*:CYGWIN*:*)
        echo ${UNAME_MACHINE}-pc-cygwin
        exit 0 ;;
@@ -732,6 +737,9 @@ EOF
     i*:PW*:*)
        echo ${UNAME_MACHINE}-pc-pw32
        exit 0 ;;
+    x86:Interix*:3*)
+       echo i386-pc-interix3
+       exit 0 ;;
     i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
        # How do we know it's Interix rather than the generic POSIX subsystem?
        # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -763,97 +771,43 @@ EOF
        echo ${UNAME_MACHINE}-unknown-linux-gnu
        exit 0 ;;
     mips:Linux:*:*)
-       cat >$dummy.c <<EOF
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-int main (int argc, char *argv[]) {
-#else
-int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __MIPSEB__
-  printf ("%s-unknown-linux-gnu\n", argv[1]);
-#endif
-#ifdef __MIPSEL__
-  printf ("%sel-unknown-linux-gnu\n", argv[1]);
-#endif
-  return 0;
-}
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) 
+       CPU=mipsel 
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) 
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif 
 EOF
-       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
-       rm -f $dummy.c $dummy
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       rm -f $dummy.c
+       test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
        ;;
     ppc:Linux:*:*)
-       # Determine Lib Version
-       cat >$dummy.c <<EOF
-#include <features.h>
-#if defined(__GLIBC__)
-extern char __libc_version[];
-extern char __libc_release[];
-#endif
-main(argc, argv)
-     int argc;
-     char *argv[];
-{
-#if defined(__GLIBC__)
-  printf("%s %s\n", __libc_version, __libc_release);
-#else
-  printf("unknown\n");
-#endif
-  return 0;
-}
-EOF
-       LIBC=""
-       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
-       if test "$?" = 0 ; then
-               ./$dummy | grep 1\.99 > /dev/null
-               if test "$?" = 0 ; then LIBC="libc1" ; fi
-       fi
-       rm -f $dummy.c $dummy
-       echo powerpc-unknown-linux-gnu${LIBC}
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
        exit 0 ;;
     alpha:Linux:*:*)
-       cat <<EOF >$dummy.s
-         .data
-         \$Lformat:
-               .byte 37,100,45,37,120,10,0     # "%d-%x\n"
-          .text
-               .globl main
-               .align 4
-               .ent main
-           main:
-               .frame \$30,16,\$26,0
-               ldgp \$29,0(\$27)
-               .prologue 1
-               .long 0x47e03d80 # implver \$0
-               lda \$2,-1
-               .long 0x47e20c21 # amask \$2,\$1
-               lda \$16,\$Lformat
-               mov \$0,\$17
-               not \$1,\$18
-               jsr \$26,printf
-               ldgp \$29,0(\$26)
-               mov 0,\$16
-               jsr \$26,exit
-               .end main
-EOF
-       LIBC=""
-       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
-       if test "$?" = 0 ; then
-               case `./$dummy` in
-               0-0)    UNAME_MACHINE="alpha" ;;
-               1-0)    UNAME_MACHINE="alphaev5" ;;
-               1-1)    UNAME_MACHINE="alphaev56" ;;
-               1-101)  UNAME_MACHINE="alphapca56" ;;
-               2-303)  UNAME_MACHINE="alphaev6" ;;
-               2-307)  UNAME_MACHINE="alphaev67" ;;
-               esac
-               objdump --private-headers $dummy | \
-                 grep ld.so.1 > /dev/null
-               if test "$?" = 0 ; then
-                       LIBC="libc1"
-               fi
-       fi
-       rm -f $dummy.s $dummy
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
        echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
        exit 0 ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
@@ -883,71 +837,61 @@ EOF
        # The BFD linker knows what the default object file format is, so
        # first see if it will tell us. cd to the root directory to prevent
        # problems with other programs or directories called `ld' in the path.
-       ld_supported_emulations=`cd /; ld --help 2>&1 \
-                        | sed -ne '/supported emulations:/!d
+       # Export LANG=C to prevent ld from outputting information in other
+       # languages.
+       ld_supported_targets=`LANG=C; export LANG; cd /; ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
                                    s/[         ][      ]*/ /g
-                                   s/.*supported emulations: *//
+                                   s/.*supported targets: *//
                                    s/ .*//
                                    p'`
-        case "$ld_supported_emulations" in
-         i*86linux)
-               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
-               exit 0
-               ;;
-         elf_i*86)
+        case "$ld_supported_targets" in
+         elf32-i386)
                TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
                ;;
-         i*86coff)
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;               
+         coff-i386)
                echo "${UNAME_MACHINE}-pc-linux-gnucoff"
-               exit 0
-               ;;
-       esac
-       # Either a pre-BFD a.out linker (linux-gnuoldld)
-       # or one that does not give us useful --help.
-       # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
-       # If ld does not provide *any* "supported emulations:"
-       # that means it is gnuoldld.
-       test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
-       case "${UNAME_MACHINE}" in
-       i*86)
-         VENDOR=pc;
-         ;;
-       *)
-         VENDOR=unknown;
-         ;;
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
        esac
        # Determine whether the default compiler is a.out or elf
-       cat >$dummy.c <<EOF
-#include <features.h>
-#ifdef __cplusplus
-#include <stdio.h>  /* for printf() prototype */
-       int main (int argc, char *argv[]) {
-#else
-       int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-#  if __GLIBC__ >= 2
-    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
-#  else
-    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-#  endif
-# else
-   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-# endif
-#else
-  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
-#endif
-  return 0;
-}
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
 EOF
-       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
-       rm -f $dummy.c $dummy
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       rm -f $dummy.c
+       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
        test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
        ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
-# are messed up and put the nodename in both sysname and nodename.
     i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
        echo i386-sequent-sysv4
        exit 0 ;;
     i*86:UNIX_SV:4.2MP:2.*)
@@ -966,14 +910,13 @@ EOF
                echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
        fi
        exit 0 ;;
-    i*86:*:5:7*)
-        # Fixed at (any) Pentium or better
-        UNAME_MACHINE=i586
-        if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
-           echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
-       else
-           echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
-       fi
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
        exit 0 ;;
     i*86:*:3.2:*)
        if test -f /usr/options/cb.name; then
@@ -1021,7 +964,7 @@ EOF
        exit 0 ;;
     M68*:*:R3V[567]*:*)
        test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
-    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
        OS_REL=''
        test -r /etc/.relid \
        && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -1067,8 +1010,8 @@ EOF
                echo ns32k-sni-sysv
        fi
        exit 0 ;;
-    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
-                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
         echo i586-unisys-sysv4
         exit 0 ;;
     *:UNIX_System_V:4*:FTX*)
@@ -1080,6 +1023,10 @@ EOF
        # From seanf@swdc.stratus.com.
        echo i860-stratus-sysv4
        exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
     mc68*:A/UX:*:*)
        echo m68k-apple-aux${UNAME_RELEASE}
        exit 0 ;;
@@ -1120,13 +1067,15 @@ EOF
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
        if test "${UNAME_MACHINE}" = "x86pc"; then
                UNAME_MACHINE=pc
+               echo i386-${UNAME_MACHINE}-nto-qnx
+       else
+               echo `uname -p`-${UNAME_MACHINE}-nto-qnx
        fi
-       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
        exit 0 ;;
     *:QNX:*:4*)
        echo i386-pc-qnx
        exit 0 ;;
-    NSR-[KW]:NONSTOP_KERNEL:*:*)
+    NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
        echo nsr-tandem-nsk${UNAME_RELEASE}
        exit 0 ;;
     *:NonStop-UX:*:*)
@@ -1172,11 +1121,18 @@ EOF
     *:ITS:*:*)
        echo pdp10-unknown-its
        exit 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit 0 ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
 
+eval $set_cc_for_build
 cat >$dummy.c <<EOF
 #ifdef _SEQUENT_
 # include <sys/types.h>
index 3cc93650207d792e7c404f8bfd00ee83ece21517..88841259b521be337d32a18a132ee7101663f5f2 100644 (file)
@@ -63,9 +63,10 @@ case "$host" in
        AC_DEFINE(BROKEN_GETADDRINFO)
        dnl AIX handles lastlog as part of its login message
        AC_DEFINE(DISABLE_LASTLOG)
+       AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H)
        ;;
 *-*-cygwin*)
-       LIBS="$LIBS -lregex /usr/lib/textmode.o"
+       LIBS="$LIBS /usr/lib/textmode.o"
        AC_DEFINE(HAVE_CYGWIN)
        AC_DEFINE(USE_PIPES)
        AC_DEFINE(DISABLE_SHADOW)
@@ -122,6 +123,7 @@ case "$host" in
        check_for_libcrypt_later=1
        AC_DEFINE(DONT_TRY_OTHER_AF)
        AC_DEFINE(PAM_TTY_KLUDGE)
+       AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H)
        inet6_default_4in6=yes
        ;;
 mips-sony-bsd|mips-sony-newsos4)
@@ -184,6 +186,7 @@ mips-sony-bsd|mips-sony-newsos4)
        LDFLAGS="$LDFLAGS -L/usr/local/lib"
        LIBS="$LIBS -lc89"
        AC_DEFINE(HAVE_BOGUS_SYS_QUEUE_H)
+       AC_DEFINE(USE_PIPES)
        ;;
 *-sni-sysv*)
        CPPFLAGS="$CPPFLAGS -I/usr/local/include"
@@ -317,45 +320,17 @@ AC_ARG_WITH(libs,
        ]       
 )
 
-AC_ARG_WITH(pcre,
-       [  --with-pcre[[=PATH]]      Override built in regex library with pcre
-                            (optionally in PATH)],
-       [
-               case "$withval" in
-               no) ;;
-               *)
-                       if test "x$withval" != "xyes"; then
-                               if test -d "$withval/lib"; then
-                                       if test -n "${need_dash_r}"; then
-                                               LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
-                                       else
-                                               LDFLAGS="-L${withval}/lib ${LDFLAGS}"
-                                       fi
-                               else
-                                       if test -n "${need_dash_r}"; then
-                                               LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
-                                       else
-                                               LDFLAGS="-L${withval} ${LDFLAGS}"
-                                       fi
-                               fi
-                               if test -d "$withval/include"; then
-                                       CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
-                               else
-                                       CPPFLAGS="-I${withval} ${CPPFLAGS}"
-                               fi
-                       fi
-
-                       AC_CHECK_HEADER(pcreposix.h,
-                               AC_CHECK_LIB(pcre, pcre_info,[
-                                       AC_DEFINE(HAVE_LIBPCRE)
-                                       LIBS="$LIBS -lpcreposix -lpcre"
-                                       no_comp_check=yes],
-                                       AC_MSG_ERROR([*** unable to locate pcre library ***])),
-                               AC_MSG_ERROR([*** unable to locate pcreposix.h include file ***]))
-                       ;;
-               esac
-       ]       
-)
+# Checks for header files.
+AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \
+       getopt.h glob.h lastlog.h limits.h login.h \
+       login_cap.h maillock.h netdb.h netgroup.h \
+       netinet/in_systm.h paths.h poll.h pty.h \
+       security/pam_appl.h shadow.h stddef.h stdint.h \
+       strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \
+       sys/poll.h sys/queue.h sys/select.h sys/stat.h \
+       sys/stropts.h sys/sysmacros.h sys/time.h \
+       sys/ttcompat.h sys/un.h time.h ttyent.h usersec.h \
+       util.h utime.h utmp.h utmpx.h)
 
 # Checks for libraries.
 AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match))
@@ -371,10 +346,25 @@ fi
 AC_CHECK_FUNC(getspnam, ,
        AC_CHECK_LIB(gen, getspnam, LIBS="$LIBS -lgen"))
 
+AC_ARG_WITH(rpath,
+       [  --without-rpath         Disable auto-added -R linker paths],
+       [
+               if test "x$withval" = "xno" ; then      
+                       need_dash_r=""
+               fi
+               if test "x$withval" = "xyes" ; then
+                       need_dash_r=1
+               fi
+       ]
+)
+
 dnl zlib is required
 AC_ARG_WITH(zlib,
        [  --with-zlib=PATH        Use zlib in PATH],
        [
+               if test "x$withval" = "xno" ; then
+                       AC_MSG_ERROR([*** zlib is required ***])
+               fi
                if test -d "$withval/lib"; then
                        if test -n "${need_dash_r}"; then
                                LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
@@ -398,23 +388,6 @@ AC_ARG_WITH(zlib,
 
 AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***]))
 
-# We don't want to check if we did an pcre override.
-if test -z "$no_comp_check" ; then
-       AC_CHECK_FUNC(regcomp, 
-               [ AC_DEFINE(HAVE_REGCOMP)],
-               [
-                       AC_CHECK_LIB(pcre, pcre_info, 
-                       [
-                               AC_DEFINE(HAVE_LIBPCRE)
-                               LIBS="$LIBS -lpcreposix -lpcre"
-                       ],
-                       [
-                               AC_MSG_ERROR([*** No regex library found.])
-                       ])
-               ]
-       )
-fi
-
 dnl UnixWare 2.x
 AC_CHECK_FUNC(strcasecmp, 
        [], [ AC_CHECK_LIB(resolv, strcasecmp, LIBS="$LIBS -lresolv") ]
@@ -430,18 +403,6 @@ AC_CHECK_FUNCS(logout updwtmp logwtmp)
 
 AC_FUNC_STRFTIME
 
-# Checks for header files.
-AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \
-       getopt.h glob.h lastlog.h limits.h login.h \
-       login_cap.h maillock.h netdb.h netgroup.h \
-       netinet/in_systm.h paths.h poll.h pty.h regex.h \
-       security/pam_appl.h shadow.h stddef.h stdint.h \
-       strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \
-       sys/poll.h sys/queue.h sys/select.h sys/stat.h \
-       sys/stropts.h sys/sysmacros.h sys/time.h \
-       sys/ttcompat.h sys/un.h time.h ttyent.h usersec.h \
-       util.h utime.h utmp.h utmpx.h)
-
 # Check for ALTDIRFUNC glob() extension
 AC_MSG_CHECKING(for GLOB_ALTDIRFUNC support)
 AC_EGREP_CPP(FOUNDIT,
@@ -507,9 +468,16 @@ AC_ARG_WITH(skey,
                        LIBS="-lskey $LIBS"
                        SKEY_MSG="yes" 
        
-                       AC_CHECK_FUNC(skey_keyinfo,
-                               [],
+                       AC_MSG_CHECKING([for s/key support])
+                       AC_TRY_RUN(
+                               [
+#include <stdio.h>
+#include <skey.h>
+int main() { char *ff = skey_keyinfo(""); ff=""; return 0; }
+                               ],
+                               [AC_MSG_RESULT(yes)],
                                [
+                                       AC_MSG_RESULT(no)
                                        AC_MSG_ERROR([** Incomplete or missing s/key libraries.])
                                ])
                fi
@@ -546,7 +514,8 @@ AC_ARG_WITH(tcp-wrappers,
                                        CPPFLAGS="-I${withval} ${CPPFLAGS}"
                                fi
                        fi
-                       LIBS="-lwrap $LIBS"
+                       LIBWRAP="-lwrap"
+                       LIBS="$LIBWRAP $LIBS"
                        AC_MSG_CHECKING(for libwrap)
                        AC_TRY_LINK(
                                [
@@ -557,12 +526,14 @@ AC_ARG_WITH(tcp-wrappers,
                                [
                                        AC_MSG_RESULT(yes)
                                        AC_DEFINE(LIBWRAP)
+                                       AC_SUBST(LIBWRAP)
                                        TCPW_MSG="yes"
                                ],
                                [
                                        AC_MSG_ERROR([*** libwrap missing])
                                ]
                        )
+                       LIBS="$saved_LIBS"
                fi
        ]
 )
@@ -678,6 +649,12 @@ AC_ARG_WITH(pam,
                        PAM_MSG="yes"
 
                        AC_DEFINE(USE_PAM)
+                       if test $ac_cv_lib_dl_dlopen = yes; then
+                               LIBPAM="-lpam -ldl"
+                       else
+                               LIBPAM="-lpam"
+                       fi
+                       AC_SUBST(LIBPAM)
                fi
        ]
 )
@@ -865,12 +842,204 @@ else
        fi
 fi
 
+# Sanity check OpenSSL headers
+AC_MSG_CHECKING([whether OpenSSL's headers match the library])
+AC_TRY_RUN(
+       [
+#include <string.h>
+#include <openssl/opensslv.h>
+int main(void) { return(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
+       ],
+       [
+               AC_MSG_RESULT(yes)
+       ],
+       [
+               AC_MSG_RESULT(no)
+               AC_MSG_ERROR(Your OpenSSL headers do not match your library)
+       ]
+)
+
 # Some Linux systems (Slackware) need crypt() from libcrypt, *not* the 
 # version in OpenSSL. Skip this for PAM
 if test "x$PAM_MSG" = "xno" -a "x$check_for_libcrypt_later" = "x1"; then
        AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
 fi
 
+
+### Configure cryptographic random number support
+
+# Check wheter OpenSSL seeds itself
+AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
+AC_TRY_RUN(
+       [
+#include <string.h>
+#include <openssl/rand.h>
+int main(void) { return(RAND_status() == 1 ? 0 : 1); }
+       ],
+       [
+               OPENSSL_SEEDS_ITSELF=yes
+               AC_MSG_RESULT(yes)
+       ],
+       [
+               AC_MSG_RESULT(no)
+               # Default to use of the rand helper if OpenSSL doesn't
+               # seed itself
+               USE_RAND_HELPER=yes
+       ]
+)
+
+
+# Do we want to force the use of the rand helper?
+AC_ARG_WITH(rand-helper,
+       [  --with-rand-helper      Use subprocess to gather strong randomness ],
+       [
+               if test "x$withval" = "xno" ; then
+                       # Force use of OpenSSL's internal RNG, even if 
+                       # the previous test showed it to be unseeded.
+                       if test -z "$OPENSSL_SEEDS_ITSELF" ; then
+                               AC_MSG_WARN([*** Forcing use of OpenSSL's non-self-seeding PRNG])
+                               OPENSSL_SEEDS_ITSELF=yes
+                               USE_RAND_HELPER=""
+                       fi
+               else
+                       USE_RAND_HELPER=yes
+               fi
+       ],
+)      
+
+# Which randomness source do we use?
+if test ! -z "$OPENSSL_SEEDS_ITSELF" -a -z "$USE_RAND_HELPER" ; then
+       # OpenSSL only
+       AC_DEFINE(OPENSSL_PRNG_ONLY)
+       RAND_MSG="OpenSSL internal ONLY"
+       INSTALL_SSH_RAND_HELPER=""
+elif test ! -z "$USE_RAND_HELPER" ; then
+       # install rand helper
+       RAND_MSG="ssh-rand-helper"
+       INSTALL_SSH_RAND_HELPER="yes"
+fi
+AC_SUBST(INSTALL_SSH_RAND_HELPER)
+
+### Configuration of ssh-rand-helper
+
+# PRNGD TCP socket
+AC_ARG_WITH(prngd-port,
+       [  --with-prngd-port=PORT  read entropy from PRNGD/EGD TCP localhost:PORT],
+       [
+               case "$withval" in
+               no)
+                       withval=""
+                       ;;
+               [[0-9]]*)
+                       ;;
+               *)
+                       AC_MSG_ERROR(You must specify a numeric port number for --with-prngd-port)
+                       ;;
+               esac
+               if test ! -z "$withval" ; then
+                       PRNGD_PORT="$withval"
+                       AC_DEFINE_UNQUOTED(PRNGD_PORT, $PRNGD_PORT)
+               fi
+       ]
+)
+
+# PRNGD Unix domain socket
+AC_ARG_WITH(prngd-socket,
+       [  --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)],
+       [
+               case "$withval" in
+               yes)
+                       withval="/var/run/egd-pool"
+                       ;;
+               no)
+                       withval=""
+                       ;;
+               /*)
+                       ;;
+               *)
+                       AC_MSG_ERROR(You must specify an absolute path to the entropy socket)
+                       ;;
+               esac
+
+               if test ! -z "$withval" ; then
+                       if test ! -z "$PRNGD_PORT" ; then
+                               AC_MSG_ERROR(You may not specify both a PRNGD/EGD port and socket)
+                       fi
+                       if test ! -r "$withval" ; then
+                               AC_MSG_WARN(Entropy socket is not readable)
+                       fi
+                       PRNGD_SOCKET="$withval"
+                       AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET")
+               fi
+       ],
+       [
+               # Check for existing socket only if we don't have a random device already
+               if test "$USE_RAND_HELPER" = yes ; then
+                       AC_MSG_CHECKING(for PRNGD/EGD socket)
+                       # Insert other locations here
+                       for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do
+                               if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then
+                                       PRNGD_SOCKET="$sock"
+                                       AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET")
+                                       break;
+                               fi
+                       done
+                       if test ! -z "$PRNGD_SOCKET" ; then
+                               AC_MSG_RESULT($PRNGD_SOCKET)
+                       else
+                               AC_MSG_RESULT(not found)
+                       fi
+               fi
+       ]
+)
+
+# Change default command timeout for hashing entropy source
+entropy_timeout=200
+AC_ARG_WITH(entropy-timeout,
+       [  --with-entropy-timeout  Specify entropy gathering command timeout (msec)],
+       [
+               if test "x$withval" != "xno" ; then
+                       entropy_timeout=$withval
+               fi
+       ]       
+)
+
+AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout)
+
+# These programs are used by the command hashing source to gather entropy 
+OSSH_PATH_ENTROPY_PROG(PROG_LS, ls)
+OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat)
+OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp)
+OSSH_PATH_ENTROPY_PROG(PROG_IFCONFIG, ifconfig)
+OSSH_PATH_ENTROPY_PROG(PROG_JSTAT, jstat)
+OSSH_PATH_ENTROPY_PROG(PROG_PS, ps)
+OSSH_PATH_ENTROPY_PROG(PROG_SAR, sar)
+OSSH_PATH_ENTROPY_PROG(PROG_W, w)
+OSSH_PATH_ENTROPY_PROG(PROG_WHO, who)
+OSSH_PATH_ENTROPY_PROG(PROG_LAST, last)
+OSSH_PATH_ENTROPY_PROG(PROG_LASTLOG, lastlog)
+OSSH_PATH_ENTROPY_PROG(PROG_DF, df)
+OSSH_PATH_ENTROPY_PROG(PROG_VMSTAT, vmstat)
+OSSH_PATH_ENTROPY_PROG(PROG_UPTIME, uptime)
+OSSH_PATH_ENTROPY_PROG(PROG_IPCS, ipcs)
+OSSH_PATH_ENTROPY_PROG(PROG_TAIL, tail)
+
+# Where does ssh-rand-helper get its randomness from?
+INSTALL_SSH_PRNG_CMDS=""
+if test ! -z "$INSTALL_SSH_RAND_HELPER" ; then
+       if test ! -z "$PRNGD_PORT" ; then
+               RAND_HELPER_MSG="TCP localhost:$PRNGD_PORT"
+       elif test ! -z "$PRNGD_SOCKET" ; then
+               RAND_HELPER_MSG="Unix domain socket \"$PRNGD_SOCKET\""
+       else
+               RAND_HELPER_MSG="Command hashing (timeout $entropy_timeout)"
+               RAND_HELPER_CMDHASH=yes
+               INSTALL_SSH_PRNG_CMDS="yes"
+       fi
+fi
+AC_SUBST(INSTALL_SSH_PRNG_CMDS)
+
+
 # Cheap hack to ensure NEWS-OS libraries are arranged right.
 if test ! -z "$SONY" ; then
   LIBS="$LIBS -liberty";
@@ -951,6 +1120,19 @@ if test -z "$have_int64_t" ; then
        )
 fi
 
+if test -z "$have_int64_t" ; then
+    AC_MSG_CHECKING([for int64_t type in sys/bitypes.h])
+       AC_TRY_COMPILE(
+               [ #include <sys/bitypes.h> ], 
+               [ int64_t a; a = 1],
+               [
+                       AC_DEFINE(HAVE_INT64_T)
+                       AC_MSG_RESULT(yes)
+               ],
+               [ AC_MSG_RESULT(no) ]
+       )
+fi
+
 AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [
        AC_TRY_COMPILE(
                [ #include <sys/types.h> ], 
@@ -990,6 +1172,19 @@ if test "x$ac_cv_have_u_int64_t" = "xyes" ; then
        have_u_int64_t=1
 fi
 
+if test -z "$have_u_int64_t" ; then
+    AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h])
+       AC_TRY_COMPILE(
+               [ #include <sys/bitypes.h> ], 
+               [ u_int64_t a; a = 1],
+               [
+                       AC_DEFINE(HAVE_U_INT64_T)
+                       AC_MSG_RESULT(yes)
+               ],
+               [ AC_MSG_RESULT(no) ]
+       )
+fi
+
 if test -z "$have_u_intxx_t" ; then
        AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [
                AC_TRY_COMPILE(
@@ -1058,6 +1253,8 @@ fi
 
 TYPE_SOCKLEN_T
 
+AC_CHECK_TYPES(sig_atomic_t,,,[#include <signal.h>])
+
 AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [
        AC_TRY_COMPILE(
                [
@@ -1587,97 +1784,6 @@ AC_CHECK_FILE("/dev/ptc",
 )
 
 # Options from here on. Some of these are preset by platform above
-
-# Check for user-specified random device, otherwise check /dev/urandom
-AC_ARG_WITH(random,
-       [  --with-random=FILE      read entropy from FILE (default=/dev/urandom)],
-       [
-               if test "x$withval" != "xno" ; then
-                       RANDOM_POOL="$withval";
-                       AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL")
-               fi
-       ],
-       [
-               # Check for random device
-               AC_CHECK_FILE("/dev/urandom",
-                       [
-                               RANDOM_POOL="/dev/urandom"; 
-                               AC_SUBST(RANDOM_POOL)
-                               AC_DEFINE_UNQUOTED(RANDOM_POOL, "$RANDOM_POOL")
-                       ]
-               )
-       ]
-)
-
-# Check for PRNGD/EGD pool file
-AC_ARG_WITH(prngd-port,
-       [  --with-prngd-port=PORT  read entropy from PRNGD/EGD localhost:PORT],
-       [
-               if test ! -z "$withval" -a "x$withval" != "xno" ; then
-                       PRNGD_PORT="$withval"
-                       AC_DEFINE_UNQUOTED(PRNGD_PORT, $PRNGD_PORT)
-               fi
-       ]
-)
-
-# Check for PRNGD/EGD pool file
-AC_ARG_WITH(prngd-socket,
-       [  --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)],
-       [
-               if test "x$withval" != "xno" ; then
-                       PRNGD_SOCKET="$withval"
-                       AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET")
-               fi
-       ],
-       [
-               # Check for existing socket only if we don't have a random device already
-               if test -z "$RANDOM_POOL" ; then
-                       AC_MSG_CHECKING(for PRNGD/EGD socket)
-                       # Insert other locations here
-                       for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do
-                               if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then
-                                       PRNGD_SOCKET="$sock"
-                                       AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET")
-                                       break;
-                               fi
-                       done
-                       if test ! -z "$PRNGD_SOCKET" ; then
-                               AC_MSG_RESULT($PRNGD_SOCKET)
-                       else
-                               AC_MSG_RESULT(not found)
-                       fi
-               fi
-       ]
-)
-
-
-# detect pathnames for entropy gathering commands, if we need them
-INSTALL_SSH_PRNG_CMDS=""
-rm -f prng_commands
-if (test -z "$RANDOM_POOL" && test -z "$PRNGD") ; then
-       # Use these commands to collect entropy
-       OSSH_PATH_ENTROPY_PROG(PROG_LS, ls)
-       OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat)
-       OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp)
-       OSSH_PATH_ENTROPY_PROG(PROG_IFCONFIG, ifconfig)
-       OSSH_PATH_ENTROPY_PROG(PROG_JSTAT, jstat)
-       OSSH_PATH_ENTROPY_PROG(PROG_PS, ps)
-       OSSH_PATH_ENTROPY_PROG(PROG_SAR, sar)
-       OSSH_PATH_ENTROPY_PROG(PROG_W, w)
-       OSSH_PATH_ENTROPY_PROG(PROG_WHO, who)
-       OSSH_PATH_ENTROPY_PROG(PROG_LAST, last)
-       OSSH_PATH_ENTROPY_PROG(PROG_LASTLOG, lastlog)
-       OSSH_PATH_ENTROPY_PROG(PROG_DF, df)
-       OSSH_PATH_ENTROPY_PROG(PROG_VMSTAT, vmstat)
-       OSSH_PATH_ENTROPY_PROG(PROG_UPTIME, uptime)
-       OSSH_PATH_ENTROPY_PROG(PROG_IPCS, ipcs)
-       OSSH_PATH_ENTROPY_PROG(PROG_TAIL, tail)
-
-       INSTALL_SSH_PRNG_CMDS="yes"
-fi
-AC_SUBST(INSTALL_SSH_PRNG_CMDS)
-
-
 AC_ARG_WITH(mantype,
        [  --with-mantype=man|cat|doc  Set man page type],
        [
@@ -1869,12 +1975,13 @@ AC_ARG_WITH(4in6,
 )
 
 # Whether to enable BSD auth support
+BSD_AUTH_MSG=no
 AC_ARG_WITH(bsd-auth,
        [  --with-bsd-auth         Enable BSD auth support],
        [
                if test "x$withval" != "xno" ; then     
                        AC_DEFINE(BSD_AUTH)
-                       bsd_auth=yes
+                       BSD_AUTH_MSG=yes
                fi
        ]
 )
@@ -2141,44 +2248,25 @@ else
 fi     
 
 
-# Change default command timeout for builtin PRNG
-entropy_timeout=200
-AC_ARG_WITH(entropy-timeout,
-       [  --with-entropy-timeout  Specify entropy gathering command timeout (msec)],
-       [
-               if test "x$withval" != "xno" ; then
-                       entropy_timeout=$withval
-               fi
-       ]       
-)
-AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout)
-
-
 if test ! -z "$blibpath" ; then
        LDFLAGS="$LDFLAGS -blibpath:$blibpath"
        AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile])
 fi
 
-AC_EXEEXT
+dnl remove pam and dl because they are in $LIBPAM
+if test "$PAM_MSG" = yes ; then
+       LIBS=`echo $LIBS | sed 's/-lpam //'`
+fi
+if test "$ac_cv_lib_pam_pam_set_item" = yes ; then
+       LIBS=`echo $LIBS | sed 's/-ldl //'`
+fi
 
+AC_EXEEXT
 AC_CONFIG_FILES([Makefile openbsd-compat/Makefile scard/Makefile ssh_prng_cmds])
 AC_OUTPUT
 
 # Print summary of options
 
-if test ! -z "$RANDOM_POOL" ; then
-       RAND_MSG="Device ($RANDOM_POOL)"
-else
-       if test ! -z "$PRNGD_PORT" ; then
-               RAND_MSG="PRNGD/EGD (port localhost:$PRNGD_PORT)"
-       elif test ! -z "$PRNGD_SOCKET" ; then
-               RAND_MSG="PRNGD/EGD (socket $PRNGD_SOCKET)"
-       else
-               RAND_MSG="Builtin (timeout $entropy_timeout)"
-               BUILTIN_RNG=1
-       fi
-fi
-
 # Someone please show me a better way :)
 A=`eval echo ${prefix}` ; A=`eval echo ${A}`
 B=`eval echo ${bindir}` ; B=`eval echo ${B}`
@@ -2198,7 +2286,6 @@ echo "               Askpass program: $E"
 echo "                  Manual pages: $F"
 echo "                      PID file: $G"
 echo "        sshd default user PATH: $H"
-echo "      Random number collection: $RAND_MSG"
 echo "                Manpage format: $MANTYPE"
 echo "                   PAM support: ${PAM_MSG}"
 echo "            KerberosIV support: $KRB4_MSG"
@@ -2210,9 +2297,10 @@ echo "          MD5 password support: $MD5_MSG"
 echo "   IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
 echo "      Use IPv4 by default hack: $IPV4_HACK_MSG"
 echo "       Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
-
-if test ! -z "$bsd_auth"; then
-       echo "              BSD Auth support: yes"
+echo "              BSD Auth support: $BSD_AUTH_MSG"
+echo "          Random number source: $RAND_MSG"
+if test ! -z "$USE_RAND_HELPER" ; then
+       echo " ssh-rand-helper collects from: $RAND_HELPER_MSG"
 fi
 
 echo ""
@@ -2222,27 +2310,29 @@ echo "          Compiler: ${CC}"
 echo "    Compiler flags: ${CFLAGS}"
 echo "Preprocessor flags: ${CPPFLAGS}"
 echo "      Linker flags: ${LDFLAGS}"
-echo "         Libraries: ${LIBS}"
+echo "         Libraries: ${LIBWRAP} ${LIBPAM} ${LIBS}"
 
 echo ""
 
 if test "x$PAM_MSG" = "xyes" ; then
-       echo "PAM is enabled. You may need to install a PAM control file for sshd,"
-       echo "otherwise password authentication may fail. Example PAM control files"
-       echo "can be found in the contrib/ subdirectory"
+       echo "PAM is enabled. You may need to install a PAM control file "
+       echo "for sshd, otherwise password authentication may fail. "
+       echo "Example PAM control files can be found in the contrib/ " 
+       echo "subdirectory"
        echo ""
 fi
 
-if test ! -z "$BUILTIN_RNG" ; then
-       echo "WARNING: you are using the builtin random number collection service."
-       echo "Please read WARNING.RNG and request that your OS vendor includes"
-       echo "/dev/random in future versions of their OS."
+if test ! -z "$NO_SFTP"; then
+       echo "sftp-server will be disabled.  Your compiler does not "
+       echo "support 64bit integers."
        echo ""
 fi
 
-if test ! -z "$NO_SFTP"; then
-       echo "sftp-server will be disabled.  Your compiler does not support"
-       echo "64bit integers."
+if test ! -z "$RAND_HELPER_CMDHASH" ; then
+       echo "WARNING: you are using the builtin random number collection "
+       echo "service. Please read WARNING.RNG and request that your OS "
+       echo "vendor includes kernel-based random number collection in "
+       echo "future versions of your OS."
        echo ""
 fi
 
index d25545710b7a32ff5a8d69156be272c347f31731..648bb2f3a7ba4ffd5b5125dc26ac9e4d3821e516 100644 (file)
@@ -11,11 +11,10 @@ or http proxy which supports the CONNECT method (eg. Squid).
 In this directory
 -----------------
 
-chroot.diff:
+chroot.diff: 
 
-Ricardo Cerqueira's <rmcc@clix.pt> patch to enable chrooting using the
-wu-ftpd style magic home directories (containing '/./'). More details in
-the head of the patch itself.
+Due to the fact the patch is never in sync with the rest of the tree.  It was
+removed. 
 
 ssh-copy-id:
 
diff --git a/openssh/contrib/aix/README b/openssh/contrib/aix/README
new file mode 100644 (file)
index 0000000..a08c084
--- /dev/null
@@ -0,0 +1,36 @@
+Overview:
+
+This directory contains files to build an AIX native (installp or SMIT
+installable) openssh package.
+
+
+Directions:
+
+./configure [options]
+cd contrib/aix; ./buildbff.sh
+
+
+Acknowledgements:
+
+The contents of this directory are based on Ben Lindstrom's Solaris
+buildpkg.sh. Ben also supplied inventory.sh.
+
+Jim Abbey's (GPL'ed) lppbuild-2.1 was used to learn how to build .bff's
+and for comparison with the output from this script, however no code
+from lppbuild is included and it is not required for operation.
+
+
+Other notes:
+
+The script treats all packages as USR packages (not ROOT+USR when
+appropriate).  It seems to work, though......
+
+
+Disclaimer:
+
+It is hoped that it is useful but there is no warranty. If it breaks
+you get to keep both pieces.
+
+
+       - Darren Tucker (dtucker at zip dot com dot au)
+         2002/03/01
diff --git a/openssh/contrib/aix/buildbff.sh b/openssh/contrib/aix/buildbff.sh
new file mode 100755 (executable)
index 0000000..6c7aaf4
--- /dev/null
@@ -0,0 +1,187 @@
+#!/bin/sh
+#
+# buildbff.sh: Create AIX SMIT-installable OpenSSH packages
+#
+# Author: Darren Tucker (dtucker at zip dot com dot au)
+# This file is placed in the public domain and comes with absolutely
+# no warranty.
+# 
+# Based originally on Ben Lindstrom's buildpkg.sh for Solaris
+#
+
+umask 022
+PKGNAME=openssh
+
+PATH=$PATH:`pwd`               # set path for external tools
+export PATH
+
+## Extract common info requires for the 'info' part of the package.
+VERSION=`tail -1 ../../version.h | sed -e 's/.*_\([0-9]\)/\1/g' | sed 's/\"$//'`
+BFFVERSION=`echo $VERSION | sed 's/p/./g'`
+
+echo "Building BFF for $PKGNAME $VERSION (package version $BFFVERSION)"
+PKGDIR=package
+
+# Clean build directory and package file
+rm -rf $PKGDIR
+mkdir $PKGDIR
+rm -f $PKGNAME-$VERSION.bff
+
+if [ ! -f ../../Makefile ]
+then
+       echo "Top-level Makefile not found (did you run ./configure?)"
+       exit 1
+fi
+
+## Start by faking root install 
+echo "Faking root install..."
+START=`pwd`
+FAKE_ROOT=$START/$PKGDIR
+cd ../.. 
+make install-nokeys DESTDIR=$FAKE_ROOT
+
+#
+# Fill in some details, like prefix and sysconfdir
+#      the eval also expands variables like sysconfdir=${prefix}/etc
+#      provided they are eval'ed in the correct order
+#
+for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir mansubdir sysconfdir piddir
+do
+       eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2`
+done
+
+# Rename config files; postinstall script will copy them if necessary
+for cfgfile in ssh_config sshd_config ssh_prng_cmds
+do
+       mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default
+done
+
+#
+# Generate lpp control files.
+#      working dir is $FAKE_ROOT but files are generated in contrib/aix
+#      and moved into place just before creation of .bff
+#
+cd $FAKE_ROOT
+echo Generating LPP control files
+find . ! -name . -print >../openssh.al
+inventory.sh >../openssh.inventory
+cp ../../../LICENCE ../openssh.copyright
+
+#
+# Create postinstall script
+#
+cat <<EOF >>../openssh.post_i
+#!/bin/sh
+
+# Create configs from defaults if necessary
+for cfgfile in ssh_config sshd_config ssh_prng_cmds
+do
+        if [ ! -f $sysconfdir/\$cfgfile ]
+        then
+                echo "Creating \$cfgfile from default"
+                cp $sysconfdir/\$cfgfile.default $sysconfdir/\$cfgfile
+        else
+                echo "\$cfgfile already exists."
+        fi
+done
+
+# Generate keys unless they already exist
+if [ -f "$sysconfdir/ssh_host_key" ] ; then
+        echo "$sysconfdir/ssh_host_key already exists, skipping."
+else
+        $bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N ""
+fi
+if [ -f $sysconfdir/ssh_host_dsa_key ] ; then
+        echo "$sysconfdir/ssh_host_dsa_key already exists, skipping."
+else
+        $bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N ""
+fi
+if [ -f $sysconfdir/ssh_host_rsa_key ] ; then
+        echo "$sysconfdir/ssh_host_rsa_key already exists, skipping."
+else 
+        $bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N ""
+fi
+
+# Add to system startup if required
+if grep $sbindir/sshd /etc/rc.tcpip >/dev/null
+then
+        echo "sshd found in rc.tcpip, not adding."
+else
+        echo >>/etc/rc.tcpip
+        echo "echo Starting sshd" >>/etc/rc.tcpip
+        echo "$sbindir/sshd" >>/etc/rc.tcpip
+fi
+EOF
+
+#
+# Create liblpp.a and move control files into it
+#
+echo Creating liblpp.a
+(
+       cd ..
+       for i in al copyright inventory post_i
+       do
+               ar -r liblpp.a openssh.$i
+               rm openssh.$i
+       done
+)
+
+#
+# Create lpp_name
+#
+# This will end up looking something like:
+# 4 R I OpenSSH {
+# OpenSSH 3.0.2.1 1 N U en_US OpenSSH 3.0.2p1 Portable for AIX
+# [
+# %
+# /usr/local/bin 8073
+# /usr/local/etc 189
+# /usr/local/libexec 185
+# /usr/local/man/man1 145
+# /usr/local/man/man8 83
+# /usr/local/sbin 2105
+# /usr/local/share 3
+# %
+# ]
+echo Creating lpp_name
+cat <<EOF >../lpp_name
+4 R I $PKGNAME {
+$PKGNAME $BFFVERSION 1 N U en_US OpenSSH $VERSION Portable for AIX
+[
+%
+EOF
+
+for i in $bindir $sysconfdir $libexecdir $mandir/man1 $mandir/man8 $sbindir $datadir
+do
+       # get size in 512 byte blocks
+       size=`du $FAKE_ROOT/$i | awk '{print $1}'`
+       echo "$i $size" >>../lpp_name
+done
+
+echo '%' >>../lpp_name
+echo ']' >>../lpp_name
+echo '}' >>../lpp_name
+
+#
+# Move pieces into place
+#
+mkdir -p usr/lpp/openssh
+mv ../liblpp.a usr/lpp/openssh
+mv ../lpp_name .
+
+#
+# Now invoke backup to create .bff file
+#      note: lpp_name needs to be the first file do we generate the
+#      file list on the fly and feed it to backup using -i
+#
+echo Creating $PKGNAME-$VERSION.bff with backup...
+(
+       echo "./lpp_name"
+       find . ! -name lpp_name -a ! -name . -print 
+) | backup  -i -q -f ../$PKGNAME-$VERSION.bff $filelist
+
+cd ..
+
+rm -rf $PKGDIR
+echo $0: done.
+
diff --git a/openssh/contrib/aix/inventory.sh b/openssh/contrib/aix/inventory.sh
new file mode 100755 (executable)
index 0000000..aa44ab9
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# inventory.sh
+#
+# Originall written by Ben Lindstrom, modified by Darren Tucker to use perl
+#
+# This will produced and AIX package inventory file, which looks like:
+#
+# /usr/local/bin:
+#          class=apply,inventory,openssh
+#          owner=root
+#          group=system
+#          mode=755
+#          type=DIRECTORY
+# /usr/local/bin/slogin:
+#          class=apply,inventory,openssh
+#          owner=root
+#          group=system
+#          mode=777
+#          type=SYMLINK
+#          target=ssh
+# /usr/local/share/Ssh.bin:
+#          class=apply,inventory,openssh
+#          owner=root
+#          group=system
+#          mode=644
+#          type=FILE
+#          size=VOLATILE
+#          checksum=VOLATILE
+
+find . ! -name . -print | perl -ne '{
+       chomp;
+       if ( -l $_ ) {
+               ($dev,$ino,$mod,$nl,$uid,$gid,$rdev,$sz,$at,$mt,$ct,$bsz,$blk)=lstat;
+       } else {
+               ($dev,$ino,$mod,$nl,$uid,$gid,$rdev,$sz,$at,$mt,$ct,$bsz,$blk)=stat;
+       }
+
+       # Start to display inventory information
+       $name = $_;
+       $name =~ s|^.||;        # Strip leading dot from path
+       print "$name:\n";
+       print "\tclass=apply,inventory,openssh\n";
+       print "\towner=root\n";
+       print "\tgroup=system\n";
+       printf "\tmode=%lo\n", $mod & 07777;    # Mask perm bits
+       
+       if ( -l $_ ) {
+               # Entry is SymLink
+               print "\ttype=SYMLINK\n";
+               printf "\ttarget=%s\n", readlink($_);
+       } elsif ( -f $_ ) {
+               # Entry is File
+               print "\ttype=FILE\n";
+               print "\tsize=VOLATILE\n";
+               print "\tchecksum=VOLATILE\n";
+       } elsif ( -d $_ ) {
+               # Entry is Directory
+               print "\ttype=DIRECTORY\n";
+       } 
+}'
index b11e54922fcf677ded30a156c6a914f41b9f6735..e2077bf0a941382532a52049ab68c72c0a09d1c8 100644 (file)
@@ -1,6 +1,6 @@
 %define use-stable     1
 %if %{use-stable}
-  %define version      3.0.2p1
+  %define version      3.1p1
   %define cvs          %{nil}
   %define release      1
 %else
index dfe17867927512cdc340baba7716c86a970ffd2f..60d3916915f6682d84997a5b9f98ed41e2084720 100644 (file)
@@ -1,5 +1,13 @@
 This package is the actual port of OpenSSH to Cygwin 1.3.
 
+===========================================================================
+Important change since 3.0.1p1-2:
+
+This version introduces the ability to register sshd as service on
+Windows 9x/Me systems.  This is done only when the options -D and/or
+-d are not given.
+===========================================================================
+
 ===========================================================================
 Important change since 2.9p2:
 
@@ -75,12 +83,12 @@ If you start sshd as deamon via cygrunsrv.exe you MUST give the
 If starting via inetd, copy sshd to eg. /usr/sbin/in.sshd and add the
 following line to your inetd.conf file:
 
-sshd stream tcp nowait root /usr/sbin/in.sshd sshd -i
+ssh stream tcp nowait root /usr/sbin/in.sshd sshd -i
 
 Moreover you'll have to add the following line to your
 ${SYSTEMROOT}/system32/drivers/etc/services file:
 
-   sshd         22/tcp          #SSH daemon
+   ssh         22/tcp          #SSH daemon
 
 ===========================================================================
 The following restrictions only apply to Cygwin versions up to 1.3.1
@@ -162,12 +170,10 @@ configure are used for the Cygwin binary distribution:
 
        --prefix=/usr \
        --sysconfdir=/etc \
-       --libexecdir='${exec_prefix}/sbin \
-       --with-pcre
+       --libexecdir='${exec_prefix}/sbin'
 
 You must have installed the zlib, openssl and regex packages to
-be able to build OpenSSH! The `--with-pcre' option requires
-the installation of the pcre package.
+be able to build OpenSSH!
 
 Please send requests, error reports etc. to cygwin@cygwin.com.
 
index 27e5ccaa1e32e11f8d871ff42c06aa012d7064b4..7cece562011174099fea86f273c70ee3b4f006cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000 Damien Miller.  All rights reserved.
+ * Copyright (c) 2000-2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+/*
+ * This is a simple GNOME SSH passphrase grabber. To use it, set the 
+ * environment variable SSH_ASKPASS to point to the location of 
+ * gnome-ssh-askpass before calling "ssh-add < /dev/null". 
+ *
+ * There is only two run-time options: if you set the environment variable
+ * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab
+ * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the 
+ * pointer will be grabbed too. These may have some benefit to security if 
+ * you don't trust your X server. We grab the keyboard always.
+ */
+
 /*
  * Compile with:
  *
@@ -57,10 +69,12 @@ passphrase_dialog(char *message)
 {
        char *passphrase;
        char **messages;
-       int result, i;
-       
+       int result, i, grab_server, grab_pointer;
        GtkWidget *dialog, *entry, *label;
 
+       grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL);
+       grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL);
+
        dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK,
            GNOME_STOCK_BUTTON_CANCEL, NULL);
 
@@ -89,9 +103,10 @@ passphrase_dialog(char *message)
        gtk_widget_show_all(dialog);
 
        /* Grab focus */
-       XGrabServer(GDK_DISPLAY());
-       if (gdk_pointer_grab(dialog->window, TRUE, 0, NULL, NULL, 
-           GDK_CURRENT_TIME))
+       if (grab_server)
+               XGrabServer(GDK_DISPLAY());
+       if (grab_pointer && gdk_pointer_grab(dialog->window, TRUE, 0, 
+           NULL, NULL, GDK_CURRENT_TIME))
                goto nograb;
        if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME))
                goto nograbkb;
@@ -103,8 +118,10 @@ passphrase_dialog(char *message)
        result = gnome_dialog_run(GNOME_DIALOG(dialog));
 
        /* Ungrab */
-       XUngrabServer(GDK_DISPLAY());
-       gdk_pointer_ungrab(GDK_CURRENT_TIME);
+       if (grab_server)
+               XUngrabServer(GDK_DISPLAY());
+       if (grab_pointer)
+               gdk_pointer_ungrab(GDK_CURRENT_TIME);
        gdk_keyboard_ungrab(GDK_CURRENT_TIME);
        gdk_flush();
 
@@ -126,7 +143,8 @@ passphrase_dialog(char *message)
  nograbkb:
        gdk_pointer_ungrab(GDK_CURRENT_TIME);
  nograb:
-       XUngrabServer(GDK_DISPLAY());
+       if (grab_server)
+               XUngrabServer(GDK_DISPLAY());
        gnome_dialog_close(GNOME_DIALOG(dialog));
        
        report_failed_grab();
index 8ab68593e762cc55103aa695adc39f71d16bd576..c36b65153c2d45a9f365ea1d1a055c8f507cf0d6 100644 (file)
@@ -1,5 +1,5 @@
 # Version of OpenSSH
-%define oversion 3.0.2p1
+%define oversion 3.1p1
 
 # Version of ssh-askpass
 %define aversion 1.2.4.1
index b3bc0c0eb594a4d91f3e85a7cbdf9b4a7ad8e138..88b0e81cf5a981a84c025c6e20c3bbbbfd01bc6f 100644 (file)
@@ -1,6 +1,6 @@
 Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
 Name: openssh
-Version: 3.0.2p1
+Version: 3.1p1
 URL: http://www.openssh.com/
 Release: 1
 Source0: openssh-%{version}.tar.gz
index bdabc1b09926358759ffbb8d2be832a52ce5aaac..cd1832ff62e2936679eddbae5204d39a5c581b68 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: crc32.h,v 1.13 2002/03/04 17:27:39 stevesk Exp $      */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1992 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: crc32.h,v 1.12 2001/06/26 17:27:23 markus Exp $"); */
-
 #ifndef CRC32_H
 #define CRC32_H
 
index 1a89be4b803887d318f5146926bad92ef7c65ce3..0442501e7a17b6ddf4c6f7ae15770c8aa29129fc 100644 (file)
@@ -1,5 +1,3 @@
-/*     $OpenBSD: deattack.c,v 1.14 2001/06/23 15:12:18 itojun Exp $    */
-
 /*
  * Cryptographic attack detector for ssh - source code
  *
  */
 
 #include "includes.h"
+RCSID("$OpenBSD: deattack.c,v 1.18 2002/03/04 17:27:39 stevesk Exp $");
+
 #include "deattack.h"
 #include "log.h"
 #include "crc32.h"
 #include "getput.h"
 #include "xmalloc.h"
+#include "deattack.h"
 
 /* SSH Constants */
 #define SSH_MAXBLOCKS  (32 * 1024)
@@ -36,7 +37,7 @@
 #define HASH_FACTOR(x) ((x)*3/2)
 #define HASH_UNUSEDCHAR        (0xff)
 #define HASH_UNUSED    (0xffff)
-#define HASH_IV        (0xfffe)
+#define HASH_IV                (0xfffe)
 
 #define HASH_MINBLOCKS (7*SSH_BLOCKSIZE)
 
@@ -85,9 +86,9 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
 {
        static u_int16_t *h = (u_int16_t *) NULL;
        static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
-       register u_int32_t i, j;
+       u_int32_t i, j;
        u_int32_t l;
-       register u_char *c;
+       u_char *c;
        u_char *d;
 
        if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
@@ -134,7 +135,7 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
 
        for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
                for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
-                    i = (i + 1) & (n - 1)) {
+                   i = (i + 1) & (n - 1)) {
                        if (h[i] == HASH_IV) {
                                if (!CMP(c, IV)) {
                                        if (check_crc(c, buf, len, IV))
index 3c2287e5319e392bcf6f315361bd3e8dda464efd..4caea9b2c77255aafbfd1c4568609cd1513b8b8b 100644 (file)
@@ -141,6 +141,14 @@ enum
 # define       NFDBITS (8 * sizeof(unsigned long))
 #endif
 
+/*
+SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but
+including rpc/rpc.h breaks Solaris 6
+*/
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK ((ulong)0x7f000001)
+#endif
+
 /* Types */
 
 /* If sys/types.h does not supply intXX_t, supply them ourselves */
@@ -161,7 +169,11 @@ typedef char int8_t;
 typedef short int int16_t;
 # else
 #  ifdef _CRAY
+#   if (SIZEOF_SHORT_INT == 4)
+typedef short int16_t;
+#   else
 typedef long  int16_t;
+#   endif
 #  else
 #   error "16 bit int type not found."
 #  endif /* _CRAY */
@@ -194,7 +206,11 @@ typedef unsigned char u_int8_t;
 typedef unsigned short int u_int16_t;
 #  else
 #   ifdef _CRAY
+#    if (SIZEOF_SHORT_INT == 4)
+typedef unsigned short u_int16_t;
+#    else
 typedef unsigned long  u_int16_t;
+#    endif
 #   else
 #    error "16 bit int type not found."
 #   endif
@@ -269,6 +285,11 @@ typedef int pid_t;
 # define HAVE_PID_T
 #endif /* HAVE_PID_T */
 
+#ifndef HAVE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+# define HAVE_SIG_ATOMIC_T
+#endif /* HAVE_SIG_ATOMIC_T */
+
 #ifndef HAVE_MODE_T
 typedef int mode_t;
 # define HAVE_MODE_T
@@ -356,6 +377,16 @@ struct winsize {
 #define _PATH_XAUTH XAUTH_PATH
 #endif /* XAUTH_PATH */
 
+/* derived from XF4/xc/lib/dps/Xlibnet.h */
+#ifndef X_UNIX_PATH
+#  ifdef __hpux
+#    define X_UNIX_PATH "/var/spool/sockets/X11/%u"
+#  else
+#    define X_UNIX_PATH "/tmp/.X11-unix/X%u"
+#  endif
+#endif /* X_UNIX_PATH */
+#define _PATH_UNIX_X X_UNIX_PATH
+
 #ifndef _PATH_TTY
 # define _PATH_TTY "/dev/tty"
 #endif
@@ -436,7 +467,7 @@ struct winsize {
 #endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */
 
 #if !defined(HAVE_ATEXIT) && defined(HAVE_ON_EXIT)
-# define atexit(a, NULL) on_exit(a, NULL)
+# define atexit(a) on_exit(a, NULL)
 #else
 # if defined(HAVE_XATEXIT)
 #  define atexit(a) xatexit(a)
index fa2508af7a258ebace49da048e36b1a368c9c1e0..33187e02824ea54803f2e56f353caf735dda7cd7 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: dh.c,v 1.17 2001/06/23 15:12:18 itojun Exp $");
+RCSID("$OpenBSD: dh.c,v 1.21 2002/03/06 00:23:27 markus Exp $");
 
 #include "xmalloc.h"
 
@@ -78,8 +78,10 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
        if (cp != NULL || *prime == '\0')
                goto fail;
 
-       dhg->g = BN_new();
-       dhg->p = BN_new();
+       if ((dhg->g = BN_new()) == NULL)
+               fatal("parse_prime: BN_new failed");
+       if ((dhg->p = BN_new()) == NULL)
+               fatal("parse_prime: BN_new failed");
        if (BN_hex2bn(&dhg->g, gen) == 0)
                goto failclean;
 
@@ -92,8 +94,8 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
        return (1);
 
  failclean:
-       BN_free(dhg->g);
-       BN_free(dhg->p);
+       BN_clear_free(dhg->g);
+       BN_clear_free(dhg->p);
  fail:
        error("Bad prime description in line %d", linenum);
        return (0);
@@ -120,8 +122,8 @@ choose_dh(int min, int wantbits, int max)
                linenum++;
                if (!parse_prime(linenum, line, &dhg))
                        continue;
-               BN_free(dhg.g);
-               BN_free(dhg.p);
+               BN_clear_free(dhg.g);
+               BN_clear_free(dhg.p);
 
                if (dhg.size > max || dhg.size < min)
                        continue;
@@ -150,8 +152,8 @@ choose_dh(int min, int wantbits, int max)
                if ((dhg.size > max || dhg.size < min) ||
                    dhg.size != best ||
                    linenum++ != which) {
-                       BN_free(dhg.g);
-                       BN_free(dhg.p);
+                       BN_clear_free(dhg.g);
+                       BN_clear_free(dhg.p);
                        continue;
                }
                break;
@@ -201,9 +203,8 @@ dh_gen_key(DH *dh, int need)
                    BN_num_bits(dh->p), 2*need);
        do {
                if (dh->priv_key != NULL)
-                       BN_free(dh->priv_key);
-               dh->priv_key = BN_new();
-               if (dh->priv_key == NULL)
+                       BN_clear_free(dh->priv_key);
+               if ((dh->priv_key = BN_new()) == NULL)
                        fatal("dh_gen_key: BN_new failed");
                /* generate a 2*need bits random private exponent */
                if (!BN_rand(dh->priv_key, 2*need, 0, 0))
@@ -225,9 +226,8 @@ dh_new_group_asc(const char *gen, const char *modulus)
 {
        DH *dh;
 
-       dh = DH_new();
-       if (dh == NULL)
-               fatal("DH_new");
+       if ((dh = DH_new()) == NULL)
+               fatal("dh_new_group_asc: DH_new");
 
        if (BN_hex2bn(&dh->p, modulus) == 0)
                fatal("BN_hex2bn p");
@@ -247,9 +247,8 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
 {
        DH *dh;
 
-       dh = DH_new();
-       if (dh == NULL)
-               fatal("DH_new");
+       if ((dh = DH_new()) == NULL)
+               fatal("dh_new_group: DH_new");
        dh->p = modulus;
        dh->g = gen;
 
index 64873d53a1d01d81f1741e76c688769c18700f29..ce32bc22f21ecab4e5c4b94a6a91be8058321b15 100644 (file)
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: dispatch.c,v 1.11 2001/06/10 11:29:20 markus Exp $");
+RCSID("$OpenBSD: dispatch.c,v 1.15 2002/01/11 13:39:36 markus Exp $");
 
 #include "ssh1.h"
 #include "ssh2.h"
@@ -37,18 +37,40 @@ RCSID("$OpenBSD: dispatch.c,v 1.11 2001/06/10 11:29:20 markus Exp $");
 dispatch_fn *dispatch[DISPATCH_MAX];
 
 void
-dispatch_protocol_error(int type, int plen, void *ctxt)
+dispatch_protocol_error(int type, u_int32_t seq, void *ctxt)
 {
-       fatal("dispatch_protocol_error: type %d plen %d", type, plen);
+       log("dispatch_protocol_error: type %d seq %u", type, seq);
+       if (!compat20)
+               fatal("protocol error");
+       packet_start(SSH2_MSG_UNIMPLEMENTED);
+       packet_put_int(seq);
+       packet_send();
+       packet_write_wait();
+}
+void
+dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt)
+{
+       log("dispatch_protocol_ignore: type %d seq %u", type, seq);
 }
 void
 dispatch_init(dispatch_fn *dflt)
 {
-       int i;
+       u_int i;
        for (i = 0; i < DISPATCH_MAX; i++)
                dispatch[i] = dflt;
 }
 void
+dispatch_range(u_int from, u_int to, dispatch_fn *fn)
+{
+       u_int i;
+
+       for (i = from; i <= to; i++) {
+               if (i >= DISPATCH_MAX)
+                       break;
+               dispatch[i] = fn;
+       }
+}
+void
 dispatch_set(int type, dispatch_fn *fn)
 {
        dispatch[type] = fn;
@@ -57,18 +79,18 @@ void
 dispatch_run(int mode, int *done, void *ctxt)
 {
        for (;;) {
-               int plen;
                int type;
+               u_int32_t seqnr;
 
                if (mode == DISPATCH_BLOCK) {
-                       type = packet_read(&plen);
+                       type = packet_read_seqnr(&seqnr);
                } else {
-                       type = packet_read_poll(&plen);
+                       type = packet_read_poll_seqnr(&seqnr);
                        if (type == SSH_MSG_NONE)
                                return;
                }
                if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL)
-                       (*dispatch[type])(type, plen, ctxt);
+                       (*dispatch[type])(type, seqnr, ctxt);
                else
                        packet_disconnect("protocol error: rcvd type %d", type);
                if (done != NULL && *done)
index 7b94032afab083506d36b8118b283dab8161c542..a82e2165b3568844914cdf739a47fde96a408dbb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dispatch.h,v 1.6 2001/06/26 17:27:23 markus Exp $     */
+/*     $OpenBSD: dispatch.h,v 1.9 2002/01/11 13:39:36 markus Exp $     */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -28,9 +28,11 @@ enum {
        DISPATCH_NONBLOCK
 };
 
-typedef void dispatch_fn(int, int, void *);
+typedef void dispatch_fn(int, u_int32_t, void *);
 
 void    dispatch_init(dispatch_fn *);
 void    dispatch_set(int, dispatch_fn *);
+void    dispatch_range(u_int, u_int, dispatch_fn *);
 void    dispatch_run(int, int *, void *);
-void    dispatch_protocol_error(int, int, void *);
+void    dispatch_protocol_error(int, u_int32_t, void *);
+void    dispatch_protocol_ignore(int, u_int32_t, void *);
index 9588f792946f413a7d7aba2aa2e28691acabe46f..9de292112b4329e3eca9df42d26447b5ea568856 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "includes.h"
 
 #include <openssl/rand.h>
-#include <openssl/sha.h>
 #include <openssl/crypto.h>
 
-/* SunOS 4.4.4 needs this */
-#ifdef HAVE_FLOATINGPOINT_H
-# include <floatingpoint.h>
-#endif /* HAVE_FLOATINGPOINT_H */
-
 #include "ssh.h"
 #include "misc.h"
 #include "xmalloc.h"
 #include "pathnames.h"
 #include "log.h"
 
-RCSID("$Id$");
-
-#ifndef offsetof
-# define offsetof(type, member) ((size_t) &((type *)0)->member)
-#endif
-
-/* Number of times to pass through command list gathering entropy */
-#define NUM_ENTROPY_RUNS       1
-
-/* Scale entropy estimates back by this amount on subsequent runs */
-#define SCALE_PER_RUN          10.0
-
-/* Minimum number of commands to be considered valid */
-#define MIN_ENTROPY_SOURCES 16
-
-#define WHITESPACE " \t\n"
-
-#ifndef RUSAGE_SELF
-# define RUSAGE_SELF 0
-#endif
-#ifndef RUSAGE_CHILDREN
-# define RUSAGE_CHILDREN 0
-#endif
-
-#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS)
-# define SAVED_IDS_WORK_WITH_SETEUID
-#endif
-
-static void
-check_openssl_version(void) 
-{
-       if (SSLeay() != OPENSSL_VERSION_NUMBER)
-               fatal("OpenSSL version mismatch. Built against %lx, you "
-                   "have %lx", OPENSSL_VERSION_NUMBER, SSLeay());
-}
-
-#if defined(PRNGD_SOCKET) || defined(PRNGD_PORT)
-# define USE_PRNGD
-#endif
-
-#if defined(USE_PRNGD) || defined(RANDOM_POOL)
-
-#ifdef USE_PRNGD
-/* Collect entropy from PRNGD/EGD */
-int
-get_random_bytes(unsigned char *buf, int len)
-{
-       int fd;
-       char msg[2];
-#ifdef PRNGD_PORT
-       struct sockaddr_in addr;
-#else
-       struct sockaddr_un addr;
-#endif
-       int addr_len, rval, errors;
-       mysig_t old_sigpipe;
-
-       memset(&addr, '\0', sizeof(addr));
-
-#ifdef PRNGD_PORT
-       addr.sin_family = AF_INET;
-       addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-       addr.sin_port = htons(PRNGD_PORT);
-       addr_len = sizeof(struct sockaddr_in);
-#else /* use IP socket PRNGD_SOCKET instead */
-       /* Sanity checks */
-       if (sizeof(PRNGD_SOCKET) > sizeof(addr.sun_path))
-               fatal("Random pool path is too long");
-       if (len > 255)
-               fatal("Too many bytes to read from PRNGD");
-
-       addr.sun_family = AF_UNIX;
-       strlcpy(addr.sun_path, PRNGD_SOCKET, sizeof(addr.sun_path));
-       addr_len = offsetof(struct sockaddr_un, sun_path) +
-           sizeof(PRNGD_SOCKET);
-#endif
-
-       old_sigpipe = mysignal(SIGPIPE, SIG_IGN);
-
-       errors = rval = 0;
-reopen:
-#ifdef PRNGD_PORT
-       fd = socket(addr.sin_family, SOCK_STREAM, 0);
-       if (fd == -1) {
-               error("Couldn't create AF_INET socket: %s", strerror(errno));
-               goto done;
-       }
-#else
-       fd = socket(addr.sun_family, SOCK_STREAM, 0);
-       if (fd == -1) {
-               error("Couldn't create AF_UNIX socket: %s", strerror(errno));
-               goto done;
-       }
-#endif
-
-       if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
-#ifdef PRNGD_PORT
-               error("Couldn't connect to PRNGD port %d: %s",
-                   PRNGD_PORT, strerror(errno));
-#else
-               error("Couldn't connect to PRNGD socket \"%s\": %s",
-                   addr.sun_path, strerror(errno));
-#endif
-               goto done;
-       }
-
-       /* Send blocking read request to PRNGD */
-       msg[0] = 0x02;
-       msg[1] = len;
-
-       if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
-               if (errno == EPIPE && errors < 10) {
-                       close(fd);
-                       errors++;
-                       goto reopen;
-               }
-               error("Couldn't write to PRNGD socket: %s",
-                   strerror(errno));
-               goto done;
-       }
-
-       if (atomicio(read, fd, buf, len) != len) {
-               if (errno == EPIPE && errors < 10) {
-                       close(fd);
-                       errors++;
-                       goto reopen;
-               }
-               error("Couldn't read from PRNGD socket: %s",
-                   strerror(errno));
-               goto done;
-       }
-
-       rval = 1;
-done:
-       mysignal(SIGPIPE, old_sigpipe);
-       if (fd != -1)
-               close(fd);
-       return(rval);
-}
-#else /* !USE_PRNGD */
-#ifdef RANDOM_POOL
-/* Collect entropy from /dev/urandom or pipe */
-static int
-get_random_bytes(unsigned char *buf, int len)
-{
-       int random_pool;
-
-       random_pool = open(RANDOM_POOL, O_RDONLY);
-       if (random_pool == -1) {
-               error("Couldn't open random pool \"%s\": %s",
-                       RANDOM_POOL, strerror(errno));
-               return(0);
-       }
-
-       if (atomicio(read, random_pool, buf, len) != len) {
-               error("Couldn't read from random pool \"%s\": %s",
-                       RANDOM_POOL, strerror(errno));
-               close(random_pool);
-               return(0);
-       }
-
-       close(random_pool);
-
-       return(1);
-}
-#endif /* RANDOM_POOL */
-#endif /* USE_PRNGD */
-
 /*
- * Seed OpenSSL's random number pool from Kernel random number generator
- * or PRNGD/EGD
+ * Portable OpenSSH PRNG seeding:
+ * If OpenSSL has not "internally seeded" itself (e.g. pulled data from 
+ * /dev/random), then we execute a "ssh-rand-helper" program which 
+ * collects entropy and writes it to stdout. The child program must 
+ * write at least RANDOM_SEED_SIZE bytes. The child is run with stderr
+ * attached, so error/debugging output should be visible.
+ *
+ * XXX: we should tell the child how many bytes we need.
  */
-void
-seed_rng(void)
-{
-       unsigned char buf[32];
 
-       debug("Seeding random number generator");
-
-       if (!get_random_bytes(buf, sizeof(buf))) {
-               if (!RAND_status())
-                       fatal("Entropy collection failed and entropy exhausted");
-       } else {
-               RAND_add(buf, sizeof(buf), sizeof(buf));
-       }
+RCSID("$Id$");
 
-       memset(buf, '\0', sizeof(buf));
-}
+#ifndef OPENSSL_PRNG_ONLY
+#define RANDOM_SEED_SIZE 48
+static uid_t original_uid, original_euid;
+#endif
 
 void
-init_rng(void) 
-{
-       check_openssl_version();
-}
-
-#else /* defined(USE_PRNGD) || defined(RANDOM_POOL) */
-
-/*
- * FIXME: proper entropy estimations. All current values are guesses
- * FIXME: (ATL) do estimates at compile time?
- * FIXME: More entropy sources
- */
-
-/* slow command timeouts (all in milliseconds) */
-/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */
-static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC;
-
-static int prng_seed_saved = 0;
-static int prng_initialised = 0;
-uid_t original_uid;
-
-typedef struct
-{
-       /* Proportion of data that is entropy */
-       double rate;
-       /* Counter goes positive if this command times out */
-       unsigned int badness;
-       /* Increases by factor of two each timeout */
-       unsigned int sticky_badness;
-       /* Path to executable */
-       char *path;
-       /* argv to pass to executable */
-       char *args[5];
-       /* full command string (debug) */
-       char *cmdstring;
-} entropy_source_t;
-
-double stir_from_system(void);
-double stir_from_programs(void);
-double stir_gettimeofday(double entropy_estimate);
-double stir_clock(double entropy_estimate);
-double stir_rusage(int who, double entropy_estimate);
-double hash_output_from_command(entropy_source_t *src, char *hash);
-
-/* this is initialised from a file, by prng_read_commands() */
-entropy_source_t *entropy_sources = NULL;
-
-double
-stir_from_system(void)
-{
-       double total_entropy_estimate;
-       long int i;
-
-       total_entropy_estimate = 0;
-
-       i = getpid();
-       RAND_add(&i, sizeof(i), 0.5);
-       total_entropy_estimate += 0.1;
-
-       i = getppid();
-       RAND_add(&i, sizeof(i), 0.5);
-       total_entropy_estimate += 0.1;
-
-       i = getuid();
-       RAND_add(&i, sizeof(i), 0.0);
-       i = getgid();
-       RAND_add(&i, sizeof(i), 0.0);
-
-       total_entropy_estimate += stir_gettimeofday(1.0);
-       total_entropy_estimate += stir_clock(0.5);
-       total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0);
-
-       return(total_entropy_estimate);
-}
-
-double
-stir_from_programs(void)
-{
-       int i;
-       int c;
-       double entropy_estimate;
-       double total_entropy_estimate;
-       char hash[SHA_DIGEST_LENGTH];
-
-       total_entropy_estimate = 0;
-       for(i = 0; i < NUM_ENTROPY_RUNS; i++) {
-               c = 0;
-               while (entropy_sources[c].path != NULL) {
-
-                       if (!entropy_sources[c].badness) {
-                               /* Hash output from command */
-                               entropy_estimate = hash_output_from_command(&entropy_sources[c], hash);
-
-                               /* Scale back entropy estimate according to command's rate */
-                               entropy_estimate *= entropy_sources[c].rate;
-
-                               /* Upper bound of entropy estimate is SHA_DIGEST_LENGTH */
-                               if (entropy_estimate > SHA_DIGEST_LENGTH)
-                                       entropy_estimate = SHA_DIGEST_LENGTH;
-
-                               /* Scale back estimates for subsequent passes through list */
-                               entropy_estimate /= SCALE_PER_RUN * (i + 1.0);
-
-                               /* Stir it in */
-                               RAND_add(hash, sizeof(hash), entropy_estimate);
-
-                               debug3("Got %0.2f bytes of entropy from '%s'", entropy_estimate,
-                                       entropy_sources[c].cmdstring);
-
-                               total_entropy_estimate += entropy_estimate;
-
-                       /* Execution times should be a little unpredictable */
-                               total_entropy_estimate += stir_gettimeofday(0.05);
-                               total_entropy_estimate += stir_clock(0.05);
-                               total_entropy_estimate += stir_rusage(RUSAGE_SELF, 0.1);
-                               total_entropy_estimate += stir_rusage(RUSAGE_CHILDREN, 0.1);
-                       } else {
-                               debug2("Command '%s' disabled (badness %d)",
-                                       entropy_sources[c].cmdstring, entropy_sources[c].badness);
-
-                               if (entropy_sources[c].badness > 0)
-                                       entropy_sources[c].badness--;
-                       }
-
-                       c++;
-               }
-       }
-
-       return(total_entropy_estimate);
-}
-
-double
-stir_gettimeofday(double entropy_estimate)
-{
-       struct timeval tv;
-
-       if (gettimeofday(&tv, NULL) == -1)
-               fatal("Couldn't gettimeofday: %s", strerror(errno));
-
-       RAND_add(&tv, sizeof(tv), entropy_estimate);
-
-       return(entropy_estimate);
-}
-
-double
-stir_clock(double entropy_estimate)
-{
-#ifdef HAVE_CLOCK
-       clock_t c;
-
-       c = clock();
-       RAND_add(&c, sizeof(c), entropy_estimate);
-
-       return(entropy_estimate);
-#else /* _HAVE_CLOCK */
-       return(0);
-#endif /* _HAVE_CLOCK */
-}
-
-double
-stir_rusage(int who, double entropy_estimate)
-{
-#ifdef HAVE_GETRUSAGE
-       struct rusage ru;
-
-       if (getrusage(who, &ru) == -1)
-               return(0);
-
-       RAND_add(&ru, sizeof(ru), entropy_estimate);
-
-       return(entropy_estimate);
-#else /* _HAVE_GETRUSAGE */
-       return(0);
-#endif /* _HAVE_GETRUSAGE */
-}
-
-
-static int
-_get_timeval_msec_difference(struct timeval *t1, struct timeval *t2) {
-       int secdiff, usecdiff;
-
-       secdiff = t2->tv_sec - t1->tv_sec;
-       usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec);
-       return (int)(usecdiff / 1000);
-}
-
-double
-hash_output_from_command(entropy_source_t *src, char *hash)
+seed_rng(void)
 {
-       static int devnull = -1;
+#ifndef OPENSSL_PRNG_ONLY
+       int devnull;
        int p[2];
-       fd_set rdset;
-       int cmd_eof = 0, error_abort = 0;
-       struct timeval tv_start, tv_current;
-       int msec_elapsed = 0;
        pid_t pid;
-       int status;
-       char buf[16384];
-       int bytes_read;
-       int total_bytes_read;
-       SHA_CTX sha;
-
-       debug3("Reading output from \'%s\'", src->cmdstring);
-
-       if (devnull == -1) {
-               devnull = open("/dev/null", O_RDWR);
-               if (devnull == -1)
-                       fatal("Couldn't open /dev/null: %s", strerror(errno));
-       }
-
-       if (pipe(p) == -1)
-               fatal("Couldn't open pipe: %s", strerror(errno));
-
-       (void)gettimeofday(&tv_start, NULL); /* record start time */
-
-       switch (pid = fork()) {
-               case -1: /* Error */
-                       close(p[0]);
-                       close(p[1]);
-                       fatal("Couldn't fork: %s", strerror(errno));
-                       /* NOTREACHED */
-               case 0: /* Child */
-                       dup2(devnull, STDIN_FILENO);
-                       dup2(p[1], STDOUT_FILENO);
-                       dup2(p[1], STDERR_FILENO);
-                       close(p[0]);
-                       close(p[1]);
-                       close(devnull);
-
-                       setuid(original_uid);
-                       execv(src->path, (char**)(src->args));
-                       debug("(child) Couldn't exec '%s': %s", src->cmdstring,
-                             strerror(errno));
-                       _exit(-1);
-               default: /* Parent */
-                       break;
-       }
-
-       RAND_add(&pid, sizeof(&pid), 0.0);
-
-       close(p[1]);
-
-       /* Hash output from child */
-       SHA1_Init(&sha);
-       total_bytes_read = 0;
-
-       while (!error_abort && !cmd_eof) {
-               int ret;
-               struct timeval tv;
-               int msec_remaining;
-
-               (void) gettimeofday(&tv_current, 0);
-               msec_elapsed = _get_timeval_msec_difference(&tv_start, &tv_current);
-               if (msec_elapsed >= entropy_timeout_current) {
-                       error_abort=1;
-                       continue;
-               }
-               msec_remaining = entropy_timeout_current - msec_elapsed;
-
-               FD_ZERO(&rdset);
-               FD_SET(p[0], &rdset);
-               tv.tv_sec =  msec_remaining / 1000;
-               tv.tv_usec = (msec_remaining % 1000) * 1000;
-
-               ret = select(p[0]+1, &rdset, NULL, NULL, &tv);
-
-               RAND_add(&tv, sizeof(tv), 0.0);
-
-               switch (ret) {
-               case 0:
-                       /* timer expired */
-                       error_abort = 1;
-                       break;
-               case 1:
-                       /* command input */
-                       do {
-                               bytes_read = read(p[0], buf, sizeof(buf));
-                       } while (bytes_read == -1 && errno == EINTR);
-                       RAND_add(&bytes_read, sizeof(&bytes_read), 0.0);
-                       if (bytes_read == -1) {
-                               error_abort = 1;
-                               break;
-                       } else if (bytes_read) {
-                               SHA1_Update(&sha, buf, bytes_read);
-                               total_bytes_read += bytes_read;
-                       } else {
-                               cmd_eof = 1;
-                       }
-                       break;
-               case -1:
-               default:
-                       /* error */
-                       debug("Command '%s': select() failed: %s", src->cmdstring,
-                             strerror(errno));
-                       error_abort = 1;
-                       break;
-               }
-       }
-
-       SHA1_Final(hash, &sha);
-
-       close(p[0]);
-
-       debug3("Time elapsed: %d msec", msec_elapsed);
-
-       if (waitpid(pid, &status, 0) == -1) {
-              error("Couldn't wait for child '%s' completion: %s", src->cmdstring,
-                    strerror(errno));
-               return(0.0);
-       }
-
-       RAND_add(&status, sizeof(&status), 0.0);
-
-       if (error_abort) {
-               /* closing p[0] on timeout causes the entropy command to
-                * SIGPIPE. Take whatever output we got, and mark this command
-                * as slow */
-               debug2("Command '%s' timed out", src->cmdstring);
-               src->sticky_badness *= 2;
-               src->badness = src->sticky_badness;
-               return(total_bytes_read);
-       }
-
-       if (WIFEXITED(status)) {
-               if (WEXITSTATUS(status)==0) {
-                       return(total_bytes_read);
-               } else {
-                       debug2("Command '%s' exit status was %d", src->cmdstring,
-                               WEXITSTATUS(status));
-                       src->badness = src->sticky_badness = 128;
-                       return (0.0);
-               }
-       } else if (WIFSIGNALED(status)) {
-               debug2("Command '%s' returned on uncaught signal %d !", src->cmdstring,
-                       status);
-               src->badness = src->sticky_badness = 128;
-               return(0.0);
-       } else
-               return(0.0);
-}
-
-/*
- * prng seedfile functions
- */
-int
-prng_check_seedfile(char *filename) {
+       int ret;
+       unsigned char buf[RANDOM_SEED_SIZE];
 
-       struct stat st;
-
-       /* FIXME raceable: eg replace seed between this stat and subsequent open */
-       /* Not such a problem because we don't trust the seed file anyway */
-       if (lstat(filename, &st) == -1) {
-               /* Give up on hard errors */
-               if (errno != ENOENT)
-                       debug("WARNING: Couldn't stat random seed file \"%s\": %s",
-                          filename, strerror(errno));
-
-               return(0);
-       }
-
-       /* regular file? */
-       if (!S_ISREG(st.st_mode))
-               fatal("PRNG seedfile %.100s is not a regular file", filename);
-
-       /* mode 0600, owned by root or the current user? */
-       if (((st.st_mode & 0177) != 0) || !(st.st_uid == original_uid)) {
-               debug("WARNING: PRNG seedfile %.100s must be mode 0600, owned by uid %d",
-                        filename, getuid());
-               return(0);
-       }
-
-       return(1);
-}
-
-void
-prng_write_seedfile(void) {
-       int fd;
-       char seed[1024];
-       char filename[1024];
-       struct passwd *pw;
-
-       /* Don't bother if we have already saved a seed */
-       if (prng_seed_saved)
+       if (RAND_status() == 1) {
+               debug3("RNG is ready, skipping seeding");
                return;
-
-       setuid(original_uid);
-
-       prng_seed_saved = 1;
-
-       pw = getpwuid(original_uid);
-       if (pw == NULL)
-               fatal("Couldn't get password entry for current user (%i): %s",
-                       original_uid, strerror(errno));
-
-       /* Try to ensure that the parent directory is there */
-       snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
-               _PATH_SSH_USER_DIR);
-       mkdir(filename, 0700);
-
-       snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
-               SSH_PRNG_SEED_FILE);
-
-       debug("writing PRNG seed to file %.100s", filename);
-
-       RAND_bytes(seed, sizeof(seed));
-
-       /* Don't care if the seed doesn't exist */
-       prng_check_seedfile(filename);
-
-       if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) {
-               debug("WARNING: couldn't access PRNG seedfile %.100s (%.100s)",
-                  filename, strerror(errno));
-       } else {
-               if (atomicio(write, fd, &seed, sizeof(seed)) != sizeof(seed))
-                       fatal("problem writing PRNG seedfile %.100s (%.100s)", filename,
-                                strerror(errno));
-
-               close(fd);
-       }
-}
-
-void
-prng_read_seedfile(void) {
-       int fd;
-       char seed[1024];
-       char filename[1024];
-       struct passwd *pw;
-
-       pw = getpwuid(original_uid);
-       if (pw == NULL)
-               fatal("Couldn't get password entry for current user (%i): %s",
-                       original_uid, strerror(errno));
-
-       snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
-               SSH_PRNG_SEED_FILE);
-
-       debug("loading PRNG seed from file %.100s", filename);
-
-       if (!prng_check_seedfile(filename)) {
-               verbose("Random seed file not found or not valid, ignoring.");
-               return;
-       }
-
-       /* open the file and read in the seed */
-       fd = open(filename, O_RDONLY);
-       if (fd == -1)
-               fatal("could not open PRNG seedfile %.100s (%.100s)", filename,
-                       strerror(errno));
-
-       if (atomicio(read, fd, &seed, sizeof(seed)) != sizeof(seed)) {
-               verbose("invalid or short read from PRNG seedfile %.100s - ignoring",
-                       filename);
-               memset(seed, '\0', sizeof(seed));
        }
-       close(fd);
 
-       /* stir in the seed, with estimated entropy zero */
-       RAND_add(&seed, sizeof(seed), 0.0);
-}
-
-
-/*
- * entropy command initialisation functions
- */
-int
-prng_read_commands(char *cmdfilename)
-{
-       FILE *f;
-       char *cp;
-       char line[1024];
-       char cmd[1024];
-       char path[256];
-       int linenum;
-       int num_cmds = 64;
-       int cur_cmd = 0;
-       double est;
-       entropy_source_t *entcmd;
-
-       f = fopen(cmdfilename, "r");
-       if (!f) {
-               fatal("couldn't read entropy commands file %.100s: %.100s",
-                   cmdfilename, strerror(errno));
-       }
-
-       entcmd = (entropy_source_t *)xmalloc(num_cmds * sizeof(entropy_source_t));
-       memset(entcmd, '\0', num_cmds * sizeof(entropy_source_t));
+       debug3("Seeing PRNG from %s", SSH_RAND_HELPER);
 
-       /* Read in file */
-       linenum = 0;
-       while (fgets(line, sizeof(line), f)) {
-               int arg;
-               char *argv;
-
-               linenum++;
-
-               /* skip leading whitespace, test for blank line or comment */
-               cp = line + strspn(line, WHITESPACE);
-               if ((*cp == 0) || (*cp == '#'))
-                       continue; /* done with this line */
-
-               /* First non-whitespace char should be double quote delimiting */
-               /* commandline */
-               if (*cp != '"') {
-                       error("bad entropy command, %.100s line %d", cmdfilename,
-                            linenum);
-                       continue;
-               }
-
-               /* first token, command args (incl. argv[0]) in double quotes */
-               cp = strtok(cp, "\"");
-               if (cp == NULL) {
-                       error("missing or bad command string, %.100s line %d -- ignored",
-                             cmdfilename, linenum);
-                       continue;
-               }
-               strlcpy(cmd, cp, sizeof(cmd));
-
-               /* second token, full command path */
-               if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
-                       error("missing command path, %.100s line %d -- ignored",
-                             cmdfilename, linenum);
-                       continue;
-               }
-
-               /* did configure mark this as dead? */
-               if (strncmp("undef", cp, 5) == 0)
-                       continue;
-
-               strlcpy(path, cp, sizeof(path));
-
-               /* third token, entropy rate estimate for this command */
-               if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
-                       error("missing entropy estimate, %.100s line %d -- ignored",
-                             cmdfilename, linenum);
-                       continue;
-               }
-               est = strtod(cp, &argv);
-
-               /* end of line */
-               if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
-                       error("garbage at end of line %d in %.100s -- ignored", linenum,
-                               cmdfilename);
-                       continue;
-               }
-
-               /* save the command for debug messages */
-               entcmd[cur_cmd].cmdstring = xstrdup(cmd);
-
-               /* split the command args */
-               cp = strtok(cmd, WHITESPACE);
-               arg = 0;
-               argv = NULL;
-               do {
-                       char *s = (char*)xmalloc(strlen(cp) + 1);
-                       strncpy(s, cp, strlen(cp) + 1);
-                       entcmd[cur_cmd].args[arg] = s;
-                       arg++;
-               } while ((arg < 5) && (cp = strtok(NULL, WHITESPACE)));
-
-               if (strtok(NULL, WHITESPACE))
-                       error("ignored extra command elements (max 5), %.100s line %d",
-                             cmdfilename, linenum);
-
-               /* Copy the command path and rate estimate */
-               entcmd[cur_cmd].path = xstrdup(path);
-               entcmd[cur_cmd].rate = est;
-
-               /* Initialise other values */
-               entcmd[cur_cmd].sticky_badness = 1;
-
-               cur_cmd++;
-
-               /* If we've filled the array, reallocate it twice the size */
-               /* Do this now because even if this we're on the last command,
-                  we need another slot to mark the last entry */
-               if (cur_cmd == num_cmds) {
-                       num_cmds *= 2;
-                       entcmd = xrealloc(entcmd, num_cmds * sizeof(entropy_source_t));
+       if ((devnull = open("/dev/null", O_RDWR)) == -1)
+               fatal("Couldn't open /dev/null: %s", strerror(errno));
+       if (pipe(p) == -1)
+               fatal("pipe: %s", strerror(errno));
+
+       if ((pid = fork()) == -1)
+               fatal("Couldn't fork: %s", strerror(errno));
+       if (pid == 0) {
+               dup2(devnull, STDIN_FILENO);
+               dup2(p[1], STDOUT_FILENO);
+               /* Keep stderr open for errors */
+               close(p[0]);
+               close(p[1]);
+               close(devnull);
+
+               if (original_uid != original_euid && 
+                   setuid(original_uid) == -1) {
+                       fprintf(stderr, "(rand child) setuid: %s\n", 
+                           strerror(errno));
+                       _exit(1);
                }
+               
+               execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL);
+               fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n", 
+                   SSH_RAND_HELPER, strerror(errno));
+               _exit(1);
        }
 
-       /* zero the last entry */
-       memset(&entcmd[cur_cmd], '\0', sizeof(entropy_source_t));
-
-       /* trim to size */
-       entropy_sources = xrealloc(entcmd, (cur_cmd+1) * sizeof(entropy_source_t));
-
-       debug("Loaded %d entropy commands from %.100s", cur_cmd, cmdfilename);
-
-       return (cur_cmd >= MIN_ENTROPY_SOURCES);
-}
-
-/*
- * Write a keyfile at exit
- */
-void
-prng_seed_cleanup(void *junk)
-{
-       prng_write_seedfile();
-}
-
-/*
- * Conditionally Seed OpenSSL's random number pool from
- * syscalls and program output
- */
-void
-seed_rng(void)
-{
-       mysig_t old_sigchld_handler;
+       close(devnull);
+       close(p[1]);
 
-       if (!prng_initialised)
-               fatal("RNG not initialised");
+       memset(buf, '\0', sizeof(buf));
+       ret = atomicio(read, p[0], buf, sizeof(buf));
+       if (ret == -1)
+               fatal("Couldn't read from ssh-rand-helper: %s",
+                   strerror(errno));
+       if (ret != sizeof(buf))
+               fatal("ssh-rand-helper child produced insufficient data");
 
-       /* Make sure some other sigchld handler doesn't reap our entropy */
-       /* commands */
-       old_sigchld_handler = mysignal(SIGCHLD, SIG_DFL);
+       close(p[0]);
 
-       debug("Seeded RNG with %i bytes from programs", 
-           (int)stir_from_programs());
-       debug("Seeded RNG with %i bytes from system calls", 
-           (int)stir_from_system());
+       if (waitpid(pid, &ret, 0) == -1)
+              fatal("Couldn't wait for ssh-rand-helper completion: %s", 
+                  strerror(errno));
 
-       if (!RAND_status())
-               fatal("Not enough entropy in RNG");
+       /* We don't mind if the child exits upon a SIGPIPE */
+       if (!WIFEXITED(ret) && 
+           (!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE))
+               fatal("ssh-rand-helper terminated abnormally");
+       if (WEXITSTATUS(ret) != 0)
+               fatal("ssh-rand-helper exit with exit status %d", ret);
 
-       mysignal(SIGCHLD, old_sigchld_handler);
+       RAND_add(buf, sizeof(buf), sizeof(buf));
+       memset(buf, '\0', sizeof(buf));
 
-       if (!RAND_status())
-               fatal("Couldn't initialise builtin random number generator -- exiting.");
+#endif /* OPENSSL_PRNG_ONLY */
+       if (RAND_status() != 1)
+               fatal("PRNG is not seeded");
 }
 
 void
-init_rng(void)
+init_rng(void) 
 {
-       int original_euid;
-
-       check_openssl_version();
-
-       original_uid = getuid();
-       original_euid = geteuid();
-
-       /* Read in collection commands */
-       if (!prng_read_commands(SSH_PRNG_COMMAND_FILE))
-               fatal("PRNG initialisation failed -- exiting.");
-
-       /* Set ourselves up to save a seed upon exit */
-       prng_seed_saved = 0;
-
-       /* Give up privs while reading seed file */
-#ifdef SAVED_IDS_WORK_WITH_SETEUID
-       if ((original_uid != original_euid) && (seteuid(original_uid) == -1))
-               fatal("Couldn't give up privileges");
-#else /* SAVED_IDS_WORK_WITH_SETEUID */
        /*
-        * Propagate the privileged uid to all of our uids.
-        * Set the effective uid to the given (unprivileged) uid. 
+        * OpenSSL version numbers: MNNFFPPS: major minor fix patch status
+        * We match major, minor, fix and status (not patch)
         */
-       if (original_uid != original_euid && (setuid(original_euid) == -1 || 
-           seteuid(original_uid) == -1))
-               fatal("Couldn't give up privileges");
-#endif /* SAVED_IDS_WORK_WITH_SETEUID */
-
-       prng_read_seedfile();
-
-#ifdef SAVED_IDS_WORK_WITH_SETEUID
-       if ((original_uid != original_euid) && (seteuid(original_euid) == -1))
-               fatal("Couldn't restore privileges");
-#else /* SAVED_IDS_WORK_WITH_SETEUID */
-       /*
-        * We are unable to restore the real uid to its unprivileged value.
-        * Propagate the real uid (usually more privileged) to effective uid
-        * as well.
-        */
-       if (original_uid != original_euid && (seteuid(original_euid) == -1 || 
-           setuid(original_uid) == -1))
-               fatal("Couldn't restore privileges");
-#endif /* SAVED_IDS_WORK_WITH_SETEUID */
-
-       fatal_add_cleanup(prng_seed_cleanup, NULL);
-       atexit(prng_write_seedfile);
+       if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L)
+               fatal("OpenSSL version mismatch. Built against %lx, you "
+                   "have %lx", OPENSSL_VERSION_NUMBER, SSLeay());
 
-       prng_initialised = 1;
+#ifndef OPENSSL_PRNG_ONLY
+       if ((original_uid = getuid()) == -1)
+               fatal("getuid: %s", strerror(errno));
+       if ((original_euid = geteuid()) == -1)
+               fatal("geteuid: %s", strerror(errno));
+#endif
 }
 
-#endif /* defined(USE_PRNGD) || defined(RANDOM_POOL) */
diff --git a/openssh/fatal.c b/openssh/fatal.c
new file mode 100644 (file)
index 0000000..9e7d160
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: fatal.c,v 1.1 2002/02/22 12:20:34 markus Exp $");
+
+#include "log.h"
+
+/* Fatal messages.  This function never returns. */
+
+void
+fatal(const char *fmt,...)
+{
+       va_list args;
+       va_start(args, fmt);
+       do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+       va_end(args);
+       fatal_cleanup();
+}
index 1a19d22cdb00be49b49a71afc27e9362b0f72da5..20cf8f20b30a03550e46106c7a06c54ef8bdbd0a 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: getput.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $      */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: getput.h,v 1.7 2001/01/10 22:56:22 markus Exp $"); */
-
 #ifndef GETPUT_H
 #define GETPUT_H
 
index cbfe720356d49dd3964ceea09d9a104799ba0d8e..66dfa68fe1f86868e8b6ff9bdf9abbdab89b8ca7 100644 (file)
@@ -1,5 +1,3 @@
-/*     $OpenBSD: groupaccess.c,v 1.4 2001/06/26 17:27:23 markus Exp $  */
-
 /*
  * Copyright (c) 2001 Kevin Steves.  All rights reserved.
  *
@@ -25,6 +23,7 @@
  */
 
 #include "includes.h"
+RCSID("$OpenBSD: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $");
 
 #include "groupaccess.h"
 #include "xmalloc.h"
index eeed920fa797a15f42d5e4eb598486be413c5699..cefff8d627650409b3efcffa1e666b17fadef4e8 100644 (file)
@@ -36,7 +36,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: hostfile.c,v 1.28 2001/06/25 08:25:37 markus Exp $");
+RCSID("$OpenBSD: hostfile.c,v 1.29 2001/12/18 10:04:21 jakob Exp $");
 
 #include "packet.h"
 #include "match.h"
@@ -49,7 +49,7 @@ RCSID("$OpenBSD: hostfile.c,v 1.28 2001/06/25 08:25:37 markus Exp $");
  * pointer over the key.  Skips any whitespace at the beginning and at end.
  */
 
-static int
+int
 hostfile_read_key(char **cpp, u_int *bitsp, Key *ret)
 {
        char *cp;
@@ -71,17 +71,6 @@ hostfile_read_key(char **cpp, u_int *bitsp, Key *ret)
        return 1;
 }
 
-int
-auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n)
-{
-       Key *k = key_new(KEY_RSA1);
-       int ret = hostfile_read_key(cpp, bitsp, k);
-       BN_copy(e, k->rsa->e);
-       BN_copy(n, k->rsa->n);
-       key_free(k);
-       return ret;
-}
-
 static int
 hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
 {
index 05ef69174d71ca2fe5a360adb7b9f98a72cb0b77..0244fdb53ea49f7556bfd838ff04d041200c6bcb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: hostfile.h,v 1.9 2001/06/26 17:27:23 markus Exp $     */
+/*     $OpenBSD: hostfile.h,v 1.10 2001/12/18 10:04:21 jakob Exp $     */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -18,9 +18,9 @@ typedef enum {
        HOST_OK, HOST_NEW, HOST_CHANGED
 }       HostStatus;
 
+int     hostfile_read_key(char **, u_int *, Key *);
 HostStatus
 check_host_in_hostfile(const char *, const char *, Key *, Key *, int *);
 int     add_host_to_hostfile(const char *, const char *, Key *);
-int     auth_rsa_read_key(char **, u_int *, BIGNUM *, BIGNUM *);
 
 #endif
index f9cf9c73ea4063b4741ba21d9f80e9e89689b8eb..4740418a75ae5ea795af02fd7f3dbcfb4d7fca6d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: includes.h,v 1.15 2001/06/08 15:25:40 markus Exp $    */
+/*     $OpenBSD: includes.h,v 1.17 2002/01/26 16:44:22 stevesk Exp $   */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
index 1a412ce0fcab2c98104d184d046b7b3c852a7880..bf8fd95b4a289a3f0ea0bffdc0ced3d88f8b1509 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.36 2001/06/25 08:25:37 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
 
 #include <openssl/crypto.h>
 
@@ -107,27 +107,23 @@ kex_prop_free(char **proposal)
 }
 
 static void
-kex_protocol_error(int type, int plen, void *ctxt)
+kex_protocol_error(int type, u_int32_t seq, void *ctxt)
 {
-       error("Hm, kex protocol error: type %d plen %d", type, plen);
+       error("Hm, kex protocol error: type %d seq %u", type, seq);
 }
 
 static void
-kex_clear_dispatch(void)
+kex_reset_dispatch(void)
 {
-       int i;
-
-       /* Numbers 30-49 are used for kex packets */
-       for (i = 30; i <= 49; i++)
-               dispatch_set(i, &kex_protocol_error);
+       dispatch_range(SSH2_MSG_TRANSPORT_MIN,
+           SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
+       dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
 }
 
 void
 kex_finish(Kex *kex)
 {
-       int plen;
-
-       kex_clear_dispatch();
+       kex_reset_dispatch();
 
        packet_start(SSH2_MSG_NEWKEYS);
        packet_send();
@@ -135,7 +131,8 @@ kex_finish(Kex *kex)
        debug("SSH2_MSG_NEWKEYS sent");
 
        debug("waiting for SSH2_MSG_NEWKEYS");
-       packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
+       packet_read_expect(SSH2_MSG_NEWKEYS);
+       packet_check_eom();
        debug("SSH2_MSG_NEWKEYS received");
 
        kex->done = 1;
@@ -166,7 +163,7 @@ kex_send_kexinit(Kex *kex)
 }
 
 void
-kex_input_kexinit(int type, int plen, void *ctxt)
+kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
 {
        char *ptr;
        int dlen;
@@ -187,7 +184,7 @@ kex_input_kexinit(int type, int plen, void *ctxt)
                xfree(packet_get_string(NULL));
        packet_get_char();
        packet_get_int();
-       packet_done();
+       packet_check_eom();
 
        kex_kexinit_finish(kex);
 }
@@ -205,8 +202,7 @@ kex_setup(char *proposal[PROPOSAL_MAX])
        kex->done = 0;
 
        kex_send_kexinit(kex);                                  /* we start */
-       kex_clear_dispatch();
-       dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
+       kex_reset_dispatch();
 
        return kex;
 }
@@ -219,7 +215,7 @@ kex_kexinit_finish(Kex *kex)
 
        kex_choose_conf(kex);
 
-       switch(kex->kex_type) {
+       switch (kex->kex_type) {
        case DH_GRP1_SHA1:
                kexdh(kex);
                break;
@@ -237,13 +233,14 @@ 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);
-       enc->cipher = cipher_by_name(name);
-       if (enc->cipher == NULL)
+       if ((enc->cipher = cipher_by_name(name)) == NULL)
                fatal("matching cipher is not supported: %s", name);
        enc->name = name;
        enc->enabled = 0;
        enc->iv = NULL;
        enc->key = NULL;
+       enc->key_len = cipher_keylen(enc->cipher);
+       enc->block_size = cipher_blocksize(enc->cipher);
 }
 static void
 choose_mac(Mac *mac, char *client, char *server)
@@ -346,10 +343,10 @@ kex_choose_conf(Kex *kex)
        need = 0;
        for (mode = 0; mode < MODE_MAX; mode++) {
                newkeys = kex->newkeys[mode];
-               if (need < newkeys->enc.cipher->key_len)
-                       need = newkeys->enc.cipher->key_len;
-               if (need < newkeys->enc.cipher->block_size)
-                       need = newkeys->enc.cipher->block_size;
+               if (need < newkeys->enc.key_len)
+                       need = newkeys->enc.key_len;
+               if (need < newkeys->enc.block_size)
+                       need = newkeys->enc.block_size;
                if (need < newkeys->mac.key_len)
                        need = newkeys->mac.key_len;
        }
@@ -364,11 +361,11 @@ static u_char *
 derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
 {
        Buffer b;
-       EVP_MD *evp_md = EVP_sha1();
+       const EVP_MD *evp_md = EVP_sha1();
        EVP_MD_CTX md;
        char c = id;
        int have;
-       int mdsz = evp_md->md_size;
+       int mdsz = EVP_MD_size(evp_md);
        u_char *digest = xmalloc(roundup(need, mdsz));
 
        buffer_init(&b);
@@ -444,7 +441,7 @@ dump_digest(char *msg, u_char *digest, int len)
        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");
index fe339211af78417397a9707b853ecabf18b48ddb..755bf332aa40b52ddd26abc31a82e626a4a63a58 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kex.h,v 1.26 2001/06/26 17:27:23 markus Exp $ */
+/*     $OpenBSD: kex.h,v 1.29 2002/02/14 23:41:01 markus Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -71,6 +71,8 @@ struct Enc {
        char    *name;
        Cipher  *cipher;
        int     enabled;
+       u_int   key_len;
+       u_int   block_size;
        u_char  *key;
        u_char  *iv;
 };
@@ -115,7 +117,7 @@ Kex *kex_setup(char *[PROPOSAL_MAX]);
 void    kex_finish(Kex *);
 
 void    kex_send_kexinit(Kex *);
-void    kex_input_kexinit(int, int, void *);
+void    kex_input_kexinit(int, u_int32_t, void *);
 void    kex_derive_keys(Kex *, u_char *, BIGNUM *);
 
 void    kexdh(Kex *);
index b850a1a226ef3749b073094a1a4f15a39c16e8b9..eaf497ca7f1d8ff20628fddca017a58a5c160e47 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexdh.c,v 1.7 2001/09/17 19:27:15 stevesk Exp $");
+RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
 
 #include <openssl/crypto.h>
 #include <openssl/bn.h>
@@ -51,7 +51,7 @@ kex_dh_hash(
 {
        Buffer b;
        static u_char digest[EVP_MAX_MD_SIZE];
-       EVP_MD *evp_md = EVP_sha1();
+       const EVP_MD *evp_md = EVP_sha1();
        EVP_MD_CTX md;
 
        buffer_init(&b);
@@ -81,7 +81,7 @@ kex_dh_hash(
        buffer_free(&b);
 
 #ifdef DEBUG_KEX
-       dump_digest("hash", digest, evp_md->md_size);
+       dump_digest("hash", digest, EVP_MD_size(evp_md));
 #endif
        return digest;
 }
@@ -97,7 +97,6 @@ kexdh_client(Kex *kex)
        u_char *server_host_key_blob = NULL, *signature = NULL;
        u_char *kbuf, *hash;
        u_int klen, kout, slen, sbloblen;
-       int dlen, plen;
 
        /* generate and send 'e', client DH public key */
        dh = dh_new_group1();
@@ -115,24 +114,24 @@ kexdh_client(Kex *kex)
 #endif
 
        debug("expecting SSH2_MSG_KEXDH_REPLY");
-       packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
+       packet_read_expect(SSH2_MSG_KEXDH_REPLY);
 
        /* key, cert */
        server_host_key_blob = packet_get_string(&sbloblen);
        server_host_key = key_from_blob(server_host_key_blob, sbloblen);
        if (server_host_key == NULL)
                fatal("cannot decode server_host_key_blob");
-
+       if (server_host_key->type != kex->hostkey_type)
+               fatal("type mismatch for decoded server_host_key_blob");
        if (kex->verify_host_key == NULL)
                fatal("cannot verify server_host_key");
        if (kex->verify_host_key(server_host_key) == -1)
                fatal("server_host_key verification failed");
 
        /* DH paramter f, server public DH key */
-       dh_server_pub = BN_new();
-       if (dh_server_pub == NULL)
+       if ((dh_server_pub = BN_new()) == NULL)
                fatal("dh_server_pub == NULL");
-       packet_get_bignum2(dh_server_pub, &dlen);
+       packet_get_bignum2(dh_server_pub);
 
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "dh_server_pub= ");
@@ -143,7 +142,7 @@ kexdh_client(Kex *kex)
 
        /* signed H */
        signature = packet_get_string(&slen);
-       packet_done();
+       packet_check_eom();
 
        if (!dh_pub_is_valid(dh, dh_server_pub))
                packet_disconnect("bad server public DH value");
@@ -154,7 +153,8 @@ kexdh_client(Kex *kex)
 #ifdef DEBUG_KEXDH
        dump_digest("shared secret", kbuf, kout);
 #endif
-       shared_secret = BN_new();
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexdh_client: BN_new failed");
        BN_bin2bn(kbuf, kout, shared_secret);
        memset(kbuf, 0, klen);
        xfree(kbuf);
@@ -171,7 +171,7 @@ kexdh_client(Kex *kex)
            shared_secret
        );
        xfree(server_host_key_blob);
-       BN_free(dh_server_pub);
+       BN_clear_free(dh_server_pub);
        DH_free(dh);
 
        if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
@@ -201,14 +201,14 @@ kexdh_server(Kex *kex)
        Key *server_host_key;
        u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
        u_int sbloblen, klen, kout;
-       int dlen, slen, plen;
+       u_int slen;
 
        /* generate server DH public key */
        dh = dh_new_group1();
        dh_gen_key(dh, kex->we_need * 8);
 
        debug("expecting SSH2_MSG_KEXDH_INIT");
-       packet_read_expect(&plen, SSH2_MSG_KEXDH_INIT);
+       packet_read_expect(SSH2_MSG_KEXDH_INIT);
 
        if (kex->load_host_key == NULL)
                fatal("Cannot load hostkey");
@@ -217,10 +217,10 @@ kexdh_server(Kex *kex)
                fatal("Unsupported hostkey type %d", kex->hostkey_type);
 
        /* key, cert */
-       dh_client_pub = BN_new();
-       if (dh_client_pub == NULL)
+       if ((dh_client_pub = BN_new()) == NULL)
                fatal("dh_client_pub == NULL");
-       packet_get_bignum2(dh_client_pub, &dlen);
+       packet_get_bignum2(dh_client_pub);
+       packet_check_eom();
 
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "dh_client_pub= ");
@@ -244,7 +244,8 @@ kexdh_server(Kex *kex)
 #ifdef DEBUG_KEXDH
        dump_digest("shared secret", kbuf, kout);
 #endif
-       shared_secret = BN_new();
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexdh_server: BN_new failed");
        BN_bin2bn(kbuf, kout, shared_secret);
        memset(kbuf, 0, klen);
        xfree(kbuf);
@@ -262,7 +263,7 @@ kexdh_server(Kex *kex)
            dh->pub_key,
            shared_secret
        );
-       BN_free(dh_client_pub);
+       BN_clear_free(dh_client_pub);
 
        /* save session id := H */
        /* XXX hashlen depends on KEX */
index f06f2c355243577ed2c079bc109d9b91fbabddfe..61896e6ed467685a995c175aa016b7cc051d7b8f 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexgex.c,v 1.9 2001/09/17 19:27:15 stevesk Exp $");
+RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
 
 #include <openssl/bn.h>
 
@@ -53,7 +53,7 @@ kexgex_hash(
 {
        Buffer b;
        static u_char digest[EVP_MAX_MD_SIZE];
-       EVP_MD *evp_md = EVP_sha1();
+       const EVP_MD *evp_md = EVP_sha1();
        EVP_MD_CTX md;
 
        buffer_init(&b);
@@ -92,7 +92,7 @@ kexgex_hash(
        buffer_free(&b);
 
 #ifdef DEBUG_KEXDH
-       dump_digest("hash", digest, evp_md->md_size);
+       dump_digest("hash", digest, EVP_MD_size(evp_md));
 #endif
        return digest;
 }
@@ -107,7 +107,7 @@ kexgex_client(Kex *kex)
        Key *server_host_key;
        u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
        u_int klen, kout, slen, sbloblen;
-       int dlen, plen, min, max, nbits;
+       int min, max, nbits;
        DH *dh;
 
        nbits = dh_estimate(kex->we_need * 8);
@@ -138,15 +138,15 @@ kexgex_client(Kex *kex)
        packet_send();
 
        debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP");
-       packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
+       packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP);
 
        if ((p = BN_new()) == NULL)
                fatal("BN_new");
-       packet_get_bignum2(p, &dlen);
+       packet_get_bignum2(p);
        if ((g = BN_new()) == NULL)
                fatal("BN_new");
-       packet_get_bignum2(g, &dlen);
-       packet_done();
+       packet_get_bignum2(g);
+       packet_check_eom();
 
        if (BN_num_bits(p) < min || BN_num_bits(p) > max)
                fatal("DH_GEX group out of range: %d !< %d !< %d",
@@ -169,24 +169,24 @@ kexgex_client(Kex *kex)
        packet_send();
 
        debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY");
-       packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
+       packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY);
 
        /* key, cert */
        server_host_key_blob = packet_get_string(&sbloblen);
        server_host_key = key_from_blob(server_host_key_blob, sbloblen);
        if (server_host_key == NULL)
                fatal("cannot decode server_host_key_blob");
-
+       if (server_host_key->type != kex->hostkey_type)
+               fatal("type mismatch for decoded server_host_key_blob");
        if (kex->verify_host_key == NULL)
                fatal("cannot verify server_host_key");
        if (kex->verify_host_key(server_host_key) == -1)
                fatal("server_host_key verification failed");
 
        /* DH paramter f, server public DH key */
-       dh_server_pub = BN_new();
-       if (dh_server_pub == NULL)
+       if ((dh_server_pub = BN_new()) == NULL)
                fatal("dh_server_pub == NULL");
-       packet_get_bignum2(dh_server_pub, &dlen);
+       packet_get_bignum2(dh_server_pub);
 
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "dh_server_pub= ");
@@ -197,7 +197,7 @@ kexgex_client(Kex *kex)
 
        /* signed H */
        signature = packet_get_string(&slen);
-       packet_done();
+       packet_check_eom();
 
        if (!dh_pub_is_valid(dh, dh_server_pub))
                packet_disconnect("bad server public DH value");
@@ -208,7 +208,8 @@ kexgex_client(Kex *kex)
 #ifdef DEBUG_KEXDH
        dump_digest("shared secret", kbuf, kout);
 #endif
-       shared_secret = BN_new();
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexgex_client: BN_new failed");
        BN_bin2bn(kbuf, kout, shared_secret);
        memset(kbuf, 0, klen);
        xfree(kbuf);
@@ -232,7 +233,7 @@ kexgex_client(Kex *kex)
        /* have keys, free DH */
        DH_free(dh);
        xfree(server_host_key_blob);
-       BN_free(dh_server_pub);
+       BN_clear_free(dh_server_pub);
 
        if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
                fatal("key_verify failed for server_host_key");
@@ -260,8 +261,8 @@ kexgex_server(Kex *kex)
        Key *server_host_key;
        DH *dh = dh;
        u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
-       u_int sbloblen, klen, kout;
-       int min = -1, max = -1, nbits = -1, type, plen, dlen, slen;
+       u_int sbloblen, klen, kout, slen;
+       int min = -1, max = -1, nbits = -1, type;
 
        if (kex->load_host_key == NULL)
                fatal("Cannot load hostkey");
@@ -269,8 +270,8 @@ kexgex_server(Kex *kex)
        if (server_host_key == NULL)
                fatal("Unsupported hostkey type %d", kex->hostkey_type);
 
-       type = packet_read(&plen);
-       switch(type){
+       type = packet_read();
+       switch (type) {
        case SSH2_MSG_KEX_DH_GEX_REQUEST:
                debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
                min = packet_get_int();
@@ -289,7 +290,7 @@ kexgex_server(Kex *kex)
        default:
                fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
        }
-       packet_done();
+       packet_check_eom();
 
        if (max < min || nbits < min || max < nbits)
                fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
@@ -312,13 +313,13 @@ kexgex_server(Kex *kex)
        dh_gen_key(dh, kex->we_need * 8);
 
        debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
-       packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_INIT);
+       packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT);
 
        /* key, cert */
-       dh_client_pub = BN_new();
-       if (dh_client_pub == NULL)
+       if ((dh_client_pub = BN_new()) == NULL)
                fatal("dh_client_pub == NULL");
-       packet_get_bignum2(dh_client_pub, &dlen);
+       packet_get_bignum2(dh_client_pub);
+       packet_check_eom();
 
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "dh_client_pub= ");
@@ -342,7 +343,8 @@ kexgex_server(Kex *kex)
 #ifdef DEBUG_KEXDH
        dump_digest("shared secret", kbuf, kout);
 #endif
-       shared_secret = BN_new();
+       if ((shared_secret = BN_new()) == NULL)
+               fatal("kexgex_server: BN_new failed");
        BN_bin2bn(kbuf, kout, shared_secret);
        memset(kbuf, 0, klen);
        xfree(kbuf);
@@ -365,7 +367,7 @@ kexgex_server(Kex *kex)
            dh->pub_key,
            shared_secret
        );
-       BN_free(dh_client_pub);
+       BN_clear_free(dh_client_pub);
 
        /* save session id := H */
        /* XXX hashlen depends on KEX */
index 57df5b93aef7ae9015572cf93dcb89eaf0e1d29b..cda91571affd8c4168746459d2a8139cd29ae34c 100644 (file)
@@ -32,7 +32,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: key.c,v 1.33 2001/10/04 14:34:16 markus Exp $");
+RCSID("$OpenBSD: key.c,v 1.41 2002/02/28 15:46:33 markus Exp $");
 
 #include <openssl/evp.h>
 
@@ -60,17 +60,25 @@ key_new(int type)
        switch (k->type) {
        case KEY_RSA1:
        case KEY_RSA:
-               rsa = RSA_new();
-               rsa->n = BN_new();
-               rsa->e = BN_new();
+               if ((rsa = RSA_new()) == NULL)
+                       fatal("key_new: RSA_new failed");
+               if ((rsa->n = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((rsa->e = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
                k->rsa = rsa;
                break;
        case KEY_DSA:
-               dsa = DSA_new();
-               dsa->p = BN_new();
-               dsa->q = BN_new();
-               dsa->g = BN_new();
-               dsa->pub_key = BN_new();
+               if ((dsa = DSA_new()) == NULL)
+                       fatal("key_new: DSA_new failed");
+               if ((dsa->p = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((dsa->q = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((dsa->g = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
+               if ((dsa->pub_key = BN_new()) == NULL)
+                       fatal("key_new: BN_new failed");
                k->dsa = dsa;
                break;
        case KEY_UNSPEC:
@@ -88,15 +96,22 @@ key_new_private(int type)
        switch (k->type) {
        case KEY_RSA1:
        case KEY_RSA:
-               k->rsa->d = BN_new();
-               k->rsa->iqmp = BN_new();
-               k->rsa->q = BN_new();
-               k->rsa->p = BN_new();
-               k->rsa->dmq1 = BN_new();
-               k->rsa->dmp1 = BN_new();
+               if ((k->rsa->d = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->iqmp = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->q = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->p = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->dmq1 = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
+               if ((k->rsa->dmp1 = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
                break;
        case KEY_DSA:
-               k->dsa->priv_key = BN_new();
+               if ((k->dsa->priv_key = BN_new()) == NULL)
+                       fatal("key_new_private: BN_new failed");
                break;
        case KEY_UNSPEC:
                break;
@@ -155,13 +170,13 @@ key_equal(Key *a, Key *b)
 }
 
 static u_char*
-key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length)
+key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
 {
-       EVP_MD *md = NULL;
+       const EVP_MD *md = NULL;
        EVP_MD_CTX ctx;
        u_char *blob = NULL;
        u_char *retval = NULL;
-       int len = 0;
+       u_int len = 0;
        int nlen, elen;
 
        *dgst_raw_length = 0;
@@ -201,8 +216,7 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length)
                retval = xmalloc(EVP_MAX_MD_SIZE);
                EVP_DigestInit(&ctx, md);
                EVP_DigestUpdate(&ctx, blob, len);
-               EVP_DigestFinal(&ctx, retval, NULL);
-               *dgst_raw_length = md->md_size;
+               EVP_DigestFinal(&ctx, retval, dgst_raw_length);
                memset(blob, 0, len);
                xfree(blob);
        } else {
@@ -212,14 +226,14 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, size_t *dgst_raw_length)
 }
 
 static char*
-key_fingerprint_hex(u_char* dgst_raw, size_t dgst_raw_len)
+key_fingerprint_hex(u_char* dgst_raw, u_int dgst_raw_len)
 {
        char *retval;
        int i;
 
        retval = xmalloc(dgst_raw_len * 3 + 1);
        retval[0] = '\0';
-       for(i = 0; i < dgst_raw_len; i++) {
+       for (i = 0; i < dgst_raw_len; i++) {
                char hex[4];
                snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
                strlcat(retval, hex, dgst_raw_len * 3);
@@ -229,7 +243,7 @@ key_fingerprint_hex(u_char* dgst_raw, size_t dgst_raw_len)
 }
 
 static char*
-key_fingerprint_bubblebabble(u_char* dgst_raw, size_t dgst_raw_len)
+key_fingerprint_bubblebabble(u_char* dgst_raw, u_int dgst_raw_len)
 {
        char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' };
        char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
@@ -280,12 +294,12 @@ key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
 {
        char *retval = NULL;
        u_char *dgst_raw;
-       size_t dgst_raw_len;
-       
+       u_int dgst_raw_len;
+
        dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len);
        if (!dgst_raw)
                fatal("key_fingerprint: null from key_fingerprint_raw()");
-       switch(dgst_rep) {
+       switch (dgst_rep) {
        case SSH_FP_HEX:
                retval = key_fingerprint_hex(dgst_raw, dgst_raw_len);
                break;
@@ -371,7 +385,7 @@ key_read(Key *ret, char **cpp)
 
        cp = *cpp;
 
-       switch(ret->type) {
+       switch (ret->type) {
        case KEY_RSA1:
                /* Get number of bits. */
                if (*cp < '0' || *cp > '9')
@@ -420,14 +434,15 @@ key_read(Key *ret, char **cpp)
                n = uudecode(cp, blob, len);
                if (n < 0) {
                        error("key_read: uudecode %s failed", cp);
+                       xfree(blob);
                        return -1;
                }
                k = key_from_blob(blob, n);
+               xfree(blob);
                if (k == NULL) {
                        error("key_read: key_from_blob %s failed", cp);
                        return -1;
                }
-               xfree(blob);
                if (k->type != type) {
                        error("key_read: type mismatch: encoding error");
                        key_free(k);
@@ -454,9 +469,9 @@ key_read(Key *ret, char **cpp)
 #endif
                }
 /*XXXX*/
+               key_free(k);
                if (success != 1)
                        break;
-               key_free(k);
                /* advance cp: skip whitespace and data */
                while (*cp == ' ' || *cp == '\t')
                        cp++;
@@ -473,8 +488,9 @@ key_read(Key *ret, char **cpp)
 int
 key_write(Key *key, FILE *f)
 {
-       int success = 0;
-       u_int bits = 0;
+       int n, success = 0;
+       u_int len, bits = 0;
+       u_char *blob, *uu;
 
        if (key->type == KEY_RSA1 && key->rsa != NULL) {
                /* size of modulus 'n' */
@@ -488,8 +504,6 @@ key_write(Key *key, FILE *f)
                }
        } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
            (key->type == KEY_RSA && key->rsa != NULL)) {
-               int len, n;
-               u_char *blob, *uu;
                key_to_blob(key, &blob, &len);
                uu = xmalloc(2*len);
                n = uuencode(blob, len, uu, 2*len);
@@ -532,7 +546,8 @@ key_ssh_name(Key *k)
        return "ssh-unknown";
 }
 u_int
-key_size(Key *k){
+key_size(Key *k)
+{
        switch (k->type) {
        case KEY_RSA1:
        case KEY_RSA:
@@ -615,15 +630,15 @@ key_from_private(Key *k)
 int
 key_type_from_name(char *name)
 {
-       if (strcmp(name, "rsa1") == 0){
+       if (strcmp(name, "rsa1") == 0) {
                return KEY_RSA1;
-       } else if (strcmp(name, "rsa") == 0){
+       } else if (strcmp(name, "rsa") == 0) {
                return KEY_RSA;
-       } else if (strcmp(name, "dsa") == 0){
+       } else if (strcmp(name, "dsa") == 0) {
                return KEY_DSA;
-       } else if (strcmp(name, "ssh-rsa") == 0){
+       } else if (strcmp(name, "ssh-rsa") == 0) {
                return KEY_RSA;
-       } else if (strcmp(name, "ssh-dss") == 0){
+       } else if (strcmp(name, "ssh-dss") == 0) {
                return KEY_DSA;
        }
        debug2("key_type_from_name: unknown key type '%s'", name);
@@ -639,7 +654,7 @@ key_names_valid2(const char *names)
                return 0;
        s = cp = xstrdup(names);
        for ((p = strsep(&cp, ",")); p && *p != '\0';
-            (p = strsep(&cp, ","))) {
+           (p = strsep(&cp, ","))) {
                switch (key_type_from_name(p)) {
                case KEY_RSA1:
                case KEY_UNSPEC:
@@ -668,7 +683,7 @@ key_from_blob(u_char *blob, int blen)
        ktype = buffer_get_string(&b, NULL);
        type = key_type_from_name(ktype);
 
-       switch(type){
+       switch (type) {
        case KEY_RSA:
                key = key_new(type);
                buffer_get_bignum2(&b, key->rsa->e);
@@ -714,7 +729,7 @@ key_to_blob(Key *key, u_char **blobp, u_int *lenp)
                return 0;
        }
        buffer_init(&b);
-       switch(key->type){
+       switch (key->type) {
        case KEY_DSA:
                buffer_put_cstring(&b, key_ssh_name(key));
                buffer_put_bignum2(&b, key->dsa->p);
@@ -747,10 +762,10 @@ key_to_blob(Key *key, u_char **blobp, u_int *lenp)
 int
 key_sign(
     Key *key,
-    u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+    u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
-       switch(key->type){
+       switch (key->type) {
        case KEY_DSA:
                return ssh_dss_sign(key, sigp, lenp, data, datalen);
                break;
@@ -767,13 +782,13 @@ key_sign(
 int
 key_verify(
     Key *key,
-    u_char *signature, int signaturelen,
-    u_char *data, int datalen)
+    u_char *signature, u_int signaturelen,
+    u_char *data, u_int datalen)
 {
        if (signaturelen == 0)
                return -1;
 
-       switch(key->type){
+       switch (key->type) {
        case KEY_DSA:
                return ssh_dss_verify(key, signature, signaturelen, data, datalen);
                break;
index 00eebb7f1a10b87eb2faf1ff3d3588af7d13bf53..a2257731aef55cd9170262e0d0537e79a4745098 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: key.h,v 1.17 2001/09/17 19:27:15 stevesk Exp $        */
+/*     $OpenBSD: key.h,v 1.18 2002/02/24 19:14:59 markus Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -74,7 +74,7 @@ int    key_to_blob(Key *, u_char **, u_int *);
 char   *key_ssh_name(Key *);
 int     key_names_valid2(const char *);
 
-int     key_sign(Key *, u_char **, int *, u_char *, int);
-int     key_verify(Key *, u_char *, int, u_char *, int);
+int     key_sign(Key *, u_char **, u_int *, u_char *, u_int);
+int     key_verify(Key *, u_char *, u_int, u_char *, u_int);
 
 #endif
index 39bc8b5d75a3aca0a5bcdb8a68f5745a3c34450c..c88f632c9e3638a10c43e82ba4730503446836d8 100644 (file)
@@ -34,7 +34,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.18 2001/06/26 17:27:23 markus Exp $");
+RCSID("$OpenBSD: log.c,v 1.22 2002/02/22 12:20:34 markus Exp $");
 
 #include "log.h"
 #include "xmalloc.h"
@@ -68,7 +68,7 @@ static struct {
        { "LOCAL5",     SYSLOG_FACILITY_LOCAL5 },
        { "LOCAL6",     SYSLOG_FACILITY_LOCAL6 },
        { "LOCAL7",     SYSLOG_FACILITY_LOCAL7 },
-       { NULL, 0 }
+       { NULL,         SYSLOG_FACILITY_NOT_SET }
 };
 
 static struct {
@@ -85,11 +85,9 @@ static struct {
        { "DEBUG1",     SYSLOG_LEVEL_DEBUG1 },
        { "DEBUG2",     SYSLOG_LEVEL_DEBUG2 },
        { "DEBUG3",     SYSLOG_LEVEL_DEBUG3 },
-       { NULL, 0 }
+       { NULL,         SYSLOG_LEVEL_NOT_SET }
 };
 
-static void     do_log(LogLevel level, const char *fmt, va_list args);
-
 SyslogFacility
 log_facility_number(char *name)
 {
@@ -98,7 +96,7 @@ log_facility_number(char *name)
                for (i = 0; log_facilities[i].name; i++)
                        if (strcasecmp(log_facilities[i].name, name) == 0)
                                return log_facilities[i].val;
-       return (SyslogFacility) - 1;
+       return SYSLOG_FACILITY_NOT_SET;
 }
 
 LogLevel
@@ -109,18 +107,7 @@ log_level_number(char *name)
                for (i = 0; log_levels[i].name; i++)
                        if (strcasecmp(log_levels[i].name, name) == 0)
                                return log_levels[i].val;
-       return (LogLevel) - 1;
-}
-/* Fatal messages.  This function never returns. */
-
-void
-fatal(const char *fmt,...)
-{
-       va_list args;
-       va_start(args, fmt);
-       do_log(SYSLOG_LEVEL_FATAL, fmt, args);
-       va_end(args);
-       fatal_cleanup();
+       return SYSLOG_LEVEL_NOT_SET;
 }
 
 /* Error messages that should be logged. */
@@ -242,7 +229,7 @@ fatal_cleanup(void)
        for (cu = fatal_cleanups; cu; cu = next_cu) {
                next_cu = cu->next;
                debug("Calling cleanup 0x%lx(0x%lx)",
-                     (u_long) cu->proc, (u_long) cu->context);
+                   (u_long) cu->proc, (u_long) cu->context);
                (*cu->proc) (cu->context);
        }
        exit(255);
@@ -328,7 +315,7 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
 
 #define MSGBUFSIZ 1024
 
-static void
+void
 do_log(LogLevel level, const char *fmt, va_list args)
 {
        char msgbuf[MSGBUFSIZ];
index 23451f74fa1f618d8e5a7b46a6915605ca9bb0bb..42a9a6ec743d82923a53973d5b20107e7e10a1ea 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: log.h,v 1.4 2001/06/26 17:27:24 markus Exp $  */
+/*     $OpenBSD: log.h,v 1.6 2002/02/22 12:20:34 markus Exp $  */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -32,7 +32,8 @@ typedef enum {
        SYSLOG_FACILITY_LOCAL4,
        SYSLOG_FACILITY_LOCAL5,
        SYSLOG_FACILITY_LOCAL6,
-       SYSLOG_FACILITY_LOCAL7
+       SYSLOG_FACILITY_LOCAL7,
+       SYSLOG_FACILITY_NOT_SET = -1,
 }       SyslogFacility;
 
 typedef enum {
@@ -43,7 +44,8 @@ typedef enum {
        SYSLOG_LEVEL_VERBOSE,
        SYSLOG_LEVEL_DEBUG1,
        SYSLOG_LEVEL_DEBUG2,
-       SYSLOG_LEVEL_DEBUG3
+       SYSLOG_LEVEL_DEBUG3,
+       SYSLOG_LEVEL_NOT_SET = -1,
 }       LogLevel;
 
 void     log_init(char *, LogLevel, SyslogFacility, int);
@@ -63,4 +65,6 @@ void     fatal_cleanup(void);
 void     fatal_add_cleanup(void (*) (void *), void *);
 void     fatal_remove_cleanup(void (*) (void *), void *);
 
+void    do_log(LogLevel, const char *, va_list);
+
 #endif
index 87c336df082200b7fbdee95c88529858528617b9..1805f3ee836ec1f67f543c5687fda0cd801b6364 100644 (file)
@@ -701,6 +701,8 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
        line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line));
        set_utmpx_time(li, utx);
        utx->ut_pid = li->pid;
+       /* strncpy(): Don't necessarily want null termination */
+       strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
 
        if (li->type == LTYPE_LOGOUT)
                return;
@@ -710,8 +712,6 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
         * for logouts.
         */
 
-       /* strncpy(): Don't necessarily want null termination */
-       strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
 # ifdef HAVE_HOST_IN_UTMPX
        strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname));
 # endif
@@ -942,9 +942,7 @@ utmpx_perform_logout(struct logininfo *li)
 {
        struct utmpx utx;
 
-       memset(&utx, '\0', sizeof(utx));
-       set_utmpx_time(li, &utx);
-       line_stripname(utx.ut_line, li->line, sizeof(utx.ut_line));
+       construct_utmpx(li, &utx);
 # ifdef HAVE_ID_IN_UTMPX
        line_abbrevname(utx.ut_id, li->line, sizeof(utx.ut_id));
 # endif
index e8b4267c3fc1e739236bbe41d05694049a4b402e..b250af2aa34de1074aa23906b5db026a8229f629 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: mac.c,v 1.2 2001/04/05 10:42:51 markus Exp $");
+RCSID("$OpenBSD: mac.c,v 1.4 2002/01/25 22:07:40 markus Exp $");
 
 #include <openssl/hmac.h>
 
@@ -56,7 +56,7 @@ mac_init(Mac *mac, char *name)
                if (strcmp(name, macs[i].name) == 0) {
                        if (mac != NULL) {
                                mac->md = (*macs[i].mdfunc)();
-                               mac->key_len = mac->mac_len = mac->md->md_size;
+                               mac->key_len = mac->mac_len = EVP_MD_size(mac->md);
                                if (macs[i].truncatebits != 0)
                                        mac->mac_len = macs[i].truncatebits/8;
                        }
@@ -99,7 +99,7 @@ mac_valid(const char *names)
                return (0);
        maclist = cp = xstrdup(names);
        for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
-            (p = strsep(&cp, MAC_SEP))) {
+           (p = strsep(&cp, MAC_SEP))) {
                if (mac_init(NULL, p) < 0) {
                        debug("bad mac %s [%s]", p, names);
                        xfree(maclist);
index 188b9a4169f69e77477c2a35ad49b02812bd7fa0..3ddb627302717236f0666a8ba9e6cbd216494896 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: match.c,v 1.14 2001/06/27 04:48:53 markus Exp $");
+RCSID("$OpenBSD: match.c,v 1.19 2002/03/01 13:12:10 markus Exp $");
 
 #include "match.h"
 #include "xmalloc.h"
@@ -104,14 +104,15 @@ match_pattern(const char *s, const char *pattern)
 }
 
 /*
- * Tries to match the host name (which must be in all lowercase) against the
+ * Tries to match the string against the
  * comma-separated sequence of subpatterns (each possibly preceded by ! to
  * indicate negation).  Returns -1 if negation matches, 1 if there is
  * a positive match, 0 if there is no match at all.
  */
 
 int
-match_hostname(const char *host, const char *pattern, u_int len)
+match_pattern_list(const char *string, const char *pattern, u_int len,
+    int dolower)
 {
        char sub[1024];
        int negated;
@@ -132,9 +133,10 @@ match_hostname(const char *host, const char *pattern, u_int len)
                 * subpattern to lowercase.
                 */
                for (subi = 0;
-                    i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
-                    subi++, i++)
-                       sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
+                   i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
+                   subi++, i++)
+                       sub[subi] = dolower && isupper(pattern[i]) ?
+                           tolower(pattern[i]) : pattern[i];
                /* If subpattern too long, return failure (no match). */
                if (subi >= sizeof(sub) - 1)
                        return 0;
@@ -146,8 +148,8 @@ match_hostname(const char *host, const char *pattern, u_int len)
                /* Null-terminate the subpattern. */
                sub[subi] = '\0';
 
-               /* Try to match the subpattern against the host name. */
-               if (match_pattern(host, sub)) {
+               /* Try to match the subpattern against the string. */
+               if (match_pattern(string, sub)) {
                        if (negated)
                                return -1;              /* Negative */
                        else
@@ -162,6 +164,18 @@ match_hostname(const char *host, const char *pattern, u_int len)
        return got_positive;
 }
 
+/*
+ * Tries to match the host name (which must be in all lowercase) against the
+ * comma-separated sequence of subpatterns (each possibly preceded by ! to
+ * indicate negation).  Returns -1 if negation matches, 1 if there is
+ * a positive match, 0 if there is no match at all.
+ */
+int
+match_hostname(const char *host, const char *pattern, u_int len)
+{
+       return match_pattern_list(host, pattern, len, 1);
+}
+
 /*
  * 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.
@@ -212,7 +226,7 @@ match_user(const char *user, const char *host, const char *ipaddr,
  * Returns first item from client-list that is also supported by server-list,
  * caller must xfree() returned string.
  */
-#define        MAX_PROP        20
+#define        MAX_PROP        40
 #define        SEP     ","
 char *
 match_list(const char *client, const char *server, u_int *next)
@@ -225,7 +239,7 @@ match_list(const char *client, const char *server, u_int *next)
        s = sp = xstrdup(server);
 
        for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
-            (p = strsep(&sp, SEP)), i++) {
+           (p = strsep(&sp, SEP)), i++) {
                if (i < MAX_PROP)
                        sproposals[i] = p;
                else
@@ -234,7 +248,7 @@ match_list(const char *client, const char *server, u_int *next)
        nproposals = i;
 
        for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
-            (p = strsep(&cp, SEP)), i++) {
+           (p = strsep(&cp, SEP)), i++) {
                for (j = 0; j < nproposals; j++) {
                        if (strcmp(p, sproposals[j]) == 0) {
                                ret = xstrdup(p);
index f05fe9b37114718214a5074734c308e7b30d7d46..a0764e0013f92df756f91123099c062e68e24c8b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: match.h,v 1.9 2001/06/26 06:32:56 itojun Exp $        */
+/*     $OpenBSD: match.h,v 1.12 2002/03/01 13:12:10 markus Exp $       */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -14,8 +14,9 @@
 #ifndef MATCH_H
 #define MATCH_H
 
-int      match_pattern(const char *, const char *);
-int      match_hostname(const char *, const char *, u_int);
+int     match_pattern(const char *, const char *);
+int     match_pattern_list(const char *, const char *, u_int, int);
+int     match_hostname(const char *, const char *, u_int);
 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 *);
index 620121fdca29f7e2fbf915c764a2e4bfb73e7949..e9fcef6ca3018c88a1d7fd9e776df351b769c3ff 100644 (file)
@@ -1,5 +1,3 @@
-/*     $OpenBSD: misc.c,v 1.12 2001/06/26 17:27:24 markus Exp $        */
-
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -25,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.12 2001/06/26 17:27:24 markus Exp $");
+RCSID("$OpenBSD: misc.c,v 1.19 2002/03/04 17:27:39 stevesk Exp $");
 
 #include "misc.h"
 #include "log.h"
@@ -37,7 +35,7 @@ chop(char *s)
 {
        char *t = s;
        while (*t) {
-               if(*t == '\n' || *t == '\r') {
+               if (*t == '\n' || *t == '\r') {
                        *t = '\0';
                        return s;
                }
@@ -65,9 +63,8 @@ set_nonblock(int fd)
        debug("fd %d setting O_NONBLOCK", fd);
        val |= O_NONBLOCK;
        if (fcntl(fd, F_SETFL, val) == -1)
-               if (errno != ENODEV)
-                       error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
-                           fd, strerror(errno));
+               debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
+                   fd, strerror(errno));
 }
 
 void
@@ -87,9 +84,30 @@ unset_nonblock(int fd)
        debug("fd %d clearing O_NONBLOCK", fd);
        val &= ~O_NONBLOCK;
        if (fcntl(fd, F_SETFL, val) == -1)
-               if (errno != ENODEV)
-                       error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
-                           fd, strerror(errno));
+               debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
+                   fd, strerror(errno));
+}
+
+/* disable nagle on socket */
+void
+set_nodelay(int fd)
+{
+       int opt;
+       socklen_t optlen;
+
+       optlen = sizeof opt;
+       if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
+               error("getsockopt TCP_NODELAY: %.100s", strerror(errno));
+               return;
+       }
+       if (opt == 1) {
+               debug2("fd %d is TCP_NODELAY", fd);
+               return;
+       }
+       opt = 1;
+       debug("fd %d setting TCP_NODELAY", fd);
+       if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
+               error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
 }
 
 /* Characters considered whitespace in strsep calls. */
@@ -298,7 +316,7 @@ addargs(arglist *args, char *fmt, ...)
        if (args->list == NULL) {
                args->nalloc = 32;
                args->num = 0;
-       } else if (args->num+2 >= args->nalloc) 
+       } else if (args->num+2 >= args->nalloc)
                args->nalloc *= 2;
 
        args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
index fc564527140dc443b6fab6bf9adafb8fbe713a96..668fd60d3bb7883a66bb5228ad39266a9e659108 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: misc.h,v 1.10 2001/06/26 17:27:24 markus Exp $        */
+/*     $OpenBSD: misc.h,v 1.11 2002/01/24 21:09:25 stevesk Exp $       */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,6 +16,7 @@ char  *chop(char *);
 char   *strdelim(char **);
 void    set_nonblock(int);
 void    unset_nonblock(int);
+void    set_nodelay(int);
 int     a2port(const char *);
 char   *cleanhostname(char *);
 char   *colon(char *);
index 082b7fd47c4d9dfc8cbf88689f815fb459e41b30..2a312f5cb2122ebe02dbf5a1d8cbfd8851f20883 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: mpaux.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $      */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,8 +14,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: mpaux.h,v 1.11 2001/06/26 17:27:24 markus Exp $"); */
-
 #ifndef MPAUX_H
 #define MPAUX_H
 
index 4a9a363709b071755ef9020a3be900f5a5f3b48d..1caf04a4eeb8826cd12b50b8935fff58aa458ef3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: myproposal.h,v 1.12 2001/03/05 15:56:16 deraadt Exp $ */
+/*     $OpenBSD: myproposal.h,v 1.13 2002/01/21 22:30:12 markus Exp $  */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -27,9 +27,7 @@
 #define        KEX_DEFAULT_PK_ALG      "ssh-rsa,ssh-dss"
 #define        KEX_DEFAULT_ENCRYPT \
        "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
-       "aes192-cbc,aes256-cbc," \
-       "rijndael128-cbc,rijndael192-cbc,rijndael256-cbc," \
-       "rijndael-cbc@lysator.liu.se"
+       "aes192-cbc,aes256-cbc"
 #define        KEX_DEFAULT_MAC \
        "hmac-md5,hmac-sha1,hmac-ripemd160," \
        "hmac-ripemd160@openssh.com," \
index 2680f0a680bf51a1365cf0c785e73e2b34f38878..fc8e7f18de6d6ee2bba07c2c3d619795d5cdace3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: nchan.c,v 1.32 2001/10/10 22:18:47 markus Exp $");
+RCSID("$OpenBSD: nchan.c,v 1.44 2002/01/21 23:27:10 markus Exp $");
 
 #include "ssh1.h"
 #include "ssh2.h"
@@ -63,14 +63,6 @@ RCSID("$OpenBSD: nchan.c,v 1.32 2001/10/10 22:18:47 markus Exp $");
 /*
  * EVENTS update channel input/output states execute ACTIONS
  */
-/* events concerning the INPUT from socket for channel (istate) */
-chan_event_fn *chan_rcvd_oclose                        = NULL;
-chan_event_fn *chan_read_failed                        = NULL;
-chan_event_fn *chan_ibuf_empty                 = NULL;
-/* events concerning the OUTPUT from channel for socket (ostate) */
-chan_event_fn *chan_rcvd_ieof                  = NULL;
-chan_event_fn *chan_write_failed               = NULL;
-chan_event_fn *chan_obuf_empty                 = NULL;
 /*
  * ACTIONS: should never update the channel states
  */
@@ -83,6 +75,28 @@ static void  chan_send_eof2(Channel *);
 static void    chan_shutdown_write(Channel *);
 static void    chan_shutdown_read(Channel *);
 
+static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
+static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
+
+static void
+chan_set_istate(Channel *c, u_int next)
+{
+       if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
+               fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
+       debug("channel %d: input %s -> %s", c->self, istates[c->istate],
+           istates[next]);
+       c->istate = next;
+}
+static void
+chan_set_ostate(Channel *c, u_int next)
+{
+       if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
+               fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
+       debug("channel %d: output %s -> %s", c->self, ostates[c->ostate],
+           ostates[next]);
+       c->ostate = next;
+}
+
 /*
  * SSH1 specific implementation of event functions
  */
@@ -93,20 +107,17 @@ chan_rcvd_oclose1(Channel *c)
        debug("channel %d: rcvd oclose", c->self);
        switch (c->istate) {
        case CHAN_INPUT_WAIT_OCLOSE:
-               debug("channel %d: input wait_oclose -> closed", c->self);
-               c->istate = CHAN_INPUT_CLOSED;
+               chan_set_istate(c, CHAN_INPUT_CLOSED);
                break;
        case CHAN_INPUT_OPEN:
-               debug("channel %d: input open -> closed", c->self);
                chan_shutdown_read(c);
                chan_send_ieof1(c);
-               c->istate = CHAN_INPUT_CLOSED;
+               chan_set_istate(c, CHAN_INPUT_CLOSED);
                break;
        case CHAN_INPUT_WAIT_DRAIN:
                /* both local read_failed and remote write_failed  */
-               log("channel %d: input drain -> closed", c->self);
                chan_send_ieof1(c);
-               c->istate = CHAN_INPUT_CLOSED;
+               chan_set_istate(c, CHAN_INPUT_CLOSED);
                break;
        default:
                error("channel %d: protocol error: rcvd_oclose for istate %d",
@@ -114,21 +125,14 @@ chan_rcvd_oclose1(Channel *c)
                return;
        }
 }
-static void
-chan_read_failed_12(Channel *c)
+void
+chan_read_failed(Channel *c)
 {
        debug("channel %d: read failed", c->self);
        switch (c->istate) {
        case CHAN_INPUT_OPEN:
-               debug("channel %d: input open -> drain", c->self);
                chan_shutdown_read(c);
-               c->istate = CHAN_INPUT_WAIT_DRAIN;
-#if 0
-               if (buffer_len(&c->input) == 0) {
-                       debug("channel %d: input: no drain shortcut", c->self);
-                       chan_ibuf_empty(c);
-               }
-#endif
+               chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
                break;
        default:
                error("channel %d: chan_read_failed for istate %d",
@@ -136,8 +140,8 @@ chan_read_failed_12(Channel *c)
                break;
        }
 }
-static void
-chan_ibuf_empty1(Channel *c)
+void
+chan_ibuf_empty(Channel *c)
 {
        debug("channel %d: ibuf empty", c->self);
        if (buffer_len(&c->input)) {
@@ -147,9 +151,14 @@ chan_ibuf_empty1(Channel *c)
        }
        switch (c->istate) {
        case CHAN_INPUT_WAIT_DRAIN:
-               debug("channel %d: input drain -> wait_oclose", c->self);
-               chan_send_ieof1(c);
-               c->istate = CHAN_INPUT_WAIT_OCLOSE;
+               if (compat20) {
+                       if (!(c->flags & CHAN_CLOSE_SENT))
+                               chan_send_eof2(c);
+                       chan_set_istate(c, CHAN_INPUT_CLOSED);
+               } else {
+                       chan_send_ieof1(c);
+                       chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
+               }
                break;
        default:
                error("channel %d: chan_ibuf_empty for istate %d",
@@ -161,37 +170,12 @@ static void
 chan_rcvd_ieof1(Channel *c)
 {
        debug("channel %d: rcvd ieof", c->self);
-       if (c->type != SSH_CHANNEL_OPEN) {
-               debug("channel %d: non-open", c->self);
-               if (c->istate == CHAN_INPUT_OPEN) {
-                       debug("channel %d: non-open: input open -> wait_oclose",
-                           c->self);
-                       chan_shutdown_read(c);
-                       chan_send_ieof1(c);
-                       c->istate = CHAN_INPUT_WAIT_OCLOSE;
-               } else {
-                       error("channel %d: non-open: istate %d != open",
-                           c->self, c->istate);
-               }
-               if (c->ostate == CHAN_OUTPUT_OPEN) {
-                       debug("channel %d: non-open: output open -> closed",
-                           c->self);
-                       chan_send_oclose1(c);
-                       c->ostate = CHAN_OUTPUT_CLOSED;
-               } else {
-                       error("channel %d: non-open: ostate %d != open",
-                           c->self, c->ostate);
-               }
-               return;
-       }
        switch (c->ostate) {
        case CHAN_OUTPUT_OPEN:
-               debug("channel %d: output open -> drain", c->self);
-               c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
+               chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
                break;
        case CHAN_OUTPUT_WAIT_IEOF:
-               debug("channel %d: output wait_ieof -> closed", c->self);
-               c->ostate = CHAN_OUTPUT_CLOSED;
+               chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
                break;
        default:
                error("channel %d: protocol error: rcvd_ieof for ostate %d",
@@ -205,14 +189,14 @@ chan_write_failed1(Channel *c)
        debug("channel %d: write failed", c->self);
        switch (c->ostate) {
        case CHAN_OUTPUT_OPEN:
-               debug("channel %d: output open -> wait_ieof", c->self);
+               chan_shutdown_write(c);
                chan_send_oclose1(c);
-               c->ostate = CHAN_OUTPUT_WAIT_IEOF;
+               chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
                break;
        case CHAN_OUTPUT_WAIT_DRAIN:
-               debug("channel %d: output wait_drain -> closed", c->self);
+               chan_shutdown_write(c);
                chan_send_oclose1(c);
-               c->ostate = CHAN_OUTPUT_CLOSED;
+               chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
                break;
        default:
                error("channel %d: chan_write_failed for ostate %d",
@@ -220,8 +204,8 @@ chan_write_failed1(Channel *c)
                break;
        }
 }
-static void
-chan_obuf_empty1(Channel *c)
+void
+chan_obuf_empty(Channel *c)
 {
        debug("channel %d: obuf empty", c->self);
        if (buffer_len(&c->output)) {
@@ -231,9 +215,10 @@ chan_obuf_empty1(Channel *c)
        }
        switch (c->ostate) {
        case CHAN_OUTPUT_WAIT_DRAIN:
-               debug("channel %d: output drain -> closed", c->self);
-               chan_send_oclose1(c);
-               c->ostate = CHAN_OUTPUT_CLOSED;
+               chan_shutdown_write(c);
+               if (!compat20)
+                       chan_send_oclose1(c);
+               chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
                break;
        default:
                error("channel %d: internal error: obuf_empty for ostate %d",
@@ -265,15 +250,14 @@ chan_send_oclose1(Channel *c)
        switch (c->ostate) {
        case CHAN_OUTPUT_OPEN:
        case CHAN_OUTPUT_WAIT_DRAIN:
-               chan_shutdown_write(c);
-               buffer_consume(&c->output, buffer_len(&c->output));
+               buffer_clear(&c->output);
                packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
                packet_put_int(c->remote_id);
                packet_send();
                break;
        default:
                error("channel %d: cannot send oclose for ostate %d",
-                    c->self, c->ostate);
+                   c->self, c->ostate);
                break;
        }
 }
@@ -282,7 +266,7 @@ chan_send_oclose1(Channel *c)
  * the same for SSH2
  */
 static void
-chan_rcvd_oclose2(Channel *c)
+chan_rcvd_close2(Channel *c)
 {
        debug("channel %d: rcvd close", c->self);
        if (c->flags & CHAN_CLOSE_RCVD)
@@ -290,8 +274,8 @@ chan_rcvd_oclose2(Channel *c)
        c->flags |= CHAN_CLOSE_RCVD;
        if (c->type == SSH_CHANNEL_LARVAL) {
                /* tear down larval channels immediately */
-               c->ostate = CHAN_OUTPUT_CLOSED;
-               c->istate = CHAN_INPUT_CLOSED;
+               chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
+               chan_set_istate(c, CHAN_INPUT_CLOSED);
                return;
        }
        switch (c->ostate) {
@@ -300,52 +284,26 @@ chan_rcvd_oclose2(Channel *c)
                 * wait until a data from the channel is consumed if a CLOSE
                 * is received
                 */
-               debug("channel %d: output open -> drain", c->self);
-               c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
+               chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
                break;
        }
        switch (c->istate) {
        case CHAN_INPUT_OPEN:
-               debug("channel %d: input open -> closed", c->self);
                chan_shutdown_read(c);
+               chan_set_istate(c, CHAN_INPUT_CLOSED);
                break;
        case CHAN_INPUT_WAIT_DRAIN:
-               debug("channel %d: input drain -> closed", c->self);
                chan_send_eof2(c);
-               break;
-       }
-       c->istate = CHAN_INPUT_CLOSED;
-}
-static void
-chan_ibuf_empty2(Channel *c)
-{
-       debug("channel %d: ibuf empty", c->self);
-       if (buffer_len(&c->input)) {
-               error("channel %d: chan_ibuf_empty for non empty buffer",
-                    c->self);
-               return;
-       }
-       switch (c->istate) {
-       case CHAN_INPUT_WAIT_DRAIN:
-               debug("channel %d: input drain -> closed", c->self);
-               if (!(c->flags & CHAN_CLOSE_SENT))
-                       chan_send_eof2(c);
-               c->istate = CHAN_INPUT_CLOSED;
-               break;
-       default:
-               error("channel %d: chan_ibuf_empty for istate %d",
-                    c->self, c->istate);
+               chan_set_istate(c, CHAN_INPUT_CLOSED);
                break;
        }
 }
 static void
-chan_rcvd_ieof2(Channel *c)
+chan_rcvd_eof2(Channel *c)
 {
        debug("channel %d: rcvd eof", c->self);
-       if (c->ostate == CHAN_OUTPUT_OPEN) {
-               debug("channel %d: output open -> drain", c->self);
-               c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
-       }
+       if (c->ostate == CHAN_OUTPUT_OPEN)
+               chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
 }
 static void
 chan_write_failed2(Channel *c)
@@ -353,14 +311,9 @@ chan_write_failed2(Channel *c)
        debug("channel %d: write failed", c->self);
        switch (c->ostate) {
        case CHAN_OUTPUT_OPEN:
-               debug("channel %d: output open -> closed", c->self);
-               chan_shutdown_write(c); /* ?? */
-               c->ostate = CHAN_OUTPUT_CLOSED;
-               break;
        case CHAN_OUTPUT_WAIT_DRAIN:
-               debug("channel %d: output drain -> closed", c->self);
                chan_shutdown_write(c);
-               c->ostate = CHAN_OUTPUT_CLOSED;
+               chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
                break;
        default:
                error("channel %d: chan_write_failed for ostate %d",
@@ -369,27 +322,6 @@ chan_write_failed2(Channel *c)
        }
 }
 static void
-chan_obuf_empty2(Channel *c)
-{
-       debug("channel %d: obuf empty", c->self);
-       if (buffer_len(&c->output)) {
-               error("channel %d: chan_obuf_empty for non empty buffer",
-                   c->self);
-               return;
-       }
-       switch (c->ostate) {
-       case CHAN_OUTPUT_WAIT_DRAIN:
-               debug("channel %d: output drain -> closed", c->self);
-               chan_shutdown_write(c);
-               c->ostate = CHAN_OUTPUT_CLOSED;
-               break;
-       default:
-               error("channel %d: chan_obuf_empty for ostate %d",
-                   c->self, c->ostate);
-               break;
-       }
-}
-static void
 chan_send_eof2(Channel *c)
 {
        debug("channel %d: send eof", c->self);
@@ -425,6 +357,34 @@ chan_send_close2(Channel *c)
 
 /* shared */
 
+void
+chan_rcvd_ieof(Channel *c)
+{
+       if (compat20)
+               chan_rcvd_eof2(c);
+       else
+               chan_rcvd_ieof1(c);
+       if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
+           buffer_len(&c->output) == 0)
+               chan_obuf_empty(c);
+}
+void
+chan_rcvd_oclose(Channel *c)
+{
+       if (compat20)
+               chan_rcvd_close2(c);
+       else
+               chan_rcvd_oclose1(c);
+}
+void
+chan_write_failed(Channel *c)
+{
+       if (compat20)
+               chan_write_failed2(c);
+       else
+               chan_write_failed1(c);
+}
+
 void
 chan_mark_dead(Channel *c)
 {
@@ -458,7 +418,7 @@ chan_is_dead(Channel *c, int send)
                debug2("channel %d: active efd: %d len %d type %s",
                    c->self, c->efd, buffer_len(&c->extended),
                    c->extended_usage==CHAN_EXTENDED_READ ?
-                      "read": "write");
+                   "read": "write");
        } else {
                if (!(c->flags & CHAN_CLOSE_SENT)) {
                        if (send) {
@@ -481,42 +441,11 @@ chan_is_dead(Channel *c, int send)
        return 0;
 }
 
-void
-chan_init_iostates(Channel *c)
-{
-       c->ostate = CHAN_OUTPUT_OPEN;
-       c->istate = CHAN_INPUT_OPEN;
-       c->flags = 0;
-}
-
-/* init */
-void
-chan_init(void)
-{
-       if (compat20) {
-               chan_rcvd_oclose                = chan_rcvd_oclose2;
-               chan_read_failed                = chan_read_failed_12;
-               chan_ibuf_empty                 = chan_ibuf_empty2;
-
-               chan_rcvd_ieof                  = chan_rcvd_ieof2;
-               chan_write_failed               = chan_write_failed2;
-               chan_obuf_empty                 = chan_obuf_empty2;
-       } else {
-               chan_rcvd_oclose                = chan_rcvd_oclose1;
-               chan_read_failed                = chan_read_failed_12;
-               chan_ibuf_empty                 = chan_ibuf_empty1;
-
-               chan_rcvd_ieof                  = chan_rcvd_ieof1;
-               chan_write_failed               = chan_write_failed1;
-               chan_obuf_empty                 = chan_obuf_empty1;
-       }
-}
-
 /* helper */
 static void
 chan_shutdown_write(Channel *c)
 {
-       buffer_consume(&c->output, buffer_len(&c->output));
+       buffer_clear(&c->output);
        if (compat20 && c->type == SSH_CHANNEL_LARVAL)
                return;
        /* shutdown failure is allowed if write failed already */
index 31f9ea9e44dabd470bf695173661efaf196f3f7c..df5711193d8b0e79d31a26200887e85c3f5bb4dc 100644 (file)
@@ -20,6 +20,8 @@ OPENBSD=base64.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getop
 
 COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o
 
+PORTS=port-irix.o port-aix.o
+
 .c.o:
        $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
 
@@ -27,9 +29,10 @@ all: libopenbsd-compat.a
 
 $(COMPAT): ../config.h
 $(OPENBSD): ../config.h
+$(PORTS): ../config.h
 
-libopenbsd-compat.a:  $(COMPAT) $(OPENBSD)
-       $(AR) rv $@ $(COMPAT) $(OPENBSD)
+libopenbsd-compat.a:  $(COMPAT) $(OPENBSD) $(PORTS)
+       $(AR) rv $@ $(COMPAT) $(OPENBSD) $(PORTS)
        $(RANLIB) $@
 
 clean:
index 0ebfdd31b6a4dbd56d7c7bc5f5582d3e8deebce1..a49bea460b3529da2120e07a13b3089315c0617c 100644 (file)
@@ -15,4 +15,4 @@ int b64_pton(char const *src, u_char *target, size_t targsize);
 # define __b64_pton b64_pton
 #endif /* HAVE___B64_NTOP */
 
-#endif /* _BSD_BINRESVPORT_H */
+#endif /* _BSD_BASE64_H */
index f5133319650c6e85ba264b6dd9d8337509618408..f56ad7c5b4c6857520321326769a5b3caabae71c 100644 (file)
@@ -58,7 +58,7 @@ int binary_pipe(int fd[2])
        return ret;
 }
 
-int check_nt_auth(int pwd_authenticated, uid_t uid)
+int check_nt_auth(int pwd_authenticated, struct passwd *pw)
 {
        /*
        * The only authentication which is able to change the user
@@ -73,6 +73,8 @@ int check_nt_auth(int pwd_authenticated, uid_t uid)
        */
        static int has_create_token = -1;
 
+       if (pw == NULL)
+               return 0;
        if (is_winnt) {
                if (has_create_token < 0) {
                        struct utsname uts;
@@ -90,7 +92,7 @@ int check_nt_auth(int pwd_authenticated, uid_t uid)
                        }
                }
                if (has_create_token < 1 &&
-                   !pwd_authenticated && geteuid() != uid)
+                   !pwd_authenticated && geteuid() != pw->pw_uid)
                        return 0;
        }
        return 1;
@@ -139,4 +141,26 @@ int check_ntsec(const char *filename)
        return 0;
 }
 
+void register_9x_service(void)
+{
+        HINSTANCE kerneldll;
+        DWORD (*RegisterServiceProcess)(DWORD, DWORD);
+
+       /* The service register mechanism in 9x/Me is pretty different from
+        * NT/2K/XP.  In NT/2K/XP we're using a special service starter
+        * application to register and control sshd as service.  This method
+        * doesn't play nicely with 9x/Me.  For that reason we register here
+        * as service when running under 9x/Me.  This function is only called
+        * by the child sshd when it's going to daemonize.
+        */
+       if (is_winnt)
+               return;
+       if (! (kerneldll = LoadLibrary("KERNEL32.DLL")))
+               return;
+       if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD))
+                         GetProcAddress(kerneldll, "RegisterServiceProcess")))
+               return;
+       RegisterServiceProcess(0, 1);
+}
+
 #endif /* HAVE_CYGWIN */
index 8bd5fadd461ea9c436b41d1ffd6cb566265c44f2..a87aeee3f17821518b2fd0e294edc4f35db5b44e 100644 (file)
@@ -24,8 +24,9 @@
 
 int binary_open(const char *filename, int flags, ...);
 int binary_pipe(int fd[2]);
-int check_nt_auth(int pwd_authenticated, uid_t uid);
+int check_nt_auth(int pwd_authenticated, struct passwd *pw);
 int check_ntsec(const char *filename);
+void register_9x_service(void);
 
 #define open binary_open
 #define pipe binary_pipe
index f704a9048ed4076628579acaa0e0a1093f3afe0c..7d23b2467b949ee2cc2776ee362a16f9df49c919 100644 (file)
@@ -49,6 +49,9 @@ daemon(nochdir, noclose)
        case -1:
                return (-1);
        case 0:
+#ifdef HAVE_CYGWIN
+               register_9x_service();
+#endif
                break;
        default:
 #ifdef HAVE_CYGWIN
index a76a1dc13f7df771c1db00acc5b4e640a361baff..391b2dd81cfce10041ba30bcdb539ca294cb9a4b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dirname.c,v 1.5 2001/06/27 00:58:54 lebel Exp $       */
+/*     $OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $     */
 
 /*
  * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -31,7 +31,7 @@
 #ifndef HAVE_DIRNAME
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: dirname.c,v 1.5 2001/06/27 00:58:54 lebel Exp $";
+static char rcsid[] = "$OpenBSD: dirname.c,v 1.6 2001/06/28 04:27:19 pjanzen Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <errno.h>
@@ -70,7 +70,7 @@ dirname(path)
                } while (endp > path && *endp == '/');
        }
 
-       if (endp - path + 1 > sizeof(bname)) {
+       if (endp - path + 2 > sizeof(bname)) {
                errno = ENAMETOOLONG;
                return(NULL);
        }
index 269af413c35195fc99ffe69d89148212a5ac632d..c85bb240c53dcfa1b8feb22373354b2d101d3265 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $  */
+/*     $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $      */
 /*     $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $       */
 
 /*
@@ -136,6 +136,19 @@ struct {                                                           \
        (head)->slh_first = (head)->slh_first->field.sle_next;          \
 } while (0)
 
+#define SLIST_REMOVE(head, elm, type, field) do {                      \
+       if ((head)->slh_first == (elm)) {                               \
+               SLIST_REMOVE_HEAD((head), field);                       \
+       }                                                               \
+       else {                                                          \
+               struct type *curelm = (head)->slh_first;                \
+               while( curelm->field.sle_next != (elm) )                \
+                       curelm = curelm->field.sle_next;                \
+               curelm->field.sle_next =                                \
+                   curelm->field.sle_next->field.sle_next;             \
+       }                                                               \
+} while (0)
+
 /*
  * List definitions.
  */
index 9ed1bc80f4eae35d7f50066368d9d3b5a80dff77..d69dc5c24a5bb75d5c5ab244d714fa1e5a57745b 100644 (file)
@@ -39,7 +39,7 @@
 #ifndef HAVE_MKDTEMP
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: mktemp.c,v 1.14 2002/01/02 20:18:32 deraadt Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #ifdef HAVE_CYGWIN
@@ -84,7 +84,8 @@ _gettemp(path, doopen, domkdir, slen)
 {
        register char *start, *trv, *suffp;
        struct stat sbuf;
-       int pid, rval;
+       int rval;
+       pid_t pid;
 
        if (doopen && domkdir) {
                errno = EINVAL;
index 845d98fb9414afe7687f6d2e22c82c7cd63e31c9..551bdc939aafe4ae83aa3cf75d769c7f8acbe2ae 100644 (file)
@@ -40,5 +40,7 @@
 
 /* Routines for a single OS platform */
 #include "bsd-cray.h"
+#include "port-irix.h"
+#include "port-aix.h"
 
 #endif /* _OPENBSD_H */
diff --git a/openssh/openbsd-compat/port-aix.c b/openssh/openbsd-compat/port-aix.c
new file mode 100644 (file)
index 0000000..31697d7
--- /dev/null
@@ -0,0 +1,126 @@
+#include "includes.h"
+
+#ifdef _AIX
+
+#ifdef HAVE_USERSEC_H
+#include <usersec.h>
+#endif /* HAVE_USERSEC_H */
+
+#include <uinfo.h>
+#include <../xmalloc.h>
+
+/* AIX limits */
+#if defined(HAVE_GETUSERATTR) && !defined(S_UFSIZE_HARD) && defined(S_UFSIZE)
+# define S_UFSIZE_HARD  S_UFSIZE "_hard"
+# define S_UCPU_HARD  S_UCPU "_hard"
+# define S_UDATA_HARD  S_UDATA "_hard"
+# define S_USTACK_HARD  S_USTACK "_hard"
+# define S_URSS_HARD  S_URSS "_hard"
+# define S_UCORE_HARD  S_UCORE "_hard"
+# define S_UNOFILE_HARD S_UNOFILE "_hard"
+#endif
+
+#if defined(HAVE_GETUSERATTR)
+/*
+ * AIX-specific login initialisation
+ */
+void 
+set_limit(char *user, char *soft, char *hard, int resource, int mult)
+{
+        struct rlimit rlim;
+        int slim, hlim;
+
+        getrlimit(resource, &rlim);
+
+        slim = 0;
+        if (getuserattr(user, soft, &slim, SEC_INT) != -1) {
+                if (slim < 0) {
+                        rlim.rlim_cur = RLIM_INFINITY;
+                } else if (slim != 0) {
+                        /* See the wackiness below */
+                        if (rlim.rlim_cur == slim * mult)
+                                slim = 0;
+                        else
+                                rlim.rlim_cur = slim * mult;
+                }
+        }
+        hlim = 0;
+        if (getuserattr(user, hard, &hlim, SEC_INT) != -1) {
+                if (hlim < 0) {
+                        rlim.rlim_max = RLIM_INFINITY;
+                } else if (hlim != 0) {
+                        rlim.rlim_max = hlim * mult;
+                }
+        }
+
+        /*
+         * XXX For cpu and fsize the soft limit is set to the hard limit
+         * if the hard limit is left at its default value and the soft limit
+         * is changed from its default value, either by requesting it
+         * (slim == 0) or by setting it to the current default.  At least
+         * that's how rlogind does it.  If you're confused you're not alone.
+         * Bug or feature? AIX 4.3.1.2
+         */
+        if ((!strcmp(soft, "fsize") || !strcmp(soft, "cpu"))
+            && hlim == 0 && slim != 0)
+                rlim.rlim_max = rlim.rlim_cur;
+        /* A specified hard limit limits the soft limit */
+        else if (hlim > 0 && rlim.rlim_cur > rlim.rlim_max)
+                rlim.rlim_cur = rlim.rlim_max;
+        /* A soft limit can increase a hard limit */
+        else if (rlim.rlim_cur > rlim.rlim_max)
+                rlim.rlim_max = rlim.rlim_cur;
+
+        if (setrlimit(resource, &rlim) != 0)
+                error("setrlimit(%.10s) failed: %.100s", soft, strerror(errno));
+}
+
+void 
+set_limits_from_userattr(char *user)
+{
+        int mask;
+        char buf[16];
+
+        set_limit(user, S_UFSIZE, S_UFSIZE_HARD, RLIMIT_FSIZE, 512);
+        set_limit(user, S_UCPU, S_UCPU_HARD, RLIMIT_CPU, 1);
+        set_limit(user, S_UDATA, S_UDATA_HARD, RLIMIT_DATA, 512);
+        set_limit(user, S_USTACK, S_USTACK_HARD, RLIMIT_STACK, 512);
+        set_limit(user, S_URSS, S_URSS_HARD, RLIMIT_RSS, 512);
+        set_limit(user, S_UCORE, S_UCORE_HARD, RLIMIT_CORE, 512);
+#if defined(S_UNOFILE)
+        set_limit(user, S_UNOFILE, S_UNOFILE_HARD, RLIMIT_NOFILE, 1);
+#endif
+
+        if (getuserattr(user, S_UMASK, &mask, SEC_INT) != -1) {
+                /* Convert decimal to octal */
+                (void) snprintf(buf, sizeof(buf), "%d", mask);
+                if (sscanf(buf, "%o", &mask) == 1)
+                        umask(mask);
+        }
+}
+#endif /* defined(HAVE_GETUSERATTR) */
+
+/*
+ * AIX has a "usrinfo" area where logname and
+ * other stuff is stored - a few applications
+ * actually use this and die if it's not set
+ */
+void
+aix_usrinfo(struct passwd *pw, char *tty, int ttyfd) 
+{
+       u_int i;
+       char *cp=NULL;
+
+       if (ttyfd == -1)
+               tty[0] = '\0';
+       cp = xmalloc(22 + strlen(tty) + 2 * strlen(pw->pw_name));
+       i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c", pw->pw_name, 0, 
+           pw->pw_name, 0, tty, 0, 0);
+       if (usrinfo(SETUINFO, cp, i) == -1)
+               fatal("Couldn't set usrinfo: %s", strerror(errno));
+       debug3("AIX/UsrInfo: set len %d", i);
+       xfree(cp);
+}
+
+#endif /* _AIX */
+
diff --git a/openssh/openbsd-compat/port-aix.h b/openssh/openbsd-compat/port-aix.h
new file mode 100644 (file)
index 0000000..29d2ee6
--- /dev/null
@@ -0,0 +1,10 @@
+#ifdef _AIX
+
+#ifdef HAVE_GETUSERATTR
+void set_limit(char *user, char *soft, char *hard, int resource, int mult);
+void set_limits_from_userattr(char *user);
+#endif /* HAVE_GETUSERATTR */
+
+void aix_usrinfo(struct passwd *pw, char *tty, int ttyfd);
+
+#endif /* _AIX */
diff --git a/openssh/openbsd-compat/port-irix.c b/openssh/openbsd-compat/port-irix.c
new file mode 100644 (file)
index 0000000..a63ec42
--- /dev/null
@@ -0,0 +1,61 @@
+#include "includes.h"
+
+#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
+
+#ifdef WITH_IRIX_PROJECT
+#include <proj.h>
+#endif /* WITH_IRIX_PROJECT */
+#ifdef WITH_IRIX_JOBS
+#include <sys/resource.h>
+#endif
+#ifdef WITH_IRIX_AUDIT
+#include <sat.h>
+#endif /* WITH_IRIX_AUDIT */
+
+void
+irix_setusercontext(struct passwd *pw)
+{
+#ifdef WITH_IRIX_PROJECT
+        prid_t projid;
+#endif /* WITH_IRIX_PROJECT */
+#ifdef WITH_IRIX_JOBS
+        jid_t jid = 0;
+#else
+# ifdef WITH_IRIX_ARRAY
+        int jid = 0;
+# endif /* WITH_IRIX_ARRAY */
+#endif /* WITH_IRIX_JOBS */
+
+#ifdef WITH_IRIX_JOBS
+        jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive");
+        if (jid == -1)
+                fatal("Failed to create job container: %.100s",
+                    strerror(errno));
+#endif /* WITH_IRIX_JOBS */
+#ifdef WITH_IRIX_ARRAY
+        /* initialize array session */
+        if (jid == 0  && newarraysess() != 0)
+                fatal("Failed to set up new array session: %.100s",
+                    strerror(errno));
+#endif /* WITH_IRIX_ARRAY */
+#ifdef WITH_IRIX_PROJECT
+        /* initialize irix project info */
+        if ((projid = getdfltprojuser(pw->pw_name)) == -1) {
+                debug("Failed to get project id, using projid 0");
+                projid = 0;
+        }
+        if (setprid(projid))
+                fatal("Failed to initialize project %d for %s: %.100s",
+                    (int)projid, pw->pw_name, strerror(errno));
+#endif /* WITH_IRIX_PROJECT */
+#ifdef WITH_IRIX_AUDIT
+        if (sysconf(_SC_AUDIT)) {
+                debug("Setting sat id to %d", (int) pw->pw_uid);
+                if (satsetid(pw->pw_uid))
+                        debug("error setting satid: %.100s", strerror(errno));
+        }
+#endif /* WITH_IRIX_AUDIT */
+}
+
+
+#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
diff --git a/openssh/openbsd-compat/port-irix.h b/openssh/openbsd-compat/port-irix.h
new file mode 100644 (file)
index 0000000..2dd3c2e
--- /dev/null
@@ -0,0 +1,5 @@
+#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
+
+void irix_setusercontext(struct passwd *pw);
+
+#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
index fdef15809d7a54a3ca8aa681dc073a3b3981616e..7687710373458434caad7c52036d1a39d92c077e 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $     */
+
 /*
  * Copyright (c) 2000 Todd C. Miller <Todd.Miller@courtesan.com>
  * All rights reserved.
@@ -26,7 +28,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.5 2001/06/27 13:23:30 djm Exp $";
+static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include "includes.h"
@@ -47,20 +49,19 @@ static char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.5 2001/06/27 13:23:30 djm
 #  define _POSIX_VDISABLE       VDISABLE
 #endif
 
+static volatile sig_atomic_t signo;
+
+static void handler(int);
+
 char *
-readpassphrase(prompt, buf, bufsiz, flags)
-       const char *prompt;
-       char *buf;
-       size_t bufsiz;
-       int flags;
+readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
 {
-       struct termios term;
+       ssize_t nr;
+       int input, output, save_errno;
        char ch, *p, *end;
-#ifdef _POSIX_VDISABLE
-       u_char status;
-#endif
-       int echo, input, output;
-       sigset_t oset, nset;
+       struct termios term, oterm;
+       struct sigaction sa, saveint, savehup, savequit, saveterm;
+       struct sigaction savetstp, savettin, savettou;
 
        /* I suppose we could alloc on demand in this case (XXX). */
        if (bufsiz == 0) {
@@ -68,6 +69,7 @@ readpassphrase(prompt, buf, bufsiz, flags)
                return(NULL);
        }
 
+restart:
        /*
         * Read and write to /dev/tty if available.  If not, read from
         * stdin and write to stderr unless a tty is required.
@@ -82,44 +84,39 @@ readpassphrase(prompt, buf, bufsiz, flags)
        }
 
        /*
-        * We block SIGINT and SIGTSTP so the terminal is not left
-        * in an inconsistent state (ie: no echo).  It would probably
-        * be better to simply catch these though.
+        * Catch signals that would otherwise cause the user to end
+        * up with echo turned off in the shell.  Don't worry about
+        * things like SIGALRM and SIGPIPE for now.
         */
-       sigemptyset(&nset);
-       sigaddset(&nset, SIGINT);
-       sigaddset(&nset, SIGTSTP);
-       (void)sigprocmask(SIG_BLOCK, &nset, &oset);
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = 0;                /* don't restart system calls */
+       sa.sa_handler = handler;
+       (void)sigaction(SIGINT, &sa, &saveint);
+       (void)sigaction(SIGHUP, &sa, &savehup);
+       (void)sigaction(SIGQUIT, &sa, &savequit);
+       (void)sigaction(SIGTERM, &sa, &saveterm);
+       (void)sigaction(SIGTSTP, &sa, &savetstp);
+       (void)sigaction(SIGTTIN, &sa, &savettin);
+       (void)sigaction(SIGTTOU, &sa, &savettou);
 
        /* Turn off echo if possible. */
-       echo = 0;
-#ifdef _POSIX_VDISABLE
-       status = _POSIX_VDISABLE;
-#endif
-       if (tcgetattr(input, &term) == 0) {
-               if (!(flags & RPP_ECHO_ON) && (term.c_lflag & ECHO)) {
-                       echo = 1;
-                       term.c_lflag &= ~ECHO;
-               }
+       if (tcgetattr(input, &oterm) == 0) {
+               memcpy(&term, &oterm, sizeof(term));
+               if (!(flags & RPP_ECHO_ON))
+                       term.c_lflag &= ~(ECHO | ECHONL);
 #ifdef VSTATUS
-               if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) {
-                       status = term.c_cc[VSTATUS];
+               if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)
                        term.c_cc[VSTATUS] = _POSIX_VDISABLE;
-               }
 #endif
                (void)tcsetattr(input, _T_FLUSH, &term);
-       }
-       if (!(flags & RPP_ECHO_ON)) {
-               if (tcgetattr(input, &term) == 0 && (term.c_lflag & ECHO)) {
-                       echo = 1;
-                       term.c_lflag &= ~ECHO;
-                       (void)tcsetattr(input, _T_FLUSH, &term);
-               }
+       } else {
+               memset(&term, 0, sizeof(term));
+               memset(&oterm, 0, sizeof(oterm));
        }
 
        (void)write(output, prompt, strlen(prompt));
        end = buf + bufsiz - 1;
-       for (p = buf; read(input, &ch, 1) == 1 && ch != '\n' && ch != '\r';) {
+       for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) {
                if (p < end) {
                        if ((flags & RPP_SEVENBIT))
                                ch &= 0x7f;
@@ -133,35 +130,55 @@ readpassphrase(prompt, buf, bufsiz, flags)
                }
        }
        *p = '\0';
-#ifdef _POSIX_VDISABLE
-       if (echo || status != _POSIX_VDISABLE) {
-#else
-       if (echo) {
-#endif
-               if (echo) {
-                       (void)write(output, "\n", 1);
-                       term.c_lflag |= ECHO;
-               }
-#ifdef VSTATUS
-               if (status != _POSIX_VDISABLE)
-                       term.c_cc[VSTATUS] = status;
-#endif
-               (void)tcsetattr(input, _T_FLUSH, &term);
-       }
-       (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+       save_errno = errno;
+       if (!(term.c_lflag & ECHO))
+               (void)write(output, "\n", 1);
+
+       /* Restore old terminal settings and signals. */
+       if (memcmp(&term, &oterm, sizeof(term)) != 0)
+               (void)tcsetattr(input, _T_FLUSH, &oterm);
+       (void)sigaction(SIGINT, &saveint, NULL);
+       (void)sigaction(SIGHUP, &savehup, NULL);
+       (void)sigaction(SIGQUIT, &savequit, NULL);
+       (void)sigaction(SIGTERM, &saveterm, NULL);
+       (void)sigaction(SIGTSTP, &savetstp, NULL);
+       (void)sigaction(SIGTTIN, &savettin, NULL);
+       (void)sigaction(SIGTTOU, &savettou, NULL);
        if (input != STDIN_FILENO)
                (void)close(input);
-       return(buf);
+
+       /*
+        * If we were interrupted by a signal, resend it to ourselves
+        * now that we have restored the signal handlers.
+        */
+       if (signo) {
+               kill(getpid(), signo); 
+               switch (signo) {
+               case SIGTSTP:
+               case SIGTTIN:
+               case SIGTTOU:
+                       signo = 0;
+                       goto restart;
+               }
+       }
+
+       errno = save_errno;
+       return(nr == -1 ? NULL : buf);
 }
 #endif /* HAVE_READPASSPHRASE */
-
+  
 #if 0
 char *
-getpass(prompt)
-        const char *prompt;
+getpass(const char *prompt)
 {
        static char buf[_PASSWORD_LEN + 1];
 
        return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF));
 }
 #endif
+
+static void handler(int s)
+{
+
+       signo = s;
+}
index ec801d498dc9d21b82d05a5ec54760df7c293b74..b4a05db95314ca677a9b35ab4f2a38a02a53536c 100644 (file)
@@ -32,7 +32,7 @@
 #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH)
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: realpath.c,v 1.5 2001/06/27 00:58:56 lebel Exp $";
+static char *rcsid = "$OpenBSD: realpath.c,v 1.6 2002/01/12 16:24:35 millert Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
@@ -74,6 +74,10 @@ realpath(const char *path, char *resolved)
        }
        close(fd);
 
+       /* Convert "." -> "" to optimize away a needless lstat() and chdir() */
+       if (path[0] == '.' && path[1] == '\0')
+               path = "";
+
        /*
         * Find the dirname and basename from the path to be resolved.
         * Change directory to the dirname component.
@@ -102,7 +106,7 @@ loop:
                p = resolved;
 
        /* Deal with the last component. */
-       if (lstat(p, &sb) == 0) {
+       if (*p != '\0' && lstat(p, &sb) == 0) {
                if (S_ISLNK(sb.st_mode)) {
                        if (++symlinks > MAXSYMLINKS) {
                                serrno = ELOOP;
index ac9670baf9133a7abdd2b0d9e0f271c18d445fd0..6c2d5cd3188a149ac2d17a87a71f51507089c2de 100644 (file)
@@ -35,7 +35,7 @@
 #ifndef HAVE_SETENV
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: setenv.c,v 1.3 1998/02/02 22:44:53 millert Exp $";
+static char *rcsid = "$OpenBSD: setenv.c,v 1.4 2001/07/09 06:57:45 deraadt Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include <stdlib.h>
@@ -101,7 +101,8 @@ setenv(name, value, rewrite)
                if (!rewrite)
                        return (0);
                if (strlen(C) >= l_value) {     /* old larger; copy over */
-                       while ((*C++ = *value++));
+                       while ((*C++ = *value++))
+                               ;
                        return (0);
                }
        } else {                                        /* create new slot */
index 38eca9ad755ef4416c4d1d84a59666edc4addd4e..e165dd13c805f43d295fa65ff649d412cf45b9a2 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.7 1999/02/25 22:10:12 art Exp $";
+static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.8 2001/11/06 19:21:40 art Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #include "includes.h"
index 7b94169a34eff0d1e3faeee21e8fc6300c5b9e2b..045d5a10556d7a8b8f840482f8800849c6bf5cab 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.72 2001/11/10 13:37:20 markus Exp $");
+RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -59,6 +59,7 @@ RCSID("$OpenBSD: packet.c,v 1.72 2001/11/10 13:37:20 markus Exp $");
 #include "mac.h"
 #include "log.h"
 #include "canohost.h"
+#include "misc.h"
 
 #ifdef PACKET_DEBUG
 #define DBG(x) x
@@ -130,8 +131,8 @@ packet_set_connection(int fd_in, int fd_out)
                fatal("packet_set_connection: cannot load cipher 'none'");
        connection_in = fd_in;
        connection_out = fd_out;
-       cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0);
-       cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0);
+       cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT);
+       cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT);
        newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
        if (!initialized) {
                initialized = 1;
@@ -147,7 +148,7 @@ packet_set_connection(int fd_in, int fd_out)
 /* Returns 1 if remote host is connected via socket, 0 if not. */
 
 int
-packet_connection_is_on_socket()
+packet_connection_is_on_socket(void)
 {
        struct sockaddr_storage from, to;
        socklen_t fromlen, tolen;
@@ -173,7 +174,7 @@ packet_connection_is_on_socket()
 /* returns 1 if connection is via ipv4 */
 
 int
-packet_connection_is_ipv4()
+packet_connection_is_ipv4(void)
 {
        struct sockaddr_storage to;
        socklen_t tolen = sizeof(to);
@@ -189,7 +190,7 @@ packet_connection_is_ipv4()
 /* Sets the connection into non-blocking mode. */
 
 void
-packet_set_nonblocking()
+packet_set_nonblocking(void)
 {
        /* Set the socket into non-blocking mode. */
        if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
@@ -204,7 +205,7 @@ packet_set_nonblocking()
 /* Returns the socket used for reading. */
 
 int
-packet_get_connection_in()
+packet_get_connection_in(void)
 {
        return connection_in;
 }
@@ -212,7 +213,7 @@ packet_get_connection_in()
 /* Returns the descriptor used for writing. */
 
 int
-packet_get_connection_out()
+packet_get_connection_out(void)
 {
        return connection_out;
 }
@@ -220,7 +221,7 @@ packet_get_connection_out()
 /* Closes the connection and clears and frees internal data structures. */
 
 void
-packet_close()
+packet_close(void)
 {
        if (!initialized)
                return;
@@ -240,6 +241,8 @@ packet_close()
                buffer_free(&compression_buffer);
                buffer_compress_uninit();
        }
+       cipher_cleanup(&send_context);
+       cipher_cleanup(&receive_context);
 }
 
 /* Sets remote side protocol flags. */
@@ -253,7 +256,7 @@ packet_set_protocol_flags(u_int protocol_flags)
 /* Returns the remote protocol flags set earlier by the above function. */
 
 u_int
-packet_get_protocol_flags()
+packet_get_protocol_flags(void)
 {
        return remote_protocol_flags;
 }
@@ -297,8 +300,8 @@ packet_set_encryption_key(const u_char *key, u_int keylen,
                fatal("packet_set_encryption_key: unknown cipher number %d", number);
        if (keylen < 20)
                fatal("packet_set_encryption_key: keylen too small: %d", keylen);
-       cipher_init(&receive_context, cipher, key, keylen, NULL, 0);
-       cipher_init(&send_context, cipher, key, keylen, NULL, 0);
+       cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
+       cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
 }
 
 /* Start constructing a packet to send. */
@@ -329,7 +332,7 @@ packet_put_int(u_int value)
        buffer_put_int(&outgoing_packet, value);
 }
 void
-packet_put_string(const char *buf, u_int len)
+packet_put_string(const void *buf, u_int len)
 {
        buffer_put_string(&outgoing_packet, buf, len);
 }
@@ -339,7 +342,7 @@ packet_put_cstring(const char *str)
        buffer_put_cstring(&outgoing_packet, str);
 }
 void
-packet_put_raw(const char *buf, u_int len)
+packet_put_raw(const void *buf, u_int len)
 {
        buffer_append(&outgoing_packet, buf, len);
 }
@@ -362,7 +365,7 @@ packet_put_bignum2(BIGNUM * value)
 static void
 packet_send1(void)
 {
-       char buf[8], *cp;
+       u_char buf[8], *cp;
        int i, padding, len;
        u_int checksum;
        u_int32_t rand = 0;
@@ -380,14 +383,14 @@ packet_send1(void)
                buffer_compress(&outgoing_packet, &compression_buffer);
                buffer_clear(&outgoing_packet);
                buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
-                             buffer_len(&compression_buffer));
+                   buffer_len(&compression_buffer));
        }
        /* Compute packet length without padding (add checksum, remove padding). */
        len = buffer_len(&outgoing_packet) + 4 - 8;
 
        /* Insert padding. Initialized to zero in packet_start1() */
        padding = 8 - len % 8;
-       if (send_context.cipher->number != SSH_CIPHER_NONE) {
+       if (!send_context.plaintext) {
                cp = buffer_ptr(&outgoing_packet);
                for (i = 0; i < padding; i++) {
                        if (i % 4 == 0)
@@ -399,7 +402,7 @@ packet_send1(void)
        buffer_consume(&outgoing_packet, 8 - padding);
 
        /* Add check bytes. */
-       checksum = ssh_crc32((u_char *) buffer_ptr(&outgoing_packet),
+       checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
            buffer_len(&outgoing_packet));
        PUT_32BIT(buf, checksum);
        buffer_append(&outgoing_packet, buf, 4);
@@ -412,9 +415,9 @@ packet_send1(void)
        /* Append to output. */
        PUT_32BIT(buf, len);
        buffer_append(&output, buf, 4);
-       buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
-       cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
-                      buffer_len(&outgoing_packet));
+       cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
+       cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
+           buffer_len(&outgoing_packet));
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "encrypted: ");
@@ -437,14 +440,20 @@ set_newkeys(int mode)
        Mac *mac;
        Comp *comp;
        CipherContext *cc;
+       int encrypt;
 
        debug("newkeys: mode %d", mode);
 
-       cc = (mode == MODE_OUT) ? &send_context : &receive_context;
+       if (mode == MODE_OUT) {
+               cc = &send_context;
+               encrypt = CIPHER_ENCRYPT;
+       } else {
+               cc = &receive_context;
+               encrypt = CIPHER_DECRYPT;
+       }
        if (newkeys[mode] != NULL) {
                debug("newkeys: rekeying");
-               /* todo: free old keys, reset compression/cipher-ctxt; */
-               memset(cc, 0, sizeof(*cc));
+               cipher_cleanup(cc);
                enc  = &newkeys[mode]->enc;
                mac  = &newkeys[mode]->mac;
                comp = &newkeys[mode]->comp;
@@ -466,10 +475,10 @@ set_newkeys(int mode)
        if (mac->md != NULL)
                mac->enabled = 1;
        DBG(debug("cipher_init_context: %d", mode));
-       cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len,
-           enc->iv, enc->cipher->block_size);
-       memset(enc->iv,  0, enc->cipher->block_size);
-       memset(enc->key, 0, enc->cipher->key_len);
+       cipher_init(cc, enc->cipher, enc->key, enc->key_len,
+           enc->iv, enc->block_size, encrypt);
+       memset(enc->iv,  0, enc->block_size);
+       memset(enc->key, 0, enc->key_len);
        if (comp->type != 0 && comp->enabled == 0) {
                packet_init_compression();
                if (mode == MODE_OUT)
@@ -487,9 +496,8 @@ static void
 packet_send2(void)
 {
        static u_int32_t seqnr = 0;
-       u_char type, *ucp, *macbuf = NULL;
+       u_char type, *cp, *macbuf = NULL;
        u_char padlen, pad;
-       char *cp;
        u_int packet_length = 0;
        u_int i, len;
        u_int32_t rand = 0;
@@ -503,10 +511,10 @@ packet_send2(void)
                mac  = &newkeys[MODE_OUT]->mac;
                comp = &newkeys[MODE_OUT]->comp;
        }
-       block_size = enc ? enc->cipher->block_size : 8;
+       block_size = enc ? enc->block_size : 8;
 
-       ucp = (u_char *) buffer_ptr(&outgoing_packet);
-       type = ucp[5];
+       cp = buffer_ptr(&outgoing_packet);
+       type = cp[5];
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "plain:     ");
@@ -546,8 +554,8 @@ packet_send2(void)
                padlen += pad;
                extra_pad = 0;
        }
-       buffer_append_space(&outgoing_packet, &cp, padlen);
-       if (enc && enc->cipher->number != SSH_CIPHER_NONE) {
+       cp = buffer_append_space(&outgoing_packet, padlen);
+       if (enc && !send_context.plaintext) {
                /* random padding */
                for (i = 0; i < padlen; i++) {
                        if (i % 4 == 0)
@@ -561,21 +569,21 @@ packet_send2(void)
        }
        /* packet_length includes payload, padding and padding length field */
        packet_length = buffer_len(&outgoing_packet) - 4;
-       ucp = (u_char *)buffer_ptr(&outgoing_packet);
-       PUT_32BIT(ucp, packet_length);
-       ucp[4] = padlen;
+       cp = buffer_ptr(&outgoing_packet);
+       PUT_32BIT(cp, packet_length);
+       cp[4] = padlen;
        DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
 
        /* compute MAC over seqnr and packet(length fields, payload, padding) */
        if (mac && mac->enabled) {
                macbuf = mac_compute(mac, seqnr,
-                   (u_char *) buffer_ptr(&outgoing_packet),
+                   buffer_ptr(&outgoing_packet),
                    buffer_len(&outgoing_packet));
                DBG(debug("done calc MAC out #%d", seqnr));
        }
        /* encrypt packet and append to output buffer. */
-       buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
-       cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
+       cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
+       cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
            buffer_len(&outgoing_packet));
        /* append unencrypted MAC */
        if (mac && mac->enabled)
@@ -594,7 +602,7 @@ packet_send2(void)
 }
 
 void
-packet_send()
+packet_send(void)
 {
        if (compat20)
                packet_send2();
@@ -610,7 +618,7 @@ packet_send()
  */
 
 int
-packet_read(int *payload_len_ptr)
+packet_read_seqnr(u_int32_t *seqnr_p)
 {
        int type, len;
        fd_set *setp;
@@ -626,13 +634,13 @@ packet_read(int *payload_len_ptr)
        /* Stay in the loop until we have received a complete packet. */
        for (;;) {
                /* Try to read a packet from the buffer. */
-               type = packet_read_poll(payload_len_ptr);
+               type = packet_read_poll_seqnr(seqnr_p);
                if (!compat20 && (
                    type == SSH_SMSG_SUCCESS
                    || type == SSH_SMSG_FAILURE
                    || type == SSH_CMSG_EOF
                    || type == SSH_CMSG_EXIT_CONFIRMATION))
-                       packet_integrity_check(*payload_len_ptr, 0, type);
+                       packet_check_eom();
                /* If we got a packet, return it. */
                if (type != SSH_MSG_NONE) {
                        xfree(setp);
@@ -665,17 +673,23 @@ packet_read(int *payload_len_ptr)
        /* NOTREACHED */
 }
 
+int
+packet_read(void)
+{
+       return packet_read_seqnr(NULL);
+}
+
 /*
  * Waits until a packet has been received, verifies that its type matches
  * that given, and gives a fatal error and exits if there is a mismatch.
  */
 
 void
-packet_read_expect(int *payload_len_ptr, int expected_type)
+packet_read_expect(int expected_type)
 {
        int type;
 
-       type = packet_read(payload_len_ptr);
+       type = packet_read();
        if (type != expected_type)
                packet_disconnect("Protocol error: expected packet type %d, got %d",
                    expected_type, type);
@@ -688,28 +702,21 @@ packet_read_expect(int *payload_len_ptr, int expected_type)
  * SSH_MSG_DISCONNECT is handled specially here.  Also,
  * SSH_MSG_IGNORE messages are skipped by this function and are never returned
  * to higher levels.
- *
- * The returned payload_len does include space consumed by:
- *     Packet length
- *     Padding
- *     Packet type
- *     Check bytes
  */
 
 static int
-packet_read_poll1(int *payload_len_ptr)
+packet_read_poll1(void)
 {
        u_int len, padded_len;
-       u_char *ucp, type;
-       char *cp;
+       u_char *cp, type;
        u_int checksum, stored_checksum;
 
        /* Check if input size is less than minimum packet size. */
        if (buffer_len(&input) < 4 + 8)
                return SSH_MSG_NONE;
        /* Get length of incoming packet. */
-       ucp = (u_char *) buffer_ptr(&input);
-       len = GET_32BIT(ucp);
+       cp = buffer_ptr(&input);
+       len = GET_32BIT(cp);
        if (len < 1 + 2 + 2 || len > 256 * 1024)
                packet_disconnect("Bad packet length %d.", len);
        padded_len = (len + 8) & ~7;
@@ -728,14 +735,14 @@ packet_read_poll1(int *payload_len_ptr)
         * (C)1998 CORE-SDI, Buenos Aires Argentina
         * Ariel Futoransky(futo@core-sdi.com)
         */
-       if (receive_context.cipher->number != SSH_CIPHER_NONE &&
+       if (!receive_context.plaintext &&
            detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED)
                packet_disconnect("crc32 compensation attack: network attack detected");
 
        /* Decrypt data to incoming_packet. */
        buffer_clear(&incoming_packet);
-       buffer_append_space(&incoming_packet, &cp, padded_len);
-       cipher_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
+       cp = buffer_append_space(&incoming_packet, padded_len);
+       cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
 
        buffer_consume(&input, padded_len);
 
@@ -745,7 +752,7 @@ packet_read_poll1(int *payload_len_ptr)
 #endif
 
        /* Compute packet checksum. */
-       checksum = ssh_crc32((u_char *) buffer_ptr(&incoming_packet),
+       checksum = ssh_crc32(buffer_ptr(&incoming_packet),
            buffer_len(&incoming_packet) - 4);
 
        /* Skip padding. */
@@ -753,11 +760,11 @@ packet_read_poll1(int *payload_len_ptr)
 
        /* Test check bytes. */
        if (len != buffer_len(&incoming_packet))
-               packet_disconnect("packet_read_poll: len %d != buffer_len %d.",
+               packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
                    len, buffer_len(&incoming_packet));
 
-       ucp = (u_char *) buffer_ptr(&incoming_packet) + len - 4;
-       stored_checksum = GET_32BIT(ucp);
+       cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
+       stored_checksum = GET_32BIT(cp);
        if (checksum != stored_checksum)
                packet_disconnect("Corrupted check bytes on input.");
        buffer_consume_end(&incoming_packet, 4);
@@ -770,18 +777,16 @@ packet_read_poll1(int *payload_len_ptr)
                    buffer_len(&compression_buffer));
        }
        type = buffer_get_char(&incoming_packet);
-       *payload_len_ptr = buffer_len(&incoming_packet);
        return type;
 }
 
 static int
-packet_read_poll2(int *payload_len_ptr)
+packet_read_poll2(u_int32_t *seqnr_p)
 {
        static u_int32_t seqnr = 0;
        static u_int packet_length = 0;
        u_int padlen, need;
-       u_char *macbuf, *ucp, type;
-       char *cp;
+       u_char *macbuf, *cp, type;
        int maclen, block_size;
        Enc *enc   = NULL;
        Mac *mac   = NULL;
@@ -793,7 +798,7 @@ packet_read_poll2(int *payload_len_ptr)
                comp = &newkeys[MODE_IN]->comp;
        }
        maclen = mac && mac->enabled ? mac->mac_len : 0;
-       block_size = enc ? enc->cipher->block_size : 8;
+       block_size = enc ? enc->block_size : 8;
 
        if (packet_length == 0) {
                /*
@@ -803,11 +808,11 @@ packet_read_poll2(int *payload_len_ptr)
                if (buffer_len(&input) < block_size)
                        return SSH_MSG_NONE;
                buffer_clear(&incoming_packet);
-               buffer_append_space(&incoming_packet, &cp, block_size);
-               cipher_decrypt(&receive_context, cp, buffer_ptr(&input),
+               cp = buffer_append_space(&incoming_packet, block_size);
+               cipher_crypt(&receive_context, cp, buffer_ptr(&input),
                    block_size);
-               ucp = (u_char *) buffer_ptr(&incoming_packet);
-               packet_length = GET_32BIT(ucp);
+               cp = buffer_ptr(&incoming_packet);
+               packet_length = GET_32BIT(cp);
                if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
                        buffer_dump(&incoming_packet);
                        packet_disconnect("Bad packet length %d.", packet_length);
@@ -832,8 +837,8 @@ packet_read_poll2(int *payload_len_ptr)
        fprintf(stderr, "read_poll enc/full: ");
        buffer_dump(&input);
 #endif
-       buffer_append_space(&incoming_packet, &cp, need);
-       cipher_decrypt(&receive_context, cp, buffer_ptr(&input), need);
+       cp = buffer_append_space(&incoming_packet, need);
+       cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
        buffer_consume(&input, need);
        /*
         * compute MAC over seqnr and packet,
@@ -841,19 +846,21 @@ packet_read_poll2(int *payload_len_ptr)
         */
        if (mac && mac->enabled) {
                macbuf = mac_compute(mac, seqnr,
-                   (u_char *) buffer_ptr(&incoming_packet),
+                   buffer_ptr(&incoming_packet),
                    buffer_len(&incoming_packet));
                if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
                        packet_disconnect("Corrupted MAC on input.");
                DBG(debug("MAC #%d ok", seqnr));
                buffer_consume(&input, mac->mac_len);
        }
+       if (seqnr_p != NULL)
+               *seqnr_p = seqnr;
        if (++seqnr == 0)
                log("incoming seqnr wraps around");
 
        /* get padlen */
-       cp = buffer_ptr(&incoming_packet) + 4;
-       padlen = (u_char) *cp;
+       cp = buffer_ptr(&incoming_packet);
+       padlen = cp[4];
        DBG(debug("input: padlen %d", padlen));
        if (padlen < 4)
                packet_disconnect("Corrupted padlen %d on input.", padlen);
@@ -878,7 +885,6 @@ packet_read_poll2(int *payload_len_ptr)
        type = buffer_get_char(&incoming_packet);
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_IN);
-       *payload_len_ptr = buffer_len(&incoming_packet);
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read/plain[%d]:\r\n", type);
        buffer_dump(&incoming_packet);
@@ -889,18 +895,18 @@ packet_read_poll2(int *payload_len_ptr)
 }
 
 int
-packet_read_poll(int *payload_len_ptr)
+packet_read_poll_seqnr(u_int32_t *seqnr_p)
 {
-       int reason;
+       int reason, seqnr;
        u_char type;
        char *msg;
 
        for (;;) {
                if (compat20) {
-                       type = packet_read_poll2(payload_len_ptr);
+                       type = packet_read_poll2(seqnr_p);
                        if (type)
                                DBG(debug("received packet type %d", type));
-                       switch(type) {
+                       switch (type) {
                        case SSH2_MSG_IGNORE:
                                break;
                        case SSH2_MSG_DEBUG:
@@ -919,13 +925,17 @@ packet_read_poll(int *payload_len_ptr)
                                xfree(msg);
                                fatal_cleanup();
                                break;
+                       case SSH2_MSG_UNIMPLEMENTED:
+                               seqnr = packet_get_int();
+                               debug("Received SSH2_MSG_UNIMPLEMENTED for %d", seqnr);
+                               break;
                        default:
                                return type;
                                break;
                        }
                } else {
-                       type = packet_read_poll1(payload_len_ptr);
-                       switch(type) {
+                       type = packet_read_poll1();
+                       switch (type) {
                        case SSH_MSG_IGNORE:
                                break;
                        case SSH_MSG_DEBUG:
@@ -950,6 +960,12 @@ packet_read_poll(int *payload_len_ptr)
        }
 }
 
+int
+packet_read_poll(void)
+{
+       return packet_read_poll_seqnr(NULL);
+}
+
 /*
  * Buffers the given amount of input characters.  This is intended to be used
  * together with packet_read_poll.
@@ -964,7 +980,7 @@ packet_process_incoming(const char *buf, u_int len)
 /* Returns a character from the packet. */
 
 u_int
-packet_get_char()
+packet_get_char(void)
 {
        char ch;
        buffer_get(&incoming_packet, &ch, 1);
@@ -974,7 +990,7 @@ packet_get_char()
 /* Returns an integer from the packet data. */
 
 u_int
-packet_get_int()
+packet_get_int(void)
 {
        return buffer_get_int(&incoming_packet);
 }
@@ -985,18 +1001,18 @@ packet_get_int()
  */
 
 void
-packet_get_bignum(BIGNUM * value, int *length_ptr)
+packet_get_bignum(BIGNUM * value)
 {
-       *length_ptr = buffer_get_bignum(&incoming_packet, value);
+       buffer_get_bignum(&incoming_packet, value);
 }
 
 void
-packet_get_bignum2(BIGNUM * value, int *length_ptr)
+packet_get_bignum2(BIGNUM * value)
 {
-       *length_ptr = buffer_get_bignum2(&incoming_packet, value);
+       buffer_get_bignum2(&incoming_packet, value);
 }
 
-char *
+void *
 packet_get_raw(int *length_ptr)
 {
        int bytes = buffer_len(&incoming_packet);
@@ -1018,7 +1034,7 @@ packet_remaining(void)
  * integer into which the length of the string is stored.
  */
 
-char *
+void *
 packet_get_string(u_int *length_ptr)
 {
        return buffer_get_string(&incoming_packet, length_ptr);
@@ -1111,7 +1127,7 @@ packet_disconnect(const char *fmt,...)
 /* Checks if there is any buffered output, and tries to write some of the output. */
 
 void
-packet_write_poll()
+packet_write_poll(void)
 {
        int len = buffer_len(&output);
        if (len > 0) {
@@ -1132,7 +1148,7 @@ packet_write_poll()
  */
 
 void
-packet_write_wait()
+packet_write_wait(void)
 {
        fd_set *setp;
 
@@ -1154,7 +1170,7 @@ packet_write_wait()
 /* Returns true if there is buffered data to write to the connection. */
 
 int
-packet_have_data_to_write()
+packet_have_data_to_write(void)
 {
        return buffer_len(&output) != 0;
 }
@@ -1162,7 +1178,7 @@ packet_have_data_to_write()
 /* Returns true if there is not too much data to write to the connection. */
 
 int
-packet_not_very_much_data_to_write()
+packet_not_very_much_data_to_write(void)
 {
        if (interactive_mode)
                return buffer_len(&output) < 16384;
@@ -1180,7 +1196,6 @@ packet_set_interactive(int interactive)
        int lowdelay = IPTOS_LOWDELAY;
        int throughput = IPTOS_THROUGHPUT;
 #endif
-       int on = 1;
 
        if (called)
                return;
@@ -1203,21 +1218,19 @@ packet_set_interactive(int interactive)
 #if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
                if (packet_connection_is_ipv4()) {
                        if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,
-                           (void *) &lowdelay, sizeof(lowdelay)) < 0)
+                           &lowdelay, sizeof(lowdelay)) < 0)
                                error("setsockopt IPTOS_LOWDELAY: %.100s",
                                    strerror(errno));
                }
 #endif
-               if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on,
-                   sizeof(on)) < 0)
-                       error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
+               set_nodelay(connection_in);
        } else if (packet_connection_is_ipv4()) {
                /*
                 * Set IP options for a non-interactive connection.  Use
                 * IPTOS_THROUGHPUT.
                 */
 #if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
-               if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput,
+               if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &throughput,
                    sizeof(throughput)) < 0)
                        error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
 #endif
@@ -1227,7 +1240,7 @@ packet_set_interactive(int interactive)
 /* Returns true if the current connection is interactive. */
 
 int
-packet_is_interactive()
+packet_is_interactive(void)
 {
        return interactive_mode;
 }
@@ -1277,7 +1290,7 @@ packet_send_ignore(int nbytes)
 
        packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
        packet_put_int(nbytes);
-       for(i = 0; i < nbytes; i++) {
+       for (i = 0; i < nbytes; i++) {
                if (i % 4 == 0)
                        rand = arc4random();
                packet_put_char(rand & 0xff);
index d5473001c5041ec78a0312c6779fb1af0b0a085d..d6bf2aab484f8cb173fc04a76ed30804358b3c7b 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: packet.h,v 1.33 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: packet.h,v 1.26 2001/11/07 16:03:17 markus Exp $"); */
-
 #ifndef PACKET_H
 #define PACKET_H
 
@@ -35,22 +35,24 @@ void     packet_put_char(int ch);
 void     packet_put_int(u_int value);
 void     packet_put_bignum(BIGNUM * value);
 void     packet_put_bignum2(BIGNUM * value);
-void     packet_put_string(const char *buf, u_int len);
+void     packet_put_string(const void *buf, u_int len);
 void     packet_put_cstring(const char *str);
-void     packet_put_raw(const char *buf, u_int len);
+void     packet_put_raw(const void *buf, u_int len);
 void     packet_send(void);
 
-int      packet_read(int *payload_len_ptr);
-void     packet_read_expect(int *payload_len_ptr, int type);
-int      packet_read_poll(int *packet_len_ptr);
+int      packet_read(void);
+void     packet_read_expect(int type);
+int      packet_read_poll(void);
 void     packet_process_incoming(const char *buf, u_int len);
+int      packet_read_seqnr(u_int32_t *seqnr_p);
+int      packet_read_poll_seqnr(u_int32_t *seqnr_p);
 
 u_int   packet_get_char(void);
 u_int   packet_get_int(void);
-void     packet_get_bignum(BIGNUM * value, int *length_ptr);
-void     packet_get_bignum2(BIGNUM * value, int *length_ptr);
-char   *packet_get_raw(int *length_ptr);
-char    *packet_get_string(u_int *length_ptr);
+void     packet_get_bignum(BIGNUM * value);
+void     packet_get_bignum2(BIGNUM * value);
+void   *packet_get_raw(int *length_ptr);
+void   *packet_get_string(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)));
 
@@ -72,17 +74,8 @@ extern int max_packet_size;
 int      packet_set_maxsize(int);
 #define  packet_get_maxsize() max_packet_size
 
-#define packet_integrity_check(payload_len, expected_len, type) \
-do { \
-       int _p = (payload_len), _e = (expected_len); \
-       if (_p != _e) { \
-               log("Packet integrity error (%d != %d) at %s:%d", \
-                   _p, _e, __FILE__, __LINE__); \
-               packet_disconnect("Packet integrity error. (%d)", (type)); \
-       } \
-} while (0)
-
-#define packet_done() \
+/* don't allow remaining bytes after the end of the message */
+#define packet_check_eom() \
 do { \
        int _len = packet_remaining(); \
        if (_len > 0) { \
index 0470a21596a3060a5b433f35beedd392e11c6e48..002c313a5d1d767d1602cd0a1e68975ec5498b66 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pathnames.h,v 1.9 2001/06/23 02:34:30 markus Exp $    */
+/*     $OpenBSD: pathnames.h,v 1.11 2002/02/09 17:37:34 deraadt Exp $  */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-#ifndef ETCDIR
 #define ETCDIR                         "/etc"
+
+#ifndef SSHDIR
+#define SSHDIR                         ETCDIR "/ssh"
 #endif
 
 #ifndef _PATH_SSH_PIDDIR
  * System-wide file containing host keys of known hosts.  This file should be
  * world-readable.
  */
-#define _PATH_SSH_SYSTEM_HOSTFILE      ETCDIR "/ssh_known_hosts"
+#define _PATH_SSH_SYSTEM_HOSTFILE      SSHDIR "/ssh_known_hosts"
 /* backward compat for protocol 2 */
-#define _PATH_SSH_SYSTEM_HOSTFILE2     ETCDIR "/ssh_known_hosts2"
+#define _PATH_SSH_SYSTEM_HOSTFILE2     SSHDIR "/ssh_known_hosts2"
 
 /*
  * Of these, ssh_host_key must be readable only by root, whereas ssh_config
  * should be world-readable.
  */
-#define _PATH_SERVER_CONFIG_FILE       ETCDIR "/sshd_config"
-#define _PATH_HOST_CONFIG_FILE         ETCDIR "/ssh_config"
-#define _PATH_HOST_KEY_FILE            ETCDIR "/ssh_host_key"
-#define _PATH_HOST_DSA_KEY_FILE                ETCDIR "/ssh_host_dsa_key"
-#define _PATH_HOST_RSA_KEY_FILE                ETCDIR "/ssh_host_rsa_key"
-#define _PATH_DH_MODULI                        ETCDIR "/moduli"
+#define _PATH_SERVER_CONFIG_FILE       SSHDIR "/sshd_config"
+#define _PATH_HOST_CONFIG_FILE         SSHDIR "/ssh_config"
+#define _PATH_HOST_KEY_FILE            SSHDIR "/ssh_host_key"
+#define _PATH_HOST_DSA_KEY_FILE                SSHDIR "/ssh_host_dsa_key"
+#define _PATH_HOST_RSA_KEY_FILE                SSHDIR "/ssh_host_rsa_key"
+#define _PATH_DH_MODULI                        SSHDIR "/moduli"
 /* Backwards compatibility */
-#define _PATH_DH_PRIMES                        ETCDIR "/primes"
+#define _PATH_DH_PRIMES                        SSHDIR "/primes"
 
 #ifndef _PATH_SSH_PROGRAM
 #define _PATH_SSH_PROGRAM              "/usr/bin/ssh"
  * use.  xauth will be run if neither of these exists.
  */
 #define _PATH_SSH_USER_RC              ".ssh/rc"
-#define _PATH_SSH_SYSTEM_RC            ETCDIR "/sshrc"
+#define _PATH_SSH_SYSTEM_RC            SSHDIR "/sshrc"
 
 /*
  * Ssh-only version of /etc/hosts.equiv.  Additionally, the daemon may use
  * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled.
  */
-#define _PATH_SSH_HOSTS_EQUIV          ETCDIR "/shosts.equiv"
+#define _PATH_SSH_HOSTS_EQUIV          SSHDIR "/shosts.equiv"
 #define _PATH_RHOSTS_EQUIV             "/etc/hosts.equiv"
 
 /*
 #define _PATH_XAUTH                    "/usr/X11R6/bin/xauth"
 #endif
 
+/* UNIX domain socket for X11 server; displaynum will replace %u */
+#ifndef _PATH_UNIX_X
+#define _PATH_UNIX_X "/tmp/.X11-unix/X%u"
+#endif
+
 /* for scp */
 #ifndef _PATH_CP
 #define _PATH_CP                       "cp"
 #ifndef ASKPASS_PROGRAM
 #define ASKPASS_PROGRAM         "/usr/lib/ssh/ssh-askpass"
 #endif /* ASKPASS_PROGRAM */
-
-/*
- * Relevant only when using builtin PRNG.
- */
-#ifndef SSH_PRNG_SEED_FILE
-# define SSH_PRNG_SEED_FILE      _PATH_SSH_USER_DIR"/prng_seed"
-#endif /* SSH_PRNG_SEED_FILE */
-#ifndef SSH_PRNG_COMMAND_FILE
-# define SSH_PRNG_COMMAND_FILE   ETCDIR "/ssh_prng_cmds"
-#endif /* SSH_PRNG_COMMAND_FILE */
index 26b1ebe52f0c858fc4702fee053733ad7ac719ce..e60435736e56f7ec64cf6dc5ea62bb08bf93e393 100644 (file)
@@ -25,7 +25,7 @@
 #include "includes.h"
 #include "uuencode.h"
 
-RCSID("$OpenBSD: radix.c,v 1.16 2001/06/23 15:12:19 itojun Exp $");
+RCSID("$OpenBSD: radix.c,v 1.17 2001/11/19 19:02:16 mpech Exp $");
 
 #ifdef AFS
 #include <krb.h>
@@ -39,7 +39,7 @@ typedef u_short my_u_short;
 /* Nasty macros from BIND-4.9.2 */
 
 #define GETSHORT(s, cp) { \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
+       my_u_char *t_cp = (my_u_char *)(cp); \
        (s) = (((my_u_short)t_cp[0]) << 8) \
            | (((my_u_short)t_cp[1])) \
            ; \
@@ -47,7 +47,7 @@ typedef u_short my_u_short;
 }
 
 #define GETLONG(l, cp) { \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
+       my_u_char *t_cp = (my_u_char *)(cp); \
        (l) = (((my_u_int32_t)t_cp[0]) << 24) \
            | (((my_u_int32_t)t_cp[1]) << 16) \
            | (((my_u_int32_t)t_cp[2]) << 8) \
@@ -57,16 +57,16 @@ typedef u_short my_u_short;
 }
 
 #define PUTSHORT(s, cp) { \
-       register my_u_short t_s = (my_u_short)(s); \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
+       my_u_short t_s = (my_u_short)(s); \
+       my_u_char *t_cp = (my_u_char *)(cp); \
        *t_cp++ = t_s >> 8; \
        *t_cp   = t_s; \
        (cp) += 2; \
 }
 
 #define PUTLONG(l, cp) { \
-       register my_u_int32_t t_l = (my_u_int32_t)(l); \
-       register my_u_char *t_cp = (my_u_char *)(cp); \
+       my_u_int32_t t_l = (my_u_int32_t)(l); \
+       my_u_char *t_cp = (my_u_char *)(cp); \
        *t_cp++ = t_l >> 24; \
        *t_cp++ = t_l >> 16; \
        *t_cp++ = t_l >> 8; \
@@ -75,9 +75,9 @@ typedef u_short my_u_short;
 }
 
 #define GETSTRING(s, p, p_l) {                 \
-    register char *p_targ = (p) + p_l;         \
-    register char *s_c = (s);                  \
-    register char *p_c = (p);                  \
+    char *p_targ = (p) + p_l;          \
+    char *s_c = (s);                   \
+    char *p_c = (p);                   \
     while (*p_c && (p_c < p_targ)) {           \
        *s_c++ = *p_c++;                        \
     }                                          \
index 63035b37f9e84c02b4341f02b7e8f5f307dfb76b..7920ac86da3ffc05f312e11a151a9379865a7656 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.91 2001/10/01 21:51:16 markus Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.95 2002/02/04 12:15:25 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -115,7 +115,7 @@ typedef enum {
        oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
        oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
        oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
-       oClearAllForwardings, oNoHostAuthenticationForLocalhost 
+       oClearAllForwardings, oNoHostAuthenticationForLocalhost
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -185,9 +185,9 @@ static struct {
        { "hostkeyalgorithms", oHostKeyAlgorithms },
        { "bindaddress", oBindAddress },
        { "smartcarddevice", oSmartcardDevice },
-       { "clearallforwardings", oClearAllForwardings }, 
-       { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 
-       { NULL, 0 }
+       { "clearallforwardings", oClearAllForwardings },
+       { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+       { NULL, oBadOption }
 };
 
 /*
@@ -225,7 +225,7 @@ add_remote_forward(Options *options, u_short port, const char *host,
        Forward *fwd;
        if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
                fatal("Too many remote forwards (max %d).",
-                     SSH_MAX_FORWARDS_PER_DIRECTION);
+                   SSH_MAX_FORWARDS_PER_DIRECTION);
        fwd = &options->remote_forwards[options->num_remote_forwards++];
        fwd->port = port;
        fwd->host = xstrdup(host);
@@ -394,7 +394,7 @@ parse_flag:
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing yes/no/ask argument.",
-                             filename, linenum);
+                           filename, linenum);
                value = 0;      /* To avoid compiler warning... */
                if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
                        value = 1;
@@ -436,7 +436,7 @@ parse_flag:
                        intptr = &options->num_identity_files;
                        if (*intptr >= SSH_MAX_IDENTITY_FILES)
                                fatal("%.200s line %d: Too many identity files specified (max %d).",
-                                     filename, linenum, SSH_MAX_IDENTITY_FILES);
+                                   filename, linenum, SSH_MAX_IDENTITY_FILES);
                        charptr =  &options->identity_files[*intptr];
                        *charptr = xstrdup(arg);
                        *intptr = *intptr + 1;
@@ -536,7 +536,7 @@ parse_int:
                value = cipher_number(arg);
                if (value == -1)
                        fatal("%.200s line %d: Bad cipher '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && *intptr == -1)
                        *intptr = value;
                break;
@@ -547,7 +547,7 @@ parse_int:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!ciphers_valid(arg))
                        fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->ciphers == NULL)
                        options->ciphers = xstrdup(arg);
                break;
@@ -558,7 +558,7 @@ parse_int:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!mac_valid(arg))
                        fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->macs == NULL)
                        options->macs = xstrdup(arg);
                break;
@@ -569,7 +569,7 @@ parse_int:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (!key_names_valid2(arg))
                        fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && options->hostkeyalgorithms == NULL)
                        options->hostkeyalgorithms = xstrdup(arg);
                break;
@@ -582,7 +582,7 @@ parse_int:
                value = proto_spec(arg);
                if (value == SSH_PROTO_UNKNOWN)
                        fatal("%.200s line %d: Bad protocol spec '%s'.",
-                             filename, linenum, arg ? arg : "<NONE>");
+                           filename, linenum, arg ? arg : "<NONE>");
                if (*activep && *intptr == SSH_PROTO_UNKNOWN)
                        *intptr = value;
                break;
@@ -591,10 +591,10 @@ parse_int:
                intptr = (int *) &options->log_level;
                arg = strdelim(&s);
                value = log_level_number(arg);
-               if (value == (LogLevel) - 1)
+               if (value == SYSLOG_LEVEL_NOT_SET)
                        fatal("%.200s line %d: unsupported log level '%s'",
-                             filename, linenum, arg ? arg : "<NONE>");
-               if (*activep && (LogLevel) * intptr == -1)
+                           filename, linenum, arg ? arg : "<NONE>");
+               if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
                        *intptr = (LogLevel) value;
                break;
 
@@ -670,7 +670,7 @@ parse_int:
                        value = SSH_ESCAPECHAR_NONE;
                else {
                        fatal("%.200s line %d: Bad escape character.",
-                             filename, linenum);
+                           filename, linenum);
                        /* NOTREACHED */
                        value = 0;      /* Avoid compiler warning. */
                }
@@ -685,7 +685,7 @@ parse_int:
        /* Check that there is no garbage at end of line. */
        if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
                fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
-                     filename, linenum, arg);
+                    filename, linenum, arg);
        }
        return 0;
 }
@@ -727,7 +727,7 @@ read_config_file(const char *filename, const char *host, Options *options)
        fclose(f);
        if (bad_options > 0)
                fatal("%s: terminating, %d bad configuration options",
-                     filename, bad_options);
+                   filename, bad_options);
        return 1;
 }
 
@@ -794,7 +794,7 @@ initialize_options(Options * options)
        options->num_local_forwards = 0;
        options->num_remote_forwards = 0;
        options->clear_forwardings = -1;
-       options->log_level = (LogLevel) - 1;
+       options->log_level = SYSLOG_LEVEL_NOT_SET;
        options->preferred_authentications = NULL;
        options->bind_address = NULL;
        options->smartcard_device = NULL;
@@ -815,10 +815,8 @@ fill_default_options(Options * options)
                options->forward_agent = 0;
        if (options->forward_x11 == -1)
                options->forward_x11 = 0;
-#ifdef _PATH_XAUTH
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
-#endif
        if (options->gateway_ports == -1)
                options->gateway_ports = 0;
        if (options->use_privileged_port == -1)
@@ -913,7 +911,7 @@ fill_default_options(Options * options)
                options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
        if (options->user_hostfile2 == NULL)
                options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
-       if (options->log_level == (LogLevel) - 1)
+       if (options->log_level == SYSLOG_LEVEL_NOT_SET)
                options->log_level = SYSLOG_LEVEL_INFO;
        if (options->clear_forwardings == 1)
                clear_forwardings(options);
index 25ffa4668b4f482ff70389e88640a98e84709e42..4fa9040c976bf06bdbccf6881d6c67e703d1e3ae 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: readconf.h,v 1.42 2002/03/04 17:27:39 stevesk Exp $   */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: readconf.h,v 1.40 2001/10/01 21:51:16 markus Exp $"); */
-
 #ifndef READCONF_H
 #define READCONF_H
 
@@ -81,7 +81,7 @@ typedef struct {
        char   *user;           /* User to log in as. */
        int     escape_char;    /* Escape character; -2 = none */
 
-       char   *system_hostfile;/* Path for /etc/ssh_known_hosts. */
+       char   *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */
        char   *user_hostfile;  /* Path for $HOME/.ssh/known_hosts. */
        char   *system_hostfile2;
        char   *user_hostfile2;
index a0429818e7c5ce8c9f84506daa520641a7615d0b..b4421ade04dccb4b9eba43b06d54b823c3ed44cd 100644 (file)
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 1988, 1993
- *      The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *      This product includes software developed by the University of
- *      California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readpass.c,v 1.23 2001/11/08 10:51:08 markus Exp $");
+RCSID("$OpenBSD: readpass.c,v 1.26 2002/02/13 00:39:15 markus Exp $");
 
 #include "xmalloc.h"
 #include "readpass.h"
@@ -46,7 +37,7 @@ ssh_askpass(char *askpass, const char *msg)
        pid_t pid;
        size_t len;
        char *pass;
-       int p[2], status;
+       int p[2], status, ret;
        char buf[1024];
 
        if (fflush(stdout) != 0)
@@ -71,14 +62,23 @@ ssh_askpass(char *askpass, const char *msg)
                fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
        }
        close(p[1]);
-       len = read(p[0], buf, sizeof buf -1);
+
+       len = ret = 0;
+       do {
+               ret = read(p[0], buf + len, sizeof(buf) - 1 - len);
+               if (ret == -1 && errno == EINTR)
+                       continue;
+               if (ret <= 0)
+                       break;
+               len += ret;
+       } while (sizeof(buf) - 1 - len > 0);
+       buf[len] = '\0';
+
        close(p[0]);
        while (waitpid(pid, &status, 0) < 0)
                if (errno != EINTR)
                        break;
-       if (len <= 1)
-               return xstrdup("");
-       buf[len] = '\0';
+
        buf[strcspn(buf, "\r\n")] = '\0';
        pass = xstrdup(buf);
        memset(buf, 0, sizeof(buf));
@@ -103,7 +103,7 @@ read_passphrase(const char *prompt, int flags)
                        use_askpass = 1;
        } else {
                rppflags |= RPP_REQUIRE_TTY;
-               ttyfd = open("/dev/tty", O_RDWR);
+               ttyfd = open(_PATH_TTY, O_RDWR);
                if (ttyfd >= 0)
                        close(ttyfd);
                else
index f28a9c66997be614ddc810b18da3a90a4fc55b84..c8ba55e78e3d7536aad2f3349f2ed9c2ab0b5b72 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rijndael.c,v 1.12 2001/09/13 09:48:39 markus Exp $ */
+/*     $OpenBSD: rijndael.c,v 1.13 2001/12/19 07:18:56 deraadt Exp $ */
 
 /**
  * rijndael-alg-fst.c
@@ -775,32 +775,31 @@ static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int
        rk[6] = GETU32(cipherKey + 24);
        rk[7] = GETU32(cipherKey + 28);
        if (keyBits == 256) {
-        for (;;) {
-               temp = rk[ 7];
-               rk[ 8] = rk[ 0] ^
-                       (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-                       (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-                       (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-                       (Te4[(temp >> 24)       ] & 0x000000ff) ^
-                       rcon[i];
-               rk[ 9] = rk[ 1] ^ rk[ 8];
-               rk[10] = rk[ 2] ^ rk[ 9];
-               rk[11] = rk[ 3] ^ rk[10];
-                       if (++i == 7) {
-                               return 14;
-                       }
-               temp = rk[11];
-               rk[12] = rk[ 4] ^
-                       (Te4[(temp >> 24)       ] & 0xff000000) ^
-                       (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
-                       (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
-                       (Te4[(temp      ) & 0xff] & 0x000000ff);
-               rk[13] = rk[ 5] ^ rk[12];
-               rk[14] = rk[ 6] ^ rk[13];
-               rk[15] = rk[ 7] ^ rk[14];
-
+               for (;;) {
+                       temp = rk[ 7];
+                       rk[ 8] = rk[ 0] ^
+                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
+                               rcon[i];
+                       rk[ 9] = rk[ 1] ^ rk[ 8];
+                       rk[10] = rk[ 2] ^ rk[ 9];
+                       rk[11] = rk[ 3] ^ rk[10];
+                               if (++i == 7) {
+                                       return 14;
+                               }
+                       temp = rk[11];
+                       rk[12] = rk[ 4] ^
+                               (Te4[(temp >> 24)       ] & 0xff000000) ^
+                               (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+                               (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
+                               (Te4[(temp      ) & 0xff] & 0x000000ff);
+                       rk[13] = rk[ 5] ^ rk[12];
+                       rk[14] = rk[ 6] ^ rk[13];
+                       rk[15] = rk[ 7] ^ rk[14];
                        rk += 8;
-        }
+               }
        }
        return 0;
 }
@@ -917,28 +916,28 @@ static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16
        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
     if (Nr > 10) {
-        /* round 10: */
-        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
-        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
-        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
-        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
-        /* round 11: */
-        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
-        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
-        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
-        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
-        if (Nr > 12) {
-            /* round 12: */
-            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
-            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
-            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
-            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
-            /* round 13: */
-            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
-            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
-            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
-            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
-        }
+       /* round 10: */
+       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+       /* round 11: */
+       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+       if (Nr > 12) {
+           /* round 12: */
+           s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+           s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+           s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+           s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+           /* round 13: */
+           t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+           t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+           t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+           t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+       }
     }
     rk += Nr << 2;
 #else  /* !FULL_UNROLL */
@@ -947,60 +946,60 @@ static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16
         */
     r = Nr >> 1;
     for (;;) {
-        t0 =
-            Te0[(s0 >> 24)       ] ^
-            Te1[(s1 >> 16) & 0xff] ^
-            Te2[(s2 >>  8) & 0xff] ^
-            Te3[(s3      ) & 0xff] ^
-            rk[4];
-        t1 =
-            Te0[(s1 >> 24)       ] ^
-            Te1[(s2 >> 16) & 0xff] ^
-            Te2[(s3 >>  8) & 0xff] ^
-            Te3[(s0      ) & 0xff] ^
-            rk[5];
-        t2 =
-            Te0[(s2 >> 24)       ] ^
-            Te1[(s3 >> 16) & 0xff] ^
-            Te2[(s0 >>  8) & 0xff] ^
-            Te3[(s1      ) & 0xff] ^
-            rk[6];
-        t3 =
-            Te0[(s3 >> 24)       ] ^
-            Te1[(s0 >> 16) & 0xff] ^
-            Te2[(s1 >>  8) & 0xff] ^
-            Te3[(s2      ) & 0xff] ^
-            rk[7];
+       t0 =
+           Te0[(s0 >> 24)       ] ^
+           Te1[(s1 >> 16) & 0xff] ^
+           Te2[(s2 >>  8) & 0xff] ^
+           Te3[(s3      ) & 0xff] ^
+           rk[4];
+       t1 =
+           Te0[(s1 >> 24)       ] ^
+           Te1[(s2 >> 16) & 0xff] ^
+           Te2[(s3 >>  8) & 0xff] ^
+           Te3[(s0      ) & 0xff] ^
+           rk[5];
+       t2 =
+           Te0[(s2 >> 24)       ] ^
+           Te1[(s3 >> 16) & 0xff] ^
+           Te2[(s0 >>  8) & 0xff] ^
+           Te3[(s1      ) & 0xff] ^
+           rk[6];
+       t3 =
+           Te0[(s3 >> 24)       ] ^
+           Te1[(s0 >> 16) & 0xff] ^
+           Te2[(s1 >>  8) & 0xff] ^
+           Te3[(s2      ) & 0xff] ^
+           rk[7];
 
-        rk += 8;
-        if (--r == 0) {
-            break;
-        }
+       rk += 8;
+       if (--r == 0) {
+           break;
+       }
 
-        s0 =
-            Te0[(t0 >> 24)       ] ^
-            Te1[(t1 >> 16) & 0xff] ^
-            Te2[(t2 >>  8) & 0xff] ^
-            Te3[(t3      ) & 0xff] ^
-            rk[0];
-        s1 =
-            Te0[(t1 >> 24)       ] ^
-            Te1[(t2 >> 16) & 0xff] ^
-            Te2[(t3 >>  8) & 0xff] ^
-            Te3[(t0      ) & 0xff] ^
-            rk[1];
-        s2 =
-            Te0[(t2 >> 24)       ] ^
-            Te1[(t3 >> 16) & 0xff] ^
-            Te2[(t0 >>  8) & 0xff] ^
-            Te3[(t1      ) & 0xff] ^
-            rk[2];
-        s3 =
-            Te0[(t3 >> 24)       ] ^
-            Te1[(t0 >> 16) & 0xff] ^
-            Te2[(t1 >>  8) & 0xff] ^
-            Te3[(t2      ) & 0xff] ^
-            rk[3];
+       s0 =
+           Te0[(t0 >> 24)       ] ^
+           Te1[(t1 >> 16) & 0xff] ^
+           Te2[(t2 >>  8) & 0xff] ^
+           Te3[(t3      ) & 0xff] ^
+           rk[0];
+       s1 =
+           Te0[(t1 >> 24)       ] ^
+           Te1[(t2 >> 16) & 0xff] ^
+           Te2[(t3 >>  8) & 0xff] ^
+           Te3[(t0      ) & 0xff] ^
+           rk[1];
+       s2 =
+           Te0[(t2 >> 24)       ] ^
+           Te1[(t3 >> 16) & 0xff] ^
+           Te2[(t0 >>  8) & 0xff] ^
+           Te3[(t1      ) & 0xff] ^
+           rk[2];
+       s3 =
+           Te0[(t3 >> 24)       ] ^
+           Te1[(t0 >> 16) & 0xff] ^
+           Te2[(t1 >>  8) & 0xff] ^
+           Te3[(t2      ) & 0xff] ^
+           rk[3];
     }
 #endif /* ?FULL_UNROLL */
     /*
@@ -1098,28 +1097,28 @@ static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16
     t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
     t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
     if (Nr > 10) {
-        /* round 10: */
-        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
-        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
-        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
-        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
-        /* round 11: */
-        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
-        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
-        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
-        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
-        if (Nr > 12) {
-            /* round 12: */
-            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
-            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
-            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
-            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
-            /* round 13: */
-            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
-            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
-            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
-            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
-        }
+       /* round 10: */
+       s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+       s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+       s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+       s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+       /* round 11: */
+       t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+       t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+       t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+       t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+       if (Nr > 12) {
+           /* round 12: */
+           s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+           s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+           s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+           s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+           /* round 13: */
+           t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+           t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+           t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+           t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+       }
     }
        rk += Nr << 2;
 #else  /* !FULL_UNROLL */
@@ -1128,60 +1127,60 @@ static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16
      */
     r = Nr >> 1;
     for (;;) {
-        t0 =
-            Td0[(s0 >> 24)       ] ^
-            Td1[(s3 >> 16) & 0xff] ^
-            Td2[(s2 >>  8) & 0xff] ^
-            Td3[(s1      ) & 0xff] ^
-            rk[4];
-        t1 =
-            Td0[(s1 >> 24)       ] ^
-            Td1[(s0 >> 16) & 0xff] ^
-            Td2[(s3 >>  8) & 0xff] ^
-            Td3[(s2      ) & 0xff] ^
-            rk[5];
-        t2 =
-            Td0[(s2 >> 24)       ] ^
-            Td1[(s1 >> 16) & 0xff] ^
-            Td2[(s0 >>  8) & 0xff] ^
-            Td3[(s3      ) & 0xff] ^
-            rk[6];
-        t3 =
-            Td0[(s3 >> 24)       ] ^
-            Td1[(s2 >> 16) & 0xff] ^
-            Td2[(s1 >>  8) & 0xff] ^
-            Td3[(s0      ) & 0xff] ^
-            rk[7];
+       t0 =
+           Td0[(s0 >> 24)       ] ^
+           Td1[(s3 >> 16) & 0xff] ^
+           Td2[(s2 >>  8) & 0xff] ^
+           Td3[(s1      ) & 0xff] ^
+           rk[4];
+       t1 =
+           Td0[(s1 >> 24)       ] ^
+           Td1[(s0 >> 16) & 0xff] ^
+           Td2[(s3 >>  8) & 0xff] ^
+           Td3[(s2      ) & 0xff] ^
+           rk[5];
+       t2 =
+           Td0[(s2 >> 24)       ] ^
+           Td1[(s1 >> 16) & 0xff] ^
+           Td2[(s0 >>  8) & 0xff] ^
+           Td3[(s3      ) & 0xff] ^
+           rk[6];
+       t3 =
+           Td0[(s3 >> 24)       ] ^
+           Td1[(s2 >> 16) & 0xff] ^
+           Td2[(s1 >>  8) & 0xff] ^
+           Td3[(s0      ) & 0xff] ^
+           rk[7];
 
-        rk += 8;
-        if (--r == 0) {
-            break;
-        }
+       rk += 8;
+       if (--r == 0) {
+           break;
+       }
 
-        s0 =
-            Td0[(t0 >> 24)       ] ^
-            Td1[(t3 >> 16) & 0xff] ^
-            Td2[(t2 >>  8) & 0xff] ^
-            Td3[(t1      ) & 0xff] ^
-            rk[0];
-        s1 =
-            Td0[(t1 >> 24)       ] ^
-            Td1[(t0 >> 16) & 0xff] ^
-            Td2[(t3 >>  8) & 0xff] ^
-            Td3[(t2      ) & 0xff] ^
-            rk[1];
-        s2 =
-            Td0[(t2 >> 24)       ] ^
-            Td1[(t1 >> 16) & 0xff] ^
-            Td2[(t0 >>  8) & 0xff] ^
-            Td3[(t3      ) & 0xff] ^
-            rk[2];
-        s3 =
-            Td0[(t3 >> 24)       ] ^
-            Td1[(t2 >> 16) & 0xff] ^
-            Td2[(t1 >>  8) & 0xff] ^
-            Td3[(t0      ) & 0xff] ^
-            rk[3];
+       s0 =
+           Td0[(t0 >> 24)       ] ^
+           Td1[(t3 >> 16) & 0xff] ^
+           Td2[(t2 >>  8) & 0xff] ^
+           Td3[(t1      ) & 0xff] ^
+           rk[0];
+       s1 =
+           Td0[(t1 >> 24)       ] ^
+           Td1[(t0 >> 16) & 0xff] ^
+           Td2[(t3 >>  8) & 0xff] ^
+           Td3[(t2      ) & 0xff] ^
+           rk[1];
+       s2 =
+           Td0[(t2 >> 24)       ] ^
+           Td1[(t1 >> 16) & 0xff] ^
+           Td2[(t0 >>  8) & 0xff] ^
+           Td3[(t3      ) & 0xff] ^
+           rk[2];
+       s3 =
+           Td0[(t3 >> 24)       ] ^
+           Td1[(t2 >> 16) & 0xff] ^
+           Td2[(t1 >>  8) & 0xff] ^
+           Td3[(t0      ) & 0xff] ^
+           rk[3];
     }
 #endif /* ?FULL_UNROLL */
     /*
@@ -1222,13 +1221,13 @@ void
 rijndael_set_key(rijndael_ctx *ctx, u_char *key, int bits, int encrypt)
 {
        ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits);
-        if (encrypt) {
+       if (encrypt) {
                ctx->decrypt = 0;
                memset(ctx->dk, 0, sizeof(ctx->dk));
        } else {
                ctx->decrypt = 1;
                memcpy(ctx->dk, ctx->ek, sizeof(ctx->ek));
-                rijndaelKeySetupDec(ctx->dk, key, bits, ctx->Nr);
+               rijndaelKeySetupDec(ctx->dk, key, bits, ctx->Nr);
        }
 }
 
index 18a4d805e1ea1085e88cd2b05cfadd5ef8a2a0b5..c614bb18877fbc3220ee29f1592f0b8ba6649842 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rijndael.h,v 1.11 2001/09/13 09:48:39 markus Exp $ */
+/*     $OpenBSD: rijndael.h,v 1.12 2001/12/19 07:18:56 deraadt Exp $ */
 
 /**
  * rijndael-alg-fst.h
@@ -32,8 +32,8 @@
 #define MAXKB  (256/8)
 #define MAXNR  14
 
-typedef unsigned char  u8;     
-typedef unsigned short u16;    
+typedef unsigned char  u8;
+typedef unsigned short u16;
 typedef unsigned int   u32;
 
 /*  The structure for key information */
index 113ee7fc42347977adc011b5610c790d466c825c..66561a4213b5cd3b78c527116b1b80ab4dac99b7 100644 (file)
@@ -60,7 +60,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: rsa.c,v 1.23 2001/06/27 05:42:24 markus Exp $");
+RCSID("$OpenBSD: rsa.c,v 1.24 2001/12/27 18:22:16 markus Exp $");
 
 #include "rsa.h"
 #include "log.h"
@@ -120,14 +120,17 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
        return len;
 }
 
+/* calculate p-1 and q-1 */
 void
 rsa_generate_additional_parameters(RSA *rsa)
 {
        BIGNUM *aux;
        BN_CTX *ctx;
-       /* Generate additional parameters */
-       aux = BN_new();
-       ctx = BN_CTX_new();
+
+       if ((aux = BN_new()) == NULL)
+               fatal("rsa_generate_additional_parameters: BN_new failed");
+       if ((ctx = BN_CTX_new()) == NULL)
+               fatal("rsa_generate_additional_parameters: BN_CTX_new failed");
 
        BN_sub(aux, rsa->q, BN_value_one());
        BN_mod(rsa->dmq1, rsa->d, aux, ctx);
index 2f596d4915154fa310ce8e29306628ad59059bd8..957d865522d2e70ebf7b9fbf7a2184c6c94f9e81 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: rsa.h,v 1.15 2002/03/04 17:27:39 stevesk Exp $        */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: rsa.h,v 1.14 2001/06/27 05:42:24 markus Exp $"); */
-
 #ifndef RSA_H
 #define RSA_H
 
index 251e5d30af995cee47251abceb58bfccee4cf78e..e8319314c681b7d861613ced29ba133fa8126484 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 #ifdef SMARTCARD
-RCSID("$OpenBSD: scard.c,v 1.15 2001/09/28 09:49:31 djm Exp $");
+RCSID("$OpenBSD: scard.c,v 1.17 2001/12/27 18:22:16 markus Exp $");
 
 #include <openssl/engine.h>
 #include <sectok.h>
@@ -48,7 +48,7 @@ static int cla = 0x00;        /* class */
 
 /* interface to libsectok */
 
-static int 
+static int
 sc_open(void)
 {
        int sw;
@@ -79,7 +79,7 @@ sc_open(void)
        return sc_fd;
 }
 
-static int 
+static int
 sc_enable_applet(void)
 {
        static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
@@ -95,7 +95,7 @@ sc_enable_applet(void)
        return 0;
 }
 
-static int 
+static int
 sc_init(void)
 {
        int status;
@@ -115,7 +115,7 @@ sc_init(void)
        return 0;
 }
 
-static int 
+static int
 sc_read_pubkey(Key * k)
 {
        u_char buf[2], *n;
@@ -133,7 +133,7 @@ sc_read_pubkey(Key * k)
 
        /* get key size */
        sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
-            sizeof(buf), buf, &sw);
+           sizeof(buf), buf, &sw);
        if (!sectok_swOK(sw)) {
                error("could not obtain key length: %s", sectok_get_sw(sw));
                goto err;
@@ -204,7 +204,7 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
                goto err;
        }
        sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
-            len, padded, &sw);
+           len, padded, &sw);
        if (!sectok_swOK(sw)) {
                error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
                    sectok_get_sw(sw));
@@ -249,7 +249,7 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
                goto err;
        }
        sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
-            len, to, &sw);
+           len, to, &sw);
        if (!sectok_swOK(sw)) {
                error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
                    sectok_get_sw(sw));
@@ -320,7 +320,8 @@ sc_get_engine(void)
        smart_rsa.rsa_sign      = def->rsa_sign;
        smart_rsa.rsa_verify    = def->rsa_verify;
 
-       smart_engine = ENGINE_new();
+       if ((smart_engine = ENGINE_new()) == NULL)
+               fatal("ENGINE_new failed");
 
        ENGINE_set_id(smart_engine, "sectok");
        ENGINE_set_name(smart_engine, "libsectok");
index 57189df1c95b091d9fa28ae87aeb7579d90ebf67..6ca99169b55b843dd1adad444e4e96e6b1a93f2a 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: scard.h,v 1.7 2002/03/04 17:27:39 stevesk Exp $       */
+
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
@@ -22,8 +24,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* $OpenBSD: scard.h,v 1.6 2001/08/01 22:03:33 markus Exp $ */
-
 #include <openssl/engine.h>
 
 #ifndef SCARD_H
diff --git a/openssh/scard/.cvsignore b/openssh/scard/.cvsignore
new file mode 100644 (file)
index 0000000..5349d34
--- /dev/null
@@ -0,0 +1,2 @@
+Makefile
+Ssh.bin
index d51e680c77796f8894e7271ac95c3ab5334d2225..69125c1ff81372829da39b9407b2b7ebbfa47475 100644 (file)
@@ -9,7 +9,7 @@
 .\"
 .\" Created: Sun May  7 00:14:37 1995 ylo
 .\"
-.\" $OpenBSD: scp.1,v 1.20 2001/09/17 23:56:07 stevesk Exp $
+.\" $OpenBSD: scp.1,v 1.21 2002/01/29 23:50:37 markus Exp $
 .\"
 .Dd September 25, 1999
 .Dt SCP 1
@@ -134,6 +134,9 @@ Forces
 .Nm
 to use IPv6 addresses only.
 .El
+.Sh DIAGNOSTICS
+.Nm
+exits with 0 on success or >0 if an error occurred.
 .Sh AUTHORS
 Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi>
 .Sh HISTORY
index fb4d3096c1a64ea01c1c2449ae858119eb0d1d25..83e7769d6458380b2a3ba0f59e697c51c79a524c 100644 (file)
@@ -75,7 +75,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.85 2001/10/01 08:06:28 markus Exp $");
+RCSID("$OpenBSD: scp.c,v 1.86 2001/12/05 03:56:39 itojun Exp $");
 
 #include "xmalloc.h"
 #include "atomicio.h"
@@ -548,14 +548,13 @@ syserr:                   run_err("%s: %s", name, strerror(errno));
 #ifdef HAVE_LONG_LONG_INT
                snprintf(buf, sizeof buf, "C%04o %lld %s\n",
                    (u_int) (stb.st_mode & FILEMODEMASK),
-                   (long long) stb.st_size, last);
+                   (long long)stb.st_size, last);
 #else
                /* XXX: Handle integer overflow? */
                snprintf(buf, sizeof buf, "C%04o %lu %s\n",
                    (u_int) (stb.st_mode & FILEMODEMASK),
                    (u_long) stb.st_size, last);
 #endif
-
                if (verbose_mode) {
                        fprintf(stderr, "Sending file modes: %s", buf);
                        fflush(stderr);
@@ -930,7 +929,7 @@ screwup:
 }
 
 int
-response()
+response(void)
 {
        char ch, *cp, resp, rbuf[2048];
 
@@ -963,7 +962,7 @@ response()
 }
 
 void
-usage()
+usage(void)
 {
        (void) fprintf(stderr,
            "usage: scp [-pqrvBC46] [-F config] [-S ssh] [-P port] [-c cipher] [-i identity]\n"
index e914d4cee57cbf36b67c0476978d13740610979f..9bbd994ca556417462dee5f9dbfcc79eeb4789b0 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.91 2001/11/12 18:17:07 markus Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.101 2002/02/04 12:15:25 markus Exp $");
 
 #if defined(KRB4) || defined(KRB5)
 #include <krb.h>
@@ -63,11 +63,12 @@ initialize_server_options(ServerOptions *options)
        options->print_lastlog = -1;
        options->x11_forwarding = -1;
        options->x11_display_offset = -1;
+       options->x11_use_localhost = -1;
        options->xauth_location = NULL;
        options->strict_modes = -1;
        options->keepalives = -1;
-       options->log_facility = (SyslogFacility) - 1;
-       options->log_level = (LogLevel) - 1;
+       options->log_facility = SYSLOG_FACILITY_NOT_SET;
+       options->log_level = SYSLOG_LEVEL_NOT_SET;
        options->rhosts_authentication = -1;
        options->rhosts_rsa_authentication = -1;
        options->hostbased_authentication = -1;
@@ -104,7 +105,7 @@ initialize_server_options(ServerOptions *options)
        options->max_startups_rate = -1;
        options->max_startups = -1;
        options->banner = NULL;
-       options->reverse_mapping_check = -1;
+       options->verify_reverse_mapping = -1;
        options->client_alive_interval = -1;
        options->client_alive_count_max = -1;
        options->authorized_keys_file = NULL;
@@ -124,9 +125,14 @@ fill_default_server_options(ServerOptions *options)
        if (options->num_host_key_files == 0) {
                /* fill default hostkeys for protocols */
                if (options->protocol & SSH_PROTO_1)
-                       options->host_key_files[options->num_host_key_files++] = _PATH_HOST_KEY_FILE;
-               if (options->protocol & SSH_PROTO_2)
-                       options->host_key_files[options->num_host_key_files++] = _PATH_HOST_DSA_KEY_FILE;
+                       options->host_key_files[options->num_host_key_files++] =
+                           _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;
+               }
        }
        if (options->num_ports == 0)
                options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
@@ -154,17 +160,17 @@ fill_default_server_options(ServerOptions *options)
                options->x11_forwarding = 0;
        if (options->x11_display_offset == -1)
                options->x11_display_offset = 10;
-#ifdef _PATH_XAUTH
+       if (options->x11_use_localhost == -1)
+               options->x11_use_localhost = 1;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
-#endif
        if (options->strict_modes == -1)
                options->strict_modes = 1;
        if (options->keepalives == -1)
                options->keepalives = 1;
-       if (options->log_facility == (SyslogFacility) (-1))
+       if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
                options->log_facility = SYSLOG_FACILITY_AUTH;
-       if (options->log_level == (LogLevel) (-1))
+       if (options->log_level == SYSLOG_LEVEL_NOT_SET)
                options->log_level = SYSLOG_LEVEL_INFO;
        if (options->rhosts_authentication == -1)
                options->rhosts_authentication = 0;
@@ -190,7 +196,7 @@ fill_default_server_options(ServerOptions *options)
        if (options->kerberos_tgt_passing == -1)
                options->kerberos_tgt_passing = 0;
 #endif
-#ifdef AFS     
+#ifdef AFS
        if (options->afs_token_passing == -1)
                options->afs_token_passing = k_hasafs();
 #endif
@@ -214,10 +220,10 @@ fill_default_server_options(ServerOptions *options)
                options->max_startups_rate = 100;               /* 100% */
        if (options->max_startups_begin == -1)
                options->max_startups_begin = options->max_startups;
-       if (options->reverse_mapping_check == -1)
-               options->reverse_mapping_check = 0;
+       if (options->verify_reverse_mapping == -1)
+               options->verify_reverse_mapping = 0;
        if (options->client_alive_interval == -1)
-               options->client_alive_interval = 0;  
+               options->client_alive_interval = 0;
        if (options->client_alive_count_max == -1)
                options->client_alive_count_max = 3;
        if (options->authorized_keys_file2 == NULL) {
@@ -252,16 +258,16 @@ typedef enum {
        sChallengeResponseAuthentication,
        sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
        sPrintMotd, sPrintLastLog, sIgnoreRhosts,
-       sX11Forwarding, sX11DisplayOffset,
+       sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
        sStrictModes, sEmptyPasswd, sKeepAlives,
        sUseLogin, sAllowTcpForwarding,
        sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
        sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
        sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
-       sBanner, sReverseMappingCheck, sHostbasedAuthentication,
-       sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 
+       sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
+       sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
        sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
-       sDeprecated 
+       sDeprecated
 } ServerOpCodes;
 
 /* Textual representation of the tokens. */
@@ -312,6 +318,7 @@ static struct {
        { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
        { "x11forwarding", sX11Forwarding },
        { "x11displayoffset", sX11DisplayOffset },
+       { "x11uselocalhost", sX11UseLocalhost },
        { "xauthlocation", sXAuthLocation },
        { "strictmodes", sStrictModes },
        { "permitemptypasswords", sEmptyPasswd },
@@ -329,12 +336,13 @@ static struct {
        { "subsystem", sSubsystem },
        { "maxstartups", sMaxStartups },
        { "banner", sBanner },
-       { "reversemappingcheck", sReverseMappingCheck },
+       { "verifyreversemapping", sVerifyReverseMapping },
+       { "reversemappingcheck", sVerifyReverseMapping },
        { "clientaliveinterval", sClientAliveInterval },
        { "clientalivecountmax", sClientAliveCountMax },
        { "authorizedkeysfile", sAuthorizedKeysFile },
        { "authorizedkeysfile2", sAuthorizedKeysFile2 },
-       { NULL, 0 }
+       { NULL, sBadOption }
 };
 
 /*
@@ -392,487 +400,501 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
        options->listen_addrs = aitop;
 }
 
-/* Reads the server configuration file. */
-
-void
-read_server_config(ServerOptions *options, const char *filename)
+int
+process_server_config_line(ServerOptions *options, char *line,
+    const char *filename, int linenum)
 {
-       FILE *f;
-       char line[1024];
        char *cp, **charptr, *arg, *p;
-       int linenum, *intptr, value;
-       int bad_options = 0;
+       int *intptr, value;
        ServerOpCodes opcode;
        int i, n;
 
-       f = fopen(filename, "r");
-       if (!f) {
-               perror(filename);
-               exit(1);
-       }
-       linenum = 0;
-       while (fgets(line, sizeof(line), f)) {
-               linenum++;
-               cp = line;
+       cp = line;
+       arg = strdelim(&cp);
+       /* Ignore leading whitespace */
+       if (*arg == '\0')
                arg = strdelim(&cp);
-               /* Ignore leading whitespace */
-               if (*arg == '\0')
-                       arg = strdelim(&cp);
-               if (!arg || !*arg || *arg == '#')
-                       continue;
-               intptr = NULL;
-               charptr = NULL;
-               opcode = parse_token(arg, filename, linenum);
-               switch (opcode) {
-               case sBadOption:
-                       bad_options++;
-                       continue;
-
-               /* Portable-specific options */
-               case sPAMAuthenticationViaKbdInt:
-                       intptr = &options->pam_authentication_via_kbd_int;
-                       goto parse_flag;
-
-               /* Standard Options */
-               case sPort:
-                       /* ignore ports from configfile if cmdline specifies ports */
-                       if (options->ports_from_cmdline)
-                               continue;
-                       if (options->listen_addrs != NULL)
-                               fatal("%s line %d: ports must be specified before "
-                                   "ListenAdress.", filename, linenum);
-                       if (options->num_ports >= MAX_PORTS)
-                               fatal("%s line %d: too many ports.",
-                                   filename, linenum);
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: missing port number.",
-                                   filename, linenum);
-                       options->ports[options->num_ports++] = a2port(arg);
-                       if (options->ports[options->num_ports-1] == 0)
-                               fatal("%s line %d: Badly formatted port number.",
-                                   filename, linenum);
-                       break;
+       if (!arg || !*arg || *arg == '#')
+               return 0;
+       intptr = NULL;
+       charptr = NULL;
+       opcode = parse_token(arg, filename, linenum);
+       switch (opcode) {
+       /* Portable-specific options */
+       case sPAMAuthenticationViaKbdInt:
+               intptr = &options->pam_authentication_via_kbd_int;
+               goto parse_flag;
 
-               case sServerKeyBits:
-                       intptr = &options->server_key_bits;
+       /* Standard Options */
+       case sBadOption:
+               return -1;
+       case sPort:
+               /* ignore ports from configfile if cmdline specifies ports */
+               if (options->ports_from_cmdline)
+                       return 0;
+               if (options->listen_addrs != NULL)
+                       fatal("%s line %d: ports must be specified before "
+                           "ListenAddress.", filename, linenum);
+               if (options->num_ports >= MAX_PORTS)
+                       fatal("%s line %d: too many ports.",
+                           filename, linenum);
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing port number.",
+                           filename, linenum);
+               options->ports[options->num_ports++] = a2port(arg);
+               if (options->ports[options->num_ports-1] == 0)
+                       fatal("%s line %d: Badly formatted port number.",
+                           filename, linenum);
+               break;
+
+       case sServerKeyBits:
+               intptr = &options->server_key_bits;
 parse_int:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: missing integer value.",
-                                   filename, linenum);
-                       value = atoi(arg);
-                       if (*intptr == -1)
-                               *intptr = value;
-                       break;
-
-               case sLoginGraceTime:
-                       intptr = &options->login_grace_time;
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing integer value.",
+                           filename, linenum);
+               value = atoi(arg);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
+       case sLoginGraceTime:
+               intptr = &options->login_grace_time;
 parse_time:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: missing time value.",
-                                   filename, linenum);
-                       if ((value = convtime(arg)) == -1)
-                               fatal("%s line %d: invalid time value.",
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing time value.",
+                           filename, linenum);
+               if ((value = convtime(arg)) == -1)
+                       fatal("%s line %d: invalid time value.",
+                           filename, linenum);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
+       case sKeyRegenerationTime:
+               intptr = &options->key_regeneration_time;
+               goto parse_time;
+
+       case sListenAddress:
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
+                       fatal("%s line %d: missing inet addr.",
+                           filename, linenum);
+               if (*arg == '[') {
+                       if ((p = strchr(arg, ']')) == NULL)
+                               fatal("%s line %d: bad ipv6 inet addr usage.",
                                    filename, linenum);
-                       if (*intptr == -1)
-                               *intptr = value;
+                       arg++;
+                       memmove(p, p+1, strlen(p+1)+1);
+               } else if (((p = strchr(arg, ':')) == NULL) ||
+                           (strchr(p+1, ':') != NULL)) {
+                       add_listen_addr(options, arg, 0);
                        break;
+               }
+               if (*p == ':') {
+                       u_short port;
 
-               case sKeyRegenerationTime:
-                       intptr = &options->key_regeneration_time;
-                       goto parse_time;
-
-               case sListenAddress:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
-                               fatal("%s line %d: missing inet addr.",
+                       p++;
+                       if (*p == '\0')
+                               fatal("%s line %d: bad inet addr:port usage.",
                                    filename, linenum);
-                       if (*arg == '[') {
-                               if ((p = strchr(arg, ']')) == NULL)
-                                       fatal("%s line %d: bad ipv6 inet addr usage.",
+                       else {
+                               *(p-1) = '\0';
+                               if ((port = a2port(p)) == 0)
+                                       fatal("%s line %d: bad port number.",
                                            filename, linenum);
-                               arg++;
-                               memmove(p, p+1, strlen(p+1)+1);
-                       } else if (((p = strchr(arg, ':')) == NULL) ||
-                                   (strchr(p+1, ':') != NULL)) {
-                               add_listen_addr(options, arg, 0);
-                               break;
+                               add_listen_addr(options, arg, port);
                        }
-                       if (*p == ':') {
-                               u_short port;
-
-                               p++;
-                               if (*p == '\0')
-                                       fatal("%s line %d: bad inet addr:port usage.",
-                                           filename, linenum);
-                               else {
-                                       *(p-1) = '\0';
-                                       if ((port = a2port(p)) == 0)
-                                               fatal("%s line %d: bad port number.",
-                                                   filename, linenum);
-                                       add_listen_addr(options, arg, port);
-                               }
-                       } else if (*p == '\0')
-                               add_listen_addr(options, arg, 0);
-                       else
-                               fatal("%s line %d: bad inet addr usage.",
-                                   filename, linenum);
-                       break;
-
-               case sHostKeyFile:
-                       intptr = &options->num_host_key_files;
-                       if (*intptr >= MAX_HOSTKEYS)
-                               fatal("%s line %d: too many host keys specified (max %d).",
-                                   filename, linenum, MAX_HOSTKEYS);
-                       charptr = &options->host_key_files[*intptr];
+               } else if (*p == '\0')
+                       add_listen_addr(options, arg, 0);
+               else
+                       fatal("%s line %d: bad inet addr usage.",
+                           filename, linenum);
+               break;
+
+       case sHostKeyFile:
+               intptr = &options->num_host_key_files;
+               if (*intptr >= MAX_HOSTKEYS)
+                       fatal("%s line %d: too many host keys specified (max %d).",
+                           filename, linenum, MAX_HOSTKEYS);
+               charptr = &options->host_key_files[*intptr];
 parse_filename:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: missing file name.",
-                                   filename, linenum);
-                       if (*charptr == NULL) {
-                               *charptr = tilde_expand_filename(arg, getuid());
-                               /* increase optional counter */
-                               if (intptr != NULL)
-                                       *intptr = *intptr + 1;
-                       }
-                       break;
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing file name.",
+                           filename, linenum);
+               if (*charptr == NULL) {
+                       *charptr = tilde_expand_filename(arg, getuid());
+                       /* increase optional counter */
+                       if (intptr != NULL)
+                               *intptr = *intptr + 1;
+               }
+               break;
 
-               case sPidFile:
-                       charptr = &options->pid_file;
-                       goto parse_filename;
-
-               case sPermitRootLogin:
-                       intptr = &options->permit_root_login;
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: missing yes/"
-                                   "without-password/forced-commands-only/no "
-                                   "argument.", filename, linenum);
-                       value = 0;      /* silence compiler */
-                       if (strcmp(arg, "without-password") == 0)
-                               value = PERMIT_NO_PASSWD;
-                       else if (strcmp(arg, "forced-commands-only") == 0)
-                               value = PERMIT_FORCED_ONLY;
-                       else if (strcmp(arg, "yes") == 0)
-                               value = PERMIT_YES;
-                       else if (strcmp(arg, "no") == 0)
-                               value = PERMIT_NO;
-                       else
-                               fatal("%s line %d: Bad yes/"
-                                   "without-password/forced-commands-only/no "
-                                   "argument: %s", filename, linenum, arg);
-                       if (*intptr == -1)
-                               *intptr = value;
-                       break;
+       case sPidFile:
+               charptr = &options->pid_file;
+               goto parse_filename;
 
-               case sIgnoreRhosts:
-                       intptr = &options->ignore_rhosts;
+       case sPermitRootLogin:
+               intptr = &options->permit_root_login;
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing yes/"
+                           "without-password/forced-commands-only/no "
+                           "argument.", filename, linenum);
+               value = 0;      /* silence compiler */
+               if (strcmp(arg, "without-password") == 0)
+                       value = PERMIT_NO_PASSWD;
+               else if (strcmp(arg, "forced-commands-only") == 0)
+                       value = PERMIT_FORCED_ONLY;
+               else if (strcmp(arg, "yes") == 0)
+                       value = PERMIT_YES;
+               else if (strcmp(arg, "no") == 0)
+                       value = PERMIT_NO;
+               else
+                       fatal("%s line %d: Bad yes/"
+                           "without-password/forced-commands-only/no "
+                           "argument: %s", filename, linenum, arg);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
+       case sIgnoreRhosts:
+               intptr = &options->ignore_rhosts;
 parse_flag:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: missing yes/no argument.",
-                                   filename, linenum);
-                       value = 0;      /* silence compiler */
-                       if (strcmp(arg, "yes") == 0)
-                               value = 1;
-                       else if (strcmp(arg, "no") == 0)
-                               value = 0;
-                       else
-                               fatal("%s line %d: Bad yes/no argument: %s",
-                                       filename, linenum, arg);
-                       if (*intptr == -1)
-                               *intptr = value;
-                       break;
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing yes/no argument.",
+                           filename, linenum);
+               value = 0;      /* silence compiler */
+               if (strcmp(arg, "yes") == 0)
+                       value = 1;
+               else if (strcmp(arg, "no") == 0)
+                       value = 0;
+               else
+                       fatal("%s line %d: Bad yes/no argument: %s",
+                               filename, linenum, arg);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
+
+       case sIgnoreUserKnownHosts:
+               intptr = &options->ignore_user_known_hosts;
+               goto parse_flag;
+
+       case sRhostsAuthentication:
+               intptr = &options->rhosts_authentication;
+               goto parse_flag;
+
+       case sRhostsRSAAuthentication:
+               intptr = &options->rhosts_rsa_authentication;
+               goto parse_flag;
+
+       case sHostbasedAuthentication:
+               intptr = &options->hostbased_authentication;
+               goto parse_flag;
+
+       case sHostbasedUsesNameFromPacketOnly:
+               intptr = &options->hostbased_uses_name_from_packet_only;
+               goto parse_flag;
+
+       case sRSAAuthentication:
+               intptr = &options->rsa_authentication;
+               goto parse_flag;
+
+       case sPubkeyAuthentication:
+               intptr = &options->pubkey_authentication;
+               goto parse_flag;
+#if defined(KRB4) || defined(KRB5)
+       case sKerberosAuthentication:
+               intptr = &options->kerberos_authentication;
+               goto parse_flag;
 
-               case sIgnoreUserKnownHosts:
-                       intptr = &options->ignore_user_known_hosts;
-                       goto parse_flag;
+       case sKerberosOrLocalPasswd:
+               intptr = &options->kerberos_or_local_passwd;
+               goto parse_flag;
 
-               case sRhostsAuthentication:
-                       intptr = &options->rhosts_authentication;
-                       goto parse_flag;
+       case sKerberosTicketCleanup:
+               intptr = &options->kerberos_ticket_cleanup;
+               goto parse_flag;
+#endif
+#if defined(AFS) || defined(KRB5)
+       case sKerberosTgtPassing:
+               intptr = &options->kerberos_tgt_passing;
+               goto parse_flag;
+#endif
+#ifdef AFS
+       case sAFSTokenPassing:
+               intptr = &options->afs_token_passing;
+               goto parse_flag;
+#endif
 
-               case sRhostsRSAAuthentication:
-                       intptr = &options->rhosts_rsa_authentication;
-                       goto parse_flag;
+       case sPasswordAuthentication:
+               intptr = &options->password_authentication;
+               goto parse_flag;
 
-               case sHostbasedAuthentication:
-                       intptr = &options->hostbased_authentication;
-                       goto parse_flag;
+       case sKbdInteractiveAuthentication:
+               intptr = &options->kbd_interactive_authentication;
+               goto parse_flag;
 
-               case sHostbasedUsesNameFromPacketOnly:
-                       intptr = &options->hostbased_uses_name_from_packet_only;
-                       goto parse_flag;
+       case sChallengeResponseAuthentication:
+               intptr = &options->challenge_response_authentication;
+               goto parse_flag;
 
-               case sRSAAuthentication:
-                       intptr = &options->rsa_authentication;
-                       goto parse_flag;
+       case sPrintMotd:
+               intptr = &options->print_motd;
+               goto parse_flag;
 
-               case sPubkeyAuthentication:
-                       intptr = &options->pubkey_authentication;
-                       goto parse_flag;
-#if defined(KRB4) || defined(KRB5)
-               case sKerberosAuthentication:
-                       intptr = &options->kerberos_authentication;
-                       goto parse_flag;
+       case sPrintLastLog:
+               intptr = &options->print_lastlog;
+               goto parse_flag;
 
-               case sKerberosOrLocalPasswd:
-                       intptr = &options->kerberos_or_local_passwd;
-                       goto parse_flag;
+       case sX11Forwarding:
+               intptr = &options->x11_forwarding;
+               goto parse_flag;
 
-               case sKerberosTicketCleanup:
-                       intptr = &options->kerberos_ticket_cleanup;
-                       goto parse_flag;
-#endif
-#if defined(AFS) || defined(KRB5)
-               case sKerberosTgtPassing:
-                       intptr = &options->kerberos_tgt_passing;
-                       goto parse_flag;
-#endif
-#ifdef AFS
-               case sAFSTokenPassing:
-                       intptr = &options->afs_token_passing;
-                       goto parse_flag;
-#endif
+       case sX11DisplayOffset:
+               intptr = &options->x11_display_offset;
+               goto parse_int;
 
-               case sPasswordAuthentication:
-                       intptr = &options->password_authentication;
-                       goto parse_flag;
-
-               case sKbdInteractiveAuthentication:
-                       intptr = &options->kbd_interactive_authentication;
-                       goto parse_flag;
-
-               case sChallengeResponseAuthentication:
-                       intptr = &options->challenge_response_authentication;
-                       goto parse_flag;
-
-               case sPrintMotd:
-                       intptr = &options->print_motd;
-                       goto parse_flag;
-
-               case sPrintLastLog:
-                       intptr = &options->print_lastlog;
-                       goto parse_flag;
-
-               case sX11Forwarding:
-                       intptr = &options->x11_forwarding;
-                       goto parse_flag;
-
-               case sX11DisplayOffset:
-                       intptr = &options->x11_display_offset;
-                       goto parse_int;
-
-               case sXAuthLocation:
-                       charptr = &options->xauth_location;
-                       goto parse_filename;
-
-               case sStrictModes:
-                       intptr = &options->strict_modes;
-                       goto parse_flag;
-
-               case sKeepAlives:
-                       intptr = &options->keepalives;
-                       goto parse_flag;
-
-               case sEmptyPasswd:
-                       intptr = &options->permit_empty_passwd;
-                       goto parse_flag;
-
-               case sUseLogin:
-                       intptr = &options->use_login;
-                       goto parse_flag;
-
-               case sGatewayPorts:
-                       intptr = &options->gateway_ports;
-                       goto parse_flag;
-
-               case sReverseMappingCheck:
-                       intptr = &options->reverse_mapping_check;
-                       goto parse_flag;
-
-               case sLogFacility:
-                       intptr = (int *) &options->log_facility;
-                       arg = strdelim(&cp);
-                       value = log_facility_number(arg);
-                       if (value == (SyslogFacility) - 1)
-                               fatal("%.200s line %d: unsupported log facility '%s'",
-                                   filename, linenum, arg ? arg : "<NONE>");
-                       if (*intptr == -1)
-                               *intptr = (SyslogFacility) value;
-                       break;
+       case sX11UseLocalhost:
+               intptr = &options->x11_use_localhost;
+               goto parse_flag;
 
-               case sLogLevel:
-                       intptr = (int *) &options->log_level;
-                       arg = strdelim(&cp);
-                       value = log_level_number(arg);
-                       if (value == (LogLevel) - 1)
-                               fatal("%.200s line %d: unsupported log level '%s'",
-                                   filename, linenum, arg ? arg : "<NONE>");
-                       if (*intptr == -1)
-                               *intptr = (LogLevel) value;
-                       break;
+       case sXAuthLocation:
+               charptr = &options->xauth_location;
+               goto parse_filename;
 
-               case sAllowTcpForwarding:
-                       intptr = &options->allow_tcp_forwarding;
-                       goto parse_flag;
+       case sStrictModes:
+               intptr = &options->strict_modes;
+               goto parse_flag;
 
-               case sAllowUsers:
-                       while ((arg = strdelim(&cp)) && *arg != '\0') {
-                               if (options->num_allow_users >= MAX_ALLOW_USERS)
-                                       fatal("%s line %d: too many allow users.",
-                                           filename, linenum);
-                               options->allow_users[options->num_allow_users++] = xstrdup(arg);
-                       }
-                       break;
+       case sKeepAlives:
+               intptr = &options->keepalives;
+               goto parse_flag;
 
-               case sDenyUsers:
-                       while ((arg = strdelim(&cp)) && *arg != '\0') {
-                               if (options->num_deny_users >= MAX_DENY_USERS)
-                                       fatal( "%s line %d: too many deny users.",
-                                           filename, linenum);
-                               options->deny_users[options->num_deny_users++] = xstrdup(arg);
-                       }
-                       break;
+       case sEmptyPasswd:
+               intptr = &options->permit_empty_passwd;
+               goto parse_flag;
 
-               case sAllowGroups:
-                       while ((arg = strdelim(&cp)) && *arg != '\0') {
-                               if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
-                                       fatal("%s line %d: too many allow groups.",
-                                           filename, linenum);
-                               options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
-                       }
-                       break;
+       case sUseLogin:
+               intptr = &options->use_login;
+               goto parse_flag;
 
-               case sDenyGroups:
-                       while ((arg = strdelim(&cp)) && *arg != '\0') {
-                               if (options->num_deny_groups >= MAX_DENY_GROUPS)
-                                       fatal("%s line %d: too many deny groups.",
-                                           filename, linenum);
-                               options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
-                       }
-                       break;
+       case sGatewayPorts:
+               intptr = &options->gateway_ports;
+               goto parse_flag;
 
-               case sCiphers:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: Missing argument.", filename, linenum);
-                       if (!ciphers_valid(arg))
-                               fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
-                                   filename, linenum, arg ? arg : "<NONE>");
-                       if (options->ciphers == NULL)
-                               options->ciphers = xstrdup(arg);
-                       break;
+       case sVerifyReverseMapping:
+               intptr = &options->verify_reverse_mapping;
+               goto parse_flag;
 
-               case sMacs:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: Missing argument.", filename, linenum);
-                       if (!mac_valid(arg))
-                               fatal("%s line %d: Bad SSH2 mac spec '%s'.",
-                                   filename, linenum, arg ? arg : "<NONE>");
-                       if (options->macs == NULL)
-                               options->macs = xstrdup(arg);
-                       break;
+       case sLogFacility:
+               intptr = (int *) &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;
+               break;
+
+       case sLogLevel:
+               intptr = (int *) &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;
+               break;
+
+       case sAllowTcpForwarding:
+               intptr = &options->allow_tcp_forwarding;
+               goto parse_flag;
+
+       case sAllowUsers:
+               while ((arg = strdelim(&cp)) && *arg != '\0') {
+                       if (options->num_allow_users >= MAX_ALLOW_USERS)
+                               fatal("%s line %d: too many allow users.",
+                                   filename, linenum);
+                       options->allow_users[options->num_allow_users++] = xstrdup(arg);
+               }
+               break;
 
-               case sProtocol:
-                       intptr = &options->protocol;
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: Missing argument.", filename, linenum);
-                       value = proto_spec(arg);
-                       if (value == SSH_PROTO_UNKNOWN)
-                               fatal("%s line %d: Bad protocol spec '%s'.",
-                                     filename, linenum, arg ? arg : "<NONE>");
-                       if (*intptr == SSH_PROTO_UNKNOWN)
-                               *intptr = value;
-                       break;
+       case sDenyUsers:
+               while ((arg = strdelim(&cp)) && *arg != '\0') {
+                       if (options->num_deny_users >= MAX_DENY_USERS)
+                               fatal( "%s line %d: too many deny users.",
+                                   filename, linenum);
+                       options->deny_users[options->num_deny_users++] = xstrdup(arg);
+               }
+               break;
 
-               case sSubsystem:
-                       if(options->num_subsystems >= MAX_SUBSYSTEMS) {
-                               fatal("%s line %d: too many subsystems defined.",
-                                     filename, linenum);
-                       }
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: Missing subsystem name.",
-                                     filename, linenum);
-                       for (i = 0; i < options->num_subsystems; i++)
-                               if(strcmp(arg, options->subsystem_name[i]) == 0)
-                                       fatal("%s line %d: Subsystem '%s' already defined.",
-                                             filename, linenum, arg);
-                       options->subsystem_name[options->num_subsystems] = xstrdup(arg);
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: Missing subsystem command.",
-                                     filename, linenum);
-                       options->subsystem_command[options->num_subsystems] = xstrdup(arg);
-                       options->num_subsystems++;
-                       break;
+       case sAllowGroups:
+               while ((arg = strdelim(&cp)) && *arg != '\0') {
+                       if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
+                               fatal("%s line %d: too many allow groups.",
+                                   filename, linenum);
+                       options->allow_groups[options->num_allow_groups++] = xstrdup(arg);
+               }
+               break;
 
-               case sMaxStartups:
-                       arg = strdelim(&cp);
-                       if (!arg || *arg == '\0')
-                               fatal("%s line %d: Missing MaxStartups spec.",
-                                     filename, linenum);
-                       if ((n = sscanf(arg, "%d:%d:%d",
-                           &options->max_startups_begin,
-                           &options->max_startups_rate,
-                           &options->max_startups)) == 3) {
-                               if (options->max_startups_begin >
-                                   options->max_startups ||
-                                   options->max_startups_rate > 100 ||
-                                   options->max_startups_rate < 1)
-                                       fatal("%s line %d: Illegal MaxStartups spec.",
-                                           filename, linenum);
-                       } else if (n != 1)
+       case sDenyGroups:
+               while ((arg = strdelim(&cp)) && *arg != '\0') {
+                       if (options->num_deny_groups >= MAX_DENY_GROUPS)
+                               fatal("%s line %d: too many deny groups.",
+                                   filename, linenum);
+                       options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
+               }
+               break;
+
+       case sCiphers:
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing argument.", filename, linenum);
+               if (!ciphers_valid(arg))
+                       fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
+                           filename, linenum, arg ? arg : "<NONE>");
+               if (options->ciphers == NULL)
+                       options->ciphers = xstrdup(arg);
+               break;
+
+       case sMacs:
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing argument.", filename, linenum);
+               if (!mac_valid(arg))
+                       fatal("%s line %d: Bad SSH2 mac spec '%s'.",
+                           filename, linenum, arg ? arg : "<NONE>");
+               if (options->macs == NULL)
+                       options->macs = xstrdup(arg);
+               break;
+
+       case sProtocol:
+               intptr = &options->protocol;
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing argument.", filename, linenum);
+               value = proto_spec(arg);
+               if (value == SSH_PROTO_UNKNOWN)
+                       fatal("%s line %d: Bad protocol spec '%s'.",
+                           filename, linenum, arg ? arg : "<NONE>");
+               if (*intptr == SSH_PROTO_UNKNOWN)
+                       *intptr = value;
+               break;
+
+       case sSubsystem:
+               if (options->num_subsystems >= MAX_SUBSYSTEMS) {
+                       fatal("%s line %d: too many subsystems defined.",
+                           filename, linenum);
+               }
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing subsystem name.",
+                           filename, linenum);
+               for (i = 0; i < options->num_subsystems; i++)
+                       if (strcmp(arg, options->subsystem_name[i]) == 0)
+                               fatal("%s line %d: Subsystem '%s' already defined.",
+                                   filename, linenum, arg);
+               options->subsystem_name[options->num_subsystems] = xstrdup(arg);
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing subsystem command.",
+                           filename, linenum);
+               options->subsystem_command[options->num_subsystems] = xstrdup(arg);
+               options->num_subsystems++;
+               break;
+
+       case sMaxStartups:
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: Missing MaxStartups spec.",
+                           filename, linenum);
+               if ((n = sscanf(arg, "%d:%d:%d",
+                   &options->max_startups_begin,
+                   &options->max_startups_rate,
+                   &options->max_startups)) == 3) {
+                       if (options->max_startups_begin >
+                           options->max_startups ||
+                           options->max_startups_rate > 100 ||
+                           options->max_startups_rate < 1)
                                fatal("%s line %d: Illegal MaxStartups spec.",
                                    filename, linenum);
-                       else
-                               options->max_startups = options->max_startups_begin;
-                       break;
+               } else if (n != 1)
+                       fatal("%s line %d: Illegal MaxStartups spec.",
+                           filename, linenum);
+               else
+                       options->max_startups = options->max_startups_begin;
+               break;
+
+       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:
+        *
+        * AuthorizedKeysFile   /etc/ssh_keys/%u
+        */
+       case sAuthorizedKeysFile:
+       case sAuthorizedKeysFile2:
+               charptr = (opcode == sAuthorizedKeysFile ) ?
+                   &options->authorized_keys_file :
+                   &options->authorized_keys_file2;
+               goto parse_filename;
+
+       case sClientAliveInterval:
+               intptr = &options->client_alive_interval;
+               goto parse_time;
+
+       case sClientAliveCountMax:
+               intptr = &options->client_alive_count_max;
+               goto parse_int;
+
+       case sDeprecated:
+               log("%s line %d: Deprecated option %s",
+                   filename, linenum, arg);
+               while (arg)
+                   arg = strdelim(&cp);
+               break;
+
+       default:
+               fatal("%s line %d: Missing handler for opcode %s (%d)",
+                   filename, linenum, arg, opcode);
+       }
+       if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
+               fatal("%s line %d: garbage at end of line; \"%.200s\".",
+                   filename, linenum, arg);
+       return 0;
+}
 
-               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:
-                *
-                * AuthorizedKeysFile   /etc/ssh_keys/%u
-                */
-               case sAuthorizedKeysFile:
-               case sAuthorizedKeysFile2:
-                       charptr = (opcode == sAuthorizedKeysFile ) ?
-                           &options->authorized_keys_file :
-                           &options->authorized_keys_file2;
-                       goto parse_filename;
-
-               case sClientAliveInterval:
-                       intptr = &options->client_alive_interval;
-                       goto parse_time;
-
-               case sClientAliveCountMax:
-                       intptr = &options->client_alive_count_max;
-                       goto parse_int;
-
-               case sDeprecated:
-                       log("%s line %d: Deprecated option %s",
-                           filename, linenum, arg);
-                       while(arg)
-                           arg = strdelim(&cp);
-                       break;
+/* Reads the server configuration file. */
 
-               default:
-                       fatal("%s line %d: Missing handler for opcode %s (%d)",
-                           filename, linenum, arg, opcode);
-               }
-               if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
-                       fatal("%s line %d: garbage at end of line; \"%.200s\".",
-                           filename, linenum, arg);
+void
+read_server_config(ServerOptions *options, const char *filename)
+{
+       FILE *f;
+       char line[1024];
+       int linenum;
+       int bad_options = 0;
+
+       f = fopen(filename, "r");
+       if (!f) {
+               perror(filename);
+               exit(1);
+       }
+       linenum = 0;
+       while (fgets(line, sizeof(line), f)) {
+               /* Update line number counter. */
+               linenum++;
+               if (process_server_config_line(options, line, filename, linenum) != 0)
+                       bad_options++;
        }
        fclose(f);
        if (bad_options > 0)
index 2e10b1c33edbebf1d1c6023c01bdcf16e1974935..3134b222a8c3999d944bbb02591fbee0cda2de54 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: servconf.h,v 1.54 2002/03/04 17:27:39 stevesk Exp $   */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: servconf.h,v 1.49 2001/08/17 18:59:47 stevesk Exp $"); */
-
 #ifndef SERVCONF_H
 #define SERVCONF_H
 
@@ -55,6 +55,7 @@ typedef struct {
        int     x11_forwarding; /* If true, permit inet (spoofing) X11 fwd. */
        int     x11_display_offset;     /* What DISPLAY number to start
                                         * searching at */
+       int     x11_use_localhost;      /* If true, use localhost for fake X11 server. */
        char   *xauth_location; /* Location of xauth program */
        int     strict_modes;   /* If true, require string home dir modes. */
        int     keepalives;     /* If true, set SO_KEEPALIVE. */
@@ -115,15 +116,15 @@ typedef struct {
        int     max_startups_rate;
        int     max_startups;
        char   *banner;                 /* SSH-2 banner message */
-       int     reverse_mapping_check;  /* cross-check ip and dns */
+       int     verify_reverse_mapping; /* cross-check ip and dns */
        int     client_alive_interval;  /*
-                                        * poke the client this often to 
-                                        * see if it's still there 
+                                        * poke the client this often to
+                                        * see if it's still there
                                         */
        int     client_alive_count_max; /*
                                         * If the client is unresponsive
                                         * for this many intervals above,
-                                        * disconnect the session 
+                                        * disconnect the session
                                         */
 
        char   *authorized_keys_file;   /* File containing public keys */
@@ -135,5 +136,7 @@ typedef struct {
 void    initialize_server_options(ServerOptions *);
 void    read_server_config(ServerOptions *, const char *);
 void    fill_default_server_options(ServerOptions *);
+int     process_server_config_line(ServerOptions *, char *, const char *, int);
+
 
 #endif                         /* SERVCONF_H */
index 0da805f09057e261951ce808f4c03e528b76e093..46b12ee3d3d73cde2992875d026bb0c865e8e648 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.83 2001/11/09 18:59:23 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.98 2002/02/06 14:55:16 markus Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -87,11 +87,56 @@ static int client_alive_timeouts = 0;
  * will exit after that, as soon as forwarded connections have terminated.
  */
 
-static volatile int child_terminated;  /* The child has terminated. */
+static volatile sig_atomic_t child_terminated = 0;     /* The child has terminated. */
 
 /* prototypes */
 static void server_init_dispatch(void);
 
+/*
+ * we write to this pipe if a SIGCHLD is caught in order to avoid
+ * the race between select() and child_terminated
+ */
+static int notify_pipe[2];
+static void
+notify_setup(void)
+{
+       if (pipe(notify_pipe) < 0) {
+               error("pipe(notify_pipe) failed %s", strerror(errno));
+       } else if ((fcntl(notify_pipe[0], F_SETFD, 1) == -1) ||
+           (fcntl(notify_pipe[1], F_SETFD, 1) == -1)) {
+               error("fcntl(notify_pipe, F_SETFD) failed %s", strerror(errno));
+               close(notify_pipe[0]);
+               close(notify_pipe[1]);
+       } else {
+               set_nonblock(notify_pipe[0]);
+               set_nonblock(notify_pipe[1]);
+               return;
+       }
+       notify_pipe[0] = -1;    /* read end */
+       notify_pipe[1] = -1;    /* write end */
+}
+static void
+notify_parent(void)
+{
+       if (notify_pipe[1] != -1)
+               write(notify_pipe[1], "", 1);
+}
+static void
+notify_prepare(fd_set *readset)
+{
+       if (notify_pipe[0] != -1)
+               FD_SET(notify_pipe[0], readset);
+}
+static void
+notify_done(fd_set *readset)
+{
+       char c;
+
+       if (notify_pipe[0] != -1 && FD_ISSET(notify_pipe[0], readset))
+               while (read(notify_pipe[0], &c, 1) != -1)
+                       debug2("notify_done: reading");
+}
+
 static void
 sigchld_handler(int sig)
 {
@@ -99,6 +144,7 @@ sigchld_handler(int sig)
        debug("Received SIGCHLD.");
        child_terminated = 1;
        mysignal(SIGCHLD, sigchld_handler);
+       notify_parent();
        errno = save_errno;
 }
 
@@ -163,15 +209,21 @@ make_packets_from_stdout_data(void)
 static void
 client_alive_check(void)
 {
+       static int had_channel = 0;
        int id;
 
+       id = channel_find_open();
+       if (id == -1) {
+               if (!had_channel)
+                       return;
+               packet_disconnect("No open channels after timeout!");
+       }
+       had_channel = 1;
+
        /* timeout, check to see how many we have had */
        if (++client_alive_timeouts > options.client_alive_count_max)
                packet_disconnect("Timeout, your session not responding.");
 
-       id = channel_find_open();
-       if (id == -1)
-               packet_disconnect("No open channels after timeout!");
        /*
         * send a bogus channel request with "wantreply",
         * we should get back a failure
@@ -195,12 +247,12 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
        int client_alive_scheduled = 0;
 
        /*
-        * if using client_alive, set the max timeout accordingly, 
+        * if using client_alive, set the max timeout accordingly,
         * and indicate that this particular timeout was for client
         * alive by setting the client_alive_scheduled flag.
         *
         * this could be randomized somewhat to make traffic
-        * analysis more difficult, but we're not doing it yet.  
+        * analysis more difficult, but we're not doing it yet.
         */
        if (compat20 &&
            max_time_milliseconds == 0 && options.client_alive_interval) {
@@ -242,6 +294,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
                if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
                        FD_SET(fdin, *writesetp);
        }
+       notify_prepare(*readsetp);
 
        /*
         * If we have buffered packet data going to the client, mark that
@@ -266,7 +319,8 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
                tvp = &tv;
        }
        if (tvp!=NULL)
-               debug3("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds);
+               debug3("tvp!=NULL kid %d mili %d", (int) child_terminated,
+                   max_time_milliseconds);
 
        /* Wait for something to happen, or the timeout to expire. */
        ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
@@ -278,6 +332,8 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
                        error("select: %.100s", strerror(errno));
        } else if (ret == 0 && client_alive_scheduled)
                client_alive_check();
+
+       notify_done(*readsetp);
 }
 
 /*
@@ -356,14 +412,10 @@ process_output(fd_set * writeset)
                if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
                        /* do nothing */
                } else if (len <= 0) {
-#ifdef USE_PIPES
-                       close(fdin);
-#else
                        if (fdin != fdout)
                                close(fdin);
                        else
                                shutdown(fdin, SHUT_WR); /* We will no longer send. */
-#endif
                        fdin = -1;
                } else {
                        /* Successful write. */
@@ -467,6 +519,8 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
        connection_in = packet_get_connection_in();
        connection_out = packet_get_connection_out();
 
+       notify_setup();
+
        previous_stdout_buffer_bytes = 0;
 
        /* Set approximate I/O buffer size. */
@@ -511,14 +565,10 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
                 * input data, cause a real eof by closing fdin.
                 */
                if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
-#ifdef USE_PIPES
-                       close(fdin);
-#else
                        if (fdin != fdout)
                                close(fdin);
                        else
                                shutdown(fdin, SHUT_WR); /* We will no longer send. */
-#endif
                        fdin = -1;
                }
                /* Make packets from buffered stderr data to send to the client. */
@@ -572,6 +622,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
                max_fd = MAX(max_fd, fdin);
                max_fd = MAX(max_fd, fdout);
                max_fd = MAX(max_fd, fderr);
+               max_fd = MAX(max_fd, notify_pipe[0]);
 
                /* Sleep in select() until we can do something. */
                wait_until_can_do_something(&readset, &writeset, &max_fd,
@@ -597,7 +648,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
        drain_output();
 
        debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
-             stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
+           stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);
 
        /* Free and clear the buffers. */
        buffer_free(&stdin_buffer);
@@ -622,7 +673,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
        /* We no longer want our SIGCHLD handler to be called. */
        mysignal(SIGCHLD, SIG_DFL);
 
-       wait_pid = waitpid(-1, &wait_status, child_terminated ? WNOHANG : 0);
+       wait_pid = waitpid(-1, &wait_status, 0);
        if (wait_pid == -1)
                packet_disconnect("wait: %.100s", strerror(errno));
        else if (wait_pid != pid)
@@ -646,8 +697,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
                 * the exit status.
                 */
                do {
-                       int plen;
-                       type = packet_read(&plen);
+                       type = packet_read();
                }
                while (type != SSH_CMSG_EXIT_CONFIRMATION);
 
@@ -696,7 +746,11 @@ server_loop2(Authctxt *authctxt)
        connection_in = packet_get_connection_in();
        connection_out = packet_get_connection_out();
 
+       notify_setup();
+
        max_fd = MAX(connection_in, connection_out);
+       max_fd = MAX(max_fd, notify_pipe[0]);
+
        xxx_authctxt = authctxt;
 
        server_init_dispatch();
@@ -734,20 +788,20 @@ server_loop2(Authctxt *authctxt)
 }
 
 static void
-server_input_channel_failure(int type, int plen, void *ctxt)
+server_input_channel_failure(int type, u_int32_t seq, void *ctxt)
 {
        debug("Got CHANNEL_FAILURE for keepalive");
-       /* 
+       /*
         * reset timeout, since we got a sane answer from the client.
         * even if this was generated by something other than
         * the bogus CHANNEL_REQUEST we send for keepalives.
         */
-       client_alive_timeouts = 0; 
+       client_alive_timeouts = 0;
 }
 
 
 static void
-server_input_stdin_data(int type, int plen, void *ctxt)
+server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
 {
        char *data;
        u_int data_len;
@@ -757,14 +811,14 @@ server_input_stdin_data(int type, int plen, void *ctxt)
        if (fdin == -1)
                return;
        data = packet_get_string(&data_len);
-       packet_integrity_check(plen, (4 + data_len), type);
+       packet_check_eom();
        buffer_append(&stdin_buffer, data, data_len);
        memset(data, 0, data_len);
        xfree(data);
 }
 
 static void
-server_input_eof(int type, int plen, void *ctxt)
+server_input_eof(int type, u_int32_t seq, void *ctxt)
 {
        /*
         * Eof from the client.  The stdin descriptor to the
@@ -772,12 +826,12 @@ server_input_eof(int type, int plen, void *ctxt)
         * drained.
         */
        debug("EOF received for stdin.");
-       packet_integrity_check(plen, 0, type);
+       packet_check_eom();
        stdin_eof = 1;
 }
 
 static void
-server_input_window_size(int type, int plen, void *ctxt)
+server_input_window_size(int type, u_int32_t seq, void *ctxt)
 {
        int row = packet_get_int();
        int col = packet_get_int();
@@ -785,7 +839,7 @@ server_input_window_size(int type, int plen, void *ctxt)
        int ypixel = packet_get_int();
 
        debug("Window change received.");
-       packet_integrity_check(plen, 4 * 4, type);
+       packet_check_eom();
        if (fdin != -1)
                pty_change_window_size(fdin, row, col, xpixel, ypixel);
 }
@@ -802,7 +856,7 @@ server_request_direct_tcpip(char *ctype)
        target_port = packet_get_int();
        originator = packet_get_string(NULL);
        originator_port = packet_get_int();
-       packet_done();
+       packet_check_eom();
 
        debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",
           originator, originator_port, target, target_port);
@@ -816,10 +870,6 @@ server_request_direct_tcpip(char *ctype)
        c = channel_new(ctype, SSH_CHANNEL_CONNECTING,
            sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
            CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
-       if (c == NULL) {
-               error("server_request_direct_tcpip: channel_new failed");
-               close(sock);
-       }
        return c;
 }
 
@@ -829,7 +879,7 @@ server_request_session(char *ctype)
        Channel *c;
 
        debug("input_session_request");
-       packet_done();
+       packet_check_eom();
        /*
         * 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
@@ -839,23 +889,17 @@ server_request_session(char *ctype)
        c = channel_new(ctype, SSH_CHANNEL_LARVAL,
            -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
            0, xstrdup("server-session"), 1);
-       if (c == NULL) {
-               error("server_request_session: channel_new failed");
-               return NULL;
-       }
        if (session_open(xxx_authctxt, c->self) != 1) {
                debug("session open failed, free channel %d", c->self);
                channel_free(c);
                return NULL;
        }
-       channel_register_callback(c->self, SSH2_MSG_CHANNEL_REQUEST,
-           session_input_channel_req, (void *)0);
        channel_register_cleanup(c->self, session_close_by_channel);
        return c;
 }
 
 static void
-server_input_channel_open(int type, int plen, void *ctxt)
+server_input_channel_open(int type, u_int32_t seq, void *ctxt)
 {
        Channel *c = NULL;
        char *ctype;
@@ -905,7 +949,7 @@ server_input_channel_open(int type, int plen, void *ctxt)
 }
 
 static void
-server_input_global_request(int type, int plen, void *ctxt)
+server_input_global_request(int type, u_int32_t seq, void *ctxt)
 {
        char *rtype;
        int want_reply;
@@ -937,11 +981,8 @@ server_input_global_request(int type, int plen, void *ctxt)
                        packet_send_debug("Server has disabled port forwarding.");
                } else {
                        /* Start listening on the port */
-                       success = channel_request_forwarding(
-                           listen_address, listen_port,
-                           /*unspec host_to_connect*/ "<unspec host>",
-                           /*unspec port_to_connect*/ 0,
-                           options.gateway_ports, /*remote*/ 1);
+                       success = channel_setup_remote_fwd_listener(
+                           listen_address, listen_port, options.gateway_ports);
                }
                xfree(listen_address);
        }
@@ -953,6 +994,33 @@ server_input_global_request(int type, int plen, void *ctxt)
        }
        xfree(rtype);
 }
+static void
+server_input_channel_req(int type, u_int32_t seq, void *ctxt)
+{
+       Channel *c;
+       int id, reply, success = 0;
+       char *rtype;
+
+       id = packet_get_int();
+       rtype = packet_get_string(NULL);
+       reply = packet_get_char();
+
+       debug("server_input_channel_req: channel %d request %s reply %d",
+           id, rtype, reply);
+
+       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)
+               success = session_input_channel_req(c, rtype);
+       if (reply) {
+               packet_start(success ?
+                   SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
+               packet_put_int(c->remote_id);
+               packet_send();
+       }
+       xfree(rtype);
+}
 
 static void
 server_init_dispatch_20(void)
@@ -966,7 +1034,7 @@ server_init_dispatch_20(void)
        dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
        dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
        dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
-       dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request);
+       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);
        /* client_alive */
index 02c0c5264f7789dd35e7fe04a66e022cf072c9c6..a31ff85d84929e984a906202318af106a5816220 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.108 2001/10/11 13:45:21 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -57,41 +57,12 @@ RCSID("$OpenBSD: session.c,v 1.108 2001/10/11 13:45:21 markus Exp $");
 #include "canohost.h"
 #include "session.h"
 
-#ifdef WITH_IRIX_PROJECT
-#include <proj.h>
-#endif /* WITH_IRIX_PROJECT */
-#ifdef WITH_IRIX_JOBS
-#include <sys/resource.h>
-#endif
-#ifdef WITH_IRIX_AUDIT
-#include <sat.h>
-#endif /* WITH_IRIX_AUDIT */
-
-#if defined(HAVE_USERSEC_H)
-#include <usersec.h>
-#endif
-
 #ifdef HAVE_CYGWIN
 #include <windows.h>
 #include <sys/cygwin.h>
 #define is_winnt       (GetVersion() < 0x80000000)
 #endif
 
-/* AIX limits */
-#if defined(HAVE_GETUSERATTR) && !defined(S_UFSIZE_HARD) && defined(S_UFSIZE)
-# define S_UFSIZE_HARD  S_UFSIZE "_hard"
-# define S_UCPU_HARD  S_UCPU "_hard"
-# define S_UDATA_HARD  S_UDATA "_hard"
-# define S_USTACK_HARD  S_USTACK "_hard"
-# define S_URSS_HARD  S_URSS "_hard"
-# define S_UCORE_HARD  S_UCORE "_hard"
-# define S_UNOFILE_HARD        S_UNOFILE "_hard"
-#endif
-
-#ifdef _AIX
-# include <uinfo.h>
-#endif
-
 /* types */
 
 #define TTYSZ 64
@@ -108,8 +79,10 @@ struct Session {
        int     row, col, xpixel, ypixel;
        char    tty[TTYSZ];
        /* X11 */
+       int     display_number;
        char    *display;
        int     screen;
+       char    *auth_display;
        char    *auth_proto;
        char    *auth_data;
        int     single_connection;
@@ -193,7 +166,7 @@ do_authenticated(Authctxt *authctxt)
 #ifdef WITH_AIXAUTHENTICATE
        /* We don't have a pty yet, so just label the line as "ssh" */
        if (loginsuccess(authctxt->user,
-           get_canonical_hostname(options.reverse_mapping_check),
+           get_canonical_hostname(options.verify_reverse_mapping),
            "ssh", &aixloginmsg) < 0)
                aixloginmsg = NULL;
 #endif /* WITH_AIXAUTHENTICATE */
@@ -231,7 +204,7 @@ do_authenticated1(Authctxt *authctxt)
 {
        Session *s;
        char *command;
-       int success, type, plen, screen_flag;
+       int success, type, screen_flag;
        int compression_level = 0, enable_compression_after_reply = 0;
        u_int proto_len, data_len, dlen;
 
@@ -247,16 +220,16 @@ do_authenticated1(Authctxt *authctxt)
                success = 0;
 
                /* Get a packet from the client. */
-               type = packet_read(&plen);
+               type = packet_read();
 
                /* Process the packet. */
                switch (type) {
                case SSH_CMSG_REQUEST_COMPRESSION:
-                       packet_integrity_check(plen, 4, type);
                        compression_level = packet_get_int();
+                       packet_check_eom();
                        if (compression_level < 1 || compression_level > 9) {
                                packet_send_debug("Received illegal compression level %d.",
-                                    compression_level);
+                                   compression_level);
                                break;
                        }
                        /* Enable compression after we have responded with SUCCESS. */
@@ -284,7 +257,7 @@ do_authenticated1(Authctxt *authctxt)
                        } else {
                                s->screen = 0;
                        }
-                       packet_done();
+                       packet_check_eom();
                        success = session_setup_x11fwd(s);
                        if (!success) {
                                xfree(s->auth_proto);
@@ -321,22 +294,22 @@ do_authenticated1(Authctxt *authctxt)
                        if (packet_set_maxsize(packet_get_int()) > 0)
                                success = 1;
                        break;
-                       
+
 #if defined(AFS) || defined(KRB5)
                case SSH_CMSG_HAVE_KERBEROS_TGT:
                        if (!options.kerberos_tgt_passing) {
                                verbose("Kerberos TGT passing disabled.");
                        } else {
                                char *kdata = packet_get_string(&dlen);
-                               packet_integrity_check(plen, 4 + dlen, type);
-                               
+                               packet_check_eom();
+
                                /* XXX - 0x41, see creds_to_radix version */
                                if (kdata[0] != 0x41) {
 #ifdef KRB5
                                        krb5_data tgt;
                                        tgt.data = kdata;
                                        tgt.length = dlen;
-                                       
+
                                        if (auth_krb5_tgt(s->authctxt, &tgt))
                                                success = 1;
                                        else
@@ -354,7 +327,7 @@ do_authenticated1(Authctxt *authctxt)
                        }
                        break;
 #endif /* AFS || KRB5 */
-                       
+
 #ifdef AFS
                case SSH_CMSG_HAVE_AFS_TOKEN:
                        if (!options.afs_token_passing || !k_hasafs()) {
@@ -362,8 +335,8 @@ do_authenticated1(Authctxt *authctxt)
                        } else {
                                /* Accept AFS token. */
                                char *token = packet_get_string(&dlen);
-                               packet_integrity_check(plen, 4 + dlen, type);
-                               
+                               packet_check_eom();
+
                                if (auth_afs_token(s->authctxt, token))
                                        success = 1;
                                else
@@ -384,7 +357,7 @@ do_authenticated1(Authctxt *authctxt)
                        } else {
                                do_exec(s, NULL);
                        }
-                       packet_done();
+                       packet_check_eom();
                        session_close(s);
                        return;
 
@@ -647,14 +620,14 @@ do_pre_login(Session *s)
        if (packet_connection_is_on_socket()) {
                fromlen = sizeof(from);
                if (getpeername(packet_get_connection_in(),
-                    (struct sockaddr *) & from, &fromlen) < 0) {
+                   (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
                        fatal_cleanup();
                }
        }
 
        record_utmp_only(pid, s->tty, s->pw->pw_name,
-           get_remote_name_or_ip(utmp_len, options.reverse_mapping_check),
+           get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
            (struct sockaddr *)&from);
 }
 #endif
@@ -680,6 +653,7 @@ do_exec(Session *s, const char *command)
        original_command = NULL;
 }
 
+
 /* administrative, login(1)-like work */
 void
 do_login(Session *s, const char *command)
@@ -700,7 +674,7 @@ do_login(Session *s, const char *command)
        if (packet_connection_is_on_socket()) {
                fromlen = sizeof(from);
                if (getpeername(packet_get_connection_in(),
-                    (struct sockaddr *) & from, &fromlen) < 0) {
+                   (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
                        fatal_cleanup();
                }
@@ -715,7 +689,7 @@ do_login(Session *s, const char *command)
 
        /* Record that there was a login on that tty from the remote host. */
        record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
-           get_remote_name_or_ip(utmp_len, options.reverse_mapping_check),
+           get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
            (struct sockaddr *)&from);
 
 #ifdef USE_PAM
@@ -809,7 +783,7 @@ check_quietlogin(Session *s, const char *command)
  */
 static void
 child_set_env(char ***envp, u_int *envsizep, const char *name,
-             const char *value)
+       const char *value)
 {
        u_int i, namelen;
        char **env;
@@ -850,7 +824,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
  */
 static void
 read_environment_file(char ***env, u_int *envsize,
-                     const char *filename)
+       const char *filename)
 {
        FILE *f;
        char buf[4096];
@@ -883,325 +857,36 @@ read_environment_file(char ***env, u_int *envsize,
        fclose(f);
 }
 
-#ifdef USE_PAM
-/*
- * Sets any environment variables which have been specified by PAM
- */
-void do_pam_environment(char ***env, u_int *envsize)
+void copy_environment(char **source, char ***env, u_int *envsize)
 {
-       char *equals, var_name[512], var_val[512];
-       char **pam_env;
+       char *var_name, *var_val;
        int i;
 
-       if ((pam_env = fetch_pam_environment()) == NULL)
+       if (source == NULL)
                return;
 
-       for(i = 0; pam_env[i] != NULL; i++) {
-               if ((equals = strstr(pam_env[i], "=")) == NULL)
+       for(i = 0; source[i] != NULL; i++) {
+               var_name = xstrdup(source[i]);
+               if ((var_val = strstr(var_name, "=")) == NULL) {
+                       xfree(var_name);
                        continue;
-
-               if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) {
-                       memset(var_name, '\0', sizeof(var_name));
-                       memset(var_val, '\0', sizeof(var_val));
-
-                       strncpy(var_name, pam_env[i], equals - pam_env[i]);
-                       strcpy(var_val, equals + 1);
-
-                       debug3("PAM environment: %s=%s", var_name, var_val);
-
-                       child_set_env(env, envsize, var_name, var_val);
                }
-       }
-}
-#endif /* USE_PAM */
-
-#ifdef HAVE_CYGWIN
-void copy_environment(char ***env, u_int *envsize)
-{
-       char *equals, var_name[512], var_val[512];
-       int i;
-
-       for(i = 0; environ[i] != NULL; i++) {
-               if ((equals = strstr(environ[i], "=")) == NULL)
-                       continue;
-
-               if (strlen(environ[i]) < (sizeof(var_name) - 1)) {
-                       memset(var_name, '\0', sizeof(var_name));
-                       memset(var_val, '\0', sizeof(var_val));
+               *var_val++ = '\0';
 
-                       strncpy(var_name, environ[i], equals - environ[i]);
-                       strcpy(var_val, equals + 1);
-
-                       debug3("Copy environment: %s=%s", var_name, var_val);
-
-                       child_set_env(env, envsize, var_name, var_val);
-               }
-       }
-}
-#endif
-
-#if defined(HAVE_GETUSERATTR)
-/*
- * AIX-specific login initialisation
- */
-void set_limit(char *user, char *soft, char *hard, int resource, int mult)
-{
-       struct rlimit rlim;
-       int slim, hlim;
-
-       getrlimit(resource, &rlim);
-
-       slim = 0;
-       if (getuserattr(user, soft, &slim, SEC_INT) != -1) {
-               if (slim < 0) {
-                       rlim.rlim_cur = RLIM_INFINITY;
-               } else if (slim != 0) {
-                       /* See the wackiness below */
-                       if (rlim.rlim_cur == slim * mult)
-                               slim = 0;
-                       else
-                               rlim.rlim_cur = slim * mult;
-               }
-       }
-
-       hlim = 0;
-       if (getuserattr(user, hard, &hlim, SEC_INT) != -1) {
-               if (hlim < 0) {
-                       rlim.rlim_max = RLIM_INFINITY;
-               } else if (hlim != 0) {
-                       rlim.rlim_max = hlim * mult;
-               }
-       }
-
-       /*
-        * XXX For cpu and fsize the soft limit is set to the hard limit
-        * if the hard limit is left at its default value and the soft limit
-        * is changed from its default value, either by requesting it
-        * (slim == 0) or by setting it to the current default.  At least
-        * that's how rlogind does it.  If you're confused you're not alone.
-        * Bug or feature? AIX 4.3.1.2
-        */
-       if ((!strcmp(soft, "fsize") || !strcmp(soft, "cpu"))
-           && hlim == 0 && slim != 0)
-               rlim.rlim_max = rlim.rlim_cur;
-       /* A specified hard limit limits the soft limit */
-       else if (hlim > 0 && rlim.rlim_cur > rlim.rlim_max)
-               rlim.rlim_cur = rlim.rlim_max;
-       /* A soft limit can increase a hard limit */
-       else if (rlim.rlim_cur > rlim.rlim_max)
-               rlim.rlim_max = rlim.rlim_cur;
-
-       if (setrlimit(resource, &rlim) != 0)
-               error("setrlimit(%.10s) failed: %.100s", soft, strerror(errno));
-}
-
-void set_limits_from_userattr(char *user)
-{
-       int mask;
-       char buf[16];
-
-       set_limit(user, S_UFSIZE, S_UFSIZE_HARD, RLIMIT_FSIZE, 512);
-       set_limit(user, S_UCPU, S_UCPU_HARD, RLIMIT_CPU, 1);
-       set_limit(user, S_UDATA, S_UDATA_HARD, RLIMIT_DATA, 512);
-       set_limit(user, S_USTACK, S_USTACK_HARD, RLIMIT_STACK, 512);
-       set_limit(user, S_URSS, S_URSS_HARD, RLIMIT_RSS, 512);
-       set_limit(user, S_UCORE, S_UCORE_HARD, RLIMIT_CORE, 512);
-#if defined(S_UNOFILE)
-       set_limit(user, S_UNOFILE, S_UNOFILE_HARD, RLIMIT_NOFILE, 1);
-#endif
-
-       if (getuserattr(user, S_UMASK, &mask, SEC_INT) != -1) {
-               /* Convert decimal to octal */
-               (void) snprintf(buf, sizeof(buf), "%d", mask);
-               if (sscanf(buf, "%o", &mask) == 1)
-                       umask(mask);
+               debug3("Copy environment: %s=%s", var_name, var_val);
+               child_set_env(env, envsize, var_name, var_val);
+               
+               xfree(var_name);
        }
 }
-#endif /* defined(HAVE_GETUSERATTR) */
 
-/*
- * Performs common processing for the child, such as setting up the
- * environment, closing extra file descriptors, setting the user and group
- * ids, and executing the command or shell.
- */
-void
-do_child(Session *s, const char *command)
+static char **
+do_setup_env(Session *s, const char *shell)
 {
-       const char *shell, *hostname = NULL, *cp = NULL;
-       struct passwd *pw = s->pw;
        char buf[256];
-       char cmd[1024];
-       FILE *f = NULL;
-       u_int envsize, i;
+       u_int i, envsize;
        char **env;
-       extern char **environ;
-       struct stat st;
-       char *argv[10];
-       int do_xauth;
-#ifdef WITH_IRIX_PROJECT
-       prid_t projid;
-#endif /* WITH_IRIX_PROJECT */
-#ifdef WITH_IRIX_JOBS
-       jid_t jid = 0;
-#else
-#ifdef WITH_IRIX_ARRAY
-       int jid = 0;
-#endif /* WITH_IRIX_ARRAY */
-#endif /* WITH_IRIX_JOBS */
-
-       do_xauth =
-           s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
-
-       /* remove hostkey from the child's memory */
-       destroy_sensitive_data();
-
-       /* login(1) is only called if we execute the login shell */
-       if (options.use_login && command != NULL)
-               options.use_login = 0;
-
-#if !defined(HAVE_OSF_SIA)
-       if (!options.use_login) {
-# ifdef HAVE_LOGIN_CAP
-               if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
-                       f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
-                           _PATH_NOLOGIN), "r");
-# else /* HAVE_LOGIN_CAP */
-               if (pw->pw_uid)
-                       f = fopen(_PATH_NOLOGIN, "r");
-# endif /* HAVE_LOGIN_CAP */
-               if (f) {
-                       /* /etc/nologin exists.  Print its contents and exit. */
-                       while (fgets(buf, sizeof(buf), f))
-                               fputs(buf, stderr);
-                       fclose(f);
-                       exit(254);
-               }
-       }
-#endif /* HAVE_OSF_SIA */
-
-       /* Set login name, uid, gid, and groups. */
-       /* Login(1) does this as well, and it needs uid 0 for the "-h"
-          switch, so we let login(1) to this for us. */
-       if (!options.use_login) {
-#ifdef HAVE_OSF_SIA
-               session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
-               if (!check_quietlogin(s, command))
-                       do_motd();
-#else /* HAVE_OSF_SIA */
-#ifdef HAVE_CYGWIN
-               if (is_winnt) {
-#else
-               if (getuid() == 0 || geteuid() == 0) {
-#endif
-# ifdef HAVE_GETUSERATTR
-                       set_limits_from_userattr(pw->pw_name);
-# endif /* HAVE_GETUSERATTR */
-# ifdef HAVE_LOGIN_CAP
-                       if (setusercontext(lc, pw, pw->pw_uid,
-                           (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
-                               perror("unable to set user context");
-                               exit(1);
-                       }
-# else /* HAVE_LOGIN_CAP */
-#if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
-                       /* Sets login uid for accounting */
-                       if (getluid() == -1 && setluid(pw->pw_uid) == -1)
-                               error("setluid: %s", strerror(errno));
-#endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
-
-                       if (setlogin(pw->pw_name) < 0)
-                               error("setlogin failed: %s", strerror(errno));
-                       if (setgid(pw->pw_gid) < 0) {
-                               perror("setgid");
-                               exit(1);
-                       }
-                       /* Initialize the group list. */
-                       if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
-                               perror("initgroups");
-                               exit(1);
-                       }
-                       endgrent();
-#  ifdef USE_PAM
-                       /*
-                        * PAM credentials may take the form of 
-                        * supplementary groups. These will have been 
-                        * wiped by the above initgroups() call.
-                        * Reestablish them here.
-                        */
-                       do_pam_setcred(0);
-#  endif /* USE_PAM */
-#  ifdef WITH_IRIX_JOBS
-                       jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive");
-                       if (jid == -1) {
-                               fatal("Failed to create job container: %.100s",
-                                     strerror(errno));
-                       }
-#  endif /* WITH_IRIX_JOBS */
-#  ifdef WITH_IRIX_ARRAY
-                       /* initialize array session */
-                       if (jid == 0) {
-                               if (newarraysess() != 0)
-                                       fatal("Failed to set up new array session: %.100s",
-                                             strerror(errno));
-                       }
-#  endif /* WITH_IRIX_ARRAY */
-#  ifdef WITH_IRIX_PROJECT
-                       /* initialize irix project info */
-                       if ((projid = getdfltprojuser(pw->pw_name)) == -1) {
-                         debug("Failed to get project id, using projid 0");
-                         projid = 0;
-                       }
-                       if (setprid(projid))
-                         fatal("Failed to initialize project %d for %s: %.100s",
-                               (int)projid, pw->pw_name, strerror(errno));
-#  endif /* WITH_IRIX_PROJECT */
-#ifdef WITH_IRIX_AUDIT
-                       if (sysconf(_SC_AUDIT)) {
-                               debug("Setting sat id to %d", (int) pw->pw_uid);
-                               if (satsetid(pw->pw_uid))
-                                       debug("error setting satid: %.100s", strerror(errno));
-                       }
-#endif /* WITH_IRIX_AUDIT */
-
-#ifdef _AIX
-                       /*
-                        * AIX has a "usrinfo" area where logname and
-                        * other stuff is stored - a few applications
-                        * actually use this and die if it's not set
-                        */
-                       if (s->ttyfd == -1)
-                               s->tty[0] = '\0';
-                       cp = xmalloc(22 + strlen(s->tty) + 
-                           2 * strlen(pw->pw_name));
-                       i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c",
-                           pw->pw_name, 0, pw->pw_name, 0, s->tty, 0, 0);
-                       if (usrinfo(SETUINFO, cp, i) == -1)
-                               fatal("Couldn't set usrinfo: %s", 
-                                   strerror(errno));
-                       debug3("AIX/UsrInfo: set len %d", i);
-                       xfree(cp);
-#endif
-
-                       /* Permanently switch to the desired uid. */
-                       permanently_set_uid(pw);
-# endif /* HAVE_LOGIN_CAP */
-               }
-#endif /* HAVE_OSF_SIA */
-
-#ifdef HAVE_CYGWIN
-               if (is_winnt)
-#endif
-               if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
-                       fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
-       }
-       /*
-        * Get the shell from the password data.  An empty shell field is
-        * legal, and means /bin/sh.
-        */
-       shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
-#ifdef HAVE_LOGIN_CAP
-       shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
-#endif
+       struct passwd *pw = s->pw;
 
        /* Initialize the environment. */
        envsize = 100;
@@ -1213,7 +898,7 @@ do_child(Session *s, const char *command)
         * The Windows environment contains some setting which are
         * important for a running system. They must not be dropped.
         */
-       copy_environment(&env, &envsize);
+       copy_environment(environ, &env, &envsize);
 #endif
 
        if (!options.use_login) {
@@ -1251,7 +936,7 @@ do_child(Session *s, const char *command)
                while (custom_environment) {
                        struct envstring *ce = custom_environment;
                        char *s = ce->s;
-                       int i;
+
                        for (i = 0; s[i] != '=' && s[i]; i++)
                                ;
                        if (s[i] == '=') {
@@ -1265,7 +950,7 @@ do_child(Session *s, const char *command)
        }
 
        snprintf(buf, sizeof buf, "%.50s %d %d",
-                get_remote_ipaddr(), get_remote_port(), get_local_port());
+           get_remote_ipaddr(), get_remote_port(), get_local_port());
        child_set_env(&env, &envsize, "SSH_CLIENT", buf);
 
        if (s->ttyfd != -1)
@@ -1279,11 +964,15 @@ do_child(Session *s, const char *command)
                    original_command);
 
 #ifdef _AIX
-       if ((cp = getenv("AUTHSTATE")) != NULL)
-               child_set_env(&env, &envsize, "AUTHSTATE", cp);
-       if ((cp = getenv("KRB5CCNAME")) != NULL)
-               child_set_env(&env, &envsize, "KRB5CCNAME", cp);
-       read_environment_file(&env, &envsize, "/etc/environment");
+       {
+               char *cp;
+
+               if ((cp = getenv("AUTHSTATE")) != NULL)
+                       child_set_env(&env, &envsize, "AUTHSTATE", cp);
+               if ((cp = getenv("KRB5CCNAME")) != NULL)
+                       child_set_env(&env, &envsize, "KRB5CCNAME", cp);
+               read_environment_file(&env, &envsize, "/etc/environment");
+       }
 #endif
 #ifdef KRB4
        if (s->authctxt->krb4_ticket_file)
@@ -1297,12 +986,12 @@ do_child(Session *s, const char *command)
 #endif
 #ifdef USE_PAM
        /* Pull in any environment variables that may have been set by PAM. */
-       do_pam_environment(&env, &envsize);
+       copy_environment(fetch_pam_environment(), &env, &envsize);
 #endif /* USE_PAM */
 
        if (auth_get_socket_name() != NULL)
                child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
-                             auth_get_socket_name());
+                   auth_get_socket_name());
 
        /* read $HOME/.ssh/environment. */
        if (!options.use_login) {
@@ -1316,10 +1005,210 @@ do_child(Session *s, const char *command)
                for (i = 0; env[i]; i++)
                        fprintf(stderr, "  %.200s\n", env[i]);
        }
+       return env;
+}
+
+/*
+ * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
+ * first in this order).
+ */
+static void
+do_rc_files(Session *s, const char *shell)
+{
+       FILE *f = NULL;
+       char cmd[1024];
+       int do_xauth;
+       struct stat st;
+
+       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)) {
+               snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
+                   shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
+               if (debug_flag)
+                       fprintf(stderr, "Running %s\n", cmd);
+               f = popen(cmd, "w");
+               if (f) {
+                       if (do_xauth)
+                               fprintf(f, "%s %s\n", s->auth_proto,
+                                   s->auth_data);
+                       pclose(f);
+               } else
+                       fprintf(stderr, "Could not run %s\n",
+                           _PATH_SSH_USER_RC);
+       } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
+               if (debug_flag)
+                       fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
+                           _PATH_SSH_SYSTEM_RC);
+               f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
+               if (f) {
+                       if (do_xauth)
+                               fprintf(f, "%s %s\n", s->auth_proto,
+                                   s->auth_data);
+                       pclose(f);
+               } else
+                       fprintf(stderr, "Could not run %s\n",
+                           _PATH_SSH_SYSTEM_RC);
+       } else if (do_xauth && options.xauth_location != NULL) {
+               /* Add authority data to .Xauthority if appropriate. */
+               if (debug_flag) {
+                       fprintf(stderr,
+                           "Running %.100s add "
+                           "%.100s %.100s %.100s\n",
+                           options.xauth_location, s->auth_display,
+                           s->auth_proto, s->auth_data);
+               }
+               snprintf(cmd, sizeof cmd, "%s -q -",
+                   options.xauth_location);
+               f = popen(cmd, "w");
+               if (f) {
+                       fprintf(f, "add %s %s %s\n",
+                           s->auth_display, s->auth_proto,
+                           s->auth_data);
+                       pclose(f);
+               } else {
+                       fprintf(stderr, "Could not run %s\n",
+                           cmd);
+               }
+       }
+}
+
+static void
+do_nologin(struct passwd *pw)
+{
+       FILE *f = NULL;
+       char buf[1024];
+
+#ifdef HAVE_LOGIN_CAP
+       if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
+               f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
+                   _PATH_NOLOGIN), "r");
+#else
+       if (pw->pw_uid)
+               f = fopen(_PATH_NOLOGIN, "r");
+#endif
+       if (f) {
+               /* /etc/nologin exists.  Print its contents and exit. */
+               while (fgets(buf, sizeof(buf), f))
+                       fputs(buf, stderr);
+               fclose(f);
+               exit(254);
+       }
+}
+
+/* Set login name, uid, gid, and groups. */
+static void
+do_setusercontext(struct passwd *pw)
+{
+#ifdef HAVE_CYGWIN
+       if (is_winnt) {
+#else /* HAVE_CYGWIN */
+       if (getuid() == 0 || geteuid() == 0) {
+#endif /* HAVE_CYGWIN */
+#ifdef HAVE_GETUSERATTR
+               set_limits_from_userattr(pw->pw_name);
+#endif /* HAVE_GETUSERATTR */
+#ifdef HAVE_LOGIN_CAP
+               if (setusercontext(lc, pw, pw->pw_uid,
+                   (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
+                       perror("unable to set user context");
+                       exit(1);
+               }
+#else
+# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
+               /* Sets login uid for accounting */
+               if (getluid() == -1 && setluid(pw->pw_uid) == -1)
+                       error("setluid: %s", strerror(errno));
+# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
+
+               if (setlogin(pw->pw_name) < 0)
+                       error("setlogin failed: %s", strerror(errno));
+               if (setgid(pw->pw_gid) < 0) {
+                       perror("setgid");
+                       exit(1);
+               }
+               /* Initialize the group list. */
+               if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
+                       perror("initgroups");
+                       exit(1);
+               }
+               endgrent();
+# ifdef USE_PAM
+               /*
+                * PAM credentials may take the form of supplementary groups. 
+                * These will have been wiped by the above initgroups() call.
+                * Reestablish them here.
+                */
+               do_pam_setcred(0);
+# 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) */
+               /* Permanently switch to the desired uid. */
+               permanently_set_uid(pw);
+#endif
+       }
+       if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
+               fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
+}
+
+/*
+ * Performs common processing for the child, such as setting up the
+ * environment, closing extra file descriptors, setting the user and group
+ * ids, and executing the command or shell.
+ */
+void
+do_child(Session *s, const char *command)
+{
+       extern char **environ;
+       char **env;
+       char *argv[10];
+       const char *shell, *shell0, *hostname = NULL;
+       struct passwd *pw = s->pw;
+       u_int i;
+
+       /* remove hostkey from the child's memory */
+       destroy_sensitive_data();
+
+       /* login(1) is only called if we execute the login shell */
+       if (options.use_login && command != NULL)
+               options.use_login = 0;
+
+       /*
+        * Login(1) does this as well, and it needs uid 0 for the "-h"
+        * switch, so we let login(1) to this for us.
+        */
+       if (!options.use_login) {
+#ifdef HAVE_OSF_SIA
+               session_setup_sia(pw->pw_name, s->ttyfd == -1 ? NULL : s->tty);
+               if (!check_quietlogin(s, command))
+                       do_motd();
+#else /* HAVE_OSF_SIA */
+               do_nologin(pw);
+# ifdef _AIX
+               aix_usrinfo(pw, s->tty, s->ttyfd);
+# endif /* _AIX */
+               do_setusercontext(pw);
+#endif /* HAVE_OSF_SIA */
+       }
+
+       /*
+        * Get the shell from the password data.  An empty shell field is
+        * legal, and means /bin/sh.
+        */
+       shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
+#ifdef HAVE_LOGIN_CAP
+       shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
+#endif
+
+       env = do_setup_env(s, shell);
+
        /* we have to stash the hostname before we close our socket. */
        if (options.use_login)
                hostname = get_remote_name_or_ip(utmp_len,
-                   options.reverse_mapping_check);
+                   options.verify_reverse_mapping);
        /*
         * Close the connection descriptors; note that this is the child, and
         * the server will still have the socket open, and it is important
@@ -1356,8 +1245,8 @@ do_child(Session *s, const char *command)
                close(i);
 
        /*
-        * Must take new environment into use so that .ssh/rc, /etc/sshrc and
-        * xauth are run in the proper environment.
+        * Must take new environment into use so that .ssh/rc,
+        * /etc/ssh/sshrc and xauth are run in the proper environment.
         */
        environ = env;
 
@@ -1365,10 +1254,10 @@ do_child(Session *s, const char *command)
        /* Try to get AFS tokens for the local cell. */
        if (k_hasafs()) {
                char cell[64];
-               
+
                if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
                        krb_afslog(cell, 0);
-               
+
                krb_afslog(0, 0);
        }
 #endif /* AFS */
@@ -1383,128 +1272,65 @@ do_child(Session *s, const char *command)
 #endif
        }
 
-       /*
-        * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
-        * in this order).
-        */
-       if (!options.use_login) {
-               /* ignore _PATH_SSH_USER_RC for subsystems */
-               if (!s->is_subsystem && (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)
-                               fprintf(stderr, "Running %s\n", cmd);
-                       f = popen(cmd, "w");
-                       if (f) {
-                               if (do_xauth)
-                                       fprintf(f, "%s %s\n", s->auth_proto,
-                                           s->auth_data);
-                               pclose(f);
-                       } else
-                               fprintf(stderr, "Could not run %s\n",
-                                   _PATH_SSH_USER_RC);
-               } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
-                       if (debug_flag)
-                               fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
-                                   _PATH_SSH_SYSTEM_RC);
-                       f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
-                       if (f) {
-                               if (do_xauth)
-                                       fprintf(f, "%s %s\n", s->auth_proto,
-                                           s->auth_data);
-                               pclose(f);
-                       } else
-                               fprintf(stderr, "Could not run %s\n",
-                                   _PATH_SSH_SYSTEM_RC);
-               } else if (do_xauth && options.xauth_location != NULL) {
-                       /* Add authority data to .Xauthority if appropriate. */
-                       char *screen = strchr(s->display, ':');
-
-                       if (debug_flag) {
-                               fprintf(stderr,
-                                   "Running %.100s add "
-                                   "%.100s %.100s %.100s\n",
-                                   options.xauth_location, s->display,
-                                   s->auth_proto, s->auth_data);
-                               if (screen != NULL)
-                                       fprintf(stderr,
-                                           "Adding %.*s/unix%s %s %s\n",
-                                           (int)(screen - s->display),
-                                           s->display, screen,
-                                           s->auth_proto, s->auth_data);
-                       }
-                       snprintf(cmd, sizeof cmd, "%s -q -",
-                           options.xauth_location);
-                       f = popen(cmd, "w");
-                       if (f) {
-                               fprintf(f, "add %s %s %s\n", s->display,
-                                   s->auth_proto, s->auth_data);
-                               if (screen != NULL)
-                                       fprintf(f, "add %.*s/unix%s %s %s\n",
-                                           (int)(screen - s->display),
-                                           s->display, screen,
-                                           s->auth_proto,
-                                           s->auth_data);
-                               pclose(f);
-                       } else {
-                               fprintf(stderr, "Could not run %s\n",
-                                   cmd);
-                       }
-               }
-               /* Get the last component of the shell name. */
-               cp = strrchr(shell, '/');
-               if (cp)
-                       cp++;
-               else
-                       cp = shell;
-       }
+       if (!options.use_login)
+               do_rc_files(s, shell);
 
        /* restore SIGPIPE for child */
        signal(SIGPIPE,  SIG_DFL);
 
+       if (options.use_login) {
+               /* Launch login(1). */
+
+               execl(LOGIN_PROGRAM, "login", "-h", hostname,
+#ifdef LOGIN_NEEDS_TERM
+                   (s->term ? s->term : "unknown"),
+#endif /* LOGIN_NEEDS_TERM */
+                   "-p", "-f", "--", pw->pw_name, (char *)NULL);
+
+               /* Login couldn't be executed, die. */
+
+               perror("login");
+               exit(1);
+       }
+
+       /* Get the last component of the shell name. */
+       if ((shell0 = strrchr(shell, '/')) != NULL)
+               shell0++;
+       else
+               shell0 = shell;
+
        /*
         * If we have no command, execute the shell.  In this case, the shell
         * name to be passed in argv[0] is preceded by '-' to indicate that
         * this is a login shell.
         */
        if (!command) {
-               if (!options.use_login) {
-                       char buf[256];
+               char argv0[256];
 
-                       /* Start the shell.  Set initial character to '-'. */
-                       buf[0] = '-';
-                       strncpy(buf + 1, cp, sizeof(buf) - 1);
-                       buf[sizeof(buf) - 1] = 0;
+               /* Start the shell.  Set initial character to '-'. */
+               argv0[0] = '-';
 
-                       /* Execute the shell. */
-                       argv[0] = buf;
-                       argv[1] = NULL;
-                       execve(shell, argv, env);
-
-                       /* Executing the shell failed. */
+               if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
+                   >= sizeof(argv0) - 1) {
+                       errno = EINVAL;
                        perror(shell);
                        exit(1);
+               }
 
-               } else {
-                       /* Launch login(1). */
-
-                       execl(LOGIN_PROGRAM, "login", "-h", hostname,
-#ifdef LOGIN_NEEDS_TERM
-                            s->term? s->term : "unknown",
-#endif
-                            "-p", "-f", "--", pw->pw_name, (char *)NULL);
-
-                       /* Login couldn't be executed, die. */
+               /* Execute the shell. */
+               argv[0] = argv0;
+               argv[1] = NULL;
+               execve(shell, argv, env);
 
-                       perror("login");
-                       exit(1);
-               }
+               /* Executing the shell failed. */
+               perror(shell);
+               exit(1);
        }
        /*
         * Execute the command using the user's shell.  This uses the -c
         * option to execute the command.
         */
-       argv[0] = (char *) cp;
+       argv[0] = (char *) shell0;
        argv[1] = "-c";
        argv[2] = (char *) command;
        argv[3] = NULL;
@@ -1520,12 +1346,12 @@ session_new(void)
        static int did_init = 0;
        if (!did_init) {
                debug("session_new: init");
-               for(i = 0; i < MAX_SESSIONS; i++) {
+               for (i = 0; i < MAX_SESSIONS; i++) {
                        sessions[i].used = 0;
                }
                did_init = 1;
        }
-       for(i = 0; i < MAX_SESSIONS; i++) {
+       for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                if (! s->used) {
                        memset(s, 0, sizeof(*s));
@@ -1545,7 +1371,7 @@ static void
 session_dump(void)
 {
        int i;
-       for(i = 0; i < MAX_SESSIONS; i++) {
+       for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                debug("dump: used %d session %d %p channel %d pid %d",
                    s->used,
@@ -1578,7 +1404,7 @@ static Session *
 session_by_channel(int id)
 {
        int i;
-       for(i = 0; i < MAX_SESSIONS; i++) {
+       for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                if (s->used && s->chanid == id) {
                        debug("session_by_channel: session %d channel %d", i, id);
@@ -1595,7 +1421,7 @@ session_by_pid(pid_t pid)
 {
        int i;
        debug("session_by_pid: pid %d", pid);
-       for(i = 0; i < MAX_SESSIONS; i++) {
+       for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                if (s->used && s->pid == pid)
                        return s;
@@ -1612,7 +1438,7 @@ session_window_change_req(Session *s)
        s->row = packet_get_int();
        s->xpixel = packet_get_int();
        s->ypixel = packet_get_int();
-       packet_done();
+       packet_check_eom();
        pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
        return 1;
 }
@@ -1677,7 +1503,7 @@ session_pty_req(Session *s)
        /* Set window size from the packet. */
        pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
 
-       packet_done();
+       packet_check_eom();
        session_proctitle(s);
        return 1;
 }
@@ -1691,8 +1517,8 @@ session_subsystem_req(Session *s)
        char *cmd, *subsys = packet_get_string(&len);
        int i;
 
-       packet_done();
-       log("subsystem request for %s", subsys);
+       packet_check_eom();
+       log("subsystem request for %.100s", subsys);
 
        for (i = 0; i < options.num_subsystems; i++) {
                if (strcmp(subsys, options.subsystem_name[i]) == 0) {
@@ -1706,11 +1532,12 @@ session_subsystem_req(Session *s)
                        s->is_subsystem = 1;
                        do_exec(s, cmd);
                        success = 1;
+                       break;
                }
        }
 
        if (!success)
-               log("subsystem request for %s failed, subsystem not found",
+               log("subsystem request for %.100s failed, subsystem not found",
                    subsys);
 
        xfree(subsys);
@@ -1726,7 +1553,7 @@ session_x11_req(Session *s)
        s->auth_proto = packet_get_string(NULL);
        s->auth_data = packet_get_string(NULL);
        s->screen = packet_get_int();
-       packet_done();
+       packet_check_eom();
 
        success = session_setup_x11fwd(s);
        if (!success) {
@@ -1741,7 +1568,7 @@ session_x11_req(Session *s)
 static int
 session_shell_req(Session *s)
 {
-       packet_done();
+       packet_check_eom();
        do_exec(s, NULL);
        return 1;
 }
@@ -1751,7 +1578,7 @@ session_exec_req(Session *s)
 {
        u_int len;
        char *command = packet_get_string(&len);
-       packet_done();
+       packet_check_eom();
        do_exec(s, command);
        xfree(command);
        return 1;
@@ -1761,7 +1588,7 @@ static int
 session_auth_agent_req(Session *s)
 {
        static int called = 0;
-       packet_done();
+       packet_check_eom();
        if (no_agent_forwarding_flag) {
                debug("session_auth_agent_req: no_agent_forwarding_flag");
                return 0;
@@ -1774,28 +1601,18 @@ session_auth_agent_req(Session *s)
        }
 }
 
-void
-session_input_channel_req(int id, void *arg)
+int
+session_input_channel_req(Channel *c, const char *rtype)
 {
-       u_int len;
-       int reply;
        int success = 0;
-       char *rtype;
        Session *s;
-       Channel *c;
 
-       rtype = packet_get_string(&len);
-       reply = packet_get_char();
-
-       s = session_by_channel(id);
-       if (s == NULL)
-               fatal("session_input_channel_req: channel %d: no session", id);
-       c = channel_lookup(id);
-       if (c == NULL)
-               fatal("session_input_channel_req: channel %d: bad channel", id);
-
-       debug("session_input_channel_req: session %d channel %d request %s reply %d",
-           s->self, id, rtype, reply);
+       if ((s = session_by_channel(c->self)) == NULL) {
+               log("session_input_channel_req: no session %d req %.100s",
+                   c->self, rtype);
+               return 0;
+       }
+       debug("session_input_channel_req: session %d req %s", s->self, rtype);
 
        /*
         * a session is in LARVAL state until a shell, a command
@@ -1819,14 +1636,7 @@ session_input_channel_req(int id, void *arg)
        if (strcmp(rtype, "window-change") == 0) {
                success = session_window_change_req(s);
        }
-
-       if (reply) {
-               packet_start(success ?
-                   SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
-               packet_put_int(c->remote_id);
-               packet_send();
-       }
-       xfree(rtype);
+       return success;
 }
 
 void
@@ -1843,7 +1653,8 @@ 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);
+           1,
+           CHAN_SES_WINDOW_DEFAULT);
 }
 
 /*
@@ -1866,7 +1677,7 @@ session_pty_cleanup(void *session)
 
        /* Record that the user has logged out. */
        if (s->pid != 0)
-               record_logout(s->pid, s->tty);
+               record_logout(s->pid, s->tty, s->pw->pw_name);
 
        /* Release the pseudo-tty. */
        pty_release(s->tty);
@@ -1887,23 +1698,19 @@ static void
 session_exit_message(Session *s, int status)
 {
        Channel *c;
-       if (s == NULL)
-               fatal("session_close: no session");
-       c = channel_lookup(s->chanid);
-       if (c == NULL)
+
+       if ((c = channel_lookup(s->chanid)) == NULL)
                fatal("session_exit_message: session %d: no channel %d",
                    s->self, s->chanid);
        debug("session_exit_message: session %d channel %d pid %d",
            s->self, s->chanid, s->pid);
 
        if (WIFEXITED(status)) {
-               channel_request_start(s->chanid,
-                   "exit-status", 0);
+               channel_request_start(s->chanid, "exit-status", 0);
                packet_put_int(WEXITSTATUS(status));
                packet_send();
        } else if (WIFSIGNALED(status)) {
-               channel_request_start(s->chanid,
-                   "exit-signal", 0);
+               channel_request_start(s->chanid, "exit-signal", 0);
                packet_put_int(WTERMSIG(status));
 #ifdef WCOREDUMP
                packet_put_char(WCOREDUMP(status));
@@ -1944,6 +1751,8 @@ session_close(Session *s)
                xfree(s->term);
        if (s->display)
                xfree(s->display);
+       if (s->auth_display)
+               xfree(s->auth_display);
        if (s->auth_data)
                xfree(s->auth_data);
        if (s->auth_proto)
@@ -2000,9 +1809,9 @@ void
 session_destroy_all(void)
 {
        int i;
-       for(i = 0; i < MAX_SESSIONS; i++) {
+       for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
-               if (s->used) 
+               if (s->used)
                        session_close(s);
        }
 }
@@ -2013,7 +1822,7 @@ session_tty_list(void)
        static char buf[1024];
        int i;
        buf[0] = '\0';
-       for(i = 0; i < MAX_SESSIONS; i++) {
+       for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                if (s->used && s->ttyfd != -1) {
                        if (buf[0] != '\0')
@@ -2039,6 +1848,8 @@ int
 session_setup_x11fwd(Session *s)
 {
        struct stat st;
+       char display[512], auth_display[512];
+       char hostname[MAXHOSTNAMELEN];
 
        if (no_x11_forwarding_flag) {
                packet_send_debug("X11 forwarding disabled in user configuration file.");
@@ -2062,11 +1873,50 @@ session_setup_x11fwd(Session *s)
                debug("X11 display already set.");
                return 0;
        }
-       s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
-       if (s->display == NULL) {
+       s->display_number = x11_create_display_inet(options.x11_display_offset,
+           options.x11_use_localhost, s->single_connection);
+       if (s->display_number == -1) {
                debug("x11_create_display_inet failed.");
                return 0;
        }
+
+       /* Set up a suitable value for the DISPLAY variable. */
+       if (gethostname(hostname, sizeof(hostname)) < 0)
+               fatal("gethostname: %.100s", strerror(errno));
+       /*
+        * auth_display must be used as the displayname when the
+        * authorization entry is added with xauth(1).  This will be
+        * different than the DISPLAY string for localhost displays.
+        */
+       if (options.x11_use_localhost) {
+               snprintf(display, sizeof display, "localhost:%d.%d",
+                   s->display_number, s->screen);
+               snprintf(auth_display, sizeof auth_display, "unix:%d.%d",
+                   s->display_number, s->screen);
+               s->display = xstrdup(display);
+               s->auth_display = xstrdup(auth_display);
+       } else {
+#ifdef IPADDR_IN_DISPLAY
+               struct hostent *he;
+               struct in_addr my_addr;
+
+               he = gethostbyname(hostname);
+               if (he == NULL) {
+                       error("Can't get IP address for X11 DISPLAY.");
+                       packet_send_debug("Can't get IP address for X11 DISPLAY.");
+                       return 0;
+               }
+               memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
+               snprintf(display, sizeof display, "%.50s:%d.%d", inet_ntoa(my_addr),
+                   s->display_number, s->screen);
+#else
+               snprintf(display, sizeof display, "%.400s:%d.%d", hostname,
+                   s->display_number, s->screen);
+#endif
+               s->display = xstrdup(display);
+               s->auth_display = xstrdup(display);
+       }
+
        return 1;
 }
 
index 6d5b8e69922dd89bcee8e7c644b77d4c9d1ad90a..ec8284a5f68faf73b3ba8d72cbc42a125bb20ec5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: session.h,v 1.13 2001/10/10 22:18:47 markus Exp $     */
+/*     $OpenBSD: session.h,v 1.14 2002/02/03 17:53:25 markus Exp $     */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -29,7 +29,7 @@
 void    do_authenticated(Authctxt *);
 
 int     session_open(Authctxt*, int);
-void    session_input_channel_req(int, void *);
+int     session_input_channel_req(Channel *, const char *);
 void    session_close_by_pid(pid_t, int);
 void    session_close_by_channel(int, void *);
 void    session_destroy_all(void);
index 4f2a1e2800840406be251e3554126e1235b732f3..17ac14a95e31c8dfe104ec5d6e53106a732ec27f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 /* XXX: memleaks */
 /* XXX: signed vs unsigned */
-/* XXX: redesign to allow concurrent overlapped operations */
-/* XXX: we use fatal too much, error may be more appropriate in places */
+/* XXX: remove all logging, only return status codes */
 /* XXX: copy between two remote sites */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.18 2001/07/14 15:10:16 stevesk Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.24 2002/02/24 16:57:19 markus Exp $");
+
+#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
+#include <sys/queue.h>
+#else
+#include "openbsd-compat/fake-queue.h"
+#endif
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -42,12 +47,17 @@ RCSID("$OpenBSD: sftp-client.c,v 1.18 2001/07/14 15:10:16 stevesk Exp $");
 #include "sftp-common.h"
 #include "sftp-client.h"
 
-/* How much data to read/write at at time during copies */
-/* XXX: what should this be? */
-#define COPY_SIZE      8192
+/* Minimum amount of data to read at at time */
+#define MIN_READ_SIZE  512
 
-/* Message ID */
-static u_int msg_id = 1;
+struct sftp_conn {
+       int fd_in;
+       int fd_out;
+       u_int transfer_buflen;
+       u_int num_requests;
+       u_int version;
+       u_int msg_id;
+};
 
 static void
 send_msg(int fd, Buffer *m)
@@ -215,11 +225,12 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
        return(a);
 }
 
-int
-do_init(int fd_in, int fd_out)
+struct sftp_conn *
+do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
 {
        int type, version;
        Buffer msg;
+       struct sftp_conn *ret;
 
        buffer_init(&msg);
        buffer_put_char(&msg, SSH2_FXP_INIT);
@@ -235,7 +246,7 @@ do_init(int fd_in, int fd_out)
                error("Invalid packet back from SSH2_FXP_INIT (type %d)",
                    type);
                buffer_free(&msg);
-               return(-1);
+               return(NULL);
        }
        version = buffer_get_int(&msg);
 
@@ -253,25 +264,43 @@ do_init(int fd_in, int fd_out)
 
        buffer_free(&msg);
 
-       return(version);
+       ret = xmalloc(sizeof(*ret));
+       ret->fd_in = fd_in;
+       ret->fd_out = fd_out;
+       ret->transfer_buflen = transfer_buflen;
+       ret->num_requests = num_requests;
+       ret->version = version;
+       ret->msg_id = 1;
+
+       /* Some filexfer v.0 servers don't support large packets */
+       if (version == 0)
+               ret->transfer_buflen = MAX(ret->transfer_buflen, 20480);
+
+       return(ret);
+}
+
+u_int
+sftp_proto_version(struct sftp_conn *conn)
+{
+       return(conn->version);
 }
 
 int
-do_close(int fd_in, int fd_out, char *handle, u_int handle_len)
+do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
 {
        u_int id, status;
        Buffer msg;
 
        buffer_init(&msg);
 
-       id = msg_id++;
+       id = conn->msg_id++;
        buffer_put_char(&msg, SSH2_FXP_CLOSE);
        buffer_put_int(&msg, id);
        buffer_put_string(&msg, handle, handle_len);
-       send_msg(fd_out, &msg);
+       send_msg(conn->fd_out, &msg);
        debug3("Sent message SSH2_FXP_CLOSE I:%d", id);
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
                error("Couldn't close file: %s", fx2txt(status));
 
@@ -282,24 +311,24 @@ do_close(int fd_in, int fd_out, char *handle, u_int handle_len)
 
 
 static int
-do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
+do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
     SFTP_DIRENT ***dir)
 {
        Buffer msg;
        u_int type, id, handle_len, i, expected_id, ents = 0;
        char *handle;
 
-       id = msg_id++;
+       id = conn->msg_id++;
 
        buffer_init(&msg);
        buffer_put_char(&msg, SSH2_FXP_OPENDIR);
        buffer_put_int(&msg, id);
        buffer_put_cstring(&msg, path);
-       send_msg(fd_out, &msg);
+       send_msg(conn->fd_out, &msg);
 
        buffer_clear(&msg);
 
-       handle = get_handle(fd_in, id, &handle_len);
+       handle = get_handle(conn->fd_in, id, &handle_len);
        if (handle == NULL)
                return(-1);
 
@@ -308,12 +337,11 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
                *dir = xmalloc(sizeof(**dir));
                (*dir)[0] = NULL;
        }
-       
 
-       for(;;) {
+       for (;;) {
                int count;
 
-               id = expected_id = msg_id++;
+               id = expected_id = conn->msg_id++;
 
                debug3("Sending SSH2_FXP_READDIR I:%d", id);
 
@@ -321,11 +349,11 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
                buffer_put_char(&msg, SSH2_FXP_READDIR);
                buffer_put_int(&msg, id);
                buffer_put_string(&msg, handle, handle_len);
-               send_msg(fd_out, &msg);
+               send_msg(conn->fd_out, &msg);
 
                buffer_clear(&msg);
 
-               get_msg(fd_in, &msg);
+               get_msg(conn->fd_in, &msg);
 
                type = buffer_get_char(&msg);
                id = buffer_get_int(&msg);
@@ -345,7 +373,7 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
                        } else {
                                error("Couldn't read directory: %s",
                                    fx2txt(status));
-                               do_close(fd_in, fd_out, handle, handle_len);
+                               do_close(conn, handle, handle_len);
                                return(status);
                        }
                } else if (type != SSH2_FXP_NAME)
@@ -356,7 +384,7 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
                if (count == 0)
                        break;
                debug3("Received %d SSH2_FXP_NAME responses", count);
-               for(i = 0; i < count; i++) {
+               for (i = 0; i < count; i++) {
                        char *filename, *longname;
                        Attrib *a;
 
@@ -383,29 +411,29 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
        }
 
        buffer_free(&msg);
-       do_close(fd_in, fd_out, handle, handle_len);
+       do_close(conn, handle, handle_len);
        xfree(handle);
 
        return(0);
 }
 
 int
-do_ls(int fd_in, int fd_out, char *path)
+do_ls(struct sftp_conn *conn, char *path)
 {
-       return(do_lsreaddir(fd_in, fd_out, path, 1, NULL));
+       return(do_lsreaddir(conn, path, 1, NULL));
 }
 
 int
-do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir)
+do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir)
 {
-       return(do_lsreaddir(fd_in, fd_out, path, 0, dir));
+       return(do_lsreaddir(conn, path, 0, dir));
 }
 
 void free_sftp_dirents(SFTP_DIRENT **s)
 {
        int i;
-       
-       for(i = 0; s[i]; i++) {
+
+       for (i = 0; s[i]; i++) {
                xfree(s[i]->filename);
                xfree(s[i]->longname);
                xfree(s[i]);
@@ -414,30 +442,31 @@ void free_sftp_dirents(SFTP_DIRENT **s)
 }
 
 int
-do_rm(int fd_in, int fd_out, char *path)
+do_rm(struct sftp_conn *conn, char *path)
 {
        u_int status, id;
 
        debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
 
-       id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_REMOVE, path, strlen(path));
-       status = get_status(fd_in, id);
+       id = conn->msg_id++;
+       send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path, 
+           strlen(path));
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
                error("Couldn't delete file: %s", fx2txt(status));
        return(status);
 }
 
 int
-do_mkdir(int fd_in, int fd_out, char *path, Attrib *a)
+do_mkdir(struct sftp_conn *conn, char *path, Attrib *a)
 {
        u_int status, id;
 
-       id = msg_id++;
-       send_string_attrs_request(fd_out, id, SSH2_FXP_MKDIR, path,
+       id = conn->msg_id++;
+       send_string_attrs_request(conn->fd_out, id, SSH2_FXP_MKDIR, path,
            strlen(path), a);
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
                error("Couldn't create directory: %s", fx2txt(status));
 
@@ -445,14 +474,15 @@ do_mkdir(int fd_in, int fd_out, char *path, Attrib *a)
 }
 
 int
-do_rmdir(int fd_in, int fd_out, char *path)
+do_rmdir(struct sftp_conn *conn, char *path)
 {
        u_int status, id;
 
-       id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_RMDIR, path, strlen(path));
+       id = conn->msg_id++;
+       send_string_request(conn->fd_out, id, SSH2_FXP_RMDIR, path,
+           strlen(path));
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
                error("Couldn't remove directory: %s", fx2txt(status));
 
@@ -460,45 +490,61 @@ do_rmdir(int fd_in, int fd_out, char *path)
 }
 
 Attrib *
-do_stat(int fd_in, int fd_out, char *path, int quiet)
+do_stat(struct sftp_conn *conn, char *path, int quiet)
 {
        u_int id;
 
-       id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path));
-       return(get_decode_stat(fd_in, id, quiet));
+       id = conn->msg_id++;
+
+       send_string_request(conn->fd_out, id, 
+           conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT, 
+           path, strlen(path));
+
+       return(get_decode_stat(conn->fd_in, id, quiet));
 }
 
 Attrib *
-do_lstat(int fd_in, int fd_out, char *path, int quiet)
+do_lstat(struct sftp_conn *conn, char *path, int quiet)
 {
        u_int id;
 
-       id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path));
-       return(get_decode_stat(fd_in, id, quiet));
+       if (conn->version == 0) {
+               if (quiet)
+                       debug("Server version does not support lstat operation");
+               else
+                       error("Server version does not support lstat operation");
+               return(NULL);
+       }
+
+       id = conn->msg_id++;
+       send_string_request(conn->fd_out, id, SSH2_FXP_LSTAT, path,
+           strlen(path));
+
+       return(get_decode_stat(conn->fd_in, id, quiet));
 }
 
 Attrib *
-do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, int quiet)
+do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
 {
        u_int id;
 
-       id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len);
-       return(get_decode_stat(fd_in, id, quiet));
+       id = conn->msg_id++;
+       send_string_request(conn->fd_out, id, SSH2_FXP_FSTAT, handle,
+           handle_len);
+
+       return(get_decode_stat(conn->fd_in, id, quiet));
 }
 
 int
-do_setstat(int fd_in, int fd_out, char *path, Attrib *a)
+do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
 {
        u_int status, id;
 
-       id = msg_id++;
-       send_string_attrs_request(fd_out, id, SSH2_FXP_SETSTAT, path,
+       id = conn->msg_id++;
+       send_string_attrs_request(conn->fd_out, id, SSH2_FXP_SETSTAT, path,
            strlen(path), a);
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
                error("Couldn't setstat on \"%s\": %s", path,
                    fx2txt(status));
@@ -507,16 +553,16 @@ do_setstat(int fd_in, int fd_out, char *path, Attrib *a)
 }
 
 int
-do_fsetstat(int fd_in, int fd_out, char *handle, u_int handle_len,
+do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len,
     Attrib *a)
 {
        u_int status, id;
 
-       id = msg_id++;
-       send_string_attrs_request(fd_out, id, SSH2_FXP_FSETSTAT, handle,
+       id = conn->msg_id++;
+       send_string_attrs_request(conn->fd_out, id, SSH2_FXP_FSETSTAT, handle,
            handle_len, a);
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
                error("Couldn't fsetstat: %s", fx2txt(status));
 
@@ -524,19 +570,20 @@ do_fsetstat(int fd_in, int fd_out, char *handle, u_int handle_len,
 }
 
 char *
-do_realpath(int fd_in, int fd_out, char *path)
+do_realpath(struct sftp_conn *conn, char *path)
 {
        Buffer msg;
        u_int type, expected_id, count, id;
        char *filename, *longname;
        Attrib *a;
 
-       expected_id = id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_REALPATH, path, strlen(path));
+       expected_id = id = conn->msg_id++;
+       send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path,
+           strlen(path));
 
        buffer_init(&msg);
 
-       get_msg(fd_in, &msg);
+       get_msg(conn->fd_in, &msg);
        type = buffer_get_char(&msg);
        id = buffer_get_int(&msg);
 
@@ -570,7 +617,7 @@ do_realpath(int fd_in, int fd_out, char *path)
 }
 
 int
-do_rename(int fd_in, int fd_out, char *oldpath, char *newpath)
+do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
 {
        Buffer msg;
        u_int status, id;
@@ -578,65 +625,71 @@ do_rename(int fd_in, int fd_out, char *oldpath, char *newpath)
        buffer_init(&msg);
 
        /* Send rename request */
-       id = msg_id++;
+       id = conn->msg_id++;
        buffer_put_char(&msg, SSH2_FXP_RENAME);
        buffer_put_int(&msg, id);
        buffer_put_cstring(&msg, oldpath);
        buffer_put_cstring(&msg, newpath);
-       send_msg(fd_out, &msg);
+       send_msg(conn->fd_out, &msg);
        debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath,
            newpath);
        buffer_free(&msg);
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
-               error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath,
-                   fx2txt(status));
+               error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
+                   newpath, fx2txt(status));
 
        return(status);
 }
 
 int
-do_symlink(int fd_in, int fd_out, char *oldpath, char *newpath)
+do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
 {
        Buffer msg;
        u_int status, id;
 
+       if (conn->version < 3) {
+               error("This server does not support the symlink operation");
+               return(SSH2_FX_OP_UNSUPPORTED);
+       }
+
        buffer_init(&msg);
 
        /* Send rename request */
-       id = msg_id++;
+       id = conn->msg_id++;
        buffer_put_char(&msg, SSH2_FXP_SYMLINK);
        buffer_put_int(&msg, id);
        buffer_put_cstring(&msg, oldpath);
        buffer_put_cstring(&msg, newpath);
-       send_msg(fd_out, &msg);
+       send_msg(conn->fd_out, &msg);
        debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
            newpath);
        buffer_free(&msg);
 
-       status = get_status(fd_in, id);
+       status = get_status(conn->fd_in, id);
        if (status != SSH2_FX_OK)
-               error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath,
-                   fx2txt(status));
+               error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
+                   newpath, fx2txt(status));
 
        return(status);
 }
 
 char *
-do_readlink(int fd_in, int fd_out, char *path)
+do_readlink(struct sftp_conn *conn, char *path)
 {
        Buffer msg;
        u_int type, expected_id, count, id;
        char *filename, *longname;
        Attrib *a;
 
-       expected_id = id = msg_id++;
-       send_string_request(fd_out, id, SSH2_FXP_READLINK, path, strlen(path));
+       expected_id = id = conn->msg_id++;
+       send_string_request(conn->fd_out, id, SSH2_FXP_READLINK, path,
+           strlen(path));
 
        buffer_init(&msg);
 
-       get_msg(fd_in, &msg);
+       get_msg(conn->fd_in, &msg);
        type = buffer_get_char(&msg);
        id = buffer_get_int(&msg);
 
@@ -669,19 +722,46 @@ do_readlink(int fd_in, int fd_out, char *path)
        return(filename);
 }
 
+static void
+send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
+    char *handle, u_int handle_len)
+{
+       Buffer msg;
+       
+       buffer_init(&msg);
+       buffer_clear(&msg);
+       buffer_put_char(&msg, SSH2_FXP_READ);
+       buffer_put_int(&msg, id);
+       buffer_put_string(&msg, handle, handle_len);
+       buffer_put_int64(&msg, offset);
+       buffer_put_int(&msg, len);
+       send_msg(fd_out, &msg);
+       buffer_free(&msg);
+}      
+
 int
-do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
+do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
     int pflag)
 {
-       int local_fd;
-       u_int expected_id, handle_len, mode, type, id;
-       u_int64_t offset;
-       char *handle;
-       Buffer msg;
        Attrib junk, *a;
-       int status;
+       Buffer msg;
+       char *handle;
+       int local_fd, status, num_req, max_req, write_error;
+       int read_error, write_errno;
+       u_int64_t offset, size;
+       u_int handle_len, mode, type, id, buflen;
+       struct request {
+               u_int id;
+               u_int len;
+               u_int64_t offset;
+               TAILQ_ENTRY(request) tq; 
+       };
+       TAILQ_HEAD(reqhead, request) requests;
+       struct request *req;
 
-       a = do_stat(fd_in, fd_out, remote_path, 0);
+       TAILQ_INIT(&requests);
+
+       a = do_stat(conn, remote_path, 0);
        if (a == NULL)
                return(-1);
 
@@ -697,134 +777,203 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
                return(-1);
        }
 
-       local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
-       if (local_fd == -1) {
-               error("Couldn't open local file \"%s\" for writing: %s",
-                   local_path, strerror(errno));
-               return(-1);
-       }
+       if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
+               size = a->size;
+       else
+               size = 0;
 
+       buflen = conn->transfer_buflen;
        buffer_init(&msg);
 
        /* Send open request */
-       id = msg_id++;
+       id = conn->msg_id++;
        buffer_put_char(&msg, SSH2_FXP_OPEN);
        buffer_put_int(&msg, id);
        buffer_put_cstring(&msg, remote_path);
        buffer_put_int(&msg, SSH2_FXF_READ);
        attrib_clear(&junk); /* Send empty attributes */
        encode_attrib(&msg, &junk);
-       send_msg(fd_out, &msg);
+       send_msg(conn->fd_out, &msg);
        debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
 
-       handle = get_handle(fd_in, id, &handle_len);
+       handle = get_handle(conn->fd_in, id, &handle_len);
        if (handle == NULL) {
                buffer_free(&msg);
-               close(local_fd);
+               return(-1);
+       }
+
+       local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+       if (local_fd == -1) {
+               error("Couldn't open local file \"%s\" for writing: %s",
+                   local_path, strerror(errno));
+               buffer_free(&msg);
+               xfree(handle);
                return(-1);
        }
 
        /* Read from remote and write to local */
-       offset = 0;
-       for(;;) {
-               u_int len;
+       write_error = read_error = write_errno = num_req = offset = 0;
+       max_req = 1;
+       while (num_req > 0 || max_req > 0) {
                char *data;
+               u_int len;
 
-               id = expected_id = msg_id++;
-
-               buffer_clear(&msg);
-               buffer_put_char(&msg, SSH2_FXP_READ);
-               buffer_put_int(&msg, id);
-               buffer_put_string(&msg, handle, handle_len);
-               buffer_put_int64(&msg, offset);
-               buffer_put_int(&msg, COPY_SIZE);
-               send_msg(fd_out, &msg);
-               debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u",
-                   id, (u_int64_t)offset, COPY_SIZE);
+               /* Send some more requests */
+               while (num_req < max_req) {
+                       debug3("Request range %llu -> %llu (%d/%d)", 
+                           offset, offset + buflen - 1, num_req, max_req);
+                       req = xmalloc(sizeof(*req));
+                       req->id = conn->msg_id++;
+                       req->len = buflen;
+                       req->offset = offset;
+                       offset += buflen;
+                       num_req++;
+                       TAILQ_INSERT_TAIL(&requests, req, tq);
+                       send_read_request(conn->fd_out, req->id, req->offset, 
+                           req->len, handle, handle_len);
+               }
 
                buffer_clear(&msg);
-
-               get_msg(fd_in, &msg);
+               get_msg(conn->fd_in, &msg);
                type = buffer_get_char(&msg);
                id = buffer_get_int(&msg);
-               debug3("Received reply T:%d I:%d", type, id);
-               if (id != expected_id)
-                       fatal("ID mismatch (%d != %d)", id, expected_id);
-               if (type == SSH2_FXP_STATUS) {
+               debug3("Received reply T:%d I:%d R:%d", type, id, max_req);
+
+               /* Find the request in our queue */
+               for(req = TAILQ_FIRST(&requests);
+                   req != NULL && req->id != id;
+                   req = TAILQ_NEXT(req, tq))
+                       ;
+               if (req == NULL)
+                       fatal("Unexpected reply %u", id);
+
+               switch (type) {
+               case SSH2_FXP_STATUS:
                        status = buffer_get_int(&msg);
+                       if (status != SSH2_FX_EOF)
+                               read_error = 1;
+                       max_req = 0;
+                       TAILQ_REMOVE(&requests, req, tq);
+                       xfree(req);
+                       num_req--;
+                       break;
+               case SSH2_FXP_DATA:
+                       data = buffer_get_string(&msg, &len);
+                       debug3("Received data %llu -> %llu", req->offset, 
+                           req->offset + len - 1);
+                       if (len > req->len)
+                               fatal("Received more data than asked for "
+                                     "%d > %d", len, req->len);
+                       if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
+                            atomicio(write, local_fd, data, len) != len) &&
+                           !write_error) {
+                               write_errno = errno;
+                               write_error = 1;
+                               max_req = 0;
+                       }
+                       xfree(data);
 
-                       if (status == SSH2_FX_EOF)
-                               break;
-                       else {
-                               error("Couldn't read from remote "
-                                   "file \"%s\" : %s", remote_path,
-                                    fx2txt(status));
-                               do_close(fd_in, fd_out, handle, handle_len);
-                               goto done;
+                       if (len == req->len) {
+                               TAILQ_REMOVE(&requests, req, tq);
+                               xfree(req);
+                               num_req--;
+                       } else {
+                               /* Resend the request for the missing data */
+                               debug3("Short data block, re-requesting "
+                                   "%llu -> %llu (%2d)", req->offset + len, 
+                                       req->offset + req->len - 1, num_req);
+                               req->id = conn->msg_id++;
+                               req->len -= len;
+                               req->offset += len;
+                               send_read_request(conn->fd_out, req->id, 
+                                   req->offset, req->len, handle, handle_len);
+                               /* Reduce the request size */
+                               if (len < buflen)
+                                       buflen = MAX(MIN_READ_SIZE, len);
                        }
-               } else if (type != SSH2_FXP_DATA) {
+                       if (max_req > 0) { /* max_req = 0 iff EOF received */
+                               if (size > 0 && offset > size) {
+                                       /* Only one request at a time
+                                        * after the expected EOF */
+                                       debug3("Finish at %llu (%2d)",
+                                           offset, num_req);
+                                       max_req = 1;
+                               }
+                               else if (max_req < conn->num_requests + 1) {
+                                       ++max_req;
+                               }
+                       }
+                       break;
+               default:
                        fatal("Expected SSH2_FXP_DATA(%d) packet, got %d",
                            SSH2_FXP_DATA, type);
                }
-
-               data = buffer_get_string(&msg, &len);
-               if (len > COPY_SIZE)
-                       fatal("Received more data than asked for %d > %d",
-                           len, COPY_SIZE);
-
-               debug3("In read loop, got %d offset %llu", len,
-                   (u_int64_t)offset);
-               if (atomicio(write, local_fd, data, len) != len) {
-                       error("Couldn't write to \"%s\": %s", local_path,
-                           strerror(errno));
-                       do_close(fd_in, fd_out, handle, handle_len);
-                       status = -1;
-                       xfree(data);
-                       goto done;
-               }
-
-               offset += len;
-               xfree(data);
        }
-       status = do_close(fd_in, fd_out, handle, handle_len);
 
-       /* Override umask and utimes if asked */
+       /* Sanity check */
+       if (TAILQ_FIRST(&requests) != NULL)
+               fatal("Transfer complete, but requests still in queue");
+
+       if (read_error) {
+               error("Couldn't read from remote file \"%s\" : %s", 
+                   remote_path, fx2txt(status));
+               do_close(conn, handle, handle_len);
+       } else if (write_error) {
+               error("Couldn't write to \"%s\": %s", local_path,
+                   strerror(write_errno));
+               status = -1;
+               do_close(conn, handle, handle_len);
+       } else {
+               status = do_close(conn, handle, handle_len);
+
+               /* Override umask and utimes if asked */
 #ifdef HAVE_FCHMOD
-       if (pflag && fchmod(local_fd, mode) == -1)
+               if (pflag && fchmod(local_fd, mode) == -1)
 #else 
-       if (pflag && chmod(local_path, mode) == -1)
+               if (pflag && chmod(local_path, mode) == -1)
 #endif /* HAVE_FCHMOD */
-               error("Couldn't set mode on \"%s\": %s", local_path,
-                   strerror(errno));
-       if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
-               struct timeval tv[2];
-               tv[0].tv_sec = a->atime;
-               tv[1].tv_sec = a->mtime;
-               tv[0].tv_usec = tv[1].tv_usec = 0;
-               if (utimes(local_path, tv) == -1)
-                       error("Can't set times on \"%s\": %s", local_path,
-                           strerror(errno));
+                       error("Couldn't set mode on \"%s\": %s", local_path,
+                             strerror(errno));
+               if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
+                       struct timeval tv[2];
+                       tv[0].tv_sec = a->atime;
+                       tv[1].tv_sec = a->mtime;
+                       tv[0].tv_usec = tv[1].tv_usec = 0;
+                       if (utimes(local_path, tv) == -1)
+                               error("Can't set times on \"%s\": %s",
+                                     local_path, strerror(errno));
+               }
        }
-
-done:
        close(local_fd);
        buffer_free(&msg);
        xfree(handle);
-       return status;
+
+       return(status);
 }
 
 int
-do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
+do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
     int pflag)
 {
-       int local_fd;
-       u_int handle_len, id;
+       int local_fd, status;
+       u_int handle_len, id, type;
        u_int64_t offset;
-       char *handle;
+       char *handle, *data;
        Buffer msg;
        struct stat sb;
        Attrib a;
-       int status;
+       u_int32_t startid;
+       u_int32_t ackid;
+       struct outstanding_ack {
+               u_int id;
+               u_int len;
+               u_int64_t offset;
+               TAILQ_ENTRY(outstanding_ack) tq; 
+       };
+       TAILQ_HEAD(ackhead, outstanding_ack) acks;
+       struct outstanding_ack *ack;
+
+       TAILQ_INIT(&acks);
 
        if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
                error("Couldn't open local file \"%s\" for reading: %s",
@@ -848,85 +997,121 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
        buffer_init(&msg);
 
        /* Send open request */
-       id = msg_id++;
+       id = conn->msg_id++;
        buffer_put_char(&msg, SSH2_FXP_OPEN);
        buffer_put_int(&msg, id);
        buffer_put_cstring(&msg, remote_path);
        buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC);
        encode_attrib(&msg, &a);
-       send_msg(fd_out, &msg);
+       send_msg(conn->fd_out, &msg);
        debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
 
        buffer_clear(&msg);
 
-       handle = get_handle(fd_in, id, &handle_len);
+       handle = get_handle(conn->fd_in, id, &handle_len);
        if (handle == NULL) {
                close(local_fd);
                buffer_free(&msg);
                return(-1);
        }
 
+       startid = ackid = id + 1;
+       data = xmalloc(conn->transfer_buflen);
+
        /* Read from local and write to remote */
        offset = 0;
-       for(;;) {
+       for (;;) {
                int len;
-               char data[COPY_SIZE];
 
                /*
                 * Can't use atomicio here because it returns 0 on EOF, thus losing
                 * the last block of the file
                 */
                do
-                       len = read(local_fd, data, COPY_SIZE);
+                       len = read(local_fd, data, conn->transfer_buflen);
                while ((len == -1) && (errno == EINTR || errno == EAGAIN));
 
                if (len == -1)
                        fatal("Couldn't read from \"%s\": %s", local_path,
                            strerror(errno));
-               if (len == 0)
+
+               if (len != 0) {
+                       ack = xmalloc(sizeof(*ack));
+                       ack->id = ++id;
+                       ack->offset = offset;
+                       ack->len = len;
+                       TAILQ_INSERT_TAIL(&acks, ack, tq);
+
+                       buffer_clear(&msg);
+                       buffer_put_char(&msg, SSH2_FXP_WRITE);
+                       buffer_put_int(&msg, ack->id);
+                       buffer_put_string(&msg, handle, handle_len);
+                       buffer_put_int64(&msg, offset);
+                       buffer_put_string(&msg, data, len);
+                       send_msg(conn->fd_out, &msg);
+                       debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
+                              id, (u_int64_t)offset, len);
+               } else if (TAILQ_FIRST(&acks) == NULL)
                        break;
 
-               buffer_clear(&msg);
-               buffer_put_char(&msg, SSH2_FXP_WRITE);
-               buffer_put_int(&msg, ++id);
-               buffer_put_string(&msg, handle, handle_len);
-               buffer_put_int64(&msg, offset);
-               buffer_put_string(&msg, data, len);
-               send_msg(fd_out, &msg);
-               debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
-                   id, (u_int64_t)offset, len);
-
-               status = get_status(fd_in, id);
-               if (status != SSH2_FX_OK) {
-                       error("Couldn't write to remote file \"%s\": %s",
-                           remote_path, fx2txt(status));
-                       do_close(fd_in, fd_out, handle, handle_len);
-                       close(local_fd);
-                       goto done;
-               }
-               debug3("In write loop, got %d offset %llu", len,
-                   (u_int64_t)offset);
+               if (ack == NULL)
+                       fatal("Unexpected ACK %u", id);
+
+               if (id == startid || len == 0 || 
+                   id - ackid >= conn->num_requests) {
+                       buffer_clear(&msg);
+                       get_msg(conn->fd_in, &msg);
+                       type = buffer_get_char(&msg);
+                       id = buffer_get_int(&msg);
 
+                       if (type != SSH2_FXP_STATUS)
+                               fatal("Expected SSH2_FXP_STATUS(%d) packet, "
+                                   "got %d", SSH2_FXP_STATUS, type);
+
+                       status = buffer_get_int(&msg);
+                       debug3("SSH2_FXP_STATUS %d", status);
+
+                       /* Find the request in our queue */
+                       for(ack = TAILQ_FIRST(&acks);
+                           ack != NULL && ack->id != id;
+                           ack = TAILQ_NEXT(ack, tq))
+                               ;
+                       if (ack == NULL)
+                               fatal("Can't find request for ID %d", id);
+                       TAILQ_REMOVE(&acks, ack, tq);
+
+                       if (status != SSH2_FX_OK) {
+                               error("Couldn't write to remote file \"%s\": %s",
+                                     remote_path, fx2txt(status));
+                               do_close(conn, handle, handle_len);
+                               close(local_fd);
+                               goto done;
+                       }
+                       debug3("In write loop, ack for %u %d bytes at %llu", 
+                          ack->id, ack->len, ack->offset);
+                       ++ackid;
+                       free(ack);
+               }
                offset += len;
        }
+       xfree(data);
 
        if (close(local_fd) == -1) {
                error("Couldn't close local file \"%s\": %s", local_path,
                    strerror(errno));
-               do_close(fd_in, fd_out, handle, handle_len);
+               do_close(conn, handle, handle_len);
                status = -1;
                goto done;
        }
 
        /* Override umask and utimes if asked */
        if (pflag)
-               do_fsetstat(fd_in, fd_out, handle, handle_len, &a);
+               do_fsetstat(conn, handle, handle_len, &a);
 
-       status = do_close(fd_in, fd_out, handle, handle_len);
+       status = do_close(conn, handle, handle_len);
 
 done:
        xfree(handle);
        buffer_free(&msg);
-       return status;
+       return(status);
 }
-
index a322b2571088be602b9262b2b1029b58c01d75bd..ceda879b9283968023a060e94bb2de55e1fdccc5 100644 (file)
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-client.h,v 1.6 2001/06/26 06:33:01 itojun Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.9 2002/02/13 00:59:23 djm Exp $ */
 
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,6 +26,9 @@
 
 /* Client side of SSH2 filexfer protocol */
 
+#ifndef _SFTP_CLIENT_H
+#define _SFTP_CLIENT_H
+
 typedef struct SFTP_DIRENT SFTP_DIRENT;
 
 struct SFTP_DIRENT {
@@ -38,55 +41,59 @@ struct SFTP_DIRENT {
  * Initialiase a SSH filexfer connection. Returns -1 on error or
  * protocol version on success.
  */
-int do_init(int, int);
+struct sftp_conn *
+do_init(int, int, u_int, u_int);
+
+u_int
+sftp_proto_version(struct sftp_conn *);
 
 /* Close file referred to by 'handle' */
-int do_close(int, int, char *, u_int);
+int do_close(struct sftp_conn *, char *, u_int);
 
 /* List contents of directory 'path' to stdout */
-int do_ls(int, int, char *);
+int do_ls(struct sftp_conn *, char *);
 
 /* Read contents of 'path' to NULL-terminated array 'dir' */
-int do_readdir(int, int, char *, SFTP_DIRENT ***);
+int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***);
 
 /* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
 void free_sftp_dirents(SFTP_DIRENT **);
 
 /* Delete file 'path' */
-int do_rm(int, int, char *);
+int do_rm(struct sftp_conn *, char *);
 
 /* Create directory 'path' */
-int do_mkdir(int, int, char *, Attrib *);
+int do_mkdir(struct sftp_conn *, char *, Attrib *);
 
 /* Remove directory 'path' */
-int do_rmdir(int, int, char *);
+int do_rmdir(struct sftp_conn *, char *);
 
 /* Get file attributes of 'path' (follows symlinks) */
-Attrib *do_stat(int, int, char *, int);
+Attrib *do_stat(struct sftp_conn *, char *, int);
 
 /* Get file attributes of 'path' (does not follow symlinks) */
-Attrib *do_lstat(int, int, char *, int);
+Attrib *do_lstat(struct sftp_conn *, char *, int);
 
 /* Get file attributes of open file 'handle' */
-Attrib *do_fstat(int, int, char *, u_int, int);
+Attrib *do_fstat(struct sftp_conn *, char *, u_int, int);
 
 /* Set file attributes of 'path' */
-int do_setstat(int, int, char *, Attrib *);
+int do_setstat(struct sftp_conn *, char *, Attrib *);
 
 /* Set file attributes of open file 'handle' */
-int do_fsetstat(int, int, char *, u_int, Attrib *);
+int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *);
 
 /* Canonicalise 'path' - caller must free result */
-char *do_realpath(int, int, char *);
+char *do_realpath(struct sftp_conn *, char *);
 
 /* Rename 'oldpath' to 'newpath' */
-int do_rename(int, int, char *, char *);
+int do_rename(struct sftp_conn *, char *, char *);
 
 /* Rename 'oldpath' to 'newpath' */
-int do_symlink(int, int, char *, char *);
+int do_symlink(struct sftp_conn *, char *, char *);
 
 /* Return target of symlink 'path' - caller must free result */
-char *do_readlink(int, int, char *);
+char *do_readlink(struct sftp_conn *, char *);
 
 /* XXX: add callbacks to do_download/do_upload so we can do progress meter */
 
@@ -94,10 +101,12 @@ char *do_readlink(int, int, char *);
  * Download 'remote_path' to 'local_path'. Preserve permissions and times
  * if 'pflag' is set
  */
-int do_download(int, int, char *, char *, int);
+int do_download(struct sftp_conn *, char *, char *, int);
 
 /*
  * Upload 'local_path' to 'remote_path'. Preserve permissions and times
  * if 'pflag' is set
  */
-int do_upload(int, int, char *, char *, int);
+int do_upload(struct sftp_conn *, char *, char *, int);
+
+#endif
index 92350481133442e55d9ae831e054675fe4b16fbd..4fb4496555cebfc9ac3f90c498d7602e98b9bf45 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-common.c,v 1.4 2001/07/14 15:10:17 stevesk Exp $");
+RCSID("$OpenBSD: sftp-common.c,v 1.5 2001/12/02 02:08:32 deraadt Exp $");
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -144,6 +144,6 @@ fx2txt(int status)
                return("Operation unsupported");
        default:
                return("Unknown status");
-       };
+       }
        /* NOTREACHED */
 }
index a432bdfc2f986d6bc60aa678d9ebe3814404f1bd..1234074c45ccc0d3f076cb0f5452517a2eef8d63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-glob.c,v 1.8 2001/07/14 15:10:17 stevesk Exp $");
+RCSID("$OpenBSD: sftp-glob.c,v 1.10 2002/02/13 00:59:23 djm Exp $");
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -41,18 +41,17 @@ struct SFTP_OPENDIR {
 };
 
 static struct {
-       int fd_in;
-       int fd_out;
+       struct sftp_conn *conn;
 } cur;
 
 static void *
 fudge_opendir(const char *path)
 {
        struct SFTP_OPENDIR *r;
-       
+
        r = xmalloc(sizeof(*r));
-       
-       if (do_readdir(cur.fd_in, cur.fd_out, (char*)path, &r->dir))
+
+       if (do_readdir(cur.conn, (char*)path, &r->dir))
                return(NULL);
 
        r->offset = 0;
@@ -110,7 +109,7 @@ static void
 attrib_to_stat(Attrib *a, struct stat *st)
 {
        memset(st, 0, sizeof(*st));
-       
+
        if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
                st->st_size = a->size;
        if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
@@ -129,12 +128,12 @@ static int
 fudge_lstat(const char *path, struct stat *st)
 {
        Attrib *a;
-       
-       if (!(a = do_lstat(cur.fd_in, cur.fd_out, (char*)path, 0)))
+
+       if (!(a = do_lstat(cur.conn, (char*)path, 0)))
                return(-1);
-       
+
        attrib_to_stat(a, st);
-       
+
        return(0);
 }
 
@@ -142,17 +141,17 @@ static int
 fudge_stat(const char *path, struct stat *st)
 {
        Attrib *a;
-       
-       if (!(a = do_stat(cur.fd_in, cur.fd_out, (char*)path, 0)))
+
+       if (!(a = do_stat(cur.conn, (char*)path, 0)))
                return(-1);
-       
+
        attrib_to_stat(a, st);
-       
+
        return(0);
 }
 
 int
-remote_glob(int fd_in, int fd_out, const char *pattern, int flags,
+remote_glob(struct sftp_conn *conn, const char *pattern, int flags,
     int (*errfunc)(const char *, int), glob_t *pglob)
 {
        pglob->gl_opendir = fudge_opendir;
@@ -160,11 +159,9 @@ remote_glob(int fd_in, int fd_out, const char *pattern, int flags,
        pglob->gl_closedir = (void (*)(void *))fudge_closedir;
        pglob->gl_lstat = fudge_lstat;
        pglob->gl_stat = fudge_stat;
-       
+
        memset(&cur, 0, sizeof(cur));
-       cur.fd_in = fd_in;
-       cur.fd_out = fd_out;
+       cur.conn = conn;
 
-       return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc,
-           pglob));
+       return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob));
 }
index 2885044ae51fee0c43ab521c3e64122506b0b267..488b0a80b5bad1a9e809b54b05ee205d6a36af8a 100644 (file)
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-glob.h,v 1.5 2001/06/26 17:27:24 markus Exp $ */
+/* $OpenBSD: sftp-glob.h,v 1.6 2002/02/13 00:59:23 djm Exp $ */
 
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 /* Remote sftp filename globbing */
 
+#ifndef _SFTP_GLOB_H
+#define _SFTP_GLOB_H
+
+#include "sftp-client.h"
+
 int
-remote_glob(int, int, const char *, int, int (*)(const char *, int), glob_t *);
+remote_glob(struct sftp_conn *, const char *, int, 
+    int (*)(const char *, int), glob_t *);
+
+#endif
index 841e562e1de21bc7a433ae8d4f6cc4b6ecae83f8..5de93891a70dd19ec88a5bef4df78f24b224a301 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 /* XXX: recursive operations */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.40 2001/08/14 09:23:02 markus Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.44 2002/02/13 00:59:23 djm Exp $");
 
 #include "buffer.h"
 #include "xmalloc.h"
@@ -42,8 +42,11 @@ RCSID("$OpenBSD: sftp-int.c,v 1.40 2001/08/14 09:23:02 markus Exp $");
 /* File to read commands from */
 extern FILE *infile;
 
-/* Version of server we are speaking to */
-int version;
+/* Size of buffer used when copying files */
+extern size_t copy_buffer_len;
+
+/* Number of concurrent outstanding requests */
+extern int num_requests;
 
 /* Seperators for interactive commands */
 #define WHITESPACE " \t\r\n"
@@ -205,7 +208,7 @@ path_append(char *p1, char *p2)
 
        ret = xmalloc(len);
        strlcpy(ret, p1, len);
-       if (strcmp(p1, "/") != 0) 
+       if (strcmp(p1, "/") != 0)
                strlcat(ret, "/", len);
        strlcat(ret, p2, len);
 
@@ -330,12 +333,12 @@ is_dir(char *path)
 }
 
 static int
-remote_is_dir(int in, int out, char *path)
+remote_is_dir(struct sftp_conn *conn, char *path)
 {
        Attrib *a;
 
        /* XXX: report errors? */
-       if ((a = do_stat(in, out, path, 1)) == NULL)
+       if ((a = do_stat(conn, path, 1)) == NULL)
                return(0);
        if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
                return(0);
@@ -343,7 +346,7 @@ remote_is_dir(int in, int out, char *path)
 }
 
 static int
-process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
+process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
 {
        char *abs_src = NULL;
        char *abs_dst = NULL;
@@ -357,7 +360,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
 
        memset(&g, 0, sizeof(g));
        debug3("Looking up %s", abs_src);
-       if (remote_glob(in, out, abs_src, 0, NULL, &g)) {
+       if (remote_glob(conn, abs_src, 0, NULL, &g)) {
                error("File \"%s\" not found.", abs_src);
                err = -1;
                goto out;
@@ -381,7 +384,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
                        goto out;
                }
                printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
-               err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag);
+               err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);
                goto out;
        }
 
@@ -393,7 +396,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
                goto out;
        }
 
-       for(i = 0; g.gl_pathv[i]; i++) {
+       for (i = 0; g.gl_pathv[i]; i++) {
                if (infer_path(g.gl_pathv[i], &tmp)) {
                        err = -1;
                        goto out;
@@ -405,7 +408,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
                        abs_dst = tmp;
 
                printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
-               if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
+               if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
                        err = -1;
                xfree(abs_dst);
                abs_dst = NULL;
@@ -420,7 +423,7 @@ out:
 }
 
 static int
-process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
+process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
 {
        char *tmp_dst = NULL;
        char *abs_dst = NULL;
@@ -446,7 +449,7 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
        if (g.gl_pathv[0] && g.gl_matchc == 1) {
                if (tmp_dst) {
                        /* If directory specified, append filename */
-                       if (remote_is_dir(in, out, tmp_dst)) {
+                       if (remote_is_dir(conn, tmp_dst)) {
                                if (infer_path(g.gl_pathv[0], &tmp)) {
                                        err = 1;
                                        goto out;
@@ -463,19 +466,19 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
                        abs_dst = make_absolute(abs_dst, pwd);
                }
                printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
-               err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag);
+               err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);
                goto out;
        }
 
        /* Multiple matches, dst may be directory or unspecified */
-       if (tmp_dst && !remote_is_dir(in, out, tmp_dst)) {
+       if (tmp_dst && !remote_is_dir(conn, tmp_dst)) {
                error("Multiple files match, but \"%s\" is not a directory",
                    tmp_dst);
                err = -1;
                goto out;
        }
 
-       for(i = 0; g.gl_pathv[i]; i++) {
+       for (i = 0; g.gl_pathv[i]; i++) {
                if (infer_path(g.gl_pathv[i], &tmp)) {
                        err = -1;
                        goto out;
@@ -487,7 +490,7 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
                        abs_dst = make_absolute(tmp, pwd);
 
                printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
-               if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
+               if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
                        err = -1;
        }
 
@@ -517,7 +520,7 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
                return(-1);
 
        /* Figure out which command we have */
-       for(i = 0; cmds[i].c; i++) {
+       for (i = 0; cmds[i].c; i++) {
                int cmdlen = strlen(cmds[i].c);
 
                /* Check for command followed by whitespace */
@@ -645,7 +648,7 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
 }
 
 static int
-parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
+parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
 {
        char *path1, *path2, *tmp;
        int pflag, cmdnum, i;
@@ -665,32 +668,26 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
        case -1:
                break;
        case I_GET:
-               err = process_get(in, out, path1, path2, *pwd, pflag);
+               err = process_get(conn, path1, path2, *pwd, pflag);
                break;
        case I_PUT:
-               err = process_put(in, out, path1, path2, *pwd, pflag);
+               err = process_put(conn, path1, path2, *pwd, pflag);
                break;
        case I_RENAME:
                path1 = make_absolute(path1, *pwd);
                path2 = make_absolute(path2, *pwd);
-               err = do_rename(in, out, path1, path2);
+               err = do_rename(conn, path1, path2);
                break;
        case I_SYMLINK:
-               if (version < 3) {
-                       error("The server (version %d) does not support "
-                           "this operation", version);
-                       err = -1;
-               } else {
-                       path2 = make_absolute(path2, *pwd);
-                       err = do_symlink(in, out, path1, path2);
-               }
+               path2 = make_absolute(path2, *pwd);
+               err = do_symlink(conn, path1, path2);
                break;
        case I_RM:
                path1 = make_absolute(path1, *pwd);
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
+               remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+               for (i = 0; g.gl_pathv[i]; i++) {
                        printf("Removing %s\n", g.gl_pathv[i]);
-                       if (do_rm(in, out, g.gl_pathv[i]) == -1)
+                       if (do_rm(conn, g.gl_pathv[i]) == -1)
                                err = -1;
                }
                break;
@@ -699,19 +696,19 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                attrib_clear(&a);
                a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
                a.perm = 0777;
-               err = do_mkdir(in, out, path1, &a);
+               err = do_mkdir(conn, path1, &a);
                break;
        case I_RMDIR:
                path1 = make_absolute(path1, *pwd);
-               err = do_rmdir(in, out, path1);
+               err = do_rmdir(conn, path1);
                break;
        case I_CHDIR:
                path1 = make_absolute(path1, *pwd);
-               if ((tmp = do_realpath(in, out, path1)) == NULL) {
+               if ((tmp = do_realpath(conn, path1)) == NULL) {
                        err = 1;
                        break;
                }
-               if ((aa = do_stat(in, out, tmp, 0)) == NULL) {
+               if ((aa = do_stat(conn, tmp, 0)) == NULL) {
                        xfree(tmp);
                        err = 1;
                        break;
@@ -734,22 +731,22 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                break;
        case I_LS:
                if (!path1) {
-                       do_ls(in, out, *pwd);
+                       do_ls(conn, *pwd);
                        break;
                }
                path1 = make_absolute(path1, *pwd);
-               if ((tmp = do_realpath(in, out, path1)) == NULL)
+               if ((tmp = do_realpath(conn, path1)) == NULL)
                        break;
                xfree(path1);
                path1 = tmp;
-               if ((aa = do_stat(in, out, path1, 0)) == NULL)
+               if ((aa = do_stat(conn, path1, 0)) == NULL)
                        break;
                if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
                    !S_ISDIR(aa->perm)) {
                        error("Can't ls: \"%s\" is not a directory", path1);
                        break;
                }
-               do_ls(in, out, path1);
+               do_ls(conn, path1);
                break;
        case I_LCHDIR:
                if (chdir(path1) == -1) {
@@ -780,17 +777,17 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                attrib_clear(&a);
                a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
                a.perm = n_arg;
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
+               remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+               for (i = 0; g.gl_pathv[i]; i++) {
                        printf("Changing mode on %s\n", g.gl_pathv[i]);
-                       do_setstat(in, out, g.gl_pathv[i], &a);
+                       do_setstat(conn, g.gl_pathv[i], &a);
                }
                break;
        case I_CHOWN:
                path1 = make_absolute(path1, *pwd);
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
-                       if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
+               remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+               for (i = 0; g.gl_pathv[i]; i++) {
+                       if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
                                continue;
                        if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
                                error("Can't get current ownership of "
@@ -800,14 +797,14 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                        printf("Changing owner on %s\n", g.gl_pathv[i]);
                        aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                        aa->uid = n_arg;
-                       do_setstat(in, out, g.gl_pathv[i], aa);
+                       do_setstat(conn, g.gl_pathv[i], aa);
                }
                break;
        case I_CHGRP:
                path1 = make_absolute(path1, *pwd);
-               remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
-               for(i = 0; g.gl_pathv[i]; i++) {
-                       if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
+               remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+               for (i = 0; g.gl_pathv[i]; i++) {
+                       if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
                                continue;
                        if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
                                error("Can't get current ownership of "
@@ -817,7 +814,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                        printf("Changing group on %s\n", g.gl_pathv[i]);
                        aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
                        aa->gid = n_arg;
-                       do_setstat(in, out, g.gl_pathv[i], aa);
+                       do_setstat(conn, g.gl_pathv[i], aa);
                }
                break;
        case I_PWD:
@@ -837,7 +834,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
                help();
                break;
        case I_VERSION:
-               printf("SFTP protocol version %d\n", version);
+               printf("SFTP protocol version %d\n", sftp_proto_version(conn));
                break;
        default:
                fatal("%d is not implemented", cmdnum);
@@ -863,12 +860,13 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
        char *pwd;
        char *dir = NULL;
        char cmd[2048];
+       struct sftp_conn *conn;
 
-       version = do_init(fd_in, fd_out);
-       if (version == -1)
+       conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
+       if (conn == NULL)
                fatal("Couldn't initialise connection to server");
 
-       pwd = do_realpath(fd_in, fd_out, ".");
+       pwd = do_realpath(conn, ".");
        if (pwd == NULL)
                fatal("Need cwd");
 
@@ -876,10 +874,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
                dir = xstrdup(file1);
                dir = make_absolute(dir, pwd);
 
-               if (remote_is_dir(fd_in, fd_out, dir) && file2 == NULL) {
+               if (remote_is_dir(conn, dir) && file2 == NULL) {
                        printf("Changing to: %s\n", dir);
                        snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
-                       parse_dispatch_command(fd_in, fd_out, cmd, &pwd);
+                       parse_dispatch_command(conn, cmd, &pwd);
                } else {
                        if (file2 == NULL)
                                snprintf(cmd, sizeof cmd, "get %s", dir);
@@ -887,7 +885,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
                                snprintf(cmd, sizeof cmd, "get %s %s", dir,
                                    file2);
 
-                       parse_dispatch_command(fd_in, fd_out, cmd, &pwd);
+                       parse_dispatch_command(conn, cmd, &pwd);
                        return;
                }
        }
@@ -899,7 +897,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
        setlinebuf(infile);
 #endif
 
-       for(;;) {
+       for (;;) {
                char *cp;
 
                printf("sftp> ");
@@ -915,7 +913,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
                if (cp)
                        *cp = '\0';
 
-               if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd))
+               if (parse_dispatch_command(conn, cmd, &pwd))
                        break;
        }
        xfree(pwd);
index 699e758b1b6ac09d16cfadec295406dfb9998d0e..97687581222979e5586c01f8c41e16953a5888fb 100644 (file)
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-int.h,v 1.4 2001/06/26 17:27:25 markus Exp $ */
+/* $OpenBSD: sftp-int.h,v 1.5 2002/02/13 00:59:23 djm Exp $ */
 
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index 2ef9753bf07d7639b344572863f3b069ed4f7eea..117e6cc15711d1acbbdf6862d2df79be7f2ecccf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.30 2001/07/31 12:42:50 jakob Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.33 2002/02/13 00:28:13 markus Exp $");
 
 #include "buffer.h"
 #include "bufaux.h"
@@ -144,7 +144,7 @@ handle_init(void)
 {
        int i;
 
-       for(i = 0; i < sizeof(handles)/sizeof(Handle); i++)
+       for (i = 0; i < sizeof(handles)/sizeof(Handle); i++)
                handles[i].use = HANDLE_UNUSED;
 }
 
@@ -153,7 +153,7 @@ handle_new(int use, char *name, int fd, DIR *dirp)
 {
        int i;
 
-       for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
+       for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
                if (handles[i].use == HANDLE_UNUSED) {
                        handles[i].use = use;
                        handles[i].dirp = dirp;
@@ -589,6 +589,11 @@ process_setstat(void)
        name = get_string(NULL);
        a = get_attrib();
        TRACE("setstat id %d name %s", id, name);
+       if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
+               ret = truncate(name, a->size);
+               if (ret == -1)
+                       status = errno_to_portable(errno);
+       }
        if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                ret = chmod(name, a->perm & 0777);
                if (ret == -1)
@@ -626,6 +631,11 @@ process_fsetstat(void)
        if (fd < 0 || name == NULL) {
                status = SSH2_FX_FAILURE;
        } else {
+               if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
+                       ret = ftruncate(fd, a->size);
+                       if (ret == -1)
+                               status = errno_to_portable(errno);
+               }
                if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
 #ifdef HAVE_FCHMOD
                        ret = fchmod(fd, a->perm & 0777);
@@ -771,7 +781,7 @@ process_readdir(void)
                }
                if (count > 0) {
                        send_names(id, count, stats);
-                       for(i = 0; i < count; i++) {
+                       for (i = 0; i < count; i++) {
                                xfree(stats[i].name);
                                xfree(stats[i].long_name);
                        }
@@ -897,7 +907,7 @@ process_readlink(void)
                send_status(id, errno_to_portable(errno));
        else {
                Stat s;
-               
+
                link[len] = '\0';
                attrib_clear(&s.attrib);
                s.name = s.long_name = link;
@@ -951,7 +961,7 @@ process(void)
 
        if (buffer_len(&iqueue) < 5)
                return;         /* Incomplete message. */
-       cp = (u_char *) buffer_ptr(&iqueue);
+       cp = buffer_ptr(&iqueue);
        msg_len = GET_32BIT(cp);
        if (msg_len > 256 * 1024) {
                error("bad message ");
index 0cc4e2b63b22942a8d112b2aebfad48ab439ff6a..2faaff1341789ba93838ba2ba10b810878995d83 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.26 2001/09/17 20:38:09 stevesk Exp $
+.\" $OpenBSD: sftp.1,v 1.33 2002/02/26 19:06:43 deraadt Exp $
 .\"
 .\" Copyright (c) 2001 Damien Miller.  All rights reserved.
 .\"
 .Nd Secure file transfer program
 .Sh SYNOPSIS
 .Nm sftp
-.Op Fl 1Cv
+.Op Fl vC1
 .Op Fl b Ar batchfile
-.Op Fl F Ar ssh_config
 .Op Fl o Ar ssh_option
 .Op Fl s Ar subsystem | sftp_server
+.Op Fl B Ar buffer_size
+.Op Fl F Ar ssh_config
+.Op Fl P Ar sftp_server path
+.Op Fl R Ar num_requests
 .Op Fl S Ar program
 .Ar host
 .Nm sftp
@@ -63,8 +66,6 @@ The last usage format allows the sftp client to start in a remote directory.
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
-.It Fl 1
-Specify the use of protocol version 1.
 .It Fl b Ar batchfile
 Batch mode reads a series of commands from an input
 .Ar batchfile
@@ -75,19 +76,10 @@ non-interactive authentication.
 .Nm
 will abort if any of the following
 commands fail:
-.Ic get , put , rename , ln , rm , mkdir , chdir , lchdir
+.Ic get , put , rename , ln ,
+.Ic rm , mkdir , chdir , lchdir
 and
 .Ic lmkdir .
-.It Fl C
-Enables compression (via ssh's
-.Fl C
-flag).
-.It Fl F Ar ssh_config
-Specifies an alternative
-per-user configuration file for
-.Nm ssh .
-This option is directly passed to
-.Xr ssh 1 .
 .It Fl o Ar ssh_option
 Can be used to pass options to
 .Nm ssh
@@ -105,6 +97,33 @@ on the remote host.  A path is useful for using sftp over
 protocol version 1, or when the remote
 .Nm sshd
 does not have an sftp subsystem configured.
+.It Fl v
+Raise logging level. This option is also passed to ssh.
+.It Fl B Ar buffer_size
+Specify  the size of the buffer that 
+.Nm
+uses when transferring files. Larger buffers require fewer round trips at
+the cost of higher memory consumption. The default is 32768 bytes.
+.It Fl C
+Enables compression (via ssh's
+.Fl C
+flag).
+.It Fl F Ar ssh_config
+Specifies an alternative
+per-user configuration file for
+.Nm ssh .
+This option is directly passed to
+.Xr ssh 1 .
+.It Fl P Ar sftp_server path
+Connect directly to a local 
+.Nm sftp-server 
+(rather than via
+.Nm ssh )
+This option may be useful in debugging the client and server.
+.It Fl R Ar num_requests
+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.
 .It Fl S Ar program
 Name of the
 .Ar program
@@ -112,8 +131,8 @@ to use for the encrypted connection.
 The program must understand
 .Xr ssh 1
 options.
-.It Fl v
-Raise logging level. This option is also passed to ssh.
+.It Fl 1
+Specify the use of protocol version 1.
 .El
 .Sh INTERACTIVE COMMANDS
 Once in interactive mode,
index 06110f9af2fda203034d8647cacbe64b0bd604b7..045e0766e5777f18c8fd47bddbc247b173d808ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001 Damien Miller.  All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -24,9 +24,8 @@
 
 #include "includes.h"
 
-RCSID("$OpenBSD: sftp.c,v 1.21 2001/09/19 19:24:19 stevesk Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.26 2002/02/12 12:32:27 djm Exp $");
 
-/* XXX: commandline mode */
 /* XXX: short-form remote directory listings (like 'ls -C') */
 
 #include "buffer.h"
@@ -46,11 +45,12 @@ extern char *__progname;
 char *__progname;
 #endif
 
-char *ssh_program = _PATH_SSH_PROGRAM;
 FILE* infile;
+size_t copy_buffer_len = 32768;
+size_t num_requests = 16;
 
 static void
-connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
+connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
 {
        int c_in, c_out;
 #ifdef USE_PIPES
@@ -81,8 +81,8 @@ connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
                close(*out);
                close(c_in);
                close(c_out);
-               execv(ssh_program, args);
-               fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
+               execv(path, args);
+               fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
                exit(1);
        }
 
@@ -93,9 +93,12 @@ connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
 static void
 usage(void)
 {
+       extern char *__progname;
+       
        fprintf(stderr,
-           "usage: sftp [-1Cv] [-b batchfile] [-F config] [-o option] [-s subsystem|path]\n"
-           "            [-S program] [user@]host[:file [file]]\n");
+           "usage: %s [-vC1] [-b batchfile] [-o option] [-s subsystem|path] [-B buffer_size]\n"
+           "            [-F config] [-P direct server path] [-S program]\n"
+           "            [user@]host[:file [file]]\n", __progname);
        exit(1);
 }
 
@@ -107,6 +110,7 @@ main(int argc, char **argv)
        char *host, *userhost, *cp, *file2;
        int debug_level = 0, sshver = 2;
        char *file1 = NULL, *sftp_server = NULL;
+       char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
        LogLevel ll = SYSLOG_LEVEL_INFO;
        arglist args;
        extern int optind;
@@ -114,7 +118,7 @@ main(int argc, char **argv)
 
        __progname = get_progname(argv[0]);
        args.list = NULL;
-       addargs(&args, "ssh");         /* overwritten with ssh_program */
+       addargs(&args, "ssh");          /* overwritten with ssh_program */
        addargs(&args, "-oFallBackToRsh no");
        addargs(&args, "-oForwardX11 no");
        addargs(&args, "-oForwardAgent no");
@@ -122,7 +126,7 @@ main(int argc, char **argv)
        ll = SYSLOG_LEVEL_INFO;
        infile = stdin;         /* Read from STDIN unless changed by -b */
 
-       while ((ch = getopt(argc, argv, "1hvCo:s:S:b:F:")) != -1) {
+       while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
                switch (ch) {
                case 'C':
                        addargs(&args, "-C");
@@ -157,54 +161,78 @@ main(int argc, char **argv)
                        } else
                                fatal("Filename already specified.");
                        break;
+               case 'P':
+                       sftp_direct = optarg;
+                       break;
+               case 'B':
+                       copy_buffer_len = strtol(optarg, &cp, 10);
+                       if (copy_buffer_len == 0 || *cp != '\0')
+                               fatal("Invalid buffer size \"%s\"", optarg);
+                       break;
+               case 'R':
+                       num_requests = strtol(optarg, &cp, 10);
+                       if (num_requests == 0 || *cp != '\0')
+                               fatal("Invalid number of requests \"%s\"", 
+                                   optarg);
+                       break;
                case 'h':
                default:
                        usage();
                }
        }
 
-       if (optind == argc || argc > (optind + 2))
-               usage();
+       if (sftp_direct == NULL) {
+               if (optind == argc || argc > (optind + 2))
+                       usage();
 
-       userhost = xstrdup(argv[optind]);
-       file2 = argv[optind+1];
+               userhost = xstrdup(argv[optind]);
+               file2 = argv[optind+1];
 
-       if ((cp = colon(userhost)) != NULL) {
-               *cp++ = '\0';
-               file1 = cp;
-       }
+               if ((cp = colon(userhost)) != NULL) {
+                       *cp++ = '\0';
+                       file1 = cp;
+               }
 
-       if ((host = strchr(userhost, '@')) == NULL)
-               host = userhost;
-       else {
-               *host++ = '\0';
-               if (!userhost[0]) {
-                       fprintf(stderr, "Missing username\n");
-                       usage();
+               if ((host = strchr(userhost, '@')) == NULL)
+                       host = userhost;
+               else {
+                       *host++ = '\0';
+                       if (!userhost[0]) {
+                               fprintf(stderr, "Missing username\n");
+                               usage();
+                       }
+                       addargs(&args, "-l%s",userhost);
                }
-               addargs(&args, "-l%s",userhost);
-       }
 
-       host = cleanhostname(host);
-       if (!*host) {
-               fprintf(stderr, "Missing hostname\n");
-               usage();
-       }
+               host = cleanhostname(host);
+               if (!*host) {
+                       fprintf(stderr, "Missing hostname\n");
+                       usage();
+               }
 
-       log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
-       addargs(&args, "-oProtocol %d", sshver);
+               log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+               addargs(&args, "-oProtocol %d", sshver);
 
-       /* no subsystem if the server-spec contains a '/' */
-       if (sftp_server == NULL || strchr(sftp_server, '/') == NULL) 
-               addargs(&args, "-s");
+               /* no subsystem if the server-spec contains a '/' */
+               if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
+                       addargs(&args, "-s");
 
-       addargs(&args, "%s", host);
-       addargs(&args, "%s", (sftp_server != NULL ? sftp_server : "sftp"));
-       args.list[0] = ssh_program;
+               addargs(&args, "%s", host);
+               addargs(&args, "%s", (sftp_server != NULL ? 
+                   sftp_server : "sftp"));
+               args.list[0] = ssh_program;
 
-       fprintf(stderr, "Connecting to %s...\n", host);
+               fprintf(stderr, "Connecting to %s...\n", host);
+               connect_to_server(ssh_program, args.list, &in, &out, 
+                   &sshpid);
+       } else {
+               args.list = NULL;
+               addargs(&args, "sftp-server");
 
-       connect_to_server(args.list, &in, &out, &sshpid);
+               fprintf(stderr, "Attaching to %s...\n", sftp_direct);
+               connect_to_server(sftp_direct, args.list, &in, &out, 
+                   &sshpid);
+       }
 
        interactive_loop(in, out, file1, file2);
 
index 2ad95864b8e03492cec90a87a09f30d41d9a3048..675c6086e952a3ce5d2fe4e100e5bbfdbdf91cc2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sftp.h,v 1.3 2001/03/07 10:11:23 djm Exp $    */
+/*     $OpenBSD: sftp.h,v 1.4 2002/02/13 00:59:23 djm Exp $    */
 
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -38,6 +38,7 @@
 #define SSH2_FXP_READ                  5
 #define SSH2_FXP_WRITE                 6
 #define SSH2_FXP_LSTAT                 7
+#define SSH2_FXP_STAT_VERSION_0                7
 #define SSH2_FXP_FSTAT                 8
 #define SSH2_FXP_SETSTAT               9
 #define SSH2_FXP_FSETSTAT              10
index b842080d632ae497d37682457c8dec8e061662b5..41d5def6ff150e6cf35c452ccb300d804629169f 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-add.1,v 1.27 2001/08/23 18:08:59 stevesk Exp $
+.\"    $OpenBSD: ssh-add.1,v 1.30 2002/02/04 20:41:16 stevesk Exp $
 .\"
 .\"  -*- nroff -*-
 .\"
 .Nm
 adds RSA or DSA identities to the authentication agent,
 .Xr ssh-agent 1 .
-When run without arguments, it adds the file
+When run without arguments, it adds the files
+.Pa $HOME/.ssh/id_rsa ,
+.Pa $HOME/.ssh/id_dsa 
+and
 .Pa $HOME/.ssh/identity .
 Alternative file names can be given on the command line.
 If any file requires a passphrase,
@@ -91,21 +94,16 @@ Remove key in smartcard
 .Bl -tag -width Ds
 .It Pa $HOME/.ssh/identity
 Contains the protocol version 1 RSA authentication identity of the user.
-This file should not be readable by anyone but the user.
-Note that
-.Nm
-ignores this file if it is accessible by others.
-It is possible to
-specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file.
-This is the default file added by
-.Nm
-when no other files have been specified.
 .It Pa $HOME/.ssh/id_dsa
 Contains the protocol version 2 DSA authentication identity of the user.
 .It Pa $HOME/.ssh/id_rsa
 Contains the protocol version 2 RSA authentication identity of the user.
 .El
+.Pp
+Identity files should not be readable by anyone but the user.
+Note that
+.Nm
+ignores identity files if they are accessible by others.
 .Sh ENVIRONMENT
 .Bl -tag -width Ds
 .It Ev "DISPLAY" and "SSH_ASKPASS"
@@ -132,6 +130,11 @@ may be necessary to redirect the input from
 .Pa /dev/null
 to make this work.)
 .El
+.Sh DIAGNOSTICS
+Exit status is 0 on success, 1 if the specified command fails,
+and 2 if
+.Nm
+is unable to contact the authentication agent.
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
index 585b71487359df8985d2a47bdca70e9abfe22501..b057a089205b09f71d3843a04e3c9fddf2ebb420 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-add.c,v 1.46 2001/10/02 08:38:50 djm Exp $");
+RCSID("$OpenBSD: ssh-add.c,v 1.50 2002/01/29 14:27:57 markus Exp $");
 
 #include <openssl/evp.h>
 
@@ -58,6 +58,15 @@ char *__progname;
 /* argv0 */
 extern char *__progname;
 
+/* Default files to add */
+static char *default_files[] = {
+       _PATH_SSH_CLIENT_ID_RSA,
+       _PATH_SSH_CLIENT_ID_DSA,
+       _PATH_SSH_CLIENT_IDENTITY, 
+       NULL
+};
+
+
 /* we keep a cache of one passphrases */
 static char *pass = NULL;
 static void
@@ -90,7 +99,7 @@ delete_file(AuthenticationConnection *ac, const char *filename)
 
        key_free(public);
        xfree(comment);
-       
+
        return ret;
 }
 
@@ -160,7 +169,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
 
        xfree(comment);
        key_free(private);
-       
+
        return ret;
 }
 
@@ -169,16 +178,16 @@ update_card(AuthenticationConnection *ac, int add, const char *id)
 {
        if (ssh_update_card(ac, add, id)) {
                fprintf(stderr, "Card %s: %s\n",
-                    add ? "added" : "removed", id);
+                   add ? "added" : "removed", id);
                return 0;
        } else {
                fprintf(stderr, "Could not %s card: %s\n",
-                    add ? "add" : "remove", id);
+                   add ? "add" : "remove", id);
                return -1;
        }
 }
 
-static void
+static int
 list_identities(AuthenticationConnection *ac, int do_fp)
 {
        Key *key;
@@ -188,8 +197,8 @@ list_identities(AuthenticationConnection *ac, int do_fp)
 
        for (version = 1; version <= 2; version++) {
                for (key = ssh_get_first_identity(ac, &comment, version);
-                    key != NULL;
-                    key = ssh_get_next_identity(ac, &comment, version)) {
+                   key != NULL;
+                   key = ssh_get_next_identity(ac, &comment, version)) {
                        had_identities = 1;
                        if (do_fp) {
                                fp = key_fingerprint(key, SSH_FP_MD5,
@@ -206,8 +215,24 @@ list_identities(AuthenticationConnection *ac, int do_fp)
                        xfree(comment);
                }
        }
-       if (!had_identities)
+       if (!had_identities) {
                printf("The agent has no identities.\n");
+               return -1;
+       }
+       return 0;
+}
+
+static int
+do_file(AuthenticationConnection *ac, int deleting, char *file)
+{
+       if (deleting) {
+               if (delete_file(ac, file) == -1)
+                       return -1;
+       } else {
+               if (add_file(ac, file) == -1)
+                       return -1;
+       }
+       return 0;
 }
 
 static void
@@ -231,8 +256,6 @@ main(int argc, char **argv)
        extern char *optarg;
        extern int optind;
        AuthenticationConnection *ac = NULL;
-       struct passwd *pw;
-       char buf[1024];
        char *sc_reader_id = NULL;
        int i, ch, deleting = 0, ret = 0;
 
@@ -246,13 +269,14 @@ main(int argc, char **argv)
        ac = ssh_get_authentication_connection();
        if (ac == NULL) {
                fprintf(stderr, "Could not open a connection to your authentication agent.\n");
-               exit(1);
+               exit(2);
        }
-        while ((ch = getopt(argc, argv, "lLdDe:s:")) != -1) {
+       while ((ch = getopt(argc, argv, "lLdDe:s:")) != -1) {
                switch (ch) {
                case 'l':
                case 'L':
-                       list_identities(ac, ch == 'l' ? 1 : 0);
+                       if (list_identities(ac, ch == 'l' ? 1 : 0) == -1)
+                               ret = 1;
                        goto done;
                        break;
                case 'd':
@@ -267,7 +291,7 @@ main(int argc, char **argv)
                        sc_reader_id = optarg;
                        break;
                case 'e':
-                       deleting = 1; 
+                       deleting = 1;
                        sc_reader_id = optarg;
                        break;
                default:
@@ -284,30 +308,26 @@ main(int argc, char **argv)
                goto done;
        }
        if (argc == 0) {
-               pw = getpwuid(getuid());
-               if (!pw) {
+               char buf[MAXPATHLEN];
+               struct passwd *pw;
+
+               if ((pw = getpwuid(getuid())) == NULL) {
                        fprintf(stderr, "No user found with uid %u\n",
                            (u_int)getuid());
                        ret = 1;
                        goto done;
                }
-               snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_CLIENT_IDENTITY);
-               if (deleting) {
-                       if (delete_file(ac, buf) == -1)
-                               ret = 1;
-               } else {
-                       if (add_file(ac, buf) == -1)
+
+               for(i = 0; default_files[i]; i++) {
+                       snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir, 
+                           default_files[i]);
+                       if (do_file(ac, deleting, buf) == -1)
                                ret = 1;
                }
        } else {
-               for (i = 0; i < argc; i++) {
-                       if (deleting) {
-                               if (delete_file(ac, argv[i]) == -1)
-                                       ret = 1;
-                       } else {
-                               if (add_file(ac, argv[i]) == -1)
-                                       ret = 1;
-                       }
+               for(i = 0; i < argc; i++) {
+                       if (do_file(ac, deleting, argv[i]) == -1)
+                               ret = 1;
                }
        }
        clear_pass();
index 00c19921caa4356f40e5c38b89a1fdaf8beb94b5..9909ef59022d7d5a7cfb8d0c3e88d14031d35e27 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.28 2001/09/05 06:23:07 deraadt Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.31 2002/02/04 20:41:16 stevesk Exp $
 .\"
 .\" Author: Tatu Ylonen <ylo@cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -94,9 +94,11 @@ Keys are added using
 .Xr ssh-add 1 .
 When executed without arguments,
 .Xr ssh-add 1
-adds the
-.Pa $HOME/.ssh/identity
-file.
+adds the files
+.Pa $HOME/.ssh/id_rsa ,
+.Pa $HOME/.ssh/id_dsa 
+and
+.Pa $HOME/.ssh/identity .
 If the identity has a passphrase,
 .Xr ssh-add 1
 asks for the passphrase (using a small X11 application if running
@@ -127,6 +129,11 @@ Later
 .Xr ssh 1
 looks at these variables and uses them to establish a connection to the agent.
 .Pp
+The agent will never send a private key over its request channel.
+Instead, operations that require a private key will be performed
+by the agent, and the result will be returned to the requester.
+This way, private keys are not exposed to clients using the agent.
+.Pp
 A unix-domain socket is created
 .Pq Pa /tmp/ssh-XXXXXXXX/agent.<pid> ,
 and the name of this socket is stored in the
@@ -147,15 +154,6 @@ line terminates.
 .Bl -tag -width Ds
 .It Pa $HOME/.ssh/identity
 Contains the protocol version 1 RSA authentication identity of the user.
-This file should not be readable by anyone but the user.
-It is possible to
-specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file.
-This file is not used by
-.Nm
-but is normally added to the agent using
-.Xr ssh-add 1
-at login time.
 .It Pa $HOME/.ssh/id_dsa
 Contains the protocol version 2 DSA authentication identity of the user.
 .It Pa $HOME/.ssh/id_rsa
index a004e32463816cbb51676c74ca4184c9d61b04a8..555396fc5e1503ad78d4930d5e1f762e23557823 100644 (file)
@@ -1,5 +1,3 @@
-/*     $OpenBSD: ssh-agent.c,v 1.72 2001/08/03 10:31:30 jakob Exp $    */
-
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.72 2001/08/03 10:31:30 jakob Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.82 2002/03/04 17:27:39 stevesk Exp $");
+
+#if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
+#include <sys/queue.h>
+#else
+#include "openbsd-compat/fake-queue.h"
+#endif
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
@@ -46,13 +50,9 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.72 2001/08/03 10:31:30 jakob Exp $");
 #include "buffer.h"
 #include "bufaux.h"
 #include "xmalloc.h"
-#include "packet.h"
 #include "getput.h"
-#include "mpaux.h"
 #include "key.h"
 #include "authfd.h"
-#include "cipher.h"
-#include "kex.h"
 #include "compat.h"
 #include "log.h"
 
@@ -61,11 +61,15 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.72 2001/08/03 10:31:30 jakob Exp $");
 #include "scard.h"
 #endif
 
+typedef enum {
+       AUTH_UNUSED,
+       AUTH_SOCKET,
+       AUTH_CONNECTION
+} sock_type;
+
 typedef struct {
        int fd;
-       enum {
-               AUTH_UNUSED, AUTH_SOCKET, AUTH_CONNECTION
-       } type;
+       sock_type type;
        Buffer input;
        Buffer output;
 } SocketEntry;
@@ -73,14 +77,15 @@ typedef struct {
 u_int sockets_alloc = 0;
 SocketEntry *sockets = NULL;
 
-typedef struct {
+typedef struct identity {
+       TAILQ_ENTRY(identity) next;
        Key *key;
        char *comment;
 } Identity;
 
 typedef struct {
        int nentries;
-       Identity *identities;
+       TAILQ_HEAD(idqueue, identity) idlist;
 } Idtab;
 
 /* private key table, one per protocol version */
@@ -105,8 +110,8 @@ static void
 idtab_init(void)
 {
        int i;
-       for (i = 0; i <=2; i++){
-               idtable[i].identities = NULL;
+       for (i = 0; i <=2; i++) {
+               TAILQ_INIT(&idtable[i].idlist);
                idtable[i].nentries = 0;
        }
 }
@@ -121,19 +126,25 @@ idtab_lookup(int version)
 }
 
 /* return matching private key for given public key */
-static Key *
-lookup_private_key(Key *key, int *idx, int version)
+static Identity *
+lookup_identity(Key *key, int version)
 {
-       int i;
+       Identity *id;
+
        Idtab *tab = idtab_lookup(version);
-       for (i = 0; i < tab->nentries; i++) {
-               if (key_equal(key, tab->identities[i].key)) {
-                       if (idx != NULL)
-                               *idx = i;
-                       return tab->identities[i].key;
-               }
+       TAILQ_FOREACH(id, &tab->idlist, next) {
+               if (key_equal(key, id->key))
+                       return (id);
        }
-       return NULL;
+       return (NULL);
+}
+
+static void
+free_identity(Identity *id)
+{
+       key_free(id->key);
+       xfree(id->comment);
+       xfree(id);
 }
 
 /* send list of supported public keys to 'client' */
@@ -142,14 +153,13 @@ process_request_identities(SocketEntry *e, int version)
 {
        Idtab *tab = idtab_lookup(version);
        Buffer msg;
-       int i;
+       Identity *id;
 
        buffer_init(&msg);
        buffer_put_char(&msg, (version == 1) ?
            SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER);
        buffer_put_int(&msg, tab->nentries);
-       for (i = 0; i < tab->nentries; i++) {
-               Identity *id = &tab->identities[i];
+       TAILQ_FOREACH(id, &tab->idlist, next) {
                if (id->key->type == KEY_RSA1) {
                        buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
                        buffer_put_bignum(&msg, id->key->rsa->e);
@@ -172,7 +182,8 @@ process_request_identities(SocketEntry *e, int version)
 static void
 process_authentication_challenge1(SocketEntry *e)
 {
-       Key *key, *private;
+       Identity *id;
+       Key *key;
        BIGNUM *challenge;
        int i, len;
        Buffer msg;
@@ -182,7 +193,8 @@ process_authentication_challenge1(SocketEntry *e)
 
        buffer_init(&msg);
        key = key_new(KEY_RSA1);
-       challenge = BN_new();
+       if ((challenge = BN_new()) == NULL)
+               fatal("process_authentication_challenge1: BN_new failed");
 
        buffer_get_int(&e->input);                              /* ignored */
        buffer_get_bignum(&e->input, key->rsa->e);
@@ -192,13 +204,14 @@ process_authentication_challenge1(SocketEntry *e)
        /* Only protocol 1.1 is supported */
        if (buffer_len(&e->input) == 0)
                goto failure;
-       buffer_get(&e->input, (char *) session_id, 16);
+       buffer_get(&e->input, session_id, 16);
        response_type = buffer_get_int(&e->input);
        if (response_type != 1)
                goto failure;
 
-       private = lookup_private_key(key, NULL, 1);
-       if (private != NULL) {
+       id = lookup_identity(key, 1);
+       if (id != NULL) {
+               Key *private = id->key;
                /* Decrypt the challenge using the private key. */
                if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
                        goto failure;
@@ -239,7 +252,7 @@ static void
 process_sign_request2(SocketEntry *e)
 {
        extern int datafellows;
-       Key *key, *private;
+       Key *key;
        u_char *blob, *data, *signature = NULL;
        u_int blen, dlen, slen = 0;
        int flags;
@@ -257,9 +270,9 @@ process_sign_request2(SocketEntry *e)
 
        key = key_from_blob(blob, blen);
        if (key != NULL) {
-               private = lookup_private_key(key, NULL, 2);
-               if (private != NULL)
-                       ok = key_sign(private, &signature, &slen, data, dlen);
+               Identity *id = lookup_identity(key, 2);
+               if (id != NULL)
+                       ok = key_sign(id->key, &signature, &slen, data, dlen);
        }
        key_free(key);
        buffer_init(&msg);
@@ -283,13 +296,13 @@ process_sign_request2(SocketEntry *e)
 static void
 process_remove_identity(SocketEntry *e, int version)
 {
-       Key *key = NULL, *private;
+       Key *key = NULL;
        u_char *blob;
        u_int blen;
        u_int bits;
        int success = 0;
 
-       switch(version){
+       switch (version) {
        case 1:
                key = key_new(KEY_RSA1);
                bits = buffer_get_int(&e->input);
@@ -307,9 +320,8 @@ process_remove_identity(SocketEntry *e, int version)
                break;
        }
        if (key != NULL) {
-               int idx;
-               private = lookup_private_key(key, &idx, version);
-               if (private != NULL) {
+               Identity *id = lookup_identity(key, version);
+               if (id != NULL) {
                        /*
                         * We have this key.  Free the old key.  Since we
                         * don\'t want to leave empty slots in the middle of
@@ -318,19 +330,12 @@ process_remove_identity(SocketEntry *e, int version)
                         * of the array.
                         */
                        Idtab *tab = idtab_lookup(version);
-                       key_free(tab->identities[idx].key);
-                       xfree(tab->identities[idx].comment);
                        if (tab->nentries < 1)
                                fatal("process_remove_identity: "
                                    "internal error: tab->nentries %d",
                                    tab->nentries);
-                       if (idx != tab->nentries - 1) {
-                               int i;
-                               for (i = idx; i < tab->nentries - 1; i++)
-                                       tab->identities[i] = tab->identities[i+1];
-                       }
-                       tab->identities[tab->nentries - 1].key = NULL;
-                       tab->identities[tab->nentries - 1].comment = NULL;
+                       TAILQ_REMOVE(&tab->idlist, id, next);
+                       free_identity(id);
                        tab->nentries--;
                        success = 1;
                }
@@ -344,13 +349,14 @@ process_remove_identity(SocketEntry *e, int version)
 static void
 process_remove_all_identities(SocketEntry *e, int version)
 {
-       u_int i;
        Idtab *tab = idtab_lookup(version);
+       Identity *id;
 
        /* Loop over all identities and clear the keys. */
-       for (i = 0; i < tab->nentries; i++) {
-               key_free(tab->identities[i].key);
-               xfree(tab->identities[i].comment);
+       for (id = TAILQ_FIRST(&tab->idlist); id;
+           id = TAILQ_FIRST(&tab->idlist)) {
+               TAILQ_REMOVE(&tab->idlist, id, next);
+               free_identity(id);
        }
 
        /* Mark that there are no identities. */
@@ -391,7 +397,7 @@ process_add_identity(SocketEntry *e, int version)
                type_name = buffer_get_string(&e->input, NULL);
                type = key_type_from_name(type_name);
                xfree(type_name);
-               switch(type) {
+               switch (type) {
                case KEY_DSA:
                        k = key_new_private(type);
                        buffer_get_bignum2(&e->input, k->dsa->p);
@@ -424,14 +430,11 @@ process_add_identity(SocketEntry *e, int version)
                goto send;
        }
        success = 1;
-       if (lookup_private_key(k, NULL, version) == NULL) {
-               if (tab->nentries == 0)
-                       tab->identities = xmalloc(sizeof(Identity));
-               else
-                       tab->identities = xrealloc(tab->identities,
-                           (tab->nentries + 1) * sizeof(Identity));
-               tab->identities[tab->nentries].key = k;
-               tab->identities[tab->nentries].comment = comment;
+       if (lookup_identity(k, version) == NULL) {
+               Identity *id = xmalloc(sizeof(Identity));
+               id->key = k;
+               id->comment = comment;
+               TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                /* Increment the number of identities. */
                tab->nentries++;
        } else {
@@ -453,7 +456,7 @@ process_add_smartcard_key (SocketEntry *e)
        Key *n = NULL, *k = NULL;
        char *sc_reader_id = NULL;
        int success = 0;
-       
+
        sc_reader_id = buffer_get_string(&e->input, NULL);
        k = sc_get_key(sc_reader_id);
        xfree(sc_reader_id);
@@ -466,36 +469,28 @@ process_add_smartcard_key (SocketEntry *e)
 
        tab = idtab_lookup(1);
        k->type = KEY_RSA1;
-       if (lookup_private_key(k, NULL, 1) == NULL) {
-               if (tab->nentries == 0)
-                       tab->identities = xmalloc(sizeof(Identity));
-               else
-                       tab->identities = xrealloc(tab->identities,
-                           (tab->nentries + 1) * sizeof(Identity));
+       if (lookup_identity(k, 1) == NULL) {
+               Identity *id = xmalloc(sizeof(Identity));
                n = key_new(KEY_RSA1);
                BN_copy(n->rsa->n, k->rsa->n);
                BN_copy(n->rsa->e, k->rsa->e);
                RSA_set_method(n->rsa, sc_get_engine());
-               tab->identities[tab->nentries].key = n;
-               tab->identities[tab->nentries].comment =
-                   xstrdup("rsa1 smartcard");
+               id->key = n;
+               id->comment = xstrdup("rsa1 smartcard");
+               TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                tab->nentries++;
        }
        k->type = KEY_RSA;
        tab = idtab_lookup(2);
-       if (lookup_private_key(k, NULL, 2) == NULL) {
-               if (tab->nentries == 0)
-                       tab->identities = xmalloc(sizeof(Identity));
-               else
-                       tab->identities = xrealloc(tab->identities,
-                           (tab->nentries + 1) * sizeof(Identity));
+       if (lookup_identity(k, 2) == NULL) {
+               Identity *id = xmalloc(sizeof(Identity));
                n = key_new(KEY_RSA);
                BN_copy(n->rsa->n, k->rsa->n);
                BN_copy(n->rsa->e, k->rsa->e);
                RSA_set_method(n->rsa, sc_get_engine());
-               tab->identities[tab->nentries].key = n;
-               tab->identities[tab->nentries].comment =
-                   xstrdup("rsa smartcard");
+               id->key = n;
+               id->comment = xstrdup("rsa smartcard");
+               TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                tab->nentries++;
        }
        key_free(k);
@@ -508,8 +503,7 @@ send:
 static void
 process_remove_smartcard_key(SocketEntry *e)
 {
-       Key *k = NULL, *private;
-       int idx;
+       Key *k = NULL;
        int success = 0;
        char *sc_reader_id = NULL;
 
@@ -520,25 +514,22 @@ process_remove_smartcard_key(SocketEntry *e)
        if (k == NULL) {
                error("sc_get_pubkey failed");
        } else {
+               Identity *id;
                k->type = KEY_RSA1;
-               private = lookup_private_key(k, &idx, 1);
-               if (private != NULL) {
+               id = lookup_identity(k, 1);
+               if (id != NULL) {
                        Idtab *tab = idtab_lookup(1);
-                       key_free(tab->identities[idx].key);
-                       xfree(tab->identities[idx].comment);
-                       if (idx != tab->nentries)
-                               tab->identities[idx] = tab->identities[tab->nentries];
+                       TAILQ_REMOVE(&tab->idlist, id, next);
+                       free_identity(id);
                        tab->nentries--;
                        success = 1;
                }
                k->type = KEY_RSA;
-               private = lookup_private_key(k, &idx, 2);
-               if (private != NULL) {
+               id = lookup_identity(k, 2);
+               if (id != NULL) {
                        Idtab *tab = idtab_lookup(2);
-                       key_free(tab->identities[idx].key);
-                       xfree(tab->identities[idx].comment);
-                       if (idx != tab->nentries)
-                               tab->identities[idx] = tab->identities[tab->nentries];
+                       TAILQ_REMOVE(&tab->idlist, id, next);
+                       free_identity(id);
                        tab->nentries--;
                        success = 1;
                }
@@ -561,7 +552,7 @@ process_message(SocketEntry *e)
        u_char *cp;
        if (buffer_len(&e->input) < 5)
                return;         /* Incomplete message. */
-       cp = (u_char *) buffer_ptr(&e->input);
+       cp = buffer_ptr(&e->input);
        msg_len = GET_32BIT(cp);
        if (msg_len > 256 * 1024) {
                shutdown(e->fd, SHUT_RDWR);
@@ -611,10 +602,10 @@ process_message(SocketEntry *e)
 #ifdef SMARTCARD
        case SSH_AGENTC_ADD_SMARTCARD_KEY:
                process_add_smartcard_key(e);
-               break; 
+               break;
        case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
                process_remove_smartcard_key(e);
-               break; 
+               break;
 #endif /* SMARTCARD */
        default:
                /* Unknown message.  Respond with failure. */
@@ -627,7 +618,7 @@ process_message(SocketEntry *e)
 }
 
 static void
-new_socket(int type, int fd)
+new_socket(sock_type type, int fd)
 {
        u_int i, old_alloc;
        if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
@@ -728,7 +719,8 @@ after_select(fd_set *readset, fd_set *writeset)
                                sock = accept(sockets[i].fd,
                                    (struct sockaddr *) &sunaddr, &slen);
                                if (sock < 0) {
-                                       perror("accept from AUTH_SOCKET");
+                                       error("accept from AUTH_SOCKET: %s",
+                                           strerror(errno));
                                        break;
                                }
                                new_socket(AUTH_CONNECTION, sock);
@@ -782,7 +774,7 @@ after_select(fd_set *readset, fd_set *writeset)
 }
 
 static void
-cleanup_socket(void)
+cleanup_socket(void *p)
 {
        if (socket_name[0])
                unlink(socket_name);
@@ -793,14 +785,14 @@ cleanup_socket(void)
 static void
 cleanup_exit(int i)
 {
-       cleanup_socket();
+       cleanup_socket(NULL);
        exit(i);
 }
 
 static void
 cleanup_handler(int sig)
 {
-       cleanup_socket();
+       cleanup_socket(NULL);
        _exit(2);
 }
 
@@ -971,7 +963,7 @@ main(int ac, char **av)
        pid = fork();
        if (pid == -1) {
                perror("fork");
-               exit(1);
+               cleanup_exit(1);
        }
        if (pid != 0) {         /* Parent - execute the given command. */
                close(sock);
@@ -994,9 +986,11 @@ main(int ac, char **av)
                perror(av[0]);
                exit(1);
        }
+       /* child */
+       log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
 
        if (setsid() == -1) {
-               perror("setsid");
+               error("setsid: %s", strerror(errno));
                cleanup_exit(1);
        }
 
@@ -1009,16 +1003,13 @@ main(int ac, char **av)
        /* deny core dumps, since memory contains unencrypted private keys */
        rlim.rlim_cur = rlim.rlim_max = 0;
        if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
-               perror("setrlimit rlimit_core failed");
+               error("setrlimit RLIMIT_CORE: %s", strerror(errno));
                cleanup_exit(1);
        }
 #endif
 
 skip:
-       if (atexit(cleanup_socket) < 0) {
-               perror("atexit");
-               cleanup_exit(1);
-       }
+       fatal_add_cleanup(cleanup_socket, NULL);
        new_socket(AUTH_SOCKET, sock);
        if (ac > 0) {
                signal(SIGALRM, check_parent_exists);
@@ -1037,7 +1028,7 @@ skip:
                if (select(max_fd + 1, readsetp, writesetp, NULL, NULL) < 0) {
                        if (errno == EINTR)
                                continue;
-                       exit(1);
+                       fatal("select: %s", strerror(errno));
                }
                after_select(readsetp, writesetp);
        }
index 9f3a28706dde1b23ec7263218d150992474e3fe0..02403f550afc22388d6cc9e7f9d3aa31a5128849 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-dss.c,v 1.9 2001/11/07 22:10:28 markus Exp $");
+RCSID("$OpenBSD: ssh-dss.c,v 1.14 2002/02/28 15:46:33 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/evp.h>
@@ -42,13 +42,13 @@ RCSID("$OpenBSD: ssh-dss.c,v 1.9 2001/11/07 22:10:28 markus Exp $");
 int
 ssh_dss_sign(
     Key *key,
-    u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+    u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
        DSA_SIG *sig;
-       EVP_MD *evp_md = EVP_sha1();
+       const EVP_MD *evp_md = EVP_sha1();
        EVP_MD_CTX md;
-       u_char *digest, *ret, sigblob[SIGBLOB_LEN];
+       u_char *ret, digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
        u_int rlen, slen, len, dlen;
        Buffer b;
 
@@ -56,16 +56,13 @@ ssh_dss_sign(
                error("ssh_dss_sign: no DSA key");
                return -1;
        }
-       dlen = evp_md->md_size;
-       digest = xmalloc(dlen);
        EVP_DigestInit(&md, evp_md);
        EVP_DigestUpdate(&md, data, datalen);
-       EVP_DigestFinal(&md, digest, NULL);
+       EVP_DigestFinal(&md, digest, &dlen);
 
        sig = DSA_do_sign(digest, dlen, key->dsa);
+       memset(digest, 'd', sizeof(digest));
 
-       memset(digest, 0, dlen);
-       xfree(digest);
        if (sig == NULL) {
                error("ssh_dss_sign: sign failed");
                return -1;
@@ -109,13 +106,13 @@ ssh_dss_sign(
 int
 ssh_dss_verify(
     Key *key,
-    u_char *signature, int signaturelen,
-    u_char *data, int datalen)
+    u_char *signature, u_int signaturelen,
+    u_char *data, u_int datalen)
 {
        DSA_SIG *sig;
-       EVP_MD *evp_md = EVP_sha1();
+       const EVP_MD *evp_md = EVP_sha1();
        EVP_MD_CTX md;
-       u_char *digest, *sigblob;
+       u_char digest[EVP_MAX_MD_SIZE], *sigblob;
        u_int len, dlen;
        int rlen, ret;
        Buffer b;
@@ -145,7 +142,7 @@ ssh_dss_verify(
                sigblob = buffer_get_string(&b, &len);
                rlen = buffer_len(&b);
                buffer_free(&b);
-               if(rlen != 0) {
+               if (rlen != 0) {
                        error("ssh_dss_verify: "
                            "remaining bytes in signature %d", rlen);
                        xfree(sigblob);
@@ -158,9 +155,12 @@ ssh_dss_verify(
        }
 
        /* parse signature */
-       sig = DSA_SIG_new();
-       sig->r = BN_new();
-       sig->s = BN_new();
+       if ((sig = DSA_SIG_new()) == NULL)
+               fatal("ssh_dss_verify: DSA_SIG_new failed");
+       if ((sig->r = BN_new()) == NULL)
+               fatal("ssh_dss_verify: BN_new failed");
+       if ((sig->s = BN_new()) == NULL)
+               fatal("ssh_dss_verify: BN_new failed");
        BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
        BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
 
@@ -170,16 +170,13 @@ ssh_dss_verify(
        }
 
        /* sha1 the data */
-       dlen = evp_md->md_size;
-       digest = xmalloc(dlen);
        EVP_DigestInit(&md, evp_md);
        EVP_DigestUpdate(&md, data, datalen);
-       EVP_DigestFinal(&md, digest, NULL);
+       EVP_DigestFinal(&md, digest, &dlen);
 
        ret = DSA_do_verify(digest, dlen, sig, key->dsa);
+       memset(digest, 'd', sizeof(digest));
 
-       memset(digest, 0, dlen);
-       xfree(digest);
        DSA_SIG_free(sig);
 
        debug("ssh_dss_verify: signature %s",
index 0613acba31fe3cbeb1b889323d23378055026a6b..94961b1e8ca7badd47fc9d8cbc7bd71ff2e8718a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh-dss.h,v 1.5 2001/06/26 17:27:25 markus Exp $      */
+/*     $OpenBSD: ssh-dss.h,v 1.6 2002/02/24 19:14:59 markus Exp $      */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -26,7 +26,7 @@
 #ifndef DSA_H
 #define DSA_H
 
-int     ssh_dss_sign(Key *, u_char **, int *, u_char *, int);
-int     ssh_dss_verify(Key *, u_char *, int, u_char *, int);
+int     ssh_dss_sign(Key *, u_char **, u_int *, u_char *, u_int);
+int     ssh_dss_verify(Key *, u_char *, u_int, u_char *, u_int);
 
 #endif
index 622cb5c9973974ab449271d96fd42c31ee176990..6ad94e6eb95ac0f611631ae33e20558de037efdd 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-keygen.1,v 1.50 2001/10/25 21:14:32 markus Exp $
+.\"    $OpenBSD: ssh-keygen.1,v 1.53 2002/02/16 14:53:37 stevesk Exp $
 .\"
 .\"  -*- nroff -*-
 .\"
@@ -47,7 +47,7 @@
 .Nm ssh-keygen
 .Op Fl q
 .Op Fl b Ar bits
-.Op Fl t Ar type
+.Fl t Ar type
 .Op Fl N Ar new_passphrase
 .Op Fl C Ar comment
 .Op Fl f Ar output_keyfile
 generates, manages and converts authentication keys for
 .Xr ssh 1 .
 .Nm
-defaults to generating a RSA1 key for use by SSH protocol version 1.
-Specifying the
+can create RSA keys for use by SSH protocol version 1 and RSA or DSA 
+keys for use by SSH protocol version 2. The type of key to be generated
+is specified with the
 .Fl t
-option instead creates a key for use by SSH protocol version 2.
+option.
 .Pp
 Normally each user wishing to use SSH
 with RSA or DSA authentication runs this once to create the authentication
@@ -111,10 +112,14 @@ The program also asks for a passphrase.
 The passphrase may be empty to indicate no passphrase
 (host keys must have an empty passphrase), or it may be a string of
 arbitrary length.
-Good passphrases are 10-30 characters long and are
+A passphrase is similar to a password, except it can be a phrase with a
+series of words, punctuation, numbers, whitespace, or any string of
+characters you want.
+Good passphrases are 10-30 characters long, are
 not simple sentences or otherwise easily guessable (English
 prose has only 1-2 bits of entropy per character, and provides very bad
-passphrases).
+passphrases), and contain a mix of upper and lowercase letters,
+numbers, and non-alphanumeric characters.
 The passphrase can be changed later by using the
 .Fl p
 option.
@@ -198,8 +203,6 @@ for protocol version 1 and
 or
 .Dq dsa
 for protocol version 2.
-The default is
-.Dq rsa1 .
 .It Fl B
 Show the bubblebabble digest of specified private or public key file.
 .It Fl C Ar comment
index 6d509972fa52558cbe7b6ced9bbcdf35b1202077..6aff4a444aed1318e961d481ff560409381a8307 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.83 2001/10/25 21:14:32 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.94 2002/02/25 16:33:27 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/pem.h>
@@ -73,8 +73,7 @@ int convert_to_ssh2 = 0;
 int convert_from_ssh2 = 0;
 int print_public = 0;
 
-/* default to RSA for SSH-1 */
-char *key_type_name = "rsa1";
+char *key_type_name = NULL;
 
 /* argv0 */
 #ifdef HAVE___PROGNAME
@@ -91,21 +90,25 @@ ask_filename(struct passwd *pw, const char *prompt)
        char buf[1024];
        char *name = NULL;
 
-       switch (key_type_from_name(key_type_name)) {
-       case KEY_RSA1:
-               name = _PATH_SSH_CLIENT_IDENTITY;
-               break;
-       case KEY_DSA:
-               name = _PATH_SSH_CLIENT_ID_DSA;
-               break;
-       case KEY_RSA:
+       if (key_type_name == NULL)
                name = _PATH_SSH_CLIENT_ID_RSA;
-               break;
-       default:
-               fprintf(stderr, "bad key type");
-               exit(1);
-               break;
-       }
+       else
+               switch (key_type_from_name(key_type_name)) {
+               case KEY_RSA1:
+                       name = _PATH_SSH_CLIENT_IDENTITY;
+                       break;
+               case KEY_DSA:
+                       name = _PATH_SSH_CLIENT_ID_DSA;
+                       break;
+               case KEY_RSA:
+                       name = _PATH_SSH_CLIENT_ID_RSA;
+                       break;
+               default:
+                       fprintf(stderr, "bad key type");
+                       exit(1);
+                       break;
+               }
+
        snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
        fprintf(stderr, "%s (%s): ", prompt, identity_file);
        fflush(stderr);
@@ -147,7 +150,7 @@ static void
 do_convert_to_ssh2(struct passwd *pw)
 {
        Key *k;
-       int len;
+       u_int len;
        u_char *blob;
        struct stat st;
 
@@ -188,12 +191,12 @@ buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
        if (buffer_len(b) < bytes)
                fatal("buffer_get_bignum_bits: input buffer too small: "
                    "need %d have %d", bytes, buffer_len(b));
-       BN_bin2bn((u_char *)buffer_ptr(b), bytes, value);
+       BN_bin2bn(buffer_ptr(b), bytes, value);
        buffer_consume(b, bytes);
 }
 
 static Key *
-do_convert_private_ssh2_from_blob(u_char *blob, int blen)
+do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
 {
        Buffer b;
        Key *key = NULL;
@@ -272,7 +275,7 @@ do_convert_private_ssh2_from_blob(u_char *blob, int blen)
                break;
        }
        rlen = buffer_len(&b);
-       if(rlen != 0)
+       if (rlen != 0)
                error("do_convert_private_ssh2_from_blob: "
                    "remaining bytes in key blob %d", rlen);
        buffer_free(&b);
@@ -333,7 +336,7 @@ do_convert_from_ssh2(struct passwd *pw)
                *p = '\0';
                strlcat(encoded, line, sizeof(encoded));
        }
-       blen = uudecode(encoded, (u_char *)blob, sizeof(blob));
+       blen = uudecode(encoded, blob, sizeof(blob));
        if (blen < 0) {
                fprintf(stderr, "uudecode failed.\n");
                exit(1);
@@ -355,7 +358,8 @@ do_convert_from_ssh2(struct passwd *pw)
                exit(1);
        }
        key_free(k);
-       fprintf(stdout, "\n");
+       if (!private)
+               fprintf(stdout, "\n");
        fclose(fp);
        exit(0);
 }
@@ -393,7 +397,7 @@ do_print_public(struct passwd *pw)
                debug("#bytes %d", len); \
                if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
                        goto done; \
-       } while(0)
+       } while (0)
 
 static int
 get_AUT0(char *aut0)
@@ -534,7 +538,9 @@ 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, rep, fptype;
+       int i, skip = 0, num = 1, invalid = 1;
+       enum fp_rep rep;
+       enum fp_type fptype;
        struct stat st;
 
        fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
@@ -668,7 +674,7 @@ do_change_passphrase(struct passwd *pw)
                        read_passphrase("Enter new passphrase (empty for no "
                            "passphrase): ", RP_ALLOW_STDIN);
                passphrase2 = read_passphrase("Enter same passphrase again: ",
-                    RP_ALLOW_STDIN);
+                   RP_ALLOW_STDIN);
 
                /* Verify that they are the same. */
                if (strcmp(passphrase1, passphrase2) != 0) {
@@ -746,7 +752,7 @@ do_change_comment(struct passwd *pw)
                fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
                key_free(private);
                exit(1);
-       }       
+       }
        printf("Key now has comment '%s'\n", comment);
 
        if (identity_comment) {
@@ -833,7 +839,7 @@ usage(void)
 int
 main(int ac, char **av)
 {
-       char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
+       char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
        char *reader_id = NULL;
        Key *private, *public;
        struct passwd *pw;
@@ -845,8 +851,6 @@ main(int ac, char **av)
        extern char *optarg;
 
        __progname = get_progname(av[0]);
-       init_rng();
-       seed_rng();
 
        SSLeay_add_all_algorithms();
 
@@ -962,8 +966,14 @@ main(int ac, char **av)
 #endif /* SMARTCARD */
        }
 
+       init_rng();
+       seed_rng();
        arc4random_stir();
 
+       if (key_type_name == NULL) {
+               printf("You must specify a key type (-t).\n");
+               usage();
+       }
        type = key_type_from_name(key_type_name);
        if (type == KEY_UNSPEC) {
                fprintf(stderr, "unknown key type %s\n", key_type_name);
index 17f73406e750569c01c6f605d42ab70acfc9cb1e..2f33ddf2068e82eea1ef642be87287f92b7cd963 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: ssh-keyscan.1,v 1.12 2001/09/05 06:23:07 deraadt Exp $
+.\"    $OpenBSD: ssh-keyscan.1,v 1.14 2002/02/13 08:33:47 mpech Exp $
 .\"
 .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
 .\"
@@ -104,7 +104,7 @@ Print the
 host key for machine
 .Pa hostname :
 .Bd -literal
-ssh-keyscan hostname
+ssh-keyscan hostname
 .Ed
 .Pp
 Find all hosts from the file
@@ -112,7 +112,7 @@ Find all hosts from the file
 which have new or different keys from those in the sorted file
 .Pa ssh_known_hosts :
 .Bd -literal
-ssh-keyscan -t rsa,dsa -f ssh_hosts | \e\ 
+ssh-keyscan -t rsa,dsa -f ssh_hosts | \e\ 
        sort -u - ssh_known_hosts | diff ssh_known_hosts -
 .Ed
 .Sh FILES
@@ -138,7 +138,7 @@ is either
 or
 .Dq ssh-dsa .
 .Pp
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh/ssh_known_hosts
 .Sh BUGS
 It generates "Connection closed by remote host" messages on the consoles
 of all the machines it scans if the server is older than version 2.9.
index 3fbe88d5601c1999aa52f5d8daddec0cf4f5297f..824264c32bcd150ed5bef58493d157d0a5bc1163 100644 (file)
@@ -7,7 +7,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.30 2001/10/08 19:05:05 markus Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.35 2002/03/04 18:30:23 stevesk Exp $");
 
 #if defined(HAVE_SYS_QUEUE_H) && !defined(HAVE_BOGUS_SYS_QUEUE_H)
 #include <sys/queue.h>
@@ -493,8 +493,9 @@ static void
 congreet(int s)
 {
        char buf[256], *cp;
+       char remote_version[sizeof buf];
        size_t bufsiz;
-       int n = 0;
+       int remote_major, remote_minor, n = 0;
        con *c = &fdcon[s];
 
        bufsiz = sizeof(buf);
@@ -510,26 +511,32 @@ congreet(int s)
                conrecycle(s);
                return;
        }
+       if (n == 0) {
+               error("%s: Connection closed by remote host", c->c_name);
+               conrecycle(s);
+               return;
+       }
        if (*cp != '\n' && *cp != '\r') {
                error("%s: bad greeting", c->c_name);
                confree(s);
                return;
        }
        *cp = '\0';
+       if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
+           &remote_major, &remote_minor, remote_version) == 3)
+               compat_datafellows(remote_version);
+       else
+               datafellows = 0;
        if (c->c_keytype != KT_RSA1) {
-               int remote_major, remote_minor;
-               char remote_version[sizeof buf];
-
-               if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
-                   &remote_major, &remote_minor, remote_version) == 3)
-                       compat_datafellows(remote_version);
-               else
-                       datafellows = 0;
                if (!ssh2_capable(remote_major, remote_minor)) {
                        debug("%s doesn't support ssh2", c->c_name);
                        confree(s);
                        return;
                }
+       } else if (remote_major != 1) {
+               debug("%s doesn't support ssh1", c->c_name);
+               confree(s);
+               return;
        }
        fprintf(stderr, "# %s %s\n", c->c_name, chop(buf));
        n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
@@ -647,6 +654,8 @@ do_host(char *host)
        char *name = strnnsep(&host, " \t\n");
        int j;
 
+       if (name == NULL)
+               return;
        for (j = KT_RSA1; j <= KT_RSA; j *= 2) {
                if (get_keytypes & j) {
                        while (ncon >= MAXCON)
@@ -656,11 +665,17 @@ do_host(char *host)
        }
 }
 
-static void
-fatal_callback(void *arg)
+void
+fatal(const char *fmt,...)
 {
+       va_list args;
+       va_start(args, fmt);
+       do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+       va_end(args);
        if (nonfatal_fatal)
                longjmp(kexjmp, -1);
+       else
+               fatal_cleanup();
 }
 
 static void
@@ -673,9 +688,9 @@ usage(void)
        fprintf(stderr, "  -p port     Connect to the specified port.\n");
        fprintf(stderr, "  -t keytype  Specify the host key type.\n");
        fprintf(stderr, "  -T timeout  Set connection timeout.\n");
-        fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
-        fprintf(stderr, "  -4          Use IPv4 only.\n");
-        fprintf(stderr, "  -6          Use IPv6 only.\n");
+       fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
+       fprintf(stderr, "  -4          Use IPv4 only.\n");
+       fprintf(stderr, "  -6          Use IPv6 only.\n");
        exit(1);
 }
 
@@ -742,7 +757,7 @@ main(int argc, char **argv)
                                        get_keytypes |= KT_RSA;
                                        break;
                                case KEY_UNSPEC:
-                                       fatal("unknown key type %s\n", tname);
+                                       fatal("unknown key type %s", tname);
                                }
                                tname = strtok(NULL, ",");
                        }
@@ -762,7 +777,6 @@ main(int argc, char **argv)
                usage();
 
        log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1);
-       fatal_add_cleanup(fatal_callback, NULL);
 
        maxfd = fdlim_get(1);
        if (maxfd < 0)
diff --git a/openssh/ssh-rand-helper.c b/openssh/ssh-rand-helper.c
new file mode 100644 (file)
index 0000000..28ea659
--- /dev/null
@@ -0,0 +1,809 @@
+/*
+ * Copyright (c) 2001-2002 Damien Miller.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include <openssl/crypto.h>
+
+/* SunOS 4.4.4 needs this */
+#ifdef HAVE_FLOATINGPOINT_H
+# include <floatingpoint.h>
+#endif /* HAVE_FLOATINGPOINT_H */
+
+#include "misc.h"
+#include "xmalloc.h"
+#include "atomicio.h"
+#include "pathnames.h"
+#include "log.h"
+
+RCSID("$Id$");
+
+/* Number of bytes we write out */
+#define OUTPUT_SEED_SIZE       48
+
+/* Length of on-disk seedfiles */
+#define SEED_FILE_SIZE         1024
+
+/* Maximum number of command-line arguments to read from file */
+#define NUM_ARGS               10
+
+/* Minimum number of usable commands to be considered sufficient */
+#define MIN_ENTROPY_SOURCES    16
+
+/* Path to on-disk seed file (relative to user's home directory */
+#ifndef SSH_PRNG_SEED_FILE
+# define SSH_PRNG_SEED_FILE      _PATH_SSH_USER_DIR"/prng_seed"
+#endif
+
+/* Path to PRNG commands list */
+#ifndef SSH_PRNG_COMMAND_FILE
+# define SSH_PRNG_COMMAND_FILE   SSHDIR "/ssh_prng_cmds"
+#endif
+
+
+#ifdef HAVE___PROGNAME
+extern char *__progname;
+#else
+char *__progname;
+#endif
+
+#ifndef offsetof
+# define offsetof(type, member) ((size_t) &((type *)0)->member)
+#endif
+
+#define WHITESPACE " \t\n"
+
+#ifndef RUSAGE_SELF
+# define RUSAGE_SELF 0
+#endif
+#ifndef RUSAGE_CHILDREN
+# define RUSAGE_CHILDREN 0
+#endif
+
+#if !defined(PRNGD_SOCKET) && !defined(PRNGD_PORT)
+# define USE_SEED_FILES
+#endif
+
+typedef struct {
+       /* Proportion of data that is entropy */
+       double rate;
+       /* Counter goes positive if this command times out */
+       unsigned int badness;
+       /* Increases by factor of two each timeout */
+       unsigned int sticky_badness;
+       /* Path to executable */
+       char *path;
+       /* argv to pass to executable */
+       char *args[NUM_ARGS]; /* XXX: arbitrary limit */
+       /* full command string (debug) */
+       char *cmdstring;
+} entropy_cmd_t;
+
+/* slow command timeouts (all in milliseconds) */
+/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */
+static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC;
+
+/* this is initialised from a file, by prng_read_commands() */
+static entropy_cmd_t *entropy_cmds = NULL;
+
+/* Prototypes */
+double stir_from_system(void);
+double stir_from_programs(void);
+double stir_gettimeofday(double entropy_estimate);
+double stir_clock(double entropy_estimate);
+double stir_rusage(int who, double entropy_estimate);
+double hash_command_output(entropy_cmd_t *src, char *hash);
+int get_random_bytes_prngd(unsigned char *buf, int len, 
+    unsigned short tcp_port, char *socket_path);
+
+/*
+ * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
+ * listening either on 'tcp_port', or via Unix domain socket at *
+ * 'socket_path'.
+ * Either a non-zero tcp_port or a non-null socket_path must be 
+ * supplied.
+ * Returns 0 on success, -1 on error
+ */
+int
+get_random_bytes_prngd(unsigned char *buf, int len, 
+    unsigned short tcp_port, char *socket_path)
+{
+       int fd, addr_len, rval, errors;
+       char msg[2];
+       struct sockaddr_storage addr;
+       struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
+       struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
+       mysig_t old_sigpipe;
+
+       /* Sanity checks */
+       if (socket_path == NULL && tcp_port == 0)
+               fatal("You must specify a port or a socket");
+       if (socket_path != NULL &&
+           strlen(socket_path) >= sizeof(addr_un->sun_path))
+               fatal("Random pool path is too long");
+       if (len > 255)
+               fatal("Too many bytes to read from PRNGD");
+
+       memset(&addr, '\0', sizeof(addr));
+
+       if (tcp_port != 0) {
+               addr_in->sin_family = AF_INET;
+               addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+               addr_in->sin_port = htons(tcp_port);
+               addr_len = sizeof(*addr_in);
+       } else {
+               addr_un->sun_family = AF_UNIX;
+               strlcpy(addr_un->sun_path, socket_path,
+                   sizeof(addr_un->sun_path));
+               addr_len = offsetof(struct sockaddr_un, sun_path) +
+                   strlen(socket_path) + 1;
+       }
+
+       old_sigpipe = mysignal(SIGPIPE, SIG_IGN);
+
+       errors = 0;
+       rval = -1;
+reopen:
+       fd = socket(addr.ss_family, SOCK_STREAM, 0);
+       if (fd == -1) {
+               error("Couldn't create socket: %s", strerror(errno));
+               goto done;
+       }
+
+       if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
+               if (tcp_port != 0) {
+                       error("Couldn't connect to PRNGD port %d: %s",
+                           tcp_port, strerror(errno));
+               } else {
+                       error("Couldn't connect to PRNGD socket \"%s\": %s",
+                           addr_un->sun_path, strerror(errno));
+               }
+               goto done;
+       }
+
+       /* Send blocking read request to PRNGD */
+       msg[0] = 0x02;
+       msg[1] = len;
+
+       if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
+               if (errno == EPIPE && errors < 10) {
+                       close(fd);
+                       errors++;
+                       goto reopen;
+               }
+               error("Couldn't write to PRNGD socket: %s",
+                   strerror(errno));
+               goto done;
+       }
+
+       if (atomicio(read, fd, buf, len) != len) {
+               if (errno == EPIPE && errors < 10) {
+                       close(fd);
+                       errors++;
+                       goto reopen;
+               }
+               error("Couldn't read from PRNGD socket: %s",
+                   strerror(errno));
+               goto done;
+       }
+
+       rval = 0;
+done:
+       mysignal(SIGPIPE, old_sigpipe);
+       if (fd != -1)
+               close(fd);
+       return rval;
+}
+
+double
+stir_gettimeofday(double entropy_estimate)
+{
+       struct timeval tv;
+
+       if (gettimeofday(&tv, NULL) == -1)
+               fatal("Couldn't gettimeofday: %s", strerror(errno));
+
+       RAND_add(&tv, sizeof(tv), entropy_estimate);
+
+       return entropy_estimate;
+}
+
+double
+stir_clock(double entropy_estimate)
+{
+#ifdef HAVE_CLOCK
+       clock_t c;
+
+       c = clock();
+       RAND_add(&c, sizeof(c), entropy_estimate);
+
+       return entropy_estimate;
+#else /* _HAVE_CLOCK */
+       return 0;
+#endif /* _HAVE_CLOCK */
+}
+
+double
+stir_rusage(int who, double entropy_estimate)
+{
+#ifdef HAVE_GETRUSAGE
+       struct rusage ru;
+
+       if (getrusage(who, &ru) == -1)
+               return 0;
+
+       RAND_add(&ru, sizeof(ru), entropy_estimate);
+
+       return entropy_estimate;
+#else /* _HAVE_GETRUSAGE */
+       return 0;
+#endif /* _HAVE_GETRUSAGE */
+}
+
+static int
+timeval_diff(struct timeval *t1, struct timeval *t2)
+{
+       int secdiff, usecdiff;
+
+       secdiff = t2->tv_sec - t1->tv_sec;
+       usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec);
+       return (int)(usecdiff / 1000);
+}
+
+double
+hash_command_output(entropy_cmd_t *src, char *hash)
+{
+       char buf[8192];
+       fd_set rdset;
+       int bytes_read, cmd_eof, error_abort, msec_elapsed, p[2];
+       int status, total_bytes_read;
+       static int devnull = -1;
+       pid_t pid;
+       SHA_CTX sha;
+       struct timeval tv_start, tv_current;
+
+       debug3("Reading output from \'%s\'", src->cmdstring);
+
+       if (devnull == -1) {
+               devnull = open("/dev/null", O_RDWR);
+               if (devnull == -1)
+                       fatal("Couldn't open /dev/null: %s", 
+                           strerror(errno));
+       }
+
+       if (pipe(p) == -1)
+               fatal("Couldn't open pipe: %s", strerror(errno));
+
+       (void)gettimeofday(&tv_start, NULL); /* record start time */
+
+       switch (pid = fork()) {
+               case -1: /* Error */
+                       close(p[0]);
+                       close(p[1]);
+                       fatal("Couldn't fork: %s", strerror(errno));
+                       /* NOTREACHED */
+               case 0: /* Child */
+                       dup2(devnull, STDIN_FILENO);
+                       dup2(p[1], STDOUT_FILENO);
+                       dup2(p[1], STDERR_FILENO);
+                       close(p[0]);
+                       close(p[1]);
+                       close(devnull);
+
+                       execv(src->path, (char**)(src->args));
+
+                       debug("(child) Couldn't exec '%s': %s", 
+                           src->cmdstring, strerror(errno));
+                       _exit(-1);
+               default: /* Parent */
+                       break;
+       }
+
+       RAND_add(&pid, sizeof(&pid), 0.0);
+
+       close(p[1]);
+
+       /* Hash output from child */
+       SHA1_Init(&sha);
+
+       cmd_eof = error_abort = msec_elapsed = total_bytes_read = 0;
+       while (!error_abort && !cmd_eof) {
+               int ret;
+               struct timeval tv;
+               int msec_remaining;
+
+               (void) gettimeofday(&tv_current, 0);
+               msec_elapsed = timeval_diff(&tv_start, &tv_current);
+               if (msec_elapsed >= entropy_timeout_current) {
+                       error_abort=1;
+                       continue;
+               }
+               msec_remaining = entropy_timeout_current - msec_elapsed;
+
+               FD_ZERO(&rdset);
+               FD_SET(p[0], &rdset);
+               tv.tv_sec = msec_remaining / 1000;
+               tv.tv_usec = (msec_remaining % 1000) * 1000;
+
+               ret = select(p[0] + 1, &rdset, NULL, NULL, &tv);
+
+               RAND_add(&tv, sizeof(tv), 0.0);
+
+               switch (ret) {
+               case 0:
+                       /* timer expired */
+                       error_abort = 1;
+                       break;
+               case 1:
+                       /* command input */
+                       do {
+                               bytes_read = read(p[0], buf, sizeof(buf));
+                       } while (bytes_read == -1 && errno == EINTR);
+                       RAND_add(&bytes_read, sizeof(&bytes_read), 0.0);
+                       if (bytes_read == -1) {
+                               error_abort = 1;
+                               break;
+                       } else if (bytes_read) {
+                               SHA1_Update(&sha, buf, bytes_read);
+                               total_bytes_read += bytes_read;
+                       } else {
+                               cmd_eof = 1;
+                       }
+                       break;
+               case -1:
+               default:
+                       /* error */
+                       debug("Command '%s': select() failed: %s", 
+                           src->cmdstring, strerror(errno));
+                       error_abort = 1;
+                       break;
+               }
+       }
+
+       SHA1_Final(hash, &sha);
+
+       close(p[0]);
+
+       debug3("Time elapsed: %d msec", msec_elapsed);
+
+       if (waitpid(pid, &status, 0) == -1) {
+              error("Couldn't wait for child '%s' completion: %s",
+                  src->cmdstring, strerror(errno));
+               return 0.0;
+       }
+
+       RAND_add(&status, sizeof(&status), 0.0);
+
+       if (error_abort) {
+               /*
+                * Closing p[0] on timeout causes the entropy command to
+                * SIGPIPE. Take whatever output we got, and mark this 
+                * command as slow 
+                */
+               debug2("Command '%s' timed out", src->cmdstring);
+               src->sticky_badness *= 2;
+               src->badness = src->sticky_badness;
+               return total_bytes_read;
+       }
+
+       if (WIFEXITED(status)) {
+               if (WEXITSTATUS(status) == 0) {
+                       return total_bytes_read;
+               } else {
+                       debug2("Command '%s' exit status was %d",
+                           src->cmdstring, WEXITSTATUS(status));
+                       src->badness = src->sticky_badness = 128;
+                       return 0.0;
+               }
+       } else if (WIFSIGNALED(status)) {
+               debug2("Command '%s' returned on uncaught signal %d !",
+                   src->cmdstring, status);
+               src->badness = src->sticky_badness = 128;
+               return 0.0;
+       } else
+               return 0.0;
+}
+
+double
+stir_from_system(void)
+{
+       double total_entropy_estimate;
+       long int i;
+
+       total_entropy_estimate = 0;
+
+       i = getpid();
+       RAND_add(&i, sizeof(i), 0.5);
+       total_entropy_estimate += 0.1;
+
+       i = getppid();
+       RAND_add(&i, sizeof(i), 0.5);
+       total_entropy_estimate += 0.1;
+
+       i = getuid();
+       RAND_add(&i, sizeof(i), 0.0);
+       i = getgid();
+       RAND_add(&i, sizeof(i), 0.0);
+
+       total_entropy_estimate += stir_gettimeofday(1.0);
+       total_entropy_estimate += stir_clock(0.5);
+       total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0);
+
+       return total_entropy_estimate;
+}
+
+double
+stir_from_programs(void)
+{
+       int c;
+       double entropy, total_entropy;
+       char hash[SHA_DIGEST_LENGTH];
+
+       total_entropy = 0;
+       for(c = 0; entropy_cmds[c].path != NULL; c++) {
+               if (!entropy_cmds[c].badness) {
+                       /* Hash output from command */
+                       entropy = hash_command_output(&entropy_cmds[c],
+                           hash);
+
+                       /* Scale back estimate by command's rate */
+                       entropy *= entropy_cmds[c].rate;
+
+                       /* Upper bound of entropy is SHA_DIGEST_LENGTH */
+                       if (entropy > SHA_DIGEST_LENGTH)
+                               entropy = SHA_DIGEST_LENGTH;
+
+                       /* Stir it in */
+                       RAND_add(hash, sizeof(hash), entropy);
+
+                       debug3("Got %0.2f bytes of entropy from '%s'", 
+                           entropy, entropy_cmds[c].cmdstring);
+
+                       total_entropy += entropy;
+
+                       /* Execution time should be a bit unpredictable */
+                       total_entropy += stir_gettimeofday(0.05);
+                       total_entropy += stir_clock(0.05);
+                       total_entropy += stir_rusage(RUSAGE_SELF, 0.1);
+                       total_entropy += stir_rusage(RUSAGE_CHILDREN, 0.1);
+               } else {
+                       debug2("Command '%s' disabled (badness %d)",
+                           entropy_cmds[c].cmdstring, 
+                           entropy_cmds[c].badness);
+
+                       if (entropy_cmds[c].badness > 0)
+                               entropy_cmds[c].badness--;
+               }
+       }
+
+       return total_entropy;
+}
+
+/*
+ * prng seedfile functions
+ */
+int
+prng_check_seedfile(char *filename)
+{
+       struct stat st;
+
+       /*
+        * XXX raceable: eg replace seed between this stat and subsequent 
+        * open. Not such a problem because we don't really trust the 
+        * seed file anyway.
+        * XXX: use secure path checking as elsewhere in OpenSSH
+        */
+       if (lstat(filename, &st) == -1) {
+               /* Give up on hard errors */
+               if (errno != ENOENT)
+                       debug("WARNING: Couldn't stat random seed file "
+                           "\"%.100s\": %s", filename, strerror(errno));
+               return 0;
+       }
+
+       /* regular file? */
+       if (!S_ISREG(st.st_mode))
+               fatal("PRNG seedfile %.100s is not a regular file",
+                   filename);
+
+       /* mode 0600, owned by root or the current user? */
+       if (((st.st_mode & 0177) != 0) || !(st.st_uid == getuid())) {
+               debug("WARNING: PRNG seedfile %.100s must be mode 0600, "
+                   "owned by uid %d", filename, getuid());
+               return 0;
+       }
+
+       return 1;
+}
+
+void
+prng_write_seedfile(void)
+{
+       int fd;
+       char seed[SEED_FILE_SIZE], filename[MAXPATHLEN];
+       struct passwd *pw;
+
+       pw = getpwuid(getuid());
+       if (pw == NULL)
+               fatal("Couldn't get password entry for current user "
+                   "(%i): %s", getuid(), strerror(errno));
+
+       /* Try to ensure that the parent directory is there */
+       snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
+           _PATH_SSH_USER_DIR);
+       mkdir(filename, 0700);
+
+       snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
+           SSH_PRNG_SEED_FILE);
+
+       debug("writing PRNG seed to file %.100s", filename);
+
+       RAND_bytes(seed, sizeof(seed));
+
+       /* Don't care if the seed doesn't exist */
+       prng_check_seedfile(filename);
+
+       if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) {
+               debug("WARNING: couldn't access PRNG seedfile %.100s "
+                   "(%.100s)", filename, strerror(errno));
+       } else {
+               if (atomicio(write, fd, &seed, sizeof(seed)) < sizeof(seed))
+                       fatal("problem writing PRNG seedfile %.100s "
+                           "(%.100s)", filename, strerror(errno));
+               close(fd);
+       }
+}
+
+void
+prng_read_seedfile(void)
+{
+       int fd;
+       char seed[SEED_FILE_SIZE], filename[MAXPATHLEN];
+       struct passwd *pw;
+
+       pw = getpwuid(getuid());
+       if (pw == NULL)
+               fatal("Couldn't get password entry for current user "
+                   "(%i): %s", getuid(), strerror(errno));
+
+       snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
+               SSH_PRNG_SEED_FILE);
+
+       debug("loading PRNG seed from file %.100s", filename);
+
+       if (!prng_check_seedfile(filename)) {
+               verbose("Random seed file not found or invalid, ignoring.");
+               return;
+       }
+
+       /* open the file and read in the seed */
+       fd = open(filename, O_RDONLY);
+       if (fd == -1)
+               fatal("could not open PRNG seedfile %.100s (%.100s)",
+                   filename, strerror(errno));
+
+       if (atomicio(read, fd, &seed, sizeof(seed)) < sizeof(seed)) {
+               verbose("invalid or short read from PRNG seedfile "
+                   "%.100s - ignoring", filename);
+               memset(seed, '\0', sizeof(seed));
+       }
+       close(fd);
+
+       /* stir in the seed, with estimated entropy zero */
+       RAND_add(&seed, sizeof(seed), 0.0);
+}
+
+
+/*
+ * entropy command initialisation functions
+ */
+int
+prng_read_commands(char *cmdfilename)
+{
+       char cmd[SEED_FILE_SIZE], *cp, line[1024], path[SEED_FILE_SIZE];
+       double est;
+       entropy_cmd_t *entcmd;
+       FILE *f;
+       int cur_cmd, linenum, num_cmds, arg;
+
+       if ((f = fopen(cmdfilename, "r")) == NULL) {
+               fatal("couldn't read entropy commands file %.100s: %.100s",
+                   cmdfilename, strerror(errno));
+       }
+
+       num_cmds = 64;
+       entcmd = xmalloc(num_cmds * sizeof(entropy_cmd_t));
+       memset(entcmd, '\0', num_cmds * sizeof(entropy_cmd_t));
+
+       /* Read in file */
+       cur_cmd = linenum = 0;
+       while (fgets(line, sizeof(line), f)) {
+               linenum++;
+
+               /* Skip leading whitespace, blank lines and comments */
+               cp = line + strspn(line, WHITESPACE);
+               if ((*cp == 0) || (*cp == '#'))
+                       continue; /* done with this line */
+
+               /*
+                * The first non-whitespace char should be a double quote 
+                * delimiting the commandline
+                */
+               if (*cp != '"') {
+                       error("bad entropy command, %.100s line %d",
+                           cmdfilename, linenum);
+                       continue;
+               }
+
+               /*
+                * First token, command args (incl. argv[0]) in double
+                * quotes
+                */
+               cp = strtok(cp, "\"");
+               if (cp == NULL) {
+                       error("missing or bad command string, %.100s "
+                           "line %d -- ignored", cmdfilename, linenum);
+                       continue;
+               }
+               strlcpy(cmd, cp, sizeof(cmd));
+
+               /* Second token, full command path */
+               if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
+                       error("missing command path, %.100s "
+                           "line %d -- ignored", cmdfilename, linenum);
+                       continue;
+               }
+
+               /* Did configure mark this as dead? */
+               if (strncmp("undef", cp, 5) == 0)
+                       continue;
+
+               strlcpy(path, cp, sizeof(path));
+
+               /* Third token, entropy rate estimate for this command */
+               if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
+                       error("missing entropy estimate, %.100s "
+                           "line %d -- ignored", cmdfilename, linenum);
+                       continue;
+               }
+               est = strtod(cp, NULL);
+
+               /* end of line */
+               if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
+                       error("garbage at end of line %d in %.100s "
+                           "-- ignored", linenum, cmdfilename);
+                       continue;
+               }
+
+               /* save the command for debug messages */
+               entcmd[cur_cmd].cmdstring = xstrdup(cmd);
+
+               /* split the command args */
+               cp = strtok(cmd, WHITESPACE);
+               arg = 0;
+               do {
+                       entcmd[cur_cmd].args[arg] = xstrdup(cp);
+                       arg++;
+               } while(arg < NUM_ARGS && (cp = strtok(NULL, WHITESPACE)));
+
+               if (strtok(NULL, WHITESPACE))
+                       error("ignored extra commands (max %d), %.100s "
+                           "line %d", NUM_ARGS, cmdfilename, linenum);
+
+               /* Copy the command path and rate estimate */
+               entcmd[cur_cmd].path = xstrdup(path);
+               entcmd[cur_cmd].rate = est;
+
+               /* Initialise other values */
+               entcmd[cur_cmd].sticky_badness = 1;
+
+               cur_cmd++;
+
+               /*
+                * If we've filled the array, reallocate it twice the size
+                * Do this now because even if this we're on the last 
+                * command we need another slot to mark the last entry
+                */
+               if (cur_cmd == num_cmds) {
+                       num_cmds *= 2;
+                       entcmd = xrealloc(entcmd, num_cmds *
+                           sizeof(entropy_cmd_t));
+               }
+       }
+
+       /* zero the last entry */
+       memset(&entcmd[cur_cmd], '\0', sizeof(entropy_cmd_t));
+
+       /* trim to size */
+       entropy_cmds = xrealloc(entcmd, (cur_cmd + 1) *
+           sizeof(entropy_cmd_t));
+
+       debug("Loaded %d entropy commands from %.100s", cur_cmd,
+           cmdfilename);
+
+       return cur_cmd < MIN_ENTROPY_SOURCES ? -1 : 0;
+}
+
+int 
+main(int argc, char **argv)
+{
+       unsigned char buf[OUTPUT_SEED_SIZE];
+       int ret;
+
+       __progname = get_progname(argv[0]);
+       /* XXX: need some debugging mode */
+       log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
+
+#ifdef USE_SEED_FILES
+       prng_read_seedfile();
+#endif
+
+       /*
+        * Seed the RNG from wherever we can
+        */
+        
+       /* Take whatever is on the stack, but don't credit it */
+       RAND_add(buf, sizeof(buf), 0);
+
+       debug("Seeded RNG with %i bytes from system calls", 
+           (int)stir_from_system());
+
+#ifdef PRNGD_PORT
+       if (get_random_bytes_prngd(buf, sizeof(buf), PRNGD_PORT, NULL) == -1)
+               fatal("Entropy collection failed");
+       RAND_add(buf, sizeof(buf), sizeof(buf));
+#elif defined(PRNGD_SOCKET)
+       if (get_random_bytes_prngd(buf, sizeof(buf), 0, PRNGD_SOCKET) == -1)
+               fatal("Entropy collection failed");
+       RAND_add(buf, sizeof(buf), sizeof(buf));
+#else
+       /* Read in collection commands */
+       if (prng_read_commands(SSH_PRNG_COMMAND_FILE) == -1)
+               fatal("PRNG initialisation failed -- exiting.");
+       debug("Seeded RNG with %i bytes from programs", 
+           (int)stir_from_programs());
+#endif
+
+#ifdef USE_SEED_FILES
+       prng_write_seedfile();
+#endif
+
+       /*
+        * Write the seed to stdout
+        */
+
+       if (!RAND_status())
+               fatal("Not enough entropy in RNG");
+
+       RAND_bytes(buf, sizeof(buf));
+
+       ret = atomicio(write, STDOUT_FILENO, buf, sizeof(buf));
+               
+       memset(buf, '\0', sizeof(buf));
+       
+       return ret == sizeof(buf) ? 0 : 1;
+}
+
index a6a703b9511c6e040d376a943aded68e5698b478..8e79d4e1d310749269e80341b258c0155de08610 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-rsa.c,v 1.13 2001/11/10 13:22:42 markus Exp $");
+RCSID("$OpenBSD: ssh-rsa.c,v 1.16 2002/02/24 19:14:59 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -40,12 +40,12 @@ RCSID("$OpenBSD: ssh-rsa.c,v 1.13 2001/11/10 13:22:42 markus Exp $");
 int
 ssh_rsa_sign(
     Key *key,
-    u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+    u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
        const EVP_MD *evp_md;
        EVP_MD_CTX md;
-       u_char *digest, *sig, *ret;
+       u_char digest[EVP_MAX_MD_SIZE], *sig, *ret;
        u_int slen, dlen, len;
        int ok, nid;
        Buffer b;
@@ -63,18 +63,15 @@ ssh_rsa_sign(
                error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
                return -1;
        }
-       dlen = evp_md->md_size;
-       digest = xmalloc(dlen);
        EVP_DigestInit(&md, evp_md);
        EVP_DigestUpdate(&md, data, datalen);
-       EVP_DigestFinal(&md, digest, NULL);
+       EVP_DigestFinal(&md, digest, &dlen);
 
        slen = RSA_size(key->rsa);
        sig = xmalloc(slen);
 
        ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
-       memset(digest, 'd', dlen);
-       xfree(digest);
+       memset(digest, 'd', sizeof(digest));
 
        if (ok != 1) {
                int ecode = ERR_get_error();
@@ -113,14 +110,14 @@ ssh_rsa_sign(
 int
 ssh_rsa_verify(
     Key *key,
-    u_char *signature, int signaturelen,
-    u_char *data, int datalen)
+    u_char *signature, u_int signaturelen,
+    u_char *data, u_int datalen)
 {
        Buffer b;
        const EVP_MD *evp_md;
        EVP_MD_CTX md;
        char *ktype;
-       u_char *sigblob, *digest;
+       u_char digest[EVP_MAX_MD_SIZE], *sigblob;
        u_int len, dlen;
        int rlen, ret, nid;
 
@@ -150,7 +147,7 @@ ssh_rsa_verify(
        sigblob = buffer_get_string(&b, &len);
        rlen = buffer_len(&b);
        buffer_free(&b);
-       if(rlen != 0) {
+       if (rlen != 0) {
                error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
                xfree(sigblob);
                return -1;
@@ -161,15 +158,12 @@ ssh_rsa_verify(
                xfree(sigblob);
                return -1;
        }
-       dlen = evp_md->md_size;
-       digest = xmalloc(dlen);
        EVP_DigestInit(&md, evp_md);
        EVP_DigestUpdate(&md, data, datalen);
-       EVP_DigestFinal(&md, digest, NULL);
+       EVP_DigestFinal(&md, digest, &dlen);
 
        ret = RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
-       memset(digest, 'd', dlen);
-       xfree(digest);
+       memset(digest, 'd', sizeof(digest));
        memset(sigblob, 's', len);
        xfree(sigblob);
        if (ret == 0) {
index 11d355d583c9550984ae52877ce1d2e2c8209be4..7177a3f921132f296c33e1affff2c6d311cb7dcb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh-rsa.h,v 1.5 2001/06/26 17:27:25 markus Exp $      */
+/*     $OpenBSD: ssh-rsa.h,v 1.6 2002/02/24 19:14:59 markus Exp $      */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -26,7 +26,7 @@
 #ifndef SSH_RSA_H
 #define SSH_RSA_H
 
-int     ssh_rsa_sign(Key *, u_char **, int *, u_char *, int);
-int     ssh_rsa_verify(Key *, u_char *, int, u_char *, int);
+int     ssh_rsa_sign(Key *, u_char **, u_int *, u_char *, u_int);
+int     ssh_rsa_verify(Key *, u_char *, u_int, u_char *, u_int);
 
 #endif
index ad3c96023de221c359fab3c4bb7b42a3c236cf83..43b75dc23edde2779123cad7a716aacba47e2899 100644 (file)
@@ -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.
 .\"
-.\" $OpenBSD: ssh.1,v 1.141 2001/11/08 17:49:53 markus Exp $
+.\" $OpenBSD: ssh.1,v 1.148 2002/02/18 17:55:20 markus Exp $
 .Dd September 25, 1999
 .Dt SSH 1
 .Os
@@ -126,7 +126,7 @@ or
 .Pa /etc/shosts.equiv ,
 and if additionally the server can verify the client's
 host key (see
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh/ssh_known_hosts
 and
 .Pa $HOME/.ssh/known_hosts
 in the
@@ -207,8 +207,8 @@ the password cannot be seen by someone listening on the network.
 .Pp
 .Ss SSH protocol version 2
 .Pp
-When a user connects using the protocol version 2
-different authentication methods are available.
+When a user connects using protocol version 2
+similar authentication methods are available.
 Using the default values for
 .Cm PreferredAuthentications ,
 the client will try to authenticate first using the hostbased method;
@@ -365,7 +365,7 @@ Host keys are stored in
 .Pa $HOME/.ssh/known_hosts
 in the user's home directory.
 Additionally, the file
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh/ssh_known_hosts
 is automatically checked for known hosts.
 Any new hosts are automatically added to the user's file.
 If a host's identification
@@ -443,11 +443,15 @@ something like
 .It Fl g
 Allows remote hosts to connect to local forwarded ports.
 .It Fl i Ar identity_file
-Selects the file from which the identity (private key) for
+Selects a file from which the identity (private key) for
 RSA or DSA authentication is read.
-Default is
+The default is
 .Pa $HOME/.ssh/identity
-in the user's home directory.
+for protocol version 1, and
+.Pa $HOME/.ssh/id_rsa
+and
+.Pa $HOME/.ssh/id_dsa
+for protocol version 2.
 Identity files may also be specified on
 a per-host basis in the configuration file.
 It is possible to have multiple
@@ -517,7 +521,6 @@ for older servers.
 .It Fl q
 Quiet mode.
 Causes all warning and diagnostic messages to be suppressed.
-Only fatal errors are displayed.
 .It Fl s
 May be used to request invocation of a subsystem on the remote system. Subsystems are a feature of the SSH2 protocol which facilitate the use
 of SSH as a secure transport for other applications (eg. sftp). The
@@ -570,7 +573,7 @@ option below.
 Specifies an alternative per-user configuration file.
 If a configuration file is given on the command line,
 the system-wide configuration file
-.Pq Pa /etc/ssh_config
+.Pq Pa /etc/ssh/ssh_config
 will be ignored.
 The default for the per-user configuration file is
 .Pa $HOME/.ssh/config .
@@ -645,7 +648,7 @@ the following order:
 command line options, user's configuration file
 .Pq Pa $HOME/.ssh/config ,
 and system-wide configuration file
-.Pq Pa /etc/ssh_config .
+.Pq Pa /etc/ssh/ssh_config .
 For each parameter, the first obtained value
 will be used.
 The configuration files contain sections bracketed by
@@ -883,7 +886,7 @@ The default is
 .It Cm GlobalKnownHostsFile
 Specifies a file to use for the global
 host key database instead of
-.Pa /etc/ssh_known_hosts .
+.Pa /etc/ssh/ssh_known_hosts .
 .It Cm HostbasedAuthentication
 Specifies whether to try rhosts based authentication with public key
 authentication.
@@ -900,7 +903,7 @@ is similar to
 Specifies the protocol version 2 host key algorithms
 that the client wants to use in order of preference.
 The default for this option is:
-.Dq ssh-rsa,ssh-dss
+.Dq ssh-rsa,ssh-dss .
 .It Cm HostKeyAlias
 Specifies an alias that should be used instead of the
 real host name when looking up or saving the host key
@@ -915,10 +918,14 @@ Numeric IP addresses are also permitted (both on the command line and in
 .Cm HostName
 specifications).
 .It Cm IdentityFile
-Specifies the file from which the user's RSA or DSA authentication identity
-is read (default
+Specifies a file from which the user's RSA or DSA authentication identity
+is read. The default is
 .Pa $HOME/.ssh/identity
-in the user's home directory).
+for protocol version 1, and
+.Pa $HOME/.ssh/id_rsa
+and
+.Pa $HOME/.ssh/id_dsa
+for protocol version 2.
 Additionally, any identities represented by the authentication agent
 will be used for authentication.
 The file name may use the tilde
@@ -927,7 +934,7 @@ It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
 .It Cm KeepAlive
-Specifies whether the system should send keepalive messages to the
+Specifies whether the system should send TCP keepalive messages to the
 other side.
 If they are sent, death of the connection or crash of one
 of the machines will be properly noticed.
@@ -942,8 +949,7 @@ if the network goes down or the remote host dies.
 This is important in scripts, and many users want it too.
 .Pp
 To disable keepalives, the value should be set to
-.Dq no
-in both the server and the client configuration files.
+.Dq no .
 .It Cm KerberosAuthentication
 Specifies whether Kerberos authentication will be used.
 The argument to this keyword must be
@@ -971,8 +977,9 @@ Only the superuser can forward privileged ports.
 Gives the verbosity level that is used when logging messages from
 .Nm ssh .
 The possible values are:
-QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
-The default is INFO.
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+The default is INFO.  DEBUG and DEBUG1 are equivalent.  DEBUG2
+and DEBUG3 each specify higher levels of verbose output.
 .It Cm MACs
 Specifies the MAC (message authentication code) algorithms
 in order of preference.
@@ -1013,7 +1020,7 @@ authentication methods. This allows a client to prefer one method (e.g.
 over another method (e.g.
 .Cm password )
 The default for this option is:
-.Dq hostbased,publickey,keyboard-interactive,password
+.Dq hostbased,publickey,keyboard-interactive,password .
 .It Cm Protocol
 Specifies the protocol versions
 .Nm
@@ -1137,7 +1144,7 @@ will never automatically add host keys to the
 file, and refuses to connect to hosts whose host key has changed.
 This provides maximum protection against trojan horse attacks,
 however, can be annoying when the
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh/ssh_known_hosts
 file is poorly maintained, or connections to new hosts are
 frequently made.
 This option forces the user to manually
@@ -1305,7 +1312,7 @@ to the environment.
 .It Pa $HOME/.ssh/known_hosts
 Records host keys for all hosts the user has logged into that are not
 in
-.Pa /etc/ssh_known_hosts .
+.Pa /etc/ssh/ssh_known_hosts .
 See
 .Xr sshd 8 .
 .It Pa $HOME/.ssh/identity, $HOME/.ssh/id_dsa, $HOME/.ssh/id_rsa
@@ -1360,7 +1367,7 @@ In the simplest form the format is the same as the .pub
 identity files.
 This file is not highly sensitive, but the recommended
 permissions are read/write for the user, and not accessible by others.
-.It Pa /etc/ssh_known_hosts
+.It Pa /etc/ssh/ssh_known_hosts
 Systemwide list of known host keys.
 This file should be prepared by the
 system administrator to contain the public host keys of all machines in the
@@ -1383,13 +1390,13 @@ to verify the client host when logging in; other names are needed because
 does not convert the user-supplied name to a canonical name before
 checking the key, because someone with access to the name servers
 would then be able to fool host authentication.
-.It Pa /etc/ssh_config
+.It Pa /etc/ssh/ssh_config
 Systemwide configuration file.
 This file provides defaults for those
 values that are not specified in the user's configuration file, and
 for those users who do not have a configuration file.
 This file must be world-readable.
-.It Pa /etc/ssh_host_key, /etc/ssh_host_dsa_key, /etc/ssh_host_rsa_key
+.It Pa /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key
 These three files contain the private parts of the host keys
 and are used for
 .Cm RhostsRSAAuthentication
@@ -1424,7 +1431,7 @@ Note that by default
 will be installed so that it requires successful RSA host
 authentication before permitting \s+2.\s0rhosts authentication.
 If the server machine does not have the client's host key in
-.Pa /etc/ssh_known_hosts ,
+.Pa /etc/ssh/ssh_known_hosts ,
 it can be stored in
 .Pa $HOME/.ssh/known_hosts .
 The easiest way to do this is to
@@ -1461,7 +1468,7 @@ This file is processed exactly as
 This file may be useful to permit logins using
 .Nm
 but not using rsh/rlogin.
-.It Pa /etc/sshrc
+.It Pa /etc/ssh/sshrc
 Commands in this file are executed by
 .Nm
 when the user logs in just before the user's shell (or command) is started.
@@ -1481,6 +1488,10 @@ Contains additional definitions for environment variables, see section
 .Sx ENVIRONMENT
 above.
 .El
+.Sh DIAGNOSTICS
+.Nm
+exits with the exit status of the remote command or with 255
+if an error occurred.
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
index 2984a597fb88c200042e137c9f62ae49ea24414a..117a0930b0b4ef4529cd9e24e87e1340f24fb8de 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.149 2001/10/24 08:51:35 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.164 2002/02/14 23:28:00 markus Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
@@ -485,7 +485,7 @@ again:
                                    fwd_host_port);
                        else if (opt == 'R')
                                add_remote_forward(&options, fwd_port, buf,
-                                    fwd_host_port);
+                                   fwd_host_port);
                        break;
 
                case 'D':
@@ -787,19 +787,36 @@ again:
 }
 
 static void
-x11_get_proto(char *proto, int proto_len, char *data, int data_len)
+x11_get_proto(char **_proto, char **_data)
 {
        char line[512];
+       static char proto[512], data[512];
        FILE *f;
        int got_data = 0, i;
+       char *display;
 
-       if (options.xauth_location) {
+       *_proto = proto;
+       *_data = data;
+       proto[0] = data[0] = '\0';
+       if (options.xauth_location && (display = getenv("DISPLAY"))) {
                /* Try to get Xauthority information for the display. */
-               snprintf(line, sizeof line, "%.100s list %.200s 2>" _PATH_DEVNULL,
-                   options.xauth_location, getenv("DISPLAY"));
+               if (strncmp(display, "localhost:", 10) == 0)
+                       /*
+                        * Handle FamilyLocal case where $DISPLAY does
+                        * not match an authorization entry.  For this we
+                        * just try "xauth list unix:displaynum.screennum".
+                        * XXX: "localhost" match to determine FamilyLocal
+                        *      is not perfect.
+                        */
+                       snprintf(line, sizeof line, "%.100s list unix:%s 2>"
+                           _PATH_DEVNULL, options.xauth_location, display+10);
+               else
+                       snprintf(line, sizeof line, "%.100s list %.200s 2>"
+                           _PATH_DEVNULL, options.xauth_location, display);
+               debug2("x11_get_proto %s", line);
                f = popen(line, "r");
                if (f && fgets(line, sizeof(line), f) &&
-                   sscanf(line, "%*s %s %s", proto, data) == 2)
+                   sscanf(line, "%*s %511s %511s", proto, data) == 2)
                        got_data = 1;
                if (f)
                        pclose(f);
@@ -815,11 +832,11 @@ x11_get_proto(char *proto, int proto_len, char *data, int data_len)
        if (!got_data) {
                u_int32_t rand = 0;
 
-               strlcpy(proto, "MIT-MAGIC-COOKIE-1", proto_len);
+               strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
                for (i = 0; i < 16; i++) {
                        if (i % 4 == 0)
                                rand = arc4random();
-                       snprintf(data + 2 * i, data_len - 2 * i, "%02x", rand & 0xff);
+                       snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
                        rand >>= 8;
                }
        }
@@ -837,7 +854,7 @@ ssh_init_forwarding(void)
                    options.local_forwards[i].port,
                    options.local_forwards[i].host,
                    options.local_forwards[i].host_port);
-               success += channel_request_local_forwarding(
+               success += channel_setup_local_fwd_listener(
                    options.local_forwards[i].port,
                    options.local_forwards[i].host,
                    options.local_forwards[i].host_port,
@@ -876,7 +893,6 @@ static int
 ssh_session(void)
 {
        int type;
-       int plen;
        int interactive = 0;
        int have_tty = 0;
        struct winsize ws;
@@ -894,7 +910,7 @@ ssh_session(void)
                packet_put_int(options.compression_level);
                packet_send();
                packet_write_wait();
-               type = packet_read(&plen);
+               type = packet_read();
                if (type == SSH_SMSG_SUCCESS)
                        packet_start_compression(options.compression_level);
                else if (type == SSH_SMSG_FAILURE)
@@ -932,7 +948,7 @@ ssh_session(void)
                packet_write_wait();
 
                /* Read response from the server. */
-               type = packet_read(&plen);
+               type = packet_read();
                if (type == SSH_SMSG_SUCCESS) {
                        interactive = 1;
                        have_tty = 1;
@@ -943,15 +959,15 @@ ssh_session(void)
        }
        /* Request X11 forwarding if enabled and DISPLAY is set. */
        if (options.forward_x11 && getenv("DISPLAY") != NULL) {
-               char proto[512], data[512];
+               char *proto, *data;
                /* Get reasonable local authentication information. */
-               x11_get_proto(proto, sizeof proto, data, sizeof data);
+               x11_get_proto(&proto, &data);
                /* Request forwarding with authentication spoofing. */
                debug("Requesting X11 forwarding with authentication spoofing.");
                x11_request_forwarding_with_spoofing(0, proto, data);
 
                /* Read response from the server. */
-               type = packet_read(&plen);
+               type = packet_read();
                if (type == SSH_SMSG_SUCCESS) {
                        interactive = 1;
                } else if (type == SSH_SMSG_FAILURE) {
@@ -971,8 +987,8 @@ ssh_session(void)
                auth_request_forwarding();
 
                /* Read response from the server. */
-               type = packet_read(&plen);
-               packet_integrity_check(plen, 0, type);
+               type = packet_read();
+               packet_check_eom();
                if (type != SSH_SMSG_SUCCESS)
                        log("Warning: Remote host denied authentication agent forwarding.");
        }
@@ -993,7 +1009,7 @@ ssh_session(void)
                int len = buffer_len(&command);
                if (len > 900)
                        len = 900;
-               debug("Sending command: %.*s", len, 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();
@@ -1011,7 +1027,7 @@ ssh_session(void)
 }
 
 static void
-client_subsystem_reply(int type, int plen, void *ctxt)
+client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
 {
        int id, len;
 
@@ -1019,10 +1035,10 @@ client_subsystem_reply(int type, int plen, void *ctxt)
        len = buffer_len(&command);
        if (len > 900)
                len = 900;
-       packet_done();
+       packet_check_eom();
        if (type == SSH2_MSG_CHANNEL_FAILURE)
                fatal("Request for subsystem '%.*s' failed on channel %d",
-                   len, buffer_ptr(&command), id);
+                   len, (u_char *)buffer_ptr(&command), id);
 }
 
 /* request pty/x11/agent/tcpfwd/shell for channel */
@@ -1059,9 +1075,9 @@ ssh_session2_setup(int id, void *arg)
        }
        if (options.forward_x11 &&
            getenv("DISPLAY") != NULL) {
-               char proto[512], data[512];
+               char *proto, *data;
                /* Get reasonable local authentication information. */
-               x11_get_proto(proto, sizeof proto, data, sizeof data);
+               x11_get_proto(&proto, &data);
                /* Request forwarding with authentication spoofing. */
                debug("Requesting X11 forwarding with authentication spoofing.");
                x11_request_forwarding_with_spoofing(id, proto, data);
@@ -1081,24 +1097,23 @@ ssh_session2_setup(int id, void *arg)
                if (len > 900)
                        len = 900;
                if (subsystem_flag) {
-                       debug("Sending subsystem: %.*s", len, buffer_ptr(&command));
+                       debug("Sending subsystem: %.*s", len, (u_char *)buffer_ptr(&command));
                        channel_request_start(id, "subsystem", /*want reply*/ 1);
                        /* register callback for reply */
                        /* XXX we asume that client_loop has already been called */
                        dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &client_subsystem_reply);
                        dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &client_subsystem_reply);
                } else {
-                       debug("Sending command: %.*s", len, buffer_ptr(&command));
+                       debug("Sending command: %.*s", len, (u_char *)buffer_ptr(&command));
                        channel_request_start(id, "exec", 0);
                }
                packet_put_string(buffer_ptr(&command), buffer_len(&command));
                packet_send();
        } else {
-               channel_request(id, "shell", 0);
+               channel_request_start(id, "shell", 0);
+               packet_send();
        }
-       /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */
 
-       /* register different callback, etc. XXX */
        packet_set_interactive(interactive);
 }
 
@@ -1130,24 +1145,20 @@ ssh_session2_open(void)
 
        window = CHAN_SES_WINDOW_DEFAULT;
        packetmax = CHAN_SES_PACKET_DEFAULT;
-       if (!tty_flag) {
-               window *= 2;
-               packetmax *=2;
+       if (tty_flag) {
+               window >>= 1;
+               packetmax >>= 1;
        }
        c = channel_new(
            "session", SSH_CHANNEL_OPENING, in, out, err,
            window, packetmax, CHAN_EXTENDED_WRITE,
            xstrdup("client-session"), /*nonblock*/0);
-       if (c == NULL)
-               fatal("ssh_session2_open: channel_new failed");
 
        debug3("ssh_session2_open: channel_new: %d", c->self);
 
        channel_send_open(c->self);
        if (!no_shell_flag)
-               channel_register_callback(c->self,
-                    SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
-                    ssh_session2_setup, (void *)0);
+               channel_register_confirm(c->self, ssh_session2_setup);
 
        return c->self;
 }
index 383c7fe9b1c9214225718f62c951d0bbb5063d6f..fdf554df0105e55185e0bb17460132899b6b6f13 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: ssh.h,v 1.64 2002/03/04 17:27:39 stevesk Exp $        */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -10,8 +12,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: ssh.h,v 1.63 2001/05/24 18:57:53 stevesk Exp $"); */
-
 #ifndef SSH_H
 #define SSH_H
 
index e45aef275febbb8681de92fc9dc9ed842869e423..091e52b139f1ea65a3341394825f57b87b8d9c33 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: ssh2.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $        */
+
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  *
  *     192-255  Local extensions
  */
-/* RCSID("$OpenBSD: ssh2.h,v 1.6 2001/03/27 17:46:49 provos Exp $"); */
+
+/* ranges */
+
+#define SSH2_MSG_TRANSPORT_MIN                         1
+#define SSH2_MSG_TRANSPORT_MAX                         49
+#define SSH2_MSG_USERAUTH_MIN                          50
+#define SSH2_MSG_USERAUTH_MAX                          79
+#define SSH2_MSG_CONNECTION_MIN                                80
+#define SSH2_MSG_CONNECTION_MAX                                127
+#define SSH2_MSG_RESERVED_MIN                          128
+#define SSH2_MSG_RESERVED_MAX                          191
+#define SSH2_MSG_LOCAL_MIN                             192
+#define SSH2_MSG_LOCAL_MAX                             255
+#define SSH2_MSG_MIN                                   1
+#define SSH2_MSG_MAX                                   255
 
 /* transport layer: generic */
 
index 62093545444b2107ae06c049ebd410ced40bf529..a8a8d72abfc644e8a49888e0fe38754e889bdebc 100644 (file)
@@ -1,8 +1,9 @@
-#      $OpenBSD: ssh_config,v 1.10 2001/04/03 21:19:38 todd Exp $
+#      $OpenBSD: ssh_config,v 1.12 2002/01/16 17:55:33 stevesk Exp $
 
-# This is ssh client systemwide configuration file.  See ssh(1) for more
-# information.  This file provides defaults for users, and the values can
-# be changed in per-user configuration files or on the command line.
+# This is the ssh client system-wide configuration file.  See ssh(1)
+# for more information.  This file provides defaults for users, and
+# the values can be changed in per-user configuration files or on the
+# command line.
 
 # Configuration data is parsed as follows:
 #  1. command line options
@@ -17,7 +18,7 @@
 # Host *
 #   ForwardAgent no
 #   ForwardX11 no
-#   RhostsAuthentication no
+#   RhostsAuthentication yes
 #   RhostsRSAAuthentication yes
 #   RSAAuthentication yes
 #   PasswordAuthentication yes
 #   UseRsh no
 #   BatchMode no
 #   CheckHostIP yes
-#   StrictHostKeyChecking yes
+#   StrictHostKeyChecking ask
 #   IdentityFile ~/.ssh/identity
-#   IdentityFile ~/.ssh/id_dsa
 #   IdentityFile ~/.ssh/id_rsa
+#   IdentityFile ~/.ssh/id_dsa
 #   Port 22
 #   Protocol 2,1
-#   Cipher blowfish
+#   Cipher 3des
+#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
 #   EscapeChar ~
index de6cc22042611f70b258e9a85c74bf419f34e38e..5bb50e0e950751b542eff6f5bc15de6c8829a45b 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.115 2001/10/08 19:05:05 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.119 2002/01/21 15:13:51 markus Exp $");
 
 #include <openssl/bn.h>
 
@@ -31,6 +31,7 @@ RCSID("$OpenBSD: sshconnect.c,v 1.115 2001/10/08 19:05:05 markus Exp $");
 #include "readconf.h"
 #include "atomicio.h"
 #include "misc.h"
+#include "readpass.h"
 
 char *client_version_string = NULL;
 char *server_version_string = NULL;
@@ -49,15 +50,15 @@ sockaddr_ntop(struct sockaddr *sa)
        static char addrbuf[INET6_ADDRSTRLEN];
 
        switch (sa->sa_family) {
-               case AF_INET:
-                       addr = &((struct sockaddr_in *)sa)->sin_addr;
-                       break;
-               case AF_INET6:
-                       addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
-                       break;
-               default:
-                       /* This case should be protected against elsewhere */
-                       abort();
+       case AF_INET:
+               addr = &((struct sockaddr_in *)sa)->sin_addr;
+               break;
+       case AF_INET6:
+               addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
+               break;
+       default:
+               /* This case should be protected against elsewhere */
+               abort();        /* XXX abort is bad -- do something else */
        }
        inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf));
        return addrbuf;
@@ -109,7 +110,7 @@ ssh_proxy_connect(const char *host, u_short port, struct passwd *pw,
        /* Create pipes for communicating with the proxy. */
        if (pipe(pin) < 0 || pipe(pout) < 0)
                fatal("Could not create pipes to communicate with the proxy: %.100s",
-                     strerror(errno));
+                   strerror(errno));
 
        debug("Executing proxy command: %.500s", command_string);
 
@@ -258,7 +259,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        int full_failure = 1;
 
        debug("ssh_connect: getuid %u geteuid %u anon %d",
-             (u_int) getuid(), (u_int) geteuid(), anonymous);
+           (u_int) getuid(), (u_int) geteuid(), anonymous);
 
        /* Get default port if port has not been set. */
        if (port == 0) {
@@ -340,7 +341,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                                 * which connect() has already returned an
                                 * error.
                                 */
-                               shutdown(sock, SHUT_RDWR);
                                close(sock);
                        }
                }
@@ -429,12 +429,12 @@ ssh_exchange_identification(void)
            &remote_major, &remote_minor, remote_version) != 3)
                fatal("Bad remote protocol version identification: '%.100s'", buf);
        debug("Remote protocol version %d.%d, remote software version %.100s",
-             remote_major, remote_minor, remote_version);
+           remote_major, remote_minor, remote_version);
 
        compat_datafellows(remote_version);
        mismatch = 0;
 
-       switch(remote_major) {
+       switch (remote_major) {
        case 1:
                if (remote_minor == 99 &&
                    (options.protocol & SSH_PROTO_2) &&
@@ -489,40 +489,24 @@ ssh_exchange_identification(void)
 static int
 confirm(const char *prompt)
 {
-       char buf[1024];
-       FILE *f;
-       int retval = -1;
+       const char *msg, *again = "Please type 'yes' or 'no': ";
+       char *p;
+       int ret = -1;
 
        if (options.batch_mode)
                return 0;
-       if (isatty(STDIN_FILENO))
-               f = stdin;
-       else
-               f = fopen(_PATH_TTY, "rw");
-       if (f == NULL)
-               return 0;
-       fflush(stdout);
-       fprintf(stderr, "%s", prompt);
-       while (1) {
-               if (fgets(buf, sizeof(buf), f) == NULL) {
-                       fprintf(stderr, "\n");
-                       strlcpy(buf, "no", sizeof buf);
-               }
-               /* Remove newline from response. */
-               if (strchr(buf, '\n'))
-                       *strchr(buf, '\n') = 0;
-               if (strcmp(buf, "yes") == 0)
-                       retval = 1;
-               else if (strcmp(buf, "no") == 0)
-                       retval = 0;
-               else
-                       fprintf(stderr, "Please type 'yes' or 'no': ");
-
-               if (retval != -1) {
-                       if (f != stdin)
-                               fclose(f);
-                       return retval;
-               }
+       for (msg = prompt;;msg = again) {
+               p = read_passphrase(msg, RP_ECHO);
+               if (p == NULL ||
+                   (p[0] == '\0') || (p[0] == '\n') ||
+                   strncasecmp(p, "no", 2) == 0)
+                       ret = 0;
+               if (strncasecmp(p, "yes", 3) == 0)
+                       ret = 1;
+               if (p)
+                       xfree(p);
+               if (ret != -1)
+                       return ret;
        }
 }
 
@@ -544,7 +528,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        int local = 0, host_ip_differ = 0;
        int salen;
        char ntop[NI_MAXHOST];
-       int host_line, ip_line;
+       char msg[1024];
+       int len, host_line, ip_line;
        const char *host_file = NULL, *ip_file = NULL;
 
        /*
@@ -559,7 +544,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        switch (hostaddr->sa_family) {
        case AF_INET:
                local = (ntohl(((struct sockaddr_in *)hostaddr)->
-                   sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
+                  sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
                salen = sizeof(struct sockaddr_in);
                break;
        case AF_INET6:
@@ -621,7 +606,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
         */
        host_file = user_hostfile;
        host_status = check_host_in_hostfile(host_file, host, host_key,
-            file_key, &host_line);
+           file_key, &host_line);
        if (host_status == HOST_NEW) {
                host_file = system_hostfile;
                host_status = check_host_in_hostfile(host_file, host, host_key,
@@ -664,7 +649,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                                    "'%.128s' not in list of known hosts.",
                                    type, ip);
                        else if (!add_host_to_hostfile(user_hostfile, ip,
-                            host_key))
+                           host_key))
                                log("Failed to add the %s host key for IP "
                                    "address '%.128s' to the list of known "
                                    "hosts (%.30s).", type, ip, user_hostfile);
@@ -689,18 +674,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        goto fail;
                } else if (options.strict_host_key_checking == 2) {
                        /* The default */
-                       char prompt[1024];
                        fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
-                       snprintf(prompt, sizeof(prompt),
+                       snprintf(msg, sizeof(msg),
                            "The authenticity of host '%.200s (%s)' can't be "
                            "established.\n"
                            "%s key fingerprint is %s.\n"
                            "Are you sure you want to continue connecting "
                            "(yes/no)? ", host, ip, type, fp);
                        xfree(fp);
-                       if (!confirm(prompt)) {
+                       if (!confirm(msg))
                                goto fail;
-                       }
                }
                if (options.check_host_ip && ip_status == HOST_NEW) {
                        snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
@@ -790,7 +773,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        error("Port forwarding is disabled to avoid "
                            "man-in-the-middle attacks.");
                        options.num_local_forwards =
-                            options.num_remote_forwards = 0;
+                           options.num_remote_forwards = 0;
                }
                /*
                 * XXX Should permit the user to change to use the new id.
@@ -804,20 +787,28 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
 
        if (options.check_host_ip && host_status != HOST_CHANGED &&
            ip_status == HOST_CHANGED) {
-               log("Warning: the %s host key for '%.200s' "
-                   "differs from the key for the IP address '%.128s'",
-                   type, host, ip);
-               if (host_status == HOST_OK)
-                       log("Matching host key in %s:%d", host_file, host_line);
-               log("Offending key for IP in %s:%d", ip_file, ip_line);
+               snprintf(msg, sizeof(msg),
+                   "Warning: the %s host key for '%.200s' "
+                   "differs from the key for the IP address '%.128s'"
+                   "\nOffending key for IP in %s:%d",
+                   type, host, ip, ip_file, ip_line);
+               if (host_status == HOST_OK) {
+                       len = strlen(msg);
+                       snprintf(msg + len, sizeof(msg) - len,
+                           "\nMatching host key in %s:%d",
+                            host_file, host_line);
+               }
                if (options.strict_host_key_checking == 1) {
+                       log(msg);
                        error("Exiting, you have requested strict checking.");
                        goto fail;
                } else if (options.strict_host_key_checking == 2) {
-                       if (!confirm("Are you sure you want " 
-                           "to continue connecting (yes/no)? ")) {
+                       strlcat(msg, "\nAre you sure you want "
+                           "to continue connecting (yes/no)? ", sizeof(msg));
+                       if (!confirm(msg))
                                goto fail;
-                       }
+               } else {
+                       log(msg);
                }
        }
 
index d6b862352963d6759972b0c147eea9e8e84e7fcc..d7722f4b9bf400becf267d73b07121e3b21732f9 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.41 2001/10/06 11:18:19 markus Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.48 2002/02/11 16:15:46 markus Exp $");
 
 #include <openssl/bn.h>
-#include <openssl/evp.h>
+#include <openssl/md5.h>
 
 #ifdef KRB4
 #include <krb.h>
@@ -67,7 +67,6 @@ try_agent_authentication(void)
        AuthenticationConnection *auth;
        u_char response[16];
        u_int i;
-       int plen, clen;
        Key *key;
        BIGNUM *challenge;
 
@@ -76,12 +75,12 @@ try_agent_authentication(void)
        if (!auth)
                return 0;
 
-       challenge = BN_new();
-
+       if ((challenge = BN_new()) == NULL)
+               fatal("try_agent_authentication: BN_new failed");
        /* Loop through identities served by the agent. */
        for (key = ssh_get_first_identity(auth, &comment, 1);
-            key != NULL;
-            key = ssh_get_next_identity(auth, &comment, 1)) {
+           key != NULL;
+           key = ssh_get_next_identity(auth, &comment, 1)) {
 
                /* Try this identity. */
                debug("Trying RSA authentication via agent with '%.100s'", comment);
@@ -94,7 +93,7 @@ try_agent_authentication(void)
                packet_write_wait();
 
                /* Wait for server's response. */
-               type = packet_read(&plen);
+               type = packet_read();
 
                /* The server sends failure if it doesn\'t like our key or
                   does not support RSA authentication. */
@@ -108,9 +107,8 @@ try_agent_authentication(void)
                        packet_disconnect("Protocol error during RSA authentication: %d",
                                          type);
 
-               packet_get_bignum(challenge, &clen);
-
-               packet_integrity_check(plen, clen, type);
+               packet_get_bignum(challenge);
+               packet_check_eom();
 
                debug("Received RSA challenge from server.");
 
@@ -135,7 +133,7 @@ try_agent_authentication(void)
                packet_write_wait();
 
                /* Wait for response from the server. */
-               type = packet_read(&plen);
+               type = packet_read();
 
                /* The server returns success if it accepted the authentication. */
                if (type == SSH_SMSG_SUCCESS) {
@@ -210,7 +208,7 @@ try_rsa_authentication(int idx)
        BIGNUM *challenge;
        Key *public, *private;
        char buf[300], *passphrase, *comment, *authfile;
-       int i, type, quit, plen, clen;
+       int i, type, quit;
 
        public = options.identity_keys[idx];
        authfile = options.identity_files[idx];
@@ -225,7 +223,7 @@ try_rsa_authentication(int idx)
        packet_write_wait();
 
        /* Wait for server's response. */
-       type = packet_read(&plen);
+       type = packet_read();
 
        /*
         * The server responds with failure if it doesn\'t like our key or
@@ -241,10 +239,10 @@ try_rsa_authentication(int idx)
                packet_disconnect("Protocol error during RSA authentication: %d", type);
 
        /* Get the challenge from the packet. */
-       challenge = BN_new();
-       packet_get_bignum(challenge, &clen);
-
-       packet_integrity_check(plen, clen, type);
+       if ((challenge = BN_new()) == NULL)
+               fatal("try_rsa_authentication: BN_new failed");
+       packet_get_bignum(challenge);
+       packet_check_eom();
 
        debug("Received RSA challenge from server.");
 
@@ -292,7 +290,7 @@ try_rsa_authentication(int idx)
                packet_write_wait();
 
                /* Expect the server to reject it... */
-               packet_read_expect(&plen, SSH_SMSG_FAILURE);
+               packet_read_expect(SSH_SMSG_FAILURE);
                BN_clear_free(challenge);
                return 0;
        }
@@ -308,7 +306,7 @@ try_rsa_authentication(int idx)
        BN_clear_free(challenge);
 
        /* Wait for response from the server. */
-       type = packet_read(&plen);
+       type = packet_read();
        if (type == SSH_SMSG_SUCCESS) {
                debug("RSA authentication accepted by server.");
                return 1;
@@ -328,7 +326,6 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
 {
        int type;
        BIGNUM *challenge;
-       int plen, clen;
 
        debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
 
@@ -342,7 +339,7 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
        packet_write_wait();
 
        /* Wait for server's response. */
-       type = packet_read(&plen);
+       type = packet_read();
 
        /* The server responds with failure if it doesn't admit our
           .rhosts authentication or doesn't know our host key. */
@@ -355,10 +352,10 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
                packet_disconnect("Protocol error during RSA authentication: %d", type);
 
        /* Get the challenge from the packet. */
-       challenge = BN_new();
-       packet_get_bignum(challenge, &clen);
-
-       packet_integrity_check(plen, clen, type);
+       if ((challenge = BN_new()) == NULL)
+               fatal("try_rhosts_rsa_authentication: BN_new failed");
+       packet_get_bignum(challenge);
+       packet_check_eom();
 
        debug("Received RSA challenge for host key from server.");
 
@@ -369,7 +366,7 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
        BN_clear_free(challenge);
 
        /* Wait for response from the server. */
-       type = packet_read(&plen);
+       type = packet_read();
        if (type == SSH_SMSG_SUCCESS) {
                debug("Rhosts or /etc/hosts.equiv with RSA host authentication accepted by server.");
                return 1;
@@ -389,7 +386,7 @@ try_krb4_authentication(void)
        char inst[INST_SZ];
        char *realm;
        CREDENTIALS cred;
-       int r, type, plen;
+       int r, type;
        socklen_t slen;
        Key_schedule schedule;
        u_long checksum, cksum;
@@ -400,10 +397,10 @@ try_krb4_authentication(void)
        /* Don't do anything if we don't have any tickets. */
        if (stat(tkt_string(), &st) < 0)
                return 0;
-       
+
        strlcpy(inst, (char *)krb_get_phost(get_canonical_hostname(1)),
            INST_SZ);
-       
+
        realm = (char *)krb_realmofhost(get_canonical_hostname(1));
        if (!realm) {
                debug("Kerberos v4: no realm for %s", get_canonical_hostname(1));
@@ -411,7 +408,7 @@ try_krb4_authentication(void)
        }
        /* This can really be anything. */
        checksum = (u_long)getpid();
-       
+
        r = krb_mk_req(&auth, KRB4_SERVICE_NAME, inst, realm, checksum);
        if (r != KSUCCESS) {
                debug("Kerberos v4 krb_mk_req failed: %s", krb_err_txt[r]);
@@ -424,22 +421,22 @@ try_krb4_authentication(void)
                return 0;
        }
        des_key_sched((des_cblock *) cred.session, schedule);
-       
+
        /* Send authentication info to server. */
        packet_start(SSH_CMSG_AUTH_KERBEROS);
        packet_put_string((char *) auth.dat, auth.length);
        packet_send();
        packet_write_wait();
-       
+
        /* Zero the buffer. */
        (void) memset(auth.dat, 0, MAX_KTXT_LEN);
-       
+
        slen = sizeof(local);
        memset(&local, 0, sizeof(local));
        if (getsockname(packet_get_connection_in(),
            (struct sockaddr *)&local, &slen) < 0)
                debug("getsockname failed: %s", strerror(errno));
-       
+
        slen = sizeof(foreign);
        memset(&foreign, 0, sizeof(foreign));
        if (getpeername(packet_get_connection_in(),
@@ -448,25 +445,25 @@ try_krb4_authentication(void)
                fatal_cleanup();
        }
        /* Get server reply. */
-       type = packet_read(&plen);
+       type = packet_read();
        switch (type) {
        case SSH_SMSG_FAILURE:
                /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
                debug("Kerberos v4 authentication failed.");
                return 0;
                break;
-               
+
        case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
                /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
                debug("Kerberos v4 authentication accepted.");
-               
+
                /* Get server's response. */
                reply = packet_get_string((u_int *) &auth.length);
                memcpy(auth.dat, reply, auth.length);
                xfree(reply);
-               
-               packet_integrity_check(plen, 4 + auth.length, type);
-               
+
+               packet_check_eom();
+
                /*
                 * If his response isn't properly encrypted with the session
                 * key, and the decrypted checksum fails to match, he's
@@ -483,7 +480,7 @@ try_krb4_authentication(void)
                memcpy((char *)&cksum, (char *)msg_data.app_data,
                    sizeof(cksum));
                cksum = ntohl(cksum);
-               
+
                /* If it matches, we're golden. */
                if (cksum == checksum + 1) {
                        debug("Kerberos v4 challenge successful.");
@@ -491,7 +488,7 @@ try_krb4_authentication(void)
                } else
                        packet_disconnect("Kerberos v4 challenge failed!");
                break;
-               
+
        default:
                packet_disconnect("Protocol error on Kerberos v4 response: %d", type);
        }
@@ -510,29 +507,29 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
        krb5_ccache ccache = NULL;
        const char *remotehost;
        krb5_data ap;
-       int type, payload_len;
+       int type;
        krb5_ap_rep_enc_part *reply = NULL;
        int ret;
-       
+
        memset(&ap, 0, sizeof(ap));
-       
+
        problem = krb5_init_context(context);
        if (problem) {
                debug("Kerberos v5: krb5_init_context failed");
                ret = 0;
                goto out;
        }
-       
+
        tkfile = krb5_cc_default_name(*context);
        if (strncmp(tkfile, "FILE:", 5) == 0)
                tkfile += 5;
-       
+
        if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
                debug("Kerberos v5: could not get default ccache (permission denied).");
                ret = 0;
                goto out;
        }
-       
+
        problem = krb5_cc_default(*context, &ccache);
        if (problem) {
                debug("Kerberos v5: krb5_cc_default failed: %s",
@@ -540,9 +537,9 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
                ret = 0;
                goto out;
        }
-       
+
        remotehost = get_canonical_hostname(1);
-       
+
        problem = krb5_mk_req(*context, auth_context, AP_OPTS_MUTUAL_REQUIRED,
            "host", remotehost, NULL, ccache, &ap);
        if (problem) {
@@ -551,48 +548,47 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
                ret = 0;
                goto out;
        }
-       
+
        packet_start(SSH_CMSG_AUTH_KERBEROS);
        packet_put_string((char *) ap.data, ap.length);
        packet_send();
        packet_write_wait();
-       
+
        xfree(ap.data);
        ap.length = 0;
-       
-       type = packet_read(&payload_len);
+
+       type = packet_read();
        switch (type) {
-        case SSH_SMSG_FAILURE:
-                /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
-                debug("Kerberos v5 authentication failed.");
-                ret = 0;
-                break;
-               
+       case SSH_SMSG_FAILURE:
+               /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
+               debug("Kerberos v5 authentication failed.");
+               ret = 0;
+               break;
+
        case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
-                /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
-                debug("Kerberos v5 authentication accepted.");
-               
-                /* Get server's response. */
-                ap.data = packet_get_string((unsigned int *) &ap.length);
-               
-                packet_integrity_check(payload_len, 4 + ap.length, type);
-                /* XXX je to dobre? */
-               
-                problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
-                if (problem) {
+               /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
+               debug("Kerberos v5 authentication accepted.");
+
+               /* Get server's response. */
+               ap.data = packet_get_string((unsigned int *) &ap.length);
+               packet_check_eom();
+               /* XXX je to dobre? */
+
+               problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
+               if (problem) {
                        ret = 0;
                }
                ret = 1;
                break;
-               
+
        default:
                packet_disconnect("Protocol error on Kerberos v5 response: %d",
                    type);
                ret = 0;
                break;
-               
+
        }
-       
+
  out:
        if (ccache != NULL)
                krb5_cc_close(*context, ccache);
@@ -600,76 +596,76 @@ try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
                krb5_free_ap_rep_enc_part(*context, reply);
        if (ap.length > 0)
                krb5_data_free(&ap);
-       
+
        return (ret);
 }
 
 static void
 send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
 {
-       int fd, type, payload_len;
+       int fd, type;
        krb5_error_code problem;
        krb5_data outbuf;
        krb5_ccache ccache = NULL;
        krb5_creds creds;
        krb5_kdc_flags flags;
        const char *remotehost;
-       
+
        memset(&creds, 0, sizeof(creds));
        memset(&outbuf, 0, sizeof(outbuf));
-       
+
        fd = packet_get_connection_in();
-       
+
        problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
        if (problem)
                goto out;
-       
+
        problem = krb5_cc_default(context, &ccache);
        if (problem)
                goto out;
-       
+
        problem = krb5_cc_get_principal(context, ccache, &creds.client);
        if (problem)
                goto out;
-       
+
        problem = krb5_build_principal(context, &creds.server,
            strlen(creds.client->realm), creds.client->realm,
            "krbtgt", creds.client->realm, NULL);
        if (problem)
                goto out;
-       
+
        creds.times.endtime = 0;
-       
+
        flags.i = 0;
        flags.b.forwarded = 1;
        flags.b.forwardable = krb5_config_get_bool(context,  NULL,
            "libdefaults", "forwardable", NULL);
-       
+
        remotehost = get_canonical_hostname(1);
-       
+
        problem = krb5_get_forwarded_creds(context, auth_context,
            ccache, flags.i, remotehost, &creds, &outbuf);
        if (problem)
                goto out;
-       
+
        packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
        packet_put_string((char *)outbuf.data, outbuf.length);
        packet_send();
        packet_write_wait();
-       
-       type = packet_read(&payload_len);
-       
+
+       type = packet_read();
+
        if (type == SSH_SMSG_SUCCESS) {
                char *pname;
-               
+
                krb5_unparse_name(context, creds.client, &pname);
                debug("Kerberos v5 TGT forwarded (%s).", pname);
                xfree(pname);
        } else
                debug("Kerberos v5 TGT forwarding failed.");
-       
+
        return;
-       
+
  out:
        if (problem)
                debug("Kerberos v5 TGT forwarding failed: %s",
@@ -692,45 +688,45 @@ send_krb4_tgt(void)
        CREDENTIALS *creds;
        struct stat st;
        char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
-       int problem, type, len;
-       
+       int problem, type;
+
        /* Don't do anything if we don't have any tickets. */
        if (stat(tkt_string(), &st) < 0)
                return;
-       
+
        creds = xmalloc(sizeof(*creds));
-       
+
        problem = krb_get_tf_fullname(TKT_FILE, pname, pinst, prealm);
        if (problem)
                goto out;
-       
+
        problem = krb_get_cred("krbtgt", prealm, prealm, creds);
        if (problem)
                goto out;
-       
+
        if (time(0) > krb_life_to_time(creds->issue_date, creds->lifetime)) {
                problem = RD_AP_EXP;
                goto out;
        }
        creds_to_radix(creds, (u_char *)buffer, sizeof(buffer));
-       
+
        packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
        packet_put_cstring(buffer);
        packet_send();
        packet_write_wait();
-       
-       type = packet_read(&len);
-       
+
+       type = packet_read();
+
        if (type == SSH_SMSG_SUCCESS)
                debug("Kerberos v4 TGT forwarded (%s%s%s@%s).",
                    creds->pname, creds->pinst[0] ? "." : "",
                    creds->pinst, creds->realm);
        else
                debug("Kerberos v4 TGT rejected.");
-       
+
        xfree(creds);
        return;
-       
+
  out:
        debug("Kerberos v4 TGT passing failed: %s", krb_err_txt[problem]);
        xfree(creds);
@@ -745,7 +741,7 @@ send_afs_tokens(void)
        int i, type, len;
        char buf[2048], *p, *server_cell;
        char buffer[8192];
-       
+
        /* Move over ktc_GetToken, here's something leaner. */
        for (i = 0; i < 100; i++) {     /* just in case */
                parms.in = (char *) &i;
@@ -755,7 +751,7 @@ send_afs_tokens(void)
                if (k_pioctl(0, VIOCGETTOK, &parms, 0) != 0)
                        break;
                p = buf;
-               
+
                /* Get secret token. */
                memcpy(&creds.ticket_st.length, p, sizeof(u_int));
                if (creds.ticket_st.length > MAX_KTXT_LEN)
@@ -763,7 +759,7 @@ send_afs_tokens(void)
                p += sizeof(u_int);
                memcpy(creds.ticket_st.dat, p, creds.ticket_st.length);
                p += creds.ticket_st.length;
-               
+
                /* Get clear token. */
                memcpy(&len, p, sizeof(len));
                if (len != sizeof(struct ClearToken))
@@ -773,7 +769,7 @@ send_afs_tokens(void)
                p += len;
                p += sizeof(len);       /* primary flag */
                server_cell = p;
-               
+
                /* Flesh out our credentials. */
                strlcpy(creds.service, "afs", sizeof(creds.service));
                creds.instance[0] = '\0';
@@ -785,7 +781,7 @@ send_afs_tokens(void)
                creds.kvno = ct.AuthHandle;
                snprintf(creds.pname, sizeof(creds.pname), "AFS ID %d", ct.ViceId);
                creds.pinst[0] = '\0';
-               
+
                /* Encode token, ship it off. */
                if (creds_to_radix(&creds, (u_char *)buffer,
                    sizeof(buffer)) <= 0)
@@ -797,8 +793,8 @@ send_afs_tokens(void)
 
                /* Roger, Roger. Clearance, Clarence. What's your vector,
                   Victor? */
-               type = packet_read(&len);
-               
+               type = packet_read();
+
                if (type == SSH_SMSG_FAILURE)
                        debug("AFS token for cell %s rejected.", server_cell);
                else if (type != SSH_SMSG_SUCCESS)
@@ -816,7 +812,6 @@ static int
 try_challenge_response_authentication(void)
 {
        int type, i;
-       int payload_len;
        u_int clen;
        char prompt[1024];
        char *challenge, *response;
@@ -829,7 +824,7 @@ try_challenge_response_authentication(void)
                packet_send();
                packet_write_wait();
 
-               type = packet_read(&payload_len);
+               type = packet_read();
                if (type != SSH_SMSG_FAILURE &&
                    type != SSH_SMSG_AUTH_TIS_CHALLENGE) {
                        packet_disconnect("Protocol error: got %d in response "
@@ -840,9 +835,9 @@ try_challenge_response_authentication(void)
                        return 0;
                }
                challenge = packet_get_string(&clen);
-               packet_integrity_check(payload_len, (4 + clen), type);
+               packet_check_eom();
                snprintf(prompt, sizeof prompt, "%s%s", challenge,
-                    strchr(challenge, '\n') ? "" : "\nResponse: ");
+                   strchr(challenge, '\n') ? "" : "\nResponse: ");
                xfree(challenge);
                if (i != 0)
                        error("Permission denied, please try again.");
@@ -860,7 +855,7 @@ try_challenge_response_authentication(void)
                xfree(response);
                packet_send();
                packet_write_wait();
-               type = packet_read(&payload_len);
+               type = packet_read();
                if (type == SSH_SMSG_SUCCESS)
                        return 1;
                if (type != SSH_SMSG_FAILURE)
@@ -877,7 +872,7 @@ try_challenge_response_authentication(void)
 static int
 try_password_authentication(char *prompt)
 {
-       int type, i, payload_len;
+       int type, i;
        char *password;
 
        debug("Doing password authentication.");
@@ -894,7 +889,7 @@ try_password_authentication(char *prompt)
                packet_send();
                packet_write_wait();
 
-               type = packet_read(&payload_len);
+               type = packet_read();
                if (type == SSH_SMSG_SUCCESS)
                        return 1;
                if (type != SSH_SMSG_FAILURE)
@@ -912,54 +907,43 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
 {
        int i;
        BIGNUM *key;
-       RSA *host_key;
-       RSA *public_key;
-       Key k;
+       Key *host_key, *server_key;
        int bits, rbits;
        int ssh_cipher_default = SSH_CIPHER_3DES;
        u_char session_key[SSH_SESSION_KEY_LENGTH];
        u_char cookie[8];
        u_int supported_ciphers;
        u_int server_flags, client_flags;
-       int payload_len, clen, sum_len = 0;
        u_int32_t rand = 0;
 
        debug("Waiting for server public key.");
 
        /* Wait for a public key packet from the server. */
-       packet_read_expect(&payload_len, SSH_SMSG_PUBLIC_KEY);
+       packet_read_expect(SSH_SMSG_PUBLIC_KEY);
 
        /* Get cookie from the packet. */
        for (i = 0; i < 8; i++)
                cookie[i] = packet_get_char();
 
        /* Get the public key. */
-       public_key = RSA_new();
-       bits = packet_get_int();/* bits */
-       public_key->e = BN_new();
-       packet_get_bignum(public_key->e, &clen);
-       sum_len += clen;
-       public_key->n = BN_new();
-       packet_get_bignum(public_key->n, &clen);
-       sum_len += clen;
-
-       rbits = BN_num_bits(public_key->n);
+       server_key = key_new(KEY_RSA1);
+       bits = packet_get_int();
+       packet_get_bignum(server_key->rsa->e);
+       packet_get_bignum(server_key->rsa->n);
+
+       rbits = BN_num_bits(server_key->rsa->n);
        if (bits != rbits) {
                log("Warning: Server lies about size of server public key: "
                    "actual size is %d bits vs. announced %d.", rbits, bits);
                log("Warning: This may be due to an old implementation of ssh.");
        }
        /* Get the host key. */
-       host_key = RSA_new();
-       bits = packet_get_int();/* bits */
-       host_key->e = BN_new();
-       packet_get_bignum(host_key->e, &clen);
-       sum_len += clen;
-       host_key->n = BN_new();
-       packet_get_bignum(host_key->n, &clen);
-       sum_len += clen;
-
-       rbits = BN_num_bits(host_key->n);
+       host_key = key_new(KEY_RSA1);
+       bits = packet_get_int();
+       packet_get_bignum(host_key->rsa->e);
+       packet_get_bignum(host_key->rsa->n);
+
+       rbits = BN_num_bits(host_key->rsa->n);
        if (bits != rbits) {
                log("Warning: Server lies about size of server host key: "
                    "actual size is %d bits vs. announced %d.", rbits, bits);
@@ -972,21 +956,17 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
 
        supported_ciphers = packet_get_int();
        supported_authentications = packet_get_int();
+       packet_check_eom();
 
        debug("Received server public key (%d bits) and host key (%d bits).",
-             BN_num_bits(public_key->n), BN_num_bits(host_key->n));
-
-       packet_integrity_check(payload_len,
-                              8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
-                              SSH_SMSG_PUBLIC_KEY);
-       k.type = KEY_RSA1;
-       k.rsa = host_key;
-       if (verify_host_key(host, hostaddr, &k) == -1)
+           BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
+
+       if (verify_host_key(host, hostaddr, host_key) == -1)
                fatal("Host key verification failed.");
 
        client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
 
-       compute_session_id(session_id, cookie, host_key->n, public_key->n);
+       compute_session_id(session_id, cookie, host_key->rsa->n, server_key->rsa->n);
 
        /* Generate a session key. */
        arc4random_stir();
@@ -1008,7 +988,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
         * is the highest byte of the integer.  The session key is xored with
         * the first 16 bytes of the session id.
         */
-       key = BN_new();
+       if ((key = BN_new()) == NULL)
+               fatal("respond_to_rsa_challenge: BN_new failed");
        BN_set_word(key, 0);
        for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) {
                BN_lshift(key, key, 8);
@@ -1022,35 +1003,35 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
         * Encrypt the integer using the public key and host key of the
         * server (key with smaller modulus first).
         */
-       if (BN_cmp(public_key->n, host_key->n) < 0) {
+       if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
                /* Public key has smaller modulus. */
-               if (BN_num_bits(host_key->n) <
-                   BN_num_bits(public_key->n) + SSH_KEY_BITS_RESERVED) {
-                       fatal("respond_to_rsa_challenge: host_key %d < public_key %d + "
-                             "SSH_KEY_BITS_RESERVED %d",
-                             BN_num_bits(host_key->n),
-                             BN_num_bits(public_key->n),
-                             SSH_KEY_BITS_RESERVED);
+               if (BN_num_bits(host_key->rsa->n) <
+                   BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
+                       fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
+                           "SSH_KEY_BITS_RESERVED %d",
+                           BN_num_bits(host_key->rsa->n),
+                           BN_num_bits(server_key->rsa->n),
+                           SSH_KEY_BITS_RESERVED);
                }
-               rsa_public_encrypt(key, key, public_key);
-               rsa_public_encrypt(key, key, host_key);
+               rsa_public_encrypt(key, key, server_key->rsa);
+               rsa_public_encrypt(key, key, host_key->rsa);
        } else {
                /* Host key has smaller modulus (or they are equal). */
-               if (BN_num_bits(public_key->n) <
-                   BN_num_bits(host_key->n) + SSH_KEY_BITS_RESERVED) {
-                       fatal("respond_to_rsa_challenge: public_key %d < host_key %d + "
-                             "SSH_KEY_BITS_RESERVED %d",
-                             BN_num_bits(public_key->n),
-                             BN_num_bits(host_key->n),
-                             SSH_KEY_BITS_RESERVED);
+               if (BN_num_bits(server_key->rsa->n) <
+                   BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
+                       fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
+                           "SSH_KEY_BITS_RESERVED %d",
+                           BN_num_bits(server_key->rsa->n),
+                           BN_num_bits(host_key->rsa->n),
+                           SSH_KEY_BITS_RESERVED);
                }
-               rsa_public_encrypt(key, key, host_key);
-               rsa_public_encrypt(key, key, public_key);
+               rsa_public_encrypt(key, key, host_key->rsa);
+               rsa_public_encrypt(key, key, server_key->rsa);
        }
 
        /* Destroy the public keys since we no longer need them. */
-       RSA_free(public_key);
-       RSA_free(host_key);
+       key_free(server_key);
+       key_free(host_key);
 
        if (options.cipher == SSH_CIPHER_NOT_SET) {
                if (cipher_mask_ssh1(1) & supported_ciphers & (1 << ssh_cipher_default))
@@ -1064,7 +1045,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
        /* Check that the selected cipher is supported. */
        if (!(supported_ciphers & (1 << options.cipher)))
                fatal("Selected cipher type %.100s not supported by server.",
-                     cipher_name(options.cipher));
+                   cipher_name(options.cipher));
 
        debug("Encryption type: %.100s", cipher_name(options.cipher));
 
@@ -1099,7 +1080,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
         * Expect a success message from the server.  Note that this message
         * will be received in encrypted form.
         */
-       packet_read_expect(&payload_len, SSH_SMSG_SUCCESS);
+       packet_read_expect(SSH_SMSG_SUCCESS);
 
        debug("Received encrypted confirmation.");
 }
@@ -1116,8 +1097,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
        krb5_auth_context auth_context = NULL;
 #endif
        int i, type;
-       int payload_len;
-       
+
        if (supported_authentications == 0)
                fatal("ssh_userauth1: server supports no auth methods");
 
@@ -1132,21 +1112,21 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
         * needed (the user has no password).  Otherwise the server responds
         * with failure.
         */
-       type = packet_read(&payload_len);
+       type = packet_read();
 
        /* check whether the connection was accepted without authentication. */
        if (type == SSH_SMSG_SUCCESS)
                goto success;
        if (type != SSH_SMSG_FAILURE)
                packet_disconnect("Protocol error: got %d in response to SSH_CMSG_USER", type);
-       
+
 #ifdef KRB5
        if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
-            options.kerberos_authentication) {
+           options.kerberos_authentication) {
                debug("Trying Kerberos v5 authentication.");
-               
+
                if (try_krb5_authentication(&context, &auth_context)) {
-                       type = packet_read(&payload_len);
+                       type = packet_read();
                        if (type == SSH_SMSG_SUCCESS)
                                goto success;
                        if (type != SSH_SMSG_FAILURE)
@@ -1154,14 +1134,14 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
                }
        }
 #endif /* KRB5 */
-       
+
 #ifdef KRB4
        if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
            options.kerberos_authentication) {
                debug("Trying Kerberos v4 authentication.");
-               
+
                if (try_krb4_authentication()) {
-                       type = packet_read(&payload_len);
+                       type = packet_read();
                        if (type == SSH_SMSG_SUCCESS)
                                goto success;
                        if (type != SSH_SMSG_FAILURE)
@@ -1169,7 +1149,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
                }
        }
 #endif /* KRB4 */
-       
+
        /*
         * Use rhosts authentication if running in privileged socket and we
         * do not wish to remain anonymous.
@@ -1183,7 +1163,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
                packet_write_wait();
 
                /* The server should respond with success or failure. */
-               type = packet_read(&payload_len);
+               type = packet_read();
                if (type == SSH_SMSG_SUCCESS)
                        goto success;
                if (type != SSH_SMSG_FAILURE)
@@ -1254,7 +1234,7 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
        if (context)
                krb5_free_context(context);
 #endif
-       
+
 #ifdef AFS
        /* Try Kerberos v4 TGT passing if the server supports it. */
        if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
index 310788538a27bafa758f246b1c40a430857e4ccb..c5b5ee51550c262f40af6bb7aeeb6d9833001c74 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.85 2001/11/07 16:03:17 markus Exp $");
-
-#include <openssl/bn.h>
-#include <openssl/md5.h>
-#include <openssl/dh.h>
-#include <openssl/hmac.h>
+RCSID("$OpenBSD: sshconnect2.c,v 1.97 2002/02/25 16:33:27 markus Exp $");
 
 #include "ssh.h"
 #include "ssh2.h"
 #include "xmalloc.h"
-#include "rsa.h"
 #include "buffer.h"
 #include "packet.h"
-#include "uidswap.h"
 #include "compat.h"
 #include "bufaux.h"
 #include "cipher.h"
 #include "kex.h"
 #include "myproposal.h"
-#include "key.h"
 #include "sshconnect.h"
 #include "authfile.h"
 #include "dh.h"
@@ -111,7 +103,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
                myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
        }
        if (options.hostkeyalgorithms != NULL)
-               myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
+               myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
                    options.hostkeyalgorithms;
 
        /* start key exchange */
@@ -146,7 +138,7 @@ typedef struct Authmethod Authmethod;
 
 typedef int sign_cb_fn(
     Authctxt *authctxt, Key *key,
-    u_char **sigp, int *lenp, u_char *data, int datalen);
+    u_char **sigp, u_int *lenp, u_char *data, u_int datalen);
 
 struct Authctxt {
        const char *server_user;
@@ -174,20 +166,20 @@ struct Authmethod {
        int     *batch_flag;    /* flag in option struct that disables method */
 };
 
-void   input_userauth_success(int type, int plen, void *ctxt);
-void   input_userauth_failure(int type, int plen, void *ctxt);
-void   input_userauth_banner(int type, int plen, void *ctxt);
-void   input_userauth_error(int type, int plen, void *ctxt);
-void   input_userauth_info_req(int type, int plen, void *ctxt);
-void   input_userauth_pk_ok(int type, int plen, void *ctxt);
+void   input_userauth_success(int, u_int32_t, void *);
+void   input_userauth_failure(int, u_int32_t, void *);
+void   input_userauth_banner(int, u_int32_t, void *);
+void   input_userauth_error(int, u_int32_t, void *);
+void   input_userauth_info_req(int, u_int32_t, void *);
+void   input_userauth_pk_ok(int, u_int32_t, void *);
 
-int    userauth_none(Authctxt *authctxt);
-int    userauth_pubkey(Authctxt *authctxt);
-int    userauth_passwd(Authctxt *authctxt);
-int    userauth_kbdint(Authctxt *authctxt);
-int    userauth_hostbased(Authctxt *authctxt);
+int    userauth_none(Authctxt *);
+int    userauth_pubkey(Authctxt *);
+int    userauth_passwd(Authctxt *);
+int    userauth_kbdint(Authctxt *);
+int    userauth_hostbased(Authctxt *);
 
-void   userauth(Authctxt *authctxt, char *authlist);
+void   userauth(Authctxt *, char *);
 
 static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *);
 static void clear_auth_state(Authctxt *);
@@ -226,7 +218,6 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
 {
        Authctxt authctxt;
        int type;
-       int plen;
 
        if (options.challenge_response_authentication)
                options.kbd_interactive_authentication = 1;
@@ -236,18 +227,18 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
        packet_put_cstring("ssh-userauth");
        packet_send();
        packet_write_wait();
-       type = packet_read(&plen);
+       type = packet_read();
        if (type != SSH2_MSG_SERVICE_ACCEPT) {
                fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
        }
        if (packet_remaining() > 0) {
-               char *reply = packet_get_string(&plen);
+               char *reply = packet_get_string(NULL);
                debug("service_accept: %s", reply);
                xfree(reply);
        } else {
                debug("buggy server: service_accept w/o service");
        }
-       packet_done();
+       packet_check_eom();
        debug("got SSH2_MSG_SERVICE_ACCEPT");
 
        if (options.preferred_authentications == NULL)
@@ -308,13 +299,13 @@ userauth(Authctxt *authctxt, char *authlist)
        }
 }
 void
-input_userauth_error(int type, int plen, void *ctxt)
+input_userauth_error(int type, u_int32_t seq, void *ctxt)
 {
        fatal("input_userauth_error: bad message during authentication: "
           "type %d", type);
 }
 void
-input_userauth_banner(int type, int plen, void *ctxt)
+input_userauth_banner(int type, u_int32_t seq, void *ctxt)
 {
        char *msg, *lang;
        debug3("input_userauth_banner");
@@ -325,7 +316,7 @@ input_userauth_banner(int type, int plen, void *ctxt)
        xfree(lang);
 }
 void
-input_userauth_success(int type, int plen, void *ctxt)
+input_userauth_success(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        if (authctxt == NULL)
@@ -336,7 +327,7 @@ input_userauth_success(int type, int plen, void *ctxt)
        authctxt->success = 1;                  /* break out */
 }
 void
-input_userauth_failure(int type, int plen, void *ctxt)
+input_userauth_failure(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        char *authlist = NULL;
@@ -347,7 +338,7 @@ input_userauth_failure(int type, int plen, void *ctxt)
 
        authlist = packet_get_string(NULL);
        partial = packet_get_char();
-       packet_done();
+       packet_check_eom();
 
        if (partial != 0)
                log("Authenticated with partial success.");
@@ -357,13 +348,15 @@ input_userauth_failure(int type, int plen, void *ctxt)
        userauth(authctxt, authlist);
 }
 void
-input_userauth_pk_ok(int type, int plen, void *ctxt)
+input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        Key *key = NULL;
        Buffer b;
-       int alen, blen, sent = 0;
-       char *pkalg, *pkblob, *fp;
+       int pktype, sent = 0;
+       u_int alen, blen;
+       char *pkalg, *fp;
+       u_char *pkblob;
 
        if (authctxt == NULL)
                fatal("input_userauth_pk_ok: no authentication context");
@@ -379,7 +372,7 @@ input_userauth_pk_ok(int type, int plen, void *ctxt)
                pkalg = packet_get_string(&alen);
                pkblob = packet_get_string(&blen);
        }
-       packet_done();
+       packet_check_eom();
 
        debug("input_userauth_pk_ok: pkalg %s blen %d lastkey %p hint %d",
            pkalg, blen, authctxt->last_key, authctxt->last_key_hint);
@@ -390,7 +383,7 @@ input_userauth_pk_ok(int type, int plen, void *ctxt)
                        debug("no last key or no sign cb");
                        break;
                }
-               if (key_type_from_name(pkalg) == KEY_UNSPEC) {
+               if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
                        debug("unknown pkalg %s", pkalg);
                        break;
                }
@@ -398,6 +391,12 @@ input_userauth_pk_ok(int type, int plen, void *ctxt)
                        debug("no key from blob. pkalg %s", pkalg);
                        break;
                }
+               if (key->type != pktype) { 
+                       error("input_userauth_pk_ok: type mismatch "
+                           "for decoded key (received %d, expected %d)",
+                            key->type, pktype);
+                       break;
+               }
                fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
                debug2("input_userauth_pk_ok: fp %s", fp);
                xfree(fp);
@@ -407,7 +406,7 @@ input_userauth_pk_ok(int type, int plen, void *ctxt)
                }
                sent = sign_and_send_pubkey(authctxt, key,
                   authctxt->last_key_sign);
-       } while(0);
+       } while (0);
 
        if (key != NULL)
                key_free(key);
@@ -446,7 +445,7 @@ userauth_passwd(Authctxt *authctxt)
        if (attempt++ >= options.number_of_password_prompts)
                return 0;
 
-       if(attempt != 1)
+       if (attempt != 1)
                error("Permission denied, please try again.");
 
        snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
@@ -483,7 +482,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
 {
        Buffer b;
        u_char *blob, *signature;
-       int bloblen, slen;
+       u_int bloblen, slen;
        int skip = 0;
        int ret = -1;
        int have_sig = 1;
@@ -568,7 +567,7 @@ send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback,
     int hint)
 {
        u_char *blob;
-       int bloblen, have_sig = 0;
+       u_int bloblen, have_sig = 0;
 
        debug3("send_pubkey_test");
 
@@ -613,7 +612,7 @@ load_identity_file(char *filename)
                if (options.batch_mode)
                        return NULL;
                snprintf(prompt, sizeof prompt,
-                    "Enter passphrase for key '%.100s': ", filename);
+                   "Enter passphrase for key '%.100s': ", filename);
                for (i = 0; i < options.number_of_password_prompts; i++) {
                        passphrase = read_passphrase(prompt, 0);
                        if (strcmp(passphrase, "") != 0) {
@@ -635,8 +634,8 @@ load_identity_file(char *filename)
 }
 
 static int
-identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
        Key *private;
        int idx, ret;
@@ -646,7 +645,7 @@ identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
                return -1;
 
        /* private key is stored in external hardware */
-       if (options.identity_keys[idx]->flags & KEY_FLAG_EXT) 
+       if (options.identity_keys[idx]->flags & KEY_FLAG_EXT)
                return key_sign(options.identity_keys[idx], sigp, lenp, data, datalen);
 
        private = load_identity_file(options.identity_files[idx]);
@@ -658,15 +657,15 @@ identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
 }
 
 static int
-agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+agent_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
        return ssh_agent_sign(authctxt->agent, key, sigp, lenp, data, datalen);
 }
 
 static int
-key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, int *lenp,
-    u_char *data, int datalen)
+key_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
 {
        return key_sign(key, sigp, lenp, data, datalen);
 }
@@ -710,7 +709,7 @@ userauth_pubkey(Authctxt *authctxt)
        if (authctxt->agent != NULL) {
                do {
                        sent = userauth_pubkey_agent(authctxt);
-               } while(!sent && authctxt->agent->howmany > 0);
+               } while (!sent && authctxt->agent->howmany > 0);
        }
        while (!sent && idx < options.num_identity_files) {
                key = options.identity_keys[idx];
@@ -768,7 +767,7 @@ userauth_kbdint(Authctxt *authctxt)
  * parse INFO_REQUEST, prompt user and send INFO_RESPONSE
  */
 void
-input_userauth_info_req(int type, int plen, void *ctxt)
+input_userauth_info_req(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        char *name, *inst, *lang, *prompt, *response;
@@ -815,7 +814,7 @@ input_userauth_info_req(int type, int plen, void *ctxt)
                xfree(response);
                xfree(prompt);
        }
-       packet_done(); /* done with parsing incoming message. */
+       packet_check_eom(); /* done with parsing incoming message. */
 
        packet_add_padding(64);
        packet_send();
@@ -957,7 +956,7 @@ authmethod_get(char *authlist)
 {
 
        char *name = NULL;
-       int next;
+       u_int next;
 
        /* Use a suitable default if we're passed a nil list.  */
        if (authlist == NULL || strlen(authlist) == 0)
@@ -992,22 +991,23 @@ authmethod_get(char *authlist)
        }
 }
 
-
-#define        DELIM   ","
-
 static char *
 authmethods_get(void)
 {
        Authmethod *method = NULL;
-       char buf[1024];
+       Buffer b;
+       char *list;
 
-       buf[0] = '\0';
+       buffer_init(&b);
        for (method = authmethods; method->name != NULL; method++) {
                if (authmethod_is_enabled(method)) {
-                       if (buf[0] != '\0')
-                               strlcat(buf, DELIM, sizeof buf);
-                       strlcat(buf, method->name, sizeof buf);
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, method->name, strlen(method->name));
                }
        }
-       return xstrdup(buf);
+       buffer_append(&b, "\0", 1);
+       list = xstrdup(buffer_ptr(&b));
+       buffer_free(&b);
+       return list;
 }
index 5a6624b7420112372f51d88a800075c37fa92216..13d80e3b8354e29f8489d7f63af8c043a747d30c 100644 (file)
@@ -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.
 .\"
-.\" $OpenBSD: sshd.8,v 1.154 2001/11/07 22:12:01 markus Exp $
+.\" $OpenBSD: sshd.8,v 1.170 2002/02/28 20:46:10 stevesk Exp $
 .Dd September 25, 1999
 .Dt SSHD 8
 .Os
@@ -49,6 +49,7 @@
 .Op Fl g Ar login_grace_time
 .Op Fl h Ar host_key_file
 .Op Fl k Ar key_gen_time
+.Op Fl o Ar option
 .Op Fl p Ar port
 .Op Fl u Ar len
 .Sh DESCRIPTION
@@ -197,7 +198,7 @@ will send the output to the standard error instead of the system log.
 .It Fl f Ar configuration_file
 Specifies the name of the configuration file.
 The default is
-.Pa /etc/sshd_config .
+.Pa /etc/ssh/sshd_config .
 .Nm
 refuses to start if there is no configuration file.
 .It Fl g Ar login_grace_time
@@ -207,12 +208,18 @@ If the client fails to authenticate the user within
 this many seconds, the server disconnects and exits.
 A value of zero indicates no limit.
 .It Fl h Ar host_key_file
-Specifies the file from which the host key is read (default
-.Pa /etc/ssh_host_key ) .
+Specifies a file from which a host key is read.
 This option must be given if
 .Nm
 is not run as root (as the normal
-host file is normally not readable by anyone but root).
+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
 the different protocol versions and host key algorithms.
 .It Fl i
@@ -237,9 +244,16 @@ it becomes impossible to recover the key for decrypting intercepted
 communications even if the machine is cracked into or physically
 seized.
 A value of zero indicates that the key will never be regenerated.
+.It Fl o Ar option
+Can be used to give options in the format used in the configuration file.
+This is useful for specifying options for which there is no separate
+command-line flag.
 .It Fl p Ar port
 Specifies the port on which the server listens for connections
 (default 22).
+Multiple port options are permitted.
+Ports specified in the configuration file are ignored when a
+command-line port is specified.
 .It Fl q
 Quiet mode.
 Nothing is sent to the system log.
@@ -248,7 +262,7 @@ authentication, and termination of each connection is logged.
 .It Fl t
 Test mode.
 Only check the validity of the configuration file and sanity of the keys.
-This is useful for updating 
+This is useful for updating
 .Nm
 reliably as configuration options may change.
 .It Fl u Ar len
@@ -279,6 +293,11 @@ Authentication mechanisms that may require DNS include
 and using a
 .Cm from="pattern-list"
 option in a key file.
+Configuration options that require DNS include using a
+USER@HOST pattern in
+.Cm AllowUsers
+or
+.Cm DenyUsers .
 .It Fl D
 When this option is specified
 .Nm
@@ -297,7 +316,7 @@ to use IPv6 addresses only.
 .Sh CONFIGURATION FILE
 .Nm
 reads configuration data from
-.Pa /etc/sshd_config
+.Pa /etc/ssh/sshd_config
 (or the file specified with
 .Fl f
 on the command line).
@@ -315,7 +334,7 @@ Specifies whether an AFS token may be forwarded to the server.
 Default is
 .Dq yes .
 .It Cm AllowGroups
-This keyword can be followed by a list of group names, separated
+This keyword can be followed by a list of group name patterns, separated
 by spaces.
 If specified, login is allowed only for users whose primary
 group or supplementary group list matches one of the patterns.
@@ -325,7 +344,7 @@ and
 can be used as
 wildcards in the patterns.
 Only group names are valid; a numerical group ID is not recognized.
-By default login is allowed regardless of the group list.
+By default, login is allowed for all groups.
 .Pp
 .It Cm AllowTcpForwarding
 Specifies whether TCP forwarding is permitted.
@@ -336,7 +355,7 @@ users are also denied shell access, as they can always install their
 own forwarders.
 .Pp
 .It Cm AllowUsers
-This keyword can be followed by a list of user names, separated
+This keyword can be followed by a list of user name patterns, separated
 by spaces.
 If specified, login is allowed only for users names that
 match one of the patterns.
@@ -346,7 +365,7 @@ and
 can be used as
 wildcards in the patterns.
 Only user names are valid; a numerical user ID is not recognized.
-By default login is allowed regardless of the user name.
+By default, login is allowed for all users.
 If the pattern takes the form USER@HOST then USER and HOST
 are separately checked, restricting logins to particular
 users from particular hosts.
@@ -364,7 +383,7 @@ After expansion,
 is taken to be an absolute path or one relative to the user's home
 directory.
 The default is
-.Dq .ssh/authorized_keys
+.Dq .ssh/authorized_keys .
 .It Cm Banner
 In some jurisdictions, sending a warning message before authentication
 may be relevant for getting legal protection.
@@ -383,7 +402,11 @@ The default is
 Specifies the ciphers allowed for protocol version 2.
 Multiple ciphers must be comma-separated.
 The default is
-.Dq aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour.
+.Pp
+.Bd -literal
+  ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
+    aes192-cbc,aes256-cbc''
+.Ed
 .It Cm ClientAliveInterval
 Sets a timeout interval in seconds after which if no data has been received
 from the client,
@@ -417,20 +440,20 @@ The default value is 3. If
 is left at the default, unresponsive ssh clients
 will be disconnected after approximately 45 seconds.
 .It Cm DenyGroups
-This keyword can be followed by a number of group names, separated
+This keyword can be followed by a list of group name patterns, separated
 by spaces.
-Users whose primary group or supplementary group list matches
-one of the patterns aren't allowed to log in.
+Login is disallowed for users whose primary group or supplementary
+group list matches one of the patterns.
 .Ql \&*
 and
 .Ql ?
 can be used as
 wildcards in the patterns.
 Only group names are valid; a numerical group ID is not recognized.
-By default login is allowed regardless of the group list.
+By default, login is allowed for all groups.
 .Pp
 .It Cm DenyUsers
-This keyword can be followed by a number of user names, separated
+This keyword can be followed by a list of user name patterns, separated
 by spaces.
 Login is disallowed for user names that match one of the patterns.
 .Ql \&*
@@ -438,7 +461,10 @@ and
 .Ql ?
 can be used as wildcards in the patterns.
 Only user names are valid; a numerical user ID is not recognized.
-By default login is allowed regardless of the user name.
+By default, login is allowed for all users.
+If the pattern takes the form USER@HOST then USER and HOST
+are separately checked, restricting logins to particular
+users from particular hosts.
 .It Cm GatewayPorts
 Specifies whether remote hosts are allowed to connect to ports
 forwarded for the client.
@@ -467,9 +493,15 @@ and applies to protocol version 2 only.
 The default is
 .Dq no .
 .It Cm HostKey
-Specifies the file containing the private host keys (default
-.Pa /etc/ssh_host_key )
-used by SSH protocol versions 1 and 2.
+Specifies a file containing a private host key
+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
 .Nm
 will refuse to use a file if it is group/world-accessible.
@@ -509,7 +541,7 @@ or
 The default is
 .Dq no .
 .It Cm KeepAlive
-Specifies whether the system should send keepalive messages to the
+Specifies whether the system should send TCP keepalive messages to the
 other side.
 If they are sent, death of the connection or crash of one
 of the machines will be properly noticed.
@@ -524,12 +556,11 @@ users and consuming server resources.
 The default is
 .Dq yes
 (to send keepalives), and the server will notice
-if the network goes down or the client host reboots.
+if the network goes down or the client host crashes.
 This avoids infinitely hanging sessions.
 .Pp
 To disable keepalives, the value should be set to
-.Dq no
-in both the server and the client configuration files.
+.Dq no .
 .It Cm KerberosAuthentication
 Specifies whether Kerberos authentication is allowed.
 This can be in the form of a Kerberos ticket, or if
@@ -612,9 +643,10 @@ The default is 600 (seconds).
 Gives the verbosity level that is used when logging messages from
 .Nm sshd .
 The possible values are:
-QUIET, FATAL, ERROR, INFO, VERBOSE and DEBUG.
-The default is INFO.
-Logging with level DEBUG violates the privacy of users
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+The default is INFO.  DEBUG and DEBUG1 are equivalent.  DEBUG2
+and DEBUG3 each specify higher levels of debugging output.
+Logging with a DEBUG level violates the privacy of users
 and is not recommended.
 .It Cm MACs
 Specifies the available MAC (message authentication code) algorithms.
@@ -741,14 +773,6 @@ Specifies whether public key authentication is allowed.
 The default is
 .Dq yes .
 Note that this option applies to protocol version 2 only.
-.It Cm ReverseMappingCheck
-Specifies whether
-.Nm
-should try to verify the remote host name and check that
-the resolved host name for the remote IP address maps back to the
-very same IP address.
-The default is
-.Dq no .
 .It Cm RhostsAuthentication
 Specifies whether authentication using rhosts or /etc/hosts.equiv
 files is sufficient.
@@ -816,6 +840,14 @@ will be disabled because
 does not know how to handle
 .Xr xauth 1
 cookies.
+.It Cm VerifyReverseMapping
+Specifies whether
+.Nm
+should try to verify the remote host name and check that
+the resolved host name for the remote IP address maps back to the
+very same IP address.
+The default is
+.Dq no .
 .It Cm X11DisplayOffset
 Specifies the first display number available for
 .Nm sshd Ns 's
@@ -833,6 +865,31 @@ way, as users can always install their own forwarders.
 X11 forwarding is automatically disabled if
 .Cm UseLogin
 is enabled.
+.It Cm X11UseLocalhost
+Specifies whether
+.Nm
+should bind the X11 forwarding server to the loopback address or to
+the wildcard address.  By default,
+.Nm
+binds the forwarding server to the loopback address and sets the
+hostname part of the
+.Ev DISPLAY
+environment variable to
+.Dq localhost .
+This prevents remote hosts from connecting to the fake display.
+However, some older X11 clients may not function with this
+configuration.
+.Cm X11UseLocalhost
+may be set to
+.Dq no
+to specify that the forwarding server should be bound to the wildcard
+address.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
 .It Cm XAuthLocation
 Specifies the location of the
 .Xr xauth 1
@@ -917,7 +974,7 @@ Changes to user's home directory.
 If
 .Pa $HOME/.ssh/rc
 exists, runs it; else if
-.Pa /etc/sshrc
+.Pa /etc/ssh/sshrc
 exists, runs
 it; otherwise runs xauth.
 The
@@ -1054,7 +1111,7 @@ command="dump /home",no-pty,no-port-forwarding 1024 33 23.\|.\|.\|2323 backup.hu
 permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23.\|.\|.\|2323
 .Sh SSH_KNOWN_HOSTS FILE FORMAT
 The
-.Pa /etc/ssh_known_hosts ,
+.Pa /etc/ssh/ssh_known_hosts ,
 and
 .Pa $HOME/.ssh/known_hosts
 files contain host public keys for all known hosts.
@@ -1079,7 +1136,7 @@ pattern on the line.
 .Pp
 Bits, exponent, and modulus are taken directly from the RSA host key; they
 can be obtained, e.g., from
-.Pa /etc/ssh_host_key.pub .
+.Pa /etc/ssh/ssh_host_key.pub .
 The optional comment field continues to the end of the line, and is not used.
 .Pp
 Lines starting with
@@ -1101,7 +1158,7 @@ Note that the lines in these files are typically hundreds of characters
 long, and you definitely don't want to type in the host keys by hand.
 Rather, generate them by a script
 or by taking
-.Pa /etc/ssh_host_key.pub
+.Pa /etc/ssh/ssh_host_key.pub
 and adding the host names at the front.
 .Ss Examples
 .Bd -literal
@@ -1110,19 +1167,19 @@ cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
 .Ed
 .Sh FILES
 .Bl -tag -width Ds
-.It Pa /etc/sshd_config
+.It Pa /etc/ssh/sshd_config
 Contains configuration data for
 .Nm sshd .
 This file should be writable by root only, but it is recommended
 (though not necessary) that it be world-readable.
-.It Pa /etc/ssh_host_key, /etc/ssh_host_dsa_key, /etc/ssh_host_rsa_key
+.It Pa /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key
 These three files contain the private parts of the host keys.
 These files should only be owned by root, readable only by root, and not
 accessible to others.
 Note that
 .Nm
 does not start if this file is group/world-accessible.
-.It Pa /etc/ssh_host_key.pub, /etc/ssh_host_dsa_key.pub, /etc/ssh_host_rsa_key.pub
+.It Pa /etc/ssh/ssh_host_key.pub, /etc/ssh/ssh_host_dsa_key.pub, /etc/ssh/ssh_host_rsa_key.pub
 These three files contain the public parts of the host keys.
 These files should be world-readable but writable only by
 root.
@@ -1155,7 +1212,7 @@ and/or
 .Pa id_rsa.pub
 files into this file, as described in
 .Xr ssh-keygen 1 .
-.It Pa "/etc/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
+.It Pa "/etc/ssh/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
 These files are consulted when using rhosts with RSA host
 authentication or protocol version 2 hostbased authentication
 to check the public key of the host.
@@ -1163,7 +1220,7 @@ The key must be listed in one of these files to be accepted.
 The client uses the same files
 to verify that it is connecting to the correct remote host.
 These files should be writable only by root/the owner.
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh/ssh_known_hosts
 should be world-readable, and
 .Pa $HOME/.ssh/known_hosts
 can but need not be world-readable.
@@ -1271,13 +1328,13 @@ something similar to:
 .Ed
 .Pp
 If this file does not exist,
-.Pa /etc/sshrc
+.Pa /etc/ssh/sshrc
 is run, and if that
 does not exist either, xauth is used to store the cookie.
 .Pp
 This file should be writable only by the user, and need not be
 readable by anyone else.
-.It Pa /etc/sshrc
+.It Pa /etc/ssh/sshrc
 Like
 .Pa $HOME/.ssh/rc .
 This can be used to specify
index 71a5c2c2e98c6dcc530ec69e1ba014511e8d31de..ea929325196e4a0dbf21915973bcbec6fbe354f8 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.209 2001/11/10 13:19:45 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.228 2002/02/27 21:23:13 stevesk Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
-#include <openssl/hmac.h>
+#include <openssl/md5.h>
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -169,11 +169,11 @@ struct {
  * Flag indicating whether the RSA server key needs to be regenerated.
  * Is set in the SIGALRM handler and cleared when the key is regenerated.
  */
-int key_do_regen = 0;
+static volatile sig_atomic_t key_do_regen = 0;
 
 /* This is set to true when a signal is received. */
-int received_sighup = 0;
-int received_sigterm = 0;
+static volatile sig_atomic_t received_sighup = 0;
+static volatile sig_atomic_t received_sigterm = 0;
 
 /* session identifier, used by RSA-auth */
 u_char session_id[16];
@@ -185,6 +185,10 @@ int session_id2_len = 0;
 /* record remote hostname or ip */
 u_int utmp_len = MAXHOSTNAMELEN;
 
+/* options.max_startup sized array of fd ints */
+int *startup_pipes = NULL;
+int startup_pipe;              /* in child */
+
 /* Prototypes for various functions defined later in this file. */
 void destroy_sensitive_data(void);
 
@@ -203,6 +207,16 @@ close_listen_socks(void)
        num_listen_socks = -1;
 }
 
+static void
+close_startup_pipes(void)
+{
+       int i;
+       if (startup_pipes)
+               for (i = 0; i < options.max_startups; i++)
+                       if (startup_pipes[i] != -1)
+                               close(startup_pipes[i]);
+}
+
 /*
  * Signal handler for SIGHUP.  Sshd execs itself when it receives SIGHUP;
  * the effect is to reread the configuration file (and to regenerate
@@ -211,8 +225,11 @@ close_listen_socks(void)
 static void
 sighup_handler(int sig)
 {
+       int save_errno = errno;
+
        received_sighup = 1;
        signal(SIGHUP, sighup_handler);
+       errno = save_errno;
 }
 
 /*
@@ -224,6 +241,7 @@ sighup_restart(void)
 {
        log("Received SIGHUP; restarting.");
        close_listen_socks();
+       close_startup_pipes();
        execv(saved_argv[0], saved_argv);
        log("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno));
        exit(1);
@@ -381,7 +399,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
                fatal_cleanup();
        }
        debug("Client protocol version %d.%d; client software version %.100s",
-             remote_major, remote_minor, remote_version);
+           remote_major, remote_minor, remote_version);
 
        compat_datafellows(remote_version);
 
@@ -392,7 +410,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
        }
 
        mismatch = 0;
-       switch(remote_major) {
+       switch (remote_major) {
        case 1:
                if (remote_minor == 99) {
                        if (options.protocol & SSH_PROTO_2)
@@ -449,7 +467,7 @@ destroy_sensitive_data(void)
                key_free(sensitive_data.server_key);
                sensitive_data.server_key = NULL;
        }
-       for(i = 0; i < options.num_host_key_files; i++) {
+       for (i = 0; i < options.num_host_key_files; i++) {
                if (sensitive_data.host_keys[i]) {
                        key_free(sensitive_data.host_keys[i]);
                        sensitive_data.host_keys[i] = NULL;
@@ -462,33 +480,37 @@ destroy_sensitive_data(void)
 static char *
 list_hostkey_types(void)
 {
-       static char buf[1024];
+       Buffer b;
+       char *p;
        int i;
-       buf[0] = '\0';
-       for(i = 0; i < options.num_host_key_files; i++) {
+
+       buffer_init(&b);
+       for (i = 0; i < options.num_host_key_files; i++) {
                Key *key = sensitive_data.host_keys[i];
                if (key == NULL)
                        continue;
-               switch(key->type) {
+               switch (key->type) {
                case KEY_RSA:
                case KEY_DSA:
-                       strlcat(buf, key_ssh_name(key), sizeof buf);
-                       strlcat(buf, ",", sizeof buf);
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       p = key_ssh_name(key);
+                       buffer_append(&b, p, strlen(p));
                        break;
                }
        }
-       i = strlen(buf);
-       if (i > 0 && buf[i-1] == ',')
-               buf[i-1] = '\0';
-       debug("list_hostkey_types: %s", buf);
-       return buf;
+       buffer_append(&b, "\0", 1);
+       p = xstrdup(buffer_ptr(&b));
+       buffer_free(&b);
+       debug("list_hostkey_types: %s", p);
+       return p;
 }
 
 static Key *
 get_hostkey_by_type(int type)
 {
        int i;
-       for(i = 0; i < options.num_host_key_files; i++) {
+       for (i = 0; i < options.num_host_key_files; i++) {
                Key *key = sensitive_data.host_keys[i];
                if (key != NULL && key->type == type)
                        return key;
@@ -525,8 +547,30 @@ drop_connection(int startups)
        return (r < p) ? 1 : 0;
 }
 
-int *startup_pipes = NULL;     /* options.max_startup sized array of fd ints */
-int startup_pipe;              /* in child */
+static void
+usage(void)
+{
+       fprintf(stderr, "sshd version %s\n", SSH_VERSION);
+       fprintf(stderr, "Usage: %s [options]\n", __progname);
+       fprintf(stderr, "Options:\n");
+       fprintf(stderr, "  -f file    Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
+       fprintf(stderr, "  -d         Debugging mode (multiple -d means more debugging)\n");
+       fprintf(stderr, "  -i         Started from inetd\n");
+       fprintf(stderr, "  -D         Do not fork into daemon mode\n");
+       fprintf(stderr, "  -t         Only test configuration file and keys\n");
+       fprintf(stderr, "  -q         Quiet (no logging)\n");
+       fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
+       fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
+       fprintf(stderr, "  -g seconds Grace period for authentication (default: 600)\n");
+       fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
+       fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n",
+           _PATH_HOST_KEY_FILE);
+       fprintf(stderr, "  -u len     Maximum hostname length for utmp recording\n");
+       fprintf(stderr, "  -4         Use IPv4 only\n");
+       fprintf(stderr, "  -6         Use IPv6 only\n");
+       fprintf(stderr, "  -o option  Process the option as if it was read from a configuration file.\n");
+       exit(1);
+}
 
 /*
  * Main program for the daemon.
@@ -564,7 +608,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:V:u:dDeiqtQ46")) != -1) {
+       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) {
                switch (opt) {
                case '4':
                        IPv4or6 = AF_INET;
@@ -646,27 +690,15 @@ main(int ac, char **av)
                case 'u':
                        utmp_len = atoi(optarg);
                        break;
+               case 'o':
+                       if (process_server_config_line(&options, optarg,
+                           "command-line", 0) != 0)
+                               exit(1);
+                       break;
                case '?':
                default:
-                       fprintf(stderr, "sshd version %s\n", SSH_VERSION);
-                       fprintf(stderr, "Usage: %s [options]\n", __progname);
-                       fprintf(stderr, "Options:\n");
-                       fprintf(stderr, "  -f file    Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
-                       fprintf(stderr, "  -d         Debugging mode (multiple -d means more debugging)\n");
-                       fprintf(stderr, "  -i         Started from inetd\n");
-                       fprintf(stderr, "  -D         Do not fork into daemon mode\n");
-                       fprintf(stderr, "  -t         Only test configuration file and keys\n");
-                       fprintf(stderr, "  -q         Quiet (no logging)\n");
-                       fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
-                       fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
-                       fprintf(stderr, "  -g seconds Grace period for authentication (default: 600)\n");
-                       fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
-                       fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n",
-                           _PATH_HOST_KEY_FILE);
-                       fprintf(stderr, "  -u len     Maximum hostname length for utmp recording\n");
-                       fprintf(stderr, "  -4         Use IPv4 only\n");
-                       fprintf(stderr, "  -6         Use IPv6 only\n");
-                       exit(1);
+                       usage();
+                       break;
                }
        }
        SSLeay_add_all_algorithms();
@@ -677,8 +709,10 @@ main(int ac, char **av)
         * key (unless started from inetd)
         */
        log_init(__progname,
-           options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
-           options.log_facility == -1 ? SYSLOG_FACILITY_AUTH : options.log_facility,
+           options.log_level == SYSLOG_LEVEL_NOT_SET ?
+           SYSLOG_LEVEL_INFO : options.log_level,
+           options.log_facility == SYSLOG_FACILITY_NOT_SET ?
+           SYSLOG_FACILITY_AUTH : options.log_facility,
            !inetd_flag);
 
 #ifdef _CRAY
@@ -706,14 +740,14 @@ main(int ac, char **av)
 
        /* load private host keys */
        sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*));
-       for(i = 0; i < options.num_host_key_files; i++)
+       for (i = 0; i < options.num_host_key_files; i++)
                sensitive_data.host_keys[i] = NULL;
        sensitive_data.server_key = NULL;
        sensitive_data.ssh1_host_key = NULL;
        sensitive_data.have_ssh1_key = 0;
        sensitive_data.have_ssh2_key = 0;
 
-       for(i = 0; i < options.num_host_key_files; i++) {
+       for (i = 0; i < options.num_host_key_files; i++) {
                key = key_load_private(options.host_key_files[i], "", NULL);
                sensitive_data.host_keys[i] = key;
                if (key == NULL) {
@@ -722,7 +756,7 @@ main(int ac, char **av)
                        sensitive_data.host_keys[i] = NULL;
                        continue;
                }
-               switch(key->type){
+               switch (key->type) {
                case KEY_RSA1:
                        sensitive_data.ssh1_host_key = key;
                        sensitive_data.have_ssh1_key = 1;
@@ -814,7 +848,7 @@ main(int ac, char **av)
        /* Chdir to the root directory so that the current disk can be
           unmounted if desired. */
        chdir("/");
-       
+
        /* ignore SIGPIPE */
        signal(SIGPIPE, SIG_IGN);
 
@@ -866,11 +900,11 @@ main(int ac, char **av)
                         * close.
                         */
                        setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
-                           (void *) &on, sizeof(on));
+                           &on, sizeof(on));
                        linger.l_onoff = 1;
                        linger.l_linger = 5;
                        setsockopt(listen_sock, SOL_SOCKET, SO_LINGER,
-                           (void *) &linger, sizeof(linger));
+                           &linger, sizeof(linger));
 
                        debug("Bind to port %s on %s.", strport, ntop);
 
@@ -963,7 +997,7 @@ main(int ac, char **av)
                                error("select: %.100s", strerror(errno));
                        if (received_sigterm) {
                                log("Received signal %d; terminating.",
-                                   received_sigterm);
+                                   (int) received_sigterm);
                                close_listen_socks();
                                unlink(options.pid_file);
                                exit(255);
@@ -1002,6 +1036,7 @@ main(int ac, char **av)
                                }
                                if (fcntl(newsock, F_SETFL, 0) < 0) {
                                        error("newsock del O_NONBLOCK: %s", strerror(errno));
+                                       close(newsock);
                                        continue;
                                }
                                if (drop_connection(startups) == 1) {
@@ -1055,9 +1090,7 @@ main(int ac, char **av)
                                                 * the connection.
                                                 */
                                                startup_pipe = startup_p[1];
-                                               for (j = 0; j < options.max_startups; j++)
-                                                       if (startup_pipes[j] != -1)
-                                                               close(startup_pipes[j]);
+                                               close_startup_pipes();
                                                close_listen_socks();
                                                sock_in = newsock;
                                                sock_out = newsock;
@@ -1117,11 +1150,11 @@ main(int ac, char **av)
        /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
        linger.l_onoff = 1;
        linger.l_linger = 5;
-       setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger));
+       setsockopt(sock_in, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
 
        /* Set keepalives if requested. */
        if (options.keepalives &&
-           setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
+           setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on,
            sizeof(on)) < 0)
                error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
 
@@ -1174,8 +1207,9 @@ main(int ac, char **av)
         * machine, he can connect from any port.  So do not use these
         * authentication methods from machines that you do not trust.
         */
-       if (remote_port >= IPPORT_RESERVED ||
-           remote_port < IPPORT_RESERVED / 2) {
+       if (options.rhosts_authentication &&
+           (remote_port >= IPPORT_RESERVED ||
+           remote_port < IPPORT_RESERVED / 2)) {
                debug("Rhosts Authentication disabled, "
                    "originating port %d not trusted.", remote_port);
                options.rhosts_authentication = 0;
@@ -1224,7 +1258,6 @@ static void
 do_ssh1_kex(void)
 {
        int i, len;
-       int plen, slen;
        int rsafail = 0;
        BIGNUM *session_key_int;
        u_char session_key[SSH_SESSION_KEY_LENGTH];
@@ -1308,7 +1341,7 @@ do_ssh1_kex(void)
            BN_num_bits(sensitive_data.ssh1_host_key->rsa->n));
 
        /* Read clients reply (cipher type and session key). */
-       packet_read_expect(&plen, SSH_CMSG_SESSION_KEY);
+       packet_read_expect(SSH_CMSG_SESSION_KEY);
 
        /* Get cipher type and check whether we accept this. */
        cipher_type = packet_get_char();
@@ -1325,13 +1358,13 @@ do_ssh1_kex(void)
        debug("Encryption type: %.200s", cipher_name(cipher_type));
 
        /* Get the encrypted integer. */
-       session_key_int = BN_new();
-       packet_get_bignum(session_key_int, &slen);
+       if ((session_key_int = BN_new()) == NULL)
+               fatal("do_ssh1_kex: BN_new failed");
+       packet_get_bignum(session_key_int);
 
        protocol_flags = packet_get_int();
        packet_set_protocol_flags(protocol_flags);
-
-       packet_integrity_check(plen, 1 + 8 + slen + 4, SSH_CMSG_SESSION_KEY);
+       packet_check_eom();
 
        /*
         * Decrypt it using our private server key and private host key (key
@@ -1401,7 +1434,7 @@ do_ssh1_kex(void)
        }
        if (rsafail) {
                int bytes = BN_num_bytes(session_key_int);
-               char *buf = xmalloc(bytes);
+               u_char *buf = xmalloc(bytes);
                MD5_CTX md;
 
                log("do_connection: generating a fake encryption key");
index e1a052a169a523c329d7259d4d4021d4d5e566d7..3eb19875ad693a1aa1635ed3bfaddbc79dfedd79 100644 (file)
@@ -1,80 +1,92 @@
-#      $OpenBSD: sshd_config,v 1.42 2001/09/20 20:57:51 mouring Exp $
-
-# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
+#      $OpenBSD: sshd_config,v 1.48 2002/02/19 02:50:59 deraadt Exp $
 
 # This is the sshd server system-wide configuration file.  See sshd(8)
 # for more information.
 
-Port 22
+# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# The strategy used for options in the default sshd_config shipped with
+# OpenSSH is to specify options with their default value where
+# possible, but leave them commented.  Uncommented options change a
+# default value.
+
+#Port 22
 #Protocol 2,1
 #ListenAddress 0.0.0.0
 #ListenAddress ::
 
 # HostKey for protocol version 1
-HostKey /etc/ssh_host_key
+#HostKey /etc/ssh/ssh_host_key
 # HostKeys for protocol version 2
-HostKey /etc/ssh_host_rsa_key
-HostKey /etc/ssh_host_dsa_key
+#HostKey /etc/ssh/ssh_host_rsa_key
+#HostKey /etc/ssh/ssh_host_dsa_key
 
 # Lifetime and size of ephemeral version 1 server key
-KeyRegenerationInterval 3600
-ServerKeyBits 768
+#KeyRegenerationInterval 3600
+#ServerKeyBits 768
 
 # Logging
-SyslogFacility AUTH
-LogLevel INFO
 #obsoletes QuietMode and FascistLogging
+#SyslogFacility AUTH
+#LogLevel INFO
 
 # Authentication:
 
-LoginGraceTime 600
-PermitRootLogin yes
-StrictModes yes
+#LoginGraceTime 600
+#PermitRootLogin yes
+#StrictModes yes
 
-RSAAuthentication yes
-PubkeyAuthentication yes
-#AuthorizedKeysFile    %h/.ssh/authorized_keys
+#RSAAuthentication yes
+#PubkeyAuthentication yes
+#AuthorizedKeysFile    .ssh/authorized_keys
 
 # rhosts authentication should not be used
-RhostsAuthentication no
+#RhostsAuthentication no
 # Don't read the user's ~/.rhosts and ~/.shosts files
-IgnoreRhosts yes
-# For this to work you will also need host keys in /etc/ssh_known_hosts
-RhostsRSAAuthentication no
+#IgnoreRhosts yes
+# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
+#RhostsRSAAuthentication no
 # similar for protocol version 2
-HostbasedAuthentication no
-# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
-#IgnoreUserKnownHosts yes
+#HostbasedAuthentication no
+# Change to yes if you don't trust ~/.ssh/known_hosts for
+# RhostsRSAAuthentication and HostbasedAuthentication
+#IgnoreUserKnownHosts no
 
 # To disable tunneled clear text passwords, change to no here!
-PasswordAuthentication yes
-PermitEmptyPasswords no
-
-# Uncomment to disable s/key passwords 
-#ChallengeResponseAuthentication no
+#PasswordAuthentication yes
+#PermitEmptyPasswords no
 
-# Uncomment to enable PAM keyboard-interactive authentication 
-# Warning: enabling this may bypass the setting of 'PasswordAuthentication'
-#PAMAuthenticationViaKbdInt yes
+# Change to no to disable s/key passwords
+#ChallengeResponseAuthentication yes
 
-# To change Kerberos options
-#KerberosAuthentication no
+# Kerberos options
+# KerberosAuthentication automatically enabled if keyfile exists
+#KerberosAuthentication yes
 #KerberosOrLocalPasswd yes
-#AFSTokenPassing no
-#KerberosTicketCleanup no
+#KerberosTicketCleanup yes
+
+# AFSTokenPassing automatically enabled if k_hasafs() is true
+#AFSTokenPassing yes
 
-# Kerberos TGT Passing does only work with the AFS kaserver
-#KerberosTgtPassing yes
+# Kerberos TGT Passing only works with the AFS kaserver
+#KerberosTgtPassing no
+
+# Set this to 'yes' to enable PAM keyboard-interactive authentication 
+# Warning: enabling this may bypass the setting of 'PasswordAuthentication'
+#PAMAuthenticationViaKbdInt yes
 
-X11Forwarding no
-X11DisplayOffset 10
-PrintMotd yes
-#PrintLastLog no
-KeepAlive yes
+#X11Forwarding no
+#X11DisplayOffset 10
+#X11UseLocalhost yes
+#PrintMotd yes
+#PrintLastLog yes
+#KeepAlive yes
 #UseLogin no
 
-#MaxStartups 10:30:60
-#Banner /etc/issue.net
-#ReverseMappingCheck yes
+#MaxStartups 10
+# no default banner path
+#Banner /some/path
+#VerifyReverseMapping no
 
+# override default of no subsystems
 Subsystem      sftp    /usr/libexec/sftp-server
index b7558b9e92561f5e0e7c1da79c6a9b021278263a..78c51abd6793df415c5147cdcf1f8524230fbc7e 100644 (file)
@@ -39,7 +39,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshlogin.c,v 1.2 2001/03/24 16:43:27 stevesk Exp $");
+RCSID("$OpenBSD: sshlogin.c,v 1.3 2001/12/19 07:18:56 deraadt Exp $");
 
 #include "loginrec.h"
 
@@ -67,7 +67,7 @@ get_last_login_time(uid_t uid, const char *logname,
 
 void
 record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
-            const char *host, struct sockaddr * addr)
+       const char *host, struct sockaddr * addr)
 {
   struct logininfo *li;
 
@@ -94,11 +94,11 @@ record_utmp_only(pid_t pid, const char *ttyname, const char *user,
 /* Records that the user has logged out. */
 
 void
-record_logout(pid_t pid, const char *ttyname)
+record_logout(pid_t pid, const char *ttyname, const char *user)
 {
   struct logininfo *li;
 
-  li = login_alloc_entry(pid, NULL, NULL, ttyname);
+  li = login_alloc_entry(pid, user, NULL, ttyname);
   login_logout(li);
   login_free_entry(li);
 }
index 79d42a98222385880924b54c10af640f4cccf242..bd30278e0e7d8d294f6469d33a5c66ea9e57d43c 100644 (file)
 void
 record_login(pid_t, const char *, const char *, uid_t,
     const char *, struct sockaddr *);
-void   record_logout(pid_t, const char *);
+void   record_logout(pid_t, const char *, const char *);
 u_long         get_last_login_time(uid_t, const char *, char *, u_int);
 
+#ifdef LOGIN_NEEDS_UTMPX
+void   record_utmp_only(pid_t, const char *, const char *, const char *,
+               struct sockaddr *);
+#endif
+
 #endif
index e1e60314109f14da39bab97c4db3d36b240b9b9a..71c48b5730248bac2a8dc54ff44f6395f220df42 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshpty.c,v 1.3 2001/07/22 21:32:27 markus Exp $");
+RCSID("$OpenBSD: sshpty.c,v 1.4 2001/12/19 07:18:56 deraadt Exp $");
 
 #ifdef HAVE_UTIL_H
 # include <util.h>
@@ -156,7 +156,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
        *ttyfd = open(name, O_RDWR | O_NOCTTY);
        if (*ttyfd < 0) {
                error("Could not open pty slave side %.100s: %.100s",
-                     name, strerror(errno));
+                   name, strerror(errno));
                close(*ptyfd);
                return 0;
        }
@@ -328,7 +328,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
        fd = open(_PATH_TTY, O_WRONLY);
        if (fd < 0)
                error("open /dev/tty failed - could not set controlling tty: %.100s",
-                     strerror(errno));
+                   strerror(errno));
        else {
                close(fd);
        }
@@ -339,7 +339,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
 
 void
 pty_change_window_size(int ptyfd, int row, int col,
-                      int xpixel, int ypixel)
+       int xpixel, int ypixel)
 {
        struct winsize w;
        w.ws_row = row;
@@ -378,15 +378,15 @@ pty_setowner(struct passwd *pw, const char *ttyname)
 
        if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
                if (chown(ttyname, pw->pw_uid, gid) < 0) {
-                       if (errno == EROFS && 
+                       if (errno == EROFS &&
                           (st.st_uid == pw->pw_uid || st.st_uid == 0))
                                error("chown(%.100s, %d, %d) failed: %.100s",
-                                     ttyname, pw->pw_uid, gid,
-                                     strerror(errno));
+                                   ttyname, pw->pw_uid, gid,
+                                   strerror(errno));
                        else
                                fatal("chown(%.100s, %d, %d) failed: %.100s",
-                                     ttyname, pw->pw_uid, gid,
-                                     strerror(errno));
+                                   ttyname, pw->pw_uid, gid,
+                                   strerror(errno));
                }
        }
 
@@ -395,10 +395,10 @@ pty_setowner(struct passwd *pw, const char *ttyname)
                        if (errno == EROFS &&
                            (st.st_mode & (S_IRGRP | S_IROTH)) == 0)
                                error("chmod(%.100s, 0%o) failed: %.100s",
-                                     ttyname, mode, strerror(errno));
+                                   ttyname, mode, strerror(errno));
                        else
                                fatal("chmod(%.100s, 0%o) failed: %.100s",
-                                     ttyname, mode, strerror(errno));
+                                   ttyname, mode, strerror(errno));
                }
        }
 }
index 4eb479f76edbc0fcb7c52486eeb4f9ccc96d19ce..df65e284e4c30305246d0c467630161d978bdcfe 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: sshpty.h,v 1.4 2002/03/04 17:27:39 stevesk Exp $      */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,8 +14,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: sshpty.h,v 1.3 2001/06/26 17:27:25 markus Exp $"); */
-
 #ifndef SSHPTY_H
 #define SSHPTY_H
 
index 78498908fc60399fc4f577a6f06f933461fbc176..5c016f80af87a42bd9e891048ea58a494d202480 100644 (file)
@@ -1,4 +1,3 @@
-/* $OpenBSD: sshtty.c,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -36,6 +35,7 @@
  */
 
 #include "includes.h"
+RCSID("$OpenBSD: sshtty.c,v 1.3 2002/03/04 17:27:39 stevesk Exp $");
 
 #include "sshtty.h"
 #include "log.h"
@@ -46,7 +46,7 @@ static int _in_raw_mode = 0;
 int
 in_raw_mode(void)
 {
-       return _in_raw_mode;    
+       return _in_raw_mode;
 }
 
 struct termios
index c0bb0b1f898cf7db1d62923a18eda4584c7eec1d..ccc001f200197c5e0ce4ba168a17600e012b9fd0 100644 (file)
@@ -43,7 +43,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ttymodes.c,v 1.14 2001/06/24 17:18:31 markus Exp $");
+RCSID("$OpenBSD: ttymodes.c,v 1.16 2001/12/27 20:39:58 markus Exp $");
 
 #include "packet.h"
 #include "log.h"
@@ -396,7 +396,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
 
                default:
                        debug("Ignoring unsupported tty mode opcode %d (0x%x)",
-                             opcode, opcode);
+                           opcode, opcode);
                        if (!compat20) {
                                /*
                                 * SSH1:
@@ -422,7 +422,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
                                         * more coming after the mode data.
                                         */
                                        log("parse_tty_modes: unknown opcode %d", opcode);
-                                       packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
                                        goto set;
                                }
                        } else {
index ad980e98cfe01c89238959321765f8d1bd7df9b1..687059281cc1220254a5ad111ae1cfaf67801789 100644 (file)
@@ -1,4 +1,5 @@
-/* RCSID("$OpenBSD: ttymodes.h,v 1.11 2001/04/14 16:33:20 stevesk Exp $"); */
+/*     $OpenBSD: ttymodes.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $   */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
index cc91fcf25fd54f0e9e557058869c17cad45c2df3..bc67d74b0f6d1235294095260902f02b769c3bd5 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: uidswap.c,v 1.18 2001/08/08 21:34:19 markus Exp $");
+RCSID("$OpenBSD: uidswap.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $");
 
 #include "log.h"
 #include "uidswap.h"
@@ -67,7 +67,7 @@ temporarily_use_uid(struct passwd *pw)
 
        privileged = 1;
        temporarily_use_uid_effective = 1;
-       saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups);                           
+       saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups);
        if (saved_egroupslen < 0)
                fatal("getgroups: %.100s", strerror(errno));
 
@@ -76,7 +76,7 @@ temporarily_use_uid(struct passwd *pw)
                if (initgroups(pw->pw_name, pw->pw_gid) < 0)
                        fatal("initgroups: %s: %.100s", pw->pw_name,
                            strerror(errno));
-               user_groupslen = getgroups(NGROUPS_MAX, user_groups);                           
+               user_groupslen = getgroups(NGROUPS_MAX, user_groups);
                if (user_groupslen < 0)
                        fatal("getgroups: %.100s", strerror(errno));
        }
index f3774f1f39608734f6d68a110cfc42190deba6bc..89fcb08152d744fd856128a4904d2f18d3272d5c 100644 (file)
@@ -1,5 +1,3 @@
-/*     $OpenBSD: uuencode.c,v 1.12 2001/03/01 02:27:18 deraadt Exp $   */
-
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -27,8 +25,7 @@
 #include "includes.h"
 #include "xmalloc.h"
 #include "uuencode.h"
-
-RCSID("$OpenBSD: uuencode.c,v 1.12 2001/03/01 02:27:18 deraadt Exp $");
+RCSID("$OpenBSD: uuencode.c,v 1.15 2002/03/04 17:27:39 stevesk Exp $");
 
 int
 uuencode(u_char *src, u_int srclength,
@@ -50,7 +47,7 @@ uudecode(const char *src, u_char *target, size_t targsize)
                ;
        for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
                ;
-       /* and remote trailing whitespace because __b64_pton needs this */
+       /* and remove trailing whitespace because __b64_pton needs this */
        *p = '\0';
        len = __b64_pton(encoded, target, targsize);
        xfree(encoded);
@@ -58,7 +55,7 @@ uudecode(const char *src, u_char *target, size_t targsize)
 }
 
 void
-dump_base64(FILE *fp, u_char *data, int len)
+dump_base64(FILE *fp, u_char *data, u_int len)
 {
        u_char *buf = xmalloc(2*len);
        int i, n;
index 0067635b677f25e547a39c09e723083115b5b0dc..682b623acb814d07263a53334065b2b96931a460 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uuencode.h,v 1.8 2001/06/26 17:27:25 markus Exp $     */
+/*     $OpenBSD: uuencode.h,v 1.9 2002/02/25 16:33:27 markus Exp $     */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -28,5 +28,5 @@
 #define UUENCODE_H
 int     uuencode(u_char *, u_int, char *, size_t);
 int     uudecode(const char *, u_char *, size_t);
-void    dump_base64(FILE *, u_char *, int);
+void    dump_base64(FILE *, u_char *, u_int);
 #endif
index 804e560c72fa28f8ad25fa15b7bf02ee68ee6674..529bd67fa3ac565f87f78da21e29fec5038f5249 100644 (file)
@@ -1,3 +1,4 @@
-/* $OpenBSD: version.h,v 1.25 2001/10/15 16:10:50 deraadt Exp $ */
+/* $OpenBSD: version.h,v 1.28 2002/03/06 00:25:55 markus Exp $ */
+
+#define SSH_VERSION    "OpenSSH_3.1p1"
 
-#define SSH_VERSION    "OpenSSH_3.0.2p1"
index e14d0141d1dad18b83f9c8ca0976fdc53a60bfa0..338a2d22dfce565e72ca2d0af35a37e95b19d021 100644 (file)
@@ -1,3 +1,5 @@
+/*     $OpenBSD: xmalloc.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $     */
+
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -14,8 +16,6 @@
  * called by a name other than "ssh" or "Secure Shell".
  */
 
-/* RCSID("$OpenBSD: xmalloc.h,v 1.7 2001/06/26 17:27:25 markus Exp $"); */
-
 #ifndef XMALLOC_H
 #define XMALLOC_H
 
This page took 6.584726 seconds and 5 git commands to generate.