diff options
author | des <des@FreeBSD.org> | 2004-01-07 11:10:17 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2004-01-07 11:10:17 +0000 |
commit | b5d16e713867abc03742aca168b7a54a25c4790b (patch) | |
tree | d7e09b6d73cb37aa875779151439b14df7273b87 /crypto | |
parent | dc42ef026434942c55e8af3dd0e975d36afc6843 (diff) | |
download | FreeBSD-src-b5d16e713867abc03742aca168b7a54a25c4790b.zip FreeBSD-src-b5d16e713867abc03742aca168b7a54a25c4790b.tar.gz |
Vendor import of OpenSSH 3.7.1p2.
Diffstat (limited to 'crypto')
216 files changed, 12791 insertions, 7117 deletions
diff --git a/crypto/openssh/CREDITS b/crypto/openssh/CREDITS index 0c86684..092229c 100644 --- a/crypto/openssh/CREDITS +++ b/crypto/openssh/CREDITS @@ -5,7 +5,7 @@ Theo de Raadt, and Dug Song - Creators of OpenSSH Alain St-Denis <Alain.St-Denis@ec.gc.ca> - Irix fix Alexandre Oliva <oliva@lsd.ic.unicamp.br> - AIX fixes -Andre Lucas <andre.lucas@dial.pipex.com> - new login code, many fixes +Andre Lucas <andre@ae-35.com> - new login code, many fixes Andreas Steinmetz <ast@domdv.de> - Shadow password expiry support Andrew McGill <andrewm@datrix.co.za> - SCO fixes Andrew Morgan <morgan@transmeta.com> - PAM bugfixes @@ -23,7 +23,7 @@ Chris Saia <csaia@wtower.com> - SuSE packaging Chris, the Young One <cky@pobox.com> - Password auth fixes Christos Zoulas <christos@zoulas.com> - Autoconf fixes Chun-Chung Chen <cjj@u.washington.edu> - RPM fixes -Corinna Vinschen <vinschen@cygnus.com> - Cygwin support +Corinna Vinschen <vinschen@redhat.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 @@ -49,6 +49,7 @@ Juergen Keil <jk@tools.de> - scp bugfixing KAMAHARA Junzo <kamahara@cc.kshosen.ac.jp> - Configure fixes Kees Cook <cook@cpoint.net> - scp fixes Kenji Miyake <kenji@miyake.org> - Configure fixes +Kevin Cawlfield <cawlfiel@us.ibm.com> - AIX fixes. Kevin O'Connor <kevin_oconnor@standardandpoors.com> - RSAless operation Kevin Steves <stevesk@pobox.com> - HP support, bugfixes, improvements Kiyokazu SUTO <suto@ks-and-ks.ne.jp> - Bugfixes @@ -69,11 +70,13 @@ Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> - Security fixes Pavel Troller <patrol@omni.sinus.cz> - Bugfixes Pekka Savola <pekkas@netcore.fi> - Bugfixes Peter Kocks <peter.kocks@baygate.com> - Makefile fixes +Peter Stuge <stuge@cdy.org> - mdoc2man.awk script Phil Hands <phil@hands.com> - Debian scripts, assorted patches Phil Karn <karn@ka9q.ampr.org> - Autoconf fixes Philippe WILLEM <Philippe.WILLEM@urssaf.fr> - Bugfixes Phill Camp <P.S.S.Camp@ukc.ac.uk> - login code fix Rip Loomis <loomisg@cist.saic.com> - Solaris package support, fixes +Roumen Petrov <openssh@roumenpetrov.info> - Compile & configure fixes SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp> - Multiple bugfixes Simon Wilkinson <sxw@dcs.ed.ac.uk> - PAM fixes, Compat with MIT KrbV Solar Designer <solar@openwall.com> - many patches and technical assistance @@ -91,5 +94,5 @@ Apologies to anyone I have missed. Damien Miller <djm@mindrot.org> -$Id: CREDITS,v 1.67 2002/07/28 20:31:19 stevesk Exp $ +$Id: CREDITS,v 1.74 2003/09/07 02:34:54 dtucker Exp $ diff --git a/crypto/openssh/ChangeLog b/crypto/openssh/ChangeLog index ebde747..eb44d4a 100644 --- a/crypto/openssh/ChangeLog +++ b/crypto/openssh/ChangeLog @@ -1,3 +1,1137 @@ +20030923 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/09/18 07:52:54 + [sshconnect.c] + missing {}; bug #656; jclonguet at free.fr + - markus@cvs.openbsd.org 2003/09/18 07:54:48 + [buffer.c] + protect against double free; #660; zardoz at users.sf.net + - markus@cvs.openbsd.org 2003/09/18 08:49:45 + [deattack.c misc.c session.c ssh-agent.c] + more buffer allocation fixes; from Solar Designer; CAN-2003-0682; + ok millert@ + - markus@cvs.openbsd.org 2003/09/19 09:02:02 + [packet.c] + buffer_dump only if PACKET_DEBUG is defined; Jedi/Sector One; pr 3471 + - (djm) Fix SSH1 challenge kludge + - (djm) Bug #671: Fix builds on OpenBSD + - (djm) Bug #676: Fix PAM stack corruption + - (djm) Fix bad free() in PAM code + - (djm) Don't call pam_end before pam_init + - (djm) Enable build with old OpenSSL again + - (djm) Trim deprecated options from INSTALL. Mention UsePAM + - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu + - (djm) Crank version.h and spec version numbers + - (djm) Release 3.7.1p2 + +20030922 + - (dtucker) [Makefile.in] Bug #644: Fix "make clean" for out-of-tree + builds. Portability corrections from tim@. + - (dtucker) [configure.ac] Bug #665: uid swapping issues on Mac OS X. + Patch from max at quendi.de. + - (dtucker) [configure.ac] Bug #657: uid swapping issues on BSDi. + - (dtucker) [configure.ac] Bug #653: uid swapping issues on Tru64. + - (dtucker) [configure.ac] Bug #693: uid swapping issues on NCR MP-RAS. + Patch from david.haughton at ncr.com + - (dtucker) [configure.ac] Bug #659: uid swapping issues on IRIX 6. + Part of patch supplied by bugzilla-openssh at thewrittenword.com + - (dtucker) [configure.ac openbsd-compat/fake-rfc2553.c + openbsd-compat/fake-rfc2553.h] Bug #659: Test for and handle systems with + where gai_strerror is defined as "const char *". Part of patch supplied + by bugzilla-openssh at thewrittenword.com + - (dtucker) [contrib/cygwin/README contrib/cygwin/ssh-host-config] Update + ssh-host-config to match current defaults, bump README version. Patch from + vinschen at redhat.com. + - (dtucker) [uidswap.c] Don't test restoration of uid on Cygwin since the + OS does not support permanently dropping privileges. Patch from + vinschen at redhat.com. + - (dtucker) [openbsd-compat/port-aix.c] Use correct include for xmalloc.h, + add canohost.h to stop warning. Based on patch from openssh-unix-dev at + thewrittenword.com + - (dtucker) [INSTALL] Bug #686: Document requirement for zlib 1.1.4 or + higher. + - (tim) Fix typo. s/SETEIUD_BREAKS_SETUID/SETEUID_BREAKS_SETUID/ + - (tim) [configure.ac] Bug 665: move 3 new AC_DEFINES outside of AC_TRY_RUN. + Report by distler AT golem ph utexas edu. + - (dtucker) [contrib/aix/pam.conf] Include example pam.conf for AIX from + article by genty at austin.ibm.com, included with the author's permission. + - (tim) [configure.ac] add --disable-etc-default-login option. ok djm + +20030919 + - (djm) Bug #683: Remove reference to --with-ipv4-default from INSTALL; + djast AT cs.toronto.edu + - (djm) Bug #680: Remove missing inet_ntoa.h header reference + - (djm) Bug #646: Fix location of x11-ssh-askpass; Jim + - (dtucker) [openbsd-compat/port-aix.h] Bug #640: Don't include audit.h + unless required. Reorder to reduce warnings. + - (dtucker) [session.c] Bug #643: Fix size_t -> u_int and fix null deref + when /etc/default/login doesn't exist or isn't readable. Fixes from + jparsons-lists at saffron.net and georg.oppenberg at deu mci com. + +20030918 + - (djm) Bug #652: Fix empty password auth + +20030917 + - (djm) OpenBSD Sync + - markus@cvs.openbsd.org 2003/09/16 21:02:40 + [buffer.c channels.c version.h] + more malloc/fatal fixes; ok millert/deraadt; ghudson at MIT.EDU + - (djm) Crank RPM spec versions + - (djm) Release 3.7.1p1 + +20030916 + - (dtucker) [acconfig.h configure.ac defines.h session.c] Bug #252: Retrieve + PATH (or SUPATH) and UMASK from /etc/default/login on platforms that have it + (eg Solaris, Reliant Unix). Patch from Robert.Dahlem at siemens.com. + ok djm@ + - (bal) OpenBSD Sync + - deraadt@cvs.openbsd.org 2003/09/16 03:03:47 + [buffer.c] + do not expand buffer before attempting to reallocate it; markus ok + - (djm) Crank spec versions + - (djm) Banish (safe) sprintf from auth-pam.c. Patch from bal + - (tim) [configure.ac] Fix portability issues. + - (djm) Release 3.7p1 + +20030914 + - (dtucker) [Makefile regress/Makefile] Fix portability issues preventing + the regression tests from running with Solaris' make. Patch from Brian + Poole (raj at cerias.purdue.edu). + - (dtucker) [regress/Makefile] AIX's make doesn't like " +=", so replace + with vanilla "=". + +20030913 + - (dtucker) [regress/agent-timeout.sh] Timeout of 5 sec is borderline for + slower hosts, increase to 10 sec. + - (dtucker) [auth-passwd.c] On AIX, call setauthdb() before loginsuccess(), + required to correctly reset failed login count when using a password + registry other than "files" (eg LDAP, see bug #543). + - (tim) [configure.ac] define WITH_ABBREV_NO_TTY for SCO. + Report by Roger Cornelius. + - (dtucker) [auth-pam.c] Use SSHD_PAM_SERVICE for PAM service name, patch + from cjwatson at debian.org. + +20030912 + - (tim) [regress/agent-ptrace.sh] sh doesn't like "if ! shell_function; then". + - (tim) [Makefile.in] only mkdir regress if it does not exist. + - (tim) [regress/yes-head.sh] shell portability fix. + +20030911 + - (dtucker) [configure.ac] Bug #588, #615: Move other libgen tests to after + the dirname test, to allow a broken dirname to be detected correctly. + Based partially on patch supplied by alex.kiernan at thus.net. ok djm@ + - (tim) [configure.ac] Move libgen tests to before libwrap to unbreak + UnixWare 2.03 using --with-tcp-wrappers. + - (tim) [configure.ac] Prefer setuid/setgid on UnixWare and Open Server. + - (tim) [regress/agent-ptrace.sh regress/dynamic-forward.sh + regress/sftp-cmds.sh regress/stderr-after-eof.sh regress/test-exec.sh] + no longer depends on which(1). patch by dtucker@ + +20030910 + - (dtucker) [configure.ac] Bug #636: Add support for Cray's new X1 machine. + Patch from wendyp at cray.com. + - (dtucker) [configure.ac] Part of bug #615: tcsendbreak might be a macro. + - (dtucker) [regressh/yes-head.sh] Some platforms (eg Solaris) don't have + "yes". + +20030909 + - (tim) [regress/Makefile] Fixes for building outside of a read-only + source tree. + - (tim) [regress/agent-timeout.sh] s/TIMEOUT/SSHAGENT_TIMEOUT/ Fixes conflict + with shell read-only variable. + - (tim) [regress/sftp-badcmds.sh regress/sftp-cmds.sh] Fix errors like + UX:rm: ERROR: Cannot remove '.' or '..' + +20030908 + - (tim) [configure.ac openbsd-compat/getrrsetbyname.c] wrap _getshort and + _getlong in #ifndef + - (tim) [configure.ac acconfig.h openbsd-compat/getrrsetbyname.c] test for + HEADER.ad in arpa/nameser.h + - (tim) [ssh-keygen.c] s/PATH_MAX/MAXPATHLEN/ ok mouring@ + +20030907 + - (dtucker) [agent-ptrace.sh dynamic-forward.sh (all regress/)] + Put "which" inside quotes. + - (dtucker) [dynamic-forward.sh forwarding.sh sftp-batch.sh (all regress/)] + Add ${EXEEXT}: required to work on Cygwin. + - (dtucker) [regress/sftp-batch.sh] Make temporary batch file name more + distinctive, so "rm ${BATCH}.*" doesn't match the script itself. + - (dtucker) [regress/sftp-cmds.sh] Skip quoted file test on Cygwin. + - (dtucker) [openbsd-compat/xcrypt.c] #elsif -> #elif + - (dtucker) [acconfig.h] Typo. + - (dtucker) [CREDITS Makefile.in configure.ac mdoc2man.awk mdoc2man.pl] + Replace mdoc2man.pl with mdoc2man.awk, provided by Peter Stuge. + +20030906 + - (dtucker) [acconfig.h configure.ac uidswap.c] Prefer setuid/setgid on AIX. + +20030905 + - (dtucker) [Makefile.in] Add distclean target for regress/, fix clean target. + +20030904 + - (dtucker) Portablize regression tests. Parts contributed by Roumen + Petrov, David M. Williams and Corinna Vinschen. + - [Makefile.in] Add "make tests" target and "make clean" hooks. + - [regress/agent-getpeereid.sh] Skip test on platforms that don't support + getpeereid. + - [regress/agent-ptrace.sh] Skip tests if platform doesn't support it or + gdb cannot be found. + - [regress/reconfigure/sh] Make path to sshd fully qualified if required. + - [regress/rekey.sh] Remove dependence on /dev/zero (not all platforms have + it). The sparse file will take less disk space too. + - [regress/sftp-cmds.sh] Ensure files used for test are readable. + - [regress/stderr-after-eof.sh] Search for a usable checksum program. + - [regress/sftp-badcmds.sh regress/sftp-cmds.sh regress/sftp.sh + regress/ssh-com-client.sh regress/ssh-com-sftp.sh regress/stderr-data.sh + regress/transfer.sh] Use ${EXEEXT} where appropriate. + - [regress/sftp.sh regress/ssh-com-sftp.sh] Remove dependency on /dev/stdin. + - [regress/agent-ptrace.sh regress/agent-timeout.sh] + "grep -q" -> "grep >/dev/null" + - [regress/agent.sh regress/proto-version.sh regress/ssh-com.sh + regress/test-exec.sh] Handle different ways of echoing without newlines. + - [regress/dynamic-forward.sh] Some "which" programs output on stderr. + - [regress/sftp-cmds.sh] Use portable "test" option. + - [regress/test-exec.sh] Use sudo, search for "whoami" equivalent, always + use Strictmodes no, wait longer for sshd startup. + - [regress/Makefile] Remove BSDisms. + - [regress/README.regress] Add a basic readme. + - [Makefile.in regress/agent-getpeereid.sh] config.h is now in $BUILDDIR + not $OBJ. + - [Makefile.in regress/agent-ptrace] Fix minor regress issues on Cygwin. + +20030903 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/26 09:58:43 + [auth-passwd.c auth.c auth.h auth1.c auth2-none.c auth2-passwd.c] + [auth2.c monitor.c] + fix passwd auth for 'username leaks via timing'; with djm@, original + patches from solar + - markus@cvs.openbsd.org 2003/08/28 12:54:34 + [auth.h] + remove kerberos support from ssh1, since it has been replaced with GSSAPI; + but keep kerberos passwd auth for ssh1 and 2; ok djm, hin, henning, ... + - markus@cvs.openbsd.org 2003/09/02 16:40:29 + [version.h] + enter 3.7 + - jmc@cvs.openbsd.org 2003/09/02 18:50:06 + [sftp.1 ssh_config.5] + escape punctuation; + ok deraadt@ + +20030902 + - (djm) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2003/08/24 17:36:51 + [auth2-gss.c] + 64 bit cleanups; markus ok + - markus@cvs.openbsd.org 2003/08/28 12:54:34 + [auth-krb5.c auth.h auth1.c monitor.c monitor.h monitor_wrap.c] + [monitor_wrap.h readconf.c servconf.c session.c ssh_config.5] + [sshconnect1.c sshd.c sshd_config sshd_config.5] + remove kerberos support from ssh1, since it has been replaced with GSSAPI; + but keep kerberos passwd auth for ssh1 and 2; ok djm, hin, henning, ... + - markus@cvs.openbsd.org 2003/08/29 10:03:15 + [compat.c compat.h] + SSH_BUG_K5USER is unused; ok henning@ + - markus@cvs.openbsd.org 2003/08/29 10:04:36 + [channels.c nchan.c] + be less chatty; debug -> debug2, cleanup; ok henning@ + - markus@cvs.openbsd.org 2003/08/31 10:26:04 + [progressmeter.c] + pass file_size + 1 to snprintf: fixes printing of truncated + file names; fix based on patch/report from sturm@; + - markus@cvs.openbsd.org 2003/08/31 12:14:22 + [progressmeter.c] + do write to buf[-1] + - markus@cvs.openbsd.org 2003/08/31 13:29:05 + [session.c] + call ssh_gssapi_storecreds conditionally from do_exec(); + with sxw@inf.ed.ac.uk + - markus@cvs.openbsd.org 2003/08/31 13:30:18 + [gss-serv.c] + correct string termination in parse_ename(); sxw@inf.ed.ac.uk + - markus@cvs.openbsd.org 2003/08/31 13:31:57 + [gss-serv.c] + whitspace KNF + - markus@cvs.openbsd.org 2003/09/01 09:50:04 + [sshd_config.5] + gss kex is not supported; sxw@inf.ed.ac.uk + - markus@cvs.openbsd.org 2003/09/01 12:50:46 + [readconf.c] + rm gssapidelegatecreds alias; never supported before + - markus@cvs.openbsd.org 2003/09/01 13:52:18 + [ssh.h] + rm whitespace + - markus@cvs.openbsd.org 2003/09/01 18:15:50 + [readconf.c readconf.h servconf.c servconf.h ssh.c] + remove unused kerberos code; ok henning@ + - markus@cvs.openbsd.org 2003/09/01 20:44:54 + [auth2-gss.c] + fix leak + - (djm) Don't initialise pam_conv structures inline. Avoids HP/UX compiler + error. Part of Bug #423, patch from michael_steffens AT hp.com + - (djm) Bug #423: reorder setting of PAM_TTY and calling of PAM session + management (now done in do_setusercontext). Largely from + michael_steffens AT hp.com + - (djm) Fix openbsd-compat/ again - remove references to strl(cpy|cat).h + +20030829 + - (bal) openbsd-compat/ clean up. Considate headers, add in Id on our + files, and added missing license to header. + +20030826 + - (djm) Bug #629: Mark ssh_config option "pamauthenticationviakbdint" + as deprecated. Remove mention from README.privsep. Patch from + aet AT cc.hut.fi + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/22 10:56:09 + [auth2.c auth2-gss.c auth.h compat.c compat.h gss-genr.c gss-serv-krb5.c + gss-serv.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c + readconf.h servconf.c servconf.h session.c session.h ssh-gss.h + ssh_config.5 sshconnect2.c sshd_config sshd_config.5] + support GSS API user authentication; patches from Simon Wilkinson, + stripped down and tested by Jakob and myself. + - markus@cvs.openbsd.org 2003/08/22 13:20:03 + [sshconnect2.c] + remove support for "kerberos-2@ssh.com" + - markus@cvs.openbsd.org 2003/08/22 13:22:27 + [auth2.c] (auth2-krb5.c removed) + nuke "kerberos-2@ssh.com" + - markus@cvs.openbsd.org 2003/08/22 20:55:06 + [LICENCE] + add Simon Wilkinson + - deraadt@cvs.openbsd.org 2003/08/24 17:36:52 + [monitor.c monitor_wrap.c sshconnect2.c] + 64 bit cleanups; markus ok + - fgsch@cvs.openbsd.org 2003/08/25 08:13:09 + [sftp-int.c] + fix div by zero when listing for filename lengths longer than width. + markus@ ok. + - djm@cvs.openbsd.org 2003/08/25 10:33:33 + [sshconnect2.c] + fprintf->logit to silence login banner with "ssh -q"; ok markus@ + - (dtucker) [Makefile.in acconfig.h auth-krb5.c auth-pam.c auth-pam.h + configure.ac defines.h gss-serv-krb5.c session.c ssh-gss.h sshconnect1.c + sshconnect2.c] Add Portable GSSAPI support, patch by Simon Wilkinson. + - (dtucker) [Makefile.in] Remove auth2-krb5. + - (dtucker) [contrib/aix/inventory.sh] Add public domain notice. ok mouring@ + (the original author) + - (dtucker) [auth.c] Do not check for locked accounts when PAM is enabled. + +20030825 + - (djm) Bug #621: Select OpenSC keys by usage attributes. Patch from + larsch@trustcenter.de + - (bal) openbsd-compat/ OpenBSD updates. Mostly licensing, ansifications + and minor fixes. OK djm@ + - (bal) redo how we handle 'mysignal()'. Move it to + openbsd-compat/bsd-misc.c, s/mysignal/signal/ and #define signal to + be our 'mysignal' by default. OK djm@ + - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny + any access to locked accounts. ok djm@ + - (djm) Bug #564: Perform PAM account checks for all authentications when + UsePAM=yes; ok dtucker + - (dtucker) [configure.ac] Bug #533, #551: define BROKEN_GETADDRINFO on + Tru64, solves getnameinfo and "bad addr or host" errors. ok djm@ + - (dtucker) [README buildbff.sh inventory.sh] (all in contrib/aix) + Update package builder: correctly handle config variables, use lsuser + rather than /etc/passwd, fix typos, add Id's. + +20030822 + - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal + -lbroken; ok dtucker + - (dtucker) [contrib/cygwin/ssh-user-config] Put keys in authorized_keys + rather that authorized_keys2. Patch from vinschen@redhat.com. + +20030821 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/14 16:08:58 + [ssh-keygen.c] + exit after primetest, ok djm@ + - (dtucker) [defines.h] Put CMSG_DATA, CMSG_FIRSTHDR with other CMSG* macros, + change CMSG_DATA to use __CMSG_ALIGN (and thus work properly), reformat for + consistency. + - (dtucker) [configure.ac] Move openpty/ctty test outside of case statement + and after normal openpty test. + +20030813 + - (dtucker) [session.c] Remove #ifdef TIOCSBRK kludge. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/13 08:33:02 + [session.c] + use more portable tcsendbreak(3) and ignore break_length; + ok deraadt, millert + - markus@cvs.openbsd.org 2003/08/13 08:46:31 + [auth1.c readconf.c readconf.h servconf.c servconf.h ssh.c ssh_config + ssh_config.5 sshconnect1.c sshd.8 sshd.c sshd_config sshd_config.5] + remove RhostsAuthentication; suggested by djm@ before; ok djm@, deraadt@, + fgsch@, miod@, henning@, jakob@ and others + - markus@cvs.openbsd.org 2003/08/13 09:07:10 + [readconf.c ssh.c] + socks4->socks, since with support both 4 and 5; dtucker@zip.com.au + - (dtucker) [configure.ac openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] + Add a tcsendbreak function for platforms that don't have one, based on the + one from OpenBSD. + +20030811 + - (dtucker) OpenBSD CVS Sync + (thanks to Simon Wilkinson for help with this -dt) + - markus@cvs.openbsd.org 2003/07/16 15:02:06 + [auth-krb5.c] + mcc -> fcc; from Love Hörnquist Åstrand <lha@it.su.se> + otherwise the kerberos credentinal is stored in a memory cache + in the privileged sshd. ok jabob@, hin@ (some time ago) + - (dtucker) [openbsd-compat/xcrypt.c] Remove Cygwin #ifdef block (duplicate + in bsd-cygwin_util.h). + +20030808 + - (dtucker) [openbsd-compat/fake-rfc2553.h] Older Linuxes have AI_PASSIVE and + AI_CANONNAME in netdb.h but not AI_NUMERICHOST, so check each definition + separately before defining them. + - (dtucker) [auth-pam.c] Don't set PAM_TTY if tty is null. ok djm@ + +20030807 + - (dtucker) [session.c] Have session_break_req not attempt to send a break + if TIOCSBRK and TIOCCBRK are not defined (eg Cygwin). + - (dtucker) [canohost.c] Bug #336: Only check ip options if IP_OPTIONS is + defined (fixes compile error on really old Linuxes). + - (dtucker) [defines.h] Bug #336: Add CMSG_DATA and CMSG_FIRSTHDR macros if + not already defined (eg Linux with some versions of libc5), based on those + from OpenBSD. + - (dtucker) [openbsd-compat/bsd-cygwin_util.c openbsd-compat/bsd-cygwin_util.h] + Remove incorrect filenames from comments (file names are in Id tags). + - (dtucker) [session.c openbsd-compat/bsd-cygwin_util.h] Move Cygwin + specific defines and includes to bsd-cygwin_util.h. Fixes build error too. + +20030802 + - (dtucker) [monitor.h monitor_wrap.h] Remove excess ident tags. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/22 13:35:22 + [auth1.c auth.h auth-passwd.c monitor.c monitor.h monitor_wrap.c + monitor_wrap.h readconf.c readconf.h servconf.c servconf.h session.c ssh.1 + ssh.c ssh_config.5 sshconnect1.c sshd.c sshd_config.5 ssh.h] + remove (already disabled) KRB4/AFS support, re-enable -k in ssh(1); + test+ok henning@ + - (dtucker) [Makefile.in acconfig.h configure.ac] Remove KRB4/AFS support. + - (dtucker) [auth-krb4.c radix.c radix.h] Remove KRB4/AFS specific files. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/23 07:42:43 + [sshd_config] + remove AFS; itojun@ + - djm@cvs.openbsd.org 2003/07/28 09:49:56 + [ssh-keygen.1 ssh-keygen.c] + Support for generating Diffie-Hellman groups (/etc/moduli) from ssh-keygen. + Based on code from Phil Karn, William Allen Simpson and Niels Provos. + ok markus@, thanks jmc@ + - markus@cvs.openbsd.org 2003/07/29 18:24:00 + [LICENCE progressmeter.c] + replace 4 clause BSD licensed progressmeter code with a replacement + from Nils Nordman and myself; ok deraadt@ + (copied from OpenBSD an re-applied portable changes) + - markus@cvs.openbsd.org 2003/07/29 18:26:46 + [progressmeter.c] + fix length for "- stalled -" (included with previous import) + - markus@cvs.openbsd.org 2003/07/30 07:44:14 + [progressmeter.c] + use only 4 digits in format_size (included with previous import) + - markus@cvs.openbsd.org 2003/07/30 07:53:27 + [progressmeter.c] + whitespace (included with previous import) + - markus@cvs.openbsd.org 2003/07/31 09:21:02 + [auth2-none.c] + check whether passwd auth is allowd, similar to proto 1; rob@pitman.co.za + ok henning + - avsm@cvs.openbsd.org 2003/07/31 15:50:16 + [atomicio.c] + correct comment: atomicio takes vwrite, not write; deraadt@ ok + - markus@cvs.openbsd.org 2003/07/31 22:34:03 + [progressmeter.c] + print rate similar old version; round instead truncate; + (included in previous progressmeter.c commit) + - (dtucker) [openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] + Add a tcgetpgrp function. + - (dtucker) [Makefile.in moduli.c moduli.h] Add new files and to Makefile. + - (dtucker) [openbsd-compat/bsd-misc.c] Fix cut-and-paste bug in tcgetpgrp. + +20030730 + - (djm) [auth-pam.c] Don't use crappy APIs like sprintf. Thanks bal + +20030726 + - (dtucker) [openbsd-compat/xcrypt.c] Fix typo: DISABLED_SHADOW -> + DISABLE_SHADOW. Fixes HP-UX compile error. + +20030724 + - (bal) [auth-passwd.c openbsd-compat/Makefile.in openbsd-compat/xcrypt.c + openbsd-compat/xcrypt.h] Split off encryption into xcrypt() interface, + and isolate shadow password functions. Tested in Solaris, but should + not break other platforms too badly (except maybe HP =). Also brings + auth-passwd.c into full sync with OpenBSD tree. + +20030723 + - (dtucker) [configure.ac] Back out change for bug #620. + +20030719 + - (dtucker) [configure.ac] Bug #620: Define BROKEN_GETADDRINFO for + Solaris/x86. Patch from jrhett at isite.net. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/14 12:36:37 + [sshd.c] + remove undocumented -V option. would be only useful if openssh is used + as ssh v1 server for ssh.com's ssh v2. + - markus@cvs.openbsd.org 2003/07/16 10:34:53 + [ssh.c sshd.c] + don't exit on multiple -v or -d; ok deraadt@ + - markus@cvs.openbsd.org 2003/07/16 10:36:28 + [sshtty.c] + clear IUCLC in enter_raw_mode; from rob@pitman.co.za; ok deraadt@, fgs@ + - deraadt@cvs.openbsd.org 2003/07/18 01:54:25 + [scp.c] + userid is unsigned, but well, force it anyways; andrushock@korovino.net + - djm@cvs.openbsd.org 2003/07/19 00:45:53 + [sftp-int.c] + fix sftp filename parsing for arguments with escaped quotes. bz #517; + ok markus + - djm@cvs.openbsd.org 2003/07/19 00:46:31 + [regress/sftp-cmds.sh] + regress test for sftp arguments with escaped quotes; ok markus + +20030714 + - (dtucker) [acconfig.h configure.ac port-aix.c] Older AIXes don't declare + loginfailed at all, so assume 3-arg loginfailed if not declared. + - (dtucker) [port-aix.h] Work around name collision on AIX for r_type by + undef'ing it. + - (dtucker) Bug #543: [configure.ac port-aix.c port-aix.h] + Call setauthdb() before loginfailed(), which may load password registry- + specific functions. Based on patch by cawlfiel at us.ibm.com. + - (dtucker) [port-aix.h] Fix prototypes. + - (dtucker) OpenBSD CVS Sync + - avsm@cvs.openbsd.org 2003/07/09 13:58:19 + [key.c] + minor tweak: when generating the hex fingerprint, give strlcat the full + bound to the buffer, and add a comment below explaining why the + zero-termination is one less than the bound. markus@ ok + - markus@cvs.openbsd.org 2003/07/10 14:42:28 + [packet.c] + the 2^(blocksize*2) rekeying limit is too expensive for 3DES, + blowfish, etc, so enforce a 1GB limit for small blocksizes. + - markus@cvs.openbsd.org 2003/07/10 20:05:55 + [sftp.c] + sync usage with manpage, add missing -R + +20030708 + - (dtucker) [acconfig.h auth-passwd.c configure.ac session.c port-aix.[ch]] + Include AIX headers for authentication functions and make calls match + prototypes. Test for and handle 3-arg and 4-arg variants of loginfailed. + - (dtucker) [session.c] Check return value of setpcred(). + - (dtucker) [auth-passwd.c auth.c session.c sshd.c port-aix.c port-aix.h] + Convert aixloginmsg into platform-independant Buffer loginmsg. + +20030707 + - (dtucker) [configure.ac] Bug #600: Check that getrusage is declared before + searching libraries for it. Fixes build errors on NCR MP-RAS. + +20030706 + - (dtucker) [ssh-rand-helper.c loginrec.c] + Apply atomicio typing change to these too. + +20030703 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/06/28 07:48:10 + [sshd.c] + report pidfile creation errors, based on patch from Roumen Petrov; + ok markus@ + - deraadt@cvs.openbsd.org 2003/06/28 16:23:06 + [atomicio.c atomicio.h authfd.c clientloop.c monitor_wrap.c msg.c + progressmeter.c scp.c sftp-client.c ssh-keyscan.c ssh.h sshconnect.c + sshd.c] + deal with typing of write vs read in atomicio + - markus@cvs.openbsd.org 2003/06/29 12:44:38 + [sshconnect.c] + memset 0, not \0; andrushock@korovino.net + - markus@cvs.openbsd.org 2003/07/02 12:56:34 + [channels.c] + deny dynamic forwarding with -R for v1, too; ok djm@ + - markus@cvs.openbsd.org 2003/07/02 14:51:16 + [channels.c ssh.1 ssh_config.5] + (re)add socks5 suppport to -D; ok djm@ + now ssh(1) can act both as a socks 4 and socks 5 server and + dynamically forward ports. + - markus@cvs.openbsd.org 2003/07/02 20:37:48 + [ssh.c] + convert hostkeyalias to lowercase, otherwise uppercase aliases will + not match at all; ok henning@ + - markus@cvs.openbsd.org 2003/07/03 08:21:46 + [regress/dynamic-forward.sh] + add socks5; speedup; reformat; based on patch from dtucker@zip.com.au + - markus@cvs.openbsd.org 2003/07/03 08:24:13 + [regress/Makefile] + enable tests for dynamic fwd via socks (-D), uses nc(1) + - djm@cvs.openbsd.org 2003/07/03 08:09:06 + [readconf.c readconf.h ssh-keysign.c ssh.c] + fix AddressFamily option in config file, from brent@graveland.net; + ok markus@ + +20030630 + - (djm) Search for support functions necessary to build our + getrrsetbyname() replacement. Patch from Roumen Petrov + +20030629 + - (dtucker) [includes.h] Bug #602: move #include of netdb.h to after in.h + (fixes compiler warnings on Solaris 2.5.1). + - (dtucker) [configure.ac] Add sanity test after system-dependant compiler + flag modifications. + +20030628 + - (djm) Bug #591: use PKCS#15 private key label as a comment in case + of OpenSC. Report and patch from larsch@trustcenter.de + - (djm) Bug #593: Sanity check OpenSC card reader number; patch from + aj@dungeon.inka.de + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/23 09:02:44 + [ssh_config.5] + document EnableSSHKeysign; bugzilla #599; ok deraadt@, jmc@ + - markus@cvs.openbsd.org 2003/06/24 08:23:46 + [auth2-hostbased.c auth2-pubkey.c auth2.c channels.c key.c key.h + monitor.c packet.c packet.h serverloop.c sshconnect2.c sshd.c] + int -> u_int; ok djm@, deraadt@, mouring@ + - miod@cvs.openbsd.org 2003/06/25 22:39:36 + [sftp-server.c] + Typo police: attribute is better written with an 'r'. + - markus@cvs.openbsd.org 2003/06/26 20:08:33 + [readconf.c] + do not dump core for 'ssh -o proxycommand host'; ok deraadt@ + - (dtucker) [regress/dynamic-forward.sh] Import new regression test. + - (dtucker) [configure.ac] Bug #570: Have ./configure --enable-FEATURE + actually enable the feature, for those normally disabled. Patch by + openssh (at) roumenpetrov.info. + +20030624 + - (dtucker) Have configure refer the user to config.log and + contrib/findssl.sh for OpenSSL header/library mismatches. + +20030622 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/21 09:14:05 + [regress/reconfigure.sh] + missing $SUDO; from dtucker@zip.com.au + - markus@cvs.openbsd.org 2003/06/18 11:28:11 + [ssh-rsa.c] + backout last change, since it violates pkcs#1 + switch to share/misc/license.template + - djm@cvs.openbsd.org 2003/06/20 05:47:58 + [sshd_config.5] + sync description of protocol 2 cipher proposal; ok markus + - djm@cvs.openbsd.org 2003/06/20 05:48:21 + [sshd_config] + sync some implemented options; ok markus@ + - (dtucker) [regress/authorized_keys_root] Remove temp data file from CVS. + - (dtucker) [openbsd-compat/setproctitle.c] Ensure SPT_TYPE is defined before + testing its value. + +20030618 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/12 07:57:38 + [monitor.c sshlogin.c sshpty.c] + typos; dtucker at zip.com.au + - djm@cvs.openbsd.org 2003/06/12 12:22:47 + [LICENCE] + mention more copyright holders; ok markus@ + - nino@cvs.openbsd.org 2003/06/12 15:34:09 + [scp.c] + Typo. Ok markus@. + - markus@cvs.openbsd.org 2003/06/12 19:12:03 + [scard.c scard.h ssh-agent.c ssh.c] + add sc_get_key_label; larsch at trustcenter.de; bugzilla#591 + - markus@cvs.openbsd.org 2003/06/16 08:22:35 + [ssh-rsa.c] + make sure the signature has at least the expected length (don't + insist on len == hlen + oidlen, since this breaks some smartcards) + bugzilla #592; ok djm@ + - markus@cvs.openbsd.org 2003/06/16 10:22:45 + [ssh-add.c] + print out key comment on each prompt; make ssh-askpass more useable; ok djm@ + - markus@cvs.openbsd.org 2003/06/17 18:14:23 + [cipher-ctr.c] + use license from /usr/share/misc/license.template for new code + - (dtucker) [reconfigure.sh rekey.sh sftp-badcmds.sh] + Import new regression tests from OpenBSD + - (dtucker) [regress/copy.1 regress/copy.2] Remove temp data files from CVS. + - (dtucker) OpenBSD CVS Sync (regress/) + - markus@cvs.openbsd.org 2003/04/02 12:21:13 + [Makefile] + enable rekey test + - djm@cvs.openbsd.org 2003/04/04 09:34:22 + [Makefile sftp-cmds.sh] + More regression tests, including recent directory rename bug; ok markus@ + - markus@cvs.openbsd.org 2003/05/14 22:08:27 + [ssh-com-client.sh ssh-com-keygen.sh ssh-com-sftp.sh ssh-com.sh] + test against some new commerical versions + - mouring@cvs.openbsd.org 2003/05/15 04:07:12 + [sftp-cmds.sh] + Advanced put/get testing for sftp. OK @djm + - markus@cvs.openbsd.org 2003/06/12 15:40:01 + [try-ciphers.sh] + add ctr + - markus@cvs.openbsd.org 2003/06/12 15:43:32 + [Makefile] + test -HUP; dtucker at zip.com.au + +20030614 + - (djm) Update license on fake-rfc2553.[ch]; ok itojun@ + +20030611 + - (djm) Mention portable copyright holders in LICENSE + - (djm) Put licenses on substantial header files + - (djm) Sync LICENSE against OpenBSD + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/06/10 09:12:11 + [scp.1 sftp-server.8 ssh.1 ssh-add.1 ssh-agent.1 ssh_config.5] + [sshd.8 sshd_config.5 ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8] + - section reorder + - COMPATIBILITY merge + - macro cleanup + - kill whitespace at EOL + - new sentence, new line + ssh pages ok markus@ + - deraadt@cvs.openbsd.org 2003/06/10 22:20:52 + [packet.c progressmeter.c] + mostly ansi cleanup; pval ok + - jakob@cvs.openbsd.org 2003/06/11 10:16:16 + [sshconnect.c] + clean up check_host_key() and improve SSHFP feedback. ok markus@ + - jakob@cvs.openbsd.org 2003/06/11 10:18:47 + [dns.c] + sync with check_host_key() change + - djm@cvs.openbsd.org 2003/06/11 11:18:38 + [authfd.c authfd.h ssh-add.c ssh-agent.c] + make agent constraints (lifetime, confirm) work with smartcard keys; + ok markus@ + + +20030609 + - (djm) Sync README.smartcard with OpenBSD -current + - (djm) Re-merge OpenSC info into README.smartcard + +20030606 + - (dtucker) [uidswap.c] Fix setreuid and add missing args to fatal(). ok djm@ + +20030605 + - (djm) Support AI_NUMERICHOST in fake-getaddrinfo.c. Needed for recent + canohost.c changes. + - (djm) Implement paranoid priv dropping checks, based on: + "SetUID demystified" - Hao Chen, David Wagner and Drew Dean + Proceedings of USENIX Security Symposium 2002 + - (djm) Don't use xmalloc() or pull in toplevel headers in fake-* code + - (djm) Merge all the openbsd/fake-* into fake-rfc2553.[ch] + - (djm) Bug #588 - Add scard-opensc.o back to Makefile.in + Patch from larsch@trustcenter.de + - (djm) Bug #589 - scard-opensc: load only keys with a private keys + Patch from larsch@trustcenter.de + - (dtucker) Add includes.h to fake-rfc2553.c so it will build. + - (dtucker) Define EAI_NONAME in fake-rfc2553.h (used by fake-rfc2553.c). + +20030604 + - (djm) Bug #573 - Remove unneeded Krb headers and compat goop. Patch from + simon@sxw.org.uk (Also matches a change in OpenBSD a while ago) + - (djm) Bug #577 - wrong flag in scard-opensc.c sc_private_decrypt. + Patch from larsch@trustcenter.de; ok markus@ + - (djm) Bug #584: scard-opensc.c doesn't work without PIN. Patch from + larsch@trustcenter.de; ok markus@ + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/06/04 08:25:18 + [sshconnect.c] + disable challenge/response and keyboard-interactive auth methods + upon hostkey mismatch. based on patch from fcusack AT fcusack.com. + bz #580; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 10:23:48 + [sshd.c] + remove duplicated group-dropping code; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:03:59 + [serverloop.c] + remove bitrotten commet; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:18:49 + [scp.c] + ansify; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:40:39 + [scp.c] + kill ssh process upon receipt of signal, bz #241. + based on patch from esb AT hawaii.edu; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:41:22 + [sftp.c] + kill ssh process on receipt of signal; ok markus@ + - (djm) Update to fix of bug #584: lock card before return. + From larsch@trustcenter.de + - (djm) Always use mysignal() for SIGALRM + +20030603 + - (djm) Replace setproctitle replacement with code derived from + UCB sendmail + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/02 09:17:34 + [auth2-hostbased.c auth.c auth-options.c auth-rhosts.c auth-rh-rsa.c] + [canohost.c monitor.c servconf.c servconf.h session.c sshd_config] + [sshd_config.5] + deprecate VerifyReverseMapping since it's dangerous if combined + with IP based access control as noted by Mike Harding; replace with + a UseDNS option, UseDNS is on by default and includes the + VerifyReverseMapping check; with itojun@, provos@, jakob@ and deraadt@ + ok deraadt@, djm@ + - millert@cvs.openbsd.org 2003/06/03 02:56:16 + [scp.c] + Remove the advertising clause in the UCB license which Berkeley + rescinded 22 July 1999. Proofed by myself and Theo. + - (djm) Fix portable-specific uses of verify_reverse_mapping too + - (djm) Sync openbsd-compat with OpenBSD CVS. + - No more 4-term BSD licenses in linked code + - (dtucker) [port-aix.c bsd-cray.c] Fix uses of verify_reverse_mapping. + +20030602 + - (djm) Fix segv from bad reordering in auth-pam.c + - (djm) Always use saved_argv in sshd.c as compat_init_setproctitle may + clobber + - (tim) openbsd-compat/xmmap.[ch] License clarifications. Add missing + CVS ID. + - (djm) Remove "noip6" option from RedHat spec file. This may now be + set at runtime using AddressFamily option. + - (djm) Fix use of macro before #define in cipher-aes.c + - (djm) Sync license on openbsd-compat/bindresvport.c with OpenBSD CVS + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/26 12:54:40 + [sshconnect.c] + fix format strings; ok markus@ + - deraadt@cvs.openbsd.org 2003/05/29 16:58:45 + [sshd.c uidswap.c] + seteuid and setegid; markus ok + - jakob@cvs.openbsd.org 2003/06/02 08:31:10 + [ssh_config.5] + VerifyHostKeyDNS is v2 only. ok markus@ + +20030530 + - (dtucker) Add missing semicolon in md5crypt.c, patch from openssh at + roumenpetrov.info + - (dtucker) Define SSHD_ACQUIRES_CTTY for NCR MP-RAS and Reliant Unix. + +20030526 + - (djm) Avoid auth2-chall.c warning when compiling without + PAM, BSD_AUTH and SKEY + +20030525 +- (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/24 09:02:22 + [log.c] + pass logged data through strnvis; ok markus + - djm@cvs.openbsd.org 2003/05/24 09:30:40 + [authfile.c monitor.c sftp-common.c sshpty.c] + cast some types for printing; ok markus@ + +20030524 + - (dtucker) Correct --osfsia in INSTALL. Patch by skeleten at shillest.net + +20030523 + - (djm) Use VIS_SAFE on logged strings rather than default strnvis + encoding (which encodes many more characters) + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/05/20 12:03:35 + [sftp.1] + - new sentence, new line + - added .Xr's + - typos + ok djm@ + - jmc@cvs.openbsd.org 2003/05/20 12:09:31 + [ssh.1 ssh_config.5 sshd.8 sshd_config.5 ssh-keygen.1] + new sentence, new line + - djm@cvs.openbsd.org 2003/05/23 08:29:30 + [sshconnect.c] + fix leak; ok markus@ + +20030520 + - (djm) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2003/05/18 23:22:01 + [log.c] + use syslog_r() in a signal handler called place; markus ok + - (djm) Configure logic to detect syslog_r and friends + +20030519 + - (djm) Sync auth-pam.h with what we actually implement + +20030518 + - (djm) Return of the dreaded PAM_TTY_KLUDGE, which went missing in + recent merge + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/16 03:27:12 + [readconf.c ssh_config ssh_config.5 ssh-keysign.c] + add AddressFamily option to ssh_config (like -4, -6 on commandline). + Portable bug #534; ok markus@ + - itojun@cvs.openbsd.org 2003/05/17 03:25:58 + [auth-rhosts.c] + just in case, put numbers to sscanf %s arg. + - markus@cvs.openbsd.org 2003/05/17 04:27:52 + [cipher.c cipher-ctr.c myproposal.h] + experimental support for aes-ctr modes from + http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-00.txt + ok djm@ + - (djm) Remove IPv4 by default hack now that we can specify AF in config + - (djm) Tidy and trim TODO + - (djm) Sync openbsd-compat/ with OpenBSD CVS head + - (djm) Big KNF on openbsd-compat/ + - (djm) KNF on md5crypt.[ch] + - (djm) KNF on auth-sia.[ch] + +20030517 + - (bal) strcat -> strlcat on openbsd-compat/realpath.c (rev 1.8 OpenBSD) + +20030516 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/15 13:52:10 + [ssh.c] + Make "ssh -V" print the OpenSSL version in a human readable form. Patch + from Craig Leres (mindrot at ee.lbl.gov); ok markus@ + - jakob@cvs.openbsd.org 2003/05/15 14:02:47 + [readconf.c servconf.c] + warn for unsupported config option. ok markus@ + - markus@cvs.openbsd.org 2003/05/15 14:09:21 + [auth2-krb5.c] + fix 64bit issue; report itojun@ + - djm@cvs.openbsd.org 2003/05/15 14:55:25 + [readconf.c readconf.h ssh_config ssh_config.5 sshconnect.c] + add a ConnectTimeout option to ssh, based on patch from + Jean-Charles Longuet (jclonguet at free.fr); portable #207 ok markus@ + - (djm) Add warning for UsePAM when built without PAM support + - (djm) A few type mismatch fixes from Bug #565 + - (djm) Guard free_pam_environment against NULL argument. Works around + HP/UX PAM problems debugged by dtucker + +20030515 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/05/14 13:11:56 + [ssh-agent.1] + setup -> set up; + from wiz@netbsd + - jakob@cvs.openbsd.org 2003/05/14 18:16:20 + [key.c key.h readconf.c readconf.h ssh_config.5 sshconnect.c] + [dns.c dns.h README.dns ssh-keygen.1 ssh-keygen.c] + add experimental support for verifying hos keys using DNS as described + in draft-ietf-secsh-dns-xx.txt. more information in README.dns. + ok markus@ and henning@ + - markus@cvs.openbsd.org 2003/05/14 22:24:42 + [clientloop.c session.c ssh.1] + allow to send a BREAK to the remote system; ok various + - markus@cvs.openbsd.org 2003/05/15 00:28:28 + [sshconnect2.c] + cleanup unregister of per-method packet handlers; ok djm@ + - jakob@cvs.openbsd.org 2003/05/15 01:48:10 + [readconf.c readconf.h servconf.c servconf.h] + always parse kerberos options. ok djm@ markus@ + - jakob@cvs.openbsd.org 2003/05/15 02:27:15 + [dns.c] + add missing freerrset + - markus@cvs.openbsd.org 2003/05/15 03:08:29 + [cipher.c cipher-bf1.c cipher-aes.c cipher-3des1.c] + split out custom EVP ciphers + - djm@cvs.openbsd.org 2003/05/15 03:10:52 + [ssh-keygen.c] + avoid warning; ok jakob@ + - mouring@cvs.openbsd.org 2003/05/15 03:39:07 + [sftp-int.c] + Make put/get (globed and nonglobed) code more consistant. OK djm@ + - mouring@cvs.openbsd.org 2003/05/15 03:43:59 + [sftp-int.c sftp.c] + Teach ls how to display multiple column display and allow users + to return to single column format via 'ls -1'. OK @djm + - jakob@cvs.openbsd.org 2003/05/15 04:08:44 + [readconf.c servconf.c] + disable kerberos when not supported. ok markus@ + - markus@cvs.openbsd.org 2003/05/15 04:08:41 + [ssh.1] + ~B is ssh2 only + - (djm) Always parse UsePAM + - (djm) Configure glue for DNS support (code doesn't work in portable yet) + - (djm) Import getrrsetbyname() function from OpenBSD libc (for DNS support) + - (djm) Tidy Makefile clean targets + - (djm) Adapt README.dns for portable + - (djm) Avoid uuencode.c warnings + - (djm) Enable UsePAM when built --with-pam + - (djm) Only build getrrsetbyname replacement when using --with-dns + - (djm) Bug #529: sshd doesn't work correctly after SIGHUP (copy argv + correctly) + - (djm) Bug #444: Wrong paths after reconfigure + - (dtucker) HP-UX needs to include <sys/strtio.h> for TIOCSBRK + +20030514 + - (djm) Bug #117: Don't lie to PAM about username + - (djm) RCSID sync w/ OpenBSD + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/04/09 12:00:37 + [readconf.c] + strip trailing whitespace from config lines before parsing. + Fixes bz 528; ok markus@ + - markus@cvs.openbsd.org 2003/04/12 10:13:57 + [cipher.c] + hide cipher details; ok djm@ + - markus@cvs.openbsd.org 2003/04/12 10:15:36 + [misc.c] + debug->debug2 + - naddy@cvs.openbsd.org 2003/04/12 11:40:15 + [ssh.1] + document -V switch, fix wording; ok markus@ + - markus@cvs.openbsd.org 2003/04/14 14:17:50 + [channels.c sshconnect.c sshd.c ssh-keyscan.c] + avoid hardcoded SOCK_xx; with itojun@; should allow ssh over SCTP + - mouring@cvs.openbsd.org 2003/04/14 21:31:27 + [sftp-int.c] + Missing globfree(&g) in process_put() spotted by Vince Brimhall + <VBrimhall@novell.com>. ok@ Theo + - markus@cvs.openbsd.org 2003/04/16 14:35:27 + [auth.h] + document struct Authctxt; with solar + - deraadt@cvs.openbsd.org 2003/04/26 04:29:49 + [ssh-keyscan.c] + -t in usage(); rogier@quaak.org + - mouring@cvs.openbsd.org 2003/04/30 01:16:20 + [sshd.8 sshd_config.5] + Escape ?, * and ! in .Ql for nroff compatibility. OpenSSH Portable + Bug #550 and * escaping suggested by jmc@. + - david@cvs.openbsd.org 2003/04/30 20:41:07 + [sshd.8] + fix invalid .Pf macro usage introduced in previous commit + ok jmc@ mouring@ + - markus@cvs.openbsd.org 2003/05/11 16:56:48 + [authfile.c ssh-keygen.c] + change key_load_public to try to read a public from: + rsa1 private or rsa1 public and ssh2 keys. + this makes ssh-keygen -e fail for ssh1 keys more gracefully + for example; report from itojun (netbsd pr 20550). + - markus@cvs.openbsd.org 2003/05/11 20:30:25 + [channels.c clientloop.c serverloop.c session.c ssh.c] + make channel_new() strdup the 'remote_name' (not the caller); ok theo + - markus@cvs.openbsd.org 2003/05/12 16:55:37 + [sshconnect2.c] + for pubkey authentication try the user keys in the following order: + 1. agent keys that are found in the config file + 2. other agent keys + 3. keys that are only listed in the config file + this helps when an agent has many keys, where the server might + close the connection before the correct key is used. report & ok pb@ + - markus@cvs.openbsd.org 2003/05/12 18:35:18 + [ssh-keyscan.1] + typo: DSA keys are of type ssh-dss; Brian Poole + - markus@cvs.openbsd.org 2003/05/14 00:52:59 + [ssh2.h] + ranges for per auth method messages + - djm@cvs.openbsd.org 2003/05/14 01:00:44 + [sftp.1] + emphasise the batchmode functionality and make reference to pubkey auth, + both of which are FAQs; ok markus@ + - markus@cvs.openbsd.org 2003/05/14 02:15:47 + [auth2.c monitor.c sshconnect2.c auth2-krb5.c] + implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ + server interops with commercial client; ok jakob@ djm@ + - jmc@cvs.openbsd.org 2003/05/14 08:25:39 + [sftp.1] + - better formatting in SYNOPSIS + - whitespace at EOL + ok djm@ + - markus@cvs.openbsd.org 2003/05/14 08:57:49 + [monitor.c] + http://bugzilla.mindrot.org/show_bug.cgi?id=560 + Privsep child continues to run after monitor killed. + Pass monitor signals through to child; Darren Tucker + - (djm) Make portable build with MIT krb5 (some issues remain) + - (djm) Add new UsePAM configuration directive to allow runtime control + over usage of PAM. This allows non-root use of sshd when built with + --with-pam + - (djm) Die screaming if start_pam() is called when UsePAM=no + - (djm) Avoid KrbV leak for MIT Kerberos + - (dtucker) Set ai_socktype and ai_protocol in fake-getaddrinfo.c. ok djm@ + - (djm) Bug #258: sscanf("[0-9]") -> sscanf("[0123456789]") for portability + +20030512 + - (djm) Redhat spec: Don't install profile.d scripts when not + building with GNOME/GTK askpass (patch from bet@rahul.net) + +20030510 + - (dtucker) Bug #318: Create ssh_prng_cmds.out during "make" rather than + "make install". Patch by roth@feep.net. + - (dtucker) Bug #536: Test for and work around openpty/controlling tty + problem on Linux (fixes "could not set controlling tty" errors). + - (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with + proper challenge-response module + - (djm) 2-clause license on loginrec.c, with permission from + andre@ae-35.com + +20030504 + - (dtucker) Bug #497: Move #include of bsd-cygwin_util.h to openbsd-compat.h. + Patch from vinschen@redhat.com. + +20030503 + - (dtucker) Add missing "void" to record_failed_login in bsd-cray.c. Noted + by wendyp@cray.com. + +20030502 + - (dtucker) Bug #544: ignore invalid cmsg_type on Linux 2.0 kernels, + privsep should now work. + - (dtucker) Move handling of bad password authentications into a platform + specific record_failed_login() function (affects AIX & Unicos). ok mouring@ + +20030429 + - (djm) Add back radix.o (used by AFS support), after it went missing from + Makefile many moons ago + - (djm) Apply "owl-always-auth" patch from Openwall/Solar Designer + - (djm) Fix blibpath specification for AIX/gcc + - (djm) Some systems have basename in -lgen. Fix from ayamura@ayamura.org + +20030428 + - (bal) [defines.h progressmeter.c scp.c] Some more culling of non 64bit + hacked code. + +20030427 + - (bal) Bug #541: return; was dropped by mistake. Reported by + furrier@iglou.com + - (bal) Since we don't support platforms lacking u_int_64. We may + as well clean out some of those evil #ifdefs + - (bal) auth1.c minor resync while looking at the code. + - (bal) auth2.c same changed as above. + +20030409 + - (djm) Bug #539: Specify creation mode with O_CREAT for lastlog. Report + from matth@eecs.berkeley.edu + - (djm) Make the spec work with Redhat 9.0 (which renames sharutils) + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/04/02 09:48:07 + [clientloop.c monitor.c monitor_wrap.c packet.c packet.h readconf.c] + [readconf.h serverloop.c sshconnect2.c] + reapply rekeying chage, tested by henning@, ok djm@ + - markus@cvs.openbsd.org 2003/04/02 14:36:26 + [ssh-keysign.c] + potential segfault if KEY_UNSPEC; cjwatson@debian.org; bug #526 + - itojun@cvs.openbsd.org 2003/04/03 07:25:27 + [progressmeter.c] + $OpenBSD$ + - itojun@cvs.openbsd.org 2003/04/03 10:17:35 + [progressmeter.c] + remove $OpenBSD$, as other *.c does not have it. + - markus@cvs.openbsd.org 2003/04/07 08:29:57 + [monitor_wrap.c] + typo: get correct counters; introduced during rekeying change. + - millert@cvs.openbsd.org 2003/04/07 21:58:05 + [progressmeter.c] + The UCB copyright here is incorrect. This code did not originate + at UCB, it was written by Luke Mewburn. Updated the copyright at + the author's request. markus@ OK + - itojun@cvs.openbsd.org 2003/04/08 20:21:29 + [*.c *.h] + rename log() into logit() to avoid name conflict. markus ok, from + netbsd + - (djm) XXX - Performed locally using: + "perl -p -i -e 's/(\s|^)log\(/$1logit\(/g' *.c *.h" + - hin@cvs.openbsd.org 2003/04/09 08:23:52 + [servconf.c] + Don't include <krb.h> when compiling with Kerberos 5 support + - (djm) Fix up missing include for packet.c + - (djm) Fix missed log => logit occurance (reference by function pointer) + +20030402 + - (bal) if IP_TOS is not found or broken don't try to compile in + packet_set_tos() function call. bug #527 + 20030401 - (djm) OpenBSD CVS Sync - jmc@cvs.openbsd.org 2003/03/28 10:11:43 @@ -54,1245 +1188,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -20030320 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2003/03/17 10:38:38 - [progressmeter.c] - don't print \n if backgrounded; from ho@ - - markus@cvs.openbsd.org 2003/03/17 11:43:47 - [version.h] - enter 3.6 - - (bal) The days of lack of int64_t support are over. Sorry kids. - - (bal) scp.c 'limit' conflicts with Cray. Rename to 'limitbw' - - (bal) Collection of Cray patches (bsd-cray.h fix for CRAYT3E and improved - guessing rules) - - (bal) Disable Privsep for Tru64 after pre-authentication due to issues - with SIA. Also, clean up of tru64 support patch by Chris Adams - <cmadams@hiwaay.net> - - (tim) [contrib/caldera/openssh.spec] workaround RPM quirk. Fix %files - -20030318 - - (tim) [configure.ac openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] - add nanosleep(). testing/corrections by Darren Tucker <dtucker@zip.com.au> - -20030317 - - (djm) Fix return value checks for RAND_bytes. Report from - Steve G <linux_4ever@yahoo.com> - -20030315 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2003/03/13 11:42:19 - [authfile.c ssh-keysign.c] - move RSA_blinding_on to generic key load method - - markus@cvs.openbsd.org 2003/03/13 11:44:50 - [ssh-agent.c] - ssh-agent is similar to ssh-keysign (allows other processes to use - private rsa keys). however, it gets key over socket and not from - a file, so we have to do blinding here as well. - -20030310 -- (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2003/03/05 22:33:43 - [channels.c monitor.c scp.c session.c sftp-client.c sftp-int.c] - [sftp-server.c ssh-add.c sshconnect2.c] - fix memory leaks; from dlheine@suif.Stanford.EDU/CLOUSEAU; ok djm@ - - (djm) One more portable-specific one from dlheine@suif.Stanford.EDU/ - CLOUSEAU - - (djm) Bug #245: TTY problems on Solaris. Fix by stevesk@ and - dtucker@zip.com.au - - (djm) AIX package builder update from dtucker@zip.com.au - -20030225 - - (djm) Fix some compile errors spotted by dtucker and his fabulous - tinderbox - -20030224 - - (djm) Tweak gnome-ssh-askpass2: - - Retry kb and mouse grab a couple of times, so passphrase dialog doesn't - immediately fail if you are doing something else when it appears (e.g. - dragging a window) - - Perform server grab after we have the keyboard and/or pointer to avoid - races. - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2003/01/27 17:06:31 - [sshd.c] - more specific error message when /var/empty has wrong permissions; - bug #46, map@appgate.com; ok henning@, provos@, stevesk@ - - markus@cvs.openbsd.org 2003/01/28 16:11:52 - [scp.1] - document -l; pekkas@netcore.fi - - stevesk@cvs.openbsd.org 2003/01/28 17:24:51 - [scp.1] - remove example not pertinent with -1 addition; ok markus@ - - jmc@cvs.openbsd.org 2003/01/31 21:54:40 - [sshd.8] - typos; sshd(8): help and ok markus@ - help and ok millert@ - - markus@cvs.openbsd.org 2003/02/02 10:51:13 - [scp.c] - call okname() only when using system(3) for remote-remote copy; - fixes bugs #483, #472; ok deraadt@, mouring@ - - markus@cvs.openbsd.org 2003/02/02 10:56:08 - [kex.c] - add support for key exchange guesses; based on work by - avraham.fraenkel@commatch.com; fixes bug #148; ok deraadt@ - - markus@cvs.openbsd.org 2003/02/03 08:56:16 - [sshpty.c] - don't call error() for readonly /dev; from soekris list; ok mcbride, - henning, deraadt. - - markus@cvs.openbsd.org 2003/02/04 09:32:08 - [key.c] - better debug3 message - - markus@cvs.openbsd.org 2003/02/04 09:33:22 - [monitor.c monitor_wrap.c] - skey/bsdauth: use 0 to indicate failure instead of -1, because - the buffer API only supports unsigned ints. - - markus@cvs.openbsd.org 2003/02/05 09:02:28 - [readconf.c] - simplify ProxyCommand parsing, remove strcat/xrealloc; ok henning@, djm@ - - markus@cvs.openbsd.org 2003/02/06 09:26:23 - [session.c] - missing call to setproctitle() after authentication; ok provos@ - - markus@cvs.openbsd.org 2003/02/06 09:27:29 - [ssh.c ssh_config.5] - support 'ProxyCommand none'; bugzilla #433; binder@arago.de; ok djm@ - - markus@cvs.openbsd.org 2003/02/06 09:29:18 - [sftp-server.c] - fix races in rename/symlink; from Tony Finch; ok djm@ - - markus@cvs.openbsd.org 2003/02/06 21:22:43 - [auth1.c auth2.c] - undo broken fix for #387, fixes #486 - - markus@cvs.openbsd.org 2003/02/10 11:51:47 - [ssh-add.1] - xref sshd_config.5 (not sshd.8); mark@summersault.com; bug #490 - - markus@cvs.openbsd.org 2003/02/12 09:33:04 - [key.c key.h ssh-dss.c ssh-rsa.c] - merge ssh-dss.h ssh-rsa.h into key.h; ok deraadt@ - - markus@cvs.openbsd.org 2003/02/12 21:39:50 - [crc32.c crc32.h] - replace crc32.c with a BSD licensed version; noted by David Turner - - markus@cvs.openbsd.org 2003/02/16 17:09:57 - [kex.c kexdh.c kexgex.c kex.h sshconnect2.c sshd.c ssh-keyscan.c] - split kex into client and server code, no need to link - server code into the client; ok provos@ - - markus@cvs.openbsd.org 2003/02/16 17:30:33 - [monitor.c monitor_wrap.c] - fix permitrootlogin forced-commands-only for privsep; bux #387; - ok provos@ - - markus@cvs.openbsd.org 2003/02/21 09:05:53 - [servconf.c] - print sshd_config filename in debug2 mode. - - mpech@cvs.openbsd.org 2003/02/21 10:34:48 - [auth-krb4.c] - ...sizeof(&adat.session) is not good here. - henning@, deraadt@, millert@ - - (djm) Add new object files to Makefile and reorder - - (djm) Bug #501: gai_strerror should return char*; - fix from dtucker@zip.com.au - - (djm) Most of Bug #499: Cygwin compile fixes for new progressmeter; - From vinschen@redhat.com - - (djm) Rest of Bug #499: Import a basename() function from OpenBSD libc - - (djm) Bug #494: Allow multiple accounts on Windows 9x/Me; - From vinschen@redhat.com - - (djm) Bug #456: Support for NEC SX6 with Unicos; from wendyp@cray.com - -20030211 - - (djm) Cygwin needs libcrypt too. Patch from vinschen@redhat.com - -20030206 - - (djm) Teach fake-getaddrinfo to use getservbyname() when provided a - string service name. Suggested by markus@, review by itojun@ - -20030131 - - (bal) AIX 4.2.1 lacks nanosleep(). Patch to use nsleep() provided by - dtucker@zip.com.au - -20030130 - - (djm) Unbreak root password auth. Spotted by dtucker@zip.com.au - -200301028 - - (djm) Search libposix4 and librt for nanosleep. From dtucker@zip.com.au - and openssh-unix-dev@thewrittenword.com - -200301027 - - (bal) Bugzilla 477 patch by wendyp@cray.com. Define TIOCGPGRP for - cray. Also removed test for tcgetpgrp in configure.ac since it - is no longer used. - -20030124 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2003/01/23 08:58:47 - [sshd_config.5] - typos; ok millert@ - - markus@cvs.openbsd.org 2003/01/23 13:50:27 - [authfd.c authfd.h readpass.c ssh-add.1 ssh-add.c ssh-agent.c] - ssh-add -c, prompt user for confirmation (using ssh-askpass) when - private agent key is used; with djm@; test by dugsong@, djm@; - ok deraadt@ - - markus@cvs.openbsd.org 2003/01/23 14:01:53 - [scp.c] - bandwidth limitation patch (scp -l) from niels@; ok todd@, deraadt@ - - markus@cvs.openbsd.org 2003/01/23 14:06:15 - [scp.1 scp.c] - scp -12; Sam Smith and others; ok provos@, deraadt@ - - (djm) Add TIMEVAL_TO_TIMESPEC macros - -20030123 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2003/01/23 00:03:00 - [auth1.c] - Don't log TIS auth response; "get rid of it" - markus@ - -20030122 - - (djm) OpenBSD CVS Sync - - marc@cvs.openbsd.org 2003/01/21 18:14:36 - [ssh-agent.1 ssh-agent.c] - Add a -t life option to ssh-agent that set the default lifetime. - The default can still be overriden by using -t in ssh-add. - OK markus@ - - (djm) Reorganise PAM & SIA password handling to eliminate some common code - - (djm) Sync regress with OpenBSD -current - -20030120 - - (djm) Fix compilation for NetBSD from dtucker@zip.com.au - - (tim) [progressmeter.c] make compilers without long long happy. - - (tim) [configure.ac] Add -belf to build ELF binaries on OpenServer 5 when - using cc. (gcc already did) - -20030118 - - (djm) Revert fix for Bug #442 for now. - -20030117 - - (djm) Bug #470: Detect strnvis, not strvis in configure. - From d_wllms@lanl.gov - -20030116 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2003/01/16 03:41:55 - [sftp-int.c] - explicitly use first glob result - -20030114 - - (djm) OpenBSD CVS Sync - - fgsch@cvs.openbsd.org 2003/01/10 23:23:24 - [sftp-int.c] - typo; from Nils Nordman <nino at nforced dot com>. - - markus@cvs.openbsd.org 2003/01/11 18:29:43 - [log.c] - set fatal_cleanups to NULL in fatal_remove_all_cleanups(); - dtucker@zip.com.au - - markus@cvs.openbsd.org 2003/01/12 16:57:02 - [progressmeter.c] - allow WARNINGS=yes; ok djm@ - - djm@cvs.openbsd.org 2003/01/13 11:04:04 - [sftp-int.c] - make cmds[] array static to avoid conflict with BSDI libc. - mindrot bug #466. Fix from mdev@idg.nl; ok markus@ - - djm@cvs.openbsd.org 2003/01/14 10:58:00 - [sftp-client.c sftp-int.c] - Don't try to upload or download non-regular files. Report from - apoloval@pantuflo.escet.urjc.es; ok markus@ - -20030113 - - (djm) Rework openbsd-compat/setproctitle.c a bit: move emulation type - detection to configure.ac. Prompted by stevesk@ - - (djm) Bug #467: Add a --disable-strip option to turn off stripping of - installed binaries. From mdev@idg.nl - -20030110 - - (djm) Enable new setproctitle emulation for Linux, AIX and HP/UX. More - systems may be added later. - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2003/01/08 23:53:26 - [sftp.1 sftp.c sftp-int.c sftp-int.h] - Cleanup error handling for batchmode - Allow blank lines and comments in input - Ability to suppress abort on error in batchmode ("-put blah") - Fixes mindrot bug #452; markus@ ok - - fgsch@cvs.openbsd.org 2003/01/10 08:19:07 - [scp.c sftp.1 sftp.c sftp-client.c sftp-int.c progressmeter.c] - [progressmeter.h] - sftp progress meter support. - original diffs by Nils Nordman <nino at nforced dot com> via - markus@, merged to -current by me, djm@ ok. - - djm@cvs.openbsd.org 2003/01/10 08:48:15 - [sftp-client.c] - Simplify and avoid redundancy in packet send and receive - functions; ok fgs@ - - djm@cvs.openbsd.org 2003/01/10 10:29:35 - [scp.c] - Don't ftruncate after write error, creating sparse files of - incorrect length - mindrot bug #403, reported by rusr@cup.hp.com; ok markus@ - - djm@cvs.openbsd.org 2003/01/10 10:32:54 - [channels.c] - hush socket() errors, except last. Fixes mindrot bug #408; ok markus@ - -20030108 - - (djm) Sync openbsd-compat/ with OpenBSD -current - - (djm) Avoid redundant xstrdup/xfree in auth2-pam.c. From Solar via markus@ - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2003/01/01 18:08:52 - [channels.c] - move big output buffer messages to debug2 - - djm@cvs.openbsd.org 2003/01/06 23:51:22 - [sftp-client.c] - Fix "get -p" download to not add user-write perm. mindrot bug #426 - reported by gfernandez@livevault.com; ok markus@ - - fgsch@cvs.openbsd.org 2003/01/07 23:42:54 - [sftp.1] - add version; from Nils Nordman <nino at nforced dot com> via markus@. - markus@ ok - - (djm) Update README to reflect AIX's status as a well supported platform. - From dtucker@zip.com.au - - (tim) [Makefile.in configure.ac] replace fixpath with sed script. Patch - by Mo DeJong. - - (tim) [auth.c] declare today at top of allowed_user() to keep - older compilers happy. - - (tim) [scp.c] make compilers without long long happy. - -20030107 - - (djm) Bug #401: Work around Linux breakage with IPv6 mapped addresses. - Based on fix from yoshfuji@linux-ipv6.org - - (djm) Bug #442: Check for and deny access to accounts with locked - passwords. Patch from dtucker@zip.com.au - - (djm) Bug #44: Use local mkstemp() rather than glibc's silly one. Fixes - Can't pass KRB4 TGT passing. Fix from: jan.iven@cern.ch - - (djm) Fix Bug #442 for PAM case - - (djm) Bug #110: bogus error messages in lastlog_get_entry(). Fix based - on one by peak@argo.troja.mff.cuni.cz - - (djm) Bug #111: Run syslog and stderr logging through strnvis to eliminate - nasties. Report from peak@argo.troja.mff.cuni.cz - - (djm) Bug #178: On AIX /etc/nologin wasnt't shown to users. Fix from - Ralf.Wenk@fh-karlsruhe.de and dtucker@zip.com.au - - (djm) Fix my fix of the fix for the Bug #442 for PAM case. Spotted by - dtucker@zip.com.au. Reorder for clarity too. - -20030103 - - (djm) Bug #461: ssh-copy-id fails with no arguments. Patch from - cjwatson@debian.org - - (djm) Bug #460: Filling utmp[x]->ut_addr_v6 if present. Patch from - cjwatson@debian.org - - (djm) Bug #446: Set LOGIN env var to pw_name on AIX. Patch from - mii@ornl.gov - -20030101 - - (stevesk) [session.c sshlogin.c sshlogin.h] complete portable - parts of pass addrlen with sockaddr * fix. - from Hajimu UMEMOTO <ume@FreeBSD.org> - -20021222 - - (bal) OpenBSD CVS Sync - - fgsch@cvs.openbsd.org 2002/11/15 10:03:09 - [authfile.c] - lseek(2) may return -1 when getting the public/private key lenght. - Simplify the code and check for errors using fstat(2). - - Problem reported by Mauricio Sanchez, markus@ ok. - - markus@cvs.openbsd.org 2002/11/18 16:43:44 - [clientloop.c] - don't overwrite SIG{INT,QUIT,TERM} handler if set to SIG_IGN; - e.g. if ssh is used for backup; report Joerg Schilling; ok millert@ - - markus@cvs.openbsd.org 2002/11/21 22:22:50 - [dh.c] - debug->debug2 - - markus@cvs.openbsd.org 2002/11/21 22:45:31 - [cipher.c kex.c packet.c sshconnect.c sshconnect2.c] - debug->debug2, unify debug messages - - deraadt@cvs.openbsd.org 2002/11/21 23:03:51 - [auth-krb5.c auth1.c hostfile.h monitor_wrap.c sftp-client.c sftp-int.c ssh-add.c ssh-rsa.c - sshconnect.c] - KNF - - markus@cvs.openbsd.org 2002/11/21 23:04:33 - [ssh.c] - debug->debug2 - - stevesk@cvs.openbsd.org 2002/11/24 21:46:24 - [ssh-keysign.8] - typo: "the the" - - wcobb@cvs.openbsd.org 2002/11/26 00:45:03 - [scp.c ssh-keygen.c] - Remove unnecessary fflush(stderr) calls, stderr is unbuffered by default. - ok markus@ - - stevesk@cvs.openbsd.org 2002/11/26 02:35:30 - [ssh-keygen.1] - remove outdated statement; ok markus@ deraadt@ - - stevesk@cvs.openbsd.org 2002/11/26 02:38:54 - [canohost.c] - KNF, comment and error message repair; ok markus@ - - markus@cvs.openbsd.org 2002/11/27 17:53:35 - [scp.c sftp.c ssh.c] - allow usernames with embedded '@', e.g. scp user@vhost@realhost:file /tmp; - http://bugzilla.mindrot.org/show_bug.cgi?id=447; ok mouring@, millert@ - - stevesk@cvs.openbsd.org 2002/12/04 04:36:47 - [session.c] - remove xauth entries before add; PR 2994 from janjaap@stack.nl. - ok markus@ - - markus@cvs.openbsd.org 2002/12/05 11:08:35 - [scp.c] - use roundup() similar to rcp/util.c and avoid problems with strange - filesystem block sizes, noted by tjr@freebsd.org; ok djm@ - - djm@cvs.openbsd.org 2002/12/06 05:20:02 - [sftp.1] - Fix cut'n'paste error, spotted by matthias.riese@b-novative.de; ok deraadt@ - - millert@cvs.openbsd.org 2002/12/09 16:50:30 - [ssh.c] - Avoid setting optind to 0 as GNU getopt treats that like we do optreset. - markus@ OK - - markus@cvs.openbsd.org 2002/12/10 08:56:00 - [session.c] - Make sure $SHELL points to the shell from the password file, even if shell - is overridden from login.conf; bug#453; semen at online.sinor.ru; ok millert@ - - markus@cvs.openbsd.org 2002/12/10 19:26:50 - [packet.c] - move tos handling to packet_set_tos; ok provos/henning/deraadt - - markus@cvs.openbsd.org 2002/12/10 19:47:14 - [packet.c] - static - - markus@cvs.openbsd.org 2002/12/13 10:03:15 - [channels.c misc.c sshconnect2.c] - cleanup debug messages, more useful information for the client user. - - markus@cvs.openbsd.org 2002/12/13 15:20:52 - [scp.c] - 1) include stalling time in total time - 2) truncate filenames to 45 instead of 20 characters - 3) print rate instead of progress bar, no more stars - 4) scale output to tty width - based on a patch from Niels; ok fries@ lebel@ fgs@ millert@ - - (bal) [msg.c msg.h scp.c ssh-keysign.c sshconnect2.c] Resync CVS IDs since - we already did s/msg_send/ssh_msg_send/ - -20021205 - - (djm) PERL-free fixpaths from stuge-openssh-unix-dev@cdy.org - -20021122 - - (tim) [configure.ac] fix STDPATH test for IRIX. First reported by - advax@triumf.ca. This type of solution tested by <herb@sgi.com> - -20021113 - - (tim) [configure.ac] remove unused variables no_libsocket and no_libnsl - -20021111 - - (tim) [contrib/solaris/opensshd.in] add umask 022 so sshd.pid is - not world writable. - -20021109 - - (bal) OpenBSD CVS Sync - - itojun@cvs.openbsd.org 2002/10/16 14:31:48 - [sftp-common.c] - 64bit pedant. %llu is "unsigned long long". markus ok - - markus@cvs.openbsd.org 2002/10/23 10:32:13 - [packet.c] - use %u for u_int - - markus@cvs.openbsd.org 2002/10/23 10:40:16 - [bufaux.c] - %u for u_int - - markus@cvs.openbsd.org 2002/11/04 10:07:53 - [auth.c] - don't compare against pw_home if realpath fails for pw_home (seen - on AFS); ok djm@ - - markus@cvs.openbsd.org 2002/11/04 10:09:51 - [packet.c] - log before send disconnect; ok djm@ - - markus@cvs.openbsd.org 2002/11/05 19:45:20 - [monitor.c] - handle overflows for size_t larger than u_int; siw@goneko.de, bug #425 - - markus@cvs.openbsd.org 2002/11/05 20:10:37 - [sftp-client.c] - typo; GaryF@livevault.com - - markus@cvs.openbsd.org 2002/11/07 16:28:47 - [sshd.c] - log to stderr if -ie is given, bug #414, prj@po.cwru.edu - - markus@cvs.openbsd.org 2002/11/07 22:08:07 - [readconf.c readconf.h ssh-keysign.8 ssh-keysign.c] - we cannot use HostbasedAuthentication for enabling ssh-keysign(8), - because HostbasedAuthentication might be enabled based on the - target host and ssh-keysign(8) does not know the remote hostname - and not trust ssh(1) about the hostname, so we add a new option - EnableSSHKeysign; ok djm@, report from zierke@informatik.uni-hamburg.de - - markus@cvs.openbsd.org 2002/11/07 22:35:38 - [scp.c] - check exit status from ssh, and exit(1) if ssh fails; bug#369; - binder@arago.de - - (bal) Update ssh-host-config and minor rewrite of bsd-cygwin_util.c - ntsec now default if cygwin version beginning w/ version 56. Patch - by Corinna Vinschen <vinschen@redhat.com> - - (bal) AIX does not log login attempts for unknown users (bug #432). - patch by dtucker@zip.com.au - -20021021 - - (djm) Bug #400: Kill ssh-rand-helper children on timeout, patch from - dtucker@zip.com.au - - (djm) Bug #317: FreeBSD needs libutil.h for openpty() Report from - dirk.meyer@dinoex.sub.org - -20021015 - - (bal) Fix bug id 383 and only call loginrestrict for AIX if not root. - - (bal) More advanced strsep test by Darren Tucker <dtucker@zip.com.au> - -20021015 - - (tim) [contrib/caldera/openssh.spec] make ssh-agent setgid nobody - -20021004 - - (bal) Disable post-authentication Privsep for OSF/1. It conflicts with - SIA. - -20021003 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/10/01 20:34:12 - [ssh-agent.c] - allow root to access the agent, since there is no protection from root. - - markus@cvs.openbsd.org 2002/10/01 13:24:50 - [version.h] - OpenSSH 3.5 - - (djm) Bump RPM spec version numbers - - (djm) Bug #406: s/msg_send/ssh_msg_send/ for Mac OS X 1.2 - -20020930 - - (djm) Tidy contrib/, add Makefile for GNOME passphrase dialogs, - tweak README - - (djm) OpenBSD CVS Sync - - mickey@cvs.openbsd.org 2002/09/27 10:42:09 - [compat.c compat.h sshd.c] - add a generic match for a prober, such as sie big brother; - idea from stevesk@; markus@ ok - - stevesk@cvs.openbsd.org 2002/09/27 15:46:21 - [ssh.1] - clarify compression level protocol 1 only; ok markus@ deraadt@ - -20020927 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/09/25 11:17:16 - [sshd_config] - sync LoginGraceTime with default - - markus@cvs.openbsd.org 2002/09/25 15:19:02 - [sshd.c] - typo; pilot@monkey.org - - markus@cvs.openbsd.org 2002/09/26 11:38:43 - [auth1.c auth.h auth-krb4.c monitor.c monitor.h monitor_wrap.c] - [monitor_wrap.h] - krb4 + privsep; ok dugsong@, deraadt@ - -20020925 - - (bal) Fix issue where successfull login does not clear failure counts - in AIX. Patch by dtucker@zip.com.au ok by djm - - (tim) Cray fixes (bug 367) based on patch from Wendy Palm @ cray. - This does not include the deattack.c fixes. - -20020923 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2002/09/23 20:46:27 - [canohost.c] - change get_peer_ipaddr() and get_local_ipaddr() to not return NULL for - non-sockets; fixes a problem passing NULL to snprintf(). ok markus@ - - markus@cvs.openbsd.org 2002/09/23 22:11:05 - [monitor.c] - only call auth_krb5 if kerberos is enabled; ok deraadt@ - - markus@cvs.openbsd.org 2002/09/24 08:46:04 - [monitor.c] - only call kerberos code for authctxt->valid - - todd@cvs.openbsd.org 2002/09/24 20:59:44 - [sshd.8] - tweak the example $HOME/.ssh/rc script to not show on any cmdline the - sensitive data it handles. This fixes bug # 402 as reported by - kolya@mit.edu (Nickolai Zeldovich). - ok markus@ and stevesk@ - -20020923 - - (tim) [configure.ac] s/return/exit/ patch by dtucker@zip.com.au - -20020922 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2002/09/19 14:53:14 - [compat.c] - - markus@cvs.openbsd.org 2002/09/19 15:51:23 - [ssh-add.c] - typo; cd@kalkatraz.de - - stevesk@cvs.openbsd.org 2002/09/19 16:03:15 - [serverloop.c] - log IP address also; ok markus@ - - stevesk@cvs.openbsd.org 2002/09/20 18:41:29 - [auth.c] - log illegal user here for missing privsep case (ssh2). - this is executed in the monitor. ok markus@ - -20020919 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2002/09/12 19:11:52 - [ssh-agent.c] - %u for uid print; ok markus@ - - stevesk@cvs.openbsd.org 2002/09/12 19:50:36 - [session.c ssh.1] - add SSH_CONNECTION and deprecate SSH_CLIENT; bug #384. ok markus@ - - stevesk@cvs.openbsd.org 2002/09/13 19:23:09 - [channels.c sshconnect.c sshd.c] - remove use of SO_LINGER, it should not be needed. error check - SO_REUSEADDR. fixup comments. ok markus@ - - stevesk@cvs.openbsd.org 2002/09/16 19:55:33 - [session.c] - log when _PATH_NOLOGIN exists; ok markus@ - - stevesk@cvs.openbsd.org 2002/09/16 20:12:11 - [sshd_config.5] - more details on X11Forwarding security issues and threats; ok markus@ - - stevesk@cvs.openbsd.org 2002/09/16 22:03:13 - [sshd.8] - reference moduli(5) in FILES /etc/moduli. - - itojun@cvs.openbsd.org 2002/09/17 07:47:02 - [channels.c] - don't quit while creating X11 listening socket. - http://mail-index.netbsd.org/current-users/2002/09/16/0005.html - got from portable. markus ok - - djm@cvs.openbsd.org 2002/09/19 01:58:18 - [ssh.c sshconnect.c] - bugzilla.mindrot.org #223 - ProxyCommands don't exit. - Patch from dtucker@zip.com.au; ok markus@ - -20020912 - - (djm) Made GNOME askpass programs return non-zero if cancel button is - pressed. - - (djm) Added getpeereid() replacement. Properly implemented for systems - with SO_PEERCRED support. Faked for systems which lack it. - - (djm) Sync sys/tree.h with OpenBSD -current. Rename tree.h and - fake-queue.h to sys-tree.h and sys-queue.h - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/09/08 20:24:08 - [hostfile.h] - no comma at end of enumerator list - - itojun@cvs.openbsd.org 2002/09/09 06:48:06 - [auth1.c auth.h auth-krb5.c monitor.c monitor.h] - [monitor_wrap.c monitor_wrap.h] - kerberos support for privsep. confirmed to work by lha@stacken.kth.se - patch from markus - - markus@cvs.openbsd.org 2002/09/09 14:54:15 - [channels.c kex.h key.c monitor.c monitor_wrap.c radix.c uuencode.c] - signed vs unsigned from -pedantic; ok henning@ - - markus@cvs.openbsd.org 2002/09/10 20:24:47 - [ssh-agent.c] - check the euid of the connecting process with getpeereid(2); - ok provos deraadt stevesk - - stevesk@cvs.openbsd.org 2002/09/11 17:55:03 - [ssh.1] - add agent and X11 forwarding warning text from ssh_config.5; ok markus@ - - stevesk@cvs.openbsd.org 2002/09/11 18:27:26 - [authfd.c authfd.h ssh.c] - don't connect to agent to test for presence if we've previously - connected; ok markus@ - - djm@cvs.openbsd.org 2002/09/11 22:41:50 - [sftp.1 sftp-client.c sftp-client.h sftp-common.c sftp-common.h] - [sftp-glob.c sftp-glob.h sftp-int.c sftp-server.c] - support for short/long listings and globbing in "ls"; ok markus@ - - djm@cvs.openbsd.org 2002/09/12 00:13:06 - [sftp-int.c] - zap unused var introduced in last commit - -20020911 - - (djm) Sync openbsd-compat with OpenBSD -current - -20020910 - - (djm) Bug #365: Read /.ssh/environment properly under CygWin. - Patch from Mark Bradshaw <bradshaw@staff.crosswalk.com> - - (djm) Bug #138: Make protocol 1 blowfish work with old OpenSSL. - Patch from Robert Halubek <rob@adso.com.pl> - -20020905 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2002/09/04 18:52:42 - [servconf.c sshd.8 sshd_config.5] - default LoginGraceTime to 2m; 1m may be too short for slow systems. - ok markus@ - - (djm) Merge openssh-TODO.patch from Redhat (null) beta - - (djm) Add gnome-ssh-askpass2.c (gtk2) by merge with patch from - Nalin Dahyabhai <nalin@redhat.com> - - (djm) Add support for building gtk2 password requestor from Redhat beta - -20020903 - - (djm) Patch from itojun@ for Darwin OS: test getaddrinfo, reorder libcrypt - - (djm) Fix Redhat RPM build dependancy test - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/08/12 10:46:35 - [ssh-agent.c] - make ssh-agent setgid, disallow ptrace. - - espie@cvs.openbsd.org 2002/08/21 11:20:59 - [sshd.8] - `RSA' updated to refer to `public key', where it matters. - okay markus@ - - stevesk@cvs.openbsd.org 2002/08/21 19:38:06 - [servconf.c sshd.8 sshd_config sshd_config.5] - change LoginGraceTime default to 1 minute; ok mouring@ markus@ - - stevesk@cvs.openbsd.org 2002/08/21 20:10:28 - [ssh-agent.c] - raise listen backlog; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/22 19:27:53 - [ssh-agent.c] - use common close function; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/22 19:38:42 - [clientloop.c] - format with current EscapeChar; bugzilla #388 from wknox@mitre.org. - ok markus@ - - stevesk@cvs.openbsd.org 2002/08/22 20:57:19 - [ssh-agent.c] - shutdown(SHUT_RDWR) not needed before close here; ok markus@ - - markus@cvs.openbsd.org 2002/08/22 21:33:58 - [auth1.c auth2.c] - auth_root_allowed() is handled by the monitor in the privsep case, - so skip this for use_privsep, ok stevesk@, fixes bugzilla #387/325 - - markus@cvs.openbsd.org 2002/08/22 21:45:41 - [session.c] - send signal name (not signal number) in "exit-signal" message; noticed - by galb@vandyke.com - - stevesk@cvs.openbsd.org 2002/08/27 17:13:56 - [ssh-rsa.c] - RSA_public_decrypt() returns -1 on error so len must be signed; - ok markus@ - - stevesk@cvs.openbsd.org 2002/08/27 17:18:40 - [ssh_config.5] - some warning text for ForwardAgent and ForwardX11; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/29 15:57:25 - [monitor.c session.c sshlogin.c sshlogin.h] - pass addrlen with sockaddr *; from Hajimu UMEMOTO <ume@FreeBSD.org> - NOTE: there are also p-specific parts to this patch. ok markus@ - - stevesk@cvs.openbsd.org 2002/08/29 16:02:54 - [ssh.1 ssh.c] - deprecate -P as UsePrivilegedPort defaults to no now; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/29 16:09:02 - [ssh_config.5] - more on UsePrivilegedPort and setuid root; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/29 19:49:42 - [ssh.c] - shrink initial privilege bracket for setuid case; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/29 22:54:10 - [ssh_config.5 sshd_config.5] - state XAuthLocation is a full pathname - -20020820 - - OpenBSD CVS Sync - - millert@cvs.openbsd.org 2002/08/02 14:43:15 - [monitor.c monitor_mm.c] - Change mm_zalloc() sanity checks to be more in line with what - we do in calloc() and add a check to monitor_mm.c. - OK provos@ and markus@ - - marc@cvs.openbsd.org 2002/08/02 16:00:07 - [ssh.1 sshd.8] - note that .ssh/environment is only read when - allowed (PermitUserEnvironment in sshd_config). - OK markus@ - - markus@cvs.openbsd.org 2002/08/02 21:23:41 - [ssh-rsa.c] - diff is u_int (2x); ok deraadt/provos - - markus@cvs.openbsd.org 2002/08/02 22:20:30 - [ssh-rsa.c] - replace RSA_verify with our own version and avoid the OpenSSL ASN.1 parser - for authentication; ok deraadt/djm - - aaron@cvs.openbsd.org 2002/08/08 13:50:23 - [sshconnect1.c] - Use & to test if bits are set, not &&; markus@ ok. - - stevesk@cvs.openbsd.org 2002/08/08 23:54:52 - [auth.c] - typo in comment - - stevesk@cvs.openbsd.org 2002/08/09 17:21:42 - [sshd_config.5] - use Op for mdoc conformance; from esr@golux.thyrsus.com - ok aaron@ - - stevesk@cvs.openbsd.org 2002/08/09 17:41:12 - [sshd_config.5] - proxy vs. fake display - - stevesk@cvs.openbsd.org 2002/08/12 17:30:35 - [ssh.1 sshd.8 sshd_config.5] - more PermitUserEnvironment; ok markus@ - - stevesk@cvs.openbsd.org 2002/08/17 23:07:14 - [ssh.1] - ForwardAgent has defaulted to no for over 2 years; be more clear here. - - stevesk@cvs.openbsd.org 2002/08/17 23:55:01 - [ssh_config.5] - ordered list here - - (bal) [defines.h] Some platforms don't have SIZE_T_MAX. So assign - it to ULONG_MAX. - -20020813 - - (tim) [configure.ac] Display OpenSSL header/library version. - Patch by dtucker@zip.com.au - -20020731 - - (bal) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/07/24 16:11:18 - [hostfile.c hostfile.h sshconnect.c] - print out all known keys for a host if we get a unknown host key, - see discussion at http://marc.theaimsgroup.com/?t=101069210100016&r=1&w=4 - - the ssharp mitm tool attacks users in a similar way, so i'd like to - pointed out again: - A MITM attack is always possible if the ssh client prints: - The authenticity of host 'bla' can't be established. - (protocol version 2 with pubkey authentication allows you to detect - MITM attacks) - - mouring@cvs.openbsd.org 2002/07/25 01:16:59 - [sftp.c] - FallBackToRsh does not exist anywhere else. Remove it from here. - OK deraadt. - - markus@cvs.openbsd.org 2002/07/29 18:57:30 - [sshconnect.c] - print file:line - - markus@cvs.openbsd.org 2002/07/30 17:03:55 - [auth-options.c servconf.c servconf.h session.c sshd_config sshd_config.5] - add PermitUserEnvironment (off by default!); from dot@dotat.at; - ok provos, deraadt - -20020730 - - (bal) [uidswap.c] SCO compile correction by gert@greenie.muc.de - -20020728 - - (stevesk) [auth-pam.c] should use PAM_MSG_MEMBER(); from solar - - (stevesk) [CREDITS] solar - - (stevesk) [ssh-rand-helper.c] RAND_bytes() and SHA1_Final() unsigned - char arg. - -20020725 - - (djm) Remove some cruft from INSTALL - - (djm) Latest config.guess and config.sub from ftp://ftp.gnu.org/gnu/config/ - -20020723 - - (bal) [bsd-cray.c bsd-cray.h] Part 2 of Cray merger. - - (bal) sync ID w/ ssh-agent.c - - (bal) OpenBSD Sync - - markus@cvs.openbsd.org 2002/07/19 15:43:33 - [log.c log.h session.c sshd.c] - remove fatal cleanups after fork; based on discussions with and code - from solar. - - stevesk@cvs.openbsd.org 2002/07/19 17:42:40 - [ssh.c] - display a warning from ssh when XAuthLocation does not exist or xauth - returned no authentication data. ok markus@ - - stevesk@cvs.openbsd.org 2002/07/21 18:32:20 - [auth-options.c] - unneeded includes - - stevesk@cvs.openbsd.org 2002/07/21 18:34:43 - [auth-options.h] - remove invalid comment - - markus@cvs.openbsd.org 2002/07/22 11:03:06 - [session.c] - fallback to _PATH_STDPATH on setusercontext+LOGIN_SETPATH errors; - - stevesk@cvs.openbsd.org 2002/07/22 17:32:56 - [monitor.c] - u_int here; ok provos@ - - stevesk@cvs.openbsd.org 2002/07/23 16:03:10 - [sshd.c] - utmp_len is unsigned; display error consistent with other options. - ok markus@ - - stevesk@cvs.openbsd.org 2002/07/15 17:15:31 - [uidswap.c] - little more debugging; ok markus@ - -20020722 - - (bal) AIX tty data limiting patch fix by leigh@solinno.co.uk - - (stevesk) [xmmap.c] missing prototype for fatal() - - (bal) [configure.ac defines.h loginrec.c sshd.c sshpty.c] Partial sync - with Cray (mostly #ifdef renaming). Patch by wendyp@cray.com. - - (bal) [configure.ac] Missing ;; from cray patch. - - (bal) [monitor_mm.c openbsd-compat/xmmap.h] Move xmmap() defines - into it's own header. - - (stevesk) [auth-pam.[ch] session.c] pam_getenvlist() must be - freed by the caller; add free_pam_environment() and use it. - - (stevesk) [auth-pam.c] typo in comment - -20020721 - - (stevesk) [auth-pam.c] merge cosmetic changes from solar's - openssh-3.4p1-owl-password-changing.diff - - (stevesk) [auth-pam.c] merge rest of solar's PAM patch; - PAM_NEW_AUTHTOK_REQD remains in #if 0 for now. - - (stevesk) [auth-pam.c] cast to avoid initialization type mismatch - warning on pam_conv struct conversation function. - - (stevesk) [auth-pam.h] license - - (stevesk) [auth-pam.h] unneeded include - - (stevesk) [auth-pam.[ch] ssh.h] move SSHD_PAM_SERVICE to auth-pam.h - -20020720 - - (stevesk) [ssh-keygen.c] bug #231: always init/seed_rng(). - -20020719 - - (tim) [contrib/solaris/buildpkg.sh] create privsep user/group if needed. - Patch by dtucker@zip.com.au - - (tim) [configure.ac] test for libxnet on HP. Patch by dtucker@zip.com.au - -20020718 - - (tim) [defines.h] Bug 313 patch by dirk.meyer@dinoex.sub.org - - (tim) [monitor_mm.c] add missing declaration for xmmap(). Reported - by ayamura@ayamura.org - - (tim) [configure.ac] Bug 267 rework int64_t test. - - (tim) [includes.h] Bug 267 add stdint.h - -20020717 - - (bal) aixbff package updated by dtucker@zip.com.au - - (tim) [configure.ac] change how we do paths in AC_PATH_PROGS tests - for autoconf 2.53. Based on a patch by jrj@purdue.edu - -20020716 - - (tim) [contrib/solaris/opensshd.in] Only kill sshd if .pid file found - -20020715 - - (bal) OpenBSD CVS Sync - - itojun@cvs.openbsd.org 2002/07/12 13:29:09 - [sshconnect.c] - print connect failure during debugging mode. - - markus@cvs.openbsd.org 2002/07/12 15:50:17 - [cipher.c] - EVP_CIPH_CUSTOM_IV for our own rijndael - - (bal) Remove unused tty defined in do_setusercontext() pointed out by - dtucker@zip.com.au plus a a more KNF since I am near it. - - (bal) Privsep user creation support in Solaris buildpkg.sh by - dtucker@zip.com.au - -20020714 - - (tim) [Makefile.in] replace "id sshd" with "sshd -t" - - (bal/tim) [acconfig.h configure.ac monitor_mm.c servconf.c - openbsd-compat/Makefile.in] support compression on platforms that - have no/broken MAP_ANON. Moved code to openbsd-compat/xmmap.c - Based on patch from nalin@redhat.com of code extracted from Owl's package - - (tim) [ssh_prng_cmds.in] Bug 323 arp -n flag doesn't exist under Solaris. - report by chris@by-design.net - - (tim) [loginrec.c] Bug 347: Fix typo (WTMPX_FILE) report by rodney@bond.net - - (tim) [loginrec.c] Bug 348: add missing found = 1; to wtmpx_islogin() - report by rodney@bond.net - -20020712 - - (tim) [Makefile.in] quiet down install-files: and check-user: - - (tim) [configure.ac] remove unused filepriv line - -20020710 - - (tim) [contrib/cygwin/ssh-host-config] explicitely sets the permissions - on /var/empty to 755 Patch by vinschen@redhat.com - - (bal) OpenBSD CVS Sync - - itojun@cvs.openbsd.org 2002/07/09 11:56:50 - [sshconnect.c] - silently try next address on connect(2). markus ok - - itojun@cvs.openbsd.org 2002/07/09 11:56:27 - [canohost.c] - suppress log on reverse lookup failiure, as there's no real value in - doing so. - markus ok - - itojun@cvs.openbsd.org 2002/07/09 12:04:02 - [sshconnect.c] - ed static function (less warnings) - - stevesk@cvs.openbsd.org 2002/07/09 17:46:25 - [sshd_config.5] - clarify no preference ordering in protocol list; ok markus@ - - itojun@cvs.openbsd.org 2002/07/10 10:28:15 - [sshconnect.c] - bark if all connection attempt fails. - - deraadt@cvs.openbsd.org 2002/07/10 17:53:54 - [rijndael.c] - use right sizeof in memcpy; markus ok - -20020709 - - (bal) NO_IPPORT_RESERVED_CONCEPT used instead of CYGWIN so other platforms - lacking that concept can share it. Patch by vinschen@redhat.com - -20020708 - - (tim) [openssh/contrib/solaris/buildpkg.sh] add PKG_INSTALL_ROOT to - work in a jumpstart environment. patch by kbrint@rufus.net - - (tim) [Makefile.in] workaround for broken pakadd on some systems. - - (tim) [configure.ac] fix libc89 utimes test. Mention default path for - --with-privsep-path= - -20020707 - - (tim) [Makefile.in] use umask instead of chmod on $(PRIVSEP_PATH) - - (tim) [acconfig.h configure.ac sshd.c] - s/BROKEN_FD_PASSING/DISABLE_FD_PASSING/ - - (tim) [contrib/cygwin/ssh-host-config] sshd account creation fixes - patch from vinschen@redhat.com - - (bal) [realpath.c] Updated with OpenBSD tree. - - (bal) OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2002/07/04 04:15:33 - [key.c monitor_wrap.c sftp-glob.c ssh-dss.c ssh-rsa.c] - patch memory leaks; grendel@zeitbombe.org - - deraadt@cvs.openbsd.org 2002/07/04 08:12:15 - [channels.c packet.c] - blah blah minor nothing as i read and re-read and re-read... - - markus@cvs.openbsd.org 2002/07/04 10:41:47 - [key.c monitor_wrap.c ssh-dss.c ssh-rsa.c] - don't allocate, copy, and discard if there is not interested in the data; - ok deraadt@ - - deraadt@cvs.openbsd.org 2002/07/06 01:00:49 - [log.c] - KNF - - deraadt@cvs.openbsd.org 2002/07/06 01:01:26 - [ssh-keyscan.c] - KNF, realloc fix, and clean usage - - stevesk@cvs.openbsd.org 2002/07/06 17:47:58 - [ssh-keyscan.c] - unused variable - - (bal) Minor KNF on ssh-keyscan.c - -20020705 - - (tim) [configure.ac] AIX 4.2.1 has authenticate() in libs. - Reported by Darren Tucker <dtucker@zip.com.au> - - (tim) [contrib/cygwin/ssh-host-config] double slash corrction - from vinschen@redhat.com - -20020704 - - (bal) Limit data to TTY for AIX only (Newer versions can't handle the - faster data rate) Bug #124 - - (bal) glob.c defines TILDE and AIX also defines it. #undef it first. - bug #265 - - (bal) One too many nulls in ports-aix.c - -20020703 - - (bal) Updated contrib/cygwin/ patch by vinschen@redhat.com - - (bal) minor correction to utimes() replacement. Patch by - onoe@sm.sony.co.jp - - OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/06/27 08:49:44 - [dh.c ssh-keyscan.c sshconnect.c] - more checks for NULL pointers; from grendel@zeitbombe.org; ok deraadt@ - - deraadt@cvs.openbsd.org 2002/06/27 09:08:00 - [monitor.c] - improve mm_zalloc check; markus ok - - deraadt@cvs.openbsd.org 2002/06/27 10:35:47 - [auth2-none.c monitor.c sftp-client.c] - use xfree() - - stevesk@cvs.openbsd.org 2002/06/27 19:49:08 - [ssh-keyscan.c] - use convtime(); ok markus@ - - millert@cvs.openbsd.org 2002/06/28 01:49:31 - [monitor_mm.c] - tree(3) wants an int return value for its compare functions and - the difference between two pointers is not an int. Just do the - safest thing and store the result in a long and then return 0, - -1, or 1 based on that result. - - deraadt@cvs.openbsd.org 2002/06/28 01:50:37 - [monitor_wrap.c] - use ssize_t - - deraadt@cvs.openbsd.org 2002/06/28 10:08:25 - [sshd.c] - range check -u option at invocation - - deraadt@cvs.openbsd.org 2002/06/28 23:05:06 - [sshd.c] - gidset[2] -> gidset[1]; markus ok - - deraadt@cvs.openbsd.org 2002/06/30 21:54:16 - [auth2.c session.c sshd.c] - lint asks that we use names that do not overlap - - deraadt@cvs.openbsd.org 2002/06/30 21:59:45 - [auth-bsdauth.c auth-skey.c auth2-chall.c clientloop.c key.c - monitor_wrap.c monitor_wrap.h scard.h session.h sftp-glob.c ssh.c - sshconnect2.c sshd.c] - minor KNF - - deraadt@cvs.openbsd.org 2002/07/01 16:15:25 - [msg.c] - %u - - markus@cvs.openbsd.org 2002/07/01 19:48:46 - [sshconnect2.c] - for compression=yes, we fallback to no-compression if the server does - not support compression, vice versa for compression=no. ok mouring@ - - markus@cvs.openbsd.org 2002/07/03 09:55:38 - [ssh-keysign.c] - use RSA_blinding_on() for rsa hostkeys (suggested by Bill Sommerfeld) - in order to avoid a possible Kocher timing attack pointed out by Charles - Hannum; ok provos@ - - markus@cvs.openbsd.org 2002/07/03 14:21:05 - [ssh-keysign.8 ssh-keysign.c ssh.c ssh_config] - re-enable ssh-keysign's sbit, but make ssh-keysign read - /etc/ssh/ssh_config and exit if HostbasedAuthentication is disabled - globally. based on discussions with deraadt, itojun and sommerfeld; - ok itojun@ - - (bal) Failed password attempts don't increment counter on AIX. Bug #145 - - (bal) Missed Makefile.in change. keysign needs readconf.o - - (bal) Clean up aix_usrinfo(). Ignore TTY= period I guess. - -20020702 - - (djm) Use PAM_MSG_MEMBER for PAM_TEXT_INFO messages, use xmalloc & - friends consistently. Spotted by Solar Designer <solar@openwall.com> - -20020629 - - (bal) fix to auth2-pam.c to swap fatal() arguments, A bit of style - clean up while I'm near it. - -20020628 - - (stevesk) [sshd_config] PAMAuthenticationViaKbdInt no; commented - options should contain default value. from solar. - - (bal) Cygwin uid0 fix by vinschen@redhat.com - - (bal) s/config.h/includes.h/ in openbsd-compat/ for *.c. Otherwise wise - have issues of our fixes not propogating right (ie bcopy instead of - memmove). OK tim - - (bal) FreeBSD needs <sys/types.h> to detect if mmap() is supported. - Bug #303 - -20020627 - - OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2002/06/26 14:49:36 - [monitor.c] - correct %u - - deraadt@cvs.openbsd.org 2002/06/26 14:50:04 - [monitor_fdpass.c] - use ssize_t for recvmsg() and sendmsg() return - - markus@cvs.openbsd.org 2002/06/26 14:51:33 - [ssh-add.c] - fix exit code for -X/-x - - deraadt@cvs.openbsd.org 2002/06/26 15:00:32 - [monitor_wrap.c] - more %u - - markus@cvs.openbsd.org 2002/06/26 22:27:32 - [ssh-keysign.c] - bug #304, xfree(data) called to early; openssh@sigint.cs.purdue.edu - -20020626 - - (stevesk) [monitor.c] remove duplicate proto15 dispatch entry for PAM - - (bal) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/06/23 21:34:07 - [channels.c] - tcode is u_int - - markus@cvs.openbsd.org 2002/06/24 13:12:23 - [ssh-agent.1] - the socket name contains ssh-agent's ppid; via mpech@ from form@ - - markus@cvs.openbsd.org 2002/06/24 14:33:27 - [channels.c channels.h clientloop.c serverloop.c] - move channel counter to u_int - - markus@cvs.openbsd.org 2002/06/24 14:55:38 - [authfile.c kex.c ssh-agent.c] - cat to (void) when output from buffer_get_X is ignored - - itojun@cvs.openbsd.org 2002/06/24 15:49:22 - [msg.c] - printf type pedant - - deraadt@cvs.openbsd.org 2002/06/24 17:57:20 - [sftp-server.c sshpty.c] - explicit (u_int) for uid and gid - - markus@cvs.openbsd.org 2002/06/25 16:22:42 - [authfd.c] - unnecessary cast - - markus@cvs.openbsd.org 2002/06/25 18:51:04 - [sshd.c] - lightweight do_setusercontext after chroot() - - (bal) Updated AIX package build. Patch by dtucker@zip.com.au - - (tim) [Makefile.in] fix test on installing ssh-rand-helper.8 - - (bal) added back in error check for mmap(). I screwed up, Pointed - out by stevesk@ - - (tim) [README.privsep] UnixWare tip no longer needed. - - (bal) fixed NeXTStep missing munmap() issue. It defines HAVE_MMAP, - but it all damned lies. - - (stevesk) [README.privsep] more for sshd pseudo-account. - - (tim) [contrib/caldera/openssh.spec] add support for privsep - - (djm) setlogin needs pgid==pid on BSD/OS; from itojun@ - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2002/06/26 08:53:12 - [bufaux.c] - limit size of BNs to 8KB; ok provos/deraadt - - markus@cvs.openbsd.org 2002/06/26 08:54:18 - [buffer.c] - limit append to 1MB and buffers to 10MB - - markus@cvs.openbsd.org 2002/06/26 08:55:02 - [channels.c] - limit # of channels to 10000 - - markus@cvs.openbsd.org 2002/06/26 08:58:26 - [session.c] - limit # of env vars to 1000; ok deraadt/djm - - deraadt@cvs.openbsd.org 2002/06/26 13:20:57 - [monitor.c] - be careful in mm_zalloc - - deraadt@cvs.openbsd.org 2002/06/26 13:49:26 - [session.c] - disclose less information from environment files; based on input - from djm, and dschultz@uclink.Berkeley.EDU - - markus@cvs.openbsd.org 2002/06/26 13:55:37 - [auth2-chall.c] - make sure # of response matches # of queries, fixes int overflow; - from ISS - - markus@cvs.openbsd.org 2002/06/26 13:56:27 - [version.h] - 3.4 - - (djm) Require krb5 devel for RPM build w/ KrbV - - (djm) Improve PAMAuthenticationViaKbdInt text from Nalin Dahyabhai - <nalin@redhat.com> - - (djm) Update spec files for release - - (djm) Fix int overflow in auth2-pam.c, similar to one discovered by ISS - - (djm) Release 3.4p1 - - (tim) [contrib/caldera/openssh.spec] remove 2 configure options I put in - by mistake - -20020625 - - (stevesk) [INSTALL acconfig.h configure.ac defines.h] remove --with-rsh - - (stevesk) [README.privsep] minor updates - - (djm) Create privsep directory and warn if privsep user is missing - during make install - - (bal) Started list of PrivSep issues in TODO - - (bal) if mmap() is substandard, don't allow compression on server side. - Post 'event' we will add more options. - - (tim) [contrib/caldera/openssh.spec] Sync with Caldera - - (bal) moved aix_usrinfo() and noted not setting real TTY. Patch by - dtucker@zip.com.au - - (tim) [acconfig.h configure.ac sshd.c] BROKEN_FD_PASSING fix from Markus - for Cygwin, Cray, & SCO - -20020624 - - OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2002/06/23 03:25:50 - [tildexpand.c] - KNF - - deraadt@cvs.openbsd.org 2002/06/23 03:26:19 - [cipher.c key.c] - KNF - - deraadt@cvs.openbsd.org 2002/06/23 03:30:58 - [scard.c ssh-dss.c ssh-rsa.c sshconnect.c sshconnect2.c sshd.c sshlogin.c - sshpty.c] - various KNF and %d for unsigned - - deraadt@cvs.openbsd.org 2002/06/23 09:30:14 - [sftp-client.c sftp-client.h sftp-common.c sftp-int.c sftp-server.c - sftp.c] - bunch of u_int vs int stuff - - deraadt@cvs.openbsd.org 2002/06/23 09:39:55 - [ssh-keygen.c] - u_int stuff - - deraadt@cvs.openbsd.org 2002/06/23 09:46:51 - [bufaux.c servconf.c] - minor KNF. things the fingers do while you read - - deraadt@cvs.openbsd.org 2002/06/23 10:29:52 - [ssh-agent.c sshd.c] - some minor KNF and %u - - deraadt@cvs.openbsd.org 2002/06/23 20:39:45 - [session.c] - compression_level is u_int - - deraadt@cvs.openbsd.org 2002/06/23 21:06:13 - [sshpty.c] - KNF - - deraadt@cvs.openbsd.org 2002/06/23 21:06:41 - [channels.c channels.h session.c session.h] - display, screen, row, col, xpixel, ypixel are u_int; markus ok - - deraadt@cvs.openbsd.org 2002/06/23 21:10:02 - [packet.c] - packet_get_int() returns unsigned for reason & seqnr - - (bal) Also fixed IPADDR_IN_DISPLAY case where display, screen, row, col, - xpixel are u_int. - - -20020623 - - (stevesk) [configure.ac] bug #255 LOGIN_NEEDS_UTMPX for AIX. - - (bal) removed GNUism for getops in ssh-agent since glibc lacks optreset. - - (bal) add extern char *getopt. Based on report by dtucker@zip.com.au - - OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2002/06/22 02:00:29 - [ssh.h] - correct comment - - stevesk@cvs.openbsd.org 2002/06/22 02:40:23 - [ssh.1] - section 5 not 4 for ssh_config - - naddy@cvs.openbsd.org 2002/06/22 11:51:39 - [ssh.1] - typo - - stevesk@cvs.openbsd.org 2002/06/22 16:32:54 - [sshd.8] - add /var/empty in FILES section - - stevesk@cvs.openbsd.org 2002/06/22 16:40:19 - [sshd.c] - check /var/empty owner mode; ok provos@ - - stevesk@cvs.openbsd.org 2002/06/22 16:41:57 - [scp.1] - typo - - stevesk@cvs.openbsd.org 2002/06/22 16:45:29 - [ssh-agent.1 sshd.8 sshd_config.5] - use process ID vs. pid/PID/process identifier - - stevesk@cvs.openbsd.org 2002/06/22 20:05:27 - [sshd.c] - don't call setsid() if debugging or run from inetd; no "Operation not - permitted" errors now; ok millert@ markus@ - - stevesk@cvs.openbsd.org 2002/06/22 23:09:51 - [monitor.c] - save auth method before monitor_reset_key_state(); bugzilla bug #284; - ok provos@ - -$Id: ChangeLog,v 1.2648 2003/04/01 11:47:16 djm Exp $ +$Id: ChangeLog,v 1.2994.2.34 2003/09/23 09:33:17 djm Exp $ diff --git a/crypto/openssh/INSTALL b/crypto/openssh/INSTALL index f5ab0db..0df6fba 100644 --- a/crypto/openssh/INSTALL +++ b/crypto/openssh/INSTALL @@ -3,7 +3,7 @@ You will need working installations of Zlib and OpenSSL. -Zlib: +Zlib 1.1.4 or greater: http://www.gzip.org/zlib/ OpenSSL 0.9.6 or greater: @@ -33,7 +33,7 @@ http://www.gnome.org/ Alternatively, Jim Knoble <jmknoble@jmknoble.cx> has written an excellent X11 passphrase requester. This is maintained separately at: -http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html +http://www.jmknoble.net/software/x11-ssh-askpass/ PRNGD: @@ -101,11 +101,8 @@ name). There are a few other options to the configure script: ---with-pam enables PAM support. - ---enable-gnome-askpass will build the GNOME passphrase dialog. You -need a working installation of GNOME, including the development -headers, for this to work. +--with-pam enables PAM support. If PAM support is compiled in, it must +also be enabled in sshd_config (refer to the UsePAM directive). --with-prngd-socket=/some/file allows you to enable EGD or PRNGD support and to specify a PRNGd socket. Use this if your Unix lacks @@ -123,19 +120,9 @@ it if lastlog is installed in a different place. --without-lastlog will disable lastlog support entirely. ---with-sia, --without-sia will enable or disable OSF1's Security +--with-osfsia, --without-osfsia will enable or disable OSF1's Security Integration Architecture. The default for OSF1 machines is enable. ---with-kerberos4=PATH will enable Kerberos IV support. You will need -to have the Kerberos libraries and header files installed for this -to work. Use the optional PATH argument to specify the root of your -Kerberos installation. - ---with-afs=PATH will enable AFS support. You will need to have the -Kerberos IV and the AFS libraries and header files installed for this -to work. Use the optional PATH argument to specify the root of your -AFS installation. AFS requires Kerberos support to be enabled. - --with-skey=PATH will enable S/Key one time password support. You will need the S/Key libraries and header files installed for this to work. @@ -161,12 +148,6 @@ created. --with-xauth=PATH specifies the location of the xauth binary ---with-ipv4-default instructs OpenSSH to use IPv4 by default for new -connections. Normally OpenSSH will try attempt to lookup both IPv6 and -IPv4 addresses. On Linux/glibc-2.1.2 this causes long delays in name -resolution. If this option is specified, you can still attempt to -connect to IPv6 addresses using the command line option '-6'. - --with-ssl-dir=DIR allows you to specify where your OpenSSL libraries are installed. @@ -217,4 +198,4 @@ Please refer to the "reporting bugs" section of the webpage at http://www.openssh.com/ -$Id: INSTALL,v 1.55 2002/07/25 04:36:25 djm Exp $ +$Id: INSTALL,v 1.56.2.4 2003/09/23 09:24:21 djm Exp $ diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE index 19d4c74..b47556d 100644 --- a/crypto/openssh/LICENCE +++ b/crypto/openssh/LICENCE @@ -76,14 +76,6 @@ OpenSSH contains no GPL code. POSSIBILITY OF SUCH DAMAGES. 2) - The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. - Comments in the file indicate it may be used for any purpose without - restrictions: - - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - -3) The 32-bit CRC compensation attack detector in deattack.c was contributed by CORE SDI S.A. under a BSD-style license. @@ -104,7 +96,7 @@ OpenSSH contains no GPL code. * Ariel Futoransky <futo@core-sdi.com> * <http://www.core-sdi.com> -4) +3) ssh-keygen was contributed by David Mazieres under a BSD-style license. @@ -114,7 +106,7 @@ OpenSSH contains no GPL code. * permitted provided that due credit is given to the author and the * OpenBSD project by leaving this copyright notice intact. -5) +4) The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers and Paulo Barreto is in the public domain and distributed with the following license: @@ -141,12 +133,10 @@ OpenSSH contains no GPL code. * 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, +5) + One component of the ssh source code is under a 3-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. + original Berkeley code. * Copyright (c) 1983, 1990, 1992, 1993, 1995 * The Regents of the University of California. All rights reserved. @@ -159,11 +149,7 @@ OpenSSH contains no GPL code. * 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 + * 3. 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. * @@ -179,7 +165,7 @@ OpenSSH contains no GPL code. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. -7) +6) Remaining components of the software are provided under a standard 2-term BSD licence with the following names as copyright holders: @@ -192,6 +178,31 @@ OpenSSH contains no GPL code. Kevin Steves Daniel Kouril Per Allansson + Wesley Griffin + Per Allansson + Nils Nordman + Simon Wilkinson + + Portable OpenSSH additionally includes code from the following copyright + holders, also under the 2-term BSD license: + + Ben Lindstrom + Tim Rice + Andre Lucas + Chris Adams + Corinna Vinschen + Cray Inc. + Denis Parker + Gert Doering + Jakob Schlyter + Jason Downs + Juha Yrjölä + Michael Stone + Networks Associates Technology, Inc. + Solar Designer + Todd C. Miller + Wayne Schroeder + William Jones * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -212,3 +223,110 @@ OpenSSH contains no GPL code. * 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. + +8) Portable OpenSSH contains the following additional licenses: + + a) md5crypt.c, md5crypt.h + + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@login.dknet.dk> wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet + * some day, and you think this stuff is worth it, you can buy me a + * beer in return. Poul-Henning Kamp + + b) snprintf replacement + + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * (papowell@astart.com) It may be used for any purpose as long as this + * notice remains intact on all source code distributions + + c) Compatibility code (openbsd-compat) + + Apart from the previously mentioned licenses, various pieces of code + in the openbsd-compat/ subdirectory are licensed as follows: + + Some code is licensed under a 3-term BSD license, to the following + copyright holders: + + Todd C. Miller + Theo de Raadt + Damien Miller + Eric P. Allman + The Regents of the University of California + + * 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. 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. + + Some code is licensed under an ISC-style license, to the following + copyright holders: + + Internet Software Consortium. + Todd C. Miller + + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Some code is licensed under a MIT-style license to the following + copyright holders: + + Free Software Foundation, Inc. + + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + + +------ +$OpenBSD: LICENCE,v 1.17 2003/08/22 20:55:06 markus Exp $ diff --git a/crypto/openssh/Makefile.in b/crypto/openssh/Makefile.in index 6702eb9..c90b17d 100644 --- a/crypto/openssh/Makefile.in +++ b/crypto/openssh/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.228 2003/03/21 00:34:34 mouring Exp $ +# $Id: Makefile.in,v 1.249.2.1 2003/09/22 01:00:12 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -46,6 +46,7 @@ LIBS=@LIBS@ LIBPAM=@LIBPAM@ LIBWRAP=@LIBWRAP@ AR=@AR@ +AWK=@AWK@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ PERL=@PERL@ @@ -61,13 +62,14 @@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \ - cipher.o compat.o compress.o crc32.o deattack.o fatal.o \ - hostfile.o log.o match.o mpaux.o nchan.o packet.o readpass.o \ - rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \ + cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \ + compat.o compress.o crc32.o deattack.o fatal.o \ + hostfile.o log.o match.o moduli.o mpaux.o nchan.o packet.o \ + readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \ key.o dispatch.o kex.o mac.o uuencode.o misc.o \ rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o kexgex.o \ - kexdhc.o kexgexc.o scard.o msg.o progressmeter.o \ - entropy.o + kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ + entropy.o scard-opensc.o gss-genr.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o @@ -80,8 +82,9 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \ monitor_mm.o monitor.o monitor_wrap.o monitor_fdpass.o \ kexdhs.o kexgexs.o \ - auth-krb5.o auth-krb4.o \ - loginrec.o auth-pam.o auth2-pam.o auth-sia.o md5crypt.o + auth-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + loginrec.o auth-pam.o auth-sia.o md5crypt.o MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 @@ -109,11 +112,11 @@ PATHSUBS = \ FIXPATHSCMD = $(SED) $(PATHSUBS) -all: $(CONFIGFILES) $(MANPAGES) $(TARGETS) +all: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) -$(LIBSSH_OBJS): config.h -$(SSHOBJS): config.h -$(SSHDOBJS): config.h +$(LIBSSH_OBJS): Makefile.in config.h +$(SSHOBJS): Makefile.in config.h +$(SSHDOBJS): Makefile.in config.h .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) -c $< @@ -171,7 +174,7 @@ $(MANPAGES): $(MANPAGES_IN) manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \ fi; \ if test "$(MANTYPE)" = "man"; then \ - $(FIXPATHSCMD) $${manpage} | $(PERL) $(srcdir)/mdoc2man.pl > $@; \ + $(FIXPATHSCMD) $${manpage} | $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \ else \ $(FIXPATHSCMD) $${manpage} > $@; \ fi @@ -180,12 +183,21 @@ $(CONFIGFILES): $(CONFIGFILES_IN) conffile=`echo $@ | sed 's/.out$$//'`; \ $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ -clean: +ssh_prng_cmds.out: ssh_prng_cmds + if test ! -z "$(INSTALL_SSH_PRNG_CMDS)"; then \ + $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \ + fi + +# fake rule to stop make trying to compile moduli.o into a binary "modulo" +moduli: + echo + +clean: regressclean rm -f *.o *.a $(TARGETS) logintest config.cache config.log rm -f *.out core (cd openbsd-compat && $(MAKE) clean) -distclean: +distclean: regressclean rm -f *.o *.a $(TARGETS) logintest config.cache config.log rm -f *.out core rm -f Makefile config.h config.status ssh_prng_cmds *~ @@ -193,15 +205,12 @@ distclean: (cd openbsd-compat && $(MAKE) distclean) (cd scard && $(MAKE) distclean) -veryclean: +veryclean: distclean rm -f configure config.h.in *.0 - rm -f *.o *.a $(TARGETS) logintest config.cache config.log - rm -f *.out core - rm -f Makefile config.h config.status ssh_prng_cmds *~ - (cd openbsd-compat && $(MAKE) distclean) - (cd scard && $(MAKE) distclean) -mrproper: distclean +mrproper: veryclean + +realclean: veryclean catman-do: @for f in $(MANPAGES_IN) ; do \ @@ -215,8 +224,8 @@ distprep: catman-do $(AUTORECONF) (cd scard && $(MAKE) -f Makefile.in distprep) -install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files host-key check-config -install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files +install: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files host-key check-config +install-nokeys: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files check-config: -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config @@ -280,7 +289,6 @@ install-files: scard-install echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \ fi @if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ - $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \ if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds ] ; then \ $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ else \ @@ -359,3 +367,39 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + +tests: $(TARGETS) + BUILDDIR=`pwd`; \ + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ + [ -f `pwd`/regress/Makefile ] || \ + ln -s $(srcdir)/regress/Makefile `pwd`/regress/Makefile ; \ + TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ + TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ + TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ + TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \ + TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \ + TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ + TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ + TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ + cd $(srcdir)/regress || exit $$?; \ + $(MAKE) \ + .OBJDIR="$${BUILDDIR}/regress" \ + .CURDIR="`pwd`" \ + BUILDDIR="$${BUILDDIR}" \ + OBJ="$${BUILDDIR}/regress/" \ + PATH="$${BUILDDIR}:$${PATH}" \ + TEST_SSH_SSH="$${TEST_SSH_SSH}" \ + TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \ + TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \ + TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \ + TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \ + TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ + TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ + TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ + EXEEXT="$(EXEEXT)" \ + $@ + +regressclean: + if [ -f regress/Makefile -a -r regress/Makefile ]; then \ + (cd regress && $(MAKE) clean) \ + fi diff --git a/crypto/openssh/README.dns b/crypto/openssh/README.dns new file mode 100644 index 0000000..e24092e --- /dev/null +++ b/crypto/openssh/README.dns @@ -0,0 +1,52 @@ +How to verify host keys using OpenSSH and DNS +--------------------------------------------- + +OpenSSH contains experimental support for verifying host keys using DNS +as described in draft-ietf-secsh-dns-xx.txt. The document contains +very brief instructions on how to test this feature. Configuring DNS +and DNSSEC is out of the scope of this document. + + +(1) Enable DNS fingerprint support in OpenSSH + + configure --with-dns + +(2) Generate and publish the DNS RR + +To create a DNS resource record (RR) containing a fingerprint of the +public host key, use the following command: + + ssh-keygen -r hostname -f keyfile -g + +where "hostname" is your fully qualified hostname and "keyfile" is the +file containing the public host key file. If you have multiple keys, +you should generate one RR for each key. + +In the example above, ssh-keygen will print the fingerprint in a +generic DNS RR format parsable by most modern name server +implementations. If your nameserver has support for the SSHFP RR, as +defined by the draft, you can omit the -g flag and ssh-keygen will +print a standard RR. + +To publish the fingerprint using the DNS you must add the generated RR +to your DNS zone file and sign your zone. + + +(3) Enable the ssh client to verify host keys using DNS + +To enable the ssh client to verify host keys using DNS, you have to +add the following option to the ssh configuration file +($HOME/.ssh/config or /etc/ssh/ssh_config): + + VerifyHostKeyDNS yes + +Upon connection the client will try to look up the fingerprint RR +using DNS. If the fingerprint received from the DNS server matches +the remote host key, the user will be notified. + + + Jakob Schlyter + Wesley Griffin + + +$OpenBSD: README.dns,v 1.1 2003/05/14 18:16:20 jakob Exp $ diff --git a/crypto/openssh/README.privsep b/crypto/openssh/README.privsep index e8bf1db..64adad8 100644 --- a/crypto/openssh/README.privsep +++ b/crypto/openssh/README.privsep @@ -40,8 +40,7 @@ Compression will be disabled on systems without a working mmap MAP_ANON. PAM-enabled OpenSSH is known to function with privsep on Linux. It does not function on HP-UX with a trusted system -configuration. PAMAuthenticationViaKbdInt does not function with -privsep. +configuration. On Compaq Tru64 Unix, only the pre-authentication part of privsep is supported. Post-authentication privsep is disabled automatically (so @@ -62,4 +61,4 @@ process 1005 is the sshd process listening for new connections. process 6917 is the privileged monitor process, 6919 is the user owned sshd process and 6921 is the shell process. -$Id: README.privsep,v 1.11 2003/03/21 01:18:09 mouring Exp $ +$Id: README.privsep,v 1.12 2003/08/26 00:48:15 djm Exp $ diff --git a/crypto/openssh/README.smartcard b/crypto/openssh/README.smartcard index 29bec8d..88810fc 100644 --- a/crypto/openssh/README.smartcard +++ b/crypto/openssh/README.smartcard @@ -1,62 +1,66 @@ How to use smartcards with OpenSSH? -OpenSSH contains experimental support for authentication using Cyberflex -smartcards and TODOS card readers, in addition to the cards with PKCS#15 -structure supported by OpenSC. +OpenSSH contains experimental support for authentication using +Cyberflex smartcards and TODOS card readers, in addition to the cards +with PKCS#15 structure supported by OpenSC. To enable this you +need to: -WARNING: Smartcard support is still in development. -Keyfile formats, etc are still subject to change. +Using libsectok: -To enable sectok support: +(1) enable sectok support in OpenSSH: -(1) install sectok: + $ ./configure --with-sectok - Sources and instructions are available from - http://www.citi.umich.edu/projects/smartcard/sectok.html - -(2) enable sectok support in OpenSSH: +(2) If you have used a previous version of ssh with your card, you + must remove the old applet and keys. - $ ./configure --with-sectok[=/path/to/libsectok] [options] + $ sectok + sectok> login -d + sectok> junload Ssh.bin + sectok> delete 0012 + sectok> delete sh + sectok> quit -(3) load the Java Cardlet to the Cyberflex card: +(3) load the Java Cardlet to the Cyberflex card and set card passphrase: $ sectok sectok> login -d sectok> jload /usr/libdata/ssh/Ssh.bin + sectok> setpass + Enter new AUT0 passphrase: + Re-enter passphrase: sectok> quit -(4) load a RSA key to the card: + Do not forget the passphrase. There is no way to + recover if you do. - Please don't use your production RSA keys, since - with the current version of sectok/ssh-keygen - the private key file is still readable. + IMPORTANT WARNING: If you attempt to login with the + wrong passphrase three times in a row, you will + destroy your card. - $ ssh-keygen -f /path/to/rsakey -U <readernum, eg. 0> +(4) load a RSA key to the card: + + $ ssh-keygen -f /path/to/rsakey -U 1 + (where 1 is the reader number, you can also try 0) In spite of the name, this does not generate a key. It just loads an already existing key on to the card. -(5) optional: - - Change the card password so that only you can - read the private key: +(5) Optional: If you don't want to use a card passphrase, change the + acl on the private key file: $ sectok sectok> login -d - sectok> setpass + sectok> acl 0012 world: w + world: w + AUT0: w inval sectok> quit - This prevents reading the key but not use of the - key by the card applet. - - Do not forget the passphrase. There is no way to - recover if you do. + If you do this, anyone who has access to your card + can assume your identity. This is not recommended. - IMPORTANT WARNING: If you attempt to login with the - wrong passphrase three times in a row, you will - destroy your card. -To enable OpenSC support: +Using OpenSC: (1) install OpenSC: @@ -71,15 +75,19 @@ To enable OpenSC support: Not supported yet. -Common smartcard options: + +Common operations: (1) tell the ssh client to use the card reader: - $ ssh -I <readernum, eg. 0> otherhost + $ ssh -I 1 otherhost (2) or tell the agent (don't forget to restart) to use the smartcard: - $ ssh-add -s <readernum, eg. 0> + $ ssh-add -s 1 + -markus, -Sat Apr 13 13:48:10 EEST 2002 +Tue Jul 17 23:54:51 CEST 2001 + +$OpenBSD: README.smartcard,v 1.8 2002/03/26 18:56:23 rees Exp $ diff --git a/crypto/openssh/TODO b/crypto/openssh/TODO index de83000..bca8185 100644 --- a/crypto/openssh/TODO +++ b/crypto/openssh/TODO @@ -1,4 +1,19 @@ +Documentation: + +- Update the docs + - Update README + - Update INSTALL + - Merge INSTALL & README.privsep + +- Install FAQ? + +- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it + would be best to use them. + +- Create a Documentation/ directory? + Programming: + - Grep for 'XXX' comments and fix - Link order is incorrect for some systems using Kerberos 4 and AFS. Result @@ -21,8 +36,9 @@ Programming: and maybe support alternate forms of authentications like OPIE via pam? -- Rework PAM ChallengeResponseAuthentication - - Use kbdint request packet with 0 prompts for informational messages +- Improve PAM ChallengeResponseAuthentication + - Informational messages + - chauthtok - Use different PAM service name for kbdint vs regular auth (suggest from Solar Designer) - Ability to select which ChallengeResponseAuthentications may be used @@ -35,70 +51,17 @@ Programming: - Finish integrating kernel-level auditing code for IRIX and SOLARIS (Gilbert.r.loomis@saic.com) -- sftp-server: Rework to step down to 32bit ints if the platform - lacks 'long long' == 64bit (Notable SCO w/ SCO compiler) - -- Linux hangs for 20 seconds when you do "sleep 20&exit". All current - solutions break scp or leaves processes hanging around after the ssh - connection has ended. It seems to be linked to two things. One - select() under Linux is not as nice as others, and two the children - of the shell are not killed on exiting the shell. - A short run-down of what happens: - - The shell starts up, and starts its own session. As a side-effect, it - gets its own process group. - - The child forks off sleep, and because it's in the background, puts it - into its own process group. The sleep command inherits a copy of the - shell's descriptor for the tty as its stdout. - - The shell exits, but doesn't SIGHUP all of its child PIDs like it probably - should(?) - - The sshd server attempts to read from the master side of the pty, and - while there are still process with the pty open, no EOF is produced. - - The sleep command exits, closes its descriptor, sshd detects the EOF, and - the connection gets closed. - Ways we've tried fixing this in sshd, and why they didn't work out: - - SIGHUP the sshd's process group. - - The shell is in its own process group. - - Track process group IDs of all children before we reap them (via an extra - field in Session structures which holds the pgid for each child pid), and - SIGHUP the pgid when we reap. - - Background commands are in yet another process group. - - Close the connection when the child dies. - - Background commands may need to write data to the connection. Also - prematurely truncates output from some commands (scp server, the - famous "dd if=/dev/zero bs=1000 count=100" case). - Known workarounds: - - bash: shopt huponexit on - - tcsh: none - - zsh: setopt HUP (usually the default setting) - (taken from email from Jason Stone to openssh-unix-dev, 5 May 2001) - - pdksh: ? - This appears to affect NetKit rsh under Linux as well: it behaves the same - with 'sleep 20 & exit'. - -- Build an automated test suite - - 64-bit builds on HP-UX 11.X (stevesk@pobox.com): - utmp/wtmp get corrupted (something in loginrec?) - can't build with PAM (no 64-bit libpam yet) -Documentation: -- More and better - -- Install FAQ? - -- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it - would be best to use them. - -- Create a Documentation/ directory? - Clean up configure/makefiles: - Clean up configure.ac - There are a few double #defined variables left to do. HAVE_LOGIN is one of them. Consider NOT looking for information in wtmpx or utmpx or any of that stuff if it's not detected from the start -- Fails to compile when cross compile. - (vinschen@redhat.com) +- Fails to compile when cross compile. (vinschen@redhat.com) - Replace the whole u_intXX_t evilness in acconfig.h with something better??? - Do it in configure.ac @@ -118,7 +81,6 @@ Packaging: - HP-UX: Provide DEPOT package scripts. (gilbert.r.loomis@saic.com) - PrivSep Issues: - mmap() issues. + /dev/zero solution (Solaris) @@ -127,11 +89,11 @@ PrivSep Issues: - PAM + See above PAM notes - AIX - + usrinfo() does not set TTY, but only required for legicy systems. Works + + usrinfo() does not set TTY, but only required for legacy systems. Works with PrivSep. - OSF + SIA is broken - Cygwin + Privsep for Pre-auth only (no fd passing) -$Id: TODO,v 1.53 2003/01/12 23:00:34 djm Exp $ +$Id: TODO,v 1.55 2003/06/11 13:56:41 dtucker Exp $ diff --git a/crypto/openssh/acconfig.h b/crypto/openssh/acconfig.h index b6e4b37..9bfb9b6 100644 --- a/crypto/openssh/acconfig.h +++ b/crypto/openssh/acconfig.h @@ -1,4 +1,28 @@ -/* $Id: acconfig.h,v 1.149 2003/03/10 00:38:10 djm Exp $ */ +/* $Id: acconfig.h,v 1.166 2003/09/16 01:52:19 dtucker Exp $ */ + +/* + * Copyright (c) 1999-2003 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. + */ #ifndef _CONFIG_H #define _CONFIG_H @@ -8,9 +32,19 @@ @TOP@ +/* Define if your platform breaks doing a seteuid before a setuid */ +#undef SETEUID_BREAKS_SETUID + +/* Define if your setreuid() is broken */ +#undef BROKEN_SETREUID + +/* Define if your setregid() is broken */ +#undef BROKEN_SETREGID + /* Define to a Set Process Title type if your system is */ /* supported by bsd-setproctitle.c */ #undef SPT_TYPE +#undef SPT_PADCHAR /* setgroups() NOOP allowed */ #undef SETGROUPS_NOOP @@ -82,6 +116,9 @@ /* Define if you want to enable AIX4's authenticate function */ #undef WITH_AIXAUTHENTICATE +/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ +#undef AIX_LOGINFAILED_4ARG + /* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ #undef WITH_IRIX_ARRAY @@ -201,18 +238,15 @@ /* Define if compiler implements __func__ */ #undef HAVE___func__ +/* Define this is you want GSSAPI support in the version 2 protocol */ +#undef GSSAPI + /* Define if you want Kerberos 5 support */ #undef KRB5 /* Define this if you are using the Heimdal version of Kerberos V5 */ #undef HEIMDAL -/* Define if you want Kerberos 4 support */ -#undef KRB4 - -/* Define if you want AFS support */ -#undef AFS - /* Define if you want S/Key support */ #undef SKEY @@ -295,9 +329,6 @@ /* Specify location of ssh.pid */ #undef _PATH_SSH_PIDDIR -/* Use IPv4 for connection by default, IPv6 can still if explicity asked */ -#undef IPV4_DEFAULT - /* getaddrinfo is broken (if present) */ #undef BROKEN_GETADDRINFO @@ -328,6 +359,9 @@ /* Define in your struct dirent expects you to allocate extra space for d_name */ #undef BROKEN_ONE_BYTE_DIRENT_D_NAME +/* Define if your system has /etc/default/login */ +#undef HAVE_ETC_DEFAULT_LOGIN + /* Define if your getopt(3) defines and uses optreset */ #undef HAVE_GETOPT_OPTRESET @@ -367,15 +401,28 @@ /* Silly mkstemp() */ #undef HAVE_STRICT_MKSTEMP -/* Setproctitle emulation */ -#undef SETPROCTITLE_STRATEGY -#undef SETPROCTITLE_PS_PADDING - /* Some systems put this outside of libc */ #undef HAVE_NANOSLEEP -/* Pushing STREAMS modules incorrectly acquires a controlling TTY */ -#undef STREAMS_PUSH_ACQUIRES_CTTY +/* Define if sshd somehow reacquires a controlling TTY after setsid() */ +#undef SSHD_ACQUIRES_CTTY + +/* Define if cmsg_type is not passed correctly */ +#undef BROKEN_CMSG_TYPE + +/* Strings used in /etc/passwd to denote locked account */ +#undef LOCKED_PASSWD_STRING +#undef LOCKED_PASSWD_PREFIX +#undef LOCKED_PASSWD_SUBSTR + +/* Define if DNS support is to be activated */ +#undef DNS + +/* Define if getrrsetbyname() exists */ +#undef HAVE_GETRRSETBYNAME + +/* Define if HEADER.ad exists in arpa/nameser.h */ +#undef HAVE_HEADER_AD @BOTTOM@ diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c index 47161eb..7637e16 100644 --- a/crypto/openssh/atomicio.c +++ b/crypto/openssh/atomicio.c @@ -24,16 +24,16 @@ */ #include "includes.h" -RCSID("$OpenBSD: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp $"); +RCSID("$OpenBSD: atomicio.c,v 1.12 2003/07/31 15:50:16 avsm Exp $"); #include "atomicio.h" /* - * ensure all of data on socket comes through. f==read || f==write + * ensure all of data on socket comes through. f==read || f==vwrite */ ssize_t atomicio(f, fd, _s, n) - ssize_t (*f) (); + ssize_t (*f) (int, void *, size_t); int fd; void *_s; size_t n; diff --git a/crypto/openssh/atomicio.h b/crypto/openssh/atomicio.h index e569d38..5c0f392 100644 --- a/crypto/openssh/atomicio.h +++ b/crypto/openssh/atomicio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $ */ +/* $OpenBSD: atomicio.h,v 1.5 2003/06/28 16:23:06 deraadt Exp $ */ /* * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. @@ -26,6 +26,8 @@ */ /* - * Ensure all of data on socket comes through. f==read || f==write + * Ensure all of data on socket comes through. f==read || f==vwrite */ -ssize_t atomicio(ssize_t (*)(), int, void *, size_t); +ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); + +#define vwrite (ssize_t (*)(int, void *, size_t))write diff --git a/crypto/openssh/auth-chall.c b/crypto/openssh/auth-chall.c index 45e0c34..00d6e0e 100644 --- a/crypto/openssh/auth-chall.c +++ b/crypto/openssh/auth-chall.c @@ -76,7 +76,33 @@ verify_response(Authctxt *authctxt, const char *response) return 0; resp[0] = (char *)response; res = device->respond(authctxt->kbdintctxt, 1, resp); + if (res == 1) { + /* postponed - send a null query just in case */ + char *name, *info, **prompts; + u_int i, numprompts, *echo_on; + + res = device->query(authctxt->kbdintctxt, &name, &info, + &numprompts, &prompts, &echo_on); + if (res == 0) { + for (i = 0; i < numprompts; i++) + xfree(prompts[i]); + xfree(prompts); + xfree(name); + xfree(echo_on); + xfree(info); + } + /* if we received more prompts, we're screwed */ + res = (res == 0 && numprompts == 0) ? 0 : -1; + } device->free_ctx(authctxt->kbdintctxt); authctxt->kbdintctxt = NULL; return res ? 0 : 1; } +void +abandon_challenge_response(Authctxt *authctxt) +{ + if (authctxt->kbdintctxt != NULL) { + device->free_ctx(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + } +} diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c index c1a0069..713b6da 100644 --- a/crypto/openssh/auth-krb5.c +++ b/crypto/openssh/auth-krb5.c @@ -28,7 +28,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-krb5.c,v 1.10 2002/11/21 23:03:51 deraadt Exp $"); +RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -40,10 +40,8 @@ RCSID("$OpenBSD: auth-krb5.c,v 1.10 2002/11/21 23:03:51 deraadt Exp $"); #include "auth.h" #ifdef KRB5 + #include <krb5.h> -#ifndef HEIMDAL -#define krb5_get_err_text(context,code) error_message(code) -#endif /* !HEIMDAL */ extern ServerOptions options; @@ -67,193 +65,6 @@ krb5_init(void *context) return (0); } -/* - * Try krb5 authentication. server_user is passed for logging purposes - * only, in auth is received ticket, in client is returned principal - * from the ticket - */ -int -auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply) -{ - krb5_error_code problem; - krb5_principal server; - krb5_ticket *ticket; - int fd, ret; - - ret = 0; - server = NULL; - ticket = NULL; - reply->length = 0; - - problem = krb5_init(authctxt); - 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(); -#ifdef HEIMDAL - problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx, &fd); -#else - problem = krb5_auth_con_genaddrs(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx,fd, - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); -#endif - 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; - -#ifdef HEIMDAL - problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client, - &authctxt->krb5_user); -#else - problem = krb5_copy_principal(authctxt->krb5_ctx, - ticket->enc_part2->client, - &authctxt->krb5_user); -#endif - 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); - - ret = 1; - err: - if (server) - krb5_free_principal(authctxt->krb5_ctx, server); - if (ticket) - krb5_free_ticket(authctxt->krb5_ctx, ticket); - if (!ret && reply->length) { - xfree(reply->data); - memset(reply, 0, sizeof(*reply)); - } - - 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); -} - -int -auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt) -{ - krb5_error_code problem; - krb5_ccache ccache = NULL; - char *pname; - krb5_creds **creds; - - if (authctxt->pw == NULL || authctxt->krb5_user == NULL) - return (0); - - temporarily_use_uid(authctxt->pw); - -#ifdef HEIMDAL - problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache); -#else -{ - char ccname[40]; - int tmpfd; - - snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); - - if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { - log("mkstemp(): %.100s", strerror(errno)); - problem = errno; - goto fail; - } - if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { - log("fchmod(): %.100s", strerror(errno)); - close(tmpfd); - problem = errno; - goto fail; - } - close(tmpfd); - problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &ccache); -} -#endif - if (problem) - goto fail; - - problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, - authctxt->krb5_user); - if (problem) - goto fail; - -#ifdef HEIMDAL - problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - ccache, tgt); - if (problem) - goto fail; -#else - problem = krb5_rd_cred(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - tgt, &creds, NULL); - if (problem) - goto fail; - problem = krb5_cc_store_cred(authctxt->krb5_ctx, ccache, *creds); - if (problem) - goto fail; -#endif - - 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); -} - int auth_krb5_password(Authctxt *authctxt, const char *password) { @@ -264,6 +75,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) int tmpfd; #endif krb5_error_code problem; + krb5_ccache ccache = NULL; if (authctxt->pw == NULL) return (0); @@ -280,23 +92,35 @@ auth_krb5_password(Authctxt *authctxt, const char *password) goto out; #ifdef HEIMDAL - problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, - &authctxt->krb5_fwd_ccache); + problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache); if (problem) goto out; - problem = krb5_cc_initialize(authctxt->krb5_ctx, - authctxt->krb5_fwd_ccache, authctxt->krb5_user); + problem = krb5_cc_initialize(authctxt->krb5_ctx, 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); + ccache, password, 1, NULL); + temporarily_use_uid(authctxt->pw); if (problem) goto out; + problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, + &authctxt->krb5_fwd_ccache); + if (problem) + goto out; + + problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache, + authctxt->krb5_fwd_ccache); + krb5_cc_destroy(authctxt->krb5_ctx, ccache); + ccache = NULL; + if (problem) + goto out; #else problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, @@ -326,13 +150,13 @@ auth_krb5_password(Authctxt *authctxt, const char *password) snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { - log("mkstemp(): %.100s", strerror(errno)); + logit("mkstemp(): %.100s", strerror(errno)); problem = errno; goto out; } if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { - log("fchmod(): %.100s", strerror(errno)); + logit("fchmod(): %.100s", strerror(errno)); close(tmpfd); problem = errno; goto out; @@ -360,6 +184,9 @@ auth_krb5_password(Authctxt *authctxt, const char *password) restore_uid(); if (problem) { + if (ccache) + krb5_cc_destroy(authctxt->krb5_ctx, ccache); + if (authctxt->krb5_ctx != NULL && problem!=-1) debug("Kerberos password authentication failed: %s", krb5_get_err_text(authctxt->krb5_ctx, problem)); @@ -391,11 +218,6 @@ krb5_cleanup_proc(void *context) krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); authctxt->krb5_user = NULL; } - if (authctxt->krb5_auth_ctx) { - krb5_auth_con_free(authctxt->krb5_ctx, - authctxt->krb5_auth_ctx); - authctxt->krb5_auth_ctx = NULL; - } if (authctxt->krb5_ctx) { krb5_free_context(authctxt->krb5_ctx); authctxt->krb5_ctx = NULL; diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c index 8595fdc..0e146ab 100644 --- a/crypto/openssh/auth-options.c +++ b/crypto/openssh/auth-options.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-options.c,v 1.26 2002/07/30 17:03:55 markus Exp $"); +RCSID("$OpenBSD: auth-options.c,v 1.28 2003/06/02 09:17:34 markus Exp $"); #include "xmalloc.h" #include "match.h" @@ -173,7 +173,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.verify_reverse_mapping); + options.use_dns); char *patterns = xmalloc(strlen(opts) + 1); opts += strlen(cp); @@ -201,7 +201,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) if (match_host_and_ip(remote_host, remote_ip, patterns) != 1) { xfree(patterns); - log("Authentication tried for %.100s with " + logit("Authentication tried for %.100s with " "correct key but not from a permitted " "host (host=%.200s, ip=%.200s).", pw->pw_name, remote_host, remote_ip); @@ -287,7 +287,7 @@ next_option: return 1; bad_option: - log("Bad options in %.100s file, line %lu: %.50s", + logit("Bad options in %.100s file, line %lu: %.50s", file, linenum, opts); auth_debug_add("Bad options in %.100s file, line %lu: %.50s", file, linenum, opts); diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c index fe9570f..e2c364e 100644 --- a/crypto/openssh/auth-pam.c +++ b/crypto/openssh/auth-pam.c @@ -1,5 +1,11 @@ -/* - * Copyright (c) 2000 Damien Miller. All rights reserved. +/*- + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by ThinkSec AS and + * NAI Labs, the Security Research Division of Network Associates, Inc. + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the + * DARPA CHATS research program. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,446 +16,730 @@ * 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. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ +/* Based on $FreeBSD$ */ #include "includes.h" +RCSID("$Id: auth-pam.c,v 1.72.2.2 2003/09/23 09:24:21 djm Exp $"); #ifdef USE_PAM -#include "xmalloc.h" -#include "log.h" +#include <security/pam_appl.h> + #include "auth.h" -#include "auth-options.h" #include "auth-pam.h" -#include "servconf.h" +#include "buffer.h" +#include "bufaux.h" #include "canohost.h" +#include "log.h" +#include "monitor_wrap.h" +#include "msg.h" +#include "packet.h" #include "readpass.h" +#include "servconf.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "auth-options.h" -extern char *__progname; +extern ServerOptions options; -extern int use_privsep; +#define __unused -RCSID("$Id: auth-pam.c,v 1.55 2003/01/22 04:42:26 djm Exp $"); +#ifdef USE_POSIX_THREADS +#include <pthread.h> +/* + * Avoid namespace clash when *not* using pthreads for systems *with* + * pthreads, which unconditionally define pthread_t via sys/types.h + * (e.g. Linux) + */ +typedef pthread_t sp_pthread_t; +#else +/* + * Simulate threads with processes. + */ +typedef pid_t sp_pthread_t; -#define NEW_AUTHTOK_MSG \ - "Warning: Your password has expired, please change it now." -#define NEW_AUTHTOK_MSG_PRIVSEP \ - "Your password has expired, the session cannot proceed." +static void +pthread_exit(void *value __unused) +{ + _exit(0); +} -static int do_pam_conversation(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr); +static int +pthread_create(sp_pthread_t *thread, const void *attr __unused, + void *(*thread_start)(void *), void *arg) +{ + pid_t pid; + + switch ((pid = fork())) { + case -1: + error("fork(): %s", strerror(errno)); + return (-1); + case 0: + thread_start(arg); + _exit(1); + default: + *thread = pid; + return (0); + } +} -/* module-local variables */ -static struct pam_conv conv = { - (int (*)())do_pam_conversation, - NULL -}; -static char *__pam_msg = NULL; -static pam_handle_t *__pamh = NULL; -static const char *__pampasswd = NULL; - -/* states for do_pam_conversation() */ -enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; -/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */ -static int password_change_required = 0; -/* remember whether the last pam_authenticate() succeeded or not */ -static int was_authenticated = 0; - -/* Remember what has been initialised */ -static int session_opened = 0; -static int creds_set = 0; - -/* accessor which allows us to switch conversation structs according to - * the authentication method being used */ -void do_pam_set_conv(struct pam_conv *conv) +static int +pthread_cancel(sp_pthread_t thread) { - pam_set_item(__pamh, PAM_CONV, conv); + return (kill(thread, SIGTERM)); } -/* start an authentication run */ -int do_pam_authenticate(int flags) +static int +pthread_join(sp_pthread_t thread, void **value __unused) { - int retval = pam_authenticate(__pamh, flags); - was_authenticated = (retval == PAM_SUCCESS); - return retval; + int status; + + waitpid(thread, &status, 0); + return (status); } +#endif + + +static pam_handle_t *sshpam_handle = NULL; +static int sshpam_err = 0; +static int sshpam_authenticated = 0; +static int sshpam_new_authtok_reqd = 0; +static int sshpam_session_open = 0; +static int sshpam_cred_established = 0; + +struct pam_ctxt { + sp_pthread_t pam_thread; + int pam_psock; + int pam_csock; + int pam_done; +}; + +static void sshpam_free_ctx(void *); /* - * PAM conversation function. - * There are two states this can run in. - * - * INITIAL_LOGIN mode simply feeds the password from the client into - * PAM in response to PAM_PROMPT_ECHO_OFF, and collects output - * messages with into __pam_msg. This is used during initial - * authentication to bypass the normal PAM password prompt. - * - * OTHER mode handles PAM_PROMPT_ECHO_OFF with read_passphrase() - * and outputs messages to stderr. This mode is used if pam_chauthtok() - * is called to update expired passwords. + * Conversation function for authentication thread. */ -static int do_pam_conversation(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr) +static int +sshpam_thread_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { + Buffer buffer; + struct pam_ctxt *ctxt; struct pam_response *reply; - int count; - char buf[1024]; - - /* PAM will free this later */ - reply = xmalloc(num_msg * sizeof(*reply)); - - for (count = 0; count < num_msg; count++) { - if (pamstate == INITIAL_LOGIN) { - /* - * We can't use stdio yet, queue messages for - * printing later - */ - switch(PAM_MSG_MEMBER(msg, count, msg_style)) { - case PAM_PROMPT_ECHO_ON: - xfree(reply); - return PAM_CONV_ERR; - case PAM_PROMPT_ECHO_OFF: - if (__pampasswd == NULL) { - xfree(reply); - return PAM_CONV_ERR; - } - reply[count].resp = xstrdup(__pampasswd); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - if (PAM_MSG_MEMBER(msg, count, msg) != NULL) { - message_cat(&__pam_msg, - PAM_MSG_MEMBER(msg, count, msg)); - } - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - default: - xfree(reply); - return PAM_CONV_ERR; - } - } else { - /* - * stdio is connected, so interact directly - */ - switch(PAM_MSG_MEMBER(msg, count, msg_style)) { - case PAM_PROMPT_ECHO_ON: - fputs(PAM_MSG_MEMBER(msg, count, msg), stderr); - fgets(buf, sizeof(buf), stdin); - reply[count].resp = xstrdup(buf); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_PROMPT_ECHO_OFF: - reply[count].resp = - read_passphrase(PAM_MSG_MEMBER(msg, count, - msg), RP_ALLOW_STDIN); - reply[count].resp_retcode = PAM_SUCCESS; - break; - case PAM_ERROR_MSG: - case PAM_TEXT_INFO: - if (PAM_MSG_MEMBER(msg, count, msg) != NULL) - fprintf(stderr, "%s\n", - PAM_MSG_MEMBER(msg, count, msg)); - reply[count].resp = xstrdup(""); - reply[count].resp_retcode = PAM_SUCCESS; - break; - default: - xfree(reply); - return PAM_CONV_ERR; - } + int i; + + *resp = NULL; + + ctxt = data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + + if ((reply = malloc(n * sizeof(*reply))) == NULL) + return (PAM_CONV_ERR); + memset(reply, 0, n * sizeof(*reply)); + + buffer_init(&buffer); + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + ssh_msg_recv(ctxt->pam_csock, &buffer); + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + reply[i].resp = buffer_get_string(&buffer, NULL); + break; + case PAM_PROMPT_ECHO_ON: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + ssh_msg_recv(ctxt->pam_csock, &buffer); + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + reply[i].resp = buffer_get_string(&buffer, NULL); + break; + case PAM_ERROR_MSG: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + break; + case PAM_TEXT_INFO: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + break; + default: + goto fail; } + buffer_clear(&buffer); } - + buffer_free(&buffer); *resp = reply; + return (PAM_SUCCESS); - return PAM_SUCCESS; + fail: + for(i = 0; i < n; i++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(reply); + buffer_free(&buffer); + return (PAM_CONV_ERR); } -/* Called at exit to cleanly shutdown PAM */ -void do_pam_cleanup_proc(void *context) +/* + * Authentication thread. + */ +static void * +sshpam_thread(void *ctxtp) { - int pam_retval = PAM_SUCCESS; + struct pam_ctxt *ctxt = ctxtp; + Buffer buffer; + struct pam_conv sshpam_conv; +#ifndef USE_POSIX_THREADS + const char *pam_user; + + pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); + setproctitle("%s [pam]", pam_user); +#endif - if (__pamh && session_opened) { - pam_retval = pam_close_session(__pamh, 0); - if (pam_retval != PAM_SUCCESS) - log("Cannot close PAM session[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } + sshpam_conv.conv = sshpam_thread_conv; + sshpam_conv.appdata_ptr = ctxt; + + buffer_init(&buffer); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&sshpam_conv); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + sshpam_err = pam_authenticate(sshpam_handle, 0); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + buffer_put_cstring(&buffer, "OK"); + ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + auth_fail: + buffer_put_cstring(&buffer, + pam_strerror(sshpam_handle, sshpam_err)); + ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + return (NULL); /* Avoid warning for non-pthread case */ +} - if (__pamh && creds_set) { - pam_retval = pam_setcred(__pamh, PAM_DELETE_CRED); - if (pam_retval != PAM_SUCCESS) - debug("Cannot delete credentials[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } +static void +sshpam_thread_cleanup(void *ctxtp) +{ + struct pam_ctxt *ctxt = ctxtp; - if (__pamh) { - pam_retval = pam_end(__pamh, pam_retval); - if (pam_retval != PAM_SUCCESS) - log("Cannot release PAM authentication[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } + pthread_cancel(ctxt->pam_thread); + pthread_join(ctxt->pam_thread, NULL); + close(ctxt->pam_psock); + close(ctxt->pam_csock); } -/* Attempt password authentation using PAM */ -int auth_pam_password(Authctxt *authctxt, const char *password) +static int +sshpam_null_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) { - extern ServerOptions options; - int pam_retval; - struct passwd *pw = authctxt->pw; + return (PAM_CONV_ERR); +} - do_pam_set_conv(&conv); +static struct pam_conv null_conv = { sshpam_null_conv, NULL }; - __pampasswd = password; +static void +sshpam_cleanup(void *arg) +{ + (void)arg; + debug("PAM: cleanup"); + if (sshpam_handle == NULL) + return; + pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); + if (sshpam_cred_established) { + pam_setcred(sshpam_handle, PAM_DELETE_CRED); + sshpam_cred_established = 0; + } + if (sshpam_session_open) { + pam_close_session(sshpam_handle, PAM_SILENT); + sshpam_session_open = 0; + } + sshpam_authenticated = sshpam_new_authtok_reqd = 0; + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; +} - pamstate = INITIAL_LOGIN; - pam_retval = do_pam_authenticate( - options.permit_empty_passwd == 0 ? PAM_DISALLOW_NULL_AUTHTOK : 0); - if (pam_retval == PAM_SUCCESS) { - debug("PAM Password authentication accepted for " - "user \"%.100s\"", pw->pw_name); - return 1; - } else { - debug("PAM Password authentication for \"%.100s\" " - "failed[%d]: %s", pw->pw_name, pam_retval, - PAM_STRERROR(__pamh, pam_retval)); - return 0; +static int +sshpam_init(const char *user) +{ + extern u_int utmp_len; + extern char *__progname; + const char *pam_rhost, *pam_user; + + if (sshpam_handle != NULL) { + /* We already have a PAM context; check if the user matches */ + sshpam_err = pam_get_item(sshpam_handle, + PAM_USER, (const void **)&pam_user); + if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) + return (0); + fatal_remove_cleanup(sshpam_cleanup, NULL); + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; } + debug("PAM: initializing for \"%s\"", user); + sshpam_err = + pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } + pam_rhost = get_remote_name_or_ip(utmp_len, options.use_dns); + debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); + sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } +#ifdef PAM_TTY_KLUDGE + /* + * Some silly PAM modules (e.g. pam_time) require a TTY to operate. + * sshd doesn't set the tty until too late in the auth process and + * may not even set one (for tty-less connections) + */ + debug("PAM: setting PAM_TTY to \"ssh\""); + sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh"); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } +#endif + fatal_add_cleanup(sshpam_cleanup, NULL); + return (0); } -/* Do account management using PAM */ -int do_pam_account(char *username, char *remote_user) +static void * +sshpam_init_ctx(Authctxt *authctxt) { - int pam_retval; + struct pam_ctxt *ctxt; + int socks[2]; - do_pam_set_conv(&conv); + /* Refuse to start if we don't have PAM enabled */ + if (!options.use_pam) + return NULL; - if (remote_user) { - debug("PAM setting ruser to \"%.200s\"", remote_user); - pam_retval = pam_set_item(__pamh, PAM_RUSER, remote_user); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set ruser failed[%d]: %.200s", pam_retval, - PAM_STRERROR(__pamh, pam_retval)); + /* Initialize PAM */ + if (sshpam_init(authctxt->user) == -1) { + error("PAM: initialization failed"); + return (NULL); } - pam_retval = pam_acct_mgmt(__pamh, 0); - debug2("pam_acct_mgmt() = %d", pam_retval); - switch (pam_retval) { - case PAM_SUCCESS: - /* This is what we want */ - break; -#if 0 - case PAM_NEW_AUTHTOK_REQD: - message_cat(&__pam_msg, use_privsep ? - NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG); - /* flag that password change is necessary */ - password_change_required = 1; - /* disallow other functionality for now */ - no_port_forwarding_flag |= 2; - no_agent_forwarding_flag |= 2; - no_x11_forwarding_flag |= 2; + ctxt = xmalloc(sizeof *ctxt); + ctxt->pam_done = 0; + + /* Start the authentication thread */ + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { + error("PAM: failed create sockets: %s", strerror(errno)); + xfree(ctxt); + return (NULL); + } + ctxt->pam_psock = socks[0]; + ctxt->pam_csock = socks[1]; + if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) { + error("PAM: failed to start authentication thread: %s", + strerror(errno)); + close(socks[0]); + close(socks[1]); + xfree(ctxt); + return (NULL); + } + fatal_add_cleanup(sshpam_thread_cleanup, ctxt); + return (ctxt); +} + +static int +sshpam_query(void *ctx, char **name, char **info, + u_int *num, char ***prompts, u_int **echo_on) +{ + Buffer buffer; + struct pam_ctxt *ctxt = ctx; + size_t plen; + u_char type; + char *msg; + size_t len; + + buffer_init(&buffer); + *name = xstrdup(""); + *info = xstrdup(""); + *prompts = xmalloc(sizeof(char *)); + **prompts = NULL; + plen = 0; + *echo_on = xmalloc(sizeof(u_int)); + while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { + type = buffer_get_char(&buffer); + msg = buffer_get_string(&buffer, NULL); + switch (type) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + *num = 1; + len = plen + strlen(msg) + 1; + **prompts = xrealloc(**prompts, len); + plen += snprintf(**prompts + plen, len, "%s", msg); + **echo_on = (type == PAM_PROMPT_ECHO_ON); + xfree(msg); + return (0); + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + /* accumulate messages */ + len = plen + strlen(msg) + 1; + **prompts = xrealloc(**prompts, len); + plen += snprintf(**prompts + plen, len, "%s", msg); + xfree(msg); break; + case PAM_SUCCESS: + case PAM_AUTH_ERR: + if (**prompts != NULL) { + /* drain any accumulated messages */ +#if 0 /* XXX - not compatible with privsep */ + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(**prompts); + packet_put_cstring(""); + packet_send(); + packet_write_wait(); #endif + xfree(**prompts); + **prompts = NULL; + } + if (type == PAM_SUCCESS) { + *num = 0; + **echo_on = 0; + ctxt->pam_done = 1; + xfree(msg); + return (0); + } + error("PAM: %s", msg); default: - log("PAM rejected by account configuration[%d]: " - "%.200s", pam_retval, PAM_STRERROR(__pamh, - pam_retval)); - return(0); + *num = 0; + **echo_on = 0; + xfree(msg); + ctxt->pam_done = -1; + return (-1); + } } + return (-1); +} - return(1); +/* XXX - see also comment in auth-chall.c:verify_response */ +static int +sshpam_respond(void *ctx, u_int num, char **resp) +{ + Buffer buffer; + struct pam_ctxt *ctxt = ctx; + + debug2("PAM: %s", __func__); + switch (ctxt->pam_done) { + case 1: + sshpam_authenticated = 1; + return (0); + case 0: + break; + default: + return (-1); + } + if (num != 1) { + error("PAM: expected one response, got %u", num); + return (-1); + } + buffer_init(&buffer); + buffer_put_cstring(&buffer, *resp); + ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer); + buffer_free(&buffer); + return (1); } -/* Do PAM-specific session initialisation */ -void do_pam_session(char *username, const char *ttyname) +static void +sshpam_free_ctx(void *ctxtp) { - int pam_retval; + struct pam_ctxt *ctxt = ctxtp; - do_pam_set_conv(&conv); + fatal_remove_cleanup(sshpam_thread_cleanup, ctxt); + sshpam_thread_cleanup(ctxtp); + xfree(ctxt); + /* + * We don't call sshpam_cleanup() here because we may need the PAM + * handle at a later stage, e.g. when setting up a session. It's + * still on the cleanup list, so pam_end() *will* be called before + * the server process terminates. + */ +} - if (ttyname != NULL) { - debug("PAM setting tty to \"%.200s\"", ttyname); - pam_retval = pam_set_item(__pamh, PAM_TTY, ttyname); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set tty failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } +KbdintDevice sshpam_device = { + "pam", + sshpam_init_ctx, + sshpam_query, + sshpam_respond, + sshpam_free_ctx +}; + +KbdintDevice mm_sshpam_device = { + "pam", + mm_sshpam_init_ctx, + mm_sshpam_query, + mm_sshpam_respond, + mm_sshpam_free_ctx +}; - pam_retval = pam_open_session(__pamh, 0); - if (pam_retval != PAM_SUCCESS) - fatal("PAM session setup failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); +/* + * This replaces auth-pam.c + */ +void +start_pam(const char *user) +{ + if (!options.use_pam) + fatal("PAM: initialisation requested when UsePAM=no"); - session_opened = 1; + if (sshpam_init(user) == -1) + fatal("PAM: initialisation failed"); } -/* Set PAM credentials */ -void do_pam_setcred(int init) +void +finish_pam(void) { - int pam_retval; + fatal_remove_cleanup(sshpam_cleanup, NULL); + sshpam_cleanup(NULL); +} - if (__pamh == NULL) - return; +u_int +do_pam_account(void) +{ + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); + debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); + + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) + return (0); + + if (sshpam_err == PAM_NEW_AUTHTOK_REQD) { + sshpam_new_authtok_reqd = 1; + + /* Prevent forwardings until password changed */ + no_port_forwarding_flag |= 2; + no_agent_forwarding_flag |= 2; + no_x11_forwarding_flag |= 2; + } - do_pam_set_conv(&conv); - - debug("PAM establishing creds"); - pam_retval = pam_setcred(__pamh, - init ? PAM_ESTABLISH_CRED : PAM_REINITIALIZE_CRED); - if (pam_retval != PAM_SUCCESS) { - if (was_authenticated) - fatal("PAM setcred failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - else - debug("PAM setcred failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); - } else - creds_set = 1; + return (1); } -/* accessor function for file scope static variable */ -int is_pam_password_change_required(void) +void +do_pam_session(void) { - return password_change_required; + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&null_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + sshpam_err = pam_open_session(sshpam_handle, 0); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: pam_open_session(): %s", + pam_strerror(sshpam_handle, sshpam_err)); + sshpam_session_open = 1; } -/* - * Have user change authentication token if pam_acct_mgmt() indicated - * it was expired. This needs to be called after an interactive - * session is established and the user's pty is connected to - * stdin/stdout/stderr. - */ -void do_pam_chauthtok(void) +void +do_pam_set_tty(const char *tty) { - int pam_retval; - - do_pam_set_conv(&conv); - - if (password_change_required) { - if (use_privsep) - fatal("Password changing is currently unsupported" - " with privilege separation"); - pamstate = OTHER; - pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); - if (pam_retval != PAM_SUCCESS) - fatal("PAM pam_chauthtok failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); -#if 0 - /* XXX: This would need to be done in the parent process, - * but there's currently no way to pass such request. */ - no_port_forwarding_flag &= ~2; - no_agent_forwarding_flag &= ~2; - no_x11_forwarding_flag &= ~2; - if (!no_port_forwarding_flag && options.allow_tcp_forwarding) - channel_permit_all_opens(); -#endif + if (tty != NULL) { + debug("PAM: setting PAM_TTY to \"%s\"", tty); + sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_TTY: %s", + pam_strerror(sshpam_handle, sshpam_err)); } } -/* Cleanly shutdown PAM */ -void finish_pam(void) +void +do_pam_setcred(int init) { - do_pam_cleanup_proc(NULL); - fatal_remove_cleanup(&do_pam_cleanup_proc, NULL); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&null_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + if (init) { + debug("PAM: establishing credentials"); + sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED); + } else { + debug("PAM: reinitializing credentials"); + sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED); + } + if (sshpam_err == PAM_SUCCESS) { + sshpam_cred_established = 1; + return; + } + if (sshpam_authenticated) + fatal("PAM: pam_setcred(): %s", + pam_strerror(sshpam_handle, sshpam_err)); + else + debug("PAM: pam_setcred(): %s", + pam_strerror(sshpam_handle, sshpam_err)); } -/* Start PAM authentication for specified account */ -void start_pam(const char *user) +int +is_pam_password_change_required(void) { - int pam_retval; - extern ServerOptions options; - extern u_int utmp_len; - const char *rhost; + return (sshpam_new_authtok_reqd); +} - debug("Starting up PAM with username \"%.200s\"", user); +static int +pam_chauthtok_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + char input[PAM_MAX_MSG_SIZE]; + struct pam_response *reply; + int i; - pam_retval = pam_start(SSHD_PAM_SERVICE, user, &conv, &__pamh); + *resp = NULL; - if (pam_retval != PAM_SUCCESS) - fatal("PAM initialisation failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); - rhost = get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping); - debug("PAM setting rhost to \"%.200s\"", rhost); + if ((reply = malloc(n * sizeof(*reply))) == NULL) + return (PAM_CONV_ERR); + memset(reply, 0, n * sizeof(*reply)); - pam_retval = pam_set_item(__pamh, PAM_RHOST, rhost); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set rhost failed[%d]: %.200s", pam_retval, - PAM_STRERROR(__pamh, pam_retval)); -#ifdef PAM_TTY_KLUDGE - /* - * Some PAM modules (e.g. pam_time) require a TTY to operate, - * and will fail in various stupid ways if they don't get one. - * sshd doesn't set the tty until too late in the auth process and may - * not even need one (for tty-less connections) - * Kludge: Set a fake PAM_TTY - */ - pam_retval = pam_set_item(__pamh, PAM_TTY, "NODEVssh"); - if (pam_retval != PAM_SUCCESS) - fatal("PAM set tty failed[%d]: %.200s", - pam_retval, PAM_STRERROR(__pamh, pam_retval)); -#endif /* PAM_TTY_KLUDGE */ + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + reply[i].resp = + read_passphrase(PAM_MSG_MEMBER(msg, i, msg), + RP_ALLOW_STDIN); + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_ON: + fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); + fgets(input, sizeof input, stdin); + reply[i].resp = xstrdup(input); + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); + reply[i].resp_retcode = PAM_SUCCESS; + break; + default: + goto fail; + } + } + *resp = reply; + return (PAM_SUCCESS); - fatal_add_cleanup(&do_pam_cleanup_proc, NULL); + fail: + for(i = 0; i < n; i++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(reply); + return (PAM_CONV_ERR); } -/* Return list of PAM environment strings */ -char **fetch_pam_environment(void) +/* + * XXX this should be done in the authentication phase, but ssh1 doesn't + * support that + */ +void +do_pam_chauthtok(void) { -#ifdef HAVE_PAM_GETENVLIST - return(pam_getenvlist(__pamh)); -#else /* HAVE_PAM_GETENVLIST */ - return(NULL); -#endif /* HAVE_PAM_GETENVLIST */ + struct pam_conv pam_conv; + + pam_conv.conv = pam_chauthtok_conv; + pam_conv.appdata_ptr = NULL; + + if (use_privsep) + fatal("Password expired (unable to change with privsep)"); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&pam_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + debug("PAM: changing password"); + sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: pam_chauthtok(): %s", + pam_strerror(sshpam_handle, sshpam_err)); } -void free_pam_environment(char **env) +/* + * Set a PAM environment string. We need to do this so that the session + * modules can handle things like Kerberos/GSI credentials that appear + * during the ssh authentication process. + */ + +int +do_pam_putenv(char *name, char *value) { - int i; + int ret = 1; +#ifdef HAVE_PAM_PUTENV + char *compound; + size_t len; - if (env != NULL) { - for (i = 0; env[i] != NULL; i++) - xfree(env[i]); - } + len = strlen(name) + strlen(value) + 2; + compound = xmalloc(len); + + snprintf(compound, len, "%s=%s", name, value); + ret = pam_putenv(sshpam_handle, compound); + xfree(compound); +#endif + + return (ret); } -/* Print any messages that have been generated during authentication */ -/* or account checking to stderr */ -void print_pam_messages(void) +void +print_pam_messages(void) { - if (__pam_msg != NULL) - fputs(__pam_msg, stderr); + /* XXX */ } -/* Append a message to buffer */ -void message_cat(char **p, const char *a) +char ** +fetch_pam_environment(void) { - char *cp; - size_t new_len; - - new_len = strlen(a); +#ifdef HAVE_PAM_GETENVLIST + debug("PAM: retrieving environment"); + return (pam_getenvlist(sshpam_handle)); +#else + return (NULL); +#endif +} - if (*p) { - size_t len = strlen(*p); +void +free_pam_environment(char **env) +{ + char **envp; - *p = xrealloc(*p, new_len + len + 2); - cp = *p + len; - } else - *p = cp = xmalloc(new_len + 2); + if (env == NULL) + return; - memcpy(cp, a, new_len); - cp[new_len] = '\n'; - cp[new_len + 1] = '\0'; + for (envp = env; *envp; envp++) + xfree(*envp); + xfree(env); } #endif /* USE_PAM */ diff --git a/crypto/openssh/auth-pam.h b/crypto/openssh/auth-pam.h index 7881b6b..5c952f3 100644 --- a/crypto/openssh/auth-pam.h +++ b/crypto/openssh/auth-pam.h @@ -1,4 +1,4 @@ -/* $Id: auth-pam.h,v 1.16 2002/07/23 00:44:07 stevesk Exp $ */ +/* $Id: auth-pam.h,v 1.21 2003/09/02 13:18:53 djm Exp $ */ /* * Copyright (c) 2000 Damien Miller. All rights reserved. @@ -31,19 +31,17 @@ # define SSHD_PAM_SERVICE __progname #endif -void start_pam(const char *user); +void start_pam(const char *); void finish_pam(void); -int auth_pam_password(Authctxt *authctxt, const char *password); -char **fetch_pam_environment(void); -void free_pam_environment(char **env); -int do_pam_authenticate(int flags); -int do_pam_account(char *username, char *remote_user); -void do_pam_session(char *username, const char *ttyname); -void do_pam_setcred(int init); -void print_pam_messages(void); +u_int do_pam_account(void); +void do_pam_session(void); +void do_pam_set_tty(const char *); +void do_pam_setcred(int ); int is_pam_password_change_required(void); void do_pam_chauthtok(void); -void do_pam_set_conv(struct pam_conv *); -void message_cat(char **p, const char *a); +int do_pam_putenv(char *, char *); +void print_pam_messages(void); +char ** fetch_pam_environment(void); +void free_pam_environment(char **); #endif /* USE_PAM */ diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c index 9901d48..971c7ba 100644 --- a/crypto/openssh/auth-passwd.c +++ b/crypto/openssh/auth-passwd.c @@ -36,55 +36,20 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); +RCSID("$OpenBSD: auth-passwd.c,v 1.29 2003/08/26 09:58:43 markus Exp $"); #include "packet.h" #include "log.h" #include "servconf.h" #include "auth.h" - -#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) -/* Don't need any of these headers for the PAM or SIA cases */ -# ifdef HAVE_CRYPT_H -# include <crypt.h> -# endif -# ifdef WITH_AIXAUTHENTICATE -# include <login.h> -# endif -# ifdef __hpux -# include <hpsecurity.h> -# include <prot.h> -# endif -# ifdef HAVE_SECUREWARE -# include <sys/security.h> -# include <sys/audit.h> -# include <prot.h> -# endif /* HAVE_SECUREWARE */ -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) -# include <shadow.h> -# endif -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) -# include <sys/label.h> -# include <sys/audit.h> -# include <pwdadj.h> -# endif -# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) -# include "md5crypt.h" -# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ - -# ifdef HAVE_CYGWIN -# undef ERROR -# include <windows.h> -# include <sys/cygwin.h> -# define is_winnt (GetVersion() < 0x80000000) -# endif -#endif /* !USE_PAM && !HAVE_OSF_SIA */ - -extern ServerOptions options; #ifdef WITH_AIXAUTHENTICATE -extern char *aixloginmsg; +# include "buffer.h" +# include "canohost.h" +extern Buffer loginmsg; #endif +extern ServerOptions options; + /* * Tries to authenticate the user using password. Returns true if * authentication succeeds. @@ -93,46 +58,26 @@ int auth_password(Authctxt *authctxt, const char *password) { struct passwd * pw = authctxt->pw; -#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) - char *encrypted_password; - char *pw_password; - char *salt; -# if defined(__hpux) || defined(HAVE_SECUREWARE) - struct pr_passwd *spw; -# endif /* __hpux || HAVE_SECUREWARE */ -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) - struct spwd *spw; -# endif -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) - struct passwd_adjunct *spw; -# endif -# ifdef WITH_AIXAUTHENTICATE - char *authmsg; - int authsuccess; - int reenter = 1; -# endif -#endif /* !defined(USE_PAM) && !defined(HAVE_OSF_SIA) */ + int ok = authctxt->valid; /* deny if no user. */ if (pw == NULL) return 0; #ifndef HAVE_CYGWIN - if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) - return 0; + if (pw && pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) + ok = 0; #endif if (*password == '\0' && options.permit_empty_passwd == 0) return 0; -#if defined(USE_PAM) - return auth_pam_password(authctxt, password); -#elif defined(HAVE_OSF_SIA) - return auth_sia_password(authctxt, password); +#if defined(HAVE_OSF_SIA) + return auth_sia_password(authctxt, password) && ok; #else # ifdef KRB5 if (options.kerberos_authentication == 1) { int ret = auth_krb5_password(authctxt, password); if (ret == 1 || ret == 0) - return ret; + return ret && ok; /* Fall back to ordinary passwd authentication. */ } # endif @@ -143,27 +88,47 @@ auth_password(Authctxt *authctxt, const char *password) if (hToken == INVALID_HANDLE_VALUE) return 0; cygwin_set_impersonation_token(hToken); - return 1; + return ok; } # endif # ifdef WITH_AIXAUTHENTICATE - authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); - - if (authsuccess) - /* We don't have a pty yet, so just label the line as "ssh" */ - if (loginsuccess(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh", &aixloginmsg) < 0) - aixloginmsg = NULL; - - return(authsuccess); -# endif -# ifdef KRB4 - if (options.kerberos_authentication == 1) { - int ret = auth_krb4_password(authctxt, password); - if (ret == 1 || ret == 0) - return ret; - /* Fall back to ordinary passwd authentication. */ + { + char *authmsg = NULL; + int reenter = 1; + int authsuccess = 0; + + if (authenticate(pw->pw_name, password, &reenter, + &authmsg) == 0 && ok) { + char *msg; + char *host = + (char *)get_canonical_hostname(options.use_dns); + + authsuccess = 1; + aix_remove_embedded_newlines(authmsg); + + debug3("AIX/authenticate succeeded for user %s: %.100s", + pw->pw_name, authmsg); + + /* No pty yet, so just label the line as "ssh" */ + aix_setauthdb(authctxt->user); + if (loginsuccess(authctxt->user, host, "ssh", + &msg) == 0) { + if (msg != NULL) { + debug("%s: msg %s", __func__, msg); + buffer_append(&loginmsg, msg, + strlen(msg)); + xfree(msg); + } + } + } else { + debug3("AIX/authenticate failed for user %s: %.100s", + pw->pw_name, authmsg); + } + + if (authmsg != NULL) + xfree(authmsg); + + return authsuccess; } # endif # ifdef BSD_AUTH @@ -171,64 +136,28 @@ auth_password(Authctxt *authctxt, const char *password) (char *)password) == 0) return 0; else - return 1; -# endif - pw_password = pw->pw_passwd; - - /* - * Various interfaces to shadow or protected password data - */ -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) - spw = getspnam(pw->pw_name); - if (spw != NULL) - pw_password = spw->sp_pwdp; -# endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ - -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) - if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) - pw_password = spw->pwa_passwd; -# endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ - -# ifdef HAVE_SECUREWARE - if ((spw = getprpwnam(pw->pw_name)) != NULL) - pw_password = spw->ufld.fd_encrypt; -# endif /* HAVE_SECUREWARE */ - -# if defined(__hpux) && !defined(HAVE_SECUREWARE) - if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) - pw_password = spw->ufld.fd_encrypt; -# endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */ + return ok; +# else + { + /* Just use the supplied fake password if authctxt is invalid */ + char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; /* Check for users with no password. */ - if ((password[0] == '\0') && (pw_password[0] == '\0')) - return 1; - - if (pw_password[0] != '\0') - salt = pw_password; - else - salt = "xx"; + if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) + return ok; + else { + /* Encrypt the candidate password using the proper salt. */ + char *encrypted_password = xcrypt(password, + (pw_password[0] && pw_password[1]) ? pw_password : "xx"); + + /* + * Authentication is accepted if the encrypted passwords + * are identical. + */ + return (strcmp(encrypted_password, pw_password) == 0) && ok; + } -# ifdef HAVE_MD5_PASSWORDS - if (is_md5_salt(salt)) - encrypted_password = md5_crypt(password, salt); - else - encrypted_password = crypt(password, salt); -# else /* HAVE_MD5_PASSWORDS */ -# if defined(__hpux) && !defined(HAVE_SECUREWARE) - if (iscomsec()) - encrypted_password = bigcrypt(password, salt); - else - encrypted_password = crypt(password, salt); -# else -# ifdef HAVE_SECUREWARE - encrypted_password = bigcrypt(password, salt); -# else - encrypted_password = crypt(password, salt); -# endif /* HAVE_SECUREWARE */ -# endif /* __hpux && !defined(HAVE_SECUREWARE) */ -# endif /* HAVE_MD5_PASSWORDS */ - - /* Authentication is accepted if the encrypted passwords are identical. */ - return (strcmp(encrypted_password, pw_password) == 0); -#endif /* !USE_PAM && !HAVE_OSF_SIA */ + } +# endif +#endif /* !HAVE_OSF_SIA */ } diff --git a/crypto/openssh/auth-rh-rsa.c b/crypto/openssh/auth-rh-rsa.c index d7848d0..2eb7e6e 100644 --- a/crypto/openssh/auth-rh-rsa.c +++ b/crypto/openssh/auth-rh-rsa.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rh-rsa.c,v 1.34 2002/03/25 09:25:06 markus Exp $"); +RCSID("$OpenBSD: auth-rh-rsa.c,v 1.36 2003/06/02 09:17:34 markus Exp $"); #include "packet.h" #include "uidswap.h" @@ -63,7 +63,7 @@ auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key) client_host_key->rsa == NULL) return 0; - chost = (char *)get_canonical_hostname(options.verify_reverse_mapping); + chost = (char *)get_canonical_hostname(options.use_dns); debug("Rhosts RSA authentication: canonical host %.900s", chost); if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) { @@ -75,7 +75,7 @@ auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key) /* Perform the challenge-response dialog with the client for the host key. */ if (!auth_rsa_challenge_dialog(client_host_key)) { - log("Client on %.800s failed to respond correctly to host authentication.", + logit("Client on %.800s failed to respond correctly to host authentication.", chost); return 0; } diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c index afca1f7..b42a64c 100644 --- a/crypto/openssh/auth-rhosts.c +++ b/crypto/openssh/auth-rhosts.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $"); +RCSID("$OpenBSD: auth-rhosts.c,v 1.31 2003/06/02 09:17:34 markus Exp $"); #include "packet.h" #include "uidswap.h" @@ -68,7 +68,8 @@ check_rhosts_file(const char *filename, const char *hostname, * This should be safe because each buffer is as big as the * whole string, and thus cannot be overwritten. */ - switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) { + switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf, + dummy)) { case 0: auth_debug_add("Found empty line in %.100s.", filename); continue; @@ -155,7 +156,7 @@ auth_rhosts(struct passwd *pw, const char *client_user) { const char *hostname, *ipaddr; - hostname = get_canonical_hostname(options.verify_reverse_mapping); + hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); return auth_rhosts2(pw, client_user, hostname, ipaddr); } @@ -220,7 +221,7 @@ auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostnam * not group or world writable. */ if (stat(pw->pw_dir, &st) < 0) { - log("Rhosts authentication refused for %.100s: " + logit("Rhosts authentication refused for %.100s: " "no home directory %.200s", pw->pw_name, pw->pw_dir); auth_debug_add("Rhosts authentication refused for %.100s: " "no home directory %.200s", pw->pw_name, pw->pw_dir); @@ -229,7 +230,7 @@ auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostnam if (options.strict_modes && ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || (st.st_mode & 022) != 0)) { - log("Rhosts authentication refused for %.100s: " + logit("Rhosts authentication refused for %.100s: " "bad ownership or modes for home directory.", pw->pw_name); auth_debug_add("Rhosts authentication refused for %.100s: " "bad ownership or modes for home directory.", pw->pw_name); @@ -256,7 +257,7 @@ auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostnam if (options.strict_modes && ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || (st.st_mode & 022) != 0)) { - log("Rhosts authentication refused for %.100s: bad modes for %.200s", + logit("Rhosts authentication refused for %.100s: bad modes for %.200s", pw->pw_name, buf); auth_debug_add("Bad file modes for %.200s", buf); continue; diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c index 92f6277..5631d23 100644 --- a/crypto/openssh/auth-rsa.c +++ b/crypto/openssh/auth-rsa.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-rsa.c,v 1.56 2002/06/10 16:53:06 stevesk Exp $"); +RCSID("$OpenBSD: auth-rsa.c,v 1.57 2003/04/08 20:21:28 itojun Exp $"); #include <openssl/rsa.h> #include <openssl/md5.h> @@ -187,7 +187,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) secure_filename(f, file, pw, line, sizeof(line)) != 0) { xfree(file); fclose(f); - log("Authentication refused: %s", line); + logit("Authentication refused: %s", line); restore_uid(); return (0); } @@ -246,7 +246,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) /* check the real bits */ if (bits != BN_num_bits(key->rsa->n)) - log("Warning: %s, line %lu: keysize mismatch: " + logit("Warning: %s, line %lu: keysize mismatch: " "actual %d vs. announced %d.", file, linenum, BN_num_bits(key->rsa->n), bits); diff --git a/crypto/openssh/auth-sia.c b/crypto/openssh/auth-sia.c index 5c9b3f5..cae5f09 100644 --- a/crypto/openssh/auth-sia.c +++ b/crypto/openssh/auth-sia.c @@ -52,26 +52,27 @@ auth_sia_password(Authctxt *authctxt, char *pass) SIAENTITY *ent = NULL; const char *host; - host = get_canonical_hostname(options.verify_reverse_mapping); + host = get_canonical_hostname(options.use_dns); - if (!authctxt->user || !pass || pass[0] == '\0') - return(0); + if (!authctxt->user || pass == NULL || pass[0] == '\0') + return (0); if (sia_ses_init(&ent, saved_argc, saved_argv, host, authctxt->user, NULL, 0, NULL) != SIASUCCESS) - return(0); + return (0); if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) { - error("Couldn't authenticate %s from %s", authctxt->user, - host); + error("Couldn't authenticate %s from %s", + authctxt->user, host); if (ret & SIASTOP) sia_ses_release(&ent); - return(0); + + return (0); } sia_ses_release(&ent); - return(1); + return (1); } void @@ -80,10 +81,10 @@ session_setup_sia(struct passwd *pw, char *tty) SIAENTITY *ent = NULL; const char *host; - host = get_canonical_hostname(options.verify_reverse_mapping); + host = get_canonical_hostname(options.use_dns); - if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name, tty, - 0, NULL) != SIASUCCESS) + if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name, + tty, 0, NULL) != SIASUCCESS) fatal("sia_ses_init failed"); if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) { @@ -97,8 +98,8 @@ session_setup_sia(struct passwd *pw, char *tty) pw->pw_name, host); if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS) - fatal("Couldn't launch session for %s from %s", pw->pw_name, - host); + fatal("Couldn't launch session for %s from %s", + pw->pw_name, host); sia_ses_release(&ent); diff --git a/crypto/openssh/auth-sia.h b/crypto/openssh/auth-sia.h index 7aecce9..38164ff 100644 --- a/crypto/openssh/auth-sia.h +++ b/crypto/openssh/auth-sia.h @@ -26,7 +26,7 @@ #ifdef HAVE_OSF_SIA -int auth_sia_password(Authctxt *authctxt, char *pass); -void session_setup_sia(struct passwd *pw, char *tty); +int auth_sia_password(Authctxt *, char *); +void session_setup_sia(struct passwd *, char *); #endif /* HAVE_OSF_SIA */ diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 1268acc..46e495a 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $"); +RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $"); #ifdef HAVE_LOGIN_H #include <login.h> @@ -54,6 +54,7 @@ RCSID("$OpenBSD: auth.c,v 1.46 2002/11/04 10:07:53 markus Exp $"); /* import */ extern ServerOptions options; +extern Buffer loginmsg; /* Debugging messages */ Buffer auth_debug; @@ -72,26 +73,25 @@ int allowed_user(struct passwd * pw) { struct stat st; - const char *hostname = NULL, *ipaddr = NULL; + const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; char *shell; int i; -#ifdef WITH_AIXAUTHENTICATE - char *loginmsg; -#endif /* WITH_AIXAUTHENTICATE */ -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) - struct spwd *spw; - time_t today; +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; -#if !defined(USE_PAM) && defined(HAVE_SHADOW_H) && \ - !defined(DISABLE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + if (!options.use_pam) + spw = getspnam(pw->pw_name); +#ifdef HAS_SHADOW_EXPIRE #define DAY (24L * 60 * 60) /* 1 day in seconds */ - if ((spw = getspnam(pw->pw_name)) != NULL) { + if (!options.use_pam && spw != NULL) { + time_t today; + today = time(NULL) / DAY; debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" " sp_max %d", (int)today, (int)spw->sp_expire, @@ -102,25 +102,58 @@ allowed_user(struct passwd * pw) * day after the day specified. */ if (spw->sp_expire != -1 && today > spw->sp_expire) { - log("Account %.100s has expired", pw->pw_name); + logit("Account %.100s has expired", pw->pw_name); return 0; } if (spw->sp_lstchg == 0) { - log("User %.100s password has expired (root forced)", + logit("User %.100s password has expired (root forced)", pw->pw_name); return 0; } if (spw->sp_max != -1 && today > spw->sp_lstchg + spw->sp_max) { - log("User %.100s password has expired (password aged)", + logit("User %.100s password has expired (password aged)", pw->pw_name); return 0; } } +#endif /* HAS_SHADOW_EXPIRE */ +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ + + /* grab passwd field for locked account check */ +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + if (spw != NULL) + passwd = spw->sp_pwdp; +#else + passwd = pw->pw_passwd; #endif + /* check for locked account */ + if (!options.use_pam && passwd && *passwd) { + int locked = 0; + +#ifdef LOCKED_PASSWD_STRING + if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) + locked = 1; +#endif +#ifdef LOCKED_PASSWD_PREFIX + if (strncmp(passwd, LOCKED_PASSWD_PREFIX, + strlen(LOCKED_PASSWD_PREFIX)) == 0) + locked = 1; +#endif +#ifdef LOCKED_PASSWD_SUBSTR + if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) + locked = 1; +#endif + if (locked) { + logit("User %.100s not allowed because account is locked", + pw->pw_name); + return 0; + } + } + /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. @@ -129,19 +162,19 @@ allowed_user(struct passwd * pw) /* deny if shell does not exists or is not executable */ if (stat(shell, &st) != 0) { - log("User %.100s not allowed because shell %.100s does not exist", + logit("User %.100s not allowed because shell %.100s does not exist", pw->pw_name, shell); return 0; } if (S_ISREG(st.st_mode) == 0 || (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { - log("User %.100s not allowed because shell %.100s is not executable", + logit("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.verify_reverse_mapping); + hostname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); } @@ -150,7 +183,7 @@ allowed_user(struct passwd * pw) for (i = 0; i < options.num_deny_users; i++) if (match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i])) { - log("User %.100s not allowed because listed in DenyUsers", + logit("User %.100s not allowed because listed in DenyUsers", pw->pw_name); return 0; } @@ -163,7 +196,7 @@ allowed_user(struct passwd * pw) break; /* i < options.num_allow_users iff we break for loop */ if (i >= options.num_allow_users) { - log("User %.100s not allowed because not listed in AllowUsers", + logit("User %.100s not allowed because not listed in AllowUsers", pw->pw_name); return 0; } @@ -171,7 +204,7 @@ allowed_user(struct passwd * pw) 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) { - log("User %.100s not allowed because not in any group", + logit("User %.100s not allowed because not in any group", pw->pw_name); return 0; } @@ -181,7 +214,7 @@ allowed_user(struct passwd * pw) if (ga_match(options.deny_groups, options.num_deny_groups)) { ga_free(); - log("User %.100s not allowed because a group is listed in DenyGroups", + logit("User %.100s not allowed because a group is listed in DenyGroups", pw->pw_name); return 0; } @@ -193,7 +226,7 @@ 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", + logit("User %.100s not allowed because none of user's groups are listed in AllowGroups", pw->pw_name); return 0; } @@ -206,26 +239,23 @@ allowed_user(struct passwd * pw) * PermitRootLogin to control logins via ssh), or if running as * non-root user (since loginrestrictions will always fail). */ - if ((pw->pw_uid != 0) && (geteuid() == 0) && - loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { - int loginrestrict_errno = errno; - - if (loginmsg && *loginmsg) { - /* Remove embedded newlines (if any) */ - char *p; - for (p = loginmsg; *p; p++) { - if (*p == '\n') - *p = ' '; + if ((pw->pw_uid != 0) && (geteuid() == 0)) { + char *msg; + + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) { + int loginrestrict_errno = errno; + + if (msg && *msg) { + buffer_append(&loginmsg, msg, strlen(msg)); + aix_remove_embedded_newlines(msg); + logit("Login restricted for %s: %.100s", + pw->pw_name, msg); } - /* Remove trailing newline */ - *--p = '\0'; - log("Login restricted for %s: %.100s", pw->pw_name, - loginmsg); + /* Don't fail if /etc/nologin set */ + if (!(loginrestrict_errno == EPERM && + stat(_PATH_NOLOGIN, &st) == 0)) + return 0; } - /* Don't fail if /etc/nologin set */ - if (!(loginrestrict_errno == EPERM && - stat(_PATH_NOLOGIN, &st) == 0)) - return 0; } #endif /* WITH_AIXAUTHENTICATE */ @@ -252,7 +282,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) !authctxt->valid || authctxt->failures >= AUTH_FAIL_LOG || strcmp(method, "password") == 0) - authlog = log; + authlog = logit; if (authctxt->postponed) authmsg = "Postponed"; @@ -268,13 +298,10 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) get_remote_port(), info); -#ifdef WITH_AIXAUTHENTICATE +#ifdef CUSTOM_FAILED_LOGIN if (authenticated == 0 && strcmp(method, "password") == 0) - loginfailed(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh"); -#endif /* WITH_AIXAUTHENTICATE */ - + record_failed_login(authctxt->user, "ssh"); +#endif } /* @@ -293,12 +320,12 @@ auth_root_allowed(char *method) break; case PERMIT_FORCED_ONLY: if (forced_command) { - log("Root login accepted for forced command."); + logit("Root login accepted for forced command."); return 1; } break; } - log("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); + logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); return 0; } @@ -390,7 +417,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, (stat(user_hostfile, &st) == 0) && ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || (st.st_mode & 022) != 0)) { - log("Authentication refused for %.100s: " + logit("Authentication refused for %.100s: " "bad owner or modes for %.200s", pw->pw_name, user_hostfile); } else { @@ -494,12 +521,10 @@ getpwnamallow(const char *user) pw = getpwnam(user); if (pw == NULL) { - log("Illegal user %.100s from %.100s", + logit("Illegal user %.100s from %.100s", user, get_remote_ipaddr()); -#ifdef WITH_AIXAUTHENTICATE - loginfailed(user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh"); +#ifdef CUSTOM_FAILED_LOGIN + record_failed_login(user, "ssh"); #endif return (NULL); } @@ -564,3 +589,24 @@ auth_debug_reset(void) auth_debug_init = 1; } } + +struct passwd * +fakepw(void) +{ + static struct passwd fake; + + memset(&fake, 0, sizeof(fake)); + fake.pw_name = "NOUSER"; + fake.pw_passwd = + "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; + fake.pw_gecos = "NOUSER"; + fake.pw_uid = -1; + fake.pw_gid = -1; +#ifdef HAVE_PW_CLASS_IN_PASSWD + fake.pw_class = ""; +#endif + fake.pw_dir = "/nonexist"; + fake.pw_shell = "/nonexist"; + + return (&fake); +} diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h index c75d753..beaacb8 100644 --- a/crypto/openssh/auth.h +++ b/crypto/openssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -48,29 +48,32 @@ typedef struct KbdintDevice KbdintDevice; struct Authctxt { int success; - int postponed; - int valid; + int postponed; /* authentication needs another step */ + int valid; /* user exists and is allowed to login */ int attempt; int failures; - char *user; + char *user; /* username sent by the client */ char *service; - struct passwd *pw; + struct passwd *pw; /* set if 'valid' */ char *style; void *kbdintctxt; #ifdef BSD_AUTH auth_session_t *as; #endif -#ifdef KRB4 - char *krb4_ticket_file; -#endif #ifdef KRB5 krb5_context krb5_ctx; - krb5_auth_context krb5_auth_ctx; krb5_ccache krb5_fwd_ccache; krb5_principal krb5_user; char *krb5_ticket_file; #endif + void *methoddata; }; +/* + * Every authentication method has to handle authentication requests for + * non-existing users, or for users that are not allowed to login. In this + * case 'valid' is set to 0, but 'user' points to the username requested by + * the client. + */ struct Authmethod { char *name; @@ -111,20 +114,6 @@ int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); int user_key_allowed(struct passwd *, Key *); -#ifdef KRB4 -#include <krb.h> -int auth_krb4(Authctxt *, KTEXT, char **, KTEXT); -int auth_krb4_password(Authctxt *, const char *); -void krb4_cleanup_proc(void *); - -#ifdef AFS -#include <kafs.h> -int auth_krb4_tgt(Authctxt *, const char *); -int auth_afs_token(Authctxt *, const char *); -#endif /* AFS */ - -#endif /* KRB4 */ - #ifdef KRB5 int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); @@ -133,7 +122,6 @@ void krb5_cleanup_proc(void *authctxt); #endif /* KRB5 */ #include "auth-pam.h" -#include "auth2-pam.h" Authctxt *do_authentication(void); Authctxt *do_authentication2(void); @@ -159,6 +147,7 @@ struct passwd * getpwnamallow(const char *user); char *get_challenge(Authctxt *); int verify_response(Authctxt *, const char *); +void abandon_challenge_response(Authctxt *); struct passwd * auth_get_user(void); @@ -184,6 +173,8 @@ void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); void auth_debug_send(void); void auth_debug_reset(void); +struct passwd *fakepw(void); + #define AUTH_FAIL_MAX 6 #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2) #define AUTH_FAIL_MSG "Too many authentication failures for %.100s" diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c index c273f2f..dfe944d 100644 --- a/crypto/openssh/auth1.c +++ b/crypto/openssh/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.47 2003/02/06 21:22:42 markus Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -49,10 +49,6 @@ get_authname(int type) case SSH_CMSG_AUTH_TIS: case SSH_CMSG_AUTH_TIS_RESPONSE: return "challenge-response"; -#if defined(KRB4) || defined(KRB5) - case SSH_CMSG_AUTH_KERBEROS: - return "kerberos"; -#endif } snprintf(buf, sizeof buf, "bad-auth-msg-%d", type); return buf; @@ -73,7 +69,7 @@ do_authloop(Authctxt *authctxt) char info[1024]; u_int dlen; u_int ulen; - int type = 0; + int prev, type = 0; struct passwd *pw = authctxt->pw; debug("Attempting authentication for %s%.100s.", @@ -81,7 +77,7 @@ do_authloop(Authctxt *authctxt) /* If the user has no password, accept authentication immediately. */ if (options.password_authentication && -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 (!options.kerberos_authentication || options.kerberos_or_local_passwd) && #endif PRIVSEP(auth_password(authctxt, ""))) { @@ -103,104 +99,22 @@ do_authloop(Authctxt *authctxt) info[0] = '\0'; /* Get a packet from the client. */ + prev = type; type = packet_read(); + /* + * If we started challenge-response authentication but the + * next packet is not a response to our challenge, release + * the resources allocated by get_challenge() (which would + * normally have been released by verify_response() had we + * received such a response) + */ + if (prev == SSH_CMSG_AUTH_TIS && + type != SSH_CMSG_AUTH_TIS_RESPONSE) + abandon_challenge_response(authctxt); + /* Process the packet. */ switch (type) { - -#if defined(KRB4) || defined(KRB5) - case SSH_CMSG_AUTH_KERBEROS: - if (!options.kerberos_authentication) { - verbose("Kerberos authentication disabled."); - } else { - char *kdata = packet_get_string(&dlen); - packet_check_eom(); - - if (kdata[0] == 4) { /* KRB_PROT_VERSION */ -#ifdef KRB4 - KTEXT_ST tkt, reply; - tkt.length = dlen; - if (tkt.length < MAX_KTXT_LEN) - memcpy(tkt.dat, kdata, tkt.length); - - if (PRIVSEP(auth_krb4(authctxt, &tkt, - &client_user, &reply))) { - authenticated = 1; - snprintf(info, sizeof(info), - " tktuser %.100s", - client_user); - - packet_start( - SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) - reply.dat, reply.length); - packet_send(); - packet_write_wait(); - } -#endif /* KRB4 */ - } else { -#ifdef KRB5 - krb5_data tkt, reply; - tkt.length = dlen; - tkt.data = kdata; - - if (PRIVSEP(auth_krb5(authctxt, &tkt, - &client_user, &reply))) { - authenticated = 1; - snprintf(info, sizeof(info), - " tktuser %.100s", - client_user); - - /* Send response to client */ - packet_start( - SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) - reply.data, reply.length); - packet_send(); - packet_write_wait(); - - if (reply.length) - xfree(reply.data); - } -#endif /* KRB5 */ - } - xfree(kdata); - } - break; -#endif /* KRB4 || KRB5 */ - -#if defined(AFS) || defined(KRB5) - /* XXX - punt on backward compatibility here. */ - case SSH_CMSG_HAVE_KERBEROS_TGT: - packet_send_debug("Kerberos TGT passing disabled before authentication."); - break; -#ifdef AFS - case SSH_CMSG_HAVE_AFS_TOKEN: - packet_send_debug("AFS token passing disabled before authentication."); - break; -#endif /* AFS */ -#endif /* AFS || KRB5 */ - - case SSH_CMSG_AUTH_RHOSTS: - if (!options.rhosts_authentication) { - verbose("Rhosts authentication disabled."); - break; - } - /* - * Get client user name. Note that we just have to - * trust the client; this is one reason why rhosts - * authentication is insecure. (Another is - * IP-spoofing on a local network.) - */ - client_user = packet_get_string(&ulen); - packet_check_eom(); - - /* Try to authenticate using /etc/hosts.equiv and .rhosts. */ - authenticated = auth_rhosts(pw, client_user); - - snprintf(info, sizeof info, " ruser %.100s", client_user); - break; - case SSH_CMSG_AUTH_RHOSTS_RSA: if (!options.rhosts_rsa_authentication) { verbose("Rhosts with RSA authentication disabled."); @@ -297,7 +211,7 @@ do_authloop(Authctxt *authctxt) * Any unknown messages will be ignored (and failure * returned) during authentication. */ - log("Unknown message during authentication: type %d", type); + logit("Unknown message during authentication: type %d", type); break; } #ifdef BSD_AUTH @@ -311,8 +225,6 @@ do_authloop(Authctxt *authctxt) authctxt->user); #ifdef _UNICOS - if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated) - cray_login_failure(authctxt->user, IA_UDBERR); if (authenticated && cray_access_denied(authctxt->user)) { authenticated = 0; fatal("Access denied for user %s.",authctxt->user); @@ -332,9 +244,10 @@ do_authloop(Authctxt *authctxt) !auth_root_allowed(get_authname(type))) authenticated = 0; #endif + #ifdef USE_PAM - if (!use_privsep && authenticated && - !do_pam_account(pw->pw_name, client_user)) + if (options.use_pam && authenticated && + !PRIVSEP(do_pam_account())) authenticated = 0; #endif @@ -349,9 +262,8 @@ do_authloop(Authctxt *authctxt) if (authenticated) return; - if (authctxt->failures++ > AUTH_FAIL_MAX) { + if (authctxt->failures++ > AUTH_FAIL_MAX) packet_disconnect(AUTH_FAIL_MSG, authctxt->user); - } packet_start(SSH_SMSG_FAILURE); packet_send(); @@ -380,16 +292,6 @@ do_authentication(void) if ((style = strchr(user, ':')) != NULL) *style++ = '\0'; -#ifdef KRB5 - /* XXX - SSH.com Kerberos v5 braindeath. */ - if ((datafellows & SSH_BUG_K5USER) && - options.kerberos_authentication) { - char *p; - if ((p = strchr(user, '@')) != NULL) - *p = '\0'; - } -#endif - authctxt = authctxt_new(); authctxt->user = user; authctxt->style = style; @@ -397,14 +299,17 @@ do_authentication(void) /* Verify that the user is a valid user. */ if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) authctxt->valid = 1; - else + else { debug("do_authentication: illegal user %s", user); + authctxt->pw = fakepw(); + } setproctitle("%s%s", authctxt->pw ? user : "unknown", use_privsep ? " [net]" : ""); #ifdef USE_PAM - PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user)); + if (options.use_pam) + PRIVSEP(start_pam(user)); #endif /* diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c index 0d17093..aacbf0b 100644 --- a/crypto/openssh/auth2-chall.c +++ b/crypto/openssh/auth2-chall.c @@ -41,6 +41,9 @@ static void input_userauth_info_response(int, u_int32_t, void *); #ifdef BSD_AUTH extern KbdintDevice bsdauth_device; #else +#ifdef USE_PAM +extern KbdintDevice sshpam_device; +#endif #ifdef SKEY extern KbdintDevice skey_device; #endif @@ -50,6 +53,9 @@ KbdintDevice *devices[] = { #ifdef BSD_AUTH &bsdauth_device, #else +#ifdef USE_PAM + &sshpam_device, +#endif #ifdef SKEY &skey_device, #endif @@ -320,18 +326,27 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) void privsep_challenge_enable(void) { +#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY) + int n = 0; +#endif #ifdef BSD_AUTH extern KbdintDevice mm_bsdauth_device; #endif +#ifdef USE_PAM + extern KbdintDevice mm_sshpam_device; +#endif #ifdef SKEY extern KbdintDevice mm_skey_device; #endif - /* As long as SSHv1 has devices[0] hard coded this is fine */ + #ifdef BSD_AUTH - devices[0] = &mm_bsdauth_device; + devices[n++] = &mm_bsdauth_device; #else +#ifdef USE_PAM + devices[n++] = &mm_sshpam_device; +#endif #ifdef SKEY - devices[0] = &mm_skey_device; + devices[n++] = &mm_skey_device; #endif #endif } diff --git a/crypto/openssh/auth2-gss.c b/crypto/openssh/auth2-gss.c new file mode 100644 index 0000000..75b94b0 --- /dev/null +++ b/crypto/openssh/auth2-gss.c @@ -0,0 +1,247 @@ +/* $OpenBSD: auth2-gss.c,v 1.3 2003/09/01 20:44:54 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI + +#include "auth.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "log.h" +#include "dispatch.h" +#include "servconf.h" +#include "compat.h" +#include "packet.h" +#include "monitor_wrap.h" + +#include "ssh-gss.h" + +extern ServerOptions options; + +static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_errtok(int, u_int32_t, void *); + +/* + * We only support those mechanisms that we know about (ie ones that we know + * how to check local user kuserok and the like + */ +static int +userauth_gssapi(Authctxt *authctxt) +{ + gss_OID_desc oid = {0, NULL}; + Gssctxt *ctxt = NULL; + int mechs; + gss_OID_set supported; + int present; + OM_uint32 ms; + u_int len; + char *doid = NULL; + + if (!authctxt->valid || authctxt->user == NULL) + return (0); + + mechs = packet_get_int(); + if (mechs == 0) { + debug("Mechanism negotiation is not supported"); + return (0); + } + + ssh_gssapi_supported_oids(&supported); + do { + mechs--; + + if (doid) + xfree(doid); + + doid = packet_get_string(&len); + + if (doid[0] != SSH_GSS_OIDTYPE || doid[1] != len-2) { + logit("Mechanism OID received using the old encoding form"); + oid.elements = doid; + oid.length = len; + } else { + oid.elements = doid + 2; + oid.length = len - 2; + } + gss_test_oid_set_member(&ms, &oid, supported, &present); + } while (mechs > 0 && !present); + + gss_release_oid_set(&ms, &supported); + + if (!present) { + xfree(doid); + return (0); + } + + if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &oid)))) { + xfree(doid); + return (0); + } + + authctxt->methoddata=(void *)ctxt; + + packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); + + /* Return OID in same format as we received it*/ + packet_put_string(doid, len); + + packet_send(); + xfree(doid); + + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); + authctxt->postponed = 1; + + return (0); +} + +static void +input_gssapi_token(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 maj_status, min_status; + u_int len; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; /* u_int vs. size_t */ + + packet_check_eom(); + + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, NULL)); + + xfree(recv_tok.value); + + if (GSS_ERROR(maj_status)) { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + userauth_finish(authctxt, 0, "gssapi"); + } else { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + if (maj_status == GSS_S_COMPLETE) { + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, + &input_gssapi_exchange_complete); + } + } + + gss_release_buffer(&min_status, &send_tok); +} + +static void +input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 maj_status; + u_int len; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; + + packet_check_eom(); + + /* Push the error token into GSSAPI to see what it says */ + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, NULL)); + + xfree(recv_tok.value); + + /* We can't return anything to the client, even if we wanted to */ + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + + /* The client will have already moved on to the next auth */ + + gss_release_buffer(&maj_status, &send_tok); +} + +/* + * This is called when the client thinks we've completed authentication. + * It should only be enabled in the dispatch handler by the function above, + * which only enables it once the GSSAPI exchange is complete. + */ + +static void +input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + + /* + * We don't need to check the status, because the stored credentials + * which userok uses are only populated once the context init step + * has returned complete. + */ + + packet_check_eom(); + + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); + userauth_finish(authctxt, authenticated, "gssapi"); +} + +Authmethod method_gssapi = { + "gssapi", + userauth_gssapi, + &options.gss_authentication +}; + +#endif /* GSSAPI */ diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c index 2bde7bb..505d3ef 100644 --- a/crypto/openssh/auth2-hostbased.c +++ b/crypto/openssh/auth2-hostbased.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2-hostbased.c,v 1.5 2003/06/24 08:23:46 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -42,7 +42,7 @@ RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); /* import */ extern ServerOptions options; extern u_char *session_id2; -extern int session_id2_len; +extern u_int session_id2_len; static int userauth_hostbased(Authctxt *authctxt) @@ -77,7 +77,7 @@ userauth_hostbased(Authctxt *authctxt) pktype = key_type_from_name(pkalg); if (pktype == KEY_UNSPEC) { /* this is perfectly legal */ - log("userauth_hostbased: unsupported " + logit("userauth_hostbased: unsupported " "public key algorithm: %s", pkalg); goto done; } @@ -136,7 +136,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, HostStatus host_status; int len; - resolvedname = get_canonical_hostname(options.verify_reverse_mapping); + resolvedname = get_canonical_hostname(options.use_dns); ipaddr = get_remote_ipaddr(); debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", @@ -152,7 +152,7 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, chost[len - 1] = '\0'; } if (strcasecmp(resolvedname, chost) != 0) - log("userauth_hostbased mismatch: " + logit("userauth_hostbased mismatch: " "client sends %s, but we resolve %s to %s", chost, ipaddr, resolvedname); if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) diff --git a/crypto/openssh/auth2-kbdint.c b/crypto/openssh/auth2-kbdint.c index e609928..1696ef4 100644 --- a/crypto/openssh/auth2-kbdint.c +++ b/crypto/openssh/auth2-kbdint.c @@ -49,10 +49,6 @@ userauth_kbdint(Authctxt *authctxt) if (options.challenge_response_authentication) authenticated = auth2_challenge(authctxt, devs); -#ifdef USE_PAM - if (authenticated == 0 && options.pam_authentication_via_kbd_int) - authenticated = auth2_pam(authctxt); -#endif xfree(devs); xfree(lang); #ifdef HAVE_CYGWIN diff --git a/crypto/openssh/auth2-none.c b/crypto/openssh/auth2-none.c index c07b2dd..c342add 100644 --- a/crypto/openssh/auth2-none.c +++ b/crypto/openssh/auth2-none.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-none.c,v 1.4 2002/06/27 10:35:47 deraadt Exp $"); +RCSID("$OpenBSD: auth2-none.c,v 1.6 2003/08/26 09:58:43 markus Exp $"); #include "auth.h" #include "xmalloc.h" @@ -100,7 +100,9 @@ userauth_none(Authctxt *authctxt) if (check_nt_auth(1, authctxt->pw) == 0) return(0); #endif - return (authctxt->valid ? PRIVSEP(auth_password(authctxt, "")) : 0); + if (options.password_authentication) + return (PRIVSEP(auth_password(authctxt, ""))); + return (0); } Authmethod method_none = { diff --git a/crypto/openssh/auth2-passwd.c b/crypto/openssh/auth2-passwd.c index ffa2795..67fb4c9 100644 --- a/crypto/openssh/auth2-passwd.c +++ b/crypto/openssh/auth2-passwd.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2-passwd.c,v 1.4 2003/08/26 09:58:43 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -44,14 +44,14 @@ userauth_passwd(Authctxt *authctxt) u_int len; change = packet_get_char(); if (change) - log("password change not supported"); + logit("password change not supported"); password = packet_get_string(&len); packet_check_eom(); - if (authctxt->valid && + if (PRIVSEP(auth_password(authctxt, password)) == 1 #ifdef HAVE_CYGWIN - check_nt_auth(1, authctxt->pw) && + && check_nt_auth(1, authctxt->pw) #endif - PRIVSEP(auth_password(authctxt, password)) == 1) + ) authenticated = 1; memset(password, 0, len); xfree(password); diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c index 947bfed..d51e939 100644 --- a/crypto/openssh/auth2-pubkey.c +++ b/crypto/openssh/auth2-pubkey.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2-pubkey.c,v 1.4 2003/06/24 08:23:46 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -44,7 +44,7 @@ RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); /* import */ extern ServerOptions options; extern u_char *session_id2; -extern int session_id2_len; +extern u_int session_id2_len; static int userauth_pubkey(Authctxt *authctxt) @@ -78,7 +78,7 @@ 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", + logit("userauth_pubkey: unsupported public key algorithm: %s", pkalg); goto done; } @@ -199,7 +199,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file) if (options.strict_modes && secure_filename(f, file, pw, line, sizeof(line)) != 0) { fclose(f); - log("Authentication refused: %s", line); + logit("Authentication refused: %s", line); restore_uid(); return 0; } diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c index 1b21eb2..41e77ef 100644 --- a/crypto/openssh/auth2.c +++ b/crypto/openssh/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $"); #include "ssh2.h" #include "xmalloc.h" @@ -36,10 +36,14 @@ RCSID("$OpenBSD: auth2.c,v 1.96 2003/02/06 21:22:43 markus Exp $"); #include "pathnames.h" #include "monitor_wrap.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* import */ extern ServerOptions options; extern u_char *session_id2; -extern int session_id2_len; +extern u_int session_id2_len; Authctxt *x_authctxt = NULL; @@ -50,10 +54,16 @@ extern Authmethod method_pubkey; extern Authmethod method_passwd; extern Authmethod method_kbdint; extern Authmethod method_hostbased; +#ifdef GSSAPI +extern Authmethod method_gssapi; +#endif Authmethod *authmethods[] = { &method_none, &method_pubkey, +#ifdef GSSAPI + &method_gssapi, +#endif &method_passwd, &method_kbdint, &method_hostbased, @@ -85,10 +95,6 @@ do_authentication2(void) /* challenge-response is implemented via keyboard interactive */ if (options.challenge_response_authentication) options.kbd_interactive_authentication = 1; - if (options.pam_authentication_via_kbd_int) - options.kbd_interactive_authentication = 1; - if (use_privsep) - options.pam_authentication_via_kbd_int = 0; dispatch_init(&dispatch_protocol_error); dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request); @@ -157,12 +163,15 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) authctxt->valid = 1; debug2("input_userauth_request: setting up authctxt for %s", user); #ifdef USE_PAM - PRIVSEP(start_pam(authctxt->pw->pw_name)); + if (options.use_pam) + PRIVSEP(start_pam(authctxt->pw->pw_name)); #endif } else { - log("input_userauth_request: illegal user %s", user); + logit("input_userauth_request: illegal user %s", user); + authctxt->pw = fakepw(); #ifdef USE_PAM - PRIVSEP(start_pam("NOUSER")); + if (options.use_pam) + PRIVSEP(start_pam(user)); #endif } setproctitle("%s%s", authctxt->pw ? user : "unknown", @@ -180,6 +189,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } /* reset state */ auth2_challenge_stop(authctxt); + +#ifdef GSSAPI + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); +#endif + authctxt->postponed = 0; /* try to authenticate user */ @@ -210,10 +225,9 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) authenticated = 0; #ifdef USE_PAM - if (!use_privsep && authenticated && authctxt->user && - !do_pam_account(authctxt->user, NULL)) + if (options.use_pam && authenticated && !PRIVSEP(do_pam_account())) authenticated = 0; -#endif /* USE_PAM */ +#endif #ifdef _UNICOS if (authenticated && cray_access_denied(authctxt->user)) { @@ -238,13 +252,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) /* now we can break out */ authctxt->success = 1; } else { - if (authctxt->failures++ > AUTH_FAIL_MAX) { + if (authctxt->failures++ > AUTH_FAIL_MAX) packet_disconnect(AUTH_FAIL_MSG, authctxt->user); - } -#ifdef _UNICOS - if (strcmp(method, "password") == 0) - cray_login_failure(authctxt->user, IA_UDBERR); -#endif /* _UNICOS */ methods = authmethods_get(); packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_put_cstring(methods); diff --git a/crypto/openssh/authfd.c b/crypto/openssh/authfd.c index a186e01..c78db6d 100644 --- a/crypto/openssh/authfd.c +++ b/crypto/openssh/authfd.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfd.c,v 1.58 2003/01/23 13:50:27 markus Exp $"); +RCSID("$OpenBSD: authfd.c,v 1.61 2003/06/28 16:23:06 deraadt Exp $"); #include <openssl/evp.h> @@ -122,8 +122,8 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply PUT_32BIT(buf, len); /* Send the length and then the packet to the agent. */ - if (atomicio(write, auth->fd, buf, 4) != 4 || - atomicio(write, auth->fd, buffer_ptr(request), + if (atomicio(vwrite, auth->fd, buf, 4) != 4 || + atomicio(vwrite, auth->fd, buffer_ptr(request), buffer_len(request)) != buffer_len(request)) { error("Error writing to authentication socket."); return 0; @@ -332,7 +332,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio buffer_get_bignum(&auth->identities, key->rsa->n); *comment = buffer_get_string(&auth->identities, NULL); if (bits != BN_num_bits(key->rsa->n)) - log("Warning: identity keysize mismatch: actual %d, announced %u", + logit("Warning: identity keysize mismatch: actual %d, announced %u", BN_num_bits(key->rsa->n), bits); break; case 2: @@ -373,7 +373,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth, if (key->type != KEY_RSA1) return 0; if (response_type == 0) { - log("Compatibility with ssh protocol version 1.0 no longer supported."); + logit("Compatibility with ssh protocol version 1.0 no longer supported."); return 0; } buffer_init(&buffer); @@ -392,7 +392,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth, type = buffer_get_char(&buffer); if (agent_failed(type)) { - log("Agent admitted failure to authenticate using the key."); + logit("Agent admitted failure to authenticate using the key."); } else if (type != SSH_AGENT_RSA_RESPONSE) { fatal("Bad authentication response: %d", type); } else { @@ -441,7 +441,7 @@ ssh_agent_sign(AuthenticationConnection *auth, } type = buffer_get_char(&msg); if (agent_failed(type)) { - log("Agent admitted failure to sign using the key."); + logit("Agent admitted failure to sign using the key."); } else if (type != SSH2_AGENT_SIGN_RESPONSE) { fatal("Bad authentication response: %d", type); } else { @@ -589,16 +589,33 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key) } int -ssh_update_card(AuthenticationConnection *auth, int add, const char *reader_id, const char *pin) +ssh_update_card(AuthenticationConnection *auth, int add, + const char *reader_id, const char *pin, u_int life, u_int confirm) { Buffer msg; - int type; + int type, constrained = (life || confirm); + + if (add) { + type = constrained ? + SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED : + SSH_AGENTC_ADD_SMARTCARD_KEY; + } else + type = SSH_AGENTC_REMOVE_SMARTCARD_KEY; buffer_init(&msg); - buffer_put_char(&msg, add ? SSH_AGENTC_ADD_SMARTCARD_KEY : - SSH_AGENTC_REMOVE_SMARTCARD_KEY); + buffer_put_char(&msg, type); buffer_put_cstring(&msg, reader_id); buffer_put_cstring(&msg, pin); + + if (constrained) { + if (life != 0) { + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); + buffer_put_int(&msg, life); + } + if (confirm != 0) + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM); + } + if (ssh_request_reply(auth, &msg, &msg) == 0) { buffer_free(&msg); return 0; @@ -641,7 +658,7 @@ decode_reply(int type) case SSH_AGENT_FAILURE: case SSH_COM_AGENT2_FAILURE: case SSH2_AGENT_FAILURE: - log("SSH_AGENT_FAILURE"); + logit("SSH_AGENT_FAILURE"); return 0; case SSH_AGENT_SUCCESS: return 1; diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h index 2a8751e..74b825c 100644 --- a/crypto/openssh/authfd.h +++ b/crypto/openssh/authfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: authfd.h,v 1.32 2003/01/23 13:50:27 markus Exp $ */ +/* $OpenBSD: authfd.h,v 1.33 2003/06/11 11:18:38 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -49,6 +49,7 @@ /* add key with constraints */ #define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 #define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 +#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 #define SSH_AGENT_CONSTRAIN_LIFETIME 1 #define SSH_AGENT_CONSTRAIN_CONFIRM 2 @@ -82,7 +83,8 @@ int ssh_add_identity_constrained(AuthenticationConnection *, Key *, int ssh_remove_identity(AuthenticationConnection *, Key *); int ssh_remove_all_identities(AuthenticationConnection *, int); int ssh_lock_agent(AuthenticationConnection *, int, const char *); -int ssh_update_card(AuthenticationConnection *, int, const char *, const char *); +int ssh_update_card(AuthenticationConnection *, int, const char *, + const char *, u_int, u_int); int ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16], diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c index 90618ef..1f46093 100644 --- a/crypto/openssh/authfile.c +++ b/crypto/openssh/authfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: authfile.c,v 1.52 2003/03/13 11:42:18 markus Exp $"); +RCSID("$OpenBSD: authfile.c,v 1.54 2003/05/24 09:30:39 djm Exp $"); #include <openssl/err.h> #include <openssl/evp.h> @@ -514,7 +514,7 @@ key_perm_ok(int fd, const char *filename) error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); error("Permissions 0%3.3o for '%s' are too open.", - st.st_mode & 0777, filename); + (u_int)st.st_mode & 0777, filename); error("It is recommended that your private key files are NOT accessible by others."); error("This private key will be ignored."); return 0; @@ -629,9 +629,18 @@ key_load_public(const char *filename, char **commentp) Key *pub; char file[MAXPATHLEN]; + /* try rsa1 private key */ pub = key_load_public_type(KEY_RSA1, filename, commentp); if (pub != NULL) return pub; + + /* try rsa1 public key */ + pub = key_new(KEY_RSA1); + if (key_try_load_public(pub, filename, commentp) == 1) + return pub; + key_free(pub); + + /* try ssh2 public key */ pub = key_new(KEY_UNSPEC); if (key_try_load_public(pub, filename, commentp) == 1) return pub; diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c index 3c276b8..37cc27f 100644 --- a/crypto/openssh/bufaux.c +++ b/crypto/openssh/bufaux.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: bufaux.c,v 1.28 2002/10/23 10:40:16 markus Exp $"); +RCSID("$OpenBSD: bufaux.c,v 1.29 2003/04/08 20:21:28 itojun Exp $"); #include <openssl/bn.h> #include "bufaux.h" @@ -119,7 +119,7 @@ buffer_put_bignum2(Buffer *buffer, BIGNUM *value) /**XXX should be two's-complement */ int i, carry; u_char *uc = buf; - log("negativ!"); + logit("negativ!"); for (i = bytes-1, carry = 1; i>=0; i--) { uc[i] ^= 0xff; if (carry) @@ -165,7 +165,6 @@ buffer_get_int(Buffer *buffer) return GET_32BIT(buf); } -#ifdef HAVE_U_INT64_T u_int64_t buffer_get_int64(Buffer *buffer) { @@ -174,7 +173,6 @@ buffer_get_int64(Buffer *buffer) buffer_get(buffer, (char *) buf, 8); return GET_64BIT(buf); } -#endif /* * Stores integers in the buffer, msb first. @@ -197,7 +195,6 @@ buffer_put_int(Buffer *buffer, u_int value) buffer_append(buffer, buf, 4); } -#ifdef HAVE_U_INT64_T void buffer_put_int64(Buffer *buffer, u_int64_t value) { @@ -206,7 +203,6 @@ buffer_put_int64(Buffer *buffer, u_int64_t value) PUT_64BIT(buf, value); buffer_append(buffer, buf, 8); } -#endif /* * Returns an arbitrary binary string from the buffer. The string cannot diff --git a/crypto/openssh/bufaux.h b/crypto/openssh/bufaux.h index 80f35c1..9355535 100644 --- a/crypto/openssh/bufaux.h +++ b/crypto/openssh/bufaux.h @@ -29,10 +29,8 @@ void buffer_put_short(Buffer *, u_short); u_int buffer_get_int(Buffer *); void buffer_put_int(Buffer *, u_int); -#ifdef HAVE_U_INT64_T u_int64_t buffer_get_int64(Buffer *); void buffer_put_int64(Buffer *, u_int64_t); -#endif int buffer_get_char(Buffer *); void buffer_put_char(Buffer *, int); diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c index 9c9ca64..a80880b 100644 --- a/crypto/openssh/buffer.c +++ b/crypto/openssh/buffer.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: buffer.c,v 1.17 2003/09/16 03:03:47 deraadt Exp $"); +RCSID("$OpenBSD: buffer.c,v 1.19 2003/09/18 07:54:48 markus Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -39,6 +39,7 @@ buffer_free(Buffer *buffer) { if (buffer->alloc > 0) { memset(buffer->buf, 0, buffer->alloc); + buffer->alloc = 0; xfree(buffer->buf); } } diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c index 941db23..438175f 100644 --- a/crypto/openssh/canohost.c +++ b/crypto/openssh/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.35 2002/11/26 02:38:54 stevesk Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus 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 verify_reverse_mapping) +get_remote_hostname(int socket, int use_dns) { struct sockaddr_storage from; int i; @@ -72,6 +72,9 @@ get_remote_hostname(int socket, int verify_reverse_mapping) NULL, 0, NI_NUMERICHOST) != 0) fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + if (!use_dns) + return xstrdup(ntop); + if (from.ss_family == AF_INET) check_ip_options(socket, ntop); @@ -80,14 +83,24 @@ get_remote_hostname(int socket, int verify_reverse_mapping) if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), NULL, 0, NI_NAMEREQD) != 0) { /* Host name not found. Use ip address. */ -#if 0 - log("Could not reverse map address %.100s.", ntop); -#endif return xstrdup(ntop); } - /* Got host name. */ - name[sizeof(name) - 1] = '\0'; + /* + * if reverse lookup result looks like a numeric hostname, + * someone is trying to trick us by PTR record like following: + * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(name, "0", &hints, &ai) == 0) { + logit("Nasty PTR record \"%s\" is set up for %s, ignoring", + name, ntop); + freeaddrinfo(ai); + return xstrdup(ntop); + } + /* * Convert it to all lowercase (which is expected by the rest * of this software). @@ -95,9 +108,6 @@ get_remote_hostname(int socket, int verify_reverse_mapping) for (i = 0; name[i]; i++) if (isupper(name[i])) name[i] = tolower(name[i]); - - if (!verify_reverse_mapping) - return xstrdup(name); /* * Map it back to an IP address and check that the given * address actually is an address of this host. This is @@ -111,7 +121,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping) hints.ai_family = from.ss_family; hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { - log("reverse mapping checking getaddrinfo for %.700s " + logit("reverse mapping checking getaddrinfo for %.700s " "failed - POSSIBLE BREAKIN ATTEMPT!", name); return xstrdup(ntop); } @@ -126,7 +136,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping) /* If we reached the end of the list, the address was not there. */ if (!ai) { /* Address not found for the host name. */ - log("Address %.100s maps to %.600s, but this does not " + logit("Address %.100s maps to %.600s, but this does not " "map back to the address - POSSIBLE BREAKIN ATTEMPT!", ntop, name); return xstrdup(ntop); @@ -149,6 +159,7 @@ get_remote_hostname(int socket, int verify_reverse_mapping) static void check_ip_options(int socket, char *ipaddr) { +#ifdef IP_OPTIONS u_char options[200]; char text[sizeof(options) * 3 + 1]; socklen_t option_size; @@ -166,11 +177,12 @@ check_ip_options(int socket, char *ipaddr) for (i = 0; i < option_size; i++) snprintf(text + i*3, sizeof(text) - i*3, " %2.2x", options[i]); - log("Connection from %.100s with IP options:%.800s", + logit("Connection from %.100s with IP options:%.800s", ipaddr, text); packet_disconnect("Connection from %.100s with IP options:%.800s", ipaddr, text); } +#endif /* IP_OPTIONS */ } /* @@ -180,14 +192,14 @@ check_ip_options(int socket, char *ipaddr) */ const char * -get_canonical_hostname(int verify_reverse_mapping) +get_canonical_hostname(int use_dns) { static char *canonical_host_name = NULL; - static int verify_reverse_mapping_done = 0; + static int use_dns_done = 0; /* Check if we have previously retrieved name with same option. */ if (canonical_host_name != NULL) { - if (verify_reverse_mapping_done != verify_reverse_mapping) + if (use_dns_done != use_dns) xfree(canonical_host_name); else return canonical_host_name; @@ -196,11 +208,11 @@ get_canonical_hostname(int verify_reverse_mapping) /* 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(), verify_reverse_mapping); + packet_get_connection_in(), use_dns); else canonical_host_name = xstrdup("UNKNOWN"); - verify_reverse_mapping_done = verify_reverse_mapping; + use_dns_done = use_dns; return canonical_host_name; } @@ -294,11 +306,11 @@ get_remote_ipaddr(void) } const char * -get_remote_name_or_ip(u_int utmp_len, int verify_reverse_mapping) +get_remote_name_or_ip(u_int utmp_len, int use_dns) { static const char *remote = ""; if (utmp_len > 0) - remote = get_canonical_hostname(verify_reverse_mapping); + remote = get_canonical_hostname(use_dns); if (utmp_len == 0 || strlen(remote) > utmp_len) remote = get_remote_ipaddr(); return remote; diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c index 218744d..3d75c8f 100644 --- a/crypto/openssh/channels.c +++ b/crypto/openssh/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.187 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.195 2003/09/16 21:02:40 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -54,7 +54,7 @@ RCSID("$OpenBSD: channels.c,v 1.187 2003/03/05 22:33:43 markus Exp $"); #include "key.h" #include "authfd.h" #include "pathnames.h" - +#include "bufaux.h" /* -- channel core */ @@ -142,12 +142,12 @@ channel_lookup(int id) Channel *c; if (id < 0 || id >= channels_alloc) { - log("channel_lookup: %d: bad id", id); + logit("channel_lookup: %d: bad id", id); return NULL; } c = channels[id]; if (c == NULL) { - log("channel_lookup: %d: bad id: channel free", id); + logit("channel_lookup: %d: bad id: channel free", id); return NULL; } return c; @@ -177,7 +177,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd, /* XXX ugly hack: nonblock is only set by the server */ if (nonblock && isatty(c->rfd)) { - debug("channel %d: rfd %d isatty", c->self, c->rfd); + debug2("channel %d: rfd %d isatty", c->self, c->rfd); c->isatty = 1; if (!isatty(c->wfd)) { error("channel %d: wfd %d is not a tty?", @@ -257,7 +257,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->local_consumed = 0; c->local_maxpacket = maxpack; c->remote_id = -1; - c->remote_name = remote_name; + c->remote_name = xstrdup(remote_name); c->remote_window = 0; c->remote_maxpacket = 0; c->force_drain = 0; @@ -305,7 +305,7 @@ channel_close_fd(int *fdp) static void channel_close_fds(Channel *c) { - debug3("channel_close_fds: channel %d: r %d w %d e %d", + debug3("channel %d: close_fds r %d w %d e %d", c->self, c->rfd, c->wfd, c->efd); channel_close_fd(&c->sock); @@ -325,11 +325,11 @@ channel_free(Channel *c) for (n = 0, i = 0; i < channels_alloc; i++) if (channels[i]) n++; - debug("channel_free: channel %d: %s, nchannels %d", c->self, + debug("channel %d: free: %s, nchannels %d", c->self, c->remote_name ? c->remote_name : "???", n); s = channel_open_message(); - debug3("channel_free: status: %s", s); + debug3("channel %d: status: %s", c->self, s); xfree(s); if (c->sock != -1) @@ -420,7 +420,7 @@ channel_not_very_much_buffered_data(void) } #endif if (buffer_len(&c->output) > packet_get_maxsize()) { - debug2("channel %d: big output buffer %d > %d", + debug2("channel %d: big output buffer %u > %u", c->self, buffer_len(&c->output), packet_get_maxsize()); return 0; @@ -576,7 +576,7 @@ channel_send_open(int id) Channel *c = channel_lookup(id); if (c == NULL) { - log("channel_send_open: %d: bad id", id); + logit("channel_send_open: %d: bad id", id); return; } debug2("channel %d: send open", id); @@ -594,10 +594,10 @@ channel_request_start(int id, char *service, int wantconfirm) Channel *c = channel_lookup(id); if (c == NULL) { - log("channel_request_start: %d: unknown channel id", id); + logit("channel_request_start: %d: unknown channel id", id); return; } - debug("channel %d: request %s", id, service) ; + debug2("channel %d: request %s", id, service) ; packet_start(SSH2_MSG_CHANNEL_REQUEST); packet_put_int(c->remote_id); packet_put_cstring(service); @@ -609,7 +609,7 @@ channel_register_confirm(int id, channel_callback_fn *fn) Channel *c = channel_lookup(id); if (c == NULL) { - log("channel_register_comfirm: %d: bad id", id); + logit("channel_register_comfirm: %d: bad id", id); return; } c->confirm = fn; @@ -620,7 +620,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn) Channel *c = channel_lookup(id); if (c == NULL) { - log("channel_register_cleanup: %d: bad id", id); + logit("channel_register_cleanup: %d: bad id", id); return; } c->detach_user = fn; @@ -631,7 +631,7 @@ channel_cancel_cleanup(int id) Channel *c = channel_lookup(id); if (c == NULL) { - log("channel_cancel_cleanup: %d: bad id", id); + logit("channel_cancel_cleanup: %d: bad id", id); return; } c->detach_user = NULL; @@ -642,7 +642,7 @@ channel_register_filter(int id, channel_filter_fn *fn) Channel *c = channel_lookup(id); if (c == NULL) { - log("channel_register_filter: %d: bad id", id); + logit("channel_register_filter: %d: bad id", id); return; } c->input_filter = fn; @@ -740,7 +740,7 @@ channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset) packet_put_int(c->remote_id); packet_send(); c->type = SSH_CHANNEL_CLOSED; - debug("channel %d: closing after input drain.", c->self); + debug2("channel %d: closing after input drain.", c->self); } } @@ -781,7 +781,7 @@ x11_open_helper(Buffer *b) proto_len = ucp[6] + 256 * ucp[7]; data_len = ucp[8] + 256 * ucp[9]; } else { - debug("Initial X11 packet contains bad byte order byte: 0x%x", + debug2("Initial X11 packet contains bad byte order byte: 0x%x", ucp[0]); return -1; } @@ -794,14 +794,14 @@ x11_open_helper(Buffer *b) /* Check if authentication protocol matches. */ if (proto_len != strlen(x11_saved_proto) || memcmp(ucp + 12, x11_saved_proto, proto_len) != 0) { - debug("X11 connection uses different authentication protocol."); + debug2("X11 connection uses different authentication protocol."); return -1; } /* Check if authentication data matches our fake data. */ if (data_len != x11_fake_data_len || memcmp(ucp + 12 + ((proto_len + 3) & ~3), x11_fake_data, x11_fake_data_len) != 0) { - debug("X11 auth data does not match fake data."); + debug2("X11 auth data does not match fake data."); return -1; } /* Check fake data length */ @@ -834,7 +834,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) * We have received an X11 connection that has bad * authentication information. */ - log("X11 connection rejected because of wrong authentication."); + logit("X11 connection rejected because of wrong authentication."); buffer_clear(&c->input); buffer_clear(&c->output); channel_close_fd(&c->sock); @@ -857,8 +857,8 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) c->type = SSH_CHANNEL_OPEN; 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); + logit("X11 connection rejected because of wrong authentication."); + debug2("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); chan_read_failed(c); buffer_clear(&c->input); chan_ibuf_empty(c); @@ -868,7 +868,7 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) chan_write_failed(c); else c->type = SSH_CHANNEL_OPEN; - debug("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); + debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate); } } @@ -926,7 +926,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) 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", + debug2("channel %d: dynamic request: socks4 host %s port %u command %u", c->self, host, c->host_port, s4_req.command); if (s4_req.command != 1) { @@ -942,6 +942,117 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) return 1; } +/* try to decode a socks5 header */ +#define SSH_SOCKS5_AUTHDONE 0x1000 +#define SSH_SOCKS5_NOAUTH 0x00 +#define SSH_SOCKS5_IPV4 0x01 +#define SSH_SOCKS5_DOMAIN 0x03 +#define SSH_SOCKS5_IPV6 0x04 +#define SSH_SOCKS5_CONNECT 0x01 +#define SSH_SOCKS5_SUCCESS 0x00 + +static int +channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset) +{ + struct { + u_int8_t version; + u_int8_t command; + u_int8_t reserved; + u_int8_t atyp; + } s5_req, s5_rsp; + u_int16_t dest_port; + u_char *p, dest_addr[255+1]; + int i, have, found, nmethods, addrlen, af; + + debug2("channel %d: decode socks5", c->self); + p = buffer_ptr(&c->input); + if (p[0] != 0x05) + return -1; + have = buffer_len(&c->input); + if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { + /* format: ver | nmethods | methods */ + if (have < 2) + return 0; + nmethods = p[1]; + if (have < nmethods + 2) + return 0; + /* look for method: "NO AUTHENTICATION REQUIRED" */ + for (found = 0, i = 2 ; i < nmethods + 2; i++) { + if (p[i] == SSH_SOCKS5_NOAUTH ) { + found = 1; + break; + } + } + if (!found) { + debug("channel %d: method SSH_SOCKS5_NOAUTH not found", + c->self); + return -1; + } + buffer_consume(&c->input, nmethods + 2); + buffer_put_char(&c->output, 0x05); /* version */ + buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ + FD_SET(c->sock, writeset); + c->flags |= SSH_SOCKS5_AUTHDONE; + debug2("channel %d: socks5 auth done", c->self); + return 0; /* need more */ + } + debug2("channel %d: socks5 post auth", c->self); + if (have < sizeof(s5_req)+1) + return 0; /* need more */ + memcpy((char *)&s5_req, p, sizeof(s5_req)); + if (s5_req.version != 0x05 || + s5_req.command != SSH_SOCKS5_CONNECT || + s5_req.reserved != 0x00) { + debug2("channel %d: only socks5 connect supported", c->self); + return -1; + } + switch(s5_req.atyp){ + case SSH_SOCKS5_IPV4: + addrlen = 4; + af = AF_INET; + break; + case SSH_SOCKS5_DOMAIN: + addrlen = p[sizeof(s5_req)]; + af = -1; + break; + case SSH_SOCKS5_IPV6: + addrlen = 16; + af = AF_INET6; + break; + default: + debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); + return -1; + } + if (have < 4 + addrlen + 2) + return 0; + buffer_consume(&c->input, sizeof(s5_req)); + if (s5_req.atyp == SSH_SOCKS5_DOMAIN) + buffer_consume(&c->input, 1); /* host string length */ + buffer_get(&c->input, (char *)&dest_addr, addrlen); + buffer_get(&c->input, (char *)&dest_port, 2); + dest_addr[addrlen] = '\0'; + if (s5_req.atyp == SSH_SOCKS5_DOMAIN) + strlcpy(c->path, dest_addr, sizeof(c->path)); + else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) + return -1; + c->host_port = ntohs(dest_port); + + debug2("channel %d: dynamic request: socks5 host %s port %u command %u", + c->self, c->path, c->host_port, s5_req.command); + + s5_rsp.version = 0x05; + s5_rsp.command = SSH_SOCKS5_SUCCESS; + s5_rsp.reserved = 0; /* ignored */ + s5_rsp.atyp = SSH_SOCKS5_IPV4; + ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY; + dest_port = 0; /* ignored */ + + buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp)); + buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr)); + buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port)); + return 1; +} + /* dynamic port forwarding */ static void channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) @@ -954,7 +1065,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) debug2("channel %d: pre_dynamic: have %d", c->self, have); /* buffer_dump(&c->input); */ /* check if the fixed size part of the packet is in buffer. */ - if (have < 4) { + if (have < 3) { /* need more */ FD_SET(c->sock, readset); return; @@ -965,6 +1076,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) case 0x04: ret = channel_decode_socks4(c, readset, writeset); break; + case 0x05: + ret = channel_decode_socks5(c, readset, writeset); + break; default: ret = -1; break; @@ -998,7 +1112,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) addrlen = sizeof(addr); newsock = accept(c->sock, &addr, &addrlen); if (c->single_connection) { - debug("single_connection: closing X11 listener."); + debug2("single_connection: closing X11 listener."); channel_close_fd(&c->sock); chan_mark_dead(c); } @@ -1014,8 +1128,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) nc = channel_new("accepted x11 socket", SSH_CHANNEL_OPENING, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, xstrdup(buf), 1); + c->local_window_max, c->local_maxpacket, 0, buf, 1); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring("x11"); @@ -1025,7 +1138,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) /* originator ipaddr and port */ packet_put_cstring(remote_ipaddr); if (datafellows & SSH_BUG_X11FWD) { - debug("ssh2 x11 bug compat mode"); + debug2("ssh2 x11 bug compat mode"); } else { packet_put_int(remote_port); } @@ -1130,10 +1243,8 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) return; } set_nodelay(newsock); - nc = channel_new(rtype, - nextstate, newsock, newsock, -1, - c->local_window_max, c->local_maxpacket, - 0, xstrdup(rtype), 1); + nc = channel_new(rtype, nextstate, newsock, newsock, -1, + c->local_window_max, c->local_maxpacket, 0, rtype, 1); nc->listening_port = c->listening_port; nc->host_port = c->host_port; strlcpy(nc->path, c->path, sizeof(nc->path)); @@ -1159,7 +1270,6 @@ static void channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) { Channel *nc; - char *name; int newsock; struct sockaddr addr; socklen_t addrlen; @@ -1171,11 +1281,10 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) error("accept from auth socket: %.100s", strerror(errno)); return; } - name = xstrdup("accepted auth socket"); nc = channel_new("accepted auth socket", SSH_CHANNEL_OPENING, newsock, newsock, -1, c->local_window_max, c->local_maxpacket, - 0, name, 1); + 0, "accepted auth socket", 1); if (compat20) { packet_start(SSH2_MSG_CHANNEL_OPEN); packet_put_cstring("auth-agent@openssh.com"); @@ -1248,16 +1357,16 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) if (len < 0 && (errno == EINTR || errno == EAGAIN)) return 1; if (len <= 0) { - debug("channel %d: read<=0 rfd %d len %d", + debug2("channel %d: read<=0 rfd %d len %d", c->self, c->rfd, len); if (c->type != SSH_CHANNEL_OPEN) { - debug("channel %d: not open", c->self); + debug2("channel %d: not open", c->self); chan_mark_dead(c); return -1; } else if (compat13) { buffer_clear(&c->output); c->type = SSH_CHANNEL_INPUT_DRAINING; - debug("channel %d: input draining.", c->self); + debug2("channel %d: input draining.", c->self); } else { chan_read_failed(c); } @@ -1265,7 +1374,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) } if (c->input_filter != NULL) { if (c->input_filter(c, buf, len) == -1) { - debug("channel %d: filter stops", c->self); + debug2("channel %d: filter stops", c->self); chan_read_failed(c); } } else { @@ -1298,12 +1407,12 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) return 1; if (len <= 0) { if (c->type != SSH_CHANNEL_OPEN) { - debug("channel %d: not open", c->self); + debug2("channel %d: not open", c->self); chan_mark_dead(c); return -1; } else if (compat13) { buffer_clear(&c->output); - debug("channel %d: input draining.", c->self); + debug2("channel %d: input draining.", c->self); c->type = SSH_CHANNEL_INPUT_DRAINING; } else { chan_write_failed(c); @@ -1510,16 +1619,16 @@ channel_garbage_collect(Channel *c) if (c->detach_user != NULL) { if (!chan_is_dead(c, 0)) return; - debug("channel %d: gc: notify user", c->self); + debug2("channel %d: gc: notify user", c->self); c->detach_user(c->self, NULL); /* if we still have a callback */ if (c->detach_user != NULL) return; - debug("channel %d: gc: user detached", c->self); + debug2("channel %d: gc: user detached", c->self); } if (!chan_is_dead(c, 1)) return; - debug("channel %d: garbage collecting", c->self); + debug2("channel %d: garbage collecting", c->self); channel_free(c); } @@ -1718,11 +1827,11 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) if (compat20) { if (data_len > c->local_maxpacket) { - log("channel %d: rcvd big packet %d, maxpack %d", + logit("channel %d: rcvd big packet %d, maxpack %d", c->self, data_len, c->local_maxpacket); } if (data_len > c->local_window) { - log("channel %d: rcvd too much data %d, win %d", + logit("channel %d: rcvd too much data %d, win %d", c->self, data_len, c->local_window); xfree(data); return; @@ -1749,7 +1858,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt) if (c == NULL) packet_disconnect("Received extended_data for bad channel %d.", id); if (c->type != SSH_CHANNEL_OPEN) { - log("channel %d: ext data for non open", id); + logit("channel %d: ext data for non open", id); return; } if (c->flags & CHAN_EOF_RCVD) { @@ -1763,13 +1872,13 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt) if (c->efd == -1 || c->extended_usage != CHAN_EXTENDED_WRITE || tcode != SSH2_EXTENDED_DATA_STDERR) { - log("channel %d: bad ext data", c->self); + logit("channel %d: bad ext data", c->self); return; } data = packet_get_string(&data_len); packet_check_eom(); if (data_len > c->local_window) { - log("channel %d: rcvd too much extended_data %d, win %d", + logit("channel %d: rcvd too much extended_data %d, win %d", c->self, data_len, c->local_window); xfree(data); return; @@ -1894,7 +2003,7 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) c->confirm(c->self, NULL); debug2("callback done"); } - debug("channel %d: open confirm rwindow %u rmax %u", c->self, + debug2("channel %d: open confirm rwindow %u rmax %u", c->self, c->remote_window, c->remote_maxpacket); } packet_check_eom(); @@ -1935,7 +2044,7 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt) msg = packet_get_string(NULL); lang = packet_get_string(NULL); } - log("channel %d: open failed: %s%s%s", id, + logit("channel %d: open failed: %s%s%s", id, reason2txt(reason), msg ? ": ": "", msg ? msg : ""); if (msg != NULL) xfree(msg); @@ -1962,7 +2071,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) c = channel_lookup(id); if (c == NULL || c->type != SSH_CHANNEL_OPEN) { - log("Received window adjust for " + logit("Received window adjust for " "non-open channel %d.", id); return; } @@ -1997,8 +2106,8 @@ channel_input_port_open(int type, u_int32_t seq, void *ctxt) originator_string, 1); c->remote_id = remote_id; } + xfree(originator_string); if (c == NULL) { - xfree(originator_string); packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); packet_send(); @@ -2059,7 +2168,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por continue; } /* Create a port to listen for the host. */ - sock = socket(ai->ai_family, SOCK_STREAM, 0); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { /* this is no error since kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); @@ -2095,7 +2204,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por /* Allocate a channel number for the socket. */ c = channel_new("port listener", type, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, - 0, xstrdup("port listener"), 1); + 0, "port listener", 1); strlcpy(c->path, host, sizeof(c->path)); c->host_port = port_to_connect; c->listening_port = listen_port; @@ -2168,7 +2277,7 @@ channel_request_remote_forwarding(u_short listen_port, success = 1; break; case SSH_SMSG_FAILURE: - log("Warning: Server denied remote port forwarding."); + logit("Warning: Server denied remote port forwarding."); break; default: /* Unknown packet */ @@ -2207,9 +2316,13 @@ channel_input_port_forward_request(int is_root, int gateway_ports) * privileged port. */ if (port < IPPORT_RESERVED && !is_root) - packet_disconnect("Requested forwarding of port %d but user is not root.", - port); + packet_disconnect( + "Requested forwarding of port %d but user is not root.", + port); + if (host_port == 0) + packet_disconnect("Dynamic forwarding denied."); #endif + /* Initiate forwarding */ channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports); @@ -2281,7 +2394,7 @@ connect_to(const char *host, u_short port) error("connect_to: getnameinfo failed"); continue; } - sock = socket(ai->ai_family, SOCK_STREAM, 0); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { if (ai->ai_next == NULL) error("socket: %.100s", strerror(errno)); @@ -2341,7 +2454,7 @@ channel_connect_to(const char *host, u_short port) } if (!permit) { - log("Received request to connect to host %.100s port %d, " + logit("Received request to connect to host %.100s port %d, " "but the request was denied.", host, port); return -1; } @@ -2382,7 +2495,8 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, for (ai = aitop; ai; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue; - sock = socket(ai->ai_family, SOCK_STREAM, 0); + sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); if (sock < 0) { if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { error("socket: %.100s", strerror(errno)); @@ -2401,7 +2515,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, } #endif if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - debug("bind port %d: %.100s", port, strerror(errno)); + debug2("bind port %d: %.100s", port, strerror(errno)); close(sock); if (ai->ai_next) @@ -2450,7 +2564,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, 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); + 0, "X11 inet listener", 1); nc->single_connection = single_connection; } @@ -2548,14 +2662,14 @@ x11_connect_display(void) } for (ai = aitop; ai; ai = ai->ai_next) { /* Create a socket. */ - sock = socket(ai->ai_family, SOCK_STREAM, 0); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { - debug("socket: %.100s", strerror(errno)); + debug2("socket: %.100s", strerror(errno)); continue; } /* Connect it to the display. */ if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { - debug("connect %.100s port %d: %.100s", buf, + debug2("connect %.100s port %d: %.100s", buf, 6000 + display_number, strerror(errno)); close(sock); continue; @@ -2607,11 +2721,11 @@ x11_input_open(int type, u_int32_t seq, void *ctxt) c->remote_id = remote_id; c->force_drain = 1; } + xfree(remote_host); if (c == NULL) { /* Send refusal to the remote host. */ packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(remote_id); - xfree(remote_host); } else { /* Send a confirmation to the remote host. */ packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); @@ -2733,7 +2847,6 @@ auth_input_open_request(int type, u_int32_t seq, void *ctxt) { Channel *c = NULL; int remote_id, sock; - char *name; /* Read the remote channel number from the message. */ remote_id = packet_get_int(); @@ -2752,9 +2865,8 @@ auth_input_open_request(int type, u_int32_t seq, void *ctxt) * agent. */ if (sock >= 0) { - name = xstrdup("authentication agent connection"); c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, - -1, 0, 0, 0, name, 1); + -1, 0, 0, 0, "authentication agent connection", 1); c->remote_id = remote_id; c->force_drain = 1; } diff --git a/crypto/openssh/cipher-3des1.c b/crypto/openssh/cipher-3des1.c new file mode 100644 index 0000000..6f9f5dd --- /dev/null +++ b/crypto/openssh/cipher-3des1.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2003 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: cipher-3des1.c,v 1.1 2003/05/15 03:08:29 markus Exp $"); + +#include <openssl/evp.h> +#include "xmalloc.h" +#include "log.h" + +#if OPENSSL_VERSION_NUMBER < 0x00906000L +#define SSH_OLD_EVP +#endif + +/* + * 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; +}; + +const EVP_CIPHER * evp_ssh1_3des(void); +void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); + +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); +#ifdef SSH_OLD_EVP + EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc); + EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc); + EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc); +#else + 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); + } +#endif + 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); + } +#ifdef SSH_OLD_EVP + EVP_Cipher(&c->k1, dest, (u_char *)src, len); + EVP_Cipher(&c->k2, dest, dest, len); + EVP_Cipher(&c->k3, dest, dest, len); +#else + 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); +#endif + 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); +} + +void +ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) +{ + struct ssh1_3des_ctx *c; + + if (len != 24) + fatal("%s: bad 3des iv length: %d", __func__, len); + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("%s: no 3des context", __func__); + if (doset) { + debug3("%s: Installed 3DES IV", __func__); + memcpy(c->k1.iv, iv, 8); + memcpy(c->k2.iv, iv + 8, 8); + memcpy(c->k3.iv, iv + 16, 8); + } else { + debug3("%s: Copying 3DES IV", __func__); + memcpy(iv, c->k1.iv, 8); + memcpy(iv + 8, c->k2.iv, 8); + memcpy(iv + 16, c->k3.iv, 8); + } +} + +const 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; +#ifndef SSH_OLD_EVP + ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; +#endif + return (&ssh1_3des); +} diff --git a/crypto/openssh/cipher-aes.c b/crypto/openssh/cipher-aes.c new file mode 100644 index 0000000..7ba9501 --- /dev/null +++ b/crypto/openssh/cipher-aes.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2003 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" +#if OPENSSL_VERSION_NUMBER < 0x00907000L +RCSID("$OpenBSD: cipher-aes.c,v 1.1 2003/05/15 03:08:29 markus Exp $"); + +#include <openssl/evp.h> +#include "rijndael.h" +#include "xmalloc.h" +#include "log.h" + +#if OPENSSL_VERSION_NUMBER < 0x00906000L +#define SSH_OLD_EVP +#endif + +#define RIJNDAEL_BLOCKSIZE 16 +struct ssh_rijndael_ctx +{ + rijndael_ctx r_ctx; + u_char r_iv[RIJNDAEL_BLOCKSIZE]; +}; + +const EVP_CIPHER * evp_rijndael(void); +void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); + +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); +} + +void +ssh_rijndael_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) +{ + struct ssh_rijndael_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("ssh_rijndael_iv: no context"); + if (doset) + memcpy(c->r_iv, iv, len); + else + memcpy(iv, c->r_iv, len); +} + +const 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; +#ifndef SSH_OLD_EVP + rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; +#endif + return (&rijndal_cbc); +} +#endif /* OPENSSL_VERSION_NUMBER */ diff --git a/crypto/openssh/cipher-bf1.c b/crypto/openssh/cipher-bf1.c new file mode 100644 index 0000000..5af695c --- /dev/null +++ b/crypto/openssh/cipher-bf1.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2003 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: cipher-bf1.c,v 1.1 2003/05/15 03:08:29 markus Exp $"); + +#include <openssl/evp.h> +#include "xmalloc.h" +#include "log.h" + +#if OPENSSL_VERSION_NUMBER < 0x00906000L +#define SSH_OLD_EVP +#endif + +/* + * SSH1 uses a variation on Blowfish, all bytes must be swapped before + * and after encryption/decryption. Thus the swap_bytes stuff (yuk). + */ + +const EVP_CIPHER * evp_ssh1_bf(void); + +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]; + } +} + +#ifdef SSH_OLD_EVP +static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (iv != NULL) + memcpy (&(ctx->oiv[0]), iv, 8); + memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8); + if (key != NULL) + BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx), + key); +} +#endif + +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); +} + +const 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; +#ifdef SSH_OLD_EVP + ssh1_bf.init = bf_ssh1_init; +#endif + ssh1_bf.do_cipher = bf_ssh1_cipher; + ssh1_bf.key_len = 32; + return (&ssh1_bf); +} diff --git a/crypto/openssh/cipher-ctr.c b/crypto/openssh/cipher-ctr.c new file mode 100644 index 0000000..4f0814b --- /dev/null +++ b/crypto/openssh/cipher-ctr.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2003 Markus Friedl <markus@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "includes.h" +RCSID("$OpenBSD: cipher-ctr.c,v 1.2 2003/06/17 18:14:23 markus Exp $"); + +#include <openssl/evp.h> + +#include "log.h" +#include "xmalloc.h" + +#if OPENSSL_VERSION_NUMBER < 0x00906000L +#define SSH_OLD_EVP +#endif + +#if OPENSSL_VERSION_NUMBER < 0x00907000L +#include "rijndael.h" +#define AES_KEY rijndael_ctx +#define AES_BLOCK_SIZE 16 +#define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b) +#define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1) +#else +#include <openssl/aes.h> +#endif + +const EVP_CIPHER *evp_aes_128_ctr(void); +void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); + +struct ssh_aes_ctr_ctx +{ + AES_KEY aes_ctx; + u_char aes_counter[AES_BLOCK_SIZE]; +}; + +/* + * increment counter 'ctr', + * the counter is of size 'len' bytes and stored in network-byte-order. + * (LSB at ctr[len-1], MSB at ctr[0]) + */ +static void +ssh_ctr_inc(u_char *ctr, u_int len) +{ + int i; + + for (i = len - 1; i >= 0; i--) + if (++ctr[i]) /* continue on overflow */ + return; +} + +static int +ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + u_int len) +{ + struct ssh_aes_ctr_ctx *c; + u_int n = 0; + u_char buf[AES_BLOCK_SIZE]; + + if (len == 0) + return (1); + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) + return (0); + + while ((len--) > 0) { + if (n == 0) { + AES_encrypt(c->aes_counter, buf, &c->aes_ctx); + ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE); + } + *(dest++) = *(src++) ^ buf[n]; + n = (n + 1) % AES_BLOCK_SIZE; + } + return (1); +} + +static int +ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, + int enc) +{ + struct ssh_aes_ctr_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) + AES_set_encrypt_key(key, ctx->key_len * 8, &c->aes_ctx); + if (iv != NULL) + memcpy(c->aes_counter, iv, AES_BLOCK_SIZE); + return (1); +} + +static int +ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct ssh_aes_ctr_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); +} + +void +ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) +{ + struct ssh_aes_ctr_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("ssh_aes_ctr_iv: no context"); + if (doset) + memcpy(c->aes_counter, iv, len); + else + memcpy(iv, c->aes_counter, len); +} + +const EVP_CIPHER * +evp_aes_128_ctr(void) +{ + static EVP_CIPHER aes_ctr; + + memset(&aes_ctr, 0, sizeof(EVP_CIPHER)); + aes_ctr.nid = NID_undef; + aes_ctr.block_size = AES_BLOCK_SIZE; + aes_ctr.iv_len = AES_BLOCK_SIZE; + aes_ctr.key_len = 16; + aes_ctr.init = ssh_aes_ctr_init; + aes_ctr.cleanup = ssh_aes_ctr_cleanup; + aes_ctr.do_cipher = ssh_aes_ctr; +#ifndef SSH_OLD_EVP + aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; +#endif + return (&aes_ctr); +} diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c index b5d3874..ce53367 100644 --- a/crypto/openssh/cipher.c +++ b/crypto/openssh/cipher.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $"); +RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $"); #include "xmalloc.h" #include "log.h" @@ -49,11 +49,14 @@ RCSID("$OpenBSD: cipher.c,v 1.62 2002/11/21 22:45:31 markus Exp $"); #endif #if OPENSSL_VERSION_NUMBER < 0x00907000L -#include "rijndael.h" -static const EVP_CIPHER *evp_rijndael(void); +extern const EVP_CIPHER *evp_rijndael(void); +extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); #endif -static const EVP_CIPHER *evp_ssh1_3des(void); -static const EVP_CIPHER *evp_ssh1_bf(void); +extern const EVP_CIPHER *evp_ssh1_bf(void); +extern const EVP_CIPHER *evp_ssh1_3des(void); +extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); +extern const EVP_CIPHER *evp_aes_128_ctr(void); +extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); struct Cipher { char *name; @@ -84,6 +87,11 @@ struct Cipher { { "rijndael-cbc@lysator.liu.se", SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc }, #endif +#if OPENSSL_VERSION_NUMBER >= 0x00906000L + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr }, +#endif { NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL } }; @@ -296,298 +304,6 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher, 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); -#ifdef SSH_OLD_EVP - EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc); - EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc); - EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc); -#else - 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); - } -#endif - 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); - } -#ifdef SSH_OLD_EVP - EVP_Cipher(&c->k1, dest, (u_char *)src, len); - EVP_Cipher(&c->k2, dest, dest, len); - EVP_Cipher(&c->k3, dest, dest, len); -#else - 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); -#endif - 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 const 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; -#ifndef SSH_OLD_EVP - ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; -#endif - 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]; - } -} - -#ifdef SSH_OLD_EVP -static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - if (iv != NULL) - memcpy (&(ctx->oiv[0]), iv, 8); - memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8); - if (key != NULL) - BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx), - key); -} -#endif -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 const 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; -#ifdef SSH_OLD_EVP - ssh1_bf.init = bf_ssh1_init; -#endif - ssh1_bf.do_cipher = bf_ssh1_cipher; - ssh1_bf.key_len = 32; - return (&ssh1_bf); -} - -#if OPENSSL_VERSION_NUMBER < 0x00907000L -/* 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 const 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; -#ifndef SSH_OLD_EVP - rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | - EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; -#endif - return (&rijndal_cbc); -} -#endif - /* * Exports an IV from the CipherContext required to export the key * state back from the unprivileged child to the privileged parent @@ -611,7 +327,6 @@ void cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) { Cipher *c = cc->cipher; - u_char *civ = NULL; int evplen; switch (c->number) { @@ -624,45 +339,28 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) if (evplen != len) fatal("%s: wrong iv length %d != %d", __func__, evplen, len); - #if OPENSSL_VERSION_NUMBER < 0x00907000L - if (c->evptype == evp_rijndael) { - struct ssh_rijndael_ctx *aesc; - - aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp); - if (aesc == NULL) - fatal("%s: no rijndael context", __func__); - civ = aesc->r_iv; - } else + if (c->evptype == evp_rijndael) + ssh_rijndael_iv(&cc->evp, 0, iv, len); + else #endif - { - civ = cc->evp.iv; - } + if (c->evptype == evp_aes_128_ctr) + ssh_aes_ctr_iv(&cc->evp, 0, iv, len); + else + memcpy(iv, cc->evp.iv, len); + break; + case SSH_CIPHER_3DES: + ssh1_3des_iv(&cc->evp, 0, iv, 24); break; - case SSH_CIPHER_3DES: { - struct ssh1_3des_ctx *desc; - if (len != 24) - fatal("%s: bad 3des iv length: %d", __func__, len); - desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); - if (desc == NULL) - fatal("%s: no 3des context", __func__); - debug3("%s: Copying 3DES IV", __func__); - memcpy(iv, desc->k1.iv, 8); - memcpy(iv + 8, desc->k2.iv, 8); - memcpy(iv + 16, desc->k3.iv, 8); - return; - } default: fatal("%s: bad cipher %d", __func__, c->number); } - memcpy(iv, civ, len); } void cipher_set_keyiv(CipherContext *cc, u_char *iv) { Cipher *c = cc->cipher; - u_char *div = NULL; int evplen = 0; switch (c->number) { @@ -672,36 +370,22 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); if (evplen == 0) return; - #if OPENSSL_VERSION_NUMBER < 0x00907000L - if (c->evptype == evp_rijndael) { - struct ssh_rijndael_ctx *aesc; - - aesc = EVP_CIPHER_CTX_get_app_data(&cc->evp); - if (aesc == NULL) - fatal("%s: no rijndael context", __func__); - div = aesc->r_iv; - } else + if (c->evptype == evp_rijndael) + ssh_rijndael_iv(&cc->evp, 1, iv, evplen); + else #endif - { - div = cc->evp.iv; - } + if (c->evptype == evp_aes_128_ctr) + ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); + else + memcpy(cc->evp.iv, iv, evplen); + break; + case SSH_CIPHER_3DES: + ssh1_3des_iv(&cc->evp, 1, iv, 24); break; - case SSH_CIPHER_3DES: { - struct ssh1_3des_ctx *desc; - desc = EVP_CIPHER_CTX_get_app_data(&cc->evp); - if (desc == NULL) - fatal("%s: no 3des context", __func__); - debug3("%s: Installed 3DES IV", __func__); - memcpy(desc->k1.iv, iv, 8); - memcpy(desc->k2.iv, iv + 8, 8); - memcpy(desc->k3.iv, iv + 16, 8); - return; - } default: fatal("%s: bad cipher %d", __func__, c->number); } - memcpy(div, iv, evplen); } #if OPENSSL_VERSION_NUMBER < 0x00907000L diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c index af207c0..d8def78 100644 --- a/crypto/openssh/clientloop.c +++ b/crypto/openssh/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.107 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.112 2003/06/28 16:23:06 deraadt Exp $"); #include "ssh.h" #include "ssh1.h" @@ -395,9 +395,9 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr) /* Flush stdout and stderr buffers. */ if (buffer_len(bout) > 0) - atomicio(write, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); + atomicio(vwrite, fileno(stdout), buffer_ptr(bout), buffer_len(bout)); if (buffer_len(berr) > 0) - atomicio(write, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); + atomicio(vwrite, fileno(stderr), buffer_ptr(berr), buffer_len(berr)); leave_raw_mode(); @@ -490,13 +490,13 @@ process_cmdline(void) if (*s == 0) goto out; if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) { - log("Invalid command."); + logit("Invalid command."); goto out; } if (s[1] == 'L') local = 1; if (!local && !compat20) { - log("Not supported for SSH protocol version 1."); + logit("Not supported for SSH protocol version 1."); goto out; } s += 2; @@ -507,24 +507,24 @@ process_cmdline(void) sfwd_port, buf, sfwd_host_port) != 3 && sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", sfwd_port, buf, sfwd_host_port) != 3) { - log("Bad forwarding specification."); + logit("Bad forwarding specification."); goto out; } if ((fwd_port = a2port(sfwd_port)) == 0 || (fwd_host_port = a2port(sfwd_host_port)) == 0) { - log("Bad forwarding port(s)."); + logit("Bad forwarding port(s)."); goto out; } if (local) { if (channel_setup_local_fwd_listener(fwd_port, buf, fwd_host_port, options.gateway_ports) < 0) { - log("Port forwarding failed."); + logit("Port forwarding failed."); goto out; } } else channel_request_remote_forwarding(fwd_port, buf, fwd_host_port); - log("Forwarding port."); + logit("Forwarding port."); out: signal(SIGINT, handler); enter_raw_mode(); @@ -574,10 +574,23 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) /* We have been continued. */ continue; + case 'B': + if (compat20) { + snprintf(string, sizeof string, + "%cB\r\n", escape_char); + buffer_append(berr, string, + strlen(string)); + channel_request_start(session_ident, + "break", 0); + packet_put_int(1000); + packet_send(); + } + continue; + case 'R': if (compat20) { if (datafellows & SSH_BUG_NOREKEY) - log("Server does not support re-keying"); + logit("Server does not support re-keying"); else need_rekeying = 1; } @@ -636,6 +649,7 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len) "%c?\r\n\ Supported escape sequences:\r\n\ %c. - terminate connection\r\n\ +%cB - send a BREAK to the remote system\r\n\ %cC - open a command line\r\n\ %cR - Request rekey (SSH protocol 2 only)\r\n\ %c^Z - suspend ssh\r\n\ @@ -646,7 +660,7 @@ Supported escape sequences:\r\n\ (Note that escapes are only recognized immediately after newline.)\r\n", escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, - escape_char, escape_char); + escape_char, escape_char, escape_char); buffer_append(berr, string, strlen(string)); continue; @@ -968,9 +982,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) /* Do channel operations unless rekeying in progress. */ if (!rekeying) { channel_after_select(readset, writeset); - - if (need_rekeying) { - debug("user requests rekeying"); + if (need_rekeying || packet_need_rekeying()) { + debug("need rekeying"); xxx_kex->done = 0; kex_send_kexinit(xxx_kex); need_rekeying = 0; @@ -1146,7 +1159,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) c = channel_new("forwarded-tcpip", SSH_CHANNEL_CONNECTING, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - xstrdup(originator_address), 1); + originator_address, 1); xfree(originator_address); xfree(listen_address); return c; @@ -1182,8 +1195,7 @@ client_request_x11(const char *request_type, int rchan) return NULL; c = channel_new("x11", SSH_CHANNEL_X11_OPEN, sock, sock, -1, - CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, - xstrdup("x11"), 1); + CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1); c->force_drain = 1; return c; } @@ -1205,7 +1217,7 @@ client_request_agent(const char *request_type, int rchan) c = channel_new("authentication agent connection", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, - xstrdup("authentication agent connection"), 1); + "authentication agent connection", 1); c->force_drain = 1; return c; } diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c index 5e1774a..af1d143 100644 --- a/crypto/openssh/compat.c +++ b/crypto/openssh/compat.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.66 2003/04/01 10:31:26 markus Exp $"); +RCSID("$OpenBSD: compat.c,v 1.69 2003/08/29 10:03:15 markus Exp $"); #include "buffer.h" #include "packet.h" @@ -79,7 +79,11 @@ compat_datafellows(const char *version) { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH_2.*," "OpenSSH_3.0*," - "OpenSSH_3.1*", SSH_BUG_EXTEOF}, + "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_BUG_GSSAPI_BER}, + { "OpenSSH_3.2*," + "OpenSSH_3.3*," + "OpenSSH_3.4*," + "OpenSSH_3.5*", SSH_BUG_GSSAPI_BER}, { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH*", 0 }, { "*MindTerm*", 0 }, @@ -131,12 +135,9 @@ compat_datafellows(const char *version) "1.2.19*," "1.2.20*," "1.2.21*," - "1.2.22*", SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, + "1.2.22*", SSH_BUG_IGNOREMSG }, { "1.3.2*", /* F-Secure */ - SSH_BUG_IGNOREMSG|SSH_BUG_K5USER }, - { "1.2.1*," - "1.2.2*," - "1.2.3*", SSH_BUG_K5USER }, + SSH_BUG_IGNOREMSG }, { "*SSH Compatible Server*", /* Netscreen */ SSH_BUG_PASSWORDPAD }, { "*OSU_0*," @@ -188,7 +189,7 @@ proto_spec(const char *spec) ret |= SSH_PROTO_2; break; default: - log("ignoring bad proto spec: '%s'.", p); + logit("ignoring bad proto spec: '%s'.", p); break; } } diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h index 881e450..7a50044 100644 --- a/crypto/openssh/compat.h +++ b/crypto/openssh/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.34 2003/04/01 10:31:26 markus Exp $ */ +/* $OpenBSD: compat.h,v 1.36 2003/08/29 10:03:15 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -53,9 +53,9 @@ #define SSH_BUG_DERIVEKEY 0x00040000 #define SSH_BUG_DUMMYCHAN 0x00100000 #define SSH_BUG_EXTEOF 0x00200000 -#define SSH_BUG_K5USER 0x00400000 -#define SSH_BUG_PROBE 0x00800000 -#define SSH_BUG_FIRSTKEX 0x01000000 +#define SSH_BUG_PROBE 0x00400000 +#define SSH_BUG_FIRSTKEX 0x00800000 +#define SSH_BUG_GSSAPI_BER 0x01000000 void enable_compat13(void); void enable_compat20(void); diff --git a/crypto/openssh/configure.ac b/crypto/openssh/configure.ac index 47fef0c..916dc10 100644 --- a/crypto/openssh/configure.ac +++ b/crypto/openssh/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.113 2003/03/21 01:18:09 mouring Exp $ +# $Id: configure.ac,v 1.154.2.11 2003/09/23 09:24:21 djm Exp $ AC_INIT AC_CONFIG_SRCDIR([ssh.c]) @@ -9,6 +9,7 @@ AC_CANONICAL_HOST AC_C_BIGENDIAN # Checks for programs. +AC_PROG_AWK AC_PROG_CPP AC_PROG_RANLIB AC_PROG_INSTALL @@ -54,36 +55,56 @@ fi # Check for some target-specific stuff case "$host" in *-*-aix*) - AFS_LIBS="-lld" CPPFLAGS="$CPPFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" - if (test "$LD" != "gcc" && test -z "$blibpath"); then - AC_MSG_CHECKING([if linkage editor ($LD) accepts -blibpath]) - saved_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -blibpath:/usr/lib:/lib:/usr/local/lib" - AC_TRY_LINK([], - [], - [ - AC_MSG_RESULT(yes) - blibpath="/usr/lib:/lib:/usr/local/lib" - ], - [ AC_MSG_RESULT(no) ] - ) - LDFLAGS="$saved_LDFLAGS" + AC_MSG_CHECKING([how to specify blibpath for linker ($LD)]) + if (test -z "$blibpath"); then + blibpath="/usr/lib:/lib:/usr/local/lib" + fi + saved_LDFLAGS="$LDFLAGS" + for tryflags in -blibpath: -Wl,-blibpath: -Wl,-rpath, ;do + if (test -z "$blibflags"); then + LDFLAGS="$saved_LDFLAGS $tryflags$blibpath" + AC_TRY_LINK([], [], [blibflags=$tryflags]) + fi + done + if (test -z "$blibflags"); then + AC_MSG_RESULT(not found) + AC_MSG_ERROR([*** must be able to specify blibpath on AIX - check config.log]) + else + AC_MSG_RESULT($blibflags) fi + LDFLAGS="$saved_LDFLAGS" + dnl Check for authenticate. Might be in libs.a on older AIXes AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)], [AC_CHECK_LIB(s,authenticate, [ AC_DEFINE(WITH_AIXAUTHENTICATE) LIBS="$LIBS -ls" ]) ]) + dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2) + AC_CHECK_DECL(loginfailed, + [AC_MSG_CHECKING(if loginfailed takes 4 arguments) + AC_TRY_COMPILE( + [#include <usersec.h>], + [(void)loginfailed("user","host","tty",0);], + [AC_MSG_RESULT(yes) + AC_DEFINE(AIX_LOGINFAILED_4ARG)], + [AC_MSG_RESULT(no)] + )], + [], + [#include <usersec.h>] + ) + AC_CHECK_FUNCS(setauthdb) AC_DEFINE(BROKEN_GETADDRINFO) AC_DEFINE(BROKEN_REALPATH) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) dnl AIX handles lastlog as part of its login message AC_DEFINE(DISABLE_LASTLOG) AC_DEFINE(LOGIN_NEEDS_UTMPX) - AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_CLOBBER_ARGV) - AC_DEFINE(SETPROCTITLE_PS_PADDING, '\0') + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) ;; *-*-cygwin*) check_for_libcrypt_later=1 @@ -91,7 +112,6 @@ case "$host" in AC_DEFINE(HAVE_CYGWIN) AC_DEFINE(USE_PIPES) AC_DEFINE(DISABLE_SHADOW) - AC_DEFINE(IPV4_DEFAULT) AC_DEFINE(IP_TOS_IS_BROKEN) AC_DEFINE(NO_X11_UNIX_SOCKETS) AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT) @@ -112,6 +132,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) [AC_MSG_RESULT(buggy) AC_DEFINE(BROKEN_GETADDRINFO)], [AC_MSG_RESULT(assume it is working)]) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) ;; *-*-hpux10.26) if test -z "$GCC"; then @@ -125,7 +148,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) - AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(SPT_TYPE,SPT_PSTAT) LIBS="$LIBS -lsec -lsecpw" AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) disable_ptmx_check=yes @@ -141,7 +165,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) - AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(SPT_TYPE,SPT_PSTAT) LIBS="$LIBS -lsec" AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) ;; @@ -154,7 +179,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) - AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_PSTAT) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(SPT_TYPE,SPT_PSTAT) LIBS="$LIBS -lsec" AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) ;; @@ -164,6 +190,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) PATH="$PATH:/usr/etc" AC_DEFINE(BROKEN_INET_NTOA) AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; *-*-irix6*) CPPFLAGS="$CPPFLAGS -I/usr/local/include" @@ -174,16 +201,26 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(WITH_IRIX_AUDIT) AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)]) AC_DEFINE(BROKEN_INET_NTOA) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; *-*-linux*) no_dev_ptmx=1 check_for_libcrypt_later=1 + check_for_openpty_ctty_bug=1 AC_DEFINE(DONT_TRY_OTHER_AF) AC_DEFINE(PAM_TTY_KLUDGE) - AC_DEFINE(SETPROCTITLE_STRATEGY,PS_USE_CLOBBER_ARGV) - AC_DEFINE(SETPROCTITLE_PS_PADDING, '\0') + AC_DEFINE(LOCKED_PASSWD_PREFIX, "!!") + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) inet6_default_4in6=yes + case `uname -r` in + 1.*|2.0.*) + AC_DEFINE(BROKEN_CMSG_TYPE) + ;; + esac ;; mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(HAVE_NEWS4) @@ -196,6 +233,11 @@ mips-sony-bsd|mips-sony-newsos4) *-*-freebsd*) check_for_libcrypt_later=1 ;; +*-*-bsdi*) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + ;; *-next-*) conf_lastlog_location="/usr/adm/lastlog" conf_utmp_location=/etc/utmp @@ -216,7 +258,10 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_TERM) AC_DEFINE(PAM_TTY_KLUDGE) - AC_DEFINE(STREAMS_PUSH_ACQUIRES_CTTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") + # Pushing STREAMS modules will cause sshd to acquire a controlling tty. + AC_DEFINE(SSHD_ACQUIRES_CTTY) + external_path_file=/etc/default/login # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) @@ -243,6 +288,10 @@ mips-sony-bsd|mips-sony-newsos4) LDFLAGS="$LDFLAGS -L/usr/local/lib" LIBS="$LIBS -lc89" AC_DEFINE(USE_PIPES) + AC_DEFINE(SSHD_ACQUIRES_CTTY) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) ;; *-sni-sysv*) CPPFLAGS="$CPPFLAGS -I/usr/local/include" @@ -251,6 +300,8 @@ mips-sony-bsd|mips-sony-newsos4) IPADDR_IN_DISPLAY=yes AC_DEFINE(USE_PIPES) AC_DEFINE(IP_TOS_IS_BROKEN) + AC_DEFINE(SSHD_ACQUIRES_CTTY) + external_path_file=/etc/default/login # /usr/ucblib/libucb.a no longer needed on ReliantUNIX # Attention: always take care to bind libsocket and libnsl before libc, # otherwise you will find lots of "SIOCGPGRP errno 22" on syslog @@ -259,11 +310,17 @@ mips-sony-bsd|mips-sony-newsos4) CPPFLAGS="$CPPFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" AC_DEFINE(USE_PIPES) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) ;; *-*-sysv5*) CPPFLAGS="$CPPFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" AC_DEFINE(USE_PIPES) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) ;; *-*-sysv*) CPPFLAGS="$CPPFLAGS -I/usr/local/include" @@ -280,6 +337,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(HAVE_SECUREWARE) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(BROKEN_SAVED_UIDS) + AC_DEFINE(WITH_ABBREV_NO_TTY) AC_CHECK_FUNCS(getluid setluid) MANTYPE=man do_sco3_extra_lib_check=yes @@ -296,6 +354,10 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(HAVE_SECUREWARE) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_FD_PASSING) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + AC_DEFINE(WITH_ABBREV_NO_TTY) AC_CHECK_FUNCS(getluid setluid) MANTYPE=man ;; @@ -306,6 +368,14 @@ mips-sony-bsd|mips-sony-newsos4) LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; +*-*-unicosmp*) + AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_FD_PASSING) + LDFLAGS="$LDFLAGS" + LIBS="$LIBS -lgen -lacid" + MANTYPE=cat + ;; *-*-unicos*) AC_DEFINE(USE_PIPES) AC_DEFINE(DISABLE_FD_PASSING) @@ -338,6 +408,11 @@ mips-sony-bsd|mips-sony-newsos4) fi fi AC_DEFINE(DISABLE_FD_PASSING) + AC_DEFINE(BROKEN_GETADDRINFO) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin") ;; *-*-nto-qnx) @@ -383,17 +458,29 @@ AC_ARG_WITH(libs, ] ) +AC_MSG_CHECKING(compiler and flags for sanity) +AC_TRY_RUN([ +#include <stdio.h> +int main(){exit(0);} + ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***]) + ] +) + # Checks for header files. -AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \ - getopt.h glob.h ia.h lastlog.h libgen.h limits.h login.h \ +AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \ + getopt.h glob.h ia.h lastlog.h limits.h login.h \ login_cap.h maillock.h netdb.h netgroup.h \ netinet/in_systm.h paths.h pty.h readpassphrase.h \ rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \ - strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \ - sys/mman.h sys/pstat.h sys/select.h sys/stat.h \ + strings.h sys/strtio.h sys/audit.h sys/bitypes.h sys/bsdtty.h \ + sys/cdefs.h sys/mman.h sys/pstat.h sys/select.h sys/stat.h \ sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h \ sys/un.h time.h tmpdir.h ttyent.h usersec.h \ - util.h utime.h utmp.h utmpx.h) + util.h utime.h utmp.h utmpx.h vis.h) # Checks for libraries. AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match)) @@ -406,8 +493,46 @@ if test "x$with_tcp_wrappers" != "xno" ; then fi fi +dnl IRIX and Solaris 2.5.1 have dirname() in libgen +AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[ + AC_CHECK_LIB(gen, dirname,[ + AC_CACHE_CHECK([for broken dirname], + ac_cv_have_broken_dirname, [ + save_LIBS="$LIBS" + LIBS="$LIBS -lgen" + AC_TRY_RUN( + [ +#include <libgen.h> +#include <string.h> + +int main(int argc, char **argv) { + char *s, buf[32]; + + strncpy(buf,"/etc", 32); + s = dirname(buf); + if (!s || strncmp(s, "/", 32) != 0) { + exit(1); + } else { + exit(0); + } +} + ], + [ ac_cv_have_broken_dirname="no" ], + [ ac_cv_have_broken_dirname="yes" ] + ) + LIBS="$save_LIBS" + ]) + if test "x$ac_cv_have_broken_dirname" = "xno" ; then + LIBS="$LIBS -lgen" + AC_DEFINE(HAVE_DIRNAME) + AC_CHECK_HEADERS(libgen.h) + fi + ]) +]) + AC_CHECK_FUNC(getspnam, , AC_CHECK_LIB(gen, getspnam, LIBS="$LIBS -lgen")) +AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME)) AC_ARG_WITH(rpath, [ --without-rpath Disable auto-added -R linker paths], @@ -604,60 +729,47 @@ AC_ARG_WITH(tcp-wrappers, dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS(\ - arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename bcopy \ - bindresvport_sa clock fchmod fchown freeaddrinfo futimes \ - gai_strerror getaddrinfo getcwd getgrouplist getnameinfo getopt \ - getpeereid _getpty getrlimit getrusage getttyent glob inet_aton \ + arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename \ + bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \ + getaddrinfo getcwd getgrouplist getnameinfo getopt \ + getpeereid _getpty getrlimit getttyent glob inet_aton \ inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \ - mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openpty pstat \ - readpassphrase realpath recvmsg rresvport_af sendmsg setdtablesize \ - setegid setenv seteuid setgroups setlogin setpcred setproctitle \ - setresgid setreuid setrlimit setsid setvbuf sigaction sigvec \ - snprintf socketpair strerror strlcat strlcpy strmode strnvis \ - sysconf tcgetpgrp truncate utimes vhangup vsnprintf waitpid \ + mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \ + pstat readpassphrase realpath recvmsg rresvport_af sendmsg \ + setdtablesize setegid setenv seteuid setgroups setlogin setpcred \ + setproctitle setregid setresgid setresuid setreuid setrlimit \ + setsid setvbuf sigaction sigvec snprintf socketpair strerror \ + strlcat strlcpy strmode strnvis sysconf tcgetpgrp \ + truncate utimes vhangup vsnprintf waitpid \ ) -AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP)) +# IRIX has a const char return value for gai_strerror() +AC_CHECK_FUNCS(gai_strerror,[ + AC_DEFINE(HAVE_GAI_STRERROR) + AC_TRY_COMPILE([ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> -dnl Make sure strsep prototype is defined before defining HAVE_STRSEP -AC_CHECK_DECL(strsep, [AC_CHECK_FUNCS(strsep)]) +const char *gai_strerror(int);],[ +char *str; -dnl IRIX and Solaris 2.5.1 have dirname() in libgen -AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[ - AC_CHECK_LIB(gen, dirname,[ - AC_CACHE_CHECK([for broken dirname], - ac_cv_have_broken_dirname, [ - save_LIBS="$LIBS" - LIBS="$LIBS -lgen" - AC_TRY_RUN( - [ -#include <libgen.h> -#include <string.h> +str = gai_strerror(0);],[ + AC_DEFINE(HAVE_CONST_GAI_STRERROR_PROTO, 1, + [Define if gai_strerror() returns const char *])])]) -int main(int argc, char **argv) { - char *s, buf[32]; +AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP)) - strncpy(buf,"/etc", 32); - s = dirname(buf); - if (!s || strncmp(s, "/", 32) != 0) { - exit(1); - } else { - exit(0); - } -} - ], - [ ac_cv_have_broken_dirname="no" ], - [ ac_cv_have_broken_dirname="yes" ] - ) - LIBS="$save_LIBS" - ]) - if test "x$ac_cv_have_broken_dirname" = "xno" ; then - LIBS="$LIBS -lgen" - AC_DEFINE(HAVE_DIRNAME) - AC_CHECK_HEADERS(libgen.h) - fi - ]) -]) +dnl Make sure prototypes are defined for these before using them. +AC_CHECK_DECL(strsep, [AC_CHECK_FUNCS(strsep)]) +AC_CHECK_DECL(getrusage, [AC_CHECK_FUNCS(getrusage)]) + +dnl tcsendbreak might be a macro +AC_CHECK_DECL(tcsendbreak, + [AC_DEFINE(HAVE_TCSENDBREAK)], + [AC_CHECK_FUNCS(tcsendbreak)], + [#include <termios.h>] +) dnl Checks for time functions AC_CHECK_FUNCS(gettimeofday time) @@ -721,6 +833,53 @@ unlink(template); exit(0); ) fi +dnl make sure that openpty does not reacquire controlling terminal +if test ! -z "$check_for_openpty_ctty_bug"; then + AC_MSG_CHECKING(if openpty correctly handles controlling tty) + AC_TRY_RUN( + [ +#include <stdio.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> + +int +main() +{ + pid_t pid; + int fd, ptyfd, ttyfd, status; + + pid = fork(); + if (pid < 0) { /* failed */ + exit(1); + } else if (pid > 0) { /* parent */ + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + else + exit(2); + } else { /* child */ + close(0); close(1); close(2); + setsid(); + openpty(&ptyfd, &ttyfd, NULL, NULL, NULL); + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) + exit(3); /* Acquired ctty: broken */ + else + exit(0); /* Did not acquire ctty: OK */ + } +} + ], + [ + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + AC_DEFINE(SSHD_ACQUIRES_CTTY) + ] + ) +fi + AC_FUNC_GETPGRP # Check for PAM libs @@ -736,6 +895,7 @@ AC_ARG_WITH(pam, AC_CHECK_LIB(dl, dlopen, , ) AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing])) AC_CHECK_FUNCS(pam_getenvlist) + AC_CHECK_FUNCS(pam_putenv) disable_shadow=yes PAM_MSG="yes" @@ -900,13 +1060,15 @@ int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); } ], [ AC_MSG_RESULT(no) - AC_MSG_ERROR(Your OpenSSL headers do not match your library) + AC_MSG_ERROR([Your OpenSSL headers do not match your library. +Check config.log for details. +Also see contrib/findssl.sh for help identifying header/library mismatches.]) ] ) # 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 +if test "x$check_for_libcrypt_later" = "x1"; then AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt") fi @@ -1747,7 +1909,6 @@ if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then fi SCARD_MSG="no" - # Check whether user wants sectok support AC_ARG_WITH(sectok, [ --with-sectok Enable smartcard support using libsectok], @@ -1797,6 +1958,29 @@ if test x$opensc_config_prefix != x ; then fi fi +# Check whether user wants DNS support +DNS_MSG="no" +AC_ARG_WITH(dns, + [ --with-dns Support for fetching keys from DNS (experimental)], + [ + if test "x$withval" != "xno" ; then + DNS_MSG="yes" + AC_DEFINE(DNS) + AC_SEARCH_LIBS(getrrsetbyname, resolv, + [AC_DEFINE(HAVE_GETRRSETBYNAME)], + [ + # Needed by our getrrsetbyname() + AC_SEARCH_LIBS(res_query, resolv) + AC_SEARCH_LIBS(dn_expand, resolv) + AC_CHECK_FUNCS(_getshort _getlong) + AC_CHECK_MEMBER(HEADER.ad, + [AC_DEFINE(HAVE_HEADER_AD)],, + [#include <arpa/nameser.h>]) + ]) + fi + ] +) + # Check whether user wants Kerberos 5 support KRB5_MSG="no" AC_ARG_WITH(kerberos5, @@ -1829,93 +2013,38 @@ AC_ARG_WITH(kerberos5, if test ! -z "$blibpath" ; then blibpath="$blibpath:${KRB5ROOT}/lib" fi - AC_CHECK_LIB(resolv, dn_expand, , ) + AC_SEARCH_LIBS(dn_expand, resolv) + + AC_CHECK_LIB(gssapi,gss_init_sec_context, + [ AC_DEFINE(GSSAPI) + K5LIBS="-lgssapi $K5LIBS" ], + [ AC_CHECK_LIB(gssapi_krb5,gss_init_sec_context, + [ AC_DEFINE(GSSAPI) + K5LIBS="-lgssapi_krb5 $K5LIBS" ], + AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]), + $K5LIBS) + ], + $K5LIBS) + + AC_CHECK_HEADER(gssapi.h, , + [ unset ac_cv_header_gssapi_h + CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" + AC_CHECK_HEADERS(gssapi.h, , + AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail]) + ) + ] + ) + + oldCPP="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" + AC_CHECK_HEADER(gssapi_krb5.h, , + [ CPPFLAGS="$oldCPP" ]) KRB5=yes fi ] ) -# Check whether user wants Kerberos 4 support -KRB4_MSG="no" -AC_ARG_WITH(kerberos4, - [ --with-kerberos4=PATH Enable Kerberos 4 support], - [ - if test "x$withval" != "xno" ; then - if test "x$withval" != "xyes" ; then - CPPFLAGS="$CPPFLAGS -I${withval}/include" - LDFLAGS="$LDFLAGS -L${withval}/lib" - if test ! -z "$need_dash_r" ; then - LDFLAGS="$LDFLAGS -R${withval}/lib" - fi - if test ! -z "$blibpath" ; then - blibpath="$blibpath:${withval}/lib" - fi - else - if test -d /usr/include/kerberosIV ; then - CPPFLAGS="$CPPFLAGS -I/usr/include/kerberosIV" - fi - fi - - AC_CHECK_HEADERS(krb.h) - if test "$ac_cv_header_krb_h" != yes; then - AC_MSG_WARN([Cannot find krb.h, build may fail]) - fi - AC_CHECK_LIB(krb, main) - if test "$ac_cv_lib_krb_main" != yes; then - AC_CHECK_LIB(krb4, main) - if test "$ac_cv_lib_krb4_main" != yes; then - AC_MSG_WARN([Cannot find libkrb nor libkrb4, build may fail]) - else - KLIBS="-lkrb4" - fi - else - KLIBS="-lkrb" - fi - AC_CHECK_LIB(des, des_cbc_encrypt) - if test "$ac_cv_lib_des_des_cbc_encrypt" != yes; then - AC_CHECK_LIB(des425, des_cbc_encrypt) - if test "$ac_cv_lib_des425_des_cbc_encrypt" != yes; then - AC_MSG_WARN([Cannot find libdes nor libdes425, build may fail]) - else - KLIBS="-ldes425" - fi - else - KLIBS="-ldes" - fi - AC_CHECK_LIB(resolv, dn_expand, , ) - KRB4=yes - KRB4_MSG="yes" - AC_DEFINE(KRB4) - fi - ] -) - -# Check whether user wants AFS support -AFS_MSG="no" -AC_ARG_WITH(afs, - [ --with-afs=PATH Enable AFS support], - [ - if test "x$withval" != "xno" ; then - - if test "x$withval" != "xyes" ; then - CPPFLAGS="$CPPFLAGS -I${withval}/include" - LDFLAGS="$LDFLAGS -L${withval}/lib" - fi - - if test -z "$KRB4" ; then - AC_MSG_WARN([AFS requires Kerberos IV support, build may fail]) - fi - - LIBS="-lkafs $LIBS" - if test ! -z "$AFS_LIBS" ; then - LIBS="$LIBS $AFS_LIBS" - fi - AC_DEFINE(AFS) - AFS_MSG="yes" - fi - ] -) -LIBS="$LIBS $KLIBS $K5LIBS" +LIBS="$LIBS $K5LIBS" # Looking for programs, paths and files @@ -2085,30 +2214,52 @@ else ) fi +# check for /etc/default/login and use it if present. +AC_ARG_ENABLE(etc-default-login, + [ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],, +[ +AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ]) + +if test "x$external_path_file" = "x/etc/default/login"; then + AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN) +fi +]) + dnl BSD systems use /etc/login.conf so --with-default-path= has no effect if test $ac_cv_func_login_getcapbool = "yes" -a \ $ac_cv_header_login_cap_h = "yes" ; then - USES_LOGIN_CONF=yes + external_path_file=/etc/login.conf fi + # Whether to mess with the default path SERVER_PATH_MSG="(default)" AC_ARG_WITH(default-path, [ --with-default-path= Specify default \$PATH environment for server], [ - if test "$USES_LOGIN_CONF" = "yes" ; then + if test "x$external_path_file" = "x/etc/login.conf" ; then AC_MSG_WARN([ --with-default-path=PATH has no effect on this system. Edit /etc/login.conf instead.]) elif test "x$withval" != "xno" ; then + if test ! -z "$external_path_file" ; then + AC_MSG_WARN([ +--with-default-path=PATH will only be used if PATH is not defined in +$external_path_file .]) + fi user_path="$withval" SERVER_PATH_MSG="$withval" fi ], - [ if test "$USES_LOGIN_CONF" = "yes" ; then - AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf]) + [ if test "x$external_path_file" = "x/etc/login.conf" ; then + AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf]) else - AC_TRY_RUN( - [ + if test ! -z "$external_path_file" ; then + AC_MSG_WARN([ +If PATH is defined in $external_path_file, ensure the path to scp is included, +otherwise scp will not work.]) + fi + AC_TRY_RUN( + [ /* find out what STDPATH is */ #include <stdio.h> #ifdef HAVE_PATHS_H @@ -2162,7 +2313,7 @@ main() fi fi ] ) -if test "$USES_LOGIN_CONF" != "yes" ; then +if test "x$external_path_file" != "x/etc/login.conf" ; then AC_DEFINE_UNQUOTED(USER_PATH, "$user_path") AC_SUBST(user_path) fi @@ -2179,18 +2330,6 @@ AC_ARG_WITH(superuser-path, ) -# Whether to force IPv4 by default (needed on broken glibc Linux) -IPV4_HACK_MSG="no" -AC_ARG_WITH(ipv4-default, - [ --with-ipv4-default Use IPv4 by connections unless '-6' specified], - [ - if test "x$withval" != "xno" ; then - AC_DEFINE(IPV4_DEFAULT) - IPV4_HACK_MSG="yes" - fi - ] -) - AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses]) IPV4_IN6_HACK_MSG="no" AC_ARG_WITH(4in6, @@ -2254,35 +2393,67 @@ AC_SUBST(piddir) dnl allow user to disable some login recording features AC_ARG_ENABLE(lastlog, [ --disable-lastlog disable use of lastlog even if detected [no]], - [ AC_DEFINE(DISABLE_LASTLOG) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_LASTLOG) + fi + ] ) AC_ARG_ENABLE(utmp, [ --disable-utmp disable use of utmp even if detected [no]], - [ AC_DEFINE(DISABLE_UTMP) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_UTMP) + fi + ] ) AC_ARG_ENABLE(utmpx, [ --disable-utmpx disable use of utmpx even if detected [no]], - [ AC_DEFINE(DISABLE_UTMPX) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_UTMPX) + fi + ] ) AC_ARG_ENABLE(wtmp, [ --disable-wtmp disable use of wtmp even if detected [no]], - [ AC_DEFINE(DISABLE_WTMP) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_WTMP) + fi + ] ) AC_ARG_ENABLE(wtmpx, [ --disable-wtmpx disable use of wtmpx even if detected [no]], - [ AC_DEFINE(DISABLE_WTMPX) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_WTMPX) + fi + ] ) AC_ARG_ENABLE(libutil, [ --disable-libutil disable use of libutil (login() etc.) [no]], - [ AC_DEFINE(DISABLE_LOGIN) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_LOGIN) + fi + ] ) AC_ARG_ENABLE(pututline, [ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]], - [ AC_DEFINE(DISABLE_PUTUTLINE) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_PUTUTLINE) + fi + ] ) AC_ARG_ENABLE(pututxline, [ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]], - [ AC_DEFINE(DISABLE_PUTUTXLINE) ] + [ + if test "x$enableval" = "xno" ; then + AC_DEFINE(DISABLE_PUTUTXLINE) + fi + ] ) AC_ARG_WITH(lastlog, [ --with-lastlog=FILE|DIR specify lastlog location [common locations]], @@ -2473,8 +2644,8 @@ fi if test ! -z "$blibpath" ; then - LDFLAGS="$LDFLAGS -blibpath:$blibpath" - AC_MSG_WARN([Please check and edit -blibpath in LDFLAGS in Makefile]) + LDFLAGS="$LDFLAGS $blibflags$blibpath" + AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile]) fi dnl remove pam and dl because they are in $LIBPAM @@ -2512,25 +2683,28 @@ echo " Askpass program: $E" echo " Manual pages: $F" echo " PID file: $G" echo " Privilege separation chroot path: $H" -if test "$USES_LOGIN_CONF" = "yes" ; then -echo " At runtime, sshd will use the path defined in /etc/login.conf" +if test "x$external_path_file" = "x/etc/login.conf" ; then +echo " At runtime, sshd will use the path defined in $external_path_file" +echo " Make sure the path to scp is present, otherwise scp will not work" else echo " sshd default user PATH: $I" + if test ! -z "$external_path_file"; then +echo " (If PATH is set in $external_path_file it will be used instead. If" +echo " used, ensure the path to scp is present, otherwise scp will not work.)" + fi fi if test ! -z "$superuser_path" ; then echo " sshd superuser user PATH: $J" fi echo " Manpage format: $MANTYPE" -echo " PAM support: ${PAM_MSG}" -echo " KerberosIV support: $KRB4_MSG" +echo " DNS support: $DNS_MSG" +echo " PAM support: $PAM_MSG" echo " KerberosV support: $KRB5_MSG" echo " Smartcard support: $SCARD_MSG" -echo " AFS support: $AFS_MSG" echo " S/KEY support: $SKEY_MSG" echo " TCP Wrappers support: $TCPW_MSG" 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" echo " BSD Auth support: $BSD_AUTH_MSG" echo " Random number source: $RAND_MSG" diff --git a/crypto/openssh/deattack.c b/crypto/openssh/deattack.c index 7bf2749..8b55d66 100644 --- a/crypto/openssh/deattack.c +++ b/crypto/openssh/deattack.c @@ -18,7 +18,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: deattack.c,v 1.18 2002/03/04 17:27:39 stevesk Exp $"); +RCSID("$OpenBSD: deattack.c,v 1.19 2003/09/18 08:49:45 markus Exp $"); #include "deattack.h" #include "log.h" diff --git a/crypto/openssh/defines.h b/crypto/openssh/defines.h index 73fbe07..e662966 100644 --- a/crypto/openssh/defines.h +++ b/crypto/openssh/defines.h @@ -1,7 +1,31 @@ +/* + * Copyright (c) 1999-2003 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. + */ + #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.97 2003/01/24 00:50:32 djm Exp $ */ +/* $Id: defines.h,v 1.103 2003/09/16 01:52:19 dtucker Exp $ */ /* Constants */ @@ -188,28 +212,21 @@ typedef unsigned long u_int32_t; #ifndef HAVE_INT64_T # if (SIZEOF_LONG_INT == 8) typedef long int int64_t; -# define HAVE_INT64_T 1 # else # if (SIZEOF_LONG_LONG_INT == 8) typedef long long int int64_t; -# define HAVE_INT64_T 1 # endif # endif #endif #ifndef HAVE_U_INT64_T # if (SIZEOF_LONG_INT == 8) typedef unsigned long int u_int64_t; -# define HAVE_U_INT64_T 1 # else # if (SIZEOF_LONG_LONG_INT == 8) typedef unsigned long long int u_int64_t; -# define HAVE_U_INT64_T 1 # endif # endif #endif -#if !defined(HAVE_LONG_LONG_INT) && (SIZEOF_LONG_LONG_INT == 8) -# define HAVE_LONG_LONG_INT 1 -#endif #ifndef HAVE_U_CHAR typedef unsigned char u_char; @@ -304,6 +321,10 @@ struct winsize { # define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" #endif +#ifndef SUPERUSER_PATH +# define SUPERUSER_PATH _PATH_STDPATH +#endif + #ifndef _PATH_DEVNULL # define _PATH_DEVNULL "/dev/null" #endif @@ -420,6 +441,23 @@ struct winsize { #define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len)) #endif +/* given pointer to struct cmsghdr, return pointer to data */ +#ifndef CMSG_DATA +#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr))) +#endif /* CMSG_DATA */ + +/* + * RFC 2292 requires to check msg_controllen, in case that the kernel returns + * an empty list for some reasons. + */ +#ifndef CMSG_FIRSTHDR +#define CMSG_FIRSTHDR(mhdr) \ + ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ + (struct cmsghdr *)(mhdr)->msg_control : \ + (struct cmsghdr *)NULL) +#endif /* CMSG_FIRSTHDR */ + + /* Function replacement / compatibility hacks */ #if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO)) @@ -487,6 +525,10 @@ struct winsize { # define __func__ "" #endif +#if defined(KRB5) && !defined(HEIMDAL) +# define krb5_get_err_text(context,code) error_message(code) +#endif + /* * Define this to use pipes instead of socketpairs for communicating with the * client program. Socketpairs do not seem to work on all systems. diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c index 1be5195..996428b 100644 --- a/crypto/openssh/dh.c +++ b/crypto/openssh/dh.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: dh.c,v 1.23 2002/11/21 22:22:50 markus Exp $"); +RCSID("$OpenBSD: dh.c,v 1.24 2003/04/08 20:21:28 itojun Exp $"); #include "xmalloc.h" @@ -112,7 +112,7 @@ choose_dh(int min, int wantbits, int max) if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL && (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { - log("WARNING: %s does not exist, using old modulus", _PATH_DH_MODULI); + logit("WARNING: %s does not exist, using old modulus", _PATH_DH_MODULI); return (dh_new_group1()); } @@ -140,7 +140,7 @@ choose_dh(int min, int wantbits, int max) if (bestcount == 0) { fclose(f); - log("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); + logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); return (NULL); } @@ -176,7 +176,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) int bits_set = 0; if (dh_pub->neg) { - log("invalid public DH value: negativ"); + logit("invalid public DH value: negativ"); return 0; } for (i = 0; i <= n; i++) @@ -187,7 +187,7 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) return 1; - log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); + logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); return 0; } diff --git a/crypto/openssh/dispatch.c b/crypto/openssh/dispatch.c index ce32bc2..c5ff650 100644 --- a/crypto/openssh/dispatch.c +++ b/crypto/openssh/dispatch.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: dispatch.c,v 1.15 2002/01/11 13:39:36 markus Exp $"); +RCSID("$OpenBSD: dispatch.c,v 1.16 2003/04/08 20:21:28 itojun Exp $"); #include "ssh1.h" #include "ssh2.h" @@ -39,7 +39,7 @@ dispatch_fn *dispatch[DISPATCH_MAX]; void dispatch_protocol_error(int type, u_int32_t seq, void *ctxt) { - log("dispatch_protocol_error: type %d seq %u", type, seq); + logit("dispatch_protocol_error: type %d seq %u", type, seq); if (!compat20) fatal("protocol error"); packet_start(SSH2_MSG_UNIMPLEMENTED); @@ -50,7 +50,7 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctxt) void dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt) { - log("dispatch_protocol_ignore: type %d seq %u", type, seq); + logit("dispatch_protocol_ignore: type %d seq %u", type, seq); } void dispatch_init(dispatch_fn *dflt) diff --git a/crypto/openssh/dns.c b/crypto/openssh/dns.c new file mode 100644 index 0000000..90ab560 --- /dev/null +++ b/crypto/openssh/dns.c @@ -0,0 +1,290 @@ +/* $OpenBSD: dns.c,v 1.6 2003/06/11 10:18:47 jakob Exp $ */ + +/* + * Copyright (c) 2003 Wesley Griffin. All rights reserved. + * Copyright (c) 2003 Jakob Schlyter. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "includes.h" + +#ifdef DNS +#include <openssl/bn.h> +#ifdef LWRES +#include <lwres/netdb.h> +#include <dns/result.h> +#else /* LWRES */ +#include <netdb.h> +#endif /* LWRES */ + +#include "xmalloc.h" +#include "key.h" +#include "dns.h" +#include "log.h" +#include "uuencode.h" + +extern char *__progname; +RCSID("$OpenBSD: dns.c,v 1.6 2003/06/11 10:18:47 jakob Exp $"); + +#ifndef LWRES +static const char *errset_text[] = { + "success", /* 0 ERRSET_SUCCESS */ + "out of memory", /* 1 ERRSET_NOMEMORY */ + "general failure", /* 2 ERRSET_FAIL */ + "invalid parameter", /* 3 ERRSET_INVAL */ + "name does not exist", /* 4 ERRSET_NONAME */ + "data does not exist", /* 5 ERRSET_NODATA */ +}; + +static const char * +dns_result_totext(unsigned int error) +{ + switch (error) { + case ERRSET_SUCCESS: + return errset_text[ERRSET_SUCCESS]; + case ERRSET_NOMEMORY: + return errset_text[ERRSET_NOMEMORY]; + case ERRSET_FAIL: + return errset_text[ERRSET_FAIL]; + case ERRSET_INVAL: + return errset_text[ERRSET_INVAL]; + case ERRSET_NONAME: + return errset_text[ERRSET_NONAME]; + case ERRSET_NODATA: + return errset_text[ERRSET_NODATA]; + default: + return "unknown error"; + } +} +#endif /* LWRES */ + + +/* + * Read SSHFP parameters from key buffer. + */ +static int +dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, + u_char **digest, u_int *digest_len, Key *key) +{ + int success = 0; + + switch (key->type) { + case KEY_RSA: + *algorithm = SSHFP_KEY_RSA; + break; + case KEY_DSA: + *algorithm = SSHFP_KEY_DSA; + break; + default: + *algorithm = SSHFP_KEY_RESERVED; + } + + if (*algorithm) { + *digest_type = SSHFP_HASH_SHA1; + *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); + success = 1; + } else { + *digest_type = SSHFP_HASH_RESERVED; + *digest = NULL; + *digest_len = 0; + success = 0; + } + + return success; +} + +/* + * Read SSHFP parameters from rdata buffer. + */ +static int +dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, + u_char **digest, u_int *digest_len, u_char *rdata, int rdata_len) +{ + int success = 0; + + *algorithm = SSHFP_KEY_RESERVED; + *digest_type = SSHFP_HASH_RESERVED; + + if (rdata_len >= 2) { + *algorithm = rdata[0]; + *digest_type = rdata[1]; + *digest_len = rdata_len - 2; + + if (*digest_len > 0) { + *digest = (u_char *) xmalloc(*digest_len); + memcpy(*digest, rdata + 2, *digest_len); + } else { + *digest = NULL; + } + + success = 1; + } + + return success; +} + + +/* + * Verify the given hostname, address and host key using DNS. + * Returns 0 if key verifies or -1 if key does NOT verify + */ +int +verify_host_key_dns(const char *hostname, struct sockaddr *address, + Key *hostkey) +{ + int counter; + int result; + struct rrsetinfo *fingerprints = NULL; + int failures = 0; + + u_int8_t hostkey_algorithm; + u_int8_t hostkey_digest_type; + u_char *hostkey_digest; + u_int hostkey_digest_len; + + u_int8_t dnskey_algorithm; + u_int8_t dnskey_digest_type; + u_char *dnskey_digest; + u_int dnskey_digest_len; + + + debug3("verify_hostkey_dns"); + if (hostkey == NULL) + fatal("No key to look up!"); + + result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, + DNS_RDATATYPE_SSHFP, 0, &fingerprints); + if (result) { + verbose("DNS lookup error: %s", dns_result_totext(result)); + return DNS_VERIFY_ERROR; + } + +#ifdef DNSSEC + /* Only accept validated answers */ + if (!fingerprints->rri_flags & RRSET_VALIDATED) { + error("Ignored unvalidated fingerprint from DNS."); + freerrset(fingerprints); + return DNS_VERIFY_ERROR; + } +#endif + + debug("found %d fingerprints in DNS", fingerprints->rri_nrdatas); + + /* Initialize host key parameters */ + if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, + &hostkey_digest, &hostkey_digest_len, hostkey)) { + error("Error calculating host key fingerprint."); + freerrset(fingerprints); + return DNS_VERIFY_ERROR; + } + + for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++) { + /* + * Extract the key from the answer. Ignore any badly + * formatted fingerprints. + */ + if (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type, + &dnskey_digest, &dnskey_digest_len, + fingerprints->rri_rdatas[counter].rdi_data, + fingerprints->rri_rdatas[counter].rdi_length)) { + verbose("Error parsing fingerprint from DNS."); + continue; + } + + /* Check if the current key is the same as the given key */ + if (hostkey_algorithm == dnskey_algorithm && + hostkey_digest_type == dnskey_digest_type) { + + if (hostkey_digest_len == dnskey_digest_len && + memcmp(hostkey_digest, dnskey_digest, + hostkey_digest_len) == 0) { + + /* Matching algoritm and digest. */ + freerrset(fingerprints); + debug("matching host key fingerprint found in DNS"); + return DNS_VERIFY_OK; + } else { + /* Correct algorithm but bad digest */ + debug("verify_hostkey_dns: failed"); + failures++; + } + } + } + + freerrset(fingerprints); + + if (failures) { + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); + error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); + error("It is also possible that the %s host key has just been changed.", + key_type(hostkey)); + error("Please contact your system administrator."); + return DNS_VERIFY_FAILED; + } + + debug("fingerprints found in DNS, but none of them matched"); + + return DNS_VERIFY_ERROR; +} + + +/* + * Export the fingerprint of a key as a DNS resource record + */ +int +export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) +{ + u_int8_t rdata_pubkey_algorithm = 0; + u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; + u_char *rdata_digest; + u_int rdata_digest_len; + + int i; + int success = 0; + + if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, + &rdata_digest, &rdata_digest_len, key)) { + + if (generic) + fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname, + DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len, + rdata_pubkey_algorithm, rdata_digest_type); + else + fprintf(f, "%s IN SSHFP %d %d ", hostname, + rdata_pubkey_algorithm, rdata_digest_type); + + for (i = 0; i < rdata_digest_len; i++) + fprintf(f, "%02x", rdata_digest[i]); + fprintf(f, "\n"); + success = 1; + } else { + error("dns_export_rr: unsupported algorithm"); + } + + return success; +} + +#endif /* DNS */ diff --git a/crypto/openssh/dns.h b/crypto/openssh/dns.h new file mode 100644 index 0000000..ba0ea9f --- /dev/null +++ b/crypto/openssh/dns.h @@ -0,0 +1,57 @@ +/* $OpenBSD: dns.h,v 1.3 2003/05/14 22:56:51 jakob Exp $ */ + +/* + * Copyright (c) 2003 Wesley Griffin. All rights reserved. + * Copyright (c) 2003 Jakob Schlyter. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "includes.h" + +#ifdef DNS +#ifndef DNS_H +#define DNS_H + +enum sshfp_types { + SSHFP_KEY_RESERVED, + SSHFP_KEY_RSA, + SSHFP_KEY_DSA +}; + +enum sshfp_hashes { + SSHFP_HASH_RESERVED, + SSHFP_HASH_SHA1 +}; + +#define DNS_RDATACLASS_IN 1 +#define DNS_RDATATYPE_SSHFP 44 + +#define DNS_VERIFY_FAILED -1 +#define DNS_VERIFY_OK 0 +#define DNS_VERIFY_ERROR 1 + +int verify_host_key_dns(const char *, struct sockaddr *, Key *); +int export_dns_rr(const char *, Key *, FILE *, int); + +#endif /* DNS_H */ +#endif /* DNS */ diff --git a/crypto/openssh/entropy.c b/crypto/openssh/entropy.c index dcc8689..2168797 100644 --- a/crypto/openssh/entropy.c +++ b/crypto/openssh/entropy.c @@ -45,7 +45,7 @@ * XXX: we should tell the child how many bytes we need. */ -RCSID("$Id: entropy.c,v 1.44 2002/06/09 19:41:48 mouring Exp $"); +RCSID("$Id: entropy.c,v 1.46 2003/08/25 01:16:21 mouring Exp $"); #ifndef OPENSSL_PRNG_ONLY #define RANDOM_SEED_SIZE 48 @@ -75,7 +75,7 @@ seed_rng(void) if (pipe(p) == -1) fatal("pipe: %s", strerror(errno)); - old_sigchld = mysignal(SIGCHLD, SIG_DFL); + old_sigchld = signal(SIGCHLD, SIG_DFL); if ((pid = fork()) == -1) fatal("Couldn't fork: %s", strerror(errno)); if (pid == 0) { @@ -89,8 +89,8 @@ seed_rng(void) if (original_uid != original_euid && ( seteuid(getuid()) == -1 || setuid(original_uid) == -1) ) { - fprintf(stderr, "(rand child) setuid(%d): %s\n", - original_uid, strerror(errno)); + fprintf(stderr, "(rand child) setuid(%li): %s\n", + (long int)original_uid, strerror(errno)); _exit(1); } @@ -116,7 +116,7 @@ seed_rng(void) if (waitpid(pid, &ret, 0) == -1) fatal("Couldn't wait for ssh-rand-helper completion: %s", strerror(errno)); - mysignal(SIGCHLD, old_sigchld); + signal(SIGCHLD, old_sigchld); /* We don't mind if the child exits upon a SIGPIPE */ if (!WIFEXITED(ret) && diff --git a/crypto/openssh/groupaccess.c b/crypto/openssh/groupaccess.c index 66dfa68..fbf794f 100644 --- a/crypto/openssh/groupaccess.c +++ b/crypto/openssh/groupaccess.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $"); +RCSID("$OpenBSD: groupaccess.c,v 1.6 2003/04/08 20:21:28 itojun Exp $"); #include "groupaccess.h" #include "xmalloc.h" @@ -49,7 +49,7 @@ ga_init(const char *user, gid_t base) ngroups = sizeof(groups_bygid) / sizeof(gid_t); if (getgrouplist(user, base, groups_bygid, &ngroups) == -1) - log("getgrouplist: groups list too small"); + logit("getgrouplist: groups list too small"); for (i = 0, j = 0; i < ngroups; i++) if ((gr = getgrgid(groups_bygid[i])) != NULL) groups_byname[j++] = xstrdup(gr->gr_name); diff --git a/crypto/openssh/gss-genr.c b/crypto/openssh/gss-genr.c new file mode 100644 index 0000000..bda12d6 --- /dev/null +++ b/crypto/openssh/gss-genr.c @@ -0,0 +1,256 @@ +/* $OpenBSD: gss-genr.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI + +#include "xmalloc.h" +#include "bufaux.h" +#include "compat.h" +#include "log.h" +#include "monitor_wrap.h" + +#include "ssh-gss.h" + + +/* Check that the OID in a data stream matches that in the context */ +int +ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len) +{ + return (ctx != NULL && ctx->oid != GSS_C_NO_OID && + ctx->oid->length == len && + memcmp(ctx->oid->elements, data, len) == 0); +} + +/* Set the contexts OID from a data stream */ +void +ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) +{ + if (ctx->oid != GSS_C_NO_OID) { + xfree(ctx->oid->elements); + xfree(ctx->oid); + } + ctx->oid = xmalloc(sizeof(gss_OID_desc)); + ctx->oid->length = len; + ctx->oid->elements = xmalloc(len); + memcpy(ctx->oid->elements, data, len); +} + +/* Set the contexts OID */ +void +ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) +{ + ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); +} + +/* All this effort to report an error ... */ +void +ssh_gssapi_error(Gssctxt *ctxt) +{ + debug("%s", ssh_gssapi_last_error(ctxt, NULL, NULL)); +} + +char * +ssh_gssapi_last_error(Gssctxt *ctxt, + OM_uint32 *major_status, OM_uint32 *minor_status) +{ + OM_uint32 lmin; + gss_buffer_desc msg = GSS_C_EMPTY_BUFFER; + OM_uint32 ctx; + Buffer b; + char *ret; + + buffer_init(&b); + + if (major_status != NULL) + *major_status = ctxt->major; + if (minor_status != NULL) + *minor_status = ctxt->minor; + + ctx = 0; + /* The GSSAPI error */ + do { + gss_display_status(&lmin, ctxt->major, + GSS_C_GSS_CODE, GSS_C_NULL_OID, &ctx, &msg); + + buffer_append(&b, msg.value, msg.length); + buffer_put_char(&b, '\n'); + + gss_release_buffer(&lmin, &msg); + } while (ctx != 0); + + /* The mechanism specific error */ + do { + gss_display_status(&lmin, ctxt->minor, + GSS_C_MECH_CODE, GSS_C_NULL_OID, &ctx, &msg); + + buffer_append(&b, msg.value, msg.length); + buffer_put_char(&b, '\n'); + + gss_release_buffer(&lmin, &msg); + } while (ctx != 0); + + buffer_put_char(&b, '\0'); + ret = xmalloc(buffer_len(&b)); + buffer_get(&b, ret, buffer_len(&b)); + buffer_free(&b); + return (ret); +} + +/* + * Initialise our GSSAPI context. We use this opaque structure to contain all + * of the data which both the client and server need to persist across + * {accept,init}_sec_context calls, so that when we do it from the userauth + * stuff life is a little easier + */ +void +ssh_gssapi_build_ctx(Gssctxt **ctx) +{ + *ctx = xmalloc(sizeof (Gssctxt)); + (*ctx)->major = 0; + (*ctx)->minor = 0; + (*ctx)->context = GSS_C_NO_CONTEXT; + (*ctx)->name = GSS_C_NO_NAME; + (*ctx)->oid = GSS_C_NO_OID; + (*ctx)->creds = GSS_C_NO_CREDENTIAL; + (*ctx)->client = GSS_C_NO_NAME; + (*ctx)->client_creds = GSS_C_NO_CREDENTIAL; +} + +/* Delete our context, providing it has been built correctly */ +void +ssh_gssapi_delete_ctx(Gssctxt **ctx) +{ + OM_uint32 ms; + + if ((*ctx) == NULL) + return; + if ((*ctx)->context != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER); + if ((*ctx)->name != GSS_C_NO_NAME) + gss_release_name(&ms, &(*ctx)->name); + if ((*ctx)->oid != GSS_C_NO_OID) { + xfree((*ctx)->oid->elements); + xfree((*ctx)->oid); + (*ctx)->oid = GSS_C_NO_OID; + } + if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->creds); + if ((*ctx)->client != GSS_C_NO_NAME) + gss_release_name(&ms, &(*ctx)->client); + if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->client_creds); + + xfree(*ctx); + *ctx = NULL; +} + +/* + * Wrapper to init_sec_context + * Requires that the context contains: + * oid + * server name (from ssh_gssapi_import_name) + */ +OM_uint32 +ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, + gss_buffer_desc* send_tok, OM_uint32 *flags) +{ + int deleg_flag = 0; + + if (deleg_creds) { + deleg_flag = GSS_C_DELEG_FLAG; + debug("Delegating credentials"); + } + + ctx->major = gss_init_sec_context(&ctx->minor, + GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, + GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, + 0, NULL, recv_tok, NULL, send_tok, flags, NULL); + + if (GSS_ERROR(ctx->major)) + ssh_gssapi_error(ctx); + + return (ctx->major); +} + +/* Create a service name for the given host */ +OM_uint32 +ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +{ + gss_buffer_desc gssbuf; + + gssbuf.length = sizeof("host@") + strlen(host); + gssbuf.value = xmalloc(gssbuf.length); + snprintf(gssbuf.value, gssbuf.length, "host@%s", host); + + if ((ctx->major = gss_import_name(&ctx->minor, + &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) + ssh_gssapi_error(ctx); + + xfree(gssbuf.value); + return (ctx->major); +} + +/* Acquire credentials for a server running on the current host. + * Requires that the context structure contains a valid OID + */ + +/* Returns a GSSAPI error code */ +OM_uint32 +ssh_gssapi_acquire_cred(Gssctxt *ctx) +{ + OM_uint32 status; + char lname[MAXHOSTNAMELEN]; + gss_OID_set oidset; + + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); + + if (gethostname(lname, MAXHOSTNAMELEN)) + return (-1); + + if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) + return (ctx->major); + + if ((ctx->major = gss_acquire_cred(&ctx->minor, + ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) + ssh_gssapi_error(ctx); + + gss_release_oid_set(&status, &oidset); + return (ctx->major); +} + +OM_uint32 +ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { + if (*ctx) + ssh_gssapi_delete_ctx(ctx); + ssh_gssapi_build_ctx(ctx); + ssh_gssapi_set_oid(*ctx, oid); + return (ssh_gssapi_acquire_cred(*ctx)); +} + +#endif /* GSSAPI */ diff --git a/crypto/openssh/gss-serv-krb5.c b/crypto/openssh/gss-serv-krb5.c new file mode 100644 index 0000000..f48e099 --- /dev/null +++ b/crypto/openssh/gss-serv-krb5.c @@ -0,0 +1,205 @@ +/* $OpenBSD: gss-serv-krb5.c,v 1.1 2003/08/22 10:56:09 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI +#ifdef KRB5 + +#include "auth.h" +#include "xmalloc.h" +#include "log.h" +#include "servconf.h" + +#include "ssh-gss.h" + +extern ServerOptions options; + +#ifdef HEIMDAL +#include <krb5.h> +#else +#include <gssapi_krb5.h> +#endif + +static krb5_context krb_context = NULL; + +/* Initialise the krb5 library, for the stuff that GSSAPI won't do */ + +static int +ssh_gssapi_krb5_init() +{ + krb5_error_code problem; + + if (krb_context != NULL) + return 1; + + problem = krb5_init_context(&krb_context); + if (problem) { + logit("Cannot initialize krb5 context"); + return 0; + } + krb5_init_ets(krb_context); + + return 1; +} + +/* Check if this user is OK to login. This only works with krb5 - other + * GSSAPI mechanisms will need their own. + * Returns true if the user is OK to log in, otherwise returns 0 + */ + +static int +ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name) +{ + krb5_principal princ; + int retval; + + if (ssh_gssapi_krb5_init() == 0) + return 0; + + if ((retval = krb5_parse_name(krb_context, client->exportedname.value, + &princ))) { + logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context, retval)); + return 0; + } + if (krb5_kuserok(krb_context, princ, name)) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + name, (char *)client->displayname.value); + } else + retval = 0; + + krb5_free_principal(krb_context, princ); + return retval; +} + + +/* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ + +static void +ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +{ + krb5_ccache ccache; + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; + + if (client->creds == NULL) { + debug("No credentials stored"); + return; + } + + if (ssh_gssapi_krb5_init() == 0) + return; + +#ifdef HEIMDAL + if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { + logit("krb5_cc_gen_new(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; + } +#else + { + int tmpfd; + char ccname[40]; + + snprintf(ccname, sizeof(ccname), + "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid()); + + if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) { + logit("mkstemp(): %.100s", strerror(errno)); + problem = errno; + return; + } + if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) { + logit("fchmod(): %.100s", strerror(errno)); + close(tmpfd); + problem = errno; + return; + } + close(tmpfd); + if ((problem = krb5_cc_resolve(krb_context, ccname, &ccache))) { + logit("krb5_cc_resolve(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; + } + } +#endif /* #ifdef HEIMDAL */ + + if ((problem = krb5_parse_name(krb_context, + client->exportedname.value, &princ))) { + logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_cc_destroy(krb_context, ccache); + return; + } + + if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { + logit("krb5_cc_initialize(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, princ); + krb5_cc_destroy(krb_context, ccache); + return; + } + + krb5_free_principal(krb_context, princ); + + if ((maj_status = gss_krb5_copy_ccache(&min_status, + client->creds, ccache))) { + logit("gss_krb5_copy_ccache() failed"); + krb5_cc_destroy(krb_context, ccache); + return; + } + + client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); + client->store.envvar = "KRB5CCNAME"; + client->store.envval = xstrdup(client->store.filename); + +#ifdef USE_PAM + if (options.use_pam) + do_pam_putenv(client->store.envvar,client->store.envval); +#endif + + krb5_cc_close(krb_context, ccache); + + return; +} + +ssh_gssapi_mech gssapi_kerberos_mech = { + "toWM5Slw5Ew8Mqkay+al2g==", + "Kerberos", + {9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"}, + NULL, + &ssh_gssapi_krb5_userok, + NULL, + &ssh_gssapi_krb5_storecreds +}; + +#endif /* KRB5 */ + +#endif /* GSSAPI */ diff --git a/crypto/openssh/gss-serv.c b/crypto/openssh/gss-serv.c new file mode 100644 index 0000000..8fd1d63 --- /dev/null +++ b/crypto/openssh/gss-serv.c @@ -0,0 +1,292 @@ +/* $OpenBSD: gss-serv.c,v 1.3 2003/08/31 13:31:57 markus Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI + +#include "bufaux.h" +#include "compat.h" +#include "auth.h" +#include "log.h" +#include "channels.h" +#include "session.h" +#include "servconf.h" +#include "monitor_wrap.h" +#include "xmalloc.h" +#include "getput.h" + +#include "ssh-gss.h" + +extern ServerOptions options; + +static ssh_gssapi_client gssapi_client = + { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, + GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}}; + +ssh_gssapi_mech gssapi_null_mech = + { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; + +#ifdef KRB5 +extern ssh_gssapi_mech gssapi_kerberos_mech; +#endif + +ssh_gssapi_mech* supported_mechs[]= { +#ifdef KRB5 + &gssapi_kerberos_mech, +#endif + &gssapi_null_mech, +}; + +/* Unpriviledged */ +void +ssh_gssapi_supported_oids(gss_OID_set *oidset) +{ + int i = 0; + OM_uint32 min_status; + int present; + gss_OID_set supported; + + gss_create_empty_oid_set(&min_status, oidset); + gss_indicate_mechs(&min_status, &supported); + + while (supported_mechs[i]->name != NULL) { + if (GSS_ERROR(gss_test_oid_set_member(&min_status, + &supported_mechs[i]->oid, supported, &present))) + present = 0; + if (present) + gss_add_oid_set_member(&min_status, + &supported_mechs[i]->oid, oidset); + i++; + } +} + + +/* Wrapper around accept_sec_context + * Requires that the context contains: + * oid + * credentials (from ssh_gssapi_acquire_cred) + */ +/* Priviledged */ +OM_uint32 +ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, + gss_buffer_desc *send_tok, OM_uint32 *flags) +{ + OM_uint32 status; + gss_OID mech; + + ctx->major = gss_accept_sec_context(&ctx->minor, + &ctx->context, ctx->creds, recv_tok, + GSS_C_NO_CHANNEL_BINDINGS, &ctx->client, &mech, + send_tok, flags, NULL, &ctx->client_creds); + + if (GSS_ERROR(ctx->major)) + ssh_gssapi_error(ctx); + + if (ctx->client_creds) + debug("Received some client credentials"); + else + debug("Got no client credentials"); + + status = ctx->major; + + /* Now, if we're complete and we have the right flags, then + * we flag the user as also having been authenticated + */ + + if (((flags == NULL) || ((*flags & GSS_C_MUTUAL_FLAG) && + (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) { + if (ssh_gssapi_getclient(ctx, &gssapi_client)) + fatal("Couldn't convert client name"); + } + + return (status); +} + +/* + * This parses an exported name, extracting the mechanism specific portion + * to use for ACL checking. It verifies that the name belongs the mechanism + * originally selected. + */ +static OM_uint32 +ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) +{ + char *tok; + OM_uint32 offset; + OM_uint32 oidl; + + tok=ename->value; + + /* + * Check that ename is long enough for all of the fixed length + * header, and that the initial ID bytes are correct + */ + + if (ename->length<6 || memcmp(tok,"\x04\x01", 2)!=0) + return GSS_S_FAILURE; + + /* + * Extract the OID, and check it. Here GSSAPI breaks with tradition + * and does use the OID type and length bytes. To confuse things + * there are two lengths - the first including these, and the + * second without. + */ + + oidl = GET_16BIT(tok+2); /* length including next two bytes */ + oidl = oidl-2; /* turn it into the _real_ length of the variable OID */ + + /* + * Check the BER encoding for correct type and length, that the + * string is long enough and that the OID matches that in our context + */ + if (tok[4] != 0x06 || tok[5] != oidl || + ename->length < oidl+6 || + !ssh_gssapi_check_oid(ctx,tok+6,oidl)) + return GSS_S_FAILURE; + + offset = oidl+6; + + if (ename->length < offset+4) + return GSS_S_FAILURE; + + name->length = GET_32BIT(tok+offset); + offset += 4; + + if (ename->length < offset+name->length) + return GSS_S_FAILURE; + + name->value = xmalloc(name->length+1); + memcpy(name->value,tok+offset,name->length); + ((char *)name->value)[name->length] = 0; + + return GSS_S_COMPLETE; +} + +/* Extract the client details from a given context. This can only reliably + * be called once for a context */ + +/* Priviledged (called from accept_secure_ctx) */ +OM_uint32 +ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) +{ + int i = 0; + + gss_buffer_desc ename; + + client->mech = NULL; + + while (supported_mechs[i]->name != NULL) { + if (supported_mechs[i]->oid.length == ctx->oid->length && + (memcmp(supported_mechs[i]->oid.elements, + ctx->oid->elements, ctx->oid->length) == 0)) + client->mech = supported_mechs[i]; + i++; + } + + if (client->mech == NULL) + return GSS_S_FAILURE; + + if ((ctx->major = gss_display_name(&ctx->minor, ctx->client, + &client->displayname, NULL))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + + if ((ctx->major = gss_export_name(&ctx->minor, ctx->client, + &ename))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } + + if ((ctx->major = ssh_gssapi_parse_ename(ctx,&ename, + &client->exportedname))) { + return (ctx->major); + } + + /* We can't copy this structure, so we just move the pointer to it */ + client->creds = ctx->client_creds; + ctx->client_creds = GSS_C_NO_CREDENTIAL; + return (ctx->major); +} + +/* As user - called through fatal cleanup hook */ +void +ssh_gssapi_cleanup_creds(void *ignored) +{ + if (gssapi_client.store.filename != NULL) { + /* Unlink probably isn't sufficient */ + debug("removing gssapi cred file\"%s\"", gssapi_client.store.filename); + unlink(gssapi_client.store.filename); + } +} + +/* As user */ +void +ssh_gssapi_storecreds(void) +{ + if (gssapi_client.mech && gssapi_client.mech->storecreds) { + (*gssapi_client.mech->storecreds)(&gssapi_client); + if (options.gss_cleanup_creds) + fatal_add_cleanup(ssh_gssapi_cleanup_creds, NULL); + } else + debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism"); +} + +/* This allows GSSAPI methods to do things to the childs environment based + * on the passed authentication process and credentials. + */ +/* As user */ +void +ssh_gssapi_do_child(char ***envp, u_int *envsizep) +{ + + if (gssapi_client.store.envvar != NULL && + gssapi_client.store.envval != NULL) { + + debug("Setting %s to %s", gssapi_client.store.envvar, + gssapi_client.store.envval); + child_set_env(envp, envsizep, gssapi_client.store.envvar, + gssapi_client.store.envval); + } +} + +/* Priviledged */ +int +ssh_gssapi_userok(char *user) +{ + if (gssapi_client.exportedname.length == 0 || + gssapi_client.exportedname.value == NULL) { + debug("No suitable client data"); + return 0; + } + if (gssapi_client.mech && gssapi_client.mech->userok) + return ((*gssapi_client.mech->userok)(&gssapi_client, user)); + else + debug("ssh_gssapi_userok: Unknown GSSAPI mechanism"); + return (0); +} + +#endif diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c index dcee034..42a8aa7 100644 --- a/crypto/openssh/hostfile.c +++ b/crypto/openssh/hostfile.c @@ -36,7 +36,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: hostfile.c,v 1.30 2002/07/24 16:11:18 markus Exp $"); +RCSID("$OpenBSD: hostfile.c,v 1.31 2003/04/08 20:21:28 itojun Exp $"); #include "packet.h" #include "match.h" @@ -77,10 +77,10 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) return 1; if (bits != BN_num_bits(key->rsa->n)) { - log("Warning: %s, line %d: keysize mismatch for host %s: " + logit("Warning: %s, line %d: keysize mismatch for host %s: " "actual %d vs. announced %d.", filename, linenum, host, BN_num_bits(key->rsa->n), bits); - log("Warning: replace %d with %d in %s, line %d.", + logit("Warning: replace %d with %d in %s, line %d.", bits, BN_num_bits(key->rsa->n), filename, linenum); } return 1; diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h index 37d402e..033cd91 100644 --- a/crypto/openssh/includes.h +++ b/crypto/openssh/includes.h @@ -50,9 +50,6 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #ifdef HAVE_NETGROUP_H # include <netgroup.h> #endif -#if defined(HAVE_NETDB_H) -# include <netdb.h> -#endif #ifdef HAVE_ENDIAN_H # include <endian.h> #endif @@ -68,6 +65,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #ifdef HAVE_NEXT # include <libc.h> #endif +#define __USE_GNU /* before unistd.h, activate extra prototypes for glibc */ #include <unistd.h> /* For STDIN_FILENO, etc */ #include <termios.h> /* Struct winsize */ @@ -133,12 +131,18 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> /* for MAP_ANONYMOUS */ #endif +#ifdef HAVE_SYS_STRTIO_H +#include <sys/strtio.h> /* for TIOCCBRK on HP-UX */ +#endif #include <netinet/in_systm.h> /* For typedefs */ #include <netinet/in.h> /* For IPv6 macros */ #include <netinet/ip.h> /* For IPTOS macros */ #include <netinet/tcp.h> #include <arpa/inet.h> +#if defined(HAVE_NETDB_H) +# include <netdb.h> +#endif #ifdef HAVE_RPC_TYPES_H # include <rpc/types.h> /* For INADDR_LOOPBACK */ #endif @@ -167,7 +171,6 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #include "version.h" #include "openbsd-compat/openbsd-compat.h" -#include "openbsd-compat/bsd-cygwin_util.h" #include "openbsd-compat/bsd-nextstep.h" #include "entropy.h" diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c index 060b637..54318cb 100644 --- a/crypto/openssh/key.c +++ b/crypto/openssh/key.c @@ -32,7 +32,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: key.c,v 1.51 2003/02/12 09:33:04 markus Exp $"); +RCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm Exp $"); #include <openssl/evp.h> @@ -169,7 +169,7 @@ key_equal(Key *a, Key *b) return 0; } -static u_char * +u_char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) { const EVP_MD *md = NULL; @@ -236,8 +236,10 @@ key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) 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); + strlcat(retval, hex, dgst_raw_len * 3 + 1); } + + /* Remove the trailing ':' character */ retval[(dgst_raw_len * 3) - 1] = '\0'; return retval; } @@ -438,7 +440,7 @@ key_read(Key *ret, char **cpp) xfree(blob); return -1; } - k = key_from_blob(blob, n); + k = key_from_blob(blob, (u_int)n); xfree(blob); if (k == NULL) { error("key_read: key_from_blob %s failed", cp); @@ -674,7 +676,7 @@ key_names_valid2(const char *names) } Key * -key_from_blob(u_char *blob, int blen) +key_from_blob(u_char *blob, u_int blen) { Buffer b; char *ktype; diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h index 725c7a0..28753fd 100644 --- a/crypto/openssh/key.h +++ b/crypto/openssh/key.h @@ -1,4 +1,4 @@ -/* $OpenBSD: key.h,v 1.20 2003/02/12 09:33:04 markus Exp $ */ +/* $OpenBSD: key.h,v 1.22 2003/06/24 08:23:46 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -61,6 +61,7 @@ void key_free(Key *); Key *key_demote(Key *); int key_equal(Key *, Key *); char *key_fingerprint(Key *, enum fp_type, enum fp_rep); +u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *); char *key_type(Key *); int key_write(Key *, FILE *); int key_read(Key *, char **); @@ -70,7 +71,7 @@ Key *key_generate(int, u_int); Key *key_from_private(Key *); int key_type_from_name(char *); -Key *key_from_blob(u_char *, int); +Key *key_from_blob(u_char *, u_int); int key_to_blob(Key *, u_char **, u_int *); char *key_ssh_name(Key *); int key_names_valid2(const char *); diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c index 84e4ce0..9bce255 100644 --- a/crypto/openssh/log.c +++ b/crypto/openssh/log.c @@ -34,12 +34,15 @@ */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.25 2003/01/11 18:29:43 markus Exp $"); +RCSID("$OpenBSD: log.c,v 1.28 2003/05/24 09:02:22 djm Exp $"); #include "log.h" #include "xmalloc.h" #include <syslog.h> +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +# include <vis.h> +#endif static LogLevel log_level = SYSLOG_LEVEL_INFO; static int log_on_stderr = 1; @@ -127,7 +130,7 @@ error(const char *fmt,...) /* Log this message (information that usually should go to the log). */ void -log(const char *fmt,...) +logit(const char *fmt,...) { va_list args; @@ -339,6 +342,9 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) void do_log(LogLevel level, const char *fmt, va_list args) { +#ifdef OPENLOG_R + struct syslog_data sdata = SYSLOG_DATA_INIT; +#endif char msgbuf[MSGBUFSIZ]; char fmtbuf[MSGBUFSIZ]; char *txt = NULL; @@ -387,14 +393,19 @@ do_log(LogLevel level, const char *fmt, va_list args) } else { vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); } - /* Escape magic chars in output. */ - strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_OCTAL); - + strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_SAFE|VIS_OCTAL); if (log_on_stderr) { - fprintf(stderr, "%s\r\n", fmtbuf); + snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); + write(STDERR_FILENO, msgbuf, strlen(msgbuf)); } else { +#ifdef OPENLOG_R + openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); + syslog_r(pri, &sdata, "%.500s", fmtbuf); + closelog_r(&sdata); +#else openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); syslog(pri, "%.500s", fmtbuf); closelog(); +#endif } } diff --git a/crypto/openssh/log.h b/crypto/openssh/log.h index 917fafa..c366681 100644 --- a/crypto/openssh/log.h +++ b/crypto/openssh/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.8 2002/07/19 15:43:33 markus Exp $ */ +/* $OpenBSD: log.h,v 1.9 2003/04/08 20:21:28 itojun Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -55,7 +55,7 @@ LogLevel log_level_number(char *); void fatal(const char *, ...) __attribute__((format(printf, 1, 2))); void error(const char *, ...) __attribute__((format(printf, 1, 2))); -void log(const char *, ...) __attribute__((format(printf, 1, 2))); +void logit(const char *, ...) __attribute__((format(printf, 1, 2))); void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); void debug(const char *, ...) __attribute__((format(printf, 1, 2))); void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c index 6697ca7..bdac3e9 100644 --- a/crypto/openssh/loginrec.c +++ b/crypto/openssh/loginrec.c @@ -12,11 +12,6 @@ * 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 Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -163,7 +158,7 @@ #include "log.h" #include "atomicio.h" -RCSID("$Id: loginrec.c,v 1.47 2003/03/10 00:23:07 djm Exp $"); +RCSID("$Id: loginrec.c,v 1.52 2003/07/06 05:20:46 dtucker Exp $"); #ifdef HAVE_UTIL_H # include <util.h> @@ -413,7 +408,7 @@ login_write (struct logininfo *li) { #ifndef HAVE_CYGWIN if ((int)geteuid() != 0) { - log("Attempt to write login records by non-root user (aborting)"); + logit("Attempt to write login records by non-root user (aborting)"); return 1; } #endif @@ -818,7 +813,7 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) endttyent(); if((struct ttyent *)0 == ty) { - log("utmp_write_entry: tty not found"); + logit("utmp_write_entry: tty not found"); return(1); } #else /* FIXME */ @@ -842,8 +837,8 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) } (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); - if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) - log("utmp_write_direct: error writing %s: %s", + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) + logit("utmp_write_direct: error writing %s: %s", UTMP_FILE, strerror(errno)); (void)close(fd); @@ -862,12 +857,12 @@ utmp_perform_login(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - log("utmp_perform_login: utmp_write_library() failed"); + logit("utmp_perform_login: utmp_write_library() failed"); return 0; } # else if (!utmp_write_direct(li, &ut)) { - log("utmp_perform_login: utmp_write_direct() failed"); + logit("utmp_perform_login: utmp_write_direct() failed"); return 0; } # endif @@ -883,12 +878,12 @@ utmp_perform_logout(struct logininfo *li) construct_utmp(li, &ut); # ifdef UTMP_USE_LIBRARY if (!utmp_write_library(li, &ut)) { - log("utmp_perform_logout: utmp_write_library() failed"); + logit("utmp_perform_logout: utmp_write_library() failed"); return 0; } # else if (!utmp_write_direct(li, &ut)) { - log("utmp_perform_logout: utmp_write_direct() failed"); + logit("utmp_perform_logout: utmp_write_direct() failed"); return 0; } # endif @@ -907,7 +902,7 @@ utmp_write_entry(struct logininfo *li) return utmp_perform_logout(li); default: - log("utmp_write_entry: invalid type field"); + logit("utmp_write_entry: invalid type field"); return 0; } } @@ -948,7 +943,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx) static int utmpx_write_direct(struct logininfo *li, struct utmpx *utx) { - log("utmpx_write_direct: not implemented!"); + logit("utmpx_write_direct: not implemented!"); return 0; } # endif /* UTMPX_USE_LIBRARY */ @@ -961,12 +956,12 @@ utmpx_perform_login(struct logininfo *li) construct_utmpx(li, &utx); # ifdef UTMPX_USE_LIBRARY if (!utmpx_write_library(li, &utx)) { - log("utmpx_perform_login: utmp_write_library() failed"); + logit("utmpx_perform_login: utmp_write_library() failed"); return 0; } # else if (!utmpx_write_direct(li, &ut)) { - log("utmpx_perform_login: utmp_write_direct() failed"); + logit("utmpx_perform_login: utmp_write_direct() failed"); return 0; } # endif @@ -1004,7 +999,7 @@ utmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return utmpx_perform_logout(li); default: - log("utmpx_write_entry: invalid type field"); + logit("utmpx_write_entry: invalid type field"); return 0; } } @@ -1026,14 +1021,14 @@ wtmp_write(struct logininfo *li, struct utmp *ut) int fd, ret = 1; if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - log("wtmp_write: problem writing %s: %s", + logit("wtmp_write: problem writing %s: %s", WTMP_FILE, strerror(errno)); return 0; } if (fstat(fd, &buf) == 0) - if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) { + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { ftruncate(fd, buf.st_size); - log("wtmp_write: problem writing %s: %s", + logit("wtmp_write: problem writing %s: %s", WTMP_FILE, strerror(errno)); ret = 0; } @@ -1070,7 +1065,7 @@ wtmp_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return wtmp_perform_logout(li); default: - log("wtmp_write_entry: invalid type field"); + logit("wtmp_write_entry: invalid type field"); return 0; } } @@ -1119,12 +1114,12 @@ wtmp_get_entry(struct logininfo *li) li->tv_sec = li->tv_usec = 0; if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { - log("wtmp_get_entry: problem opening %s: %s", + logit("wtmp_get_entry: problem opening %s: %s", WTMP_FILE, strerror(errno)); return 0; } if (fstat(fd, &st) != 0) { - log("wtmp_get_entry: couldn't stat %s: %s", + logit("wtmp_get_entry: couldn't stat %s: %s", WTMP_FILE, strerror(errno)); close(fd); return 0; @@ -1139,7 +1134,7 @@ wtmp_get_entry(struct logininfo *li) while (!found) { if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) { - log("wtmp_get_entry: read of %s failed: %s", + logit("wtmp_get_entry: read of %s failed: %s", WTMP_FILE, strerror(errno)); close (fd); return 0; @@ -1192,15 +1187,15 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) int fd, ret = 1; if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - log("wtmpx_write: problem opening %s: %s", + logit("wtmpx_write: problem opening %s: %s", WTMPX_FILE, strerror(errno)); return 0; } if (fstat(fd, &buf) == 0) - if (atomicio(write, fd, utx, sizeof(*utx)) != sizeof(*utx)) { + if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { ftruncate(fd, buf.st_size); - log("wtmpx_write: problem writing %s: %s", + logit("wtmpx_write: problem writing %s: %s", WTMPX_FILE, strerror(errno)); ret = 0; } @@ -1239,7 +1234,7 @@ wtmpx_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return wtmpx_perform_logout(li); default: - log("wtmpx_write_entry: invalid type field"); + logit("wtmpx_write_entry: invalid type field"); return 0; } } @@ -1275,12 +1270,12 @@ wtmpx_get_entry(struct logininfo *li) li->tv_sec = li->tv_usec = 0; if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { - log("wtmpx_get_entry: problem opening %s: %s", + logit("wtmpx_get_entry: problem opening %s: %s", WTMPX_FILE, strerror(errno)); return 0; } if (fstat(fd, &st) != 0) { - log("wtmpx_get_entry: couldn't stat %s: %s", + logit("wtmpx_get_entry: couldn't stat %s: %s", WTMPX_FILE, strerror(errno)); close(fd); return 0; @@ -1295,7 +1290,7 @@ wtmpx_get_entry(struct logininfo *li) while (!found) { if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) { - log("wtmpx_get_entry: read of %s failed: %s", + logit("wtmpx_get_entry: read of %s failed: %s", WTMPX_FILE, strerror(errno)); close (fd); return 0; @@ -1340,7 +1335,7 @@ syslogin_perform_login(struct logininfo *li) struct utmp *ut; if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { - log("syslogin_perform_login: couldn't malloc()"); + logit("syslogin_perform_login: couldn't malloc()"); return 0; } construct_utmp(li, ut); @@ -1359,7 +1354,7 @@ syslogin_perform_logout(struct logininfo *li) (void)line_stripname(line, li->line, sizeof(line)); if (!logout(line)) { - log("syslogin_perform_logout: logout() returned an error"); + logit("syslogin_perform_logout: logout() returned an error"); # ifdef HAVE_LOGWTMP } else { logwtmp(line, "", ""); @@ -1382,7 +1377,7 @@ syslogin_write_entry(struct logininfo *li) case LTYPE_LOGOUT: return syslogin_perform_logout(li); default: - log("syslogin_write_entry: Invalid type field"); + logit("syslogin_write_entry: Invalid type field"); return 0; } } @@ -1417,7 +1412,7 @@ lastlog_filetype(char *filename) struct stat st; if (stat(LASTLOG_FILE, &st) != 0) { - log("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, + logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, strerror(errno)); return 0; } @@ -1448,12 +1443,12 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) LASTLOG_FILE, li->username); break; default: - log("lastlog_openseek: %.100s is not a file or directory!", + logit("lastlog_openseek: %.100s is not a file or directory!", LASTLOG_FILE); return 0; } - *fd = open(lastlog_file, filemode); + *fd = open(lastlog_file, filemode, 0600); if ( *fd < 0) { debug("lastlog_openseek: Couldn't open %s: %s", lastlog_file, strerror(errno)); @@ -1465,7 +1460,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); if ( lseek(*fd, offset, SEEK_SET) != offset ) { - log("lastlog_openseek: %s->lseek(): %s", + logit("lastlog_openseek: %s->lseek(): %s", lastlog_file, strerror(errno)); return 0; } @@ -1487,9 +1482,9 @@ lastlog_perform_login(struct logininfo *li) return(0); /* write the entry */ - if (atomicio(write, fd, &last, sizeof(last)) != sizeof(last)) { + if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); - log("lastlog_write_filemode: Error writing to %s: %s", + logit("lastlog_write_filemode: Error writing to %s: %s", LASTLOG_FILE, strerror(errno)); return 0; } @@ -1505,7 +1500,7 @@ lastlog_write_entry(struct logininfo *li) case LTYPE_LOGIN: return lastlog_perform_login(li); default: - log("lastlog_write_entry: Invalid type field"); + logit("lastlog_write_entry: Invalid type field"); return 0; } } diff --git a/crypto/openssh/loginrec.h b/crypto/openssh/loginrec.h index 732e21e..7f932c2 100644 --- a/crypto/openssh/loginrec.h +++ b/crypto/openssh/loginrec.h @@ -12,11 +12,6 @@ * 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 Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -40,7 +35,7 @@ #include <netinet/in.h> #include <sys/socket.h> -/* RCSID("$Id: loginrec.h,v 1.6 2001/05/08 20:33:06 mouring Exp $"); */ +/* RCSID("$Id: loginrec.h,v 1.7 2003/06/03 02:18:50 djm Exp $"); */ /** ** you should use the login_* calls to work around platform dependencies diff --git a/crypto/openssh/logintest.c b/crypto/openssh/logintest.c index da9ea50..3f3997d 100644 --- a/crypto/openssh/logintest.c +++ b/crypto/openssh/logintest.c @@ -9,11 +9,6 @@ * 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 Markus Friedl. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -48,7 +43,7 @@ #include "loginrec.h" -RCSID("$Id: logintest.c,v 1.8 2001/04/05 23:05:22 stevesk Exp $"); +RCSID("$Id: logintest.c,v 1.10 2003/08/21 23:34:41 djm Exp $"); #ifdef HAVE___PROGNAME extern char *__progname; @@ -292,7 +287,7 @@ main(int argc, char *argv[]) { printf("Platform-independent login recording test driver\n"); - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); if (argc == 2) { if (strncmp(argv[1], "-i", 3) == 0) compile_opts_only = 1; diff --git a/crypto/openssh/md5crypt.c b/crypto/openssh/md5crypt.c index ba98ccc..e14d53a 100644 --- a/crypto/openssh/md5crypt.c +++ b/crypto/openssh/md5crypt.c @@ -1,159 +1,165 @@ /* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * <phk@login.dknet.dk> wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet some + * day, and you think this stuff is worth it, you can buy me a beer in + * return. Poul-Henning Kamp * ---------------------------------------------------------------------------- */ -/* - * Ported from FreeBSD to Linux, only minimal changes. --marekm - */ - -/* - * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu - */ - #include "includes.h" -RCSID("$Id: md5crypt.c,v 1.5 2001/02/09 01:55:36 djm Exp $"); - #if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) - #include <openssl/md5.h> -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +RCSID("$Id: md5crypt.c,v 1.7 2003/05/30 06:58:23 dtucker Exp $"); + +/* 0 ... 63 => ascii - 64 */ +static unsigned char itoa64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -static char *magic = "$1$"; /* - * This string is magic for - * this algorithm. Having - * it this way, we can get - * get better later on - */ +static char *magic = "$1$"; -static void -to64(char *s, unsigned long v, int n) +static char * +to64(unsigned long v, int n) { + static char buf[5]; + char *s = buf; + + if (n > 4) + return (NULL); + + memset(buf, '\0', sizeof(buf)); while (--n >= 0) { *s++ = itoa64[v&0x3f]; v >>= 6; } + + return (buf); } int is_md5_salt(const char *salt) { - return (!strncmp(salt, magic, strlen(magic))); + return (strncmp(salt, magic, strlen(magic)) == 0); } -/* - * UNIX password - * - * Use MD5 for what it is best at... - */ - char * md5_crypt(const char *pw, const char *salt) { - static char passwd[120], *p; - static const char *sp,*ep; - unsigned char final[16]; - int sl,pl,i,j; - MD5_CTX ctx,ctx1; + static char passwd[120], salt_copy[9], *p; + static const char *sp, *ep; + unsigned char final[16]; + int sl, pl, i, j; + MD5_CTX ctx, ctx1; unsigned long l; /* Refine the Salt first */ sp = salt; /* If it starts with the magic string, then skip that */ - if(!strncmp(sp,magic,strlen(magic))) + if(strncmp(sp, magic, strlen(magic)) == 0) sp += strlen(magic); /* It stops at the first '$', max 8 chars */ - for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) - continue; + for (ep = sp; *ep != '$'; ep++) { + if (*ep == '\0' || ep >= (sp + 8)) + return (NULL); + } /* get the length of the true salt */ sl = ep - sp; + /* Stash the salt */ + memcpy(salt_copy, sp, sl); + salt_copy[sl] = '\0'; + MD5_Init(&ctx); /* The password first, since that is what is most unknown */ - MD5_Update(&ctx,pw,strlen(pw)); + MD5_Update(&ctx, pw, strlen(pw)); /* Then our magic string */ - MD5_Update(&ctx,magic,strlen(magic)); + MD5_Update(&ctx, magic, strlen(magic)); /* Then the raw salt */ - MD5_Update(&ctx,sp,sl); + MD5_Update(&ctx, sp, sl); - /* Then just as many characters of the MD5(pw,salt,pw) */ + /* Then just as many characters of the MD5(pw, salt, pw) */ MD5_Init(&ctx1); - MD5_Update(&ctx1,pw,strlen(pw)); - MD5_Update(&ctx1,sp,sl); - MD5_Update(&ctx1,pw,strlen(pw)); - MD5_Final(final,&ctx1); + MD5_Update(&ctx1, pw, strlen(pw)); + MD5_Update(&ctx1, sp, sl); + MD5_Update(&ctx1, pw, strlen(pw)); + MD5_Final(final, &ctx1); + for(pl = strlen(pw); pl > 0; pl -= 16) - MD5_Update(&ctx,final,pl>16 ? 16 : pl); + MD5_Update(&ctx, final, pl > 16 ? 16 : pl); /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); + memset(final, '\0', sizeof final); /* Then something really weird... */ - for (j=0,i = strlen(pw); i ; i >>= 1) - if(i&1) - MD5_Update(&ctx, final+j, 1); + for (j = 0, i = strlen(pw); i != 0; i >>= 1) + if (i & 1) + MD5_Update(&ctx, final + j, 1); else - MD5_Update(&ctx, pw+j, 1); + MD5_Update(&ctx, pw + j, 1); /* Now make the output string */ - strcpy(passwd,magic); - strncat(passwd,sp,sl); - strcat(passwd,"$"); + snprintf(passwd, sizeof(passwd), "%s%s$", magic, salt_copy); - MD5_Final(final,&ctx); + MD5_Final(final, &ctx); /* * and now, just to make sure things don't run too fast * On a 60 Mhz Pentium this takes 34 msec, so you would * need 30 seconds to build a 1000 entry dictionary... */ - for(i=0;i<1000;i++) { + for(i = 0; i < 1000; i++) { MD5_Init(&ctx1); - if(i & 1) - MD5_Update(&ctx1,pw,strlen(pw)); + if (i & 1) + MD5_Update(&ctx1, pw, strlen(pw)); else - MD5_Update(&ctx1,final,16); + MD5_Update(&ctx1, final, 16); - if(i % 3) - MD5_Update(&ctx1,sp,sl); + if (i % 3) + MD5_Update(&ctx1, sp, sl); - if(i % 7) - MD5_Update(&ctx1,pw,strlen(pw)); + if (i % 7) + MD5_Update(&ctx1, pw, strlen(pw)); - if(i & 1) - MD5_Update(&ctx1,final,16); + if (i & 1) + MD5_Update(&ctx1, final, 16); else - MD5_Update(&ctx1,pw,strlen(pw)); - MD5_Final(final,&ctx1); + MD5_Update(&ctx1, pw, strlen(pw)); + + MD5_Final(final, &ctx1); } p = passwd + strlen(passwd); - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; - l = final[11] ; to64(p,l,2); p += 2; - *p = '\0'; + l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; + strlcat(passwd, to64(l, 4), sizeof(passwd)); + l = final[11] ; + strlcat(passwd, to64(l, 2), sizeof(passwd)); /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); + memset(final, 0, sizeof(final)); + memset(salt_copy, 0, sizeof(salt_copy)); + memset(&ctx, 0, sizeof(ctx)); + memset(&ctx1, 0, sizeof(ctx1)); + (void)to64(0, 4); - return passwd; + return (passwd); } #endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ diff --git a/crypto/openssh/md5crypt.h b/crypto/openssh/md5crypt.h index 21356fb..2341e2c 100644 --- a/crypto/openssh/md5crypt.h +++ b/crypto/openssh/md5crypt.h @@ -7,15 +7,7 @@ * ---------------------------------------------------------------------------- */ -/* - * Ported from FreeBSD to Linux, only minimal changes. --marekm - */ - -/* - * Adapted from shadow-19990607 by Tudor Bosman, tudorb@jm.nu - */ - -/* $Id: md5crypt.h,v 1.3 2001/02/09 01:55:36 djm Exp $ */ +/* $Id: md5crypt.h,v 1.4 2003/05/18 14:46:46 djm Exp $ */ #ifndef _MD5CRYPT_H #define _MD5CRYPT_H @@ -24,8 +16,8 @@ #if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) -int is_md5_salt(const char *salt); -char *md5_crypt(const char *pw, const char *salt); +int is_md5_salt(const char *); +char *md5_crypt(const char *, const char *); #endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ diff --git a/crypto/openssh/mdoc2man.awk b/crypto/openssh/mdoc2man.awk new file mode 100644 index 0000000..856e2d7 --- /dev/null +++ b/crypto/openssh/mdoc2man.awk @@ -0,0 +1,340 @@ +#!/usr/bin/awk +# +# Version history: +# v3, I put the program under a proper license +# Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo +# v2, fixed to work on GNU awk --posix and MacOS X +# v1, first attempt, didn't work on MacOS X +# +# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +BEGIN { + optlist=0 + oldoptlist=0 + nospace=0 + synopsis=0 + reference=0 + block=0 + ext=0 + extopt=0 + literal=0 + prenl=0 + line="" +} + +function wtail() { + retval="" + while(w<nwords) { + if(length(retval)) + retval=retval OFS + retval=retval words[++w] + } + return retval +} + +function add(str) { + for(;prenl;prenl--) + line=line "\n" + line=line str +} + +! /^\./ { + for(;prenl;prenl--) + print "" + print + if(literal) + print ".br" + next +} + +/^\.\\"/ { next } + +{ + option=0 + parens=0 + angles=0 + sub("^\\.","") + nwords=split($0,words) + for(w=1;w<=nwords;w++) { + skip=0 + if(match(words[w],"^Li|Pf$")) { + skip=1 + } else if(match(words[w],"^Xo$")) { + skip=1 + ext=1 + if(length(line)&&!(match(line," $")||prenl)) + add(OFS) + } else if(match(words[w],"^Xc$")) { + skip=1 + ext=0 + if(!extopt) + prenl++ + w=nwords + } else if(match(words[w],"^Bd$")) { + skip=1 + if(match(words[w+1],"-literal")) { + literal=1 + prenl++ + w=nwords + } + } else if(match(words[w],"^Ed$")) { + skip=1 + literal=0 + } else if(match(words[w],"^Ns$")) { + skip=1 + if(!nospace) + nospace=1 + sub(" $","",line) + } else if(match(words[w],"^No$")) { + skip=1 + sub(" $","",line) + add(words[++w]) + } else if(match(words[w],"^Dq$")) { + skip=1 + add("``") + add(words[++w]) + while(w<nwords&&!match(words[w+1],"^[\\.,]")) + add(OFS words[++w]) + add("''") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Sq|Ql$")) { + skip=1 + add("`" words[++w] "'") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Oo$")) { + skip=1 + extopt=1 + if(!nospace) + nospace=1 + add("[") + } else if(match(words[w],"^Oc$")) { + skip=1 + extopt=0 + add("]") + } + if(!skip) { + if(!nospace&&length(line)&&!(match(line," $")||prenl)) + add(OFS) + if(nospace==1) + nospace=0 + } + if(match(words[w],"^Dd$")) { + date=wtail() + next + } else if(match(words[w],"^Dt$")) { + id=wtail() + next + } else if(match(words[w],"^Os$")) { + add(".TH " id " \"" date "\" \"" wtail() "\"") + } else if(match(words[w],"^Sh$")) { + add(".SH") + synopsis=match(words[w+1],"SYNOPSIS") + } else if(match(words[w],"^Xr$")) { + add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w]) + } else if(match(words[w],"^Rs$")) { + split("",refauthors) + nrefauthors=0 + reftitle="" + refissue="" + refdate="" + refopt="" + reference=1 + next + } else if(match(words[w],"^Re$")) { + prenl++ + for(i=nrefauthors-1;i>0;i--) { + add(refauthors[i]) + if(i>1) + add(", ") + } + if(nrefauthors>1) + add(" and ") + add(refauthors[0] ", \\fI" reftitle "\\fP") + if(length(refissue)) + add(", " refissue) + if(length(refdate)) + add(", " refdate) + if(length(refopt)) + add(", " refopt) + add(".") + reference=0 + } else if(reference) { + if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() } + if(match(words[w],"^%T$")) { + reftitle=wtail() + sub("^\"","",reftitle) + sub("\"$","",reftitle) + } + if(match(words[w],"^%N$")) { refissue=wtail() } + if(match(words[w],"^%D$")) { refdate=wtail() } + if(match(words[w],"^%O$")) { refopt=wtail() } + } else if(match(words[w],"^Nm$")) { + if(synopsis) { + add(".br") + prenl++ + } + n=words[++w] + if(!length(name)) + name=n + if(!length(n)) + n=name + add("\\fB" n "\\fP") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Nd$")) { + add("\\- " wtail()) + } else if(match(words[w],"^Fl$")) { + add("\\fB\\-" words[++w] "\\fP") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Ar$")) { + add("\\fI") + if(w==nwords) + add("file ...\\fP") + else { + add(words[++w] "\\fP") + while(match(words[w+1],"^\\|$")) + add(OFS words[++w] " \\fI" words[++w] "\\fP") + } + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Cm$")) { + add("\\fB" words[++w] "\\fP") + while(w<nwords&&match(words[w+1],"^[\\.,:;)]")) + add(words[++w]) + } else if(match(words[w],"^Op$")) { + option=1 + if(!nospace) + nospace=1 + add("[") + } else if(match(words[w],"^Pp$")) { + prenl++ + } else if(match(words[w],"^An$")) { + prenl++ + } else if(match(words[w],"^Ss$")) { + add(".SS") + } else if(match(words[w],"^Pa$")&&!option) { + add("\\fI") + w++ + if(match(words[w],"^\\.")) + add("\\&") + add(words[w] "\\fP") + while(w<nwords&&match(words[w+1],"^[\\.,:;)]")) + add(words[++w]) + } else if(match(words[w],"^Dv$")) { + add(".BR") + } else if(match(words[w],"^Em|Ev$")) { + add(".IR") + } else if(match(words[w],"^Pq$")) { + add("(") + nospace=1 + parens=1 + } else if(match(words[w],"^Aq$")) { + add("<") + nospace=1 + angles=1 + } else if(match(words[w],"^S[xy]$")) { + add(".B " wtail()) + } else if(match(words[w],"^Ic$")) { + plain=1 + add("\\fB") + while(w<nwords) { + w++ + if(match(words[w],"^Op$")) { + w++ + add("[") + words[nwords]=words[nwords] "]" + } + if(match(words[w],"^Ar$")) { + add("\\fI" words[++w] "\\fP") + } else if(match(words[w],"^[\\.,]")) { + sub(" $","",line) + if(plain) { + add("\\fP") + plain=0 + } + add(words[w]) + } else { + if(!plain) { + add("\\fB") + plain=1 + } + add(words[w]) + } + if(!nospace) + add(OFS) + } + sub(" $","",line) + if(plain) + add("\\fP") + } else if(match(words[w],"^Bl$")) { + oldoptlist=optlist + if(match(words[w+1],"-bullet")) + optlist=1 + else if(match(words[w+1],"-enum")) { + optlist=2 + enum=0 + } else if(match(words[w+1],"-tag")) + optlist=3 + else if(match(words[w+1],"-item")) + optlist=4 + else if(match(words[w+1],"-bullet")) + optlist=1 + w=nwords + } else if(match(words[w],"^El$")) { + optlist=oldoptlist + } else if(match(words[w],"^It$")&&optlist) { + if(optlist==1) + add(".IP \\(bu") + else if(optlist==2) + add(".IP " ++enum ".") + else if(optlist==3) { + add(".TP") + prenl++ + if(match(words[w+1],"^Pa|Ev$")) { + add(".B") + w++ + } + } else if(optlist==4) + add(".IP") + } else if(match(words[w],"^Sm$")) { + if(match(words[w+1],"off")) + nospace=2 + else if(match(words[w+1],"on")) + nospace=0 + w++ + } else if(!skip) { + add(words[w]) + } + } + if(match(line,"^\\.[^a-zA-Z]")) + sub("^\\.","",line) + if(parens) + add(")") + if(angles) + add(">") + if(option) + add("]") + if(ext&&!extopt&&!match(line," $")) + add(OFS) + if(!ext&&!extopt&&length(line)) { + print line + prenl=0 + line="" + } +} diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c index 84c94f9..ac616de 100644 --- a/crypto/openssh/misc.c +++ b/crypto/openssh/misc.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.20 2002/12/13 10:03:15 markus Exp $"); +RCSID("$OpenBSD: misc.c,v 1.22 2003/09/18 08:49:45 markus Exp $"); #include "misc.h" #include "log.h" @@ -60,7 +60,7 @@ set_nonblock(int fd) debug2("fd %d is O_NONBLOCK", fd); return; } - debug("fd %d setting O_NONBLOCK", fd); + debug2("fd %d setting O_NONBLOCK", fd); val |= O_NONBLOCK; if (fcntl(fd, F_SETFL, val) == -1) debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", @@ -326,29 +326,3 @@ addargs(arglist *args, char *fmt, ...) args->list[args->num++] = xstrdup(buf); args->list[args->num] = NULL; } - -mysig_t -mysignal(int sig, mysig_t act) -{ -#ifdef HAVE_SIGACTION - struct sigaction sa, osa; - - if (sigaction(sig, NULL, &osa) == -1) - return (mysig_t) -1; - if (osa.sa_handler != act) { - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; -#if defined(SA_INTERRUPT) - if (sig == SIGALRM) - sa.sa_flags |= SA_INTERRUPT; -#endif - sa.sa_handler = act; - if (sigaction(sig, &sa, NULL) == -1) - return (mysig_t) -1; - } - return (osa.sa_handler); -#else - return (signal(sig, act)); -#endif -} diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h index 3b4b879..6d2869b 100644 --- a/crypto/openssh/misc.h +++ b/crypto/openssh/misc.h @@ -31,7 +31,3 @@ struct arglist { int nalloc; }; void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3))); - -/* wrapper for signal interface */ -typedef void (*mysig_t)(int); -mysig_t mysignal(int sig, mysig_t act); diff --git a/crypto/openssh/moduli.c b/crypto/openssh/moduli.c new file mode 100644 index 0000000..eb2c0fd --- /dev/null +++ b/crypto/openssh/moduli.c @@ -0,0 +1,617 @@ +/* $OpenBSD: moduli.c,v 1.1 2003/07/28 09:49:56 djm Exp $ */ +/* + * Copyright 1994 Phil Karn <karn@qualcomm.com> + * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> + * Copyright 2000 Niels Provos <provos@citi.umich.edu> + * 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. + */ + +/* + * Two-step process to generate safe primes for DHGEX + * + * Sieve candidates for "safe" primes, + * suitable for use as Diffie-Hellman moduli; + * that is, where q = (p-1)/2 is also prime. + * + * First step: generate candidate primes (memory intensive) + * Second step: test primes' safety (processor intensive) + */ + +#include "includes.h" +#include "moduli.h" +#include "xmalloc.h" +#include "log.h" + +#include <openssl/bn.h> + + +/* + * Debugging defines + */ + +/* define DEBUG_LARGE 1 */ +/* define DEBUG_SMALL 1 */ +/* define DEBUG_TEST 1 */ + +/* + * File output defines + */ + +/* need line long enough for largest moduli plus headers */ +#define QLINESIZE (100+8192) + +/* Type: decimal. + * Specifies the internal structure of the prime modulus. + */ +#define QTYPE_UNKNOWN (0) +#define QTYPE_UNSTRUCTURED (1) +#define QTYPE_SAFE (2) +#define QTYPE_SCHNOOR (3) +#define QTYPE_SOPHIE_GERMAINE (4) +#define QTYPE_STRONG (5) + +/* Tests: decimal (bit field). + * Specifies the methods used in checking for primality. + * Usually, more than one test is used. + */ +#define QTEST_UNTESTED (0x00) +#define QTEST_COMPOSITE (0x01) +#define QTEST_SIEVE (0x02) +#define QTEST_MILLER_RABIN (0x04) +#define QTEST_JACOBI (0x08) +#define QTEST_ELLIPTIC (0x10) + +/* Size: decimal. + * Specifies the number of the most significant bit (0 to M). + ** WARNING: internally, usually 1 to N. + */ +#define QSIZE_MINIMUM (511) + +/* + * Prime sieving defines + */ + +/* Constant: assuming 8 bit bytes and 32 bit words */ +#define SHIFT_BIT (3) +#define SHIFT_BYTE (2) +#define SHIFT_WORD (SHIFT_BIT+SHIFT_BYTE) +#define SHIFT_MEGABYTE (20) +#define SHIFT_MEGAWORD (SHIFT_MEGABYTE-SHIFT_BYTE) + +/* + * Constant: when used with 32-bit integers, the largest sieve prime + * has to be less than 2**32. + */ +#define SMALL_MAXIMUM (0xffffffffUL) + +/* Constant: can sieve all primes less than 2**32, as 65537**2 > 2**32-1. */ +#define TINY_NUMBER (1UL<<16) + +/* Ensure enough bit space for testing 2*q. */ +#define TEST_MAXIMUM (1UL<<16) +#define TEST_MINIMUM (QSIZE_MINIMUM + 1) +/* real TEST_MINIMUM (1UL << (SHIFT_WORD - TEST_POWER)) */ +#define TEST_POWER (3) /* 2**n, n < SHIFT_WORD */ + +/* bit operations on 32-bit words */ +#define BIT_CLEAR(a,n) ((a)[(n)>>SHIFT_WORD] &= ~(1L << ((n) & 31))) +#define BIT_SET(a,n) ((a)[(n)>>SHIFT_WORD] |= (1L << ((n) & 31))) +#define BIT_TEST(a,n) ((a)[(n)>>SHIFT_WORD] & (1L << ((n) & 31))) + +/* + * Prime testing defines + */ + +/* + * Sieving data (XXX - move to struct) + */ + +/* sieve 2**16 */ +static u_int32_t *TinySieve, tinybits; + +/* sieve 2**30 in 2**16 parts */ +static u_int32_t *SmallSieve, smallbits, smallbase; + +/* sieve relative to the initial value */ +static u_int32_t *LargeSieve, largewords, largetries, largenumbers; +static u_int32_t largebits, largememory; /* megabytes */ +static BIGNUM *largebase; + + +/* + * print moduli out in consistent form, + */ +static int +qfileout(FILE * ofile, u_int32_t otype, u_int32_t otests, u_int32_t otries, + u_int32_t osize, u_int32_t ogenerator, BIGNUM * omodulus) +{ + struct tm *gtm; + time_t time_now; + int res; + + time(&time_now); + gtm = gmtime(&time_now); + + res = fprintf(ofile, "%04d%02d%02d%02d%02d%02d %u %u %u %u %x ", + gtm->tm_year + 1900, gtm->tm_mon + 1, gtm->tm_mday, + gtm->tm_hour, gtm->tm_min, gtm->tm_sec, + otype, otests, otries, osize, ogenerator); + + if (res < 0) + return (-1); + + if (BN_print_fp(ofile, omodulus) < 1) + return (-1); + + res = fprintf(ofile, "\n"); + fflush(ofile); + + return (res > 0 ? 0 : -1); +} + + +/* + ** Sieve p's and q's with small factors + */ +static void +sieve_large(u_int32_t s) +{ + u_int32_t r, u; + + debug2("sieve_large %u", s); + largetries++; + /* r = largebase mod s */ + r = BN_mod_word(largebase, s); + if (r == 0) + u = 0; /* s divides into largebase exactly */ + else + u = s - r; /* largebase+u is first entry divisible by s */ + + if (u < largebits * 2) { + /* + * The sieve omits p's and q's divisible by 2, so ensure that + * largebase+u is odd. Then, step through the sieve in + * increments of 2*s + */ + if (u & 0x1) + u += s; /* Make largebase+u odd, and u even */ + + /* Mark all multiples of 2*s */ + for (u /= 2; u < largebits; u += s) + BIT_SET(LargeSieve, u); + } + + /* r = p mod s */ + r = (2 * r + 1) % s; + if (r == 0) + u = 0; /* s divides p exactly */ + else + u = s - r; /* p+u is first entry divisible by s */ + + if (u < largebits * 4) { + /* + * The sieve omits p's divisible by 4, so ensure that + * largebase+u is not. Then, step through the sieve in + * increments of 4*s + */ + while (u & 0x3) { + if (SMALL_MAXIMUM - u < s) + return; + u += s; + } + + /* Mark all multiples of 4*s */ + for (u /= 4; u < largebits; u += s) + BIT_SET(LargeSieve, u); + } +} + +/* + * list candidates for Sophie-Germaine primes (where q = (p-1)/2) + * to standard output. + * The list is checked against small known primes (less than 2**30). + */ +int +gen_candidates(FILE *out, int memory, int power, BIGNUM *start) +{ + BIGNUM *q; + u_int32_t j, r, s, t; + u_int32_t smallwords = TINY_NUMBER >> 6; + u_int32_t tinywords = TINY_NUMBER >> 6; + time_t time_start, time_stop; + int i, ret = 0; + + largememory = memory; + + /* + * Set power to the length in bits of the prime to be generated. + * This is changed to 1 less than the desired safe prime moduli p. + */ + if (power > TEST_MAXIMUM) { + error("Too many bits: %u > %lu", power, TEST_MAXIMUM); + return (-1); + } else if (power < TEST_MINIMUM) { + error("Too few bits: %u < %u", power, TEST_MINIMUM); + return (-1); + } + power--; /* decrement before squaring */ + + /* + * The density of ordinary primes is on the order of 1/bits, so the + * density of safe primes should be about (1/bits)**2. Set test range + * to something well above bits**2 to be reasonably sure (but not + * guaranteed) of catching at least one safe prime. + */ + largewords = ((power * power) >> (SHIFT_WORD - TEST_POWER)); + + /* + * Need idea of how much memory is available. We don't have to use all + * of it. + */ + if (largememory > LARGE_MAXIMUM) { + logit("Limited memory: %u MB; limit %lu MB", + largememory, LARGE_MAXIMUM); + largememory = LARGE_MAXIMUM; + } + + if (largewords <= (largememory << SHIFT_MEGAWORD)) { + logit("Increased memory: %u MB; need %u bytes", + largememory, (largewords << SHIFT_BYTE)); + largewords = (largememory << SHIFT_MEGAWORD); + } else if (largememory > 0) { + logit("Decreased memory: %u MB; want %u bytes", + largememory, (largewords << SHIFT_BYTE)); + largewords = (largememory << SHIFT_MEGAWORD); + } + + TinySieve = calloc(tinywords, sizeof(u_int32_t)); + if (TinySieve == NULL) { + error("Insufficient memory for tiny sieve: need %u bytes", + tinywords << SHIFT_BYTE); + exit(1); + } + tinybits = tinywords << SHIFT_WORD; + + SmallSieve = calloc(smallwords, sizeof(u_int32_t)); + if (SmallSieve == NULL) { + error("Insufficient memory for small sieve: need %u bytes", + smallwords << SHIFT_BYTE); + xfree(TinySieve); + exit(1); + } + smallbits = smallwords << SHIFT_WORD; + + /* + * dynamically determine available memory + */ + while ((LargeSieve = calloc(largewords, sizeof(u_int32_t))) == NULL) + largewords -= (1L << (SHIFT_MEGAWORD - 2)); /* 1/4 MB chunks */ + + largebits = largewords << SHIFT_WORD; + largenumbers = largebits * 2; /* even numbers excluded */ + + /* validation check: count the number of primes tried */ + largetries = 0; + q = BN_new(); + + /* + * Generate random starting point for subprime search, or use + * specified parameter. + */ + largebase = BN_new(); + if (start == NULL) + BN_rand(largebase, power, 1, 1); + else + BN_copy(largebase, start); + + /* ensure odd */ + BN_set_bit(largebase, 0); + + time(&time_start); + + logit("%.24s Sieve next %u plus %u-bit", ctime(&time_start), + largenumbers, power); + debug2("start point: 0x%s", BN_bn2hex(largebase)); + + /* + * TinySieve + */ + for (i = 0; i < tinybits; i++) { + if (BIT_TEST(TinySieve, i)) + continue; /* 2*i+3 is composite */ + + /* The next tiny prime */ + t = 2 * i + 3; + + /* Mark all multiples of t */ + for (j = i + t; j < tinybits; j += t) + BIT_SET(TinySieve, j); + + sieve_large(t); + } + + /* + * Start the small block search at the next possible prime. To avoid + * fencepost errors, the last pass is skipped. + */ + for (smallbase = TINY_NUMBER + 3; + smallbase < (SMALL_MAXIMUM - TINY_NUMBER); + smallbase += TINY_NUMBER) { + for (i = 0; i < tinybits; i++) { + if (BIT_TEST(TinySieve, i)) + continue; /* 2*i+3 is composite */ + + /* The next tiny prime */ + t = 2 * i + 3; + r = smallbase % t; + + if (r == 0) { + s = 0; /* t divides into smallbase exactly */ + } else { + /* smallbase+s is first entry divisible by t */ + s = t - r; + } + + /* + * The sieve omits even numbers, so ensure that + * smallbase+s is odd. Then, step through the sieve + * in increments of 2*t + */ + if (s & 1) + s += t; /* Make smallbase+s odd, and s even */ + + /* Mark all multiples of 2*t */ + for (s /= 2; s < smallbits; s += t) + BIT_SET(SmallSieve, s); + } + + /* + * SmallSieve + */ + for (i = 0; i < smallbits; i++) { + if (BIT_TEST(SmallSieve, i)) + continue; /* 2*i+smallbase is composite */ + + /* The next small prime */ + sieve_large((2 * i) + smallbase); + } + + memset(SmallSieve, 0, smallwords << SHIFT_BYTE); + } + + time(&time_stop); + + logit("%.24s Sieved with %u small primes in %ld seconds", + ctime(&time_stop), largetries, (long) (time_stop - time_start)); + + for (j = r = 0; j < largebits; j++) { + if (BIT_TEST(LargeSieve, j)) + continue; /* Definitely composite, skip */ + + debug2("test q = largebase+%u", 2 * j); + BN_set_word(q, 2 * j); + BN_add(q, q, largebase); + if (qfileout(out, QTYPE_SOPHIE_GERMAINE, QTEST_SIEVE, + largetries, (power - 1) /* MSB */, (0), q) == -1) { + ret = -1; + break; + } + + r++; /* count q */ + } + + time(&time_stop); + + xfree(LargeSieve); + xfree(SmallSieve); + xfree(TinySieve); + + logit("%.24s Found %u candidates", ctime(&time_stop), r); + + return (ret); +} + +/* + * perform a Miller-Rabin primality test + * on the list of candidates + * (checking both q and p) + * The result is a list of so-call "safe" primes + */ +int +prime_test(FILE *in, FILE *out, u_int32_t trials, + u_int32_t generator_wanted) +{ + BIGNUM *q, *p, *a; + BN_CTX *ctx; + char *cp, *lp; + u_int32_t count_in = 0, count_out = 0, count_possible = 0; + u_int32_t generator_known, in_tests, in_tries, in_type, in_size; + time_t time_start, time_stop; + int res; + + time(&time_start); + + p = BN_new(); + q = BN_new(); + ctx = BN_CTX_new(); + + debug2("%.24s Final %u Miller-Rabin trials (%x generator)", + ctime(&time_start), trials, generator_wanted); + + res = 0; + lp = xmalloc(QLINESIZE + 1); + while (fgets(lp, QLINESIZE, in) != NULL) { + int ll = strlen(lp); + + count_in++; + if (ll < 14 || *lp == '!' || *lp == '#') { + debug2("%10u: comment or short line", count_in); + continue; + } + + /* XXX - fragile parser */ + /* time */ + cp = &lp[14]; /* (skip) */ + + /* type */ + in_type = strtoul(cp, &cp, 10); + + /* tests */ + in_tests = strtoul(cp, &cp, 10); + + if (in_tests & QTEST_COMPOSITE) { + debug2("%10u: known composite", count_in); + continue; + } + /* tries */ + in_tries = strtoul(cp, &cp, 10); + + /* size (most significant bit) */ + in_size = strtoul(cp, &cp, 10); + + /* generator (hex) */ + generator_known = strtoul(cp, &cp, 16); + + /* Skip white space */ + cp += strspn(cp, " "); + + /* modulus (hex) */ + switch (in_type) { + case QTYPE_SOPHIE_GERMAINE: + debug2("%10u: (%u) Sophie-Germaine", count_in, in_type); + a = q; + BN_hex2bn(&a, cp); + /* p = 2*q + 1 */ + BN_lshift(p, q, 1); + BN_add_word(p, 1); + in_size += 1; + generator_known = 0; + break; + default: + debug2("%10u: (%u)", count_in, in_type); + a = p; + BN_hex2bn(&a, cp); + /* q = (p-1) / 2 */ + BN_rshift(q, p, 1); + break; + } + + /* + * due to earlier inconsistencies in interpretation, check + * the proposed bit size. + */ + if (BN_num_bits(p) != (in_size + 1)) { + debug2("%10u: bit size %u mismatch", count_in, in_size); + continue; + } + if (in_size < QSIZE_MINIMUM) { + debug2("%10u: bit size %u too short", count_in, in_size); + continue; + } + + if (in_tests & QTEST_MILLER_RABIN) + in_tries += trials; + else + in_tries = trials; + /* + * guess unknown generator + */ + if (generator_known == 0) { + if (BN_mod_word(p, 24) == 11) + generator_known = 2; + else if (BN_mod_word(p, 12) == 5) + generator_known = 3; + else { + u_int32_t r = BN_mod_word(p, 10); + + if (r == 3 || r == 7) { + generator_known = 5; + } + } + } + /* + * skip tests when desired generator doesn't match + */ + if (generator_wanted > 0 && + generator_wanted != generator_known) { + debug2("%10u: generator %d != %d", + count_in, generator_known, generator_wanted); + continue; + } + + count_possible++; + + /* + * The (1/4)^N performance bound on Miller-Rabin is + * extremely pessimistic, so don't spend a lot of time + * really verifying that q is prime until after we know + * that p is also prime. A single pass will weed out the + * vast majority of composite q's. + */ + if (BN_is_prime(q, 1, NULL, ctx, NULL) <= 0) { + debug2("%10u: q failed first possible prime test", + count_in); + continue; + } + + /* + * q is possibly prime, so go ahead and really make sure + * that p is prime. If it is, then we can go back and do + * the same for q. If p is composite, chances are that + * will show up on the first Rabin-Miller iteration so it + * doesn't hurt to specify a high iteration count. + */ + if (!BN_is_prime(p, trials, NULL, ctx, NULL)) { + debug2("%10u: p is not prime", count_in); + continue; + } + debug("%10u: p is almost certainly prime", count_in); + + /* recheck q more rigorously */ + if (!BN_is_prime(q, trials - 1, NULL, ctx, NULL)) { + debug("%10u: q is not prime", count_in); + continue; + } + debug("%10u: q is almost certainly prime", count_in); + + if (qfileout(out, QTYPE_SAFE, (in_tests | QTEST_MILLER_RABIN), + in_tries, in_size, generator_known, p)) { + res = -1; + break; + } + + count_out++; + } + + time(&time_stop); + xfree(lp); + BN_free(p); + BN_free(q); + BN_CTX_free(ctx); + + logit("%.24s Found %u safe primes of %u candidates in %ld seconds", + ctime(&time_stop), count_out, count_possible, + (long) (time_stop - time_start)); + + return (res); +} diff --git a/crypto/openssh/moduli.h b/crypto/openssh/moduli.h new file mode 100644 index 0000000..9cd1cd3 --- /dev/null +++ b/crypto/openssh/moduli.h @@ -0,0 +1,23 @@ +/* $OpenBSD: moduli.h,v 1.1 2003/07/28 09:49:56 djm Exp $ */ + +#include <sys/types.h> +#include <openssl/bn.h> + +/* + * Using virtual memory can cause thrashing. This should be the largest + * number that is supported without a large amount of disk activity -- + * that would increase the run time from hours to days or weeks! + */ +#define LARGE_MINIMUM (8UL) /* megabytes */ + +/* + * Do not increase this number beyond the unsigned integer bit size. + * Due to a multiple of 4, it must be LESS than 128 (yielding 2**30 bits). + */ +#define LARGE_MAXIMUM (127UL) /* megabytes */ + +/* Minimum number of primality tests to perform */ +#define TRIAL_MINIMUM (4) + +int gen_candidates(FILE *, int, int, BIGNUM *); +int prime_test(FILE *, FILE *, u_int32_t, u_int32_t); diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c index bcd007e..e565647 100644 --- a/crypto/openssh/monitor.c +++ b/crypto/openssh/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.36 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $"); #include <openssl/dh.h> @@ -59,6 +59,11 @@ RCSID("$OpenBSD: monitor.c,v 1.36 2003/04/01 10:22:21 markus Exp $"); #include "ssh2.h" #include "mpaux.h" +#ifdef GSSAPI +#include "ssh-gss.h" +static Gssctxt *gsscontext = NULL; +#endif + /* Imports */ extern ServerOptions options; extern u_int utmp_len; @@ -93,7 +98,7 @@ struct { u_int olen; } child_state; -/* Functions on the montior that answer unprivileged requests */ +/* Functions on the monitor that answer unprivileged requests */ int mm_answer_moduli(int, Buffer *); int mm_answer_sign(int, Buffer *); @@ -118,13 +123,17 @@ int mm_answer_sessid(int, Buffer *); #ifdef USE_PAM int mm_answer_pam_start(int, Buffer *); +int mm_answer_pam_account(int, Buffer *); +int mm_answer_pam_init_ctx(int, Buffer *); +int mm_answer_pam_query(int, Buffer *); +int mm_answer_pam_respond(int, Buffer *); +int mm_answer_pam_free_ctx(int, Buffer *); #endif -#ifdef KRB4 -int mm_answer_krb4(int, Buffer *); -#endif -#ifdef KRB5 -int mm_answer_krb5(int, Buffer *); +#ifdef GSSAPI +int mm_answer_gss_setup_ctx(int, Buffer *); +int mm_answer_gss_accept_ctx(int, Buffer *); +int mm_answer_gss_userok(int, Buffer *); #endif static Authctxt *authctxt; @@ -137,8 +146,9 @@ static int key_blobtype = MM_NOKEY; static char *hostbased_cuser = NULL; static char *hostbased_chost = NULL; static char *auth_method = "unknown"; -static int session_id2_len = 0; +static u_int session_id2_len = 0; static u_char *session_id2 = NULL; +static pid_t monitor_child_pid; struct mon_table { enum monitor_reqtype type; @@ -163,6 +173,11 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, + {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, + {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif #ifdef BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, @@ -174,6 +189,11 @@ struct mon_table mon_dispatch_proto20[] = { #endif {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, +#ifdef GSSAPI + {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, + {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, +#endif {0, 0, NULL} }; @@ -205,12 +225,11 @@ struct mon_table mon_dispatch_proto15[] = { #endif #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, -#endif -#ifdef KRB4 - {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4}, -#endif -#ifdef KRB5 - {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, + {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, + {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, #endif {0, 0, NULL} }; @@ -286,8 +305,16 @@ monitor_child_preauth(struct monitor *pmonitor) !auth_root_allowed(auth_method)) authenticated = 0; #ifdef USE_PAM - if (!do_pam_account(authctxt->pw->pw_name, NULL)) - authenticated = 0; + /* PAM needs to perform account checks after auth */ + if (options.use_pam) { + Buffer m; + + buffer_init(&m); + mm_request_receive_expect(pmonitor->m_sendfd, + MONITOR_REQ_PAM_ACCOUNT, &m); + authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m); + buffer_free(&m); + } #endif } @@ -310,9 +337,25 @@ monitor_child_preauth(struct monitor *pmonitor) return (authctxt); } +static void +monitor_set_child_handler(pid_t pid) +{ + monitor_child_pid = pid; +} + +static void +monitor_child_handler(int signal) +{ + kill(monitor_child_pid, signal); +} + void monitor_child_postauth(struct monitor *pmonitor) { + monitor_set_child_handler(pmonitor->m_pid); + signal(SIGHUP, &monitor_child_handler); + signal(SIGTERM, &monitor_child_handler); + if (compat20) { mon_dispatch = mon_dispatch_postauth20; @@ -320,7 +363,6 @@ monitor_child_postauth(struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - } else { mon_dispatch = mon_dispatch_postauth15; monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -556,7 +598,8 @@ mm_answer_pwnamallow(int socket, Buffer *m) } #ifdef USE_PAM - monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); + if (options.use_pam) + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); #endif return (0); @@ -606,7 +649,7 @@ mm_answer_authpassword(int socket, Buffer *m) passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && - authctxt->valid && auth_password(authctxt, passwd); + auth_password(authctxt, passwd); memset(passwd, 0, strlen(passwd)); xfree(passwd); @@ -739,14 +782,133 @@ mm_answer_pam_start(int socket, Buffer *m) { char *user; + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + user = buffer_get_string(m, NULL); start_pam(user); xfree(user); + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); + return (0); } + +int +mm_answer_pam_account(int socket, Buffer *m) +{ + u_int ret; + + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + + ret = do_pam_account(); + + buffer_put_int(m, ret); + + mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); + + return (ret); +} + +static void *sshpam_ctxt, *sshpam_authok; +extern KbdintDevice sshpam_device; + +int +mm_answer_pam_init_ctx(int socket, Buffer *m) +{ + + debug3("%s", __func__); + authctxt->user = buffer_get_string(m, NULL); + sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); + sshpam_authok = NULL; + buffer_clear(m); + if (sshpam_ctxt != NULL) { + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); + buffer_put_int(m, 1); + } else { + buffer_put_int(m, 0); + } + mm_request_send(socket, MONITOR_ANS_PAM_INIT_CTX, m); + return (0); +} + +int +mm_answer_pam_query(int socket, Buffer *m) +{ + char *name, *info, **prompts; + u_int num, *echo_on; + int i, ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); + if (ret == 0 && num == 0) + sshpam_authok = sshpam_ctxt; + if (num > 1 || name == NULL || info == NULL) + ret = -1; + buffer_clear(m); + buffer_put_int(m, ret); + buffer_put_cstring(m, name); + xfree(name); + buffer_put_cstring(m, info); + xfree(info); + buffer_put_int(m, num); + for (i = 0; i < num; ++i) { + buffer_put_cstring(m, prompts[i]); + xfree(prompts[i]); + buffer_put_int(m, echo_on[i]); + } + if (prompts != NULL) + xfree(prompts); + if (echo_on != NULL) + xfree(echo_on); + mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m); + return (0); +} + +int +mm_answer_pam_respond(int socket, Buffer *m) +{ + char **resp; + u_int num; + int i, ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + num = buffer_get_int(m); + if (num > 0) { + resp = xmalloc(num * sizeof(char *)); + for (i = 0; i < num; ++i) + resp[i] = buffer_get_string(m, NULL); + ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); + for (i = 0; i < num; ++i) + xfree(resp[i]); + xfree(resp); + } else { + ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL); + } + buffer_clear(m); + buffer_put_int(m, ret); + mm_request_send(socket, MONITOR_ANS_PAM_RESPOND, m); + auth_method = "keyboard-interactive/pam"; + if (ret == 0) + sshpam_authok = sshpam_ctxt; + return (0); +} + +int +mm_answer_pam_free_ctx(int socket, Buffer *m) +{ + + debug3("%s", __func__); + (sshpam_device.free_ctx)(sshpam_ctxt); + buffer_clear(m); + mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m); + return (sshpam_authok == sshpam_ctxt); +} #endif static void @@ -870,7 +1032,7 @@ monitor_valid_userblob(u_char *data, u_int datalen) fail++; p = buffer_get_string(&b, NULL); if (strcmp(authctxt->user, p) != 0) { - log("wrong user name passed to monitor: expected %s != %.100s", + logit("wrong user name passed to monitor: expected %s != %.100s", authctxt->user, p); fail++; } @@ -918,7 +1080,7 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, fail++; p = buffer_get_string(&b, NULL); if (strcmp(authctxt->user, p) != 0) { - log("wrong user name passed to monitor: expected %s != %.100s", + logit("wrong user name passed to monitor: expected %s != %.100s", authctxt->user, p); fail++; } @@ -1028,14 +1190,14 @@ mm_record_login(Session *s, struct passwd *pw) } /* Record that there was a login on that tty from the remote host. */ record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, - get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), + get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); } static void mm_session_close(Session *s) { - debug3("%s: session %d pid %d", __func__, s->self, s->pid); + debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); if (s->ttyfd != -1) { debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); fatal_remove_cleanup(session_pty_cleanup2, (void *)s); @@ -1299,89 +1461,6 @@ mm_answer_rsa_response(int socket, Buffer *m) return (success); } -#ifdef KRB4 -int -mm_answer_krb4(int socket, Buffer *m) -{ - KTEXT_ST auth, reply; - char *client, *p; - int success; - u_int alen; - - reply.length = auth.length = 0; - - p = buffer_get_string(m, &alen); - if (alen >= MAX_KTXT_LEN) - fatal("%s: auth too large", __func__); - memcpy(auth.dat, p, alen); - auth.length = alen; - memset(p, 0, alen); - xfree(p); - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb4(authctxt, &auth, &client, &reply); - - memset(auth.dat, 0, alen); - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client); - buffer_put_string(m, reply.dat, reply.length); - if (client) - xfree(client); - if (reply.length) - memset(reply.dat, 0, reply.length); - } - - debug3("%s: sending result %d", __func__, success); - mm_request_send(socket, MONITOR_ANS_KRB4, m); - - auth_method = "kerberos"; - - /* Causes monitor loop to terminate if authenticated */ - return (success); -} -#endif - -#ifdef KRB5 -int -mm_answer_krb5(int socket, Buffer *m) -{ - krb5_data tkt, reply; - char *client_user; - u_int len; - int success; - - /* use temporary var to avoid size issues on 64bit arch */ - tkt.data = buffer_get_string(m, &len); - tkt.length = len; - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb5(authctxt, &tkt, &client_user, &reply); - - if (tkt.length) - xfree(tkt.data); - - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client_user); - buffer_put_string(m, reply.data, reply.length); - if (client_user) - xfree(client_user); - if (reply.length) - xfree(reply.data); - } - mm_request_send(socket, MONITOR_ANS_KRB5, m); - - return success; -} -#endif - int mm_answer_term(int socket, Buffer *req) { @@ -1497,6 +1576,8 @@ mm_get_keystate(struct monitor *pmonitor) Buffer m; u_char *blob, *p; u_int bloblen, plen; + u_int32_t seqnr, packets; + u_int64_t blocks; debug3("%s: Waiting for new keys", __func__); @@ -1526,8 +1607,14 @@ mm_get_keystate(struct monitor *pmonitor) xfree(blob); /* Now get sequence numbers for the packets */ - packet_set_seqnr(MODE_OUT, buffer_get_int(&m)); - packet_set_seqnr(MODE_IN, buffer_get_int(&m)); + seqnr = buffer_get_int(&m); + blocks = buffer_get_int64(&m); + packets = buffer_get_int(&m); + packet_set_state(MODE_OUT, seqnr, blocks, packets); + seqnr = buffer_get_int(&m); + blocks = buffer_get_int64(&m); + packets = buffer_get_int(&m); + packet_set_state(MODE_IN, seqnr, blocks, packets); skip: /* Get the key context */ @@ -1648,3 +1735,79 @@ monitor_reinit(struct monitor *mon) mon->m_recvfd = pair[0]; mon->m_sendfd = pair[1]; } + +#ifdef GSSAPI +int +mm_answer_gss_setup_ctx(int socket, Buffer *m) +{ + gss_OID_desc oid; + OM_uint32 major; + u_int len; + + oid.elements = buffer_get_string(m, &len); + oid.length = len; + + major = ssh_gssapi_server_ctx(&gsscontext, &oid); + + xfree(oid.elements); + + buffer_clear(m); + buffer_put_int(m, major); + + mm_request_send(socket,MONITOR_ANS_GSSSETUP, m); + + /* Now we have a context, enable the step */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); + + return (0); +} + +int +mm_answer_gss_accept_ctx(int socket, Buffer *m) +{ + gss_buffer_desc in; + gss_buffer_desc out = GSS_C_EMPTY_BUFFER; + OM_uint32 major,minor; + OM_uint32 flags = 0; /* GSI needs this */ + u_int len; + + in.value = buffer_get_string(m, &len); + in.length = len; + major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); + xfree(in.value); + + buffer_clear(m); + buffer_put_int(m, major); + buffer_put_string(m, out.value, out.length); + buffer_put_int(m, flags); + mm_request_send(socket, MONITOR_ANS_GSSSTEP, m); + + gss_release_buffer(&minor, &out); + + /* Complete - now we can do signing */ + if (major==GSS_S_COMPLETE) { + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); + } + return (0); +} + +int +mm_answer_gss_userok(int socket, Buffer *m) +{ + int authenticated; + + authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + + buffer_clear(m); + buffer_put_int(m, authenticated); + + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m); + + auth_method="gssapi"; + + /* Monitor loop will terminate if authenticated */ + return (authenticated); +} +#endif /* GSSAPI */ diff --git a/crypto/openssh/monitor.h b/crypto/openssh/monitor.h index 668ac98..2461156 100644 --- a/crypto/openssh/monitor.h +++ b/crypto/openssh/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ +/* $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> @@ -49,9 +49,15 @@ enum monitor_reqtype { MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED, MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, - MONITOR_REQ_KRB4, MONITOR_ANS_KRB4, - MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, + MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, + MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, + MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, MONITOR_REQ_PAM_START, + MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, + MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, + MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, + MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, + MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, MONITOR_REQ_TERM }; diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c index 641ce72..22b7882 100644 --- a/crypto/openssh/monitor_fdpass.c +++ b/crypto/openssh/monitor_fdpass.c @@ -113,9 +113,11 @@ mm_receive_fd(int socket) fatal("%s: no fd", __func__); #else cmsg = CMSG_FIRSTHDR(&msg); +#ifndef BROKEN_CMSG_TYPE if (cmsg->cmsg_type != SCM_RIGHTS) fatal("%s: expected type %d got %d", __func__, SCM_RIGHTS, cmsg->cmsg_type); +#endif fd = (*(int *)CMSG_DATA(cmsg)); #endif return fd; diff --git a/crypto/openssh/monitor_mm.c b/crypto/openssh/monitor_mm.c index b4a6e40..e57c87c 100644 --- a/crypto/openssh/monitor_mm.c +++ b/crypto/openssh/monitor_mm.c @@ -30,7 +30,6 @@ RCSID("$OpenBSD: monitor_mm.c,v 1.8 2002/08/02 14:43:15 millert Exp $"); #include <sys/mman.h> #endif -#include "openbsd-compat/xmmap.h" #include "ssh.h" #include "xmalloc.h" #include "log.h" diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c index c971413..4034d56 100644 --- a/crypto/openssh/monitor_wrap.c +++ b/crypto/openssh/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $"); #include <openssl/bn.h> #include <openssl/dh.h> @@ -47,11 +47,16 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $"); #include "atomicio.h" #include "monitor_fdpass.h" #include "getput.h" +#include "servconf.h" #include "auth.h" #include "channels.h" #include "session.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* Imports */ extern int compat20; extern Newkeys *newkeys[]; @@ -59,6 +64,7 @@ extern z_stream incoming_stream; extern z_stream outgoing_stream; extern struct monitor *pmonitor; extern Buffer input, output; +extern ServerOptions options; void mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) @@ -70,9 +76,9 @@ mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) PUT_32BIT(buf, mlen + 1); buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ - if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf)) + if (atomicio(vwrite, socket, buf, sizeof(buf)) != sizeof(buf)) fatal("%s: write", __func__); - if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen) + if (atomicio(vwrite, socket, buffer_ptr(m), mlen) != mlen) fatal("%s: write", __func__); } @@ -520,6 +526,8 @@ mm_send_keystate(struct monitor *pmonitor) Buffer m; u_char *blob, *p; u_int bloblen, plen; + u_int32_t seqnr, packets; + u_int64_t blocks; buffer_init(&m); @@ -568,8 +576,14 @@ mm_send_keystate(struct monitor *pmonitor) buffer_put_string(&m, blob, bloblen); xfree(blob); - buffer_put_int(&m, packet_get_seqnr(MODE_OUT)); - buffer_put_int(&m, packet_get_seqnr(MODE_IN)); + packet_get_state(MODE_OUT, &seqnr, &blocks, &packets); + buffer_put_int(&m, seqnr); + buffer_put_int64(&m, blocks); + buffer_put_int(&m, packets); + packet_get_state(MODE_IN, &seqnr, &blocks, &packets); + buffer_put_int(&m, seqnr); + buffer_put_int64(&m, blocks); + buffer_put_int(&m, packets); debug3("%s: New keys have been sent", __func__); skip: @@ -661,6 +675,8 @@ mm_start_pam(char *user) Buffer m; debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); buffer_init(&m); buffer_put_cstring(&m, user); @@ -669,6 +685,112 @@ mm_start_pam(char *user) buffer_free(&m); } + +u_int +mm_do_pam_account(void) +{ + Buffer m; + u_int ret; + + debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); + + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_PAM_ACCOUNT, &m); + ret = buffer_get_int(&m); + + buffer_free(&m); + + debug3("%s returning %d", __func__, ret); + + return (ret); +} + +void * +mm_sshpam_init_ctx(Authctxt *authctxt) +{ + Buffer m; + int success; + + debug3("%s", __func__); + buffer_init(&m); + buffer_put_cstring(&m, authctxt->user); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); + success = buffer_get_int(&m); + if (success == 0) { + debug3("%s: pam_init_ctx failed", __func__); + buffer_free(&m); + return (NULL); + } + buffer_free(&m); + return (authctxt); +} + +int +mm_sshpam_query(void *ctx, char **name, char **info, + u_int *num, char ***prompts, u_int **echo_on) +{ + Buffer m; + int i, ret; + + debug3("%s", __func__); + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); + ret = buffer_get_int(&m); + debug3("%s: pam_query returned %d", __func__, ret); + *name = buffer_get_string(&m, NULL); + *info = buffer_get_string(&m, NULL); + *num = buffer_get_int(&m); + *prompts = xmalloc((*num + 1) * sizeof(char *)); + *echo_on = xmalloc((*num + 1) * sizeof(u_int)); + for (i = 0; i < *num; ++i) { + (*prompts)[i] = buffer_get_string(&m, NULL); + (*echo_on)[i] = buffer_get_int(&m); + } + buffer_free(&m); + return (ret); +} + +int +mm_sshpam_respond(void *ctx, u_int num, char **resp) +{ + Buffer m; + int i, ret; + + debug3("%s", __func__); + buffer_init(&m); + buffer_put_int(&m, num); + for (i = 0; i < num; ++i) + buffer_put_cstring(&m, resp[i]); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); + ret = buffer_get_int(&m); + debug3("%s: pam_respond returned %d", __func__, ret); + buffer_free(&m); + return (ret); +} + +void +mm_sshpam_free_ctx(void *ctxtp) +{ + Buffer m; + + debug3("%s", __func__); + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); + buffer_free(&m); +} #endif /* USE_PAM */ /* Request process termination */ @@ -949,73 +1071,69 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) return (success); } -#ifdef KRB4 -int -mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply) +#ifdef GSSAPI +OM_uint32 +mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { - KTEXT auth, reply; - Buffer m; - u_int rlen; - int success = 0; - char *p; + Buffer m; + OM_uint32 major; - debug3("%s entering", __func__); - auth = _auth; - reply = _reply; + /* Client doesn't get to see the context */ + *ctx = NULL; buffer_init(&m); - buffer_put_string(&m, auth->dat, auth->length); + buffer_put_string(&m, oid->elements, oid->length); - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m); - mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); + + major = buffer_get_int(&m); - success = buffer_get_int(&m); - if (success) { - *client = buffer_get_string(&m, NULL); - p = buffer_get_string(&m, &rlen); - if (rlen >= MAX_KTXT_LEN) - fatal("%s: reply from monitor too large", __func__); - reply->length = rlen; - memcpy(reply->dat, p, rlen); - memset(p, 0, rlen); - xfree(p); - } buffer_free(&m); - return (success); + return (major); } -#endif -#ifdef KRB5 -int -mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) +OM_uint32 +mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, + gss_buffer_desc *out, OM_uint32 *flags) { - krb5_data *tkt, *reply; Buffer m; - int success; - - debug3("%s entering", __func__); - tkt = (krb5_data *) argp; - reply = (krb5_data *) resp; + OM_uint32 major; + u_int len; buffer_init(&m); - buffer_put_string(&m, tkt->data, tkt->length); + buffer_put_string(&m, in->value, in->length); - mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m); - mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); - success = buffer_get_int(&m); - if (success) { - u_int len; + major = buffer_get_int(&m); + out->value = buffer_get_string(&m, &len); + out->length = len; + if (flags) + *flags = buffer_get_int(&m); - *userp = buffer_get_string(&m, NULL); - reply->data = buffer_get_string(&m, &len); - reply->length = len; - } else { - memset(reply, 0, sizeof(*reply)); - *userp = NULL; - } + buffer_free(&m); + + return (major); +} + +int +mm_ssh_gssapi_userok(char *user) +{ + Buffer m; + int authenticated = 0; + + buffer_init(&m); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, + &m); + + authenticated = buffer_get_int(&m); buffer_free(&m); - return (success); + debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); + return (authenticated); } -#endif +#endif /* GSSAPI */ diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h index d960a3d..5e03345 100644 --- a/crypto/openssh/monitor_wrap.h +++ b/crypto/openssh/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> @@ -55,8 +55,21 @@ int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *); BIGNUM *mm_auth_rsa_generate_challenge(Key *); +#ifdef GSSAPI +#include "ssh-gss.h" +OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid); +OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt, + gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags); +int mm_ssh_gssapi_userok(char *user); +#endif + #ifdef USE_PAM void mm_start_pam(char *); +u_int mm_do_pam_account(void); +void *mm_sshpam_init_ctx(struct Authctxt *); +int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); +int mm_sshpam_respond(void *, u_int, char **); +void mm_sshpam_free_ctx(void *); #endif void mm_terminate(void); @@ -83,16 +96,6 @@ int mm_bsdauth_respond(void *, u_int, char **); int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); -/* auth_krb */ -#ifdef KRB4 -int mm_auth_krb4(struct Authctxt *, void *, char **, void *); -#endif -#ifdef KRB5 -/* auth and reply are really krb5_data objects, but we don't want to - * include all of the krb5 headers here */ -int mm_auth_krb5(void *authctxt, void *auth, char **client, void *reply); -#endif - /* zlib allocation hooks */ void *mm_zalloc(struct mm_master *, u_int, u_int); diff --git a/crypto/openssh/msg.c b/crypto/openssh/msg.c index 5d266c2..6a806c3 100644 --- a/crypto/openssh/msg.c +++ b/crypto/openssh/msg.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: msg.c,v 1.5 2002/12/19 00:07:02 djm Exp $"); +RCSID("$OpenBSD: msg.c,v 1.6 2003/06/28 16:23:06 deraadt Exp $"); #include "buffer.h" #include "getput.h" @@ -40,9 +40,9 @@ ssh_msg_send(int fd, u_char type, Buffer *m) PUT_32BIT(buf, mlen + 1); buf[4] = type; /* 1st byte of payload is mesg-type */ - if (atomicio(write, fd, buf, sizeof(buf)) != sizeof(buf)) + if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) fatal("ssh_msg_send: write"); - if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen) + if (atomicio(vwrite, fd, buffer_ptr(m), mlen) != mlen) fatal("ssh_msg_send: write"); } diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h index 62f5cfb..8b431d9 100644 --- a/crypto/openssh/myproposal.h +++ b/crypto/openssh/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.14 2002/04/03 09:26:11 markus Exp $ */ +/* $OpenBSD: myproposal.h,v 1.15 2003/05/17 04:27:52 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -27,7 +27,8 @@ #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,rijndael-cbc@lysator.liu.se" + "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ + "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_DEFAULT_MAC \ "hmac-md5,hmac-sha1,hmac-ripemd160," \ "hmac-ripemd160@openssh.com," \ diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c index bce7325..3138cdd 100644 --- a/crypto/openssh/nchan.c +++ b/crypto/openssh/nchan.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: nchan.c,v 1.47 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: nchan.c,v 1.49 2003/08/29 10:04:36 markus Exp $"); #include "ssh1.h" #include "ssh2.h" @@ -83,7 +83,7 @@ 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], + debug2("channel %d: input %s -> %s", c->self, istates[c->istate], istates[next]); c->istate = next; } @@ -92,7 +92,7 @@ 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], + debug2("channel %d: output %s -> %s", c->self, ostates[c->ostate], ostates[next]); c->ostate = next; } @@ -104,7 +104,7 @@ chan_set_ostate(Channel *c, u_int next) static void chan_rcvd_oclose1(Channel *c) { - debug("channel %d: rcvd oclose", c->self); + debug2("channel %d: rcvd oclose", c->self); switch (c->istate) { case CHAN_INPUT_WAIT_OCLOSE: chan_set_istate(c, CHAN_INPUT_CLOSED); @@ -128,7 +128,7 @@ chan_rcvd_oclose1(Channel *c) void chan_read_failed(Channel *c) { - debug("channel %d: read failed", c->self); + debug2("channel %d: read failed", c->self); switch (c->istate) { case CHAN_INPUT_OPEN: chan_shutdown_read(c); @@ -143,7 +143,7 @@ chan_read_failed(Channel *c) void chan_ibuf_empty(Channel *c) { - debug("channel %d: ibuf empty", c->self); + debug2("channel %d: ibuf empty", c->self); if (buffer_len(&c->input)) { error("channel %d: chan_ibuf_empty for non empty buffer", c->self); @@ -169,7 +169,7 @@ chan_ibuf_empty(Channel *c) static void chan_rcvd_ieof1(Channel *c) { - debug("channel %d: rcvd ieof", c->self); + debug2("channel %d: rcvd ieof", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); @@ -186,7 +186,7 @@ chan_rcvd_ieof1(Channel *c) static void chan_write_failed1(Channel *c) { - debug("channel %d: write failed", c->self); + debug2("channel %d: write failed", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: chan_shutdown_write(c); @@ -207,7 +207,7 @@ chan_write_failed1(Channel *c) void chan_obuf_empty(Channel *c) { - debug("channel %d: obuf empty", c->self); + debug2("channel %d: obuf empty", c->self); if (buffer_len(&c->output)) { error("channel %d: chan_obuf_empty for non empty buffer", c->self); @@ -229,7 +229,7 @@ chan_obuf_empty(Channel *c) static void chan_send_ieof1(Channel *c) { - debug("channel %d: send ieof", c->self); + debug2("channel %d: send ieof", c->self); switch (c->istate) { case CHAN_INPUT_OPEN: case CHAN_INPUT_WAIT_DRAIN: @@ -246,7 +246,7 @@ chan_send_ieof1(Channel *c) static void chan_send_oclose1(Channel *c) { - debug("channel %d: send oclose", c->self); + debug2("channel %d: send oclose", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: case CHAN_OUTPUT_WAIT_DRAIN: @@ -268,7 +268,7 @@ chan_send_oclose1(Channel *c) static void chan_rcvd_close2(Channel *c) { - debug("channel %d: rcvd close", c->self); + debug2("channel %d: rcvd close", c->self); if (c->flags & CHAN_CLOSE_RCVD) error("channel %d: protocol error: close rcvd twice", c->self); c->flags |= CHAN_CLOSE_RCVD; @@ -301,7 +301,7 @@ chan_rcvd_close2(Channel *c) static void chan_rcvd_eof2(Channel *c) { - debug("channel %d: rcvd eof", c->self); + debug2("channel %d: rcvd eof", c->self); c->flags |= CHAN_EOF_RCVD; if (c->ostate == CHAN_OUTPUT_OPEN) chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN); @@ -309,7 +309,7 @@ chan_rcvd_eof2(Channel *c) static void chan_write_failed2(Channel *c) { - debug("channel %d: write failed", c->self); + debug2("channel %d: write failed", c->self); switch (c->ostate) { case CHAN_OUTPUT_OPEN: case CHAN_OUTPUT_WAIT_DRAIN: @@ -325,7 +325,7 @@ chan_write_failed2(Channel *c) static void chan_send_eof2(Channel *c) { - debug("channel %d: send eof", c->self); + debug2("channel %d: send eof", c->self); switch (c->istate) { case CHAN_INPUT_WAIT_DRAIN: packet_start(SSH2_MSG_CHANNEL_EOF); @@ -342,7 +342,7 @@ chan_send_eof2(Channel *c) static void chan_send_close2(Channel *c) { - debug("channel %d: send close", c->self); + debug2("channel %d: send close", c->self); if (c->ostate != CHAN_OUTPUT_CLOSED || c->istate != CHAN_INPUT_CLOSED) { error("channel %d: cannot send close for istate/ostate %d/%d", @@ -398,13 +398,13 @@ int chan_is_dead(Channel *c, int send) { if (c->type == SSH_CHANNEL_ZOMBIE) { - debug("channel %d: zombie", c->self); + debug2("channel %d: zombie", c->self); return 1; } if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) return 0; if (!compat20) { - debug("channel %d: is dead", c->self); + debug2("channel %d: is dead", c->self); return 1; } if ((datafellows & SSH_BUG_EXTEOF) && @@ -421,7 +421,7 @@ chan_is_dead(Channel *c, int send) } else { /* channel would be dead if we sent a close */ if (c->flags & CHAN_CLOSE_RCVD) { - debug("channel %d: almost dead", + debug2("channel %d: almost dead", c->self); return 1; } @@ -429,7 +429,7 @@ chan_is_dead(Channel *c, int send) } if ((c->flags & CHAN_CLOSE_SENT) && (c->flags & CHAN_CLOSE_RCVD)) { - debug("channel %d: is dead", c->self); + debug2("channel %d: is dead", c->self); return 1; } return 0; @@ -443,15 +443,15 @@ chan_shutdown_write(Channel *c) if (compat20 && c->type == SSH_CHANNEL_LARVAL) return; /* shutdown failure is allowed if write failed already */ - debug("channel %d: close_write", c->self); + debug2("channel %d: close_write", c->self); if (c->sock != -1) { if (shutdown(c->sock, SHUT_WR) < 0) - debug("channel %d: chan_shutdown_write: " + debug2("channel %d: chan_shutdown_write: " "shutdown() failed for fd%d: %.100s", c->self, c->sock, strerror(errno)); } else { if (channel_close_fd(&c->wfd) < 0) - log("channel %d: chan_shutdown_write: " + logit("channel %d: chan_shutdown_write: " "close() failed for fd%d: %.100s", c->self, c->wfd, strerror(errno)); } @@ -461,7 +461,7 @@ chan_shutdown_read(Channel *c) { if (compat20 && c->type == SSH_CHANNEL_LARVAL) return; - debug("channel %d: close_read", c->self); + debug2("channel %d: close_read", c->self); if (c->sock != -1) { /* * shutdown(sock, SHUT_READ) may return ENOTCONN if the @@ -476,7 +476,7 @@ chan_shutdown_read(Channel *c) strerror(errno)); } else { if (channel_close_fd(&c->rfd) < 0) - log("channel %d: chan_shutdown_read: " + logit("channel %d: chan_shutdown_read: " "close() failed for fd%d: %.100s", c->self, c->rfd, strerror(errno)); } diff --git a/crypto/openssh/openbsd-compat/Makefile.in b/crypto/openssh/openbsd-compat/Makefile.in index 8615e36..c48593f 100644 --- a/crypto/openssh/openbsd-compat/Makefile.in +++ b/crypto/openssh/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.25 2003/02/24 01:55:56 djm Exp $ +# $Id: Makefile.in,v 1.28 2003/07/24 06:52:14 mouring Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -16,9 +16,9 @@ RANLIB=@RANLIB@ INSTALL=@INSTALL@ LDFLAGS=-L. @LDFLAGS@ -OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o vis.o +OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o vis.o -COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o xmmap.o +COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o PORTS=port-irix.o port-aix.o diff --git a/crypto/openssh/openbsd-compat/base64.h b/crypto/openssh/openbsd-compat/base64.h index 72db3ff..732c6b3 100644 --- a/crypto/openssh/openbsd-compat/base64.h +++ b/crypto/openssh/openbsd-compat/base64.h @@ -1,23 +1,65 @@ -/* $Id: base64.h,v 1.4 2003/02/24 04:45:43 djm Exp $ */ +/* $Id: base64.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ #ifndef _BSD_BASE64_H #define _BSD_BASE64_H -#include "config.h" +#include "includes.h" #ifndef HAVE___B64_NTOP # ifndef HAVE_B64_NTOP int b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); # endif /* !HAVE_B64_NTOP */ -# define __b64_ntop b64_ntop +# define __b64_ntop(a,b,c,d) b64_ntop(a,b,c,d) #endif /* HAVE___B64_NTOP */ #ifndef HAVE___B64_PTON # ifndef HAVE_B64_PTON int b64_pton(char const *src, u_char *target, size_t targsize); # endif /* !HAVE_B64_PTON */ -# define __b64_pton b64_pton +# define __b64_pton(a,b,c) b64_pton(a,b,c) #endif /* HAVE___B64_PTON */ #endif /* _BSD_BASE64_H */ diff --git a/crypto/openssh/openbsd-compat/basename.c b/crypto/openssh/openbsd-compat/basename.c index 5a3823b..2054c80 100644 --- a/crypto/openssh/openbsd-compat/basename.c +++ b/crypto/openssh/openbsd-compat/basename.c @@ -1,37 +1,26 @@ -/* $OpenBSD: basename.c,v 1.8 2002/06/09 05:03:59 deraadt Exp $ */ +/* $OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $ */ /* * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "includes.h" -#if !defined(HAVE_BASENAME) +#include "includes.h" +#ifndef HAVE_BASENAME #ifndef lint -static char rcsid[] = "$OpenBSD: basename.c,v 1.8 2002/06/09 05:03:59 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $"; #endif /* not lint */ char * diff --git a/crypto/openssh/openbsd-compat/bindresvport.c b/crypto/openssh/openbsd-compat/bindresvport.c index 620f980..8a273f9 100644 --- a/crypto/openssh/openbsd-compat/bindresvport.c +++ b/crypto/openssh/openbsd-compat/bindresvport.c @@ -1,48 +1,37 @@ -/* This file has be modified from the original OpenBSD source */ +/* This file has be substantially modified from the original OpenBSD source */ + +/* $OpenBSD: bindresvport.c,v 1.15 2003/05/20 22:42:35 deraadt Exp $ */ /* - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 + * Copyright 1996, Jason Downs. All rights reserved. + * Copyright 1998, Theo de Raadt. All rights reserved. + * Copyright 2000, 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" #ifndef HAVE_BINDRESVPORT_SA -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: bindresvport.c,v 1.13 2000/01/26 03:43:21 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ - -/* - * Copyright (c) 1987 by Sun Microsystems, Inc. - * - * Portions Copyright(C) 1996, Jason Downs. All rights reserved. - */ - #include "includes.h" #define STARTPORT 600 diff --git a/crypto/openssh/openbsd-compat/bsd-arc4random.c b/crypto/openssh/openbsd-compat/bsd-arc4random.c index dd08130..5f89096 100644 --- a/crypto/openssh/openbsd-compat/bsd-arc4random.c +++ b/crypto/openssh/openbsd-compat/bsd-arc4random.c @@ -25,7 +25,7 @@ #include "includes.h" #include "log.h" -RCSID("$Id: bsd-arc4random.c,v 1.6 2003/03/17 05:13:53 djm Exp $"); +RCSID("$Id: bsd-arc4random.c,v 1.7 2003/05/18 14:13:38 djm Exp $"); #ifndef HAVE_ARC4RANDOM @@ -70,6 +70,7 @@ void arc4random_stir(void) fatal("Couldn't obtain random bytes (error %ld)", ERR_get_error()); RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); + RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); memset(rand_buf, 0, sizeof(rand_buf)); rc4_ready = REKEY_BYTES; diff --git a/crypto/openssh/openbsd-compat/bsd-cray.c b/crypto/openssh/openbsd-compat/bsd-cray.c index edb3112..f2ac428 100644 --- a/crypto/openssh/openbsd-compat/bsd-cray.c +++ b/crypto/openssh/openbsd-compat/bsd-cray.c @@ -1,5 +1,5 @@ /* - * $Id: bsd-cray.c,v 1.8 2002/09/26 00:38:51 tim Exp $ + * $Id: bsd-cray.c,v 1.12 2003/06/03 02:45:27 dtucker Exp $ * * bsd-cray.c * @@ -67,10 +67,10 @@ extern ServerOptions options; -char cray_tmpdir[TPATHSIZ+1]; /* job TMPDIR path */ +char cray_tmpdir[TPATHSIZ + 1]; /* job TMPDIR path */ -struct sysv sysv; /* system security structure */ -struct usrv usrv; /* user security structure */ +struct sysv sysv; /* system security structure */ +struct usrv usrv; /* user security structure */ /* * Functions. @@ -86,39 +86,40 @@ int cray_access_denied(char *); void cray_login_failure(char *username, int errcode) { - struct udb *ueptr; /* UDB pointer for username */ - ia_failure_t fsent; /* ia_failure structure */ + struct udb *ueptr; /* UDB pointer for username */ + ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ - struct jtab jtab; /* job table structure */ - int jid = 0; /* job id */ + struct jtab jtab; /* job table structure */ + int jid = 0; /* job id */ - if ((jid = getjtab(&jtab)) < 0) { + if ((jid = getjtab(&jtab)) < 0) debug("cray_login_failure(): getjtab error"); - } + getsysudb(); - if ((ueptr = getudbnam(username)) == UDB_NULL) { + if ((ueptr = getudbnam(username)) == UDB_NULL) debug("cray_login_failure(): getudbname() returned NULL"); - } endudb(); - fsent.revision = 0; - fsent.uname = username; - fsent.host = (char *)get_canonical_hostname(options.verify_reverse_mapping); - fsent.ttyn = "sshd"; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = ueptr; - fsent.jid = jid; - fsent.errcode = errcode; - fsent.pwdp = NULL; - fsent.exitcode = 0; /* dont exit in ia_failure() */ - - fret.revision = 0; - fret.normal = 0; + + memset(&fsent, '\0', sizeof(fsent)); + fsent.revision = 0; + fsent.uname = username; + fsent.host = (char *)get_canonical_hostname(options.use_dns); + fsent.ttyn = "sshd"; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = ueptr; + fsent.jid = jid; + fsent.errcode = errcode; + fsent.pwdp = NULL; + fsent.exitcode = 0; /* dont exit in ia_failure() */ + + fret.revision = 0; + fret.normal = 0; /* * Call ia_failure because of an login failure. */ - ia_failure(&fsent,&fret); + ia_failure(&fsent, &fret); } /* @@ -127,338 +128,316 @@ cray_login_failure(char *username, int errcode) int cray_access_denied(char *username) { - struct udb *ueptr; /* UDB pointer for username */ - int errcode; /* IA errorcode */ + struct udb *ueptr; /* UDB pointer for username */ + int errcode; /* IA errorcode */ errcode = 0; getsysudb(); - if ((ueptr = getudbnam(username)) == UDB_NULL) { + if ((ueptr = getudbnam(username)) == UDB_NULL) debug("cray_login_failure(): getudbname() returned NULL"); - } endudb(); - if (ueptr && ueptr->ue_disabled) + + if (ueptr != NULL && ueptr->ue_disabled) errcode = IA_DISABLED; if (errcode) cray_login_failure(username, errcode); + return (errcode); } +/* + * record_failed_login: generic "login failed" interface function + */ +void +record_failed_login(const char *user, const char *ttyname) +{ + cray_login_failure((char *)user, IA_UDBERR); +} + int cray_setup (uid_t uid, char *username, const char *command) { extern struct udb *getudb(); extern char *setlimits(); - int err; /* error return */ - time_t system_time; /* current system clock */ - time_t expiration_time; /* password expiration time */ - int maxattempts; /* maximum no. of failed login attempts */ - int SecureSys; /* unicos security flag */ - int minslevel = 0; /* system minimum security level */ - int i, j; - int valid_acct = -1; /* flag for reading valid acct */ - char acct_name[MAXACID] = { "" }; /* used to read acct name */ - struct jtab jtab; /* Job table struct */ - struct udb ue; /* udb entry for logging-in user */ - struct udb *up; /* pointer to UDB entry */ - struct secstat secinfo; /* file security attributes */ - struct servprov init_info; /* used for sesscntl() call */ - int jid; /* job ID */ - int pid; /* process ID */ - char *sr; /* status return from setlimits() */ - char *ttyn = NULL; /* ttyname or command name*/ - char hostname[MAXHOSTNAMELEN]; - passwd_t pwdacm, - pwddialup, - pwdudb, - pwdwal, - pwddce; /* passwd stuff for ia_user */ - ia_user_ret_t uret; /* stuff returned from ia_user */ - ia_user_t usent; /* ia_user main structure */ - int ia_rcode; /* ia_user return code */ - ia_failure_t fsent; /* ia_failure structure */ + int err; /* error return */ + time_t system_time; /* current system clock */ + time_t expiration_time; /* password expiration time */ + int maxattempts; /* maximum no. of failed login attempts */ + int SecureSys; /* unicos security flag */ + int minslevel = 0; /* system minimum security level */ + int i, j; + int valid_acct = -1; /* flag for reading valid acct */ + char acct_name[MAXACID] = { "" }; /* used to read acct name */ + struct jtab jtab; /* Job table struct */ + struct udb ue; /* udb entry for logging-in user */ + struct udb *up; /* pointer to UDB entry */ + struct secstat secinfo; /* file security attributes */ + struct servprov init_info; /* used for sesscntl() call */ + int jid; /* job ID */ + int pid; /* process ID */ + char *sr; /* status return from setlimits() */ + char *ttyn = NULL; /* ttyname or command name*/ + char hostname[MAXHOSTNAMELEN]; + /* passwd stuff for ia_user */ + passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; + ia_user_ret_t uret; /* stuff returned from ia_user */ + ia_user_t usent /* ia_user main structure */ + int ia_rcode; /* ia_user return code */ + ia_failure_t fsent; /* ia_failure structure */ ia_failure_ret_t fret; /* ia_failure return stuff */ - ia_success_t ssent; /* ia_success structure */ + ia_success_t ssent; /* ia_success structure */ ia_success_ret_t sret; /* ia_success return stuff */ - int ia_mlsrcode; /* ia_mlsuser return code */ - int secstatrc; /* [f]secstat return code */ + int ia_mlsrcode; /* ia_mlsuser return code */ + int secstatrc; /* [f]secstat return code */ if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { getsysv(&sysv, sizeof(struct sysv)); minslevel = sysv.sy_minlvl; - if (getusrv(&usrv) < 0) { - debug("getusrv() failed, errno = %d",errno); - exit(1); - } + if (getusrv(&usrv) < 0) + fatal("getusrv() failed, errno = %d", errno); } hostname[0] = '\0'; - strncpy(hostname, - (char *)get_canonical_hostname(options.verify_reverse_mapping), + strlcpy(hostname, + (char *)get_canonical_hostname(options.use_dns), MAXHOSTNAMELEN); - /* - * Fetch user's UDB entry. - */ - getsysudb(); - if ((up = getudbnam(username)) == UDB_NULL) { - debug("cannot fetch user's UDB entry"); - exit(1); - } - - /* - * Prevent any possible fudging so perform a data - * safety check and compare the supplied uid against - * the udb's uid. - */ - if (up->ue_uid != uid) { - debug("IA uid missmatch"); - exit(1); - } + /* + * Fetch user's UDB entry. + */ + getsysudb(); + if ((up = getudbnam(username)) == UDB_NULL) + fatal("cannot fetch user's UDB entry"); + + /* + * Prevent any possible fudging so perform a data + * safety check and compare the supplied uid against + * the udb's uid. + */ + if (up->ue_uid != uid) + fatal("IA uid missmatch"); endudb(); - if ((jid = getjtab (&jtab)) < 0) { + if ((jid = getjtab(&jtab)) < 0) { debug("getjtab"); - return -1; + return(-1); } pid = getpid(); ttyn = ttyname(0); if (SecureSys) { - if (ttyn) { + if (ttyn != NULL) secstatrc = secstat(ttyn, &secinfo); - } else { + else secstatrc = fsecstat(1, &secinfo); - } - if (secstatrc == 0) { + + if (secstatrc == 0) debug("[f]secstat() successful"); - } else { - debug("[f]secstat() error, rc = %d", secstatrc); - exit(1); - } + else + fatal("[f]secstat() error, rc = %d", secstatrc); } if ((ttyn == NULL) && ((char *)command != NULL)) ttyn = (char *)command; - /* - * Initialize all structures to call ia_user - */ - usent.revision = 0; - usent.uname = username; - usent.host = hostname; - usent.ttyn = ttyn; - usent.caller = IA_SSHD; - usent.pswdlist = &pwdacm; - usent.ueptr = &ue; - usent.flags = IA_INTERACTIVE | IA_FFLAG; - pwdacm.atype = IA_SECURID; - pwdacm.pwdp = NULL; - pwdacm.next = &pwdudb; - - pwdudb.atype = IA_UDB; - pwdudb.pwdp = NULL; - pwdudb.next = &pwddce; - - pwddce.atype = IA_DCE; - pwddce.pwdp = NULL; - pwddce.next = &pwddialup; - - pwddialup.atype = IA_DIALUP; - pwddialup.pwdp = NULL; - /* pwddialup.next = &pwdwal; */ - pwddialup.next = NULL; - - pwdwal.atype = IA_WAL; - pwdwal.pwdp = NULL; - pwdwal.next = NULL; - - uret.revision = 0; - uret.pswd = NULL; - uret.normal = 0; - - ia_rcode = ia_user(&usent, &uret); - - switch (ia_rcode) { - /* - * These are acceptable return codes from ia_user() - */ - case IA_UDBWEEK: /* Password Expires in 1 week */ - expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; - printf ("WARNING - your current password will expire %s\n", - ctime((const time_t *)&expiration_time)); - break; - case IA_UDBEXPIRED: - if (ttyname(0) != NULL) { - /* Force a password change */ - printf("Your password has expired; Choose a new one.\n"); - execl("/bin/passwd", "passwd", username, 0); - exit(9); - } - - break; - case IA_NORMAL: /* Normal Return Code */ - break; - case IA_BACKDOOR: - strcpy(ue.ue_name, "root"); - strcpy(ue.ue_passwd, ""); - strcpy(ue.ue_dir, "/"); - strcpy(ue.ue_shell, "/bin/sh"); - strcpy(ue.ue_age, ""); - strcpy(ue.ue_comment, ""); - strcpy(ue.ue_loghost, ""); - strcpy(ue.ue_logline, ""); - ue.ue_uid=-1; - ue.ue_nice[UDBRC_INTER]=0; - for (i=0;i<MAXVIDS;i++) - ue.ue_gids[i]=0; - ue.ue_logfails=0; - ue.ue_minlvl=minslevel; - ue.ue_maxlvl=minslevel; - ue.ue_deflvl=minslevel; - ue.ue_defcomps=0; - ue.ue_comparts=0; - ue.ue_permits=0; - ue.ue_trap=0; - ue.ue_disabled=0; - ue.ue_logtime=0; - break; - case IA_CONSOLE: /* Superuser not from Console */ - case IA_TRUSTED: /* Trusted user */ - if (options.permit_root_login > PERMIT_NO) - break; /* Accept root login */ - default: - /* - * These are failed return codes from ia_user() - */ - switch (ia_rcode) - { - case IA_BADAUTH: - printf ("Bad authorization, access denied.\n"); - break; - case IA_DIALUPERR: - break; - case IA_DISABLED: - printf ("Your login has been disabled. Contact the system "); - printf ("administrator for assistance.\n"); - break; - case IA_GETSYSV: - printf ("getsysv() failed - errno = %d\n", errno); - break; - case IA_LOCALHOST: - break; - case IA_MAXLOGS: - printf ("Maximum number of failed login attempts exceeded.\n"); - printf ("Access denied.\n"); - break; - case IA_NOPASS: - break; - case IA_PUBLIC: - break; - case IA_SECURIDERR: - break; - case IA_CONSOLE: - break; - case IA_TRUSTED: - break; - case IA_UDBERR: - break; - case IA_UDBPWDNULL: - /* - * NULL password not allowed on MLS systems - */ - if (SecureSys) { - printf("NULL Password not allowed on MLS systems.\n"); - } - break; - case IA_UNKNOWN: - break; - case IA_UNKNOWNYP: - break; - case IA_WALERR: - break; - default: - /* nothing special */ - ; - } /* 2. switch (ia_rcode) */ - /* - * Authentication failed. - */ - printf("sshd: Login incorrect, (0%o)\n", - ia_rcode-IA_ERRORCODE); - - /* - * Initialize structure for ia_failure - * which will exit. - */ - fsent.revision = 0; - fsent.uname = username; - fsent.host = hostname; - fsent.ttyn = ttyn; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = &ue; - fsent.jid = jid; - fsent.errcode = ia_rcode; - fsent.pwdp = uret.pswd; - fsent.exitcode = 1; - - fret.revision = 0; - fret.normal = 0; - - /* - * Call ia_failure because of an IA failure. - * There is no return because ia_failure exits. - */ - - ia_failure(&fsent,&fret); - - exit(1); - } /* 1. switch (ia_rcode) */ + /* + * Initialize all structures to call ia_user + */ + usent.revision = 0; + usent.uname = username; + usent.host = hostname; + usent.ttyn = ttyn; + usent.caller = IA_SSHD; + usent.pswdlist = &pwdacm; + usent.ueptr = &ue; + usent.flags = IA_INTERACTIVE | IA_FFLAG; + pwdacm.atype = IA_SECURID; + pwdacm.pwdp = NULL; + pwdacm.next = &pwdudb; + + pwdudb.atype = IA_UDB; + pwdudb.pwdp = NULL; + pwdudb.next = &pwddce; + + pwddce.atype = IA_DCE; + pwddce.pwdp = NULL; + pwddce.next = &pwddialup; + + pwddialup.atype = IA_DIALUP; + pwddialup.pwdp = NULL; + /* pwddialup.next = &pwdwal; */ + pwddialup.next = NULL; + + pwdwal.atype = IA_WAL; + pwdwal.pwdp = NULL; + pwdwal.next = NULL; + + uret.revision = 0; + uret.pswd = NULL; + uret.normal = 0; + + ia_rcode = ia_user(&usent, &uret); + switch (ia_rcode) { + /* + * These are acceptable return codes from ia_user() + */ + case IA_UDBWEEK: /* Password Expires in 1 week */ + expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; + printf ("WARNING - your current password will expire %s\n", + ctime((const time_t *)&expiration_time)); + break; + case IA_UDBEXPIRED: + if (ttyname(0) != NULL) { + /* Force a password change */ + printf("Your password has expired; Choose a new one.\n"); + execl("/bin/passwd", "passwd", username, 0); + exit(9); + } + break; + case IA_NORMAL: /* Normal Return Code */ + break; + case IA_BACKDOOR: + /* XXX: can we memset it to zero here so save some of this */ + strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); + strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); + strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); + + ue.ue_passwd[0] = '\0'; + ue.ue_age[0] = '\0'; + ue.ue_comment[0] = '\0'; + ue.ue_loghost[0] = '\0'; + ue.ue_logline[0] = '\0'; + + ue.ue_uid = -1; + ue.ue_nice[UDBRC_INTER] = 0; + + for (i = 0; i < MAXVIDS; i++) + ue.ue_gids[i] = 0; + + ue.ue_logfails = 0; + ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; + ue.ue_defcomps = 0; + ue.ue_comparts = 0; + ue.ue_permits = 0; + ue.ue_trap = 0; + ue.ue_disabled = 0; + ue.ue_logtime = 0; + break; + case IA_CONSOLE: /* Superuser not from Console */ + case IA_TRUSTED: /* Trusted user */ + if (options.permit_root_login > PERMIT_NO) + break; /* Accept root login */ + default: + /* + * These are failed return codes from ia_user() + */ + switch (ia_rcode) + { + case IA_BADAUTH: + printf("Bad authorization, access denied.\n"); + break; + case IA_DISABLED: + printf("Your login has been disabled. Contact the system "); + printf("administrator for assistance.\n"); + break; + case IA_GETSYSV: + printf("getsysv() failed - errno = %d\n", errno); + break; + case IA_MAXLOGS: + printf("Maximum number of failed login attempts exceeded.\n"); + printf("Access denied.\n"); + break; + case IA_UDBPWDNULL: + if (SecureSys) + printf("NULL Password not allowed on MLS systems.\n"); + break; + default: + break; + } + + /* + * Authentication failed. + */ + printf("sshd: Login incorrect, (0%o)\n", + ia_rcode-IA_ERRORCODE); + + /* + * Initialize structure for ia_failure + * which will exit. + */ + fsent.revision = 0; + fsent.uname = username; + fsent.host = hostname; + fsent.ttyn = ttyn; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = &ue; + fsent.jid = jid; + fsent.errcode = ia_rcode; + fsent.pwdp = uret.pswd; + fsent.exitcode = 1; + + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an IA failure. + * There is no return because ia_failure exits. + */ + ia_failure(&fsent, &fret); + + exit(1); + } + ia_mlsrcode = IA_NORMAL; if (SecureSys) { debug("calling ia_mlsuser()"); - ia_mlsrcode = ia_mlsuser (&ue, &secinfo, &usrv, NULL, 0); + ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); } if (ia_mlsrcode != IA_NORMAL) { printf("sshd: Login incorrect, (0%o)\n", - ia_mlsrcode-IA_ERRORCODE); + ia_mlsrcode-IA_ERRORCODE); /* - * Initialize structure for ia_failure - * which will exit. - */ + * Initialize structure for ia_failure + * which will exit. + */ fsent.revision = 0; - fsent.uname = username; - fsent.host = hostname; - fsent.ttyn = ttyn; - fsent.caller = IA_SSHD; - fsent.flags = IA_INTERACTIVE; - fsent.ueptr = &ue; - fsent.jid = jid; - fsent.errcode = ia_mlsrcode; - fsent.pwdp = uret.pswd; + fsent.uname = username; + fsent.host = hostname; + fsent.ttyn = ttyn; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = &ue; + fsent.jid = jid; + fsent.errcode = ia_mlsrcode; + fsent.pwdp = uret.pswd; fsent.exitcode = 1; - fret.revision = 0; - fret.normal = 0; + fret.revision = 0; + fret.normal = 0; /* - * Call ia_failure because of an IA failure. - * There is no return because ia_failure exits. - */ + * Call ia_failure because of an IA failure. + * There is no return because ia_failure exits. + */ ia_failure(&fsent,&fret); exit(1); } - /* Provide login status information */ - if (options.print_lastlog && ue.ue_logtime != 0) { - printf("Last successful login was : %.*s ", - 19, (char *)ctime(&ue.ue_logtime)); - - if (*ue.ue_loghost != '\0') - printf("from %.*s\n", sizeof(ue.ue_loghost), ue.ue_loghost); - - else printf("on %.*s\n", sizeof(ue.ue_logline), ue.ue_logline); - - if ( SecureSys && (ue.ue_logfails != 0)) - printf(" followed by %d failed attempts\n", ue.ue_logfails); - } - - + /* Provide login status information */ + if (options.print_lastlog && ue.ue_logtime != 0) { + printf("Last successful login was : %.*s ", 19, + (char *)ctime(&ue.ue_logtime)); + + if (*ue.ue_loghost != '\0') { + printf("from %.*s\n", sizeof(ue.ue_loghost), + ue.ue_loghost); + } else { + printf("on %.*s\n", sizeof(ue.ue_logline), + ue.ue_logline); + } + + if (SecureSys && (ue.ue_logfails != 0)) { + printf(" followed by %d failed attempts\n", + ue.ue_logfails); + } + } + /* * Call ia_success to process successful I/A. */ @@ -472,109 +451,116 @@ cray_setup (uid_t uid, char *username, const char *command) ssent.jid = jid; ssent.errcode = ia_rcode; ssent.us = NULL; - ssent.time = 1; /* Set ue_logtime */ + ssent.time = 1; /* Set ue_logtime */ sret.revision = 0; sret.normal = 0; - ia_success(&ssent,&sret); + ia_success(&ssent, &sret); - /* - * Query for account, iff > 1 valid acid & askacid permbit - */ - if (((ue.ue_permbits & PERMBITS_ACCTID) || - (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && - ue.ue_permbits & PERMBITS_ASKACID) { + /* + * Query for account, iff > 1 valid acid & askacid permbit + */ + if (((ue.ue_permbits & PERMBITS_ACCTID) || + (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && + ue.ue_permbits & PERMBITS_ASKACID) { if (ttyname(0) != NULL) { - debug("cray_setup: ttyname true case, %.100s", ttyname); - while (valid_acct == -1) { - printf("Account (? for available accounts)" - " [%s]: ", acid2nam(ue.ue_acids[0])); - gets(acct_name); - switch (acct_name[0]) { - case EOF: - exit(0); - break; - case '\0': - valid_acct = ue.ue_acids[0]; - strcpy(acct_name, acid2nam(valid_acct)); - break; - case '?': - /* Print the list 3 wide */ - for (i = 0, j = 0; i < MAXVIDS; i++) { - if (ue.ue_acids[i] == -1) { - printf("\n"); - break; - } - if (++j == 4) { - j = 1; - printf("\n"); - } - printf(" %s", - acid2nam(ue.ue_acids[i])); - } - if (ue.ue_permbits & PERMBITS_ACCTID) - printf("\"acctid\" permbit also allows" - " you to select any valid " - "account name.\n"); - printf("\n"); - break; - default: - if ((valid_acct = nam2acid(acct_name)) == -1) printf("Account id not found for" - " account name \"%s\"\n\n", - acct_name); - break; - } - /* - * If an account was given, search the user's - * acids array to verify they can use this account. - */ - if ((valid_acct != -1) && - !(ue.ue_permbits & PERMBITS_ACCTID)) { - for (i = 0; i < MAXVIDS; i++) { - if (ue.ue_acids[i] == -1) - break; - if (valid_acct == ue.ue_acids[i]) - break; - } - if (i == MAXVIDS || - ue.ue_acids[i] == -1) { - fprintf(stderr, "Cannot set" - " account name to " - "\"%s\", permission " - "denied\n\n", acct_name); - valid_acct = -1; - } - } - } + debug("cray_setup: ttyname true case, %.100s", ttyname); + while (valid_acct == -1) { + printf("Account (? for available accounts)" + " [%s]: ", acid2nam(ue.ue_acids[0])); + fgets(acct_name, MAXACID, stdin); + switch (acct_name[0]) { + case EOF: + exit(0); + break; + case '\0': + valid_acct = ue.ue_acids[0]; + strlcpy(acct_name, acid2nam(valid_acct), MAXACID); + break; + case '?': + /* Print the list 3 wide */ + for (i = 0, j = 0; i < MAXVIDS; i++) { + if (ue.ue_acids[i] == -1) { + printf("\n"); + break; + } + if (++j == 4) { + j = 1; + printf("\n"); + } + printf(" %s", + acid2nam(ue.ue_acids[i])); + } + if (ue.ue_permbits & PERMBITS_ACCTID) { + printf("\"acctid\" permbit also allows" + " you to select any valid " + "account name.\n"); + } + printf("\n"); + break; + default: + valid_acct = nam2acid(acct_name); + if (valid_acct == -1) { + printf( + "Account id not found for" + " account name \"%s\"\n\n", + acct_name); + break; + } + /* + * If an account was given, search the user's + * acids array to verify they can use this account. + */ + if ((valid_acct != -1) && + !(ue.ue_permbits & PERMBITS_ACCTID)) { + for (i = 0; i < MAXVIDS; i++) { + if (ue.ue_acids[i] == -1) + break; + if (valid_acct == ue.ue_acids[i]) + break; + } + if (i == MAXVIDS || + ue.ue_acids[i] == -1) { + fprintf(stderr, "Cannot set" + " account name to " + "\"%s\", permission " + "denied\n\n", acct_name); + valid_acct = -1; + } + } + } + } else { + /* + * The client isn't connected to a terminal and can't + * respond to an acid prompt. Use default acid. + */ + debug("cray_setup: ttyname false case, %.100s", + ttyname); + valid_acct = ue.ue_acids[0]; + } } else { /* - * The client isn't connected to a terminal and can't - * respond to an acid prompt. Use default acid. + * The user doesn't have the askacid permbit set or + * only has one valid account to use. */ - debug("cray_setup: ttyname false case, %.100s", ttyname); valid_acct = ue.ue_acids[0]; } - } else { - /* - * The user doesn't have the askacid permbit set or - * only has one valid account to use. - */ - valid_acct = ue.ue_acids[0]; - } - if (acctid(0, valid_acct) < 0) { - printf ("Bad account id: %d\n", valid_acct); - exit(1); - } - -/* set up shares and quotas */ -/* Now set shares, quotas, limits, including CPU time for the (interactive) - * job and process, and set up permissions (for chown etc), etc. - */ + if (acctid(0, valid_acct) < 0) { + printf ("Bad account id: %d\n", valid_acct); + exit(1); + } + + /* + * Now set shares, quotas, limits, including CPU time for the + * (interactive) job and process, and set up permissions + * (for chown etc), etc. + */ if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { - printf("Unable to give %d shares to <%s>(%d/%d)\n", ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); + printf("Unable to give %d shares to <%s>(%d/%d)\n", + ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); exit(1); - } + } sr = setlimits(username, C_PROC, pid, UDBRC_INTER); if (sr != NULL) { @@ -587,17 +573,15 @@ cray_setup (uid_t uid, char *username, const char *command) exit(1); } /* - * Place the service provider information into + * Place the service provider information into * the session table (Unicos) or job table (Unicos/mk). * There exist double defines for the job/session table in * unicos/mk (jtab.h) so no need for a compile time switch. */ - bzero((char *)&init_info, sizeof(struct servprov)); - init_info.s_sessinit.si_id = URM_SPT_LOGIN; + memset(&init_info, '\0', sizeof(init_info)); + init_info.s_sessinit.si_id = URM_SPT_LOGIN; init_info.s_sessinit.si_pid = getpid(); init_info.s_sessinit.si_sid = jid; - init_info.s_routing.seqno = 0; - init_info.s_routing.iadrs = 0; sesscntl(0, S_SETSERVPO, (int)&init_info); /* @@ -610,7 +594,7 @@ cray_setup (uid_t uid, char *username, const char *command) } } - return(0); + return (0); } /* @@ -623,10 +607,10 @@ void drop_cray_privs() { #if defined(_SC_CRAY_PRIV_SU) - priv_proc_t* privstate; - int result; - extern int priv_set_proc(); - extern priv_proc_t* priv_init_proc(); + priv_proc_t *privstate; + int result; + extern int priv_set_proc(); + extern priv_proc_t *priv_init_proc(); /* * If ether of theses two flags are not set @@ -654,15 +638,17 @@ drop_cray_privs() usrv.sv_intcat = TFM_SYSTEM; usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); - if (setusrv(&usrv) < 0) + if (setusrv(&usrv) < 0) { fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, strerror(errno)); + } if ((privstate = priv_init_proc()) != NULL) { result = priv_set_proc(privstate); - if (result != 0 ) + if (result != 0 ) { fatal("%s(%d): priv_set_proc(): %s", __FILE__, __LINE__, strerror(errno)); + } priv_free_proc(privstate); } debug ("Privileges should be cleared..."); @@ -683,6 +669,7 @@ cray_retain_utmp(struct utmp *ut, int pid) struct utmp utmp; if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { + /* XXX use atomicio */ while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { if (pid == utmp.ut_pid) { ut->ut_jid = utmp.ut_jid; @@ -693,9 +680,8 @@ cray_retain_utmp(struct utmp *ut, int pid) } } close(fd); - } - else - fatal("Unable to open utmp file"); + } else + fatal("Unable to open utmp file"); } /* @@ -708,11 +694,9 @@ cray_retain_utmp(struct utmp *ut, int pid) void cray_delete_tmpdir(char *login, int jid, uid_t uid) { - int child; static char jtmp[TPATHSIZ]; struct stat statbuf; - int c; - int wstat; + int child, c, wstat; for (c = 'a'; c <= 'z'; c++) { snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); diff --git a/crypto/openssh/openbsd-compat/bsd-cray.h b/crypto/openssh/openbsd-compat/bsd-cray.h index a09954f..a121ea1 100644 --- a/crypto/openssh/openbsd-compat/bsd-cray.h +++ b/crypto/openssh/openbsd-compat/bsd-cray.h @@ -1,8 +1,6 @@ -/* - * $Id: bsd-cray.h,v 1.7 2003/03/21 01:05:38 mouring Exp $ - * - * bsd-cray.h - * +/* $Id: bsd-cray.h,v 1.10 2003/08/29 16:59:52 mouring Exp $ */ + +/* * Copyright (c) 2002, Cray Inc. (Wendy Palm <wendyp@cray.com>) * Significant portions provided by * Wayne Schroeder, SDSC <schroeder@sdsc.edu> @@ -34,25 +32,31 @@ * on UNICOS systems. * */ + #ifndef _BSD_CRAY_H #define _BSD_CRAY_H #ifdef _UNICOS -void cray_init_job(struct passwd *); /* init cray job */ -void cray_job_termination_handler(int); /* process end of job signal */ -void cray_login_failure(char *username, int errcode); -int cray_access_denied(char *username); -extern char cray_tmpdir[]; /* cray tmpdir */ + +void cray_init_job(struct passwd *); +void cray_job_termination_handler(int); +void cray_login_failure(char *, int ); +int cray_access_denied(char *); +#define CUSTOM_FAILED_LOGIN 1 +void record_failed_login(const char *, const char *); +extern char cray_tmpdir[]; + #ifndef IA_SSHD -#define IA_SSHD IA_LOGIN +# define IA_SSHD IA_LOGIN #endif #ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 +# define MAXHOSTNAMELEN 64 #endif #ifndef _CRAYT3E -#include <sys/ttold.h> -#define TIOCGPGRP (tIOC|20) -#endif +# include <sys/ttold.h> +# define TIOCGPGRP (tIOC|20) #endif +#endif /* UNICOS */ + #endif /* _BSD_CRAY_H */ diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c index 0fa5964..a87cf3c 100644 --- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.c +++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.c @@ -1,6 +1,4 @@ /* - * cygwin_util.c - * * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> * * Redistribution and use in source and binary forms, with or without @@ -31,7 +29,7 @@ #include "includes.h" -RCSID("$Id: bsd-cygwin_util.c,v 1.9 2002/11/09 15:59:29 mouring Exp $"); +RCSID("$Id: bsd-cygwin_util.c,v 1.11 2003/08/07 06:23:43 dtucker Exp $"); #ifdef HAVE_CYGWIN @@ -53,7 +51,8 @@ RCSID("$Id: bsd-cygwin_util.c,v 1.9 2002/11/09 15:59:29 mouring Exp $"); # undef pipe #endif -int binary_open(const char *filename, int flags, ...) +int +binary_open(const char *filename, int flags, ...) { va_list ap; mode_t mode; @@ -61,55 +60,56 @@ int binary_open(const char *filename, int flags, ...) va_start(ap, flags); mode = va_arg(ap, mode_t); va_end(ap); - return open(filename, flags | O_BINARY, mode); + return (open(filename, flags | O_BINARY, mode)); } -int binary_pipe(int fd[2]) +int +binary_pipe(int fd[2]) { int ret = pipe(fd); if (!ret) { - setmode (fd[0], O_BINARY); - setmode (fd[1], O_BINARY); + setmode(fd[0], O_BINARY); + setmode(fd[1], O_BINARY); } - return ret; + return (ret); } #define HAS_CREATE_TOKEN 1 #define HAS_NTSEC_BY_DEFAULT 2 -static int has_capability(int what) +static int +has_capability(int what) { - /* has_capability() basically calls uname() and checks if - specific capabilities of Cygwin can be evaluated from that. - This simplifies the calling functions which only have to ask - for a capability using has_capability() instead of having - to figure that out by themselves. */ static int inited; static int has_create_token; static int has_ntsec_by_default; + /* + * has_capability() basically calls uname() and checks if + * specific capabilities of Cygwin can be evaluated from that. + * This simplifies the calling functions which only have to ask + * for a capability using has_capability() instead of having + * to figure that out by themselves. + */ if (!inited) { struct utsname uts; char *c; if (!uname(&uts)) { - int major_high = 0; - int major_low = 0; - int minor = 0; - int api_major_version = 0; - int api_minor_version = 0; + int major_high = 0, major_low = 0, minor = 0; + int api_major_version = 0, api_minor_version = 0; char *c; sscanf(uts.release, "%d.%d.%d", &major_high, - &major_low, &minor); - c = strchr(uts.release, '('); - if (c) + &major_low, &minor); + if ((c = strchr(uts.release, '(')) != NULL) { sscanf(c + 1, "%d.%d", &api_major_version, - &api_minor_version); + &api_minor_version); + } if (major_high > 1 || (major_high == 1 && (major_low > 3 || - (major_low == 3 && minor >= 2)))) + (major_low == 3 && minor >= 2)))) has_create_token = 1; if (api_major_version > 0 || api_minor_version >= 56) has_ntsec_by_default = 1; @@ -118,14 +118,15 @@ static int has_capability(int what) } switch (what) { case HAS_CREATE_TOKEN: - return has_create_token; + return (has_create_token); case HAS_NTSEC_BY_DEFAULT: - return has_ntsec_by_default; + return (has_ntsec_by_default); } - return 0; + return (0); } -int check_nt_auth(int pwd_authenticated, struct passwd *pw) +int +check_nt_auth(int pwd_authenticated, struct passwd *pw) { /* * The only authentication which is able to change the user @@ -149,34 +150,33 @@ int check_nt_auth(int pwd_authenticated, struct passwd *pw) has_create_token = 0; if (has_capability(HAS_CREATE_TOKEN) && (ntsec_on(cygwin) || - (has_capability(HAS_NTSEC_BY_DEFAULT) && - !ntsec_off(cygwin)))) + (has_capability(HAS_NTSEC_BY_DEFAULT) && + !ntsec_off(cygwin)))) has_create_token = 1; } if (has_create_token < 1 && !pwd_authenticated && geteuid() != pw->pw_uid) - return 0; + return (0); } - return 1; + return (1); } -int check_ntsec(const char *filename) +int +check_ntsec(const char *filename) { char *cygwin; - int allow_ntea = 0; - int allow_ntsec = 0; + int allow_ntea = 0, allow_ntsec = 0; struct statfs fsstat; /* Windows 95/98/ME don't support file system security at all. */ if (!is_winnt) - return 0; + return (0); /* Evaluate current CYGWIN settings. */ cygwin = getenv("CYGWIN"); allow_ntea = ntea_on(cygwin); allow_ntsec = ntsec_on(cygwin) || - (has_capability(HAS_NTSEC_BY_DEFAULT) && - !ntsec_off(cygwin)); + (has_capability(HAS_NTSEC_BY_DEFAULT) && !ntsec_off(cygwin)); /* * `ntea' is an emulation of POSIX attributes. It doesn't support @@ -185,14 +185,14 @@ int check_ntsec(const char *filename) * for security checks. */ if (allow_ntea) - return 1; + return (1); /* * Retrieve file system flags. In Cygwin, file system flags are * copied to f_type which has no meaning in Win32 itself. */ if (statfs(filename, &fsstat)) - return 1; + return (1); /* * Only file systems supporting ACLs are able to set permissions. @@ -200,12 +200,13 @@ int check_ntsec(const char *filename) * ACLs to support POSIX permissions on files. */ if (fsstat.f_type & FS_PERSISTENT_ACLS) - return allow_ntsec; + return (allow_ntsec); - return 0; + return (0); } -void register_9x_service(void) +void +register_9x_service(void) { HINSTANCE kerneldll; DWORD (*RegisterServiceProcess)(DWORD, DWORD); @@ -219,10 +220,10 @@ void register_9x_service(void) */ if (is_winnt) return; - if (! (kerneldll = LoadLibrary("KERNEL32.DLL"))) + if (!(kerneldll = LoadLibrary("KERNEL32.DLL"))) return; - if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) - GetProcAddress(kerneldll, "RegisterServiceProcess"))) + if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) + GetProcAddress(kerneldll, "RegisterServiceProcess"))) return; RegisterServiceProcess(0, 1); } diff --git a/crypto/openssh/openbsd-compat/bsd-cygwin_util.h b/crypto/openssh/openbsd-compat/bsd-cygwin_util.h index af470bd..5ccb0fb 100644 --- a/crypto/openssh/openbsd-compat/bsd-cygwin_util.h +++ b/crypto/openssh/openbsd-compat/bsd-cygwin_util.h @@ -1,8 +1,6 @@ -/* $Id: bsd-cygwin_util.h,v 1.7 2002/04/15 22:00:52 stevesk Exp $ */ +/* $Id: bsd-cygwin_util.h,v 1.10 2003/08/07 06:28:16 dtucker Exp $ */ /* - * cygwin_util.c - * * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> * * Redistribution and use in source and binary forms, with or without @@ -36,12 +34,17 @@ #ifdef HAVE_CYGWIN +#undef ERROR +#define is_winnt (GetVersion() < 0x80000000) + +#include <windows.h> +#include <sys/cygwin.h> #include <io.h> -int binary_open(const char *filename, int flags, ...); +int binary_open(const char *, int , ...); int binary_pipe(int fd[2]); -int check_nt_auth(int pwd_authenticated, struct passwd *pw); -int check_ntsec(const char *filename); +int check_nt_auth(int, struct passwd *); +int check_ntsec(const char *); void register_9x_service(void); #define open binary_open diff --git a/crypto/openssh/openbsd-compat/bsd-misc.c b/crypto/openssh/openbsd-compat/bsd-misc.c index b8e9996..08b089b 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.c +++ b/crypto/openssh/openbsd-compat/bsd-misc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2000 Damien Miller. All rights reserved. + * Copyright (c) 1999-2003 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,13 +25,13 @@ #include "includes.h" #include "xmalloc.h" -RCSID("$Id: bsd-misc.c,v 1.12 2003/03/18 18:21:41 tim Exp $"); +RCSID("$Id: bsd-misc.c,v 1.19 2003/08/25 01:16:21 mouring Exp $"); /* * NB. duplicate __progname in case it is an alias for argv[0] * Otherwise it may get clobbered by setproctitle() */ -char *get_progname(char *argv0) +char *ssh_get_progname(char *argv0) { #ifdef HAVE___PROGNAME extern char *__progname; @@ -41,21 +41,21 @@ char *get_progname(char *argv0) char *p; if (argv0 == NULL) - return "unknown"; /* XXX */ + return ("unknown"); /* XXX */ p = strrchr(argv0, '/'); if (p == NULL) p = argv0; else p++; - return xstrdup(p); + return (xstrdup(p)); #endif } #ifndef HAVE_SETLOGIN int setlogin(const char *name) { - return(0); + return (0); } #endif /* !HAVE_SETLOGIN */ @@ -63,21 +63,21 @@ int setlogin(const char *name) int innetgr(const char *netgroup, const char *host, const char *user, const char *domain) { - return(0); + return (0); } #endif /* HAVE_INNETGR */ #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) int seteuid(uid_t euid) { - return(setreuid(-1,euid)); + return (setreuid(-1, euid)); } #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) int setegid(uid_t egid) { - return(setresgid(-1,egid,-1)); + return(setresgid(-1, egid, -1)); } #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ @@ -88,9 +88,9 @@ const char *strerror(int e) extern char *sys_errlist[]; if ((e >= 0) && (e < sys_nerr)) - return(sys_errlist[e]); - else - return("unlisted error"); + return (sys_errlist[e]); + + return ("unlisted error"); } #endif @@ -102,24 +102,25 @@ int utimes(char *filename, struct timeval *tvp) ub.actime = tvp[0].tv_sec; ub.modtime = tvp[1].tv_sec; - return(utime(filename, &ub)); + return (utime(filename, &ub)); } #endif #ifndef HAVE_TRUNCATE -int truncate (const char *path, off_t length) +int truncate(const char *path, off_t length) { int fd, ret, saverrno; fd = open(path, O_WRONLY); if (fd < 0) - return -1; + return (-1); ret = ftruncate(fd, length); saverrno = errno; - (void) close (fd); + close(fd); if (ret == -1) errno = saverrno; + return(ret); } #endif /* HAVE_TRUNCATE */ @@ -131,7 +132,7 @@ int truncate (const char *path, off_t length) int setgroups(size_t size, const gid_t *list) { - return 0; + return (0); } #endif @@ -166,3 +167,62 @@ int nanosleep(const struct timespec *req, struct timespec *rem) #endif +#ifndef HAVE_TCGETPGRP +pid_t +tcgetpgrp(int fd) +{ + int ctty_pgrp; + + if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) + return(-1); + else + return(ctty_pgrp); +} +#endif /* HAVE_TCGETPGRP */ + +#ifndef HAVE_TCSENDBREAK +int +tcsendbreak(int fd, int duration) +{ +# if defined(TIOCSBRK) && defined(TIOCCBRK) + struct timeval sleepytime; + + sleepytime.tv_sec = 0; + sleepytime.tv_usec = 400000; + if (ioctl(fd, TIOCSBRK, 0) == -1) + return (-1); + (void)select(0, 0, 0, 0, &sleepytime); + if (ioctl(fd, TIOCCBRK, 0) == -1) + return (-1); + return (0); +# else + return -1; +# endif +} +#endif /* HAVE_TCSENDBREAK */ + +mysig_t +mysignal(int sig, mysig_t act) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa, osa; + + if (sigaction(sig, NULL, &osa) == -1) + return (mysig_t) -1; + if (osa.sa_handler != act) { + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; +#ifdef SA_INTERRUPT + if (sig == SIGALRM) + sa.sa_flags |= SA_INTERRUPT; +#endif + sa.sa_handler = act; + if (sigaction(sig, &sa, NULL) == -1) + return (mysig_t) -1; + } + return (osa.sa_handler); +#else + return (signal(sig, act)); +#endif +} diff --git a/crypto/openssh/openbsd-compat/bsd-misc.h b/crypto/openssh/openbsd-compat/bsd-misc.h index 78d9ccd..6b70473 100644 --- a/crypto/openssh/openbsd-compat/bsd-misc.h +++ b/crypto/openssh/openbsd-compat/bsd-misc.h @@ -1,5 +1,7 @@ +/* $Id: bsd-misc.h,v 1.13 2003/08/29 16:59:52 mouring Exp $ */ + /* - * Copyright (c) 1999-2000 Damien Miller. All rights reserved. + * Copyright (c) 1999-2003 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,42 +24,39 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: bsd-misc.h,v 1.7 2003/03/18 18:21:41 tim Exp $ */ - #ifndef _BSD_MISC_H #define _BSD_MISC_H -#include "config.h" +#include "includes.h" -char *get_progname(char *argv0); +char *ssh_get_progname(char *); #ifndef HAVE_SETSID #define setsid() setpgrp(0, getpid()) #endif /* !HAVE_SETSID */ #ifndef HAVE_SETENV -int setenv(const char *name, const char *value, int overwrite); +int setenv(const char *, const char *, int); #endif /* !HAVE_SETENV */ #ifndef HAVE_SETLOGIN -int setlogin(const char *name); +int setlogin(const char *); #endif /* !HAVE_SETLOGIN */ #ifndef HAVE_INNETGR -int innetgr(const char *netgroup, const char *host, - const char *user, const char *domain); +int innetgr(const char *, const char *, const char *, const char *); #endif /* HAVE_INNETGR */ #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) -int seteuid(uid_t euid); +int seteuid(uid_t); #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) -int setegid(uid_t egid); +int setegid(uid_t); #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) -const char *strerror(int e); +const char *strerror(int); #endif @@ -69,15 +68,15 @@ struct timeval { } #endif /* HAVE_STRUCT_TIMEVAL */ -int utimes(char *filename, struct timeval *tvp); +int utimes(char *, struct timeval *); #endif /* HAVE_UTIMES */ #ifndef HAVE_TRUNCATE -int truncate (const char *path, off_t length); +int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ #if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) -int setgroups(size_t size, const gid_t *list); +int setgroups(size_t, const gid_t *); #endif #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) @@ -87,7 +86,21 @@ struct timespec { long tv_nsec; }; #endif -int nanosleep(const struct timespec *req, struct timespec *rem); +int nanosleep(const struct timespec *, struct timespec *); +#endif + +#ifndef HAVE_TCGETPGRP +pid_t tcgetpgrp(int); +#endif + +#ifndef HAVE_TCSENDBREAK +int tcsendbreak(int, int); #endif +/* wrapper for signal interface */ +typedef void (*mysig_t)(int); +mysig_t mysignal(int sig, mysig_t act); + +#define signal(a,b) mysignal(a,b) + #endif /* _BSD_MISC_H */ diff --git a/crypto/openssh/openbsd-compat/bsd-nextstep.c b/crypto/openssh/openbsd-compat/bsd-nextstep.c index 85b298a..bd35a3a 100644 --- a/crypto/openssh/openbsd-compat/bsd-nextstep.c +++ b/crypto/openssh/openbsd-compat/bsd-nextstep.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -22,7 +24,7 @@ #include "includes.h" -RCSID("$Id: bsd-nextstep.c,v 1.4 2001/03/26 05:35:34 mouring Exp $"); +RCSID("$Id: bsd-nextstep.c,v 1.6 2003/06/01 03:23:57 mouring Exp $"); #ifdef HAVE_NEXT #include <errno.h> @@ -40,7 +42,7 @@ posix_wait(int *status) if (status) *status = (int) statusp.w_status; - return wait_pid; + return (wait_pid); } int diff --git a/crypto/openssh/openbsd-compat/bsd-nextstep.h b/crypto/openssh/openbsd-compat/bsd-nextstep.h index c6a7019..ca5b4b5 100644 --- a/crypto/openssh/openbsd-compat/bsd-nextstep.h +++ b/crypto/openssh/openbsd-compat/bsd-nextstep.h @@ -1,4 +1,8 @@ +/* $Id: bsd-nextstep.h,v 1.9 2003/08/29 16:59:52 mouring Exp $ */ + /* + * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -21,8 +25,6 @@ * */ -/* $Id: bsd-nextstep.h,v 1.6 2001/03/19 13:42:22 mouring Exp $ */ - #ifndef _NEXT_POSIX_H #define _NEXT_POSIX_H @@ -37,22 +39,21 @@ #define dirent direct /* Swap out NeXT's BSD wait() for a more POSIX complient one */ -pid_t posix_wait(int *status); +pid_t posix_wait(int *); #define wait(a) posix_wait(a) /* #ifdef wrapped functions that need defining for clean compiling */ pid_t getppid(void); void vhangup(void); -int innetgr(const char *netgroup, const char *host, const char *user, - const char *domain); +int innetgr(const char *, const char *, const char *, const char *); /* TERMCAP */ -int tcgetattr(int fd, struct termios *t); -int tcsetattr(int fd, int opt, const struct termios *t); -int tcsetpgrp(int fd, pid_t pgrp); -speed_t cfgetospeed(const struct termios *t); -speed_t cfgetispeed(const struct termios *t); -int cfsetospeed(struct termios *t, int speed); -int cfsetispeed(struct termios *t, int speed); +int tcgetattr(int, struct termios *); +int tcsetattr(int, int, const struct termios *); +int tcsetpgrp(int, pid_t); +speed_t cfgetospeed(const struct termios *); +speed_t cfgetispeed(const struct termios *); +int cfsetospeed(struct termios *, int); +int cfsetispeed(struct termios *, int); #endif /* HAVE_NEXT */ #endif /* _NEXT_POSIX_H */ diff --git a/crypto/openssh/openbsd-compat/bsd-snprintf.c b/crypto/openssh/openbsd-compat/bsd-snprintf.c index 2f82180..e4d8a43 100644 --- a/crypto/openssh/openbsd-compat/bsd-snprintf.c +++ b/crypto/openssh/openbsd-compat/bsd-snprintf.c @@ -58,7 +58,7 @@ #include "includes.h" -RCSID("$Id: bsd-snprintf.c,v 1.6 2003/04/01 11:31:56 djm Exp $"); +RCSID("$Id: bsd-snprintf.c,v 1.7 2003/05/18 14:13:39 djm Exp $"); #if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ # undef HAVE_SNPRINTF @@ -72,15 +72,15 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args); static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, - int min, int max); + int min, int max); static void fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, - int min, int max, int flags); + int min, int max, int flags); static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, - int min, int max, int flags); + int min, int max, int flags); static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); @@ -121,15 +121,10 @@ dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); static void dopr(char *buffer, size_t maxlen, const char *format, va_list args) { - char *strvalue; - char ch; + char *strvalue, ch; long value; long double fvalue; - int min = 0; - int max = -1; - int state = DP_S_DEFAULT; - int flags = 0; - int cflags = 0; + int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0; size_t currlen = 0; ch = *format++; @@ -139,224 +134,224 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) state = DP_S_DONE; switch(state) { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - dopr_outch(buffer, &currlen, maxlen, ch); + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch(buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; ch = *format++; break; - case DP_S_FLAGS: - switch (ch) { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } + case '+': + flags |= DP_F_PLUS; + ch = *format++; break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) { - min = 10*min + char_to_int (ch); - ch = *format++; - } else if (ch == '*') { - min = va_arg (args, int); - ch = *format++; - state = DP_S_DOT; - } else - state = DP_S_DOT; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; break; - case DP_S_DOT: - if (ch == '.') { - state = DP_S_MAX; - ch = *format++; - } else - state = DP_S_MOD; + case '#': + flags |= DP_F_NUM; + ch = *format++; break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) { - if (max < 0) - max = 0; - max = 10*max + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - max = va_arg (args, int); - ch = *format++; - state = DP_S_MOD; - } else - state = DP_S_MOD; + case '0': + flags |= DP_F_ZERO; + ch = *format++; break; - case DP_S_MOD: - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { - cflags = DP_C_LONG_LONG; - ch = *format++; - } - break; - case 'q': - cflags = DP_C_LONG_LONG; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; + default: + state = DP_S_MIN; break; - case DP_S_CONV: - switch (ch) { - case 'd': - case 'i': - if (cflags == DP_C_SHORT) - value = va_arg(args, int); - else if (cflags == DP_C_LONG) - value = va_arg(args, long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg (args, long long); - else - value = va_arg (args, int); - fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'o': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); - break; - case 'u': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); - break; - case 'X': - flags |= DP_F_UP; - case 'x': - flags |= DP_F_UNSIGNED; - if (cflags == DP_C_SHORT) - value = va_arg(args, unsigned int); - else if (cflags == DP_C_LONG) - value = va_arg(args, unsigned long int); - else if (cflags == DP_C_LONG_LONG) - value = va_arg(args, unsigned long long); - else - value = va_arg(args, unsigned int); - fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - /* um, floating point? */ - fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); - break; - case 'E': - flags |= DP_F_UP; - case 'e': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - break; - case 'G': - flags |= DP_F_UP; - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, long double); - else - fvalue = va_arg(args, double); - break; - case 'c': - dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); - break; - case 's': - strvalue = va_arg(args, char *); - if (max < 0) - max = maxlen; /* ie, no max */ - fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); - break; - case 'p': - strvalue = va_arg(args, void *); - fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); - break; - case 'n': - if (cflags == DP_C_SHORT) { - short int *num; - num = va_arg(args, short int *); - *num = currlen; - } else if (cflags == DP_C_LONG) { - long int *num; - num = va_arg(args, long int *); - *num = currlen; - } else if (cflags == DP_C_LONG_LONG) { - long long *num; - num = va_arg(args, long long *); - *num = currlen; - } else { - int *num; - num = va_arg(args, int *); - *num = currlen; - } - break; - case '%': - dopr_outch(buffer, &currlen, maxlen, ch); - break; - case 'w': /* not supported yet, treat as next char */ - ch = *format++; - break; - default: /* Unknown, skip */ - break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10 * min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10 * max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { + cflags = DP_C_LONG_LONG; + ch = *format++; } + break; + case 'q': + cflags = DP_C_LONG_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; break; - case DP_S_DONE: + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg(args, int); + else if (cflags == DP_C_LONG) + value = va_arg(args, long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, long long); + else + value = va_arg (args, int); + fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); break; - default: /* hmm? */ - break; /* some picky compilers need this */ + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + /* um, floating point? */ + fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'c': + dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); + break; + case 's': + strvalue = va_arg(args, char *); + if (max < 0) + max = maxlen; /* ie, no max */ + fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg(args, void *); + fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg(args, long int *); + *num = currlen; + } else if (cflags == DP_C_LONG_LONG) { + long long *num; + num = va_arg(args, long long *); + *num = currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch(buffer, &currlen, maxlen, ch); + break; + case 'w': /* not supported yet, treat as next char */ + ch = *format++; + break; + default: /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: /* hmm? */ + break; /* some picky compilers need this */ } } if (currlen < maxlen - 1) @@ -367,10 +362,9 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args) static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) + char *value, int flags, int min, int max) { - int padlen, strln; /* amount to pad */ - int cnt = 0; + int cnt = 0, padlen, strln; /* amount to pad */ if (value == 0) value = "<NULL>"; @@ -402,15 +396,13 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - long value, int base, int min, int max, int flags) + long value, int base, int min, int max, int flags) { unsigned long uvalue; char convert[20]; - int signvalue = 0; - int place = 0; + int signvalue = 0, place = 0, caps = 0; int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ - int caps = 0; if (max < 0) max = 0; @@ -429,11 +421,10 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ - do { convert[place++] = - (caps? "0123456789ABCDEF":"0123456789abcdef") - [uvalue % (unsigned)base]; + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned)base]; uvalue = (uvalue / (unsigned)base ); } while (uvalue && (place < 20)); if (place == 20) @@ -453,7 +444,6 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ - /* Spaces */ while (spadlen > 0) { dopr_outch(buffer, currlen, maxlen, ' '); @@ -512,16 +502,11 @@ static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, int min, int max, int flags) { - char iconvert[20]; - char fconvert[20]; - int signvalue = 0; - int iplace = 0; - int fplace = 0; + char iconvert[20], fconvert[20]; + int signvalue = 0, iplace = 0, fplace = 0; int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - long intpart; - long fracpart; + int zpadlen = 0, caps = 0; + long intpart, fracpart; long double ufvalue; /* @@ -562,7 +547,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, /* Convert integer part */ do { iconvert[iplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [intpart % 10]; intpart = (intpart / 10); } while(intpart && (iplace < 20)); if (iplace == 20) @@ -572,7 +558,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, /* Convert fractional part */ do { fconvert[fplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [fracpart % 10]; fracpart = (fracpart / 10); } while(fracpart && (fplace < 20)); if (fplace == 20) @@ -611,8 +598,8 @@ fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); /* - * Decimal point. This should probably use locale to find the correct - * char to print out. + * Decimal point. This should probably use locale to find the + * correct char to print out. */ dopr_outch(buffer, currlen, maxlen, '.'); @@ -662,90 +649,4 @@ snprintf(char *str,size_t count,const char *fmt,...) return(strlen(str)); } -#ifdef TEST_SNPRINTF -int -main(void) -{ -#define LONG_STRING 1024 - char buf1[LONG_STRING]; - char buf2[LONG_STRING]; - char *fp_fmt[] = { - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - NULL - }; - double fp_nums[] = { - -1.5, - 134.21, - 91340.2, - 341.1234, - 0203.9, - 0.96, - 0.996, - 0.9996, - 1.996, - 4.136, - 0 - }; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%lld", - "%qd", - NULL - }; - long long int_nums[] = { -1, 134, 91340, 341, 0203, 0, 9999999 }; - int x, y; - int fail = 0; - int num = 0; - - printf("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] != NULL ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - snprintf(buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); - sprintf (buf2, fp_fmt[x], fp_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\t" - "snprintf = %s\n\tsprintf = %s\n", - fp_fmt[x], buf1, buf2); - fail++; - } - num++; - } - } - for (x = 0; int_fmt[x] != NULL ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - snprintf(buf1, sizeof (buf1), int_fmt[x], int_nums[y]); - sprintf(buf2, int_fmt[x], int_nums[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\t" - "snprintf = %s\n\tsprintf = %s\n", - int_fmt[x], buf1, buf2); - fail++; - } - num++; - } - } - printf("%d tests failed out of %d.\n", fail, num); - return(0); -} -#endif /* SNPRINTF_TEST */ - #endif /* !HAVE_SNPRINTF */ diff --git a/crypto/openssh/openbsd-compat/bsd-waitpid.c b/crypto/openssh/openbsd-compat/bsd-waitpid.c index 47b4446..93c9ec3 100644 --- a/crypto/openssh/openbsd-compat/bsd-waitpid.c +++ b/crypto/openssh/openbsd-compat/bsd-waitpid.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 2000 Ben Lindstrom. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -22,7 +24,7 @@ #include "includes.h" -RCSID("$Id: bsd-waitpid.c,v 1.3 2001/03/26 05:35:34 mouring Exp $"); +RCSID("$Id: bsd-waitpid.c,v 1.5 2003/06/01 03:23:57 mouring Exp $"); #ifndef HAVE_WAITPID #include <errno.h> @@ -38,15 +40,16 @@ waitpid(int pid, int *stat_loc, int options) if (pid <= 0) { if (pid != -1) { errno = EINVAL; - return -1; + return (-1); } - pid = 0; /* wait4() wants pid=0 for indiscriminate wait. */ + /* wait4() wants pid=0 for indiscriminate wait. */ + pid = 0; } wait_pid = wait4(pid, &statusp, options, NULL); if (stat_loc) *stat_loc = (int) statusp.w_status; - return wait_pid; + return (wait_pid); } #endif /* !HAVE_WAITPID */ diff --git a/crypto/openssh/openbsd-compat/bsd-waitpid.h b/crypto/openssh/openbsd-compat/bsd-waitpid.h index e24edd7..2d853db 100644 --- a/crypto/openssh/openbsd-compat/bsd-waitpid.h +++ b/crypto/openssh/openbsd-compat/bsd-waitpid.h @@ -1,4 +1,8 @@ +/* $Id: bsd-waitpid.h,v 1.5 2003/08/29 16:59:52 mouring Exp $ */ + /* + * Copyright (c) 2000 Ben Lindstrom. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -21,8 +25,6 @@ * */ -/* $Id: bsd-waitpid.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ - #ifndef _BSD_WAITPID_H #define _BSD_WAITPID_H @@ -43,7 +45,7 @@ #define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) /* Prototype */ -pid_t waitpid(int pid, int *stat_loc, int options); +pid_t waitpid(int, int *, int); #endif /* !HAVE_WAITPID */ #endif /* _BSD_WAITPID_H */ diff --git a/crypto/openssh/openbsd-compat/daemon.c b/crypto/openssh/openbsd-compat/daemon.c index 7d23b24..6dd45f6 100644 --- a/crypto/openssh/openbsd-compat/daemon.c +++ b/crypto/openssh/openbsd-compat/daemon.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -36,12 +32,11 @@ #ifndef HAVE_DAEMON #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: daemon.c,v 1.2 1996/08/19 08:22:13 tholo Exp $"; +static char rcsid[] = "$OpenBSD: daemon.c,v 1.5 2003/07/15 17:32:41 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ int -daemon(nochdir, noclose) - int nochdir, noclose; +daemon(int nochdir, int noclose) { int fd; diff --git a/crypto/openssh/openbsd-compat/dirname.c b/crypto/openssh/openbsd-compat/dirname.c index 35c7d8e..1ab7516 100644 --- a/crypto/openssh/openbsd-compat/dirname.c +++ b/crypto/openssh/openbsd-compat/dirname.c @@ -1,46 +1,34 @@ -/* $OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $ */ +/* $OpenBSD: dirname.c,v 1.10 2003/06/17 21:56:23 millert Exp $ */ /* * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com> - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifndef HAVE_DIRNAME -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: dirname.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $"; -#endif /* LIBC_SCCS and not lint */ +#ifndef lint +static char rcsid[] = "$OpenBSD: dirname.c,v 1.10 2003/06/17 21:56:23 millert Exp $"; +#endif /* not lint */ #include <errno.h> #include <string.h> #include <sys/param.h> char * -dirname(path) - const char *path; +dirname(const char *path) { static char bname[MAXPATHLEN]; register const char *endp; diff --git a/crypto/openssh/openbsd-compat/fake-rfc2553.c b/crypto/openssh/openbsd-compat/fake-rfc2553.c new file mode 100644 index 0000000..b0cc69b --- /dev/null +++ b/crypto/openssh/openbsd-compat/fake-rfc2553.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2000-2003 Damien Miller. All rights reserved. + * Copyright (C) 1999 WIDE Project. 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. Neither the name of the project 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 PROJECT 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 PROJECT 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. + */ + +/* + * Pseudo-implementation of RFC2553 name / address resolution functions + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" + +RCSID("$Id: fake-rfc2553.c,v 1.4.2.1 2003/09/22 02:09:18 dtucker Exp $"); + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv != NULL) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlcpy(serv, tmpserv, servlen) >= servlen) + return (EAI_MEMORY); + } + + if (host != NULL) { + if (flags & NI_NUMERICHOST) { + if (strlcpy(host, inet_ntoa(sin->sin_addr), + hostlen) >= hostlen) + return (EAI_MEMORY); + else + return (0); + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return (EAI_NODATA); + + if (strlcpy(host, hp->h_name, hostlen) >= hostlen) + return (EAI_MEMORY); + else + return (0); + } + } + return (0); +} +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef HAVE_GAI_STRERROR +#ifdef HAVE_CONST_GAI_STRERROR_PROTO +const char * +#else +char * +#endif +gai_strerror(int err) +{ + switch (err) { + case EAI_NODATA: + return ("no address associated with name"); + case EAI_MEMORY: + return ("memory allocation failure."); + case EAI_NONAME: + return ("nodename nor servname provided, or not known"); + default: + return ("unknown/invalid error."); + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void +freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + for(; ai != NULL;) { + next = ai->ai_next; + free(ai); + ai = next; + } +} +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETADDRINFO +static struct +addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) +{ + struct addrinfo *ai; + + ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return (NULL); + + memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + /* XXX: the following is not generally correct, but does what we want */ + if (hints->ai_socktype) + ai->ai_socktype = hints->ai_socktype; + else + ai->ai_socktype = SOCK_STREAM; + + if (hints->ai_protocol) + ai->ai_protocol = hints->ai_protocol; + + return (ai); +} + +int +getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct hostent *hp; + struct servent *sp; + struct in_addr in; + int i; + long int port; + u_long addr; + + port = 0; + if (servname != NULL) { + char *cp; + + port = strtol(servname, &cp, 10); + if (port > 0 && port <= 65535 && *cp == '\0') + port = htons(port); + else if ((sp = getservbyname(servname, NULL)) != NULL) + port = sp->s_port; + else + port = 0; + } + + if (hints && hints->ai_flags & AI_PASSIVE) { + addr = htonl(0x00000000); + if (hostname && inet_aton(hostname, &in) != 0) + addr = in.s_addr; + *res = malloc_ai(port, addr, hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + if (!hostname) { + *res = malloc_ai(port, htonl(0x7f000001), hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + if (inet_aton(hostname, &in)) { + *res = malloc_ai(port, in.s_addr, hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + /* Don't try DNS if AI_NUMERICHOST is set */ + if (hints && hints->ai_flags & AI_NUMERICHOST) + return (EAI_NONAME); + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + struct addrinfo *cur, *prev; + + cur = prev = *res = NULL; + for (i = 0; hp->h_addr_list[i]; i++) { + struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; + + cur = malloc_ai(port, in->s_addr, hints); + if (cur == NULL) { + if (*res != NULL) + freeaddrinfo(*res); + return (EAI_MEMORY); + } + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return (0); + } + + return (EAI_NODATA); +} +#endif /* !HAVE_GETADDRINFO */ diff --git a/crypto/openssh/openbsd-compat/fake-rfc2553.h b/crypto/openssh/openbsd-compat/fake-rfc2553.h new file mode 100644 index 0000000..2d54392 --- /dev/null +++ b/crypto/openssh/openbsd-compat/fake-rfc2553.h @@ -0,0 +1,154 @@ +/* $Id: fake-rfc2553.h,v 1.6.2.1 2003/09/22 02:09:18 dtucker Exp $ */ + +/* + * Copyright (C) 2000-2003 Damien Miller. All rights reserved. + * Copyright (C) 1999 WIDE Project. 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. Neither the name of the project 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 PROJECT 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 PROJECT 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. + */ + +/* + * Pseudo-implementation of RFC2553 name / address resolution functions + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#ifndef _FAKE_RFC2553_H +#define _FAKE_RFC2553_H + +#include "includes.h" +#include "sys/types.h" + +/* + * First, socket and INET6 related definitions + */ +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *)(a))[0] == 0 && ((u_int32_t *)(a))[1] == 0 && \ + ((u_int32_t *)(a))[2] == 0 && ((u_int32_t *)(a))[3] == htonl(1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + u_int8_t s6_addr[16]; +}; +#endif /* !HAVE_STRUCT_IN6_ADDR */ + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + unsigned short sin6_family; + u_int16_t sin6_port; + u_int32_t sin6_flowinfo; + struct in6_addr sin6_addr; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +/* + * Next, RFC2553 name / address resolution API + */ + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST (1) +#endif +#ifndef NI_NAMEREQD +# define NI_NAMEREQD (1<<1) +#endif +#ifndef NI_NUMERICSERV +# define NI_NUMERICSERV (1<<2) +#endif + +#ifndef AI_PASSIVE +# define AI_PASSIVE (1) +#endif +#ifndef AI_CANONNAME +# define AI_CANONNAME (1<<1) +#endif +#ifndef AI_NUMERICHOST +# define AI_NUMERICHOST (1<<2) +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#ifndef EAI_NODATA +# define EAI_NODATA 1 +# define EAI_MEMORY 2 +# define EAI_NONAME 3 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *, const char *, + const struct addrinfo *, struct addrinfo **); +#endif /* !HAVE_GETADDRINFO */ + +#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO) +char *gai_strerror(int); +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *); +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int); +#endif /* !HAVE_GETNAMEINFO */ + +#endif /* !_FAKE_RFC2553_H */ + diff --git a/crypto/openssh/openbsd-compat/getcwd.c b/crypto/openssh/openbsd-compat/getcwd.c index f4b98e8..31d1cfe 100644 --- a/crypto/openssh/openbsd-compat/getcwd.c +++ b/crypto/openssh/openbsd-compat/getcwd.c @@ -10,6 +10,9 @@ * 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. 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 @@ -29,7 +32,7 @@ #if !defined(HAVE_GETCWD) #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getcwd.c,v 1.7 2002/11/24 01:52:27 cloder Exp $"; +static char rcsid[] = "$OpenBSD: getcwd.c,v 1.9 2003/06/11 21:03:10 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -47,7 +50,7 @@ static char rcsid[] = "$OpenBSD: getcwd.c,v 1.7 2002/11/24 01:52:27 cloder Exp $ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) char * -getcwd(char *pt,size_t size) +getcwd(char *pt, size_t size) { register struct dirent *dp; register DIR *dir = NULL; diff --git a/crypto/openssh/openbsd-compat/getgrouplist.c b/crypto/openssh/openbsd-compat/getgrouplist.c index f7a27c3..085cda8 100644 --- a/crypto/openssh/openbsd-compat/getgrouplist.c +++ b/crypto/openssh/openbsd-compat/getgrouplist.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -36,7 +32,7 @@ #ifndef HAVE_GETGROUPLIST #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.7 1997/08/19 19:13:27 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.9 2003/06/25 21:16:47 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -44,6 +40,7 @@ static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.7 1997/08/19 19:13:27 deraad */ #include <sys/types.h> #include <string.h> +#include <unistd.h> #include <grp.h> int diff --git a/crypto/openssh/openbsd-compat/getopt.c b/crypto/openssh/openbsd-compat/getopt.c index a3fe807..2136fbf 100644 --- a/crypto/openssh/openbsd-compat/getopt.c +++ b/crypto/openssh/openbsd-compat/getopt.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -35,7 +31,7 @@ #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: getopt.c,v 1.4 2002/12/08 22:57:14 millert Exp $"; +static char *rcsid = "$OpenBSD: getopt.c,v 1.5 2003/06/02 20:18:37 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname.c b/crypto/openssh/openbsd-compat/getrrsetbyname.c new file mode 100644 index 0000000..44fa275 --- /dev/null +++ b/crypto/openssh/openbsd-compat/getrrsetbyname.c @@ -0,0 +1,578 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */ + +/* + * Copyright (c) 2001 Jakob Schlyter. 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. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME) + +#include "getrrsetbyname.h" + +/* #include "thread_private.h" */ + +#define ANSWER_BUFFER_SIZE 1024*64 + +struct dns_query { + char *name; + u_int16_t type; + u_int16_t class; + struct dns_query *next; +}; + +struct dns_rr { + char *name; + u_int16_t type; + u_int16_t class; + u_int16_t ttl; + u_int16_t size; + void *rdata; + struct dns_rr *next; +}; + +struct dns_response { + HEADER header; + struct dns_query *query; + struct dns_rr *answer; + struct dns_rr *authority; + struct dns_rr *additional; +}; + +static struct dns_response *parse_dns_response(const u_char *, int); +static struct dns_query *parse_dns_qsection(const u_char *, int, + const u_char **, int); +static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, + int); + +static void free_dns_query(struct dns_query *); +static void free_dns_rr(struct dns_rr *); +static void free_dns_response(struct dns_response *); + +static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ + +#ifndef INT32SZ +# define INT32SZ 4 +#endif +#ifndef INT16SZ +# define INT16SZ 2 +#endif + +#ifndef GETSHORT +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} +#endif + +#ifndef GETLONG +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} +#endif + +/* + * Routines to insert/extract short/long's. + */ + +#ifndef HAVE__GETSHORT +static u_int16_t +_getshort(msgp) + register const u_char *msgp; +{ + register u_int16_t u; + + GETSHORT(u, msgp); + return (u); +} +#endif + +#ifndef HAVE__GETLONG +static u_int32_t +_getlong(msgp) + register const u_char *msgp; +{ + register u_int32_t u; + + GETLONG(u, msgp); + return (u); +} +#endif + +int +getrrsetbyname(const char *hostname, unsigned int rdclass, + unsigned int rdtype, unsigned int flags, + struct rrsetinfo **res) +{ + struct __res_state *_resp = &_res; + int result; + struct rrsetinfo *rrset = NULL; + struct dns_response *response; + struct dns_rr *rr; + struct rdatainfo *rdata; + int length; + unsigned int index_ans, index_sig; + u_char answer[ANSWER_BUFFER_SIZE]; + + /* check for invalid class and type */ + if (rdclass > 0xffff || rdtype > 0xffff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow queries of class or type ANY */ + if (rdclass == 0xff || rdtype == 0xff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow flags yet, unimplemented */ + if (flags) { + result = ERRSET_INVAL; + goto fail; + } + + /* initialize resolver */ + if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { + result = ERRSET_FAIL; + goto fail; + } + +#ifdef DEBUG + _resp->options |= RES_DEBUG; +#endif /* DEBUG */ + +#ifdef RES_USE_DNSSEC + /* turn on DNSSEC if EDNS0 is configured */ + if (_resp->options & RES_USE_EDNS0) + _resp->options |= RES_USE_DNSSEC; +#endif /* RES_USE_DNSEC */ + + /* make query */ + length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, + answer, sizeof(answer)); + if (length < 0) { + switch(h_errno) { + case HOST_NOT_FOUND: + result = ERRSET_NONAME; + goto fail; + case NO_DATA: + result = ERRSET_NODATA; + goto fail; + default: + result = ERRSET_FAIL; + goto fail; + } + } + + /* parse result */ + response = parse_dns_response(answer, length); + if (response == NULL) { + result = ERRSET_FAIL; + goto fail; + } + + if (response->header.qdcount != 1) { + result = ERRSET_FAIL; + goto fail; + } + + /* initialize rrset */ + rrset = calloc(1, sizeof(struct rrsetinfo)); + if (rrset == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + rrset->rri_rdclass = response->query->class; + rrset->rri_rdtype = response->query->type; + rrset->rri_ttl = response->answer->ttl; + rrset->rri_nrdatas = response->header.ancount; + +#ifdef HAVE_HEADER_AD + /* check for authenticated data */ + if (response->header.ad == 1) + rrset->rri_flags |= RRSET_VALIDATED; +#endif + + /* copy name from answer section */ + length = strlen(response->answer->name); + rrset->rri_name = malloc(length + 1); + if (rrset->rri_name == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + strlcpy(rrset->rri_name, response->answer->name, length + 1); + + /* count answers */ + rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, + rrset->rri_rdtype); + rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, + T_SIG); + + /* allocate memory for answers */ + rrset->rri_rdatas = calloc(rrset->rri_nrdatas, + sizeof(struct rdatainfo)); + if (rrset->rri_rdatas == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* allocate memory for signatures */ + rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* copy answers & signatures */ + for (rr = response->answer, index_ans = 0, index_sig = 0; + rr; rr = rr->next) { + + rdata = NULL; + + if (rr->class == rrset->rri_rdclass && + rr->type == rrset->rri_rdtype) + rdata = &rrset->rri_rdatas[index_ans++]; + + if (rr->class == rrset->rri_rdclass && + rr->type == T_SIG) + rdata = &rrset->rri_sigs[index_sig++]; + + if (rdata) { + rdata->rdi_length = rr->size; + rdata->rdi_data = malloc(rr->size); + + if (rdata->rdi_data == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + memcpy(rdata->rdi_data, rr->rdata, rr->size); + } + } + + *res = rrset; + return (ERRSET_SUCCESS); + +fail: + if (rrset != NULL) + freerrset(rrset); + return (result); +} + +void +freerrset(struct rrsetinfo *rrset) +{ + u_int16_t i; + + if (rrset == NULL) + return; + + if (rrset->rri_rdatas) { + for (i = 0; i < rrset->rri_nrdatas; i++) { + if (rrset->rri_rdatas[i].rdi_data == NULL) + break; + free(rrset->rri_rdatas[i].rdi_data); + } + free(rrset->rri_rdatas); + } + + if (rrset->rri_sigs) { + for (i = 0; i < rrset->rri_nsigs; i++) { + if (rrset->rri_sigs[i].rdi_data == NULL) + break; + free(rrset->rri_sigs[i].rdi_data); + } + free(rrset->rri_sigs); + } + + if (rrset->rri_name) + free(rrset->rri_name); + free(rrset); +} + +/* + * DNS response parsing routines + */ +static struct dns_response * +parse_dns_response(const u_char *answer, int size) +{ + struct dns_response *resp; + const u_char *cp; + + /* allocate memory for the response */ + resp = calloc(1, sizeof(*resp)); + if (resp == NULL) + return (NULL); + + /* initialize current pointer */ + cp = answer; + + /* copy header */ + memcpy(&resp->header, cp, HFIXEDSZ); + cp += HFIXEDSZ; + + /* fix header byte order */ + resp->header.qdcount = ntohs(resp->header.qdcount); + resp->header.ancount = ntohs(resp->header.ancount); + resp->header.nscount = ntohs(resp->header.nscount); + resp->header.arcount = ntohs(resp->header.arcount); + + /* there must be at least one query */ + if (resp->header.qdcount < 1) { + free_dns_response(resp); + return (NULL); + } + + /* parse query section */ + resp->query = parse_dns_qsection(answer, size, &cp, + resp->header.qdcount); + if (resp->header.qdcount && resp->query == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse answer section */ + resp->answer = parse_dns_rrsection(answer, size, &cp, + resp->header.ancount); + if (resp->header.ancount && resp->answer == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse authority section */ + resp->authority = parse_dns_rrsection(answer, size, &cp, + resp->header.nscount); + if (resp->header.nscount && resp->authority == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse additional section */ + resp->additional = parse_dns_rrsection(answer, size, &cp, + resp->header.arcount); + if (resp->header.arcount && resp->additional == NULL) { + free_dns_response(resp); + return (NULL); + } + + return (resp); +} + +static struct dns_query * +parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) +{ + struct dns_query *head, *curr, *prev; + int i, length; + char name[MAXDNAME]; + + for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { + + /* allocate and initialize struct */ + curr = calloc(1, sizeof(struct dns_query)); + if (curr == NULL) { + free_dns_query(head); + return (NULL); + } + if (head == NULL) + head = curr; + if (prev != NULL) + prev->next = curr; + + /* name */ + length = dn_expand(answer, answer + size, *cp, name, + sizeof(name)); + if (length < 0) { + free_dns_query(head); + return (NULL); + } + curr->name = strdup(name); + if (curr->name == NULL) { + free_dns_query(head); + return (NULL); + } + *cp += length; + + /* type */ + curr->type = _getshort(*cp); + *cp += INT16SZ; + + /* class */ + curr->class = _getshort(*cp); + *cp += INT16SZ; + } + + return (head); +} + +static struct dns_rr * +parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) +{ + struct dns_rr *head, *curr, *prev; + int i, length; + char name[MAXDNAME]; + + for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { + + /* allocate and initialize struct */ + curr = calloc(1, sizeof(struct dns_rr)); + if (curr == NULL) { + free_dns_rr(head); + return (NULL); + } + if (head == NULL) + head = curr; + if (prev != NULL) + prev->next = curr; + + /* name */ + length = dn_expand(answer, answer + size, *cp, name, + sizeof(name)); + if (length < 0) { + free_dns_rr(head); + return (NULL); + } + curr->name = strdup(name); + if (curr->name == NULL) { + free_dns_rr(head); + return (NULL); + } + *cp += length; + + /* type */ + curr->type = _getshort(*cp); + *cp += INT16SZ; + + /* class */ + curr->class = _getshort(*cp); + *cp += INT16SZ; + + /* ttl */ + curr->ttl = _getlong(*cp); + *cp += INT32SZ; + + /* rdata size */ + curr->size = _getshort(*cp); + *cp += INT16SZ; + + /* rdata itself */ + curr->rdata = malloc(curr->size); + if (curr->rdata == NULL) { + free_dns_rr(head); + return (NULL); + } + memcpy(curr->rdata, *cp, curr->size); + *cp += curr->size; + } + + return (head); +} + +static void +free_dns_query(struct dns_query *p) +{ + if (p == NULL) + return; + + if (p->name) + free(p->name); + free_dns_query(p->next); + free(p); +} + +static void +free_dns_rr(struct dns_rr *p) +{ + if (p == NULL) + return; + + if (p->name) + free(p->name); + if (p->rdata) + free(p->rdata); + free_dns_rr(p->next); + free(p); +} + +static void +free_dns_response(struct dns_response *p) +{ + if (p == NULL) + return; + + free_dns_query(p->query); + free_dns_rr(p->answer); + free_dns_rr(p->authority); + free_dns_rr(p->additional); + free(p); +} + +static int +count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type) +{ + int n = 0; + + while(p) { + if (p->class == class && p->type == type) + n++; + p = p->next; + } + + return (n); +} + +#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */ diff --git a/crypto/openssh/openbsd-compat/getrrsetbyname.h b/crypto/openssh/openbsd-compat/getrrsetbyname.h new file mode 100644 index 0000000..6466a54 --- /dev/null +++ b/crypto/openssh/openbsd-compat/getrrsetbyname.h @@ -0,0 +1,100 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */ + +/* + * Copyright (c) 2001 Jakob Schlyter. 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. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GETRRSETBYNAME_H +#define _GETRRSETBYNAME_H + +#include "includes.h" + +#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME) + +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <netdb.h> +#include <resolv.h> + +/* + * Flags for getrrsetbyname() + */ +#ifndef RRSET_VALIDATED +# define RRSET_VALIDATED 1 +#endif + +/* + * Return codes for getrrsetbyname() + */ +#ifndef ERRSET_SUCCESS +# define ERRSET_SUCCESS 0 +# define ERRSET_NOMEMORY 1 +# define ERRSET_FAIL 2 +# define ERRSET_INVAL 3 +# define ERRSET_NONAME 4 +# define ERRSET_NODATA 5 +#endif + +struct rdatainfo { + unsigned int rdi_length; /* length of data */ + unsigned char *rdi_data; /* record data */ +}; + +struct rrsetinfo { + unsigned int rri_flags; /* RRSET_VALIDATED ... */ + unsigned int rri_rdclass; /* class number */ + unsigned int rri_rdtype; /* RR type number */ + unsigned int rri_ttl; /* time to live */ + unsigned int rri_nrdatas; /* size of rdatas array */ + unsigned int rri_nsigs; /* size of sigs array */ + char *rri_name; /* canonical name */ + struct rdatainfo *rri_rdatas; /* individual records */ + struct rdatainfo *rri_sigs; /* individual signatures */ +}; + +int getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **); +void freerrset(struct rrsetinfo *); + +#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */ + +#endif /* _GETRRSETBYNAME_H */ diff --git a/crypto/openssh/openbsd-compat/glob.c b/crypto/openssh/openbsd-compat/glob.c index e928a22..50f35c3 100644 --- a/crypto/openssh/openbsd-compat/glob.c +++ b/crypto/openssh/openbsd-compat/glob.c @@ -13,11 +13,7 @@ * 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 + * 3. 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. * @@ -56,7 +52,7 @@ get_arg_max(void) #if 0 static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; #else -static char rcsid[] = "$OpenBSD: glob.c,v 1.20 2002/06/14 21:34:58 todd Exp $"; +static char rcsid[] = "$OpenBSD: glob.c,v 1.22 2003/06/25 21:16:47 deraadt Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -615,7 +611,7 @@ glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, * and dirent.h as taking pointers to differently typed opaque * structures. */ - struct dirent *(*readdirfunc)(); + struct dirent *(*readdirfunc)(void *); if (pathend > pathend_last) return (1); @@ -640,7 +636,7 @@ glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else - readdirfunc = readdir; + readdirfunc = (struct dirent *(*)(void *))readdir; while ((dp = (*readdirfunc)(dirp))) { register u_char *sc; register Char *dc; diff --git a/crypto/openssh/openbsd-compat/glob.h b/crypto/openssh/openbsd-compat/glob.h index 6421f70..aceddbc 100644 --- a/crypto/openssh/openbsd-compat/glob.h +++ b/crypto/openssh/openbsd-compat/glob.h @@ -1,4 +1,4 @@ -/* $OpenBSD: glob.h,v 1.7 2002/02/17 19:42:21 millert Exp $ */ +/* $OpenBSD: glob.h,v 1.8 2003/06/02 19:34:12 millert Exp $ */ /* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ /* @@ -16,11 +16,7 @@ * 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 + * 3. 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. * diff --git a/crypto/openssh/openbsd-compat/inet_aton.c b/crypto/openssh/openbsd-compat/inet_aton.c index 1fc001d..5de4986 100644 --- a/crypto/openssh/openbsd-compat/inet_aton.c +++ b/crypto/openssh/openbsd-compat/inet_aton.c @@ -1,8 +1,6 @@ -/* $OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $ */ +/* $OpenBSD: inet_addr.c,v 1.7 2003/06/02 20:18:35 millert Exp $ */ /* - * ++Copyright++ 1983, 1990, 1993 - * - * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -14,11 +12,7 @@ * 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 + * 3. 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. * @@ -64,7 +58,7 @@ static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; #else -static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.6 1999/05/03 22:31:14 yanick Exp $"; +static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.7 2003/06/02 20:18:35 millert Exp $"; #endif #endif /* LIBC_SCCS and not lint */ diff --git a/crypto/openssh/openbsd-compat/inet_ntoa.c b/crypto/openssh/openbsd-compat/inet_ntoa.c index ac5f567..f9fdc9e 100644 --- a/crypto/openssh/openbsd-compat/inet_ntoa.c +++ b/crypto/openssh/openbsd-compat/inet_ntoa.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -36,7 +32,7 @@ #if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.3 2002/06/27 10:14:01 itojun Exp $"; +static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.4 2003/06/02 20:18:35 millert Exp $"; #endif /* LIBC_SCCS and not lint */ /* @@ -47,7 +43,6 @@ static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.3 2002/06/27 10:14:01 itojun Ex #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> -#include "inet_ntoa.h" char *inet_ntoa(struct in_addr in) { diff --git a/crypto/openssh/openbsd-compat/inet_ntop.c b/crypto/openssh/openbsd-compat/inet_ntop.c index 3bea519..075eac4 100644 --- a/crypto/openssh/openbsd-compat/inet_ntop.c +++ b/crypto/openssh/openbsd-compat/inet_ntop.c @@ -31,7 +31,6 @@ static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Ex #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> -#include "openbsd-compat/fake-socket.h" #include <netinet/in.h> #include <arpa/inet.h> #ifndef HAVE_CYGWIN diff --git a/crypto/openssh/openbsd-compat/mktemp.c b/crypto/openssh/openbsd-compat/mktemp.c index c951050..2cd7478 100644 --- a/crypto/openssh/openbsd-compat/mktemp.c +++ b/crypto/openssh/openbsd-compat/mktemp.c @@ -13,11 +13,7 @@ * 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 + * 3. 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. * @@ -39,7 +35,7 @@ #if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: mktemp.c,v 1.16 2002/05/27 18:20:45 millert Exp $"; +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.17 2003/06/02 20:18:37 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #ifdef HAVE_CYGWIN diff --git a/crypto/openssh/openbsd-compat/openbsd-compat.h b/crypto/openssh/openbsd-compat/openbsd-compat.h index c3e19b9..852948c 100644 --- a/crypto/openssh/openbsd-compat/openbsd-compat.h +++ b/crypto/openssh/openbsd-compat/openbsd-compat.h @@ -1,49 +1,168 @@ -/* $Id: openbsd-compat.h,v 1.19 2003/02/24 01:55:56 djm Exp $ */ +/* $Id: openbsd-compat.h,v 1.24 2003/08/29 16:59:52 mouring Exp $ */ -#ifndef _OPENBSD_H -#define _OPENBSD_H +/* + * Copyright (c) 1999-2003 Damien Miller. All rights reserved. + * Copyright (c) 2003 Ben Lindstrom. All rights reserved. + * Copyright (c) 2002 Tim Rice. 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 "config.h" +#ifndef _OPENBSD_COMPAT_H +#define _OPENBSD_COMPAT_H + +#include "includes.h" /* OpenBSD function replacements */ -#include "basename.h" -#include "bindresvport.h" -#include "getcwd.h" -#include "realpath.h" -#include "rresvport.h" -#include "strlcpy.h" -#include "strlcat.h" -#include "strmode.h" -#include "mktemp.h" -#include "daemon.h" -#include "dirname.h" #include "base64.h" #include "sigact.h" -#include "inet_ntoa.h" -#include "inet_ntop.h" -#include "strsep.h" -#include "setproctitle.h" -#include "getgrouplist.h" #include "glob.h" #include "readpassphrase.h" -#include "getopt.h" #include "vis.h" +#include "getrrsetbyname.h" + + +#ifndef HAVE_BASENAME +char *basename(const char *path); +#endif + +#ifndef HAVE_BINDRESVPORT_SA +int bindresvport_sa(int sd, struct sockaddr *sa); +#endif + +#ifndef HAVE_GETCWD +char *getcwd(char *pt, size_t size); +#endif + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) +char *realpath(const char *path, char *resolved); +#endif + +#ifndef HAVE_RRESVPORT_AF +int rresvport_af(int *alport, sa_family_t af); +#endif + +#ifndef HAVE_STRLCPY +/* #include <sys/types.h> XXX Still needed? */ +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRLCAT +/* #include <sys/types.h> XXX Still needed? */ +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_SETENV +int setenv(register const char *name, register const char *value, int rewrite); +#endif + +#ifndef HAVE_STRMODE +void strmode(int mode, char *p); +#endif + +#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); +#endif + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif + +#ifndef HAVE_DIRNAME +char *dirname(const char *path); +#endif + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) +char *inet_ntoa(struct in_addr in); +#endif + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + +#ifndef HAVE_INET_ATON +int inet_aton(const char *cp, struct in_addr *addr); +#endif + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...); +void compat_init_setproctitle(int argc, char *argv[]); +#endif + +#ifndef HAVE_GETGROUPLIST +/* #include <grp.h> XXXX Still needed ? */ +int getgrouplist(const char *, gid_t, gid_t *, int *); +#endif + +#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) +int BSDgetopt(int argc, char * const *argv, const char *opts); +#endif + /* Home grown routines */ -#include "bsd-arc4random.h" -#include "bsd-getpeereid.h" #include "bsd-misc.h" -#include "bsd-snprintf.h" #include "bsd-waitpid.h" +/*#include <sys/types.h> XXX Still needed? * For uid_t, gid_t * */ + +#ifndef HAVE_GETPEEREID +int getpeereid(int , uid_t *, gid_t *); +#endif + +#ifndef HAVE_ARC4RANDOM +unsigned int arc4random(void); +void arc4random_stir(void); +#endif /* !HAVE_ARC4RANDOM */ + + + + +/* #include <sys/types.h> XXX needed? For size_t */ + +#ifndef HAVE_SNPRINTF +int snprintf(char *, size_t, const char *, ...); +#endif + +#ifndef HAVE_VSNPRINTF +int vsnprintf(char *, size_t, const char *, va_list); +#endif + +void *xmmap(size_t size); +char *xcrypt(const char *password, const char *salt); +char *shadow_pw(struct passwd *pw); + + /* rfc2553 socket API replacements */ -#include "fake-getaddrinfo.h" -#include "fake-getnameinfo.h" -#include "fake-socket.h" +#include "fake-rfc2553.h" /* Routines for a single OS platform */ #include "bsd-cray.h" +#include "bsd-cygwin_util.h" #include "port-irix.h" #include "port-aix.h" -#endif /* _OPENBSD_H */ +#endif /* _OPENBSD_COMPAT_H */ diff --git a/crypto/openssh/openbsd-compat/port-aix.c b/crypto/openssh/openbsd-compat/port-aix.c index 4c96a31..9fbcce9 100644 --- a/crypto/openssh/openbsd-compat/port-aix.c +++ b/crypto/openssh/openbsd-compat/port-aix.c @@ -24,11 +24,18 @@ * */ #include "includes.h" +#include "ssh.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" +#include "xmalloc.h" #ifdef _AIX #include <uinfo.h> -#include <../xmalloc.h> +#include "port-aix.h" + +extern ServerOptions options; /* * AIX has a "usrinfo" area where logname and other stuff is stored - @@ -41,16 +48,95 @@ void aix_usrinfo(struct passwd *pw) { u_int i; + size_t len; char *cp; - cp = xmalloc(16 + 2 * strlen(pw->pw_name)); - i = sprintf(cp, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, 0, - pw->pw_name, 0); + len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); + cp = xmalloc(len); + + i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', + pw->pw_name, '\0'); if (usrinfo(SETUINFO, cp, i) == -1) fatal("Couldn't set usrinfo: %s", strerror(errno)); debug3("AIX/UsrInfo: set len %d", i); + xfree(cp); } +#ifdef WITH_AIXAUTHENTICATE +/* + * Remove embedded newlines in string (if any). + * Used before logging messages returned by AIX authentication functions + * so the message is logged on one line. + */ +void +aix_remove_embedded_newlines(char *p) +{ + if (p == NULL) + return; + + for (; *p; p++) { + if (*p == '\n') + *p = ' '; + } + /* Remove trailing whitespace */ + if (*--p == ' ') + *p = '\0'; +} +#endif /* WITH_AIXAUTHENTICATE */ + +# ifdef CUSTOM_FAILED_LOGIN +/* + * record_failed_login: generic "login failed" interface function + */ +void +record_failed_login(const char *user, const char *ttyname) +{ + char *hostname = get_canonical_hostname(options.use_dns); + + if (geteuid() != 0) + return; + + aix_setauthdb(user); +# ifdef AIX_LOGINFAILED_4ARG + loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH); +# else + loginfailed((char *)user, hostname, (char *)ttyname); +# endif +} + +/* + * If we have setauthdb, retrieve the password registry for the user's + * account then feed it to setauthdb. This may load registry-specific method + * code. If we don't have setauthdb or have already called it this is a no-op. + */ +void +aix_setauthdb(const char *user) +{ +# ifdef HAVE_SETAUTHDB + static char *registry = NULL; + + if (registry != NULL) /* have already done setauthdb */ + return; + + if (setuserdb(S_READ) == -1) { + debug3("%s: Could not open userdb to read", __func__); + return; + } + + if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { + if (setauthdb(registry, NULL) == 0) + debug3("%s: AIX/setauthdb set registry %s", __func__, + registry); + else + debug3("%s: AIX/setauthdb set registry %s failed: %s", + __func__, registry, strerror(errno)); + } else + debug3("%s: Could not read S_REGISTRY for user: %s", __func__, + strerror(errno)); + enduserdb(); +# endif +} +# endif /* CUSTOM_FAILED_LOGIN */ #endif /* _AIX */ diff --git a/crypto/openssh/openbsd-compat/port-aix.h b/crypto/openssh/openbsd-compat/port-aix.h index 4abe003..94c8c51 100644 --- a/crypto/openssh/openbsd-compat/port-aix.h +++ b/crypto/openssh/openbsd-compat/port-aix.h @@ -1,3 +1,5 @@ +/* $Id: port-aix.h,v 1.14.2.1 2003/09/19 10:46:22 dtucker Exp $ */ + /* * * Copyright (c) 2001 Gert Doering. All rights reserved. @@ -21,11 +23,24 @@ * 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. - * */ #ifdef _AIX +#ifdef WITH_AIXAUTHENTICATE +# include <login.h> +# include <userpw.h> +# if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG) +# include <sys/audit.h> +# endif +# include <usersec.h> +#endif + +/* Some versions define r_type in the above headers, which causes a conflict */ +#ifdef r_type +# undef r_type +#endif + /* AIX 4.2.x doesn't have nanosleep but does have nsleep which is equivalent */ #if !defined(HAVE_NANOSLEEP) && defined(HAVE_NSLEEP) # define nanosleep(a,b) nsleep(a,b) @@ -36,5 +51,12 @@ # include <sys/timers.h> #endif -void aix_usrinfo(struct passwd *pw); +#ifdef WITH_AIXAUTHENTICATE +# define CUSTOM_FAILED_LOGIN 1 +void record_failed_login(const char *, const char *); +void aix_setauthdb(const char *); +#endif + +void aix_usrinfo(struct passwd *); +void aix_remove_embedded_newlines(char *); #endif /* _AIX */ diff --git a/crypto/openssh/openbsd-compat/port-irix.c b/crypto/openssh/openbsd-compat/port-irix.c index a63ec42..aa6db1c 100644 --- a/crypto/openssh/openbsd-compat/port-irix.c +++ b/crypto/openssh/openbsd-compat/port-irix.c @@ -1,15 +1,42 @@ +/* + * Copyright (c) 2000 Denis Parker. All rights reserved. + * Copyright (c) 2000 Michael Stone. 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" -#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) +#if defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || \ + defined(WITH_IRIX_ARRAY) #ifdef WITH_IRIX_PROJECT -#include <proj.h> +# include <proj.h> #endif /* WITH_IRIX_PROJECT */ #ifdef WITH_IRIX_JOBS -#include <sys/resource.h> +# include <sys/resource.h> #endif #ifdef WITH_IRIX_AUDIT -#include <sat.h> +# include <sat.h> #endif /* WITH_IRIX_AUDIT */ void @@ -17,14 +44,12 @@ irix_setusercontext(struct passwd *pw) { #ifdef WITH_IRIX_PROJECT prid_t projid; -#endif /* WITH_IRIX_PROJECT */ +#endif #ifdef WITH_IRIX_JOBS jid_t jid = 0; -#else -# ifdef WITH_IRIX_ARRAY +#elif defined(WITH_IRIX_ARRAY) int jid = 0; -# endif /* WITH_IRIX_ARRAY */ -#endif /* WITH_IRIX_JOBS */ +#endif #ifdef WITH_IRIX_JOBS jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); diff --git a/crypto/openssh/openbsd-compat/port-irix.h b/crypto/openssh/openbsd-compat/port-irix.h index 2dd3c2e..67c4863 100644 --- a/crypto/openssh/openbsd-compat/port-irix.h +++ b/crypto/openssh/openbsd-compat/port-irix.h @@ -1,5 +1,39 @@ -#if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) +/* $Id: port-irix.h,v 1.4 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000 Denis Parker. All rights reserved. + * Copyright (c) 2000 Michael Stone. 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. + */ + +#ifndef _PORT_IRIX_H +#define _PORT_IRIX_H + +#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) */ + +#endif /* ! _PORT_IRIX_H */ diff --git a/crypto/openssh/openbsd-compat/readpassphrase.c b/crypto/openssh/openbsd-compat/readpassphrase.c index 4e549b6..0d0baf5 100644 --- a/crypto/openssh/openbsd-compat/readpassphrase.c +++ b/crypto/openssh/openbsd-compat/readpassphrase.c @@ -1,34 +1,27 @@ -/* $OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $ */ +/* $OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:23 millert Exp $ */ /* * Copyright (c) 2000-2002 Todd C. Miller <Todd.Miller@courtesan.com> - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.14 2002/06/28 01:43:58 millert Exp $"; +static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:23 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include "includes.h" @@ -185,6 +178,7 @@ getpass(const char *prompt) static void handler(int s) { + signo = s; } #endif /* HAVE_READPASSPHRASE */ diff --git a/crypto/openssh/openbsd-compat/realpath.c b/crypto/openssh/openbsd-compat/realpath.c index b9035ca..77da14e 100644 --- a/crypto/openssh/openbsd-compat/realpath.c +++ b/crypto/openssh/openbsd-compat/realpath.c @@ -13,6 +13,9 @@ * 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. 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 @@ -32,7 +35,7 @@ #if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $"; +static char *rcsid = "$OpenBSD: realpath.c,v 1.10 2003/08/01 21:04:59 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> @@ -62,7 +65,7 @@ char * realpath(const char *path, char *resolved) { struct stat sb; - int fd, n, rootd, serrno = 0; + int fd, n, needslash, serrno = 0; char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN]; int symlinks = 0; @@ -138,18 +141,18 @@ loop: * happens if the last component is empty, or the dirname is root. */ if (resolved[0] == '/' && resolved[1] == '\0') - rootd = 1; + needslash = 0; else - rootd = 0; + needslash = 1; if (*wbuf) { - if (strlen(resolved) + strlen(wbuf) + rootd + 1 > MAXPATHLEN) { + if (strlen(resolved) + strlen(wbuf) + needslash >= MAXPATHLEN) { serrno = ENAMETOOLONG; goto err1; } - if (rootd == 0) - (void)strcat(resolved, "/"); - (void)strcat(resolved, wbuf); + if (needslash == 0) + strlcat(resolved, "/", MAXPATHLEN); + strlcat(resolved, wbuf, MAXPATHLEN); } /* Go back to where we came from. */ diff --git a/crypto/openssh/openbsd-compat/rresvport.c b/crypto/openssh/openbsd-compat/rresvport.c index 9f05896..608a3b1 100644 --- a/crypto/openssh/openbsd-compat/rresvport.c +++ b/crypto/openssh/openbsd-compat/rresvport.c @@ -11,12 +11,7 @@ * 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. - * This product includes software developed by Theo de Raadt. - * 4. Neither the name of the University nor the names of its contributors + * 3. 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. * @@ -38,7 +33,7 @@ #ifndef HAVE_RRESVPORT_AF #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: rresvport.c,v 1.5 2000/01/26 03:43:20 deraadt Exp $"; +static char *rcsid = "$OpenBSD: rresvport.c,v 1.6 2003/06/03 02:11:35 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ #include "includes.h" diff --git a/crypto/openssh/openbsd-compat/setenv.c b/crypto/openssh/openbsd-compat/setenv.c index e5c5de6..c9941c1 100644 --- a/crypto/openssh/openbsd-compat/setenv.c +++ b/crypto/openssh/openbsd-compat/setenv.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -35,7 +31,7 @@ #ifndef HAVE_SETENV #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: setenv.c,v 1.5 2002/12/10 22:44:13 mickey Exp $"; +static char *rcsid = "$OpenBSD: setenv.c,v 1.6 2003/06/02 20:18:38 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <stdlib.h> diff --git a/crypto/openssh/openbsd-compat/setproctitle.c b/crypto/openssh/openbsd-compat/setproctitle.c index 07af7e9..b41100f 100644 --- a/crypto/openssh/openbsd-compat/setproctitle.c +++ b/crypto/openssh/openbsd-compat/setproctitle.c @@ -1,41 +1,34 @@ -/* - * Based on src/backend/utils/misc/pg_status.c from - * PostgreSQL Database Management System - * - * Portions Copyright (c) 1996-2001, The PostgreSQL Global Development Group - * - * Portions Copyright (c) 1994, The Regents of the University of California - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without a written agreement - * is hereby granted, provided that the above copyright notice and this - * paragraph and the following two paragraphs appear in all copies. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING - * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS - * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ +/* Based on conf.c from UCB sendmail 8.8.8 */ -/*-------------------------------------------------------------------- - * ps_status.c - * - * Routines to support changing the ps display of PostgreSQL backends - * to contain some useful information. Mechanism differs wildly across - * platforms. +/* + * Copyright 2003 Damien Miller + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. * - * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.5 2003/01/20 02:15:11 djm Exp $ + * 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. 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. * - * Copyright 2000 by PostgreSQL Global Development Group - * various details abducted from various places - *-------------------------------------------------------------------- + * 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. */ #include "includes.h" @@ -44,200 +37,121 @@ #include <unistd.h> #ifdef HAVE_SYS_PSTAT_H -#include <sys/pstat.h> /* for HP-UX */ -#endif -#ifdef HAVE_PS_STRINGS -#include <machine/vmparam.h> /* for old BSD */ -#include <sys/exec.h> +#include <sys/pstat.h> #endif -/*------ - * Alternative ways of updating ps display: - * - * SETPROCTITLE_STRATEGY == PS_USE_PSTAT - * use the pstat(PSTAT_SETCMD, ) - * (HPUX) - * SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS - * assign PS_STRINGS->ps_argvstr = "string" - * (some BSD systems) - * SETPROCTITLE_STRATEGY == PS_USE_CHANGE_ARGV - * assign argv[0] = "string" - * (some other BSD systems) - * SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV - * write over the argv and environment area - * (most SysV-like systems) - * SETPROCTITLE_STRATEGY == PS_USE_NONE - * don't update ps display - * (This is the default, as it is safest.) - */ +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_PSTAT 1 /* cover argv with title information */ +#define SPT_REUSEARGV 2 /* use pstat(PSTAT_SETCMD, ...) */ -#define PS_USE_NONE 0 -#define PS_USE_PSTAT 1 -#define PS_USE_PS_STRINGS 2 -#define PS_USE_CHANGE_ARGV 3 -#define PS_USE_CLOBBER_ARGV 4 - -#ifndef SETPROCTITLE_STRATEGY -# define SETPROCTITLE_STRATEGY PS_USE_NONE +#ifndef SPT_TYPE +# define SPT_TYPE SPT_NONE #endif -#ifndef SETPROCTITLE_PS_PADDING -# define SETPROCTITLE_PS_PADDING ' ' +#ifndef SPT_PADCHAR +# define SPT_PADCHAR '\0' #endif -#endif /* HAVE_SETPROCTITLE */ -extern char **environ; - -/* - * argv clobbering uses existing argv space, all other methods need a buffer - */ -#if SETPROCTITLE_STRATEGY != PS_USE_CLOBBER_ARGV -static char ps_buffer[256]; -static const size_t ps_buffer_size = sizeof(ps_buffer); -#else -static char *ps_buffer; /* will point to argv area */ -static size_t ps_buffer_size; /* space determined at run time */ +#if SPT_TYPE == SPT_REUSEARGV +static char *argv_start = NULL; +static size_t argv_env_len = 0; #endif -/* save the original argv[] location here */ -static int save_argc; -static char **save_argv; - -extern char *__progname; +#endif /* HAVE_SETPROCTITLE */ -#ifndef HAVE_SETPROCTITLE -/* - * Call this to update the ps status display to a fixed prefix plus an - * indication of what you're currently doing passed in the argument. - */ void -setproctitle(const char *fmt, ...) +compat_init_setproctitle(int argc, char *argv[]) { -#if SETPROCTITLE_STRATEGY == PS_USE_PSTAT - union pstun pst; -#endif -#if SETPROCTITLE_STRATEGY != PS_USE_NONE - ssize_t used; - va_list ap; - - /* no ps display if you didn't call save_ps_display_args() */ - if (save_argv == NULL) - return; -#if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV - /* If ps_buffer is a pointer, it might still be null */ - if (ps_buffer == NULL) - return; -#endif /* PS_USE_CLOBBER_ARGV */ +#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV + extern char **environ; + char *lastargv = NULL; + char **envp = environ; + int i; /* - * Overwrite argv[] to point at appropriate space, if needed + * NB: This assumes that argv has already been copied out of the + * way. This is true for sshd, but may not be true for other + * programs. Beware. */ -#if SETPROCTITLE_STRATEGY == PS_USE_CHANGE_ARGV - save_argv[0] = ps_buffer; - save_argv[1] = NULL; -#endif /* PS_USE_CHANGE_ARGV */ -#if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV - save_argv[1] = NULL; -#endif /* PS_USE_CLOBBER_ARGV */ + if (argc == 0 || argv[0] == NULL) + return; + + /* Fail if we can't allocate room for the new environment */ + for (i = 0; envp[i] != NULL; i++) + ; + if ((environ = malloc(sizeof(*environ) * (i + 1))) == NULL) { + environ = envp; /* put it back */ + return; + } /* - * Make fixed prefix of ps display. + * Find the last argv string or environment variable within + * our process memory area. */ - - va_start(ap, fmt); - if (fmt == NULL) - snprintf(ps_buffer, ps_buffer_size, "%s", __progname); - else { - used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); - if (used == -1 || used >= ps_buffer_size) - used = ps_buffer_size; - vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); + for (i = 0; i < argc; i++) { + if (lastargv == NULL || lastargv + 1 == argv[i]) + lastargv = argv[i] + strlen(argv[i]); + } + for (i = 0; envp[i] != NULL; i++) { + if (lastargv + 1 == envp[i]) + lastargv = envp[i] + strlen(envp[i]); } - va_end(ap); - -#if SETPROCTITLE_STRATEGY == PS_USE_PSTAT - pst.pst_command = ps_buffer; - pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); -#endif /* PS_USE_PSTAT */ - -#if SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS - PS_STRINGS->ps_nargvstr = 1; - PS_STRINGS->ps_argvstr = ps_buffer; -#endif /* PS_USE_PS_STRINGS */ -#if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV - /* pad unused memory */ - used = strlen(ps_buffer); - memset(ps_buffer + used, SETPROCTITLE_PS_PADDING, - ps_buffer_size - used); -#endif /* PS_USE_CLOBBER_ARGV */ + argv[1] = NULL; + argv_start = argv[0]; + argv_env_len = lastargv - argv[0] - 1; -#endif /* PS_USE_NONE */ + /* + * Copy environment + * XXX - will truncate env on strdup fail + */ + for (i = 0; envp[i] != NULL; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; +#endif /* SPT_REUSEARGV */ } -#endif /* HAVE_SETPROCTITLE */ - -/* - * Call this early in startup to save the original argc/argv values. - * - * argv[] will not be overwritten by this routine, but may be overwritten - * during setproctitle. Also, the physical location of the environment - * strings may be moved, so this should be called before any code that - * might try to hang onto a getenv() result. - */ +#ifndef HAVE_SETPROCTITLE void -compat_init_setproctitle(int argc, char *argv[]) +setproctitle(const char *fmt, ...) { -#if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV - char *end_of_area = NULL; - char **new_environ; - int i; +#if SPT_TYPE != SPT_NONE + va_list ap; + char buf[1024]; + size_t len; + extern char *__progname; +#if SPT_TYPE == SPT_PSTAT + union pstun pst; #endif - save_argc = argc; - save_argv = argv; - -#if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV - /* - * If we're going to overwrite the argv area, count the available - * space. Also move the environment to make additional room. - */ - - /* - * check for contiguous argv strings - */ - for (i = 0; i < argc; i++) { - if (i == 0 || end_of_area + 1 == argv[i]) - end_of_area = argv[i] + strlen(argv[i]); - } - - /* probably can't happen? */ - if (end_of_area == NULL) { - ps_buffer = NULL; - ps_buffer_size = 0; +#if SPT_TYPE == SPT_REUSEARGV + if (argv_env_len <= 0) return; - } +#endif - /* - * check for contiguous environ strings following argv - */ - for (i = 0; environ[i] != NULL; i++) { - if (end_of_area + 1 == environ[i]) - end_of_area = environ[i] + strlen(environ[i]); + strlcpy(buf, __progname, sizeof(buf)); + + va_start(ap, fmt); + if (fmt != NULL) { + len = strlcat(buf, ": ", sizeof(buf)); + if (len < sizeof(buf)) + vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); } + va_end(ap); - ps_buffer = argv[0]; - ps_buffer_size = end_of_area - argv[0] - 1; +#if SPT_TYPE == SPT_PSTAT + pst.pst_command = buf; + pstat(PSTAT_SETCMD, pst, strlen(buf), 0, 0); +#elif SPT_TYPE == SPT_REUSEARGV +/* debug("setproctitle: copy \"%s\" into len %d", + buf, argv_env_len); */ + len = strlcpy(argv_start, buf, argv_env_len); + for(; len < argv_env_len; len++) + argv_start[len] = SPT_PADCHAR; +#endif - /* - * Duplicate and move the environment out of the way - */ - new_environ = malloc(sizeof(char *) * (i + 1)); - for (i = 0; environ[i] != NULL; i++) - new_environ[i] = strdup(environ[i]); - new_environ[i] = NULL; - environ = new_environ; -#endif /* PS_USE_CLOBBER_ARGV */ +#endif /* SPT_NONE */ } +#endif /* HAVE_SETPROCTITLE */ diff --git a/crypto/openssh/openbsd-compat/strlcat.c b/crypto/openssh/openbsd-compat/strlcat.c index 3a9b5d1..cae1665 100644 --- a/crypto/openssh/openbsd-compat/strlcat.c +++ b/crypto/openssh/openbsd-compat/strlcat.c @@ -1,42 +1,30 @@ -/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */ +/* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifndef HAVE_STRLCAT #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $"; +static char *rcsid = "$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <string.h> -#include "strlcat.h" /* * Appends src to string dst of size siz (unlike strncat, siz is the @@ -46,10 +34,7 @@ static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp * If retval >= siz, truncation occurred. */ size_t -strlcat(dst, src, siz) - char *dst; - const char *src; - size_t siz; +strlcat(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; diff --git a/crypto/openssh/openbsd-compat/strlcpy.c b/crypto/openssh/openbsd-compat/strlcpy.c index 2f87eca..c8fe299 100644 --- a/crypto/openssh/openbsd-compat/strlcpy.c +++ b/crypto/openssh/openbsd-compat/strlcpy.c @@ -1,42 +1,30 @@ -/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */ +/* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * THIS SOFTWARE IS PROVIDED ``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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" #ifndef HAVE_STRLCPY #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $"; +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <string.h> -#include "strlcpy.h" /* * Copy src to string dst of size siz. At most siz-1 characters @@ -44,10 +32,7 @@ static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t -strlcpy(dst, src, siz) - char *dst; - const char *src; - size_t siz; +strlcpy(char *dst, const char *src, size_t siz) { register char *d = dst; register const char *s = src; diff --git a/crypto/openssh/openbsd-compat/strmode.c b/crypto/openssh/openbsd-compat/strmode.c index e64d198..adf5e27 100644 --- a/crypto/openssh/openbsd-compat/strmode.c +++ b/crypto/openssh/openbsd-compat/strmode.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -35,15 +31,17 @@ #ifndef HAVE_STRMODE #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strmode.c,v 1.3 1997/06/13 13:57:20 deraadt Exp $"; +static char *rcsid = "$OpenBSD: strmode.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> #include <sys/stat.h> #include <string.h> +/* XXX mode should be mode_t */ + void -strmode(register mode_t mode, register char *p) +strmode(int mode, char *p) { /* print type */ switch (mode & S_IFMT) { diff --git a/crypto/openssh/openbsd-compat/strsep.c b/crypto/openssh/openbsd-compat/strsep.c index d0afc44..b136713 100644 --- a/crypto/openssh/openbsd-compat/strsep.c +++ b/crypto/openssh/openbsd-compat/strsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */ +/* $OpenBSD: strsep.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -12,11 +12,7 @@ * 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 + * 3. 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. * @@ -44,7 +40,7 @@ #if 0 static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; #else -static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $"; +static char *rcsid = "$OpenBSD: strsep.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -62,9 +58,9 @@ static char *rcsid = "$OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ char * strsep(char **stringp, const char *delim) { - register char *s; - register const char *spanp; - register int c, sc; + char *s; + const char *spanp; + int c, sc; char *tok; if ((s = *stringp) == NULL) diff --git a/crypto/openssh/openbsd-compat/sys-queue.h b/crypto/openssh/openbsd-compat/sys-queue.h index 176fe31..dd5c475 100644 --- a/crypto/openssh/openbsd-compat/sys-queue.h +++ b/crypto/openssh/openbsd-compat/sys-queue.h @@ -1,4 +1,4 @@ -/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */ +/* $OpenBSD: queue.h,v 1.23 2003/06/02 23:28:21 millert Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ /* @@ -13,11 +13,7 @@ * 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 + * 3. 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. * diff --git a/crypto/openssh/openbsd-compat/vis.c b/crypto/openssh/openbsd-compat/vis.c index fc57413..e6a2ce9 100644 --- a/crypto/openssh/openbsd-compat/vis.c +++ b/crypto/openssh/openbsd-compat/vis.c @@ -10,11 +10,7 @@ * 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 + * 3. 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. * @@ -30,14 +26,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#include "config.h" +#include "includes.h" #if !defined(HAVE_STRNVIS) #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $"; +static char rcsid[] = "$OpenBSD: vis.c,v 1.12 2003/06/02 20:18:35 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <ctype.h> +#include <string.h> #include "vis.h" @@ -47,8 +44,9 @@ static char rcsid[] = "$OpenBSD: vis.c,v 1.8 2002/02/19 19:39:36 millert Exp $"; ((flag & VIS_SP) == 0 && (c) == ' ') || \ ((flag & VIS_TAB) == 0 && (c) == '\t') || \ ((flag & VIS_NL) == 0 && (c) == '\n') || \ - ((flag & VIS_SAFE) && \ - ((c) == '\b' || (c) == '\007' || (c) == '\r'))) + ((flag & VIS_SAFE) && ((c) == '\b' || \ + (c) == '\007' || (c) == '\r' || \ + isgraph((u_char)(c))))) /* * vis - visually encode characters @@ -169,16 +167,20 @@ strvis(dst, src, flag) int strnvis(dst, src, siz, flag) - register char *dst; - register const char *src; + char *dst; + const char *src; size_t siz; int flag; { - register char c; + char c; char *start, *end; + char tbuf[5]; + int i; + i = 0; for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { if (isvisible(c)) { + i = 1; *dst++ = c; if (c == '\\' && (flag & VIS_NOSLASH) == 0) { /* need space for the extra '\\' */ @@ -186,22 +188,25 @@ strnvis(dst, src, siz, flag) *dst++ = '\\'; else { dst--; + i = 2; break; } } src++; } else { - /* vis(3) requires up to 4 chars */ - if (dst + 3 < end) - dst = vis(dst, c, flag, *++src); - else + i = vis(tbuf, c, flag, *++src) - tbuf; + if (dst + i <= end) { + memcpy(dst, tbuf, i); + dst += i; + } else { + src--; break; + } } } - *dst = '\0'; - if (dst >= end) { - char tbuf[5]; - + if (siz > 0) + *dst = '\0'; + if (dst + i > end) { /* adjust return value for truncation */ while ((c = *src)) dst += vis(tbuf, c, flag, *++src) - tbuf; diff --git a/crypto/openssh/openbsd-compat/vis.h b/crypto/openssh/openbsd-compat/vis.h index 5df6f36..1c131cc 100644 --- a/crypto/openssh/openbsd-compat/vis.h +++ b/crypto/openssh/openbsd-compat/vis.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vis.h,v 1.5 2002/02/16 21:27:17 millert Exp $ */ +/* $OpenBSD: vis.h,v 1.6 2003/06/02 19:34:12 millert Exp $ */ /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ /*- @@ -13,11 +13,7 @@ * 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 + * 3. 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. * @@ -35,7 +31,8 @@ * * @(#)vis.h 5.9 (Berkeley) 4/3/91 */ -#include "config.h" + +#include "includes.h" #if !defined(HAVE_STRNVIS) #ifndef _VIS_H_ diff --git a/crypto/openssh/openbsd-compat/xcrypt.c b/crypto/openssh/openbsd-compat/xcrypt.c new file mode 100644 index 0000000..5b5d69c --- /dev/null +++ b/crypto/openssh/openbsd-compat/xcrypt.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003 Ben Lindstrom. 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" + +#if !defined(HAVE_OSF_SIA) + +# ifdef HAVE_CRYPT_H +# include <crypt.h> +# endif + +# ifdef __hpux +# include <hpsecurity.h> +# include <prot.h> +# endif + +# ifdef HAVE_SECUREWARE +# include <sys/security.h> +# include <sys/audit.h> +# include <prot.h> +# endif + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +# include <shadow.h> +# endif + +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) +# include <sys/label.h> +# include <sys/audit.h> +# include <pwdadj.h> +# endif + +# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +# endif + +char * +xcrypt(const char *password, const char *salt) +{ + char *crypted; + +# ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + crypted = md5_crypt(password, salt); + else + crypted = crypt(password, salt); +# elif defined(__hpux) && !defined(HAVE_SECUREWARE) + if (iscomsec()) + crypted = bigcrypt(password, salt); + else + crypted = crypt(password, salt); +# elif defined(HAVE_SECUREWARE) + crypted = bigcrypt(password, salt); +# else + crypted = crypt(password, salt); +# endif + + return crypted; +} + +/* + * Handle shadowed password systems in a cleaner way for portable + * version. + */ + +char * +shadow_pw(struct passwd *pw) +{ + char *pw_password = pw->pw_passwd; + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + struct spwd *spw = getspnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->sp_pwdp; +# endif +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) + struct passwd_adjunct *spw; + if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) + pw_password = spw->pwa_passwd; +# elif defined(HAVE_SECUREWARE) + struct pr_passwd *spw = getprpwnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->ufld.fd_encrypt; +# elif defined(__hpux) && !defined(HAVE_SECUREWARE) + struct pr_passwd *spw; + if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) + pw_password = spw->ufld.fd_encrypt; +# endif + + return pw_password; +} + +#endif /* !defined(HAVE_OSF_SIA) */ diff --git a/crypto/openssh/openbsd-compat/xmmap.c b/crypto/openssh/openbsd-compat/xmmap.c index 8f1d202..9dc4340 100644 --- a/crypto/openssh/openbsd-compat/xmmap.c +++ b/crypto/openssh/openbsd-compat/xmmap.c @@ -1,4 +1,7 @@ /* + * Copyright (c) 2002 Tim Rice. All rights reserved. + * MAP_FAILED code by Solar Designer. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -20,6 +23,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* $Id: xmmap.c,v 1.3 2003/06/02 02:25:27 tim Exp $ */ + #include "includes.h" #ifdef HAVE_SYS_MMAN_H diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c index 77860d6..02b629f 100644 --- a/crypto/openssh/packet.c +++ b/crypto/openssh/packet.c @@ -37,7 +37,9 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.110 2003/09/19 09:02:02 markus Exp $"); + +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "buffer.h" @@ -106,7 +108,7 @@ static int compression_buffer_ready = 0; static int packet_compression = 0; /* default maximum packet size */ -int max_packet_size = 32768; +u_int max_packet_size = 32768; /* Flag indicating whether this module has been initialized. */ static int initialized = 0; @@ -116,8 +118,14 @@ static int interactive_mode = 0; /* Session key information for Encryption and MAC */ Newkeys *newkeys[MODE_MAX]; -static u_int32_t read_seqnr = 0; -static u_int32_t send_seqnr = 0; +static struct packet_state { + u_int32_t seqnr; + u_int32_t packets; + u_int64_t blocks; +} p_read, p_send; + +static u_int64_t max_blocks_in, max_blocks_out; +static u_int32_t rekey_limit; /* Session key for protocol v1 */ static u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; @@ -126,6 +134,13 @@ static u_int ssh1_keylen; /* roundup current message to extra_pad bytes */ static u_char extra_pad = 0; +struct packet { + TAILQ_ENTRY(packet) next; + u_char type; + Buffer payload; +}; +TAILQ_HEAD(, packet) outgoing; + /* * Sets the descriptors used for communication. Disables encryption until * packet_set_encryption_key is called. @@ -148,6 +163,7 @@ packet_set_connection(int fd_in, int fd_out) buffer_init(&output); buffer_init(&outgoing_packet); buffer_init(&incoming_packet); + TAILQ_INIT(&outgoing); } /* Kludge: arrange the close function to be called from fatal(). */ fatal_add_cleanup((void (*) (void *)) packet_close, NULL); @@ -249,27 +265,31 @@ packet_set_iv(int mode, u_char *dat) cipher_set_keyiv(cc, dat); } int -packet_get_ssh1_cipher() +packet_get_ssh1_cipher(void) { return (cipher_get_number(receive_context.cipher)); } - -u_int32_t -packet_get_seqnr(int mode) +void +packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets) { - return (mode == MODE_IN ? read_seqnr : send_seqnr); + struct packet_state *state; + + state = (mode == MODE_IN) ? &p_read : &p_send; + *seqnr = state->seqnr; + *blocks = state->blocks; + *packets = state->packets; } void -packet_set_seqnr(int mode, u_int32_t seqnr) +packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets) { - if (mode == MODE_IN) - read_seqnr = seqnr; - else if (mode == MODE_OUT) - send_seqnr = seqnr; - else - fatal("packet_set_seqnr: bad mode %d", mode); + struct packet_state *state; + + state = (mode == MODE_IN) ? &p_read : &p_send; + state->seqnr = seqnr; + state->blocks = blocks; + state->packets = packets; } /* returns 1 if connection is via ipv4 */ @@ -562,6 +582,7 @@ set_newkeys(int mode) Mac *mac; Comp *comp; CipherContext *cc; + u_int64_t *max_blocks; int encrypt; debug2("set_newkeys: mode %d", mode); @@ -569,9 +590,13 @@ set_newkeys(int mode) if (mode == MODE_OUT) { cc = &send_context; encrypt = CIPHER_ENCRYPT; + p_send.packets = p_send.blocks = 0; + max_blocks = &max_blocks_out; } else { cc = &receive_context; encrypt = CIPHER_DECRYPT; + p_read.packets = p_read.blocks = 0; + max_blocks = &max_blocks_in; } if (newkeys[mode] != NULL) { debug("set_newkeys: rekeying"); @@ -610,13 +635,23 @@ set_newkeys(int mode) buffer_compress_init_recv(); comp->enabled = 1; } + /* + * The 2^(blocksize*2) limit is too expensive for 3DES, + * blowfish, etc, so enforce a 1GB limit for small blocksizes. + */ + if (enc->block_size >= 16) + *max_blocks = (u_int64_t)1 << (enc->block_size*2); + else + *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; + if (rekey_limit) + *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size); } /* * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) */ static void -packet_send2(void) +packet_send2_wrapped(void) { u_char type, *cp, *macbuf = NULL; u_char padlen, pad; @@ -698,10 +733,10 @@ packet_send2(void) /* compute MAC over seqnr and packet(length fields, payload, padding) */ if (mac && mac->enabled) { - macbuf = mac_compute(mac, send_seqnr, + macbuf = mac_compute(mac, p_send.seqnr, buffer_ptr(&outgoing_packet), buffer_len(&outgoing_packet)); - DBG(debug("done calc MAC out #%d", send_seqnr)); + DBG(debug("done calc MAC out #%d", p_send.seqnr)); } /* encrypt packet and append to output buffer. */ cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); @@ -715,14 +750,64 @@ packet_send2(void) buffer_dump(&output); #endif /* increment sequence number for outgoing packets */ - if (++send_seqnr == 0) - log("outgoing seqnr wraps around"); + if (++p_send.seqnr == 0) + logit("outgoing seqnr wraps around"); + if (++p_send.packets == 0) + if (!(datafellows & SSH_BUG_NOREKEY)) + fatal("XXX too many packets with same key"); + p_send.blocks += (packet_length + 4) / block_size; buffer_clear(&outgoing_packet); if (type == SSH2_MSG_NEWKEYS) set_newkeys(MODE_OUT); } +static void +packet_send2(void) +{ + static int rekeying = 0; + struct packet *p; + u_char type, *cp; + + cp = buffer_ptr(&outgoing_packet); + type = cp[5]; + + /* during rekeying we can only send key exchange messages */ + if (rekeying) { + if (!((type >= SSH2_MSG_TRANSPORT_MIN) && + (type <= SSH2_MSG_TRANSPORT_MAX))) { + debug("enqueue packet: %u", type); + p = xmalloc(sizeof(*p)); + p->type = type; + memcpy(&p->payload, &outgoing_packet, sizeof(Buffer)); + buffer_init(&outgoing_packet); + TAILQ_INSERT_TAIL(&outgoing, p, next); + return; + } + } + + /* rekeying starts with sending KEXINIT */ + if (type == SSH2_MSG_KEXINIT) + rekeying = 1; + + packet_send2_wrapped(); + + /* after a NEWKEYS message we can send the complete queue */ + if (type == SSH2_MSG_NEWKEYS) { + rekeying = 0; + while ((p = TAILQ_FIRST(&outgoing))) { + type = p->type; + debug("dequeue packet: %u", type); + buffer_free(&outgoing_packet); + memcpy(&outgoing_packet, &p->payload, + sizeof(Buffer)); + TAILQ_REMOVE(&outgoing, p, next); + xfree(p); + packet_send2_wrapped(); + } + } +} + void packet_send(void) { @@ -784,7 +869,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) /* Read data from the socket. */ len = read(connection_in, buf, sizeof(buf)); if (len == 0) { - log("Connection closed by %.200s", get_remote_ipaddr()); + logit("Connection closed by %.200s", get_remote_ipaddr()); fatal_cleanup(); } if (len < 0) @@ -935,7 +1020,9 @@ packet_read_poll2(u_int32_t *seqnr_p) cp = buffer_ptr(&incoming_packet); packet_length = GET_32BIT(cp); if (packet_length < 1 + 4 || packet_length > 256 * 1024) { +#ifdef PACKET_DEBUG buffer_dump(&incoming_packet); +#endif packet_disconnect("Bad packet length %u.", packet_length); } DBG(debug("input: packet len %u", packet_length+4)); @@ -966,18 +1053,22 @@ packet_read_poll2(u_int32_t *seqnr_p) * increment sequence number for incoming packet */ if (mac && mac->enabled) { - macbuf = mac_compute(mac, read_seqnr, + macbuf = mac_compute(mac, p_read.seqnr, 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", read_seqnr)); + DBG(debug("MAC #%d ok", p_read.seqnr)); buffer_consume(&input, mac->mac_len); } if (seqnr_p != NULL) - *seqnr_p = read_seqnr; - if (++read_seqnr == 0) - log("incoming seqnr wraps around"); + *seqnr_p = p_read.seqnr; + if (++p_read.seqnr == 0) + logit("incoming seqnr wraps around"); + if (++p_read.packets == 0) + if (!(datafellows & SSH_BUG_NOREKEY)) + fatal("XXX too many packets with same key"); + p_read.blocks += (packet_length + 4) / block_size; /* get padlen */ cp = buffer_ptr(&incoming_packet); @@ -1042,7 +1133,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) case SSH2_MSG_DISCONNECT: reason = packet_get_int(); msg = packet_get_string(NULL); - log("Received disconnect from %s: %u: %.400s", + logit("Received disconnect from %s: %u: %.400s", get_remote_ipaddr(), reason, msg); xfree(msg); fatal_cleanup(); @@ -1068,7 +1159,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) break; case SSH_MSG_DISCONNECT: msg = packet_get_string(NULL); - log("Received disconnect from %s: %.400s", + logit("Received disconnect from %s: %.400s", get_remote_ipaddr(), msg); fatal_cleanup(); xfree(msg); @@ -1227,7 +1318,7 @@ packet_disconnect(const char *fmt,...) va_end(args); /* Display the error locally */ - log("Disconnecting: %.100s", buf); + logit("Disconnecting: %.100s", buf); /* Send the disconnect message to the other side, and wait for it to get sent. */ if (compat20) { @@ -1314,6 +1405,8 @@ packet_not_very_much_data_to_write(void) return buffer_len(&output) < 128 * 1024; } + +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) static void packet_set_tos(int interactive) { @@ -1327,6 +1420,7 @@ packet_set_tos(int interactive) error("setsockopt IP_TOS %d: %.100s:", tos, strerror(errno)); } +#endif /* Informs that the current session is interactive. Sets IP flags for that. */ @@ -1361,18 +1455,18 @@ packet_is_interactive(void) return interactive_mode; } -int -packet_set_maxsize(int s) +u_int +packet_set_maxsize(u_int s) { static int called = 0; if (called) { - log("packet_set_maxsize: called twice: old %d new %d", + logit("packet_set_maxsize: called twice: old %d new %d", max_packet_size, s); return -1; } if (s < 4 * 1024 || s > 1024 * 1024) { - log("packet_set_maxsize: bad size %d", s); + logit("packet_set_maxsize: bad size %d", s); return -1; } called = 1; @@ -1414,3 +1508,22 @@ packet_send_ignore(int nbytes) rand >>= 8; } } + +#define MAX_PACKETS (1<<31) +int +packet_need_rekeying(void) +{ + if (datafellows & SSH_BUG_NOREKEY) + return 0; + return + (p_send.packets > MAX_PACKETS) || + (p_read.packets > MAX_PACKETS) || + (max_blocks_out && (p_send.blocks > max_blocks_out)) || + (max_blocks_in && (p_read.blocks > max_blocks_in)); +} + +void +packet_set_rekey_limit(u_int32_t bytes) +{ + rekey_limit = bytes; +} diff --git a/crypto/openssh/packet.h b/crypto/openssh/packet.h index 46830c3..7732faf 100644 --- a/crypto/openssh/packet.h +++ b/crypto/openssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.37 2003/04/01 10:22:21 markus Exp $ */ +/* $OpenBSD: packet.h,v 1.40 2003/06/24 08:23:46 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -62,8 +62,8 @@ int packet_get_keyiv_len(int); void packet_get_keyiv(int, u_char *, u_int); int packet_get_keycontext(int, u_char *); void packet_set_keycontext(int, u_char *); -u_int32_t packet_get_seqnr(int); -void packet_set_seqnr(int, u_int32_t); +void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *); +void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t); int packet_get_ssh1_cipher(void); void packet_set_iv(int, u_char *); @@ -81,8 +81,8 @@ void packet_add_padding(u_char); void tty_make_modes(int, struct termios *); void tty_parse_modes(int, int *); -extern int max_packet_size; -int packet_set_maxsize(int); +extern u_int max_packet_size; +u_int packet_set_maxsize(u_int); #define packet_get_maxsize() max_packet_size /* don't allow remaining bytes after the end of the message */ @@ -90,10 +90,13 @@ int packet_set_maxsize(int); do { \ int _len = packet_remaining(); \ if (_len > 0) { \ - log("Packet integrity error (%d bytes remaining) at %s:%d", \ + logit("Packet integrity error (%d bytes remaining) at %s:%d", \ _len ,__FILE__, __LINE__); \ packet_disconnect("Packet integrity error."); \ } \ } while (0) +int packet_need_rekeying(void); +void packet_set_rekey_limit(u_int32_t); + #endif /* PACKET_H */ diff --git a/crypto/openssh/progressmeter.c b/crypto/openssh/progressmeter.c index 90eb97f..c315464 100644 --- a/crypto/openssh/progressmeter.c +++ b/crypto/openssh/progressmeter.c @@ -1,6 +1,5 @@ /* - * Copyright (c) 1999 Theo de Raadt. All rights reserved. - * Copyright (c) 1999 Aaron Campbell. All rights reserved. + * Copyright (c) 2003 Nils Nordman. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,260 +22,244 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * Parts from: - * - * 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. - * - */ - #include "includes.h" -RCSID("$OpenBSD: progressmeter.c,v 1.3 2003/03/17 10:38:38 markus Exp $"); +RCSID("$OpenBSD: progressmeter.c,v 1.15 2003/08/31 12:14:22 markus Exp $"); -#ifdef HAVE_LIBGEN_H -#include <libgen.h> -#endif - -#include "atomicio.h" #include "progressmeter.h" +#include "atomicio.h" +#include "misc.h" -/* Number of seconds before xfer considered "stalled". */ -#define STALLTIME 5 -/* alarm() interval for updating progress meter. */ -#define PROGRESSTIME 1 - -/* Signal handler used for updating the progress meter. */ -static void update_progress_meter(int); +#define DEFAULT_WINSIZE 80 +#define MAX_WINSIZE 512 +#define PADDING 1 /* padding between the progress indicators */ +#define UPDATE_INTERVAL 1 /* update the progress meter every second */ +#define STALL_TIME 5 /* we're stalled after this many seconds */ -/* Returns non-zero if we are the foreground process. */ -static int foregroundproc(void); +/* determines whether we can output to the terminal */ +static int can_output(void); -/* Returns width of the terminal (for progress meter calculations). */ -static int get_tty_width(void); +/* formats and inserts the specified size into the given buffer */ +static void format_size(char *, int, off_t); +static void format_rate(char *, int, off_t); -/* Visual statistics about files as they are transferred. */ -static void draw_progress_meter(void); +/* updates the progressmeter to reflect the current state of the transfer */ +void refresh_progress_meter(void); -/* Time a transfer started. */ -static struct timeval start; +/* signal handler for updating the progress meter */ +static void update_progress_meter(int); -/* Number of bytes of current file transferred so far. */ -static volatile off_t *statbytes; +static time_t start; /* start progress */ +static time_t last_update; /* last progress update */ +static char *file; /* name of the file being transferred */ +static off_t end_pos; /* ending position of transfer */ +static off_t cur_pos; /* transfer position as of last refresh */ +static volatile off_t *counter; /* progress counter */ +static long stalled; /* how long we have been stalled */ +static int bytes_per_second; /* current speed in bytes per second */ +static int win_size; /* terminal window size */ -/* Total size of current file. */ -static off_t totalbytes; +/* units for format_size */ +static const char unit[] = " KMGT"; -/* Name of current file being transferred. */ -static char *curfile; +static int +can_output(void) +{ + return (getpgrp() == tcgetpgrp(STDOUT_FILENO)); +} -/* Time of last update. */ -static struct timeval lastupdate; +static void +format_rate(char *buf, int size, off_t bytes) +{ + int i; + + bytes *= 100; + for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) + bytes = (bytes + 512) / 1024; + if (i == 0) { + i++; + bytes = (bytes + 512) / 1024; + } + snprintf(buf, size, "%3lld.%1lld%c%s", + (int64_t) bytes / 100, + (int64_t) (bytes + 5) / 10 % 10, + unit[i], + i ? "B" : " "); +} -/* Size at the time of the last update. */ -static off_t lastsize; +static void +format_size(char *buf, int size, off_t bytes) +{ + int i; + + for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) + bytes = (bytes + 512) / 1024; + snprintf(buf, size, "%4lld%c%s", + (int64_t) bytes, + unit[i], + i ? "B" : " "); +} void -start_progress_meter(char *file, off_t filesize, off_t *counter) +refresh_progress_meter(void) { - if ((curfile = basename(file)) == NULL) - curfile = file; + char buf[MAX_WINSIZE + 1]; + time_t now; + off_t transferred; + double elapsed; + int percent; + int bytes_left; + int cur_speed; + int hours, minutes, seconds; + int i, len; + int file_len; + + transferred = *counter - cur_pos; + cur_pos = *counter; + now = time(NULL); + bytes_left = end_pos - cur_pos; + + if (bytes_left > 0) + elapsed = now - last_update; + else + elapsed = now - start; - totalbytes = filesize; - statbytes = counter; - (void) gettimeofday(&start, (struct timezone *) 0); - lastupdate = start; - lastsize = 0; + /* calculate speed */ + if (elapsed != 0) + cur_speed = (transferred / elapsed); + else + cur_speed = 0; - draw_progress_meter(); - signal(SIGALRM, update_progress_meter); - alarm(PROGRESSTIME); -} +#define AGE_FACTOR 0.9 + if (bytes_per_second != 0) { + bytes_per_second = (bytes_per_second * AGE_FACTOR) + + (cur_speed * (1.0 - AGE_FACTOR)); + } else + bytes_per_second = cur_speed; + + /* filename */ + buf[0] = '\0'; + file_len = win_size - 35; + if (file_len > 0) { + len = snprintf(buf, file_len + 1, "\r%s", file); + if (len < 0) + len = 0; + for (i = len; i < file_len; i++ ) + buf[i] = ' '; + buf[file_len] = '\0'; + } -void -stop_progress_meter() -{ - alarm(0); - draw_progress_meter(); - if (foregroundproc() != 0) - atomicio(write, fileno(stdout), "\n", 1); + /* percent of transfer done */ + if (end_pos != 0) + percent = ((float)cur_pos / end_pos) * 100; + else + percent = 100; + snprintf(buf + strlen(buf), win_size - strlen(buf), + " %3d%% ", percent); + + /* amount transferred */ + format_size(buf + strlen(buf), win_size - strlen(buf), + cur_pos); + strlcat(buf, " ", win_size); + + /* bandwidth usage */ + format_rate(buf + strlen(buf), win_size - strlen(buf), + bytes_per_second); + strlcat(buf, "/s ", win_size); + + /* ETA */ + if (!transferred) + stalled += elapsed; + else + stalled = 0; + + if (stalled >= STALL_TIME) + strlcat(buf, "- stalled -", win_size); + else if (bytes_per_second == 0 && bytes_left) + strlcat(buf, " --:-- ETA", win_size); + else { + if (bytes_left > 0) + seconds = bytes_left / bytes_per_second; + else + seconds = elapsed; + + hours = seconds / 3600; + seconds -= hours * 3600; + minutes = seconds / 60; + seconds -= minutes * 60; + + if (hours != 0) + snprintf(buf + strlen(buf), win_size - strlen(buf), + "%d:%02d:%02d", hours, minutes, seconds); + else + snprintf(buf + strlen(buf), win_size - strlen(buf), + " %02d:%02d", minutes, seconds); + + if (bytes_left > 0) + strlcat(buf, " ETA", win_size); + else + strlcat(buf, " ", win_size); + } + + atomicio(vwrite, STDOUT_FILENO, buf, win_size); + last_update = now; } static void update_progress_meter(int ignore) { - int save_errno = errno; + int save_errno; + + save_errno = errno; + + if (can_output()) + refresh_progress_meter(); - draw_progress_meter(); signal(SIGALRM, update_progress_meter); - alarm(PROGRESSTIME); + alarm(UPDATE_INTERVAL); errno = save_errno; } -static int -foregroundproc(void) -{ - static pid_t pgrp = -1; - int ctty_pgrp; - - if (pgrp == -1) - pgrp = getpgrp(); - -#ifdef HAVE_TCGETPGRP - return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 && - ctty_pgrp == pgrp); -#else - return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 && - ctty_pgrp == pgrp)); -#endif -} - -static void -draw_progress_meter() +void +start_progress_meter(char *f, off_t filesize, off_t *stat) { - static const char spaces[] = " " - " " - " " - " " - " " - " "; - static const char prefixes[] = " KMGTP"; - struct timeval now, td, wait; - off_t cursize, abbrevsize, bytespersec; - double elapsed; - int ratio, remaining, i, ai, bi, nspaces; - char buf[512]; - - if (foregroundproc() == 0) - return; + struct winsize winsize; - (void) gettimeofday(&now, (struct timezone *) 0); - cursize = *statbytes; - if (totalbytes != 0) { - ratio = 100.0 * cursize / totalbytes; - ratio = MAX(ratio, 0); - ratio = MIN(ratio, 100); + start = last_update = time(NULL); + file = f; + end_pos = filesize; + cur_pos = 0; + counter = stat; + stalled = 0; + bytes_per_second = 0; + + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 && + winsize.ws_col != 0) { + if (winsize.ws_col > MAX_WINSIZE) + win_size = MAX_WINSIZE; + else + win_size = winsize.ws_col; } else - ratio = 100; - - abbrevsize = cursize; - for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++) - abbrevsize >>= 10; + win_size = DEFAULT_WINSIZE; + win_size += 1; /* trailing \0 */ - timersub(&now, &lastupdate, &wait); - if (cursize > lastsize) { - lastupdate = now; - lastsize = cursize; - wait.tv_sec = 0; - } - timersub(&now, &start, &td); - elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - - bytespersec = 0; - if (cursize > 0) { - bytespersec = cursize; - if (elapsed > 0.0) - bytespersec /= elapsed; - } - for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++) - bytespersec >>= 10; - - nspaces = MIN(get_tty_width() - 79, sizeof(spaces) - 1); - -#ifdef HAVE_LONG_LONG_INT - snprintf(buf, sizeof(buf), - "\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s", - curfile, - nspaces, - spaces, - ratio, - (long long)abbrevsize, - prefixes[ai], - ai == 0 ? ' ' : 'B', - (long long)(bytespersec / 1024), - (int)((bytespersec % 1024) * 10 / 1024), - prefixes[bi] - ); -#else - /* XXX: Handle integer overflow? */ - snprintf(buf, sizeof(buf), - "\r%-45.45s%.*s%3d%% %4lu%c%c %3lu.%01d%cB/s", - curfile, - nspaces, - spaces, - ratio, - (u_long)abbrevsize, - prefixes[ai], - ai == 0 ? ' ' : 'B', - (u_long)(bytespersec / 1024), - (int)((bytespersec % 1024) * 10 / 1024), - prefixes[bi] - ); -#endif - - if (cursize <= 0 || elapsed <= 0.0 || cursize > totalbytes) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " --:-- ETA"); - } else if (wait.tv_sec >= STALLTIME) { - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " - stalled -"); - } else { - if (cursize != totalbytes) - remaining = (int)(totalbytes / (cursize / elapsed) - - elapsed); - else - remaining = elapsed; + if (can_output()) + refresh_progress_meter(); - i = remaining / 3600; - if (i) - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%2d:", i); - else - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - " "); - i = remaining % 3600; - snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), - "%02d:%02d%s", i / 60, i % 60, - (cursize != totalbytes) ? " ETA" : " "); - } - atomicio(write, fileno(stdout), buf, strlen(buf)); + signal(SIGALRM, update_progress_meter); + alarm(UPDATE_INTERVAL); } -static int -get_tty_width(void) +void +stop_progress_meter(void) { - struct winsize winsize; + alarm(0); - if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1) - return (winsize.ws_col ? winsize.ws_col : 80); - else - return (80); + if (!can_output()) + return; + + /* Ensure we complete the progress */ + if (cur_pos != end_pos) + refresh_progress_meter(); + + atomicio(vwrite, STDOUT_FILENO, "\n", 1); } diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c index 1df5ce2..13987ff 100644 --- a/crypto/openssh/readconf.c +++ b/crypto/openssh/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -57,7 +57,6 @@ RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); Host fascist.blob.com Port 23123 User tylonen - RhostsAuthentication no PasswordAuthentication no Host puukko.hut.fi @@ -75,7 +74,6 @@ RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); Host * ForwardAgent no ForwardX11 no - RhostsAuthentication yes PasswordAuthentication yes RSAAuthentication yes RhostsRSAAuthentication yes @@ -91,18 +89,9 @@ RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); typedef enum { oBadOption, - oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, + oForwardAgent, oForwardX11, oGatewayPorts, oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, -#if defined(KRB4) || defined(KRB5) - oKerberosAuthentication, -#endif -#if defined(AFS) || defined(KRB5) - oKerberosTgtPassing, -#endif -#ifdef AFS - oAFSTokenPassing, -#endif oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, @@ -114,8 +103,9 @@ typedef enum { oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, oClearAllForwardings, oNoHostAuthenticationForLocalhost, - oEnableSSHKeysign, - oDeprecated + oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, + oAddressFamily, oGssAuthentication, oGssDelegateCreds, + oDeprecated, oUnsupported } OpCodes; /* Textual representations of the tokens. */ @@ -129,7 +119,7 @@ static struct { { "xauthlocation", oXAuthLocation }, { "gatewayports", oGatewayPorts }, { "useprivilegedport", oUsePrivilegedPort }, - { "rhostsauthentication", oRhostsAuthentication }, + { "rhostsauthentication", oDeprecated }, { "passwordauthentication", oPasswordAuthentication }, { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, { "kbdinteractivedevices", oKbdInteractiveDevices }, @@ -141,14 +131,15 @@ static struct { { "challengeresponseauthentication", oChallengeResponseAuthentication }, { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ -#if defined(KRB4) || defined(KRB5) - { "kerberosauthentication", oKerberosAuthentication }, -#endif -#if defined(AFS) || defined(KRB5) - { "kerberostgtpassing", oKerberosTgtPassing }, -#endif -#ifdef AFS - { "afstokenpassing", oAFSTokenPassing }, + { "kerberosauthentication", oUnsupported }, + { "kerberostgtpassing", oUnsupported }, + { "afstokenpassing", oUnsupported }, +#if defined(GSSAPI) + { "gssapiauthentication", oGssAuthentication }, + { "gssapidelegatecredentials", oGssDelegateCreds }, +#else + { "gssapiauthentication", oUnsupported }, + { "gssapidelegatecredentials", oUnsupported }, #endif { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, @@ -184,10 +175,22 @@ static struct { { "preferredauthentications", oPreferredAuthentications }, { "hostkeyalgorithms", oHostKeyAlgorithms }, { "bindaddress", oBindAddress }, +#ifdef SMARTCARD { "smartcarddevice", oSmartcardDevice }, +#else + { "smartcarddevice", oUnsupported }, +#endif { "clearallforwardings", oClearAllForwardings }, { "enablesshkeysign", oEnableSSHKeysign }, +#ifdef DNS + { "verifyhostkeydns", oVerifyHostKeyDNS }, +#else + { "verifyhostkeydns", oUnsupported }, +#endif { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, + { "rekeylimit", oRekeyLimit }, + { "connecttimeout", oConnectTimeout }, + { "addressfamily", oAddressFamily }, { NULL, oBadOption } }; @@ -281,6 +284,13 @@ process_config_line(Options *options, const char *host, u_short fwd_port, fwd_host_port; char sfwd_host_port[6]; + /* Strip trailing whitespace */ + for(len = strlen(line) - 1; len > 0; len--) { + if (strchr(WHITESPACE, line[len]) == NULL) + break; + line[len] = '\0'; + } + s = line; /* Get the keyword. (Each line is supposed to begin with a keyword). */ keyword = strdelim(&s); @@ -297,6 +307,20 @@ process_config_line(Options *options, const char *host, /* don't panic, but count bad options */ return -1; /* NOTREACHED */ + case oConnectTimeout: + intptr = &options->connection_timeout; +/* parse_time: */ + arg = strdelim(&s); + 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 oForwardAgent: intptr = &options->forward_agent; parse_flag: @@ -326,10 +350,6 @@ parse_flag: intptr = &options->use_privileged_port; goto parse_flag; - case oRhostsAuthentication: - intptr = &options->rhosts_authentication; - goto parse_flag; - case oPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; @@ -361,21 +381,15 @@ parse_flag: case oChallengeResponseAuthentication: intptr = &options->challenge_response_authentication; goto parse_flag; -#if defined(KRB4) || defined(KRB5) - case oKerberosAuthentication: - intptr = &options->kerberos_authentication; - goto parse_flag; -#endif -#if defined(AFS) || defined(KRB5) - case oKerberosTgtPassing: - intptr = &options->kerberos_tgt_passing; + + case oGssAuthentication: + intptr = &options->gss_authentication; goto parse_flag; -#endif -#ifdef AFS - case oAFSTokenPassing: - intptr = &options->afs_token_passing; + + case oGssDelegateCreds: + intptr = &options->gss_deleg_creds; goto parse_flag; -#endif + case oBatchMode: intptr = &options->batch_mode; goto parse_flag; @@ -384,6 +398,10 @@ parse_flag: intptr = &options->check_host_ip; goto parse_flag; + case oVerifyHostKeyDNS: + intptr = &options->verify_host_key_dns; + goto parse_flag; + case oStrictHostKeyChecking: intptr = &options->strict_host_key_checking; arg = strdelim(&s); @@ -423,6 +441,31 @@ parse_flag: intptr = &options->compression_level; goto parse_int; + case oRekeyLimit: + intptr = &options->rekey_limit; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + if (arg[0] < '0' || arg[0] > '9') + fatal("%.200s line %d: Bad number.", filename, linenum); + value = strtol(arg, &endofnumber, 10); + if (arg == endofnumber) + fatal("%.200s line %d: Bad number.", filename, linenum); + switch (toupper(*endofnumber)) { + case 'K': + value *= 1<<10; + break; + case 'M': + value *= 1<<20; + break; + case 'G': + value *= 1<<30; + break; + } + if (*activep && *intptr == -1) + *intptr = value; + break; + case oIdentityFile: arg = strdelim(&s); if (!arg || *arg == '\0') @@ -489,6 +532,8 @@ parse_string: goto parse_string; case oProxyCommand: + if (s == NULL) + fatal("%.200s line %d: Missing argument.", filename, linenum); charptr = &options->proxy_command; len = strspn(s, WHITESPACE "="); if (*activep && *charptr == NULL) @@ -626,7 +671,7 @@ parse_int: fatal("%.200s line %d: Badly formatted port number.", filename, linenum); if (*activep) - add_local_forward(options, fwd_port, "socks4", 0); + add_local_forward(options, fwd_port, "socks", 0); break; case oClearAllForwardings: @@ -666,6 +711,21 @@ parse_int: *intptr = value; break; + case oAddressFamily: + arg = strdelim(&s); + intptr = &options->address_family; + if (strcasecmp(arg, "inet") == 0) + value = AF_INET; + else if (strcasecmp(arg, "inet6") == 0) + value = AF_INET6; + else if (strcasecmp(arg, "any") == 0) + value = AF_UNSPEC; + else + fatal("Unsupported AddressFamily \"%s\"", arg); + if (*activep && *intptr == -1) + *intptr = value; + break; + case oEnableSSHKeysign: intptr = &options->enable_ssh_keysign; goto parse_flag; @@ -675,6 +735,11 @@ parse_int: filename, linenum, keyword); return 0; + case oUnsupported: + error("%s line %d: Unsupported option \"%s\"", + filename, linenum, keyword); + return 0; + default: fatal("process_config_line: Unimplemented opcode %d", opcode); } @@ -744,19 +809,11 @@ initialize_options(Options * options) options->xauth_location = NULL; options->gateway_ports = -1; options->use_privileged_port = -1; - options->rhosts_authentication = -1; options->rsa_authentication = -1; options->pubkey_authentication = -1; options->challenge_response_authentication = -1; -#if defined(KRB4) || defined(KRB5) - options->kerberos_authentication = -1; -#endif -#if defined(AFS) || defined(KRB5) - options->kerberos_tgt_passing = -1; -#endif -#ifdef AFS - options->afs_token_passing = -1; -#endif + options->gss_authentication = -1; + options->gss_deleg_creds = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->kbd_interactive_devices = NULL; @@ -769,7 +826,9 @@ initialize_options(Options * options) options->keepalives = -1; options->compression_level = -1; options->port = -1; + options->address_family = -1; options->connection_attempts = -1; + options->connection_timeout = -1; options->number_of_password_prompts = -1; options->cipher = -1; options->ciphers = NULL; @@ -795,6 +854,8 @@ initialize_options(Options * options) options->smartcard_device = NULL; options->enable_ssh_keysign = - 1; options->no_host_authentication_for_localhost = - 1; + options->rekey_limit = - 1; + options->verify_host_key_dns = -1; } /* @@ -817,26 +878,16 @@ fill_default_options(Options * options) options->gateway_ports = 0; if (options->use_privileged_port == -1) options->use_privileged_port = 0; - if (options->rhosts_authentication == -1) - options->rhosts_authentication = 0; if (options->rsa_authentication == -1) options->rsa_authentication = 1; if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; if (options->challenge_response_authentication == -1) options->challenge_response_authentication = 1; -#if defined(KRB4) || defined(KRB5) - if (options->kerberos_authentication == -1) - options->kerberos_authentication = 1; -#endif -#if defined(AFS) || defined(KRB5) - if (options->kerberos_tgt_passing == -1) - options->kerberos_tgt_passing = 1; -#endif -#ifdef AFS - if (options->afs_token_passing == -1) - options->afs_token_passing = 1; -#endif + if (options->gss_authentication == -1) + options->gss_authentication = 1; + if (options->gss_deleg_creds == -1) + options->gss_deleg_creds = 0; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -859,6 +910,8 @@ fill_default_options(Options * options) options->compression_level = 6; if (options->port == -1) options->port = 0; /* Filled in ssh_connect. */ + if (options->address_family == -1) + options->address_family = AF_UNSPEC; if (options->connection_attempts == -1) options->connection_attempts = 1; if (options->number_of_password_prompts == -1) @@ -911,6 +964,10 @@ fill_default_options(Options * options) options->no_host_authentication_for_localhost = 0; if (options->enable_ssh_keysign == -1) options->enable_ssh_keysign = 0; + if (options->rekey_limit == -1) + options->rekey_limit = 0; + if (options->verify_host_key_dns == -1) + options->verify_host_key_dns = 0; /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h index 78e04fe..60287f7 100644 --- a/crypto/openssh/readconf.h +++ b/crypto/openssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.46 2003/04/01 10:22:21 markus Exp $ */ +/* $OpenBSD: readconf.h,v 1.55 2003/09/01 18:15:50 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -33,7 +33,6 @@ typedef struct { char *xauth_location; /* Location for xauth program */ int gateway_ports; /* Allow remote connects to forwarded ports. */ int use_privileged_port; /* Don't use privileged port if false. */ - int rhosts_authentication; /* Try rhosts authentication. */ int rhosts_rsa_authentication; /* Try rhosts with RSA * authentication. */ int rsa_authentication; /* Try RSA authentication. */ @@ -41,15 +40,8 @@ typedef struct { int hostbased_authentication; /* ssh2's rhosts_rsa */ int challenge_response_authentication; /* Try S/Key or TIS, authentication. */ -#if defined(KRB4) || defined(KRB5) - int kerberos_authentication; /* Try Kerberos authentication. */ -#endif -#if defined(AFS) || defined(KRB5) - int kerberos_tgt_passing; /* Try Kerberos TGT passing. */ -#endif -#ifdef AFS - int afs_token_passing; /* Try AFS token passing. */ -#endif + int gss_authentication; /* Try GSS authentication */ + int gss_deleg_creds; /* Delegate GSS credentials */ int password_authentication; /* Try password * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ @@ -64,8 +56,11 @@ typedef struct { LogLevel log_level; /* Level for logging. */ int port; /* Port to connect. */ + int address_family; int connection_attempts; /* Max attempts (seconds) before * giving up */ + int connection_timeout; /* Max time (seconds) before + * aborting connection attempt */ int number_of_password_prompts; /* Max number of password * prompts. */ int cipher; /* Cipher to use. */ @@ -86,6 +81,7 @@ typedef struct { char *preferred_authentications; char *bind_address; /* local socket address for connection to sshd */ char *smartcard_device; /* Smartcard reader device */ + int verify_host_key_dns; /* Verify host key using DNS */ int num_identity_files; /* Number of files for RSA/DSA identities. */ char *identity_files[SSH_MAX_IDENTITY_FILES]; @@ -101,6 +97,7 @@ typedef struct { int clear_forwardings; int enable_ssh_keysign; + int rekey_limit; int no_host_authentication_for_localhost; } Options; diff --git a/crypto/openssh/regress/Makefile b/crypto/openssh/regress/Makefile index 6e20293..623be8d 100644 --- a/crypto/openssh/regress/Makefile +++ b/crypto/openssh/regress/Makefile @@ -1,8 +1,11 @@ -# $OpenBSD: Makefile,v 1.20 2003/01/08 23:54:22 djm Exp $ +# $OpenBSD: Makefile,v 1.24 2003/07/03 08:24:13 markus Exp $ -REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 +REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec +tests: $(REGRESS_TARGETS) -CLEANFILES+= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 +clean: + for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done +distclean: clean LTESTS= connect \ proxy-connect \ @@ -11,6 +14,7 @@ LTESTS= connect \ proto-mismatch \ exit-status \ transfer \ + rekey \ stderr-data \ stderr-after-eof \ broken-pipe \ @@ -24,30 +28,34 @@ LTESTS= connect \ keygen-change \ sftp \ sftp-cmds \ + sftp-badcmds \ sftp-batch \ + reconfigure \ + dynamic-forward \ forwarding USER!= id -un -CLEANFILES+= authorized_keys_${USER} known_hosts pidfile \ +CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ + authorized_keys_${USER} known_hosts pidfile \ ssh_config ssh_proxy sshd_config sshd_proxy \ rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \ - ls.copy + ls.copy remote_pid -#LTESTS+= ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp +#LTESTS += ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp t1: ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv t2: - cat ${.CURDIR}/rsa_openssh.prv > t2.out - chmod 600 t2.out - ssh-keygen -yf t2.out | diff - ${.CURDIR}/rsa_openssh.pub + cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out + chmod 600 $(OBJ)/t2.out + ssh-keygen -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub t3: - ssh-keygen -ef ${.CURDIR}/rsa_openssh.pub |\ - ssh-keygen -if /dev/stdin |\ - diff - ${.CURDIR}/rsa_openssh.pub + ssh-keygen -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/rsa_secsh.pub + ssh-keygen -if $(OBJ)/rsa_secsh.pub | diff - ${.CURDIR}/rsa_openssh.pub + rm -f ${.CURDIR}/rsa_secsh.pub t4: ssh-keygen -lf ${.CURDIR}/rsa_openssh.pub |\ @@ -58,22 +66,21 @@ t5: awk '{print $$2}' | diff - ${.CURDIR}/t5.ok t6: - ssh-keygen -if ${.CURDIR}/dsa_ssh2.prv > t6.out1 - ssh-keygen -if ${.CURDIR}/dsa_ssh2.pub > t6.out2 - chmod 600 t6.out1 - ssh-keygen -yf t6.out1 | diff - t6.out2 + ssh-keygen -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 + ssh-keygen -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 + chmod 600 $(OBJ)/t6.out1 + ssh-keygen -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 -t7.out: +$(OBJ)/t7.out: ssh-keygen -q -t rsa -N '' -f $@ -t7: t7.out - ssh-keygen -lf t7.out > /dev/null - ssh-keygen -Bf t7.out > /dev/null +t7: $(OBJ)/t7.out + ssh-keygen -lf $(OBJ)/t7.out > /dev/null + ssh-keygen -Bf $(OBJ)/t7.out > /dev/null -.for t in ${LTESTS} -REGRESS_TARGETS+=t-${t} -t-${t}: - sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/${t}.sh -.endfor - -.include "bsd.regress.mk" +t-exec: ${LTESTS:=.sh} + @if [ "x$?" = "x" ]; then exit 0; fi; \ + for TEST in ""$?; do \ + echo "run test $${TEST}" ... 1>&2; \ + (sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ + done diff --git a/crypto/openssh/regress/README.regress b/crypto/openssh/regress/README.regress new file mode 100644 index 0000000..916894a --- /dev/null +++ b/crypto/openssh/regress/README.regress @@ -0,0 +1,86 @@ +Overview. + +$ ./configure && make tests + +You'll see some progress info. A failure will cause either the make to +abort or the driver script to report a "FATAL" failure. + +The test consists of 2 parts. The first is the file-based tests which is +driven by the Makefile, and the second is a set of network or proxycommand +based tests, which are driven by a driver script (test-exec.sh) which is +called multiple times by the Makefile. + +Failures in the first part will cause the Makefile to return an error. +Failures in the second part will print a "FATAL" message for the failed +test and continue. + +OpenBSD has a system-wide regression test suite. OpenSSH Portable's test +suite is based on OpenBSD's with modifications. + + +Environment variables. + +SUDO: path to sudo command, if desired. Note that some systems (notably + systems using PAM) require sudo to execute some tests. +TEST_SSH_TRACE: set yo "yes" for verbose output from tests +TEST_SSH_QUIET: set to "yes" to suppress non-fatal output. +TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD + SSHKEYGEN,SSHKEYSCAN,SFTP,SFTPSERVER +OBJ: used by test scripts to access build dir. + + +Individual tests. + +You can invoke test-exec.sh directly if you set up the path to find the +binaries under test and the test scripts themselves, for example: + +$ cd regress +$ PATH=`pwd`/..:$PATH:. sh test-exec.sh `pwd` agent-timeout.sh +ok agent timeout test + + +Files. + +test-exec.sh: the main test driver. Sets environment, creates config files +and keys and runs the specified test. + +At the time of writing, the individual tests are: +agent-timeout.sh: agent timeout test +agent.sh: simple agent test +broken-pipe.sh: broken pipe test +connect-privsep.sh: proxy connect with privsep +connect.sh: simple connect +exit-status.sh: remote exit status +forwarding.sh: local and remote forwarding +keygen-change.sh: change passphrase for key +keyscan.sh: keyscan +proto-mismatch.sh: protocol version mismatch +proto-version.sh: sshd version with different protocol combinations +proxy-connect.sh: proxy connect +sftp.sh: basic sftp put/get +ssh-com-client.sh: connect with ssh.com client +ssh-com-keygen.sh: ssh.com key import +ssh-com-sftp.sh: basic sftp put/get with ssh.com server +ssh-com.sh: connect to ssh.com server +stderr-after-eof.sh: stderr data after eof +stderr-data.sh: stderr data transfer +transfer.sh: transfer data +try-ciphers.sh: try ciphers +yes-head.sh: yes pipe head + + +Problems? + +Run the failing test with shell tracing (-x) turned on: +$ PATH=`pwd`/..:$PATH:. sh -x test-exec.sh `pwd` agent-timeout.sh + +Failed tests can be difficult to diagnose. Suggestions: +- run the individual test via ./test-exec.sh `pwd` [testname] +- set LogLevel to VERBOSE in test-exec.sh and enable syslogging of + auth.debug (eg to /var/log/authlog). + + +Known Issues. + + +$Id: README.regress,v 1.1 2003/09/04 05:39:54 dtucker Exp $ diff --git a/crypto/openssh/regress/agent-getpeereid.sh b/crypto/openssh/regress/agent-getpeereid.sh index 0889fe8..46d20dc 100644 --- a/crypto/openssh/regress/agent-getpeereid.sh +++ b/crypto/openssh/regress/agent-getpeereid.sh @@ -7,6 +7,12 @@ UNPRIV=nobody ASOCK=${OBJ}/agent SSH_AUTH_SOCK=/nonexistant +if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 +then + echo "skipped (not supported on this platform)" + exit 0 +fi + trace "start agent" eval `${SSHAGENT} -s -a ${ASOCK}` > /dev/null r=$? diff --git a/crypto/openssh/regress/agent-ptrace.sh b/crypto/openssh/regress/agent-ptrace.sh index 9f9c999..cd9c002 100644 --- a/crypto/openssh/regress/agent-ptrace.sh +++ b/crypto/openssh/regress/agent-ptrace.sh @@ -3,6 +3,22 @@ tid="disallow agent ptrace attach" +if have_prog uname ; then + case `uname` in + Linux|HP-UX|SunOS|NetBSD|AIX|CYGWIN*) + echo "skipped (not supported on this platform)" + exit 0 + ;; + esac +fi + +if have_prog gdb ; then + : ok +else + echo "skipped (gdb not found)" + exit 0 +fi + trace "start agent" eval `${SSHAGENT} -s` > /dev/null r=$? @@ -16,7 +32,7 @@ EOF if [ $? -ne 0 ]; then fail "gdb failed: exit code $?" fi - grep -q 'ptrace: Operation not permitted.' ${OBJ}/gdb.out + grep 'ptrace: Operation not permitted.' >/dev/null ${OBJ}/gdb.out r=$? rm -f ${OBJ}/gdb.out if [ $r -ne 0 ]; then diff --git a/crypto/openssh/regress/agent-timeout.sh b/crypto/openssh/regress/agent-timeout.sh index 28b1be0..3a40e7a 100644 --- a/crypto/openssh/regress/agent-timeout.sh +++ b/crypto/openssh/regress/agent-timeout.sh @@ -3,7 +3,7 @@ tid="agent timeout test" -TIMEOUT=5 +SSHAGENT_TIMEOUT=10 trace "start agent" eval `${SSHAGENT} -s` > /dev/null @@ -13,7 +13,7 @@ if [ $r -ne 0 ]; then else trace "add keys with timeout" for t in rsa rsa1; do - ${SSHADD} -t ${TIMEOUT} $OBJ/$t > /dev/null 2>&1 + ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1 if [ $? -ne 0 ]; then fail "ssh-add did succeed exit code 0" fi @@ -23,10 +23,10 @@ else if [ $n -ne 2 ]; then fail "ssh-add -l did not return 2 keys: $n" fi - trace "sleeping 2*${TIMEOUT} seconds" - sleep ${TIMEOUT} - sleep ${TIMEOUT} - ${SSHADD} -l 2> /dev/null | grep -q 'The agent has no identities.' + trace "sleeping 2*${SSHAGENT_TIMEOUT} seconds" + sleep ${SSHAGENT_TIMEOUT} + sleep ${SSHAGENT_TIMEOUT} + ${SSHADD} -l 2> /dev/null | grep 'The agent has no identities.' >/dev/null if [ $? -ne 0 ]; then fail "ssh-add -l still returns keys after timeout" fi diff --git a/crypto/openssh/regress/agent.sh b/crypto/openssh/regress/agent.sh index 7e9b4cb..b344877 100644 --- a/crypto/openssh/regress/agent.sh +++ b/crypto/openssh/regress/agent.sh @@ -19,7 +19,7 @@ else fail "ssh-add -l did not fail with exit code 1" fi trace "overwrite authorized keys" - echo -n > $OBJ/authorized_keys_$USER + echon > $OBJ/authorized_keys_$USER for t in rsa rsa1; do # generate user key for agent rm -f $OBJ/$t-agent diff --git a/crypto/openssh/regress/dynamic-forward.sh b/crypto/openssh/regress/dynamic-forward.sh new file mode 100644 index 0000000..2b0b825 --- /dev/null +++ b/crypto/openssh/regress/dynamic-forward.sh @@ -0,0 +1,47 @@ +# $OpenBSD: dynamic-forward.sh,v 1.2 2003/07/03 08:21:46 markus Exp $ +# Placed in the Public Domain. + +tid="dynamic forwarding" + +PORT=4242 +FWDPORT=4243 +DATA=/bin/ls${EXEEXT} + +if have_prog nc && nc -h 2>&1 | grep "x proxy address" >/dev/null; then + proxycmd="nc -x 127.0.0.1:$FWDPORT -X" +elif have_prog connect; then + proxycmd="connect -S 127.0.0.1:$FWDPORT -" +else + echo "skipped (no suitable ProxyCommand found)" + exit 0 +fi +trace "will use ProxyCommand $proxycmd" + +start_sshd + +for p in 1 2; do + trace "start dynamic forwarding, fork to background" + ${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q somehost \ + exec sh -c \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\' + + for s in 4 5; do + for h in 127.0.0.1 localhost; do + trace "testing ssh protocol $p socks version $s host $h" + ${SSH} -F $OBJ/ssh_config \ + -o "ProxyCommand ${proxycmd}${s} $h $PORT" \ + somehost cat $DATA > $OBJ/ls.copy + test -f $OBJ/ls.copy || fail "failed copy $DATA" + cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" + done + done + + if [ -f $OBJ/remote_pid ]; then + remote=`cat $OBJ/remote_pid` + trace "terminate remote shell, pid $remote" + if [ $remote -gt 1 ]; then + kill -HUP $remote + fi + else + fail "no pid file: $OBJ/remote_pid" + fi +done diff --git a/crypto/openssh/regress/forwarding.sh b/crypto/openssh/regress/forwarding.sh index 7b281c0..dfe065d 100644 --- a/crypto/openssh/regress/forwarding.sh +++ b/crypto/openssh/regress/forwarding.sh @@ -2,6 +2,7 @@ # Placed in the Public Domain. tid="local and remote forwarding" +DATA=/bin/ls${EXEEXT} start_sshd @@ -25,9 +26,9 @@ for p in 1 2; do trace "transfer over forwarded channels and check result" ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ - somehost cat /bin/ls > $OBJ/ls.copy - test -f $OBJ/ls.copy || fail "failed copy /bin/ls" - cmp /bin/ls $OBJ/ls.copy || fail "corrupted copy of /bin/ls" + somehost cat $DATA > $OBJ/ls.copy + test -f $OBJ/ls.copy || fail "failed copy $DATA" + cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" sleep 10 done diff --git a/crypto/openssh/regress/proto-version.sh b/crypto/openssh/regress/proto-version.sh index 7dc616f..1651a69 100644 --- a/crypto/openssh/regress/proto-version.sh +++ b/crypto/openssh/regress/proto-version.sh @@ -8,7 +8,7 @@ check_version () { version=$1 expect=$2 - banner=`echo -n | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy` + banner=`echon | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy` case ${banner} in SSH-1.99-*) proto=199 diff --git a/crypto/openssh/regress/reconfigure.sh b/crypto/openssh/regress/reconfigure.sh new file mode 100644 index 0000000..ba6dbc6 --- /dev/null +++ b/crypto/openssh/regress/reconfigure.sh @@ -0,0 +1,35 @@ +# $OpenBSD: reconfigure.sh,v 1.2 2003/06/21 09:14:05 markus Exp $ +# Placed in the Public Domain. + +tid="simple connect after reconfigure" + +# we need the full path to sshd for -HUP +case $SSHD in +/*) + # full path is OK + ;; +*) + # otherwise make fully qualified + SSHD=$OBJ/$SSHD +esac + +start_sshd + +$SUDO kill -HUP `cat $PIDFILE` +sleep 1 + +trace "wait for sshd to restart" +i=0; +while [ ! -f $PIDFILE -a $i -lt 10 ]; do + i=`expr $i + 1` + sleep $i +done + +test -f $PIDFILE || fatal "sshd did not restart" + +for p in 1 2; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed after reconfigure" + fi +done diff --git a/crypto/openssh/regress/rekey.sh b/crypto/openssh/regress/rekey.sh new file mode 100644 index 0000000..6b7e845 --- /dev/null +++ b/crypto/openssh/regress/rekey.sh @@ -0,0 +1,31 @@ +# $OpenBSD: rekey.sh,v 1.1 2003/03/28 13:58:28 markus Exp $ +# Placed in the Public Domain. + +tid="rekey during transfer data" + +DATA=${OBJ}/data +COPY=${OBJ}/copy +LOG=${OBJ}/log + +rm -f ${COPY} ${LOG} ${DATA} +dd if=/bin/ls${EXEEXT} of=${DATA} bs=1k seek=511 count=1 > /dev/null 2>&1 + +for s in 16 1k 128k 256k; do + trace "rekeylimit ${s}" + rm -f ${COPY} + cat $DATA | \ + ${SSH} -oCompression=no -oRekeyLimit=$s \ + -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" \ + 2> ${LOG} + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + cmp $DATA ${COPY} || fail "corrupted copy" + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done +rm -f ${COPY} ${LOG} ${DATA} diff --git a/crypto/openssh/regress/sftp-badcmds.sh b/crypto/openssh/regress/sftp-badcmds.sh new file mode 100644 index 0000000..a6a1940 --- /dev/null +++ b/crypto/openssh/regress/sftp-badcmds.sh @@ -0,0 +1,78 @@ +# $OpenBSD: sftp-badcmds.sh,v 1.2 2003/05/15 04:07:12 mouring Exp $ +# Placed in the Public Domain. + +tid="sftp invalid commands" + +DATA=/bin/ls${EXEEXT} +DATA2=/bin/cat${EXEEXT} +NONEXIST=/NONEXIST.$$ +COPY=${OBJ}/copy +GLOBFILES=`(cd /bin;echo l*)` + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd + +rm -f ${COPY} +verbose "$tid: get nonexistent" +echo "get $NONEXIST $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get nonexistent failed" +test -f ${COPY} && fail "existing copy after get nonexistent" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to nonexistent directory" +echo "get /bin/l* $NONEXIST" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get nonexistent failed" +for x in $GLOBFILES; do + test -f ${COPY}.dd/$x && fail "existing copy after get nonexistent" +done + +rm -f ${COPY} +verbose "$tid: put nonexistent" +echo "put $NONEXIST $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put nonexistent failed" +test -f ${COPY} && fail "existing copy after put nonexistent" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to nonexistent directory" +echo "put /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put nonexistent failed" +for x in $GLOBFILES; do + test -f ${COPY}.dd/$x && fail "existing copy after nonexistent" +done + +rm -f ${COPY} +verbose "$tid: rename nonexistent" +echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename nonexist failed" +test -f ${COPY}.1 && fail "file exists after rename nonexistent" + +rm -f ${COPY} ${COPY}.1 +cp $DATA $COPY +cp $DATA2 ${COPY}.1 +verbose "$tid: rename target exists" +echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename target exists failed" +test -f ${COPY} || fail "oldname missing after rename target exists" +test -f ${COPY}.1 || fail "newname missing after rename target exists" +cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists" +cmp $DATA2 ${COPY}.1 >/dev/null 2>&1 || fail "corrupted newname after rename target exists" + +rm -rf ${COPY} ${COPY}.dd +cp $DATA $COPY +mkdir ${COPY}.dd +verbose "$tid: rename target exists (directory)" +echo "rename $COPY ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename target exists (directory) failed" +test -f ${COPY} || fail "oldname missing after rename target exists (directory)" +test -d ${COPY}.dd || fail "newname missing after rename target exists (directory)" +cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists (directory)" + +rm -f ${COPY}.dd/* +rm -rf ${COPY} +cp ${DATA2} ${COPY} +verbose "$tid: glob put files to local file" +echo "put /bin/l* $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 +cmp ${DATA2} ${COPY} || fail "put successed when it should have failed" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd + + diff --git a/crypto/openssh/regress/sftp-batch.sh b/crypto/openssh/regress/sftp-batch.sh index cffacb6..f648eae 100644 --- a/crypto/openssh/regress/sftp-batch.sh +++ b/crypto/openssh/regress/sftp-batch.sh @@ -3,9 +3,9 @@ tid="sftp batchfile" -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy -BATCH=${OBJ}/sftp-batch +BATCH=${OBJ}/sftp-batch.tmp rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* diff --git a/crypto/openssh/regress/sftp-cmds.sh b/crypto/openssh/regress/sftp-cmds.sh index 462c680..1256aeb 100644 --- a/crypto/openssh/regress/sftp-cmds.sh +++ b/crypto/openssh/regress/sftp-cmds.sh @@ -1,17 +1,42 @@ -# $OpenBSD: sftp-cmds.sh,v 1.2 2003/01/10 07:52:41 djm Exp $ +# $OpenBSD: sftp-cmds.sh,v 1.5 2003/07/19 00:46:31 djm Exp $ # Placed in the Public Domain. # XXX - TODO: -# - globbed operations # - chmod / chown / chgrp # - -p flag for get & put tid="sftp commands" -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy - -rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* +# test that these files are readable! +for i in `(cd /bin;echo l*)` +do + if [ -r $i ]; then + GLOBFILES="$GLOBFILES $i" + fi +done + +if have_prog uname +then + case `uname` in + CYGWIN*) + os=cygwin + ;; + *) + os=`uname` + ;; + esac +else + os="unknown" +fi + +# Path with embedded quote +QUOTECOPY=${COPY}".\"blah\"" +QUOTECOPY_ARG=${COPY}'.\"blah\"' + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 +mkdir ${COPY}.dd verbose "$tid: lls" echo "lls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ @@ -54,21 +79,91 @@ echo "get $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ || fail "get failed" cmp $DATA ${COPY} || fail "corrupted copy after get" +rm -f ${COPY}.dd/* +verbose "$tid: get to directory" +echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to directory" +echo "get /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" +done + +rm -f ${COPY}.dd/* +verbose "$tid: get to local dir" +(echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to local dir" +(echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" +done + rm -f ${COPY} verbose "$tid: put" echo "put $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ || fail "put failed" cmp $DATA ${COPY} || fail "corrupted copy after put" +if [ "$os" != "cygwin" ]; then +rm -f ${QUOTECOPY} +verbose "$tid: put filename with quotes" +echo "put $DATA \"$QUOTECOPY_ARG\"" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" +fi + +rm -f ${COPY}.dd/* +verbose "$tid: put to directory" +echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to directory" +echo "put /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" +done + +rm -f ${COPY}.dd/* +verbose "$tid: put to local dir" +(echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to local dir" +(echo "cd ${COPY}.dd"; echo "put /bin/l*") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" +done + verbose "$tid: rename" echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ || fail "rename failed" test -f ${COPY}.1 || fail "missing file after rename" cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename" +verbose "$tid: rename directory" +echo "rename ${COPY}.dd ${COPY}.dd2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename directory failed" +test -d ${COPY}.dd && fail "oldname exists after rename directory" +test -d ${COPY}.dd2 || fail "missing newname after rename directory" + verbose "$tid: ln" echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" -test -L ${COPY}.2 || fail "missing file after ln" +test -h ${COPY}.2 || fail "missing file after ln" verbose "$tid: mkdir" echo "mkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ @@ -95,6 +190,6 @@ verbose "$tid: lchdir" echo "lchdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ || fail "lchdir failed" -rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 diff --git a/crypto/openssh/regress/sftp.sh b/crypto/openssh/regress/sftp.sh index e8d4731..0e22f8f 100644 --- a/crypto/openssh/regress/sftp.sh +++ b/crypto/openssh/regress/sftp.sh @@ -3,27 +3,33 @@ tid="basic sftp put/get" -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy +SFTPCMDFILE=${OBJ}/batch +cat >$SFTPCMDFILE <<EOF +version +get $DATA ${COPY}.1 +put $DATA ${COPY}.2 +EOF + BUFFERSIZE="5 1000 32000 64000" REQUESTS="1 2 10" for B in ${BUFFERSIZE}; do for R in ${REQUESTS}; do verbose "test $tid: buffer_size $B num_requests $R" - rm -f ${COPY}.1 ${COPY}.2 - ${SFTP} -P ${SFTPSERVER} -B $B -R $R -b /dev/stdin \ - > /dev/null 2>&1 << EOF - version - get $DATA ${COPY}.1 - put $DATA ${COPY}.2 -EOF + rm -f ${COPY}.1 ${COPY}.2 + ${SFTP} -P ${SFTPSERVER} -B $B -R $R -b $SFTPCMDFILE \ + > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "sftp failed with $r" + else + cmp $DATA ${COPY}.1 || fail "corrupted copy after get" + cmp $DATA ${COPY}.2 || fail "corrupted copy after put" fi - cmp $DATA ${COPY}.1 || fail "corrupted copy after get" - cmp $DATA ${COPY}.2 || fail "corrupted copy after put" done done +rm -f ${COPY}.1 ${COPY}.2 +rm -f $SFTPCMDFILE diff --git a/crypto/openssh/regress/ssh-com-client.sh b/crypto/openssh/regress/ssh-com-client.sh index 015ebbb..fc95322 100644 --- a/crypto/openssh/regress/ssh-com-client.sh +++ b/crypto/openssh/regress/ssh-com-client.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com-client.sh,v 1.4 2002/07/16 08:58:16 markus Exp $ +# $OpenBSD: ssh-com-client.sh,v 1.5 2003/05/14 22:08:27 markus Exp $ # Placed in the Public Domain. tid="connect with ssh.com client" @@ -17,6 +17,8 @@ VERSIONS=" 3.0.0 3.1.0 3.2.0 + 3.2.2 + 3.2.3 3.3.0" # 2.0.10 2.0.12 2.0.13 don't like the test setup @@ -62,7 +64,7 @@ EOF # we need a real server (no ProxyConnect option) start_sshd -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy rm -f ${COPY} diff --git a/crypto/openssh/regress/ssh-com-keygen.sh b/crypto/openssh/regress/ssh-com-keygen.sh index e93dc78..dbe9b0a 100644 --- a/crypto/openssh/regress/ssh-com-keygen.sh +++ b/crypto/openssh/regress/ssh-com-keygen.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com-keygen.sh,v 1.2 2002/07/16 08:58:16 markus Exp $ +# $OpenBSD: ssh-com-keygen.sh,v 1.3 2003/05/14 22:08:27 markus Exp $ # Placed in the Public Domain. tid="ssh.com key import" @@ -20,6 +20,8 @@ VERSIONS=" 3.0.0 3.1.0 3.2.0 + 3.2.2 + 3.2.3 3.3.0" COMPRV=${OBJ}/comkey diff --git a/crypto/openssh/regress/ssh-com-sftp.sh b/crypto/openssh/regress/ssh-com-sftp.sh index f08018b..6ca7dad 100644 --- a/crypto/openssh/regress/ssh-com-sftp.sh +++ b/crypto/openssh/regress/ssh-com-sftp.sh @@ -1,10 +1,17 @@ -# $OpenBSD: ssh-com-sftp.sh,v 1.3 2002/07/16 08:58:16 markus Exp $ +# $OpenBSD: ssh-com-sftp.sh,v 1.4 2003/05/14 22:08:27 markus Exp $ # Placed in the Public Domain. tid="basic sftp put/get with ssh.com server" -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy +SFTPCMDFILE=${OBJ}/batch + +cat >$SFTPCMDFILE <<EOF +version +get $DATA ${COPY}.1 +put $DATA ${COPY}.2 +EOF BUFFERSIZE="5 1000 32000 64000" REQUESTS="1 2 10" @@ -26,6 +33,8 @@ VERSIONS=" 3.0.0 3.1.0 3.2.0 + 3.2.2 + 3.2.3 3.3.0" # go for it @@ -39,18 +48,17 @@ for v in ${VERSIONS}; do for R in ${REQUESTS}; do verbose "test $tid: buffer_size $B num_requests $R" rm -f ${COPY}.1 ${COPY}.2 - ${SFTP} -P ${server} -B $B -R $R -b /dev/stdin \ - > /dev/null 2>&1 << EOF - version - get $DATA ${COPY}.1 - put $DATA ${COPY}.2 -EOF + ${SFTP} -P ${server} -B $B -R $R -b $SFTPCMDFILE \ + > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then fail "sftp failed with $r" + else + cmp $DATA ${COPY}.1 || fail "corrupted copy after get" + cmp $DATA ${COPY}.2 || fail "corrupted copy after put" fi - cmp $DATA ${COPY}.1 || fail "corrupted copy after get" - cmp $DATA ${COPY}.2 || fail "corrupted copy after put" done done done +rm -f ${COPY}.1 ${COPY}.2 +rm -f $SFTPCMDFILE diff --git a/crypto/openssh/regress/ssh-com.sh b/crypto/openssh/regress/ssh-com.sh index c2bd153..78ae6e9 100644 --- a/crypto/openssh/regress/ssh-com.sh +++ b/crypto/openssh/regress/ssh-com.sh @@ -1,4 +1,4 @@ -# $OpenBSD: ssh-com.sh,v 1.4 2002/07/16 08:58:16 markus Exp $ +# $OpenBSD: ssh-com.sh,v 1.5 2003/05/14 22:08:27 markus Exp $ # Placed in the Public Domain. tid="connect to ssh.com server" @@ -18,6 +18,8 @@ VERSIONS=" 3.0.0 3.1.0 3.2.0 + 3.2.2 + 3.2.3 3.3.0" # 2.0.10 does not support UserConfigDirectory # 2.3.1 requires a config in $HOME/.ssh2 @@ -65,7 +67,7 @@ done # convert and append DSA hostkey ( - echo -n 'ssh2-localhost-with-alias,127.0.0.1,::1 ' + echon 'ssh2-localhost-with-alias,127.0.0.1,::1 ' ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub ) >> $OBJ/known_hosts diff --git a/crypto/openssh/regress/stderr-after-eof.sh b/crypto/openssh/regress/stderr-after-eof.sh index bebd700..05a5ea5 100644 --- a/crypto/openssh/regress/stderr-after-eof.sh +++ b/crypto/openssh/regress/stderr-after-eof.sh @@ -7,13 +7,23 @@ DATA=/etc/motd DATA=${OBJ}/data COPY=${OBJ}/copy -MD5=md5sum +if have_prog md5sum; then + CHECKSUM=md5sum +elif have_prog openssl; then + CHECKSUM="openssl md5" +elif have_prog cksum; then + CHECKSUM=cksum +elif have_prog sum; then + CHECKSUM=sum +else + fatal "No checksum program available, aborting $tid test" +fi # setup data rm -f ${DATA} ${COPY} cp /dev/null ${DATA} for i in 1 2 3 4 5 6; do - (date;echo $i) | $MD5 >> ${DATA} + (date;echo $i) | $CHECKSUM >> ${DATA} done ${SSH} -2 -F $OBJ/ssh_proxy otherhost \ diff --git a/crypto/openssh/regress/stderr-data.sh b/crypto/openssh/regress/stderr-data.sh index 0157690..1daf79b 100644 --- a/crypto/openssh/regress/stderr-data.sh +++ b/crypto/openssh/regress/stderr-data.sh @@ -3,7 +3,7 @@ tid="stderr data transfer" -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy rm -f ${COPY} diff --git a/crypto/openssh/regress/test-exec.sh b/crypto/openssh/regress/test-exec.sh index a7a8ddb..cc7ea67 100644 --- a/crypto/openssh/regress/test-exec.sh +++ b/crypto/openssh/regress/test-exec.sh @@ -2,10 +2,16 @@ # Placed in the Public Domain. PORT=4242 -USER=`id -un` -SUDO= #SUDO=sudo +if [ -x /usr/ucb/whoami ]; then + USER=`/usr/ucb/whoami` +elif whoami >/dev/null 2>&1; then + USER=`whoami` +else + USER=`id -un` +fi + OBJ=$1 if [ "x$OBJ" = "x" ]; then echo '$OBJ not defined' @@ -72,6 +78,32 @@ export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER #echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER # helper +echon() +{ + if [ "x`echo -n`" = "x" ]; then + echo -n "$@" + elif [ "x`echo '\c'`" = "x" ]; then + echo "$@\c" + else + fatal "Don't know how to echo without newline." + fi +} + +have_prog() +{ + saved_IFS="$IFS" + IFS=":" + for i in $PATH + do + if [ -x $i/$1 ]; then + IFS="$saved_IFS" + return 0 + fi + done + IFS="$saved_IFS" + return 1 +} + cleanup () { if [ -f $PIDFILE ]; then @@ -111,7 +143,7 @@ fail () fatal () { - echo -n "FATAL: " + echon "FATAL: " fail "$@" cleanup exit $RESULT @@ -130,6 +162,7 @@ cat << EOF > $OBJ/sshd_config PidFile $PIDFILE AuthorizedKeysFile $OBJ/authorized_keys_%u LogLevel QUIET + StrictModes no EOF # server config for proxy connects @@ -169,7 +202,7 @@ for t in rsa rsa1; do # known hosts file for client ( - echo -n 'localhost-with-alias,127.0.0.1,::1 ' + echon 'localhost-with-alias,127.0.0.1,::1 ' cat $OBJ/$t.pub ) >> $OBJ/known_hosts @@ -189,7 +222,7 @@ chmod 644 $OBJ/authorized_keys_$USER # create a proxy version of the client config ( cat $OBJ/ssh_config - echo proxycommand ${SSHD} -i -f $OBJ/sshd_proxy + echo proxycommand ${SUDO} ${SSHD} -i -f $OBJ/sshd_proxy ) > $OBJ/ssh_proxy # check proxy config @@ -203,7 +236,7 @@ start_sshd () trace "wait for sshd" i=0; - while [ ! -f $PIDFILE -a $i -lt 5 ]; do + while [ ! -f $PIDFILE -a $i -lt 10 ]; do i=`expr $i + 1` sleep $i done diff --git a/crypto/openssh/regress/transfer.sh b/crypto/openssh/regress/transfer.sh index 31cdc0c..13ea367 100644 --- a/crypto/openssh/regress/transfer.sh +++ b/crypto/openssh/regress/transfer.sh @@ -3,7 +3,7 @@ tid="transfer data" -DATA=/bin/ls +DATA=/bin/ls${EXEEXT} COPY=${OBJ}/copy for p in 1 2; do diff --git a/crypto/openssh/regress/try-ciphers.sh b/crypto/openssh/regress/try-ciphers.sh index 161f039..2c727f6 100644 --- a/crypto/openssh/regress/try-ciphers.sh +++ b/crypto/openssh/regress/try-ciphers.sh @@ -1,10 +1,11 @@ -# $OpenBSD: try-ciphers.sh,v 1.7 2002/04/03 09:30:01 markus Exp $ +# $OpenBSD: try-ciphers.sh,v 1.8 2003/06/12 15:40:01 markus Exp $ # Placed in the Public Domain. tid="try ciphers" ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc arcfour - aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se" + aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se + aes128-ctr aes192-ctr aes256-ctr" macs="hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96" for c in $ciphers; do diff --git a/crypto/openssh/regress/yes-head.sh b/crypto/openssh/regress/yes-head.sh index f213f68..17a4d0d 100644 --- a/crypto/openssh/regress/yes-head.sh +++ b/crypto/openssh/regress/yes-head.sh @@ -4,7 +4,7 @@ tid="yes pipe head" for p in 1 2; do - lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'yes | head -2000' | (sleep 3 ; wc -l)` + lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | head -2000"' | (sleep 3 ; wc -l)` if [ $? -ne 0 ]; then fail "yes|head test failed" lines = 0; diff --git a/crypto/openssh/scard-opensc.c b/crypto/openssh/scard-opensc.c index dd21de3..2489fec 100644 --- a/crypto/openssh/scard-opensc.c +++ b/crypto/openssh/scard-opensc.c @@ -89,6 +89,12 @@ sc_init(void) r = sc_establish_context(&ctx, "openssh"); if (r) goto err; + if (sc_reader_id >= ctx->reader_count) { + r = SC_ERROR_NO_READERS_FOUND; + error("Illegal reader number %d (max %d)", sc_reader_id, + ctx->reader_count -1); + goto err; + } r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card); if (r) goto err; @@ -104,7 +110,8 @@ err: /* private key operations */ static int -sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out) +sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out, + unsigned int usage) { int r; struct sc_priv_data *priv; @@ -124,7 +131,8 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out) goto err; } } - r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); + r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, + usage, &key_obj); if (r) { error("Unable to find private key from SmartCard: %s", sc_strerror(r)); @@ -133,7 +141,16 @@ sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out) key = key_obj->data; r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, &pin_obj); - if (r) { + if (r == SC_ERROR_OBJECT_NOT_FOUND) { + /* no pin required */ + r = sc_lock(card); + if (r) { + error("Unable to lock smartcard: %s", sc_strerror(r)); + goto err; + } + *key_obj_out = key_obj; + return 0; + } else if (r) { error("Unable to find PIN object from SmartCard: %s", sc_strerror(r)); goto err; @@ -161,6 +178,9 @@ err: return -1; } +#define SC_USAGE_DECRYPT SC_PKCS15_PRKEY_USAGE_DECRYPT | \ + SC_PKCS15_PRKEY_USAGE_UNWRAP + static int sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding) @@ -170,10 +190,11 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, if (padding != RSA_PKCS1_PADDING) return -1; - r = sc_prkey_op_init(rsa, &key_obj); + r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT); if (r) return -1; - r = sc_pkcs15_decipher(p15card, key_obj, 0, from, flen, to, flen); + r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1, + from, flen, to, flen); sc_unlock(card); if (r < 0) { error("sc_pkcs15_decipher() failed: %s", sc_strerror(r)); @@ -185,6 +206,9 @@ err: return -1; } +#define SC_USAGE_SIGN SC_PKCS15_PRKEY_USAGE_SIGN | \ + SC_PKCS15_PRKEY_USAGE_SIGNRECOVER + static int sc_sign(int type, u_char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) @@ -193,7 +217,15 @@ sc_sign(int type, u_char *m, unsigned int m_len, int r; unsigned long flags = 0; - r = sc_prkey_op_init(rsa, &key_obj); + /* XXX: sc_prkey_op_init will search for a pkcs15 private + * key object with the sign or signrecover usage flag set. + * If the signing key has only the non-repudiation flag set + * the key will be rejected as using a non-repudiation key + * for authentication is not recommended. Note: This does not + * prevent the use of a non-repudiation key for authentication + * if the sign or signrecover flag is set as well. + */ + r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN); if (r) return -1; /* FIXME: length of sigret correct? */ @@ -321,7 +353,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); if (r) { - log("Certificate read failed: %s", sc_strerror(r)); + logit("Certificate read failed: %s", sc_strerror(r)); goto err; } x509 = X509_new(); @@ -331,7 +363,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) } p = cert->data; if (!d2i_X509(&x509, &p, cert->data_len)) { - log("Unable to parse X.509 certificate"); + logit("Unable to parse X.509 certificate"); r = -1; goto err; } @@ -341,7 +373,7 @@ sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) X509_free(x509); x509 = NULL; if (pubkey->type != EVP_PKEY_RSA) { - log("Public key is of unknown type"); + logit("Public key is of unknown type"); r = -1; goto err; } @@ -413,7 +445,7 @@ sc_get_keys(const char *id, const char *pin) r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, certs, 32); if (r == 0) { - log("No certificates found on smartcard"); + logit("No certificates found on smartcard"); r = -1; goto err; } else if (r < 0) { @@ -423,9 +455,14 @@ sc_get_keys(const char *id, const char *pin) } key_count = r; } - /* FIXME: only keep entries with a corresponding private key */ keys = xmalloc(sizeof(Key *) * (key_count*2+1)); for (i = 0; i < key_count; i++) { + sc_pkcs15_object_t *tmp_obj = NULL; + cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id; + if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj)) + /* skip the public key (certificate) if no + * corresponding private key is present */ + continue; k = key_new(KEY_RSA); if (k == NULL) break; @@ -459,4 +496,30 @@ sc_put_key(Key *prv, const char *id) return -1; } +char * +sc_get_key_label(Key *key) +{ + int r; + const struct sc_priv_data *priv; + struct sc_pkcs15_object *key_obj; + + priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa); + if (priv == NULL || p15card == NULL) { + logit("SmartCard key not loaded"); + /* internal error => return default label */ + return xstrdup("smartcard key"); + } + r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); + if (r) { + logit("Unable to find private key from SmartCard: %s", + sc_strerror(r)); + return xstrdup("smartcard key"); + } + if (key_obj == NULL || key_obj->label == NULL) + /* the optional PKCS#15 label does not exists + * => return the default label */ + return xstrdup("smartcard key"); + return xstrdup(key_obj->label); +} + #endif /* SMARTCARD */ diff --git a/crypto/openssh/scard.c b/crypto/openssh/scard.c index 9791938..906287b 100644 --- a/crypto/openssh/scard.c +++ b/crypto/openssh/scard.c @@ -24,7 +24,7 @@ #include "includes.h" #if defined(SMARTCARD) && defined(USE_SECTOK) -RCSID("$OpenBSD: scard.c,v 1.26 2002/06/23 03:30:17 deraadt Exp $"); +RCSID("$OpenBSD: scard.c,v 1.28 2003/06/12 19:12:02 markus Exp $"); #include <openssl/evp.h> #include <sectok.h> @@ -526,7 +526,7 @@ sc_put_key(Key *prv, const char *id) } if (!sectok_swOK(sw)) goto done; - log("cyberflex_load_rsa_priv done"); + logit("cyberflex_load_rsa_priv done"); key_fid[0] = 0x73; key_fid[1] = 0x68; if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5], @@ -536,7 +536,7 @@ sc_put_key(Key *prv, const char *id) } if (!sectok_swOK(sw)) goto done; - log("cyberflex_load_rsa_pub done"); + logit("cyberflex_load_rsa_pub done"); status = 0; done: @@ -554,4 +554,11 @@ done: sectok_close(fd); return (status); } + +char * +sc_get_key_label(Key *key) +{ + return xstrdup("smartcard key"); +} + #endif /* SMARTCARD && USE_SECTOK */ diff --git a/crypto/openssh/scard.h b/crypto/openssh/scard.h index 00999cb..9ba20a3 100644 --- a/crypto/openssh/scard.h +++ b/crypto/openssh/scard.h @@ -1,4 +1,4 @@ -/* $OpenBSD: scard.h,v 1.11 2002/06/30 21:59:45 deraadt Exp $ */ +/* $OpenBSD: scard.h,v 1.12 2003/06/12 19:12:03 markus Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -36,5 +36,6 @@ Key **sc_get_keys(const char *, const char *); void sc_close(void); int sc_put_key(Key *, const char *); +char *sc_get_key_label(Key *); #endif diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1 index a3ec2e0..a971500 100644 --- a/crypto/openssh/scp.1 +++ b/crypto/openssh/scp.1 @@ -9,7 +9,7 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.27 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: scp.1,v 1.28 2003/06/10 09:12:11 jmc Exp $ .\" .Dd September 25, 1999 .Dt SCP 1 @@ -148,14 +148,6 @@ to use IPv6 addresses only. .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 -.Nm -is based on the -.Xr rcp 1 -program in BSD source code from the Regents of the University of -California. .Sh SEE ALSO .Xr rcp 1 , .Xr sftp 1 , @@ -165,3 +157,13 @@ California. .Xr ssh-keygen 1 , .Xr ssh_config 5 , .Xr sshd 8 +.Sh HISTORY +.Nm +is based on the +.Xr rcp 1 +program in BSD source code from the Regents of the University of +California. +.Sh AUTHORS +.An Timo Rinne Aq tri@iki.fi +and +.An Tatu Ylonen Aq ylo@cs.hut.fi diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c index 35d4c5f..4f9247c 100644 --- a/crypto/openssh/scp.c +++ b/crypto/openssh/scp.c @@ -52,11 +52,7 @@ * 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 + * 3. 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. * @@ -75,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.102 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: scp.c,v 1.108 2003/07/18 01:54:25 deraadt Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -111,7 +107,16 @@ int showprogress = 1; char *ssh_program = _PATH_SSH_PROGRAM; /* This is used to store the pid of ssh_program */ -pid_t do_cmd_pid; +pid_t do_cmd_pid = -1; + +static void +killchild(int signo) +{ + if (do_cmd_pid > 1) + kill(do_cmd_pid, signo); + + _exit(1); +} /* * This function executes the given command as the specified user on the @@ -146,7 +151,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) close(reserved[0]); close(reserved[1]); - /* For a child to execute the command on the remote host using ssh. */ + /* Fork a child to execute the command on the remote host using ssh. */ do_cmd_pid = fork(); if (do_cmd_pid == 0) { /* Child. */ @@ -174,6 +179,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) *fdout = pin[1]; close(pout[1]); *fdin = pout[0]; + signal(SIGTERM, killchild); + signal(SIGINT, killchild); + signal(SIGHUP, killchild); return 0; } @@ -206,9 +214,7 @@ void toremote(char *, int, char *[]); void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char **argv) { int ch, fflag, tflag, status; double speed; @@ -216,7 +222,7 @@ main(argc, argv) extern char *optarg; extern int optind; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ @@ -292,7 +298,7 @@ main(argc, argv) argv += optind; if ((pwd = getpwuid(userid = getuid())) == NULL) - fatal("unknown user %d", (int) userid); + fatal("unknown user %u", (u_int) userid); if (!isatty(STDERR_FILENO)) showprogress = 0; @@ -353,9 +359,7 @@ main(argc, argv) } void -toremote(targ, argc, argv) - char *targ, *argv[]; - int argc; +toremote(char *targ, int argc, char **argv) { int i, len; char *bp, *host, *src, *suser, *thost, *tuser; @@ -443,9 +447,7 @@ toremote(targ, argc, argv) } void -tolocal(argc, argv) - int argc; - char *argv[]; +tolocal(int argc, char **argv) { int i, len; char *bp, *host, *src, *suser; @@ -494,9 +496,7 @@ tolocal(argc, argv) } void -source(argc, argv) - int argc; - char *argv[]; +source(int argc, char **argv) { struct stat stb; static BUF buffer; @@ -549,25 +549,18 @@ syserr: run_err("%s: %s", name, strerror(errno)); (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", (u_long) stb.st_mtime, (u_long) stb.st_atime); - (void) atomicio(write, remout, buf, strlen(buf)); + (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) -#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); -#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 + (int64_t)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } - (void) atomicio(write, remout, buf, strlen(buf)); + (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { @@ -587,9 +580,9 @@ next: (void) close(fd); haderr = result >= 0 ? EIO : errno; } if (haderr) - (void) atomicio(write, remout, bp->buf, amt); + (void) atomicio(vwrite, remout, bp->buf, amt); else { - result = atomicio(write, remout, bp->buf, amt); + result = atomicio(vwrite, remout, bp->buf, amt); if (result != amt) haderr = result >= 0 ? EIO : errno; statbytes += result; @@ -603,7 +596,7 @@ next: (void) close(fd); if (close(fd) < 0 && !haderr) haderr = errno; if (!haderr) - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); else run_err("%s: %s", name, strerror(haderr)); (void) response(); @@ -611,9 +604,7 @@ next: (void) close(fd); } void -rsource(name, statp) - char *name; - struct stat *statp; +rsource(char *name, struct stat *statp) { DIR *dirp; struct dirent *dp; @@ -632,7 +623,7 @@ rsource(name, statp) (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", (u_long) statp->st_mtime, (u_long) statp->st_atime); - (void) atomicio(write, remout, path, strlen(path)); + (void) atomicio(vwrite, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); return; @@ -642,7 +633,7 @@ rsource(name, statp) (u_int) (statp->st_mode & FILEMODEMASK), 0, last); if (verbose_mode) fprintf(stderr, "Entering directory: %s", path); - (void) atomicio(write, remout, path, strlen(path)); + (void) atomicio(vwrite, remout, path, strlen(path)); if (response() < 0) { closedir(dirp); return; @@ -661,7 +652,7 @@ rsource(name, statp) source(1, vect); } (void) closedir(dirp); - (void) atomicio(write, remout, "E\n", 2); + (void) atomicio(vwrite, remout, "E\n", 2); (void) response(); } @@ -720,9 +711,7 @@ bwlimit(int amount) } void -sink(argc, argv) - int argc; - char *argv[]; +sink(int argc, char **argv) { static BUF buffer; struct stat stb; @@ -753,7 +742,7 @@ sink(argc, argv) if (targetshouldbedirectory) verifydir(targ); - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) targisdir = 1; for (first = 1;; first = 0) { @@ -771,7 +760,7 @@ sink(argc, argv) if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) - (void) atomicio(write, STDERR_FILENO, + (void) atomicio(vwrite, STDERR_FILENO, buf + 1, strlen(buf + 1)); if (buf[0] == '\02') exit(1); @@ -779,7 +768,7 @@ sink(argc, argv) continue; } if (buf[0] == 'E') { - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); return; } if (ch == '\n') @@ -801,7 +790,7 @@ sink(argc, argv) atime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != '\0') SCREWUP("atime.usec not delimited"); - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); continue; } if (*cp != 'C' && *cp != 'D') { @@ -886,7 +875,7 @@ sink(argc, argv) bad: run_err("%s: %s", np, strerror(errno)); continue; } - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { (void) close(ofd); continue; @@ -923,7 +912,7 @@ bad: run_err("%s: %s", np, strerror(errno)); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { - j = atomicio(write, ofd, bp->buf, count); + j = atomicio(vwrite, ofd, bp->buf, count); if (j != count) { wrerr = YES; wrerrno = j >= 0 ? EIO : errno; @@ -936,7 +925,7 @@ bad: run_err("%s: %s", np, strerror(errno)); if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && - (j = atomicio(write, ofd, bp->buf, count)) != count) { + (j = atomicio(vwrite, ofd, bp->buf, count)) != count) { wrerr = YES; wrerrno = j >= 0 ? EIO : errno; } @@ -981,7 +970,7 @@ bad: run_err("%s: %s", np, strerror(errno)); run_err("%s: %s", np, strerror(wrerrno)); break; case NO: - (void) atomicio(write, remout, "", 1); + (void) atomicio(vwrite, remout, "", 1); break; case DISPLAYED: break; @@ -1016,7 +1005,7 @@ response(void) } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); if (!iamremote) - (void) atomicio(write, STDERR_FILENO, rbuf, cp - rbuf); + (void) atomicio(vwrite, STDERR_FILENO, rbuf, cp - rbuf); ++errs; if (resp == 1) return (-1); @@ -1061,8 +1050,7 @@ run_err(const char *fmt,...) } void -verifydir(cp) - char *cp; +verifydir(char *cp) { struct stat stb; @@ -1076,8 +1064,7 @@ verifydir(cp) } int -okname(cp0) - char *cp0; +okname(char *cp0) { int c; char *cp; @@ -1107,9 +1094,7 @@ bad: fprintf(stderr, "%s: invalid user name\n", cp0); } BUF * -allocbuf(bp, fd, blksize) - BUF *bp; - int fd, blksize; +allocbuf(BUF *bp, int fd, int blksize) { size_t size; #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE @@ -1137,8 +1122,7 @@ allocbuf(bp, fd, blksize) } void -lostconn(signo) - int signo; +lostconn(int signo) { if (!iamremote) write(STDERR_FILENO, "lost connection\n", 16); diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c index 2510659..58f49a2 100644 --- a/crypto/openssh/servconf.c +++ b/crypto/openssh/servconf.c @@ -10,23 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.116 2003/02/21 09:05:53 markus Exp $"); - -#if defined(KRB4) -#include <krb.h> -#endif -#if defined(KRB5) -#ifdef HEIMDAL -#include <krb.h> -#else -/* Bodge - but then, so is using the kerberos IV KEYFILE to get a Kerberos V - * keytab */ -#define KEYFILE "/etc/krb5.keytab" -#endif -#endif -#ifdef AFS -#include <kafs.h> -#endif +RCSID("$OpenBSD: servconf.c,v 1.127 2003/09/01 18:15:50 markus Exp $"); #include "ssh.h" #include "log.h" @@ -56,7 +40,7 @@ initialize_server_options(ServerOptions *options) memset(options, 0, sizeof(*options)); /* Portable-specific options */ - options->pam_authentication_via_kbd_int = -1; + options->use_pam = -1; /* Standard Options */ options->num_ports = 0; @@ -80,23 +64,16 @@ initialize_server_options(ServerOptions *options) options->keepalives = -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; options->hostbased_uses_name_from_packet_only = -1; options->rsa_authentication = -1; options->pubkey_authentication = -1; -#if defined(KRB4) || defined(KRB5) options->kerberos_authentication = -1; options->kerberos_or_local_passwd = -1; options->kerberos_ticket_cleanup = -1; -#endif -#if defined(AFS) || defined(KRB5) - options->kerberos_tgt_passing = -1; -#endif -#ifdef AFS - options->afs_token_passing = -1; -#endif + options->gss_authentication=-1; + options->gss_cleanup_creds = -1; options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; @@ -118,7 +95,7 @@ initialize_server_options(ServerOptions *options) options->max_startups_rate = -1; options->max_startups = -1; options->banner = NULL; - options->verify_reverse_mapping = -1; + options->use_dns = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; options->authorized_keys_file = NULL; @@ -132,8 +109,8 @@ void fill_default_server_options(ServerOptions *options) { /* Portable-specific options */ - if (options->pam_authentication_via_kbd_int == -1) - options->pam_authentication_via_kbd_int = 0; + if (options->use_pam == -1) + options->use_pam = 0; /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) @@ -188,8 +165,6 @@ fill_default_server_options(ServerOptions *options) options->log_facility = SYSLOG_FACILITY_AUTH; if (options->log_level == SYSLOG_LEVEL_NOT_SET) options->log_level = SYSLOG_LEVEL_INFO; - if (options->rhosts_authentication == -1) - options->rhosts_authentication = 0; if (options->rhosts_rsa_authentication == -1) options->rhosts_rsa_authentication = 0; if (options->hostbased_authentication == -1) @@ -200,22 +175,16 @@ fill_default_server_options(ServerOptions *options) options->rsa_authentication = 1; if (options->pubkey_authentication == -1) options->pubkey_authentication = 1; -#if defined(KRB4) || defined(KRB5) if (options->kerberos_authentication == -1) options->kerberos_authentication = 0; if (options->kerberos_or_local_passwd == -1) options->kerberos_or_local_passwd = 1; if (options->kerberos_ticket_cleanup == -1) options->kerberos_ticket_cleanup = 1; -#endif -#if defined(AFS) || defined(KRB5) - if (options->kerberos_tgt_passing == -1) - options->kerberos_tgt_passing = 0; -#endif -#ifdef AFS - if (options->afs_token_passing == -1) - options->afs_token_passing = 0; -#endif + if (options->gss_authentication == -1) + options->gss_authentication = 0; + if (options->gss_cleanup_creds == -1) + options->gss_cleanup_creds = 1; if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) @@ -240,8 +209,8 @@ 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->verify_reverse_mapping == -1) - options->verify_reverse_mapping = 0; + if (options->use_dns == -1) + options->use_dns = 1; if (options->client_alive_interval == -1) options->client_alive_interval = 0; if (options->client_alive_count_max == -1) @@ -275,21 +244,13 @@ fill_default_server_options(ServerOptions *options) typedef enum { sBadOption, /* == unknown option */ /* Portable-specific options */ - sPAMAuthenticationViaKbdInt, + sUsePAM, /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, - sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, -#if defined(KRB4) || defined(KRB5) + sRhostsRSAAuthentication, sRSAAuthentication, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, -#endif -#if defined(AFS) || defined(KRB5) - sKerberosTgtPassing, -#endif -#ifdef AFS - sAFSTokenPassing, -#endif - sChallengeResponseAuthentication, + sKerberosTgtPassing, sChallengeResponseAuthentication, sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, @@ -298,11 +259,12 @@ typedef enum { sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, - sBanner, sVerifyReverseMapping, sHostbasedAuthentication, + sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, + sGssAuthentication, sGssCleanupCreds, sUsePrivilegeSeparation, - sDeprecated + sDeprecated, sUnsupported } ServerOpCodes; /* Textual representation of the tokens. */ @@ -311,7 +273,12 @@ static struct { ServerOpCodes opcode; } keywords[] = { /* Portable-specific options */ - { "PAMAuthenticationViaKbdInt", sPAMAuthenticationViaKbdInt }, +#ifdef USE_PAM + { "usepam", sUsePAM }, +#else + { "usepam", sUnsupported }, +#endif + { "pamauthenticationviakbdint", sDeprecated }, /* Standard Options */ { "port", sPort }, { "hostkey", sHostKeyFile }, @@ -323,23 +290,30 @@ static struct { { "permitrootlogin", sPermitRootLogin }, { "syslogfacility", sLogFacility }, { "loglevel", sLogLevel }, - { "rhostsauthentication", sRhostsAuthentication }, + { "rhostsauthentication", sDeprecated }, { "rhostsrsaauthentication", sRhostsRSAAuthentication }, { "hostbasedauthentication", sHostbasedAuthentication }, { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly }, { "rsaauthentication", sRSAAuthentication }, { "pubkeyauthentication", sPubkeyAuthentication }, { "dsaauthentication", sPubkeyAuthentication }, /* alias */ -#if defined(KRB4) || defined(KRB5) +#ifdef KRB5 { "kerberosauthentication", sKerberosAuthentication }, { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, { "kerberosticketcleanup", sKerberosTicketCleanup }, +#else + { "kerberosauthentication", sUnsupported }, + { "kerberosorlocalpasswd", sUnsupported }, + { "kerberosticketcleanup", sUnsupported }, #endif -#if defined(AFS) || defined(KRB5) - { "kerberostgtpassing", sKerberosTgtPassing }, -#endif -#ifdef AFS - { "afstokenpassing", sAFSTokenPassing }, + { "kerberostgtpassing", sUnsupported }, + { "afstokenpassing", sUnsupported }, +#ifdef GSSAPI + { "gssapiauthentication", sGssAuthentication }, + { "gssapicleanupcreds", sGssCleanupCreds }, +#else + { "gssapiauthentication", sUnsupported }, + { "gssapicleanupcreds", sUnsupported }, #endif { "passwordauthentication", sPasswordAuthentication }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication }, @@ -373,8 +347,9 @@ static struct { { "subsystem", sSubsystem }, { "maxstartups", sMaxStartups }, { "banner", sBanner }, - { "verifyreversemapping", sVerifyReverseMapping }, - { "reversemappingcheck", sVerifyReverseMapping }, + { "usedns", sUseDNS }, + { "verifyreversemapping", sDeprecated }, + { "reversemappingcheck", sDeprecated }, { "clientaliveinterval", sClientAliveInterval }, { "clientalivecountmax", sClientAliveCountMax }, { "authorizedkeysfile", sAuthorizedKeysFile }, @@ -458,8 +433,8 @@ process_server_config_line(ServerOptions *options, char *line, opcode = parse_token(arg, filename, linenum); switch (opcode) { /* Portable-specific options */ - case sPAMAuthenticationViaKbdInt: - intptr = &options->pam_authentication_via_kbd_int; + case sUsePAM: + intptr = &options->use_pam; goto parse_flag; /* Standard Options */ @@ -622,10 +597,6 @@ parse_flag: 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; @@ -645,7 +616,7 @@ 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; @@ -657,17 +628,14 @@ 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; + + case sGssAuthentication: + intptr = &options->gss_authentication; goto parse_flag; -#endif -#ifdef AFS - case sAFSTokenPassing: - intptr = &options->afs_token_passing; + + case sGssCleanupCreds: + intptr = &options->gss_cleanup_creds; goto parse_flag; -#endif case sPasswordAuthentication: intptr = &options->password_authentication; @@ -733,8 +701,8 @@ parse_flag: intptr = &options->gateway_ports; goto parse_flag; - case sVerifyReverseMapping: - intptr = &options->verify_reverse_mapping; + case sUseDNS: + intptr = &options->use_dns; goto parse_flag; case sLogFacility: @@ -910,7 +878,14 @@ parse_flag: goto parse_int; case sDeprecated: - log("%s line %d: Deprecated option %s", + logit("%s line %d: Deprecated option %s", + filename, linenum, arg); + while (arg) + arg = strdelim(&cp); + break; + + case sUnsupported: + logit("%s line %d: Unsupported option %s", filename, linenum, arg); while (arg) arg = strdelim(&cp); diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h index 024987d..828e94c 100644 --- a/crypto/openssh/servconf.h +++ b/crypto/openssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.59 2002/07/30 17:03:55 markus Exp $ */ +/* $OpenBSD: servconf.h,v 1.65 2003/09/01 18:15:50 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -65,15 +65,12 @@ typedef struct { int gateway_ports; /* If true, allow remote connects to forwarded ports. */ SyslogFacility log_facility; /* Facility for system logging. */ LogLevel log_level; /* Level for system logging. */ - int rhosts_authentication; /* If true, permit rhosts - * authentication. */ int rhosts_rsa_authentication; /* If true, permit rhosts RSA * authentication. */ int hostbased_authentication; /* If true, permit ssh2 hostbased auth */ int hostbased_uses_name_from_packet_only; /* experimental */ int rsa_authentication; /* If true, permit RSA authentication. */ int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ -#if defined(KRB4) || defined(KRB5) int kerberos_authentication; /* If true, permit Kerberos * authentication. */ int kerberos_or_local_passwd; /* If true, permit kerberos @@ -83,14 +80,8 @@ typedef struct { * /etc/passwd */ int kerberos_ticket_cleanup; /* If true, destroy ticket * file on logout. */ -#endif -#if defined(AFS) || defined(KRB5) - int kerberos_tgt_passing; /* If true, permit Kerberos TGT - * passing. */ -#endif -#ifdef AFS - int afs_token_passing; /* If true, permit AFS token passing. */ -#endif + int gss_authentication; /* If true, permit GSSAPI authentication */ + int gss_cleanup_creds; /* If true, destroy cred cache on logout */ int password_authentication; /* If true, permit password * authentication. */ int kbd_interactive_authentication; /* If true, permit */ @@ -118,7 +109,7 @@ typedef struct { int max_startups_rate; int max_startups; char *banner; /* SSH-2 banner message */ - int verify_reverse_mapping; /* cross-check ip and dns */ + int use_dns; int client_alive_interval; /* * poke the client this often to * see if it's still there @@ -131,7 +122,7 @@ typedef struct { char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; - int pam_authentication_via_kbd_int; + int use_pam; /* Enable auth via PAM */ } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/crypto/openssh/serverloop.c b/crypto/openssh/serverloop.c index f4df9cc..a953902 100644 --- a/crypto/openssh/serverloop.c +++ b/crypto/openssh/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.106 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.110 2003/06/24 08:23:46 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -158,7 +158,7 @@ sigchld_handler(int sig) static void make_packets_from_stderr_data(void) { - int len; + u_int len; /* Send buffered stderr data to the client. */ while (buffer_len(&stderr_buffer) > 0 && @@ -187,7 +187,7 @@ make_packets_from_stderr_data(void) static void make_packets_from_stdout_data(void) { - int len; + u_int len; /* Send buffered stdout data to the client. */ while (buffer_len(&stdout_buffer) > 0 && @@ -771,8 +771,14 @@ server_loop2(Authctxt *authctxt) &nalloc, 0); collect_children(); - if (!rekeying) + if (!rekeying) { channel_after_select(readset, writeset); + if (packet_need_rekeying()) { + debug("need rekeying"); + xxx_kex->done = 0; + kex_send_kexinit(xxx_kex); + } + } process_input(readset); if (connection_closed) break; @@ -874,7 +880,7 @@ server_request_direct_tcpip(char *ctype) return NULL; c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, - CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1); + CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1); return c; } @@ -893,7 +899,7 @@ 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); + 0, "server-session", 1); if (session_open(xxx_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); channel_free(c); @@ -971,7 +977,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) pw = auth_get_user(); if (pw == NULL) fatal("server_input_global_request: no user"); - listen_address = packet_get_string(NULL); /* XXX currently ignored */ + listen_address = packet_get_string(NULL); listen_port = (u_short)packet_get_int(); debug("server_input_global_request: tcpip-forward listen %s port %d", listen_address, listen_port); diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c index c75fea9..2898ac5 100644 --- a/crypto/openssh/session.c +++ b/crypto/openssh/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -58,10 +58,8 @@ RCSID("$OpenBSD: session.c,v 1.154 2003/03/05 22:33:43 markus Exp $"); #include "session.h" #include "monitor_wrap.h" -#ifdef HAVE_CYGWIN -#include <windows.h> -#include <sys/cygwin.h> -#define is_winnt (GetVersion() < 0x80000000) +#ifdef GSSAPI +#include "ssh-gss.h" #endif /* func */ @@ -95,6 +93,7 @@ extern int debug_flag; extern u_int utmp_len; extern int startup_pipe; extern void destroy_sensitive_data(void); +extern Buffer loginmsg; /* original command from peer. */ const char *original_command = NULL; @@ -103,10 +102,6 @@ const char *original_command = NULL; #define MAX_SESSIONS 10 Session sessions[MAX_SESSIONS]; -#ifdef WITH_AIXAUTHENTICATE -char *aixloginmsg; -#endif /* WITH_AIXAUTHENTICATE */ - #ifdef HAVE_LOGIN_CAP login_cap_t *lc; #endif @@ -192,7 +187,7 @@ auth_input_request_forwarding(struct passwd * pw) nc = channel_new("auth socket", SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, - 0, xstrdup("auth socket"), 1); + 0, "auth socket", 1); strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); return 1; } @@ -225,10 +220,6 @@ do_authenticated(Authctxt *authctxt) /* remove agent socket */ if (auth_sock_name != NULL) auth_sock_cleanup_proc(authctxt->pw); -#ifdef KRB4 - if (options.kerberos_ticket_cleanup) - krb4_cleanup_proc(authctxt); -#endif #ifdef KRB5 if (options.kerberos_ticket_cleanup) krb5_cleanup_proc(authctxt); @@ -341,58 +332,6 @@ do_authenticated1(Authctxt *authctxt) 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_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 - verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user); -#endif /* KRB5 */ - } else { -#ifdef AFS - if (auth_krb4_tgt(s->authctxt, kdata)) - success = 1; - else - verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user); -#endif /* AFS */ - } - xfree(kdata); - } - break; -#endif /* AFS || KRB5 */ - -#ifdef AFS - case SSH_CMSG_HAVE_AFS_TOKEN: - if (!options.afs_token_passing || !k_hasafs()) { - verbose("AFS token passing disabled."); - } else { - /* Accept AFS token. */ - char *token = packet_get_string(&dlen); - packet_check_eom(); - - if (auth_afs_token(s->authctxt, token)) - success = 1; - else - verbose("AFS token refused for %.100s", - s->authctxt->user); - xfree(token); - } - break; -#endif /* AFS */ - case SSH_CMSG_EXEC_SHELL: case SSH_CMSG_EXEC_CMD: if (type == SSH_CMSG_EXEC_CMD) { @@ -412,7 +351,7 @@ do_authenticated1(Authctxt *authctxt) * Any unknown messages in this phase are ignored, * and a failure message is returned. */ - log("Unknown packet type received after authentication: %d", type); + logit("Unknown packet type received after authentication: %d", type); } packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); packet_send(); @@ -456,11 +395,12 @@ do_exec_no_pty(Session *s, const char *command) session_proctitle(s); #if defined(USE_PAM) - do_pam_session(s->pw->pw_name, NULL); - do_pam_setcred(1); - if (is_pam_password_change_required()) - packet_disconnect("Password change required but no " - "TTY available"); + if (options.use_pam) { + do_pam_setcred(1); + if (is_pam_password_change_required()) + packet_disconnect("Password change required but no " + "TTY available"); + } #endif /* USE_PAM */ /* Fork the child. */ @@ -583,8 +523,10 @@ do_exec_pty(Session *s, const char *command) ttyfd = s->ttyfd; #if defined(USE_PAM) - do_pam_session(s->pw->pw_name, s->tty); - do_pam_setcred(1); + if (options.use_pam) { + do_pam_set_tty(s->tty); + do_pam_setcred(1); + } #endif /* Fork the child. */ @@ -690,7 +632,7 @@ do_pre_login(Session *s) } record_utmp_only(pid, s->tty, s->pw->pw_name, - get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), + get_remote_name_or_ip(utmp_len, options.use_dns), (struct sockaddr *)&from, fromlen); } #endif @@ -708,6 +650,14 @@ do_exec(Session *s, const char *command) debug("Forced command '%.900s'", command); } +#ifdef GSSAPI + if (options.gss_authentication) { + temporarily_use_uid(s->pw); + ssh_gssapi_storecreds(); + restore_uid(); + } +#endif + if (s->ttyfd != -1) do_exec_pty(s, command); else @@ -745,7 +695,7 @@ do_login(Session *s, const char *command) if (!use_privsep) record_login(pid, s->tty, pw->pw_name, pw->pw_uid, get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping), + options.use_dns), (struct sockaddr *)&from, fromlen); #ifdef USE_PAM @@ -753,9 +703,10 @@ do_login(Session *s, const char *command) * If password change is needed, do it now. * This needs to occur before the ~/.hushlogin check. */ - if (is_pam_password_change_required()) { + if (options.use_pam && is_pam_password_change_required()) { print_pam_messages(); do_pam_chauthtok(); + /* XXX - signal [net] parent to enable forwardings */ } #endif @@ -763,13 +714,16 @@ do_login(Session *s, const char *command) return; #ifdef USE_PAM - if (!is_pam_password_change_required()) + if (options.use_pam && !is_pam_password_change_required()) print_pam_messages(); #endif /* USE_PAM */ -#ifdef WITH_AIXAUTHENTICATE - if (aixloginmsg && *aixloginmsg) - printf("%s\n", aixloginmsg); -#endif /* WITH_AIXAUTHENTICATE */ + + /* display post-login message */ + if (buffer_len(&loginmsg) > 0) { + buffer_append(&loginmsg, "\0", 1); + printf("%s\n", (char *)buffer_ptr(&loginmsg)); + } + buffer_free(&loginmsg); #ifndef NO_SSH_LASTLOG if (options.print_lastlog && s->last_login_time != 0) { @@ -840,12 +794,23 @@ check_quietlogin(Session *s, const char *command) * Sets the value of the given variable in the environment. If the variable * already exists, its value is overriden. */ -static void +void child_set_env(char ***envp, u_int *envsizep, const char *name, const char *value) { - u_int i, namelen; char **env; + u_int envsize; + u_int i, namelen; + + /* + * If we're passed an uninitialized list, allocate a single null + * entry before continuing. + */ + if (*envp == NULL && *envsizep == 0) { + *envp = xmalloc(sizeof(char *)); + *envp[0] = NULL; + *envsizep = 1; + } /* * Find the slot where the value should be stored. If the variable @@ -862,12 +827,13 @@ child_set_env(char ***envp, u_int *envsizep, const char *name, xfree(env[i]); } else { /* New variable. Expand if necessary. */ - if (i >= (*envsizep) - 1) { - if (*envsizep >= 1000) - fatal("child_set_env: too many env vars," - " skipping: %.100s", name); - (*envsizep) += 50; - env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *)); + envsize = *envsizep; + if (i >= envsize - 1) { + if (envsize >= 1000) + fatal("child_set_env: too many env vars"); + envsize += 50; + env = (*envp) = xrealloc(env, envsize * sizeof(char *)); + *envsizep = envsize; } /* Need to set the NULL pointer at end of array beyond the new slot. */ env[i + 1] = NULL; @@ -923,6 +889,61 @@ read_environment_file(char ***env, u_int *envsize, fclose(f); } +#ifdef HAVE_ETC_DEFAULT_LOGIN +/* + * Return named variable from specified environment, or NULL if not present. + */ +static char * +child_get_env(char **env, const char *name) +{ + int i; + size_t len; + + len = strlen(name); + for (i=0; env[i] != NULL; i++) + if (strncmp(name, env[i], len) == 0 && env[i][len] == '=') + return(env[i] + len + 1); + return NULL; +} + +/* + * Read /etc/default/login. + * We pick up the PATH (or SUPATH for root) and UMASK. + */ +static void +read_etc_default_login(char ***env, u_int *envsize, uid_t uid) +{ + char **tmpenv = NULL, *var; + u_int i, tmpenvsize = 0; + mode_t mask; + + /* + * We don't want to copy the whole file to the child's environment, + * so we use a temporary environment and copy the variables we're + * interested in. + */ + read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login"); + + if (tmpenv == NULL) + return; + + if (uid == 0) + var = child_get_env(tmpenv, "SUPATH"); + else + var = child_get_env(tmpenv, "PATH"); + if (var != NULL) + child_set_env(env, envsize, "PATH", var); + + if ((var = child_get_env(tmpenv, "UMASK")) != NULL) + if (sscanf(var, "%5lo", &mask) == 1) + umask(mask); + + for (i = 0; tmpenv[i] != NULL; i++) + xfree(tmpenv[i]); + xfree(tmpenv); +} +#endif /* HAVE_ETC_DEFAULT_LOGIN */ + void copy_environment(char **source, char ***env, u_int *envsize) { char *var_name, *var_val; @@ -951,7 +972,7 @@ do_setup_env(Session *s, const char *shell) { char buf[256]; u_int i, envsize; - char **env, *laddr; + char **env, *laddr, *path = NULL; struct passwd *pw = s->pw; /* Initialize the environment. */ @@ -967,6 +988,13 @@ do_setup_env(Session *s, const char *shell) copy_environment(environ, &env, &envsize); #endif +#ifdef GSSAPI + /* Allow any GSSAPI methods that we've used to alter + * the childs environment as they see fit + */ + ssh_gssapi_do_child(&env, &envsize); +#endif + if (!options.use_login) { /* Set basic environment. */ child_set_env(&env, &envsize, "USER", pw->pw_name); @@ -988,12 +1016,15 @@ do_setup_env(Session *s, const char *shell) * needed for loading shared libraries. So the path better * remains intact here. */ -# ifdef SUPERUSER_PATH - child_set_env(&env, &envsize, "PATH", - s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH); -# else - child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); -# endif /* SUPERUSER_PATH */ +# ifdef HAVE_ETC_DEFAULT_LOGIN + read_etc_default_login(&env, &envsize, pw->pw_uid); + path = child_get_env(env, "PATH"); +# endif /* HAVE_ETC_DEFAULT_LOGIN */ + if (path == NULL || *path == '\0') { + child_set_env(&env, &envsize, "PATH", + s->pw->pw_uid == 0 ? + SUPERUSER_PATH : _PATH_STDPATH); + } # endif /* HAVE_CYGWIN */ #endif /* HAVE_LOGIN_CAP */ @@ -1062,11 +1093,6 @@ do_setup_env(Session *s, const char *shell) read_environment_file(&env, &envsize, "/etc/environment"); } #endif -#ifdef KRB4 - if (s->authctxt->krb4_ticket_file) - child_set_env(&env, &envsize, "KRBTKFILE", - s->authctxt->krb4_ticket_file); -#endif #ifdef KRB5 if (s->authctxt->krb5_ticket_file) child_set_env(&env, &envsize, "KRB5CCNAME", @@ -1077,10 +1103,9 @@ do_setup_env(Session *s, const char *shell) * Pull in any environment variables that may have * been set by PAM. */ - { - char **p; + if (options.use_pam) { + char **p = fetch_pam_environment(); - p = fetch_pam_environment(); copy_environment(p, &env, &envsize); free_pam_environment(p); } @@ -1192,7 +1217,7 @@ do_nologin(struct passwd *pw) #endif if (f) { /* /etc/nologin exists. Print its contents and exit. */ - log("User %.100s not allowed because %s exists", + logit("User %.100s not allowed because %s exists", pw->pw_name, _PATH_NOLOGIN); while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); @@ -1212,7 +1237,8 @@ do_setusercontext(struct passwd *pw) { #ifdef HAVE_SETPCRED - setpcred(pw->pw_name); + if (setpcred(pw->pw_name, (char **)NULL) == -1) + fatal("Failed to set process credentials"); #endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP # ifdef __bsdi__ @@ -1248,7 +1274,10 @@ do_setusercontext(struct passwd *pw) * These will have been wiped by the above initgroups() call. * Reestablish them here. */ - do_pam_setcred(0); + if (options.use_pam) { + do_pam_session(); + do_pam_setcred(0); + } # endif /* USE_PAM */ # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) irix_setusercontext(pw); @@ -1349,7 +1378,7 @@ do_child(Session *s, const char *command) /* we have to stash the hostname before we close our socket. */ if (options.use_login) hostname = get_remote_name_or_ip(utmp_len, - options.verify_reverse_mapping); + options.use_dns); /* * Close the connection descriptors; note that this is the child, and * the server will still have the socket open, and it is important @@ -1391,18 +1420,6 @@ do_child(Session *s, const char *command) */ environ = env; -#ifdef AFS - /* 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 */ - /* Change current directory to the user\'s home directory. */ if (chdir(pw->pw_dir) < 0) { fprintf(stderr, "Could not chdir to home directory %s: %s\n", @@ -1672,7 +1689,7 @@ session_subsystem_req(Session *s) int i; packet_check_eom(); - log("subsystem request for %.100s", subsys); + logit("subsystem request for %.100s", subsys); for (i = 0; i < options.num_subsystems; i++) { if (strcmp(subsys, options.subsystem_name[i]) == 0) { @@ -1691,7 +1708,7 @@ session_subsystem_req(Session *s) } if (!success) - log("subsystem request for %.100s failed, subsystem not found", + logit("subsystem request for %.100s failed, subsystem not found", subsys); xfree(subsys); @@ -1739,6 +1756,20 @@ session_exec_req(Session *s) } static int +session_break_req(Session *s) +{ + u_int break_length; + + break_length = packet_get_int(); /* ignored */ + packet_check_eom(); + + if (s->ttyfd == -1 || + tcsendbreak(s->ttyfd, 0) < 0) + return 0; + return 1; +} + +static int session_auth_agent_req(Session *s) { static int called = 0; @@ -1762,7 +1793,7 @@ session_input_channel_req(Channel *c, const char *rtype) Session *s; if ((s = session_by_channel(c->self)) == NULL) { - log("session_input_channel_req: no session %d req %.100s", + logit("session_input_channel_req: no session %d req %.100s", c->self, rtype); return 0; } @@ -1785,6 +1816,8 @@ session_input_channel_req(Channel *c, const char *rtype) success = session_auth_agent_req(s); } else if (strcmp(rtype, "subsystem") == 0) { success = session_subsystem_req(s); + } else if (strcmp(rtype, "break") == 0) { + success = session_break_req(s); } } if (strcmp(rtype, "window-change") == 0) { @@ -2121,4 +2154,8 @@ static void do_authenticated2(Authctxt *authctxt) { server_loop2(authctxt); +#if defined(GSSAPI) + if (options.gss_cleanup_creds) + ssh_gssapi_cleanup_creds(NULL); +#endif } diff --git a/crypto/openssh/session.h b/crypto/openssh/session.h index d3ddfab..525e47f 100644 --- a/crypto/openssh/session.h +++ b/crypto/openssh/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $ */ +/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -68,4 +68,7 @@ Session *session_new(void); Session *session_by_tty(char *); void session_close(Session *); void do_setusercontext(struct passwd *); +void child_set_env(char ***envp, u_int *envsizep, const char *name, + const char *value); + #endif diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c index 3b3279e..ffff0fe 100644 --- a/crypto/openssh/sftp-client.c +++ b/crypto/openssh/sftp-client.c @@ -28,7 +28,7 @@ /* XXX: copy between two remote sites */ #include "includes.h" -RCSID("$OpenBSD: sftp-client.c,v 1.42 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: sftp-client.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $"); #include "openbsd-compat/sys-queue.h" @@ -71,10 +71,10 @@ send_msg(int fd, Buffer *m) /* Send length first */ PUT_32BIT(mlen, buffer_len(m)); - if (atomicio(write, fd, mlen, sizeof(mlen)) <= 0) + if (atomicio(vwrite, fd, mlen, sizeof(mlen)) <= 0) fatal("Couldn't send packet: %s", strerror(errno)); - if (atomicio(write, fd, buffer_ptr(m), buffer_len(m)) <= 0) + if (atomicio(vwrite, fd, buffer_ptr(m), buffer_len(m)) <= 0) fatal("Couldn't send packet: %s", strerror(errno)); buffer_clear(m); @@ -507,7 +507,7 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet) if (quiet) debug("Server version does not support lstat operation"); else - log("Server version does not support lstat operation"); + logit("Server version does not support lstat operation"); return(do_stat(conn, path, quiet)); } @@ -875,7 +875,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path, fatal("Received more data than asked for " "%u > %u", len, req->len); if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || - atomicio(write, local_fd, data, len) != len) && + atomicio(vwrite, local_fd, data, len) != len) && !write_error) { write_errno = errno; write_error = 1; diff --git a/crypto/openssh/sftp-common.c b/crypto/openssh/sftp-common.c index 31d4138..5313b13 100644 --- a/crypto/openssh/sftp-common.c +++ b/crypto/openssh/sftp-common.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sftp-common.c,v 1.8 2002/10/16 14:31:48 itojun Exp $"); +RCSID("$OpenBSD: sftp-common.c,v 1.9 2003/05/24 09:30:40 djm Exp $"); #include "buffer.h" #include "bufaux.h" @@ -206,8 +206,8 @@ ls_file(char *name, struct stat *st, int remote) tbuf[0] = '\0'; ulen = MAX(strlen(user), 8); glen = MAX(strlen(group), 8); - snprintf(buf, sizeof buf, "%s %3d %-*s %-*s %8llu %s %s", mode, - st->st_nlink, ulen, user, glen, group, + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, (unsigned long long)st->st_size, tbuf, name); return xstrdup(buf); } diff --git a/crypto/openssh/sftp-int.c b/crypto/openssh/sftp-int.c index 6987de9..c93eaab 100644 --- a/crypto/openssh/sftp-int.c +++ b/crypto/openssh/sftp-int.c @@ -25,7 +25,7 @@ /* XXX: recursive operations */ #include "includes.h" -RCSID("$OpenBSD: sftp-int.c,v 1.57 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: sftp-int.c,v 1.62 2003/08/25 08:13:09 fgsch Exp $"); #include "buffer.h" #include "xmalloc.h" @@ -53,6 +53,10 @@ int showprogress = 1; /* Seperators for interactive commands */ #define WHITESPACE " \t\r\n" +/* Define what type of ls view (0 - multi-column) */ +#define LONG_VIEW 1 /* Full view ala ls -l */ +#define SHORT_VIEW 2 /* Single row view ala ls -1 */ + /* Commands for interactive mode */ #define I_CHDIR 1 #define I_CHGRP 2 @@ -307,7 +311,10 @@ parse_ls_flags(const char **cpp, int *lflag) for(; strchr(WHITESPACE, *cp) == NULL; cp++) { switch (*cp) { case 'l': - *lflag = 1; + *lflag = LONG_VIEW; + break; + case '1': + *lflag = SHORT_VIEW; break; default: error("Invalid flag -%c", *cp); @@ -325,7 +332,7 @@ get_pathname(const char **cpp, char **path) { const char *cp = *cpp, *end; char quot; - int i; + int i, j; cp += strspn(cp, WHITESPACE); if (!*cp) { @@ -334,37 +341,55 @@ get_pathname(const char **cpp, char **path) return (0); } + *path = xmalloc(strlen(cp) + 1); + /* Check for quoted filenames */ if (*cp == '\"' || *cp == '\'') { quot = *cp++; - end = strchr(cp, quot); - if (end == NULL) { - error("Unterminated quote"); - goto fail; + /* Search for terminating quote, unescape some chars */ + for (i = j = 0; i <= strlen(cp); i++) { + if (cp[i] == quot) { /* Found quote */ + (*path)[j] = '\0'; + i++; + break; + } + if (cp[i] == '\0') { /* End of string */ + error("Unterminated quote"); + goto fail; + } + if (cp[i] == '\\') { /* Escaped characters */ + i++; + if (cp[i] != '\'' && cp[i] != '\"' && + cp[i] != '\\') { + error("Bad escaped character '\%c'", + cp[i]); + goto fail; + } + } + (*path)[j++] = cp[i]; } - if (cp == end) { + + if (j == 0) { error("Empty quotes"); goto fail; } - *cpp = end + 1 + strspn(end + 1, WHITESPACE); + *cpp = cp + i + strspn(cp + i, WHITESPACE); } else { /* Read to end of filename */ end = strpbrk(cp, WHITESPACE); if (end == NULL) end = strchr(cp, '\0'); *cpp = end + strspn(end, WHITESPACE); - } - i = end - cp; - - *path = xmalloc(i + 1); - memcpy(*path, cp, i); - (*path)[i] = '\0'; - return(0); + memcpy(*path, cp, end - cp); + (*path)[end - cp] = '\0'; + } + return (0); fail: - *path = NULL; + xfree(*path); + *path = NULL; return (-1); } @@ -425,29 +450,8 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) goto out; } - /* Only one match, dst may be file, directory or unspecified */ - if (g.gl_pathv[0] && g.gl_matchc == 1) { - if (dst) { - /* If directory specified, append filename */ - if (is_dir(dst)) { - if (infer_path(g.gl_pathv[0], &tmp)) { - err = 1; - goto out; - } - abs_dst = path_append(dst, tmp); - xfree(tmp); - } else - abs_dst = xstrdup(dst); - } else if (infer_path(g.gl_pathv[0], &abs_dst)) { - err = -1; - goto out; - } - err = do_download(conn, g.gl_pathv[0], abs_dst, pflag); - goto out; - } - - /* Multiple matches, dst may be directory or unspecified */ - if (dst && !is_dir(dst)) { + /* If multiple matches, dst must be a directory or unspecified */ + if (g.gl_matchc > 1 && dst && !is_dir(dst)) { error("Multiple files match, but \"%s\" is not a directory", dst); err = -1; @@ -459,7 +463,19 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) err = -1; goto out; } - if (dst) { + + if (g.gl_matchc == 1 && dst) { + /* If directory specified, append filename */ + if (is_dir(dst)) { + if (infer_path(g.gl_pathv[0], &tmp)) { + err = 1; + goto out; + } + abs_dst = path_append(dst, tmp); + xfree(tmp); + } else + abs_dst = xstrdup(dst); + } else if (dst) { abs_dst = path_append(dst, tmp); xfree(tmp); } else @@ -503,38 +519,8 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) goto out; } - /* Only one match, dst may be file, directory or unspecified */ - if (g.gl_pathv[0] && g.gl_matchc == 1) { - if (!is_reg(g.gl_pathv[0])) { - error("Can't upload %s: not a regular file", - g.gl_pathv[0]); - err = 1; - goto out; - } - if (tmp_dst) { - /* If directory specified, append filename */ - if (remote_is_dir(conn, tmp_dst)) { - if (infer_path(g.gl_pathv[0], &tmp)) { - err = 1; - goto out; - } - abs_dst = path_append(tmp_dst, tmp); - xfree(tmp); - } else - abs_dst = xstrdup(tmp_dst); - } else { - if (infer_path(g.gl_pathv[0], &abs_dst)) { - err = -1; - goto out; - } - abs_dst = make_absolute(abs_dst, pwd); - } - 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(conn, tmp_dst)) { + /* If multiple matches, dst may be directory or unspecified */ + if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) { error("Multiple files match, but \"%s\" is not a directory", tmp_dst); err = -1; @@ -551,7 +537,20 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) err = -1; goto out; } - if (tmp_dst) { + + if (g.gl_matchc == 1 && tmp_dst) { + /* If directory specified, append filename */ + if (remote_is_dir(conn, tmp_dst)) { + if (infer_path(g.gl_pathv[0], &tmp)) { + err = 1; + goto out; + } + abs_dst = path_append(tmp_dst, tmp); + xfree(tmp); + } else + abs_dst = xstrdup(tmp_dst); + + } else if (tmp_dst) { abs_dst = path_append(tmp_dst, tmp); xfree(tmp); } else @@ -567,6 +566,7 @@ out: xfree(abs_dst); if (tmp_dst) xfree(tmp_dst); + globfree(&g); return(err); } @@ -583,15 +583,27 @@ sdirent_comp(const void *aa, const void *bb) static int do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { - int n; + int n, c = 1, colspace = 0, columns = 1; SFTP_DIRENT **d; if ((n = do_readdir(conn, path, &d)) != 0) return (n); - /* Count entries for sort */ - for (n = 0; d[n] != NULL; n++) - ; + if (!(lflag & SHORT_VIEW)) { + int m = 0, width = 80; + struct winsize ws; + + /* Count entries for sort and find longest filename */ + for (n = 0; d[n] != NULL; n++) + m = MAX(m, strlen(d[n]->filename)); + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) + width = ws.ws_col; + + columns = width / (m + 2); + columns = MAX(columns, 1); + colspace = width / columns; + } qsort(d, n, sizeof(*d), sdirent_comp); @@ -602,7 +614,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) fname = path_strip(tmp, strip_path); xfree(tmp); - if (lflag) { + if (lflag & LONG_VIEW) { char *lname; struct stat sb; @@ -612,13 +624,20 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) printf("%s\n", lname); xfree(lname); } else { - /* XXX - multicolumn display would be nice here */ - printf("%s\n", fname); + printf("%-*s", colspace, fname); + if (c >= columns) { + printf("\n"); + c = 1; + } else + c++; } xfree(fname); } + if (!(lflag & LONG_VIEW) && (c != 1)) + printf("\n"); + free_sftp_dirents(d); return (0); } @@ -629,9 +648,8 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { glob_t g; - int i; + int i, c = 1, colspace = 0, columns = 1; Attrib *a; - struct stat sb; memset(&g, 0, sizeof(g)); @@ -658,12 +676,31 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, } } + if (!(lflag & SHORT_VIEW)) { + int m = 0, width = 80; + struct winsize ws; + + /* Count entries for sort and find longest filename */ + for (i = 0; g.gl_pathv[i]; i++) + m = MAX(m, strlen(g.gl_pathv[i])); + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) + width = ws.ws_col; + + columns = width / (m + 2); + columns = MAX(columns, 1); + colspace = width / columns; + } + for (i = 0; g.gl_pathv[i]; i++) { - char *fname, *lname; + char *fname; fname = path_strip(g.gl_pathv[i], strip_path); - if (lflag) { + if (lflag & LONG_VIEW) { + char *lname; + struct stat sb; + /* * XXX: this is slow - 1 roundtrip per path * A solution to this is to fork glob() and @@ -679,12 +716,19 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, printf("%s\n", lname); xfree(lname); } else { - /* XXX - multicolumn display would be nice here */ - printf("%s\n", fname); + printf("%-*s", colspace, fname); + if (c >= columns) { + printf("\n"); + c = 1; + } else + c++; } xfree(fname); } + if (!(lflag & LONG_VIEW) && (c != 1)) + printf("\n"); + if (g.gl_pathc) globfree(&g); diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8 index 0a0210a..871f837 100644 --- a/crypto/openssh/sftp-server.8 +++ b/crypto/openssh/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.8 2001/06/23 05:57:08 deraadt Exp $ +.\" $OpenBSD: sftp-server.8,v 1.9 2003/06/10 09:12:11 jmc Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -56,7 +56,7 @@ for more information. .%O work in progress material .Re .Sh AUTHORS -Markus Friedl <markus@openbsd.org> +.An Markus Friedl Aq markus@openbsd.org .Sh HISTORY .Nm first appeared in OpenBSD 2.8 . diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c index 9a66b4d..9166853 100644 --- a/crypto/openssh/sftp-server.c +++ b/crypto/openssh/sftp-server.c @@ -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.41 2003/03/26 04:02:51 deraadt Exp $"); +RCSID("$OpenBSD: sftp-server.c,v 1.43 2003/06/25 22:39:36 miod Exp $"); #include "buffer.h" #include "bufaux.h" @@ -52,7 +52,7 @@ Buffer oqueue; /* Version of client */ int version; -/* portable attibutes, etc. */ +/* portable attributes, etc. */ typedef struct Stat Stat; @@ -442,7 +442,7 @@ process_read(void) (u_int64_t)off, len); if (len > sizeof buf) { len = sizeof buf; - log("read change len %d", len); + logit("read change len %d", len); } fd = handle_to_fd(handle); if (fd >= 0) { @@ -495,7 +495,7 @@ process_write(void) } else if (ret == len) { status = SSH2_FX_OK; } else { - log("nothing at all written"); + logit("nothing at all written"); } } } @@ -1030,7 +1030,7 @@ main(int ac, char **av) /* XXX should use getopt */ - __progname = get_progname(av[0]); + __progname = ssh_get_progname(av[0]); handle_init(); #ifdef DEBUG_SFTP_SERVER diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1 index 02d2c27..753a4f2 100644 --- a/crypto/openssh/sftp.1 +++ b/crypto/openssh/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.41 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: sftp.1,v 1.45 2003/09/02 18:50:06 jmc Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -27,7 +27,7 @@ .Os .Sh NAME .Nm sftp -.Nd Secure file transfer program +.Nd secure file transfer program .Sh SYNOPSIS .Nm sftp .Bk -words @@ -43,13 +43,16 @@ .Ar host .Ek .Nm sftp -.Oo Oo Ar user Ns No @ Oc Ns +.Oo Oo Ar user Ns @ Oc Ns .Ar host Ns Oo : Ns Ar file Oo .Ar file Oc Oc Oc .Nm sftp -.Oo Oo Ar user Ns No @ Oc Ns +.Oo Oo Ar user Ns @ Oc Ns .Ar host Ns Oo : Ns Ar dir Ns .Oo Ar / Oc Oc Oc +.Nm sftp +.Fl b Ar batchfile +.Oo Ar user Ns @ Oc Ns Ar host .Sh DESCRIPTION .Nm is an interactive file transfer program, similar to @@ -68,8 +71,17 @@ The second usage format will retrieve files automatically if a non-interactive authentication method is used; otherwise it will do so after successful interactive authentication. .Pp -The last usage format allows the sftp client to start in a remote directory. +The third usage format allows the sftp client to start in a remote directory. .Pp +The final usage format allows for automated sessions using the +.Fl b +option. +In such cases, it is usually necessary to configure public key authentication +to obviate the need to enter a password at connection time (see +.Xr sshd 8 +and +.Xr ssh-keygen 1 +for details). The options are as follows: .Bl -tag -width Ds .It Fl b Ar batchfile @@ -89,10 +101,9 @@ and .Ic lmkdir . Termination on error can be suppressed on a command by command basis by prefixing the command with a -.Ic '-' -character (For example, -.Ic -rm /tmp/blah* -). +.Sq Ic \- +character (for example, +.Ic -rm /tmp/blah* ) . .It Fl o Ar ssh_option Can be used to pass options to .Nm ssh @@ -101,22 +112,27 @@ in the format used in This is useful for specifying options for which there is no separate .Nm sftp -command-line flag. For example, to specify an alternate -port use: +command-line flag. +For example, to specify an alternate port use: .Ic sftp -oPort=24 . .It Fl s Ar subsystem | sftp_server Specifies the SSH2 subsystem or the path for an sftp server -on the remote host. A path is useful for using sftp over -protocol version 1, or when the remote -.Nm sshd +on the remote host. +A path is useful for using +.Nm +over protocol version 1, or when the remote +.Xr sshd 8 does not have an sftp subsystem configured. .It Fl v -Raise logging level. This option is also passed to ssh. +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. +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 @@ -124,19 +140,19 @@ flag). .It Fl F Ar ssh_config Specifies an alternative per-user configuration file for -.Nm ssh . +.Xr ssh 1 . This option is directly passed to .Xr ssh 1 . .It Fl P Ar sftp_server path -Connect directly to a local -.Nm sftp-server +Connect directly to a local sftp server (rather than via -.Nm ssh ) +.Xr ssh 1 ) 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. +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 @@ -156,7 +172,8 @@ Commands are case insensitive and pathnames may be enclosed in quotes if they contain spaces. .Bl -tag -width Ds .It Ic bye -Quit sftp. +Quit +.Nm sftp . .It Ic cd Ar path Change remote directory to .Ar path . @@ -183,7 +200,8 @@ to .Ar own must be a numeric UID. .It Ic exit -Quit sftp. +Quit +.Nm sftp . .It Xo Ic get .Op Ar flags .Ar remote-path @@ -194,7 +212,8 @@ Retrieve the and store it on the local machine. If the local path name is not specified, it is given the same name it has on the -remote machine. If the +remote machine. +If the .Fl P flag is specified, then the file's full permission and access time are copied too. @@ -224,7 +243,8 @@ Display remote directory listing of either .Ar path or current directory if .Ar path -is not specified. If the +is not specified. +If the .Fl l flag is specified, then display additional details including permissions and ownership information. @@ -243,15 +263,18 @@ Toggle display of progress meter. .Xc Upload .Ar local-path -and store it on the remote machine. If the remote path name is not -specified, it is given the same name it has on the local machine. If the +and store it on the remote machine. +If the remote path name is not specified, it is given the same name it has +on the local machine. +If the .Fl P flag is specified, then the file's full permission and access time are copied too. .It Ic pwd Display remote working directory. .It Ic quit -Quit sftp. +Quit +.Nm sftp . .It Ic rename Ar oldpath Ar newpath Rename remote file from .Ar oldpath @@ -272,17 +295,15 @@ to Display the .Nm protocol version. -.It Ic ! Ar command +.It Ic \&! Ar command Execute .Ar command in local shell. -.It Ic ! +.It Ic \&! Escape to local shell. -.It Ic ? +.It Ic \&? Synonym for help. .El -.Sh AUTHORS -Damien Miller <djm@mindrot.org> .Sh SEE ALSO .Xr scp 1 , .Xr ssh 1 , diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c index e8adcba..c2a6593 100644 --- a/crypto/openssh/sftp.c +++ b/crypto/openssh/sftp.c @@ -24,9 +24,7 @@ #include "includes.h" -RCSID("$OpenBSD: sftp.c,v 1.34 2003/01/10 08:19:07 fgsch Exp $"); - -/* XXX: short-form remote directory listings (like 'ls -C') */ +RCSID("$OpenBSD: sftp.c,v 1.37 2003/07/10 20:05:55 markus Exp $"); #include "buffer.h" #include "xmalloc.h" @@ -48,11 +46,21 @@ char *__progname; FILE* infile; size_t copy_buffer_len = 32768; size_t num_requests = 16; +static pid_t sshpid = -1; extern int showprogress; static void -connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid) +killchild(int signo) +{ + if (sshpid > 1) + kill(sshpid, signo); + + _exit(1); +} + +static void +connect_to_server(char *path, char **args, int *in, int *out) { int c_in, c_out; @@ -74,9 +82,9 @@ connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid) c_in = c_out = inout[1]; #endif /* USE_PIPES */ - if ((*sshpid = fork()) == -1) + if ((sshpid = fork()) == -1) fatal("fork: %s", strerror(errno)); - else if (*sshpid == 0) { + else if (sshpid == 0) { if ((dup2(c_in, STDIN_FILENO) == -1) || (dup2(c_out, STDOUT_FILENO) == -1)) { fprintf(stderr, "dup2: %s\n", strerror(errno)); @@ -91,6 +99,9 @@ connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid) exit(1); } + signal(SIGTERM, killchild); + signal(SIGINT, killchild); + signal(SIGHUP, killchild); close(c_in); close(c_out); } @@ -101,8 +112,9 @@ usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-vC1] [-b batchfile] [-o option] [-s subsystem|path] [-B buffer_size]\n" - " [-F config] [-P direct server path] [-S program]\n" + "usage: %s [-vC1] [-b batchfile] [-o ssh_option] [-s subsystem | sftp_server]\n" + " [-B buffer_size] [-F ssh_config] [-P sftp_server path]\n" + " [-R num_requests] [-S program]\n" " [user@]host[:file [file]]\n", __progname); exit(1); } @@ -111,7 +123,6 @@ int main(int argc, char **argv) { int in, out, ch, err; - pid_t sshpid; char *host, *userhost, *cp, *file2; int debug_level = 0, sshver = 2; char *file1 = NULL, *sftp_server = NULL; @@ -121,7 +132,7 @@ main(int argc, char **argv) extern int optind; extern char *optarg; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-oForwardX11 no"); @@ -229,15 +240,13 @@ main(int argc, char **argv) args.list[0] = ssh_program; fprintf(stderr, "Connecting to %s...\n", host); - connect_to_server(ssh_program, args.list, &in, &out, - &sshpid); + connect_to_server(ssh_program, args.list, &in, &out); } else { args.list = NULL; addargs(&args, "sftp-server"); fprintf(stderr, "Attaching to %s...\n", sftp_direct); - connect_to_server(sftp_direct, args.list, &in, &out, - &sshpid); + connect_to_server(sftp_direct, args.list, &in, &out); } err = interactive_loop(in, out, file1, file2); diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1 index bcdb8e7..fe01908 100644 --- a/crypto/openssh/ssh-add.1 +++ b/crypto/openssh/ssh-add.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-add.1,v 1.38 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh-add.1,v 1.39 2003/06/10 09:12:11 jmc Exp $ .\" .\" -*- nroff -*- .\" @@ -109,20 +109,6 @@ Add key in smartcard Remove key in smartcard .Ar reader . .El -.Sh FILES -.Bl -tag -width Ds -.It Pa $HOME/.ssh/identity -Contains the protocol version 1 RSA authentication identity of the user. -.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" @@ -152,11 +138,30 @@ to make this work.) Identifies the path of a unix-domain socket used to communicate with the agent. .El +.Sh FILES +.Bl -tag -width Ds +.It Pa $HOME/.ssh/identity +Contains the protocol version 1 RSA authentication identity of the user. +.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 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 SEE ALSO +.Xr ssh 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. @@ -166,8 +171,3 @@ removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -.Sh SEE ALSO -.Xr ssh 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 , -.Xr sshd 8 diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c index 9adec30..2e394e5 100644 --- a/crypto/openssh/ssh-add.c +++ b/crypto/openssh/ssh-add.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-add.c,v 1.66 2003/03/05 22:33:43 markus Exp $"); +RCSID("$OpenBSD: ssh-add.c,v 1.68 2003/06/16 10:22:45 markus Exp $"); #include <openssl/evp.h> @@ -164,7 +164,8 @@ add_file(AuthenticationConnection *ac, const char *filename) if (private != NULL) break; clear_pass(); - strlcpy(msg, "Bad passphrase, try again: ", sizeof msg); + snprintf(msg, sizeof msg, + "Bad passphrase, try again for %.200s: ", comment); } } @@ -201,7 +202,7 @@ update_card(AuthenticationConnection *ac, int add, const char *id) if (pin == NULL) return -1; - if (ssh_update_card(ac, add, id, pin)) { + if (ssh_update_card(ac, add, id, pin, lifetime, confirm)) { fprintf(stderr, "Card %s: %s\n", add ? "added" : "removed", id); ret = 0; @@ -318,7 +319,7 @@ main(int argc, char **argv) char *sc_reader_id = NULL; int i, ch, deleting = 0, ret = 0; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); init_rng(); seed_rng(); diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1 index fde4608..aab15cc 100644 --- a/crypto/openssh/ssh-agent.1 +++ b/crypto/openssh/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.37 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.39 2003/06/10 09:12:11 jmc Exp $ .\" .\" Author: Tatu Ylonen <ylo@cs.hut.fi> .\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -133,7 +133,7 @@ However, the connection to the agent is forwarded over SSH remote logins, and the user can thus use the privileges given by the identities anywhere in the network in a secure way. .Pp -There are two main ways to get an agent setup: +There are two main ways to get an agent set up: Either the agent starts a new subcommand into which some environment variables are exported, or the agent prints the needed shell commands (either @@ -179,6 +179,11 @@ authentication agent. These sockets should only be readable by the owner. The sockets should get automatically removed when the agent exits. .El +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. @@ -188,8 +193,3 @@ removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -.Sh SEE ALSO -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-keygen 1 , -.Xr sshd 8 diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c index eb593de..e1e6cae 100644 --- a/crypto/openssh/ssh-agent.c +++ b/crypto/openssh/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.108 2003/03/13 11:44:50 markus Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.112 2003/09/18 08:49:45 markus Exp $"); #include <openssl/evp.h> #include <openssl/md5.h> @@ -261,7 +261,7 @@ process_authentication_challenge1(SocketEntry *e) /* The response is MD5 of decrypted challenge plus session id. */ len = BN_num_bytes(challenge); if (len <= 0 || len > 32) { - log("process_authentication_challenge: bad challenge length %d", len); + logit("process_authentication_challenge: bad challenge length %d", len); goto failure; } memset(buf, 0, 32); @@ -350,7 +350,7 @@ process_remove_identity(SocketEntry *e, int version) buffer_get_bignum(&e->request, key->rsa->n); if (bits != key_size(key)) - log("Warning: identity keysize mismatch: actual %u, announced %u", + logit("Warning: identity keysize mismatch: actual %u, announced %u", key_size(key), bits); break; case 2: @@ -580,13 +580,29 @@ static void process_add_smartcard_key (SocketEntry *e) { char *sc_reader_id = NULL, *pin; - int i, version, success = 0; + int i, version, success = 0, death = 0, confirm = 0; Key **keys, *k; Identity *id; Idtab *tab; sc_reader_id = buffer_get_string(&e->request, NULL); pin = buffer_get_string(&e->request, NULL); + + while (buffer_len(&e->request)) { + switch (buffer_get_char(&e->request)) { + case SSH_AGENT_CONSTRAIN_LIFETIME: + death = time(NULL) + buffer_get_int(&e->request); + break; + case SSH_AGENT_CONSTRAIN_CONFIRM: + confirm = 1; + break; + default: + break; + } + } + if (lifetime && !death) + death = time(NULL) + lifetime; + keys = sc_get_keys(sc_reader_id, pin); xfree(sc_reader_id); xfree(pin); @@ -602,9 +618,9 @@ process_add_smartcard_key (SocketEntry *e) if (lookup_identity(k, version) == NULL) { id = xmalloc(sizeof(Identity)); id->key = k; - id->comment = xstrdup("smartcard key"); - id->death = 0; - id->confirm = 0; + id->comment = sc_get_key_label(k); + id->death = death; + id->confirm = confirm; TAILQ_INSERT_TAIL(&tab->idlist, id, next); tab->nentries++; success = 1; @@ -748,6 +764,7 @@ process_message(SocketEntry *e) break; #ifdef SMARTCARD case SSH_AGENTC_ADD_SMARTCARD_KEY: + case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: process_add_smartcard_key(e); break; case SSH_AGENTC_REMOVE_SMARTCARD_KEY: @@ -767,7 +784,7 @@ process_message(SocketEntry *e) static void new_socket(sock_type type, int fd) { - u_int i, old_alloc; + u_int i, old_alloc, new_alloc; if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) error("fcntl O_NONBLOCK: %s", strerror(errno)); @@ -778,25 +795,26 @@ new_socket(sock_type type, int fd) for (i = 0; i < sockets_alloc; i++) if (sockets[i].type == AUTH_UNUSED) { sockets[i].fd = fd; - sockets[i].type = type; buffer_init(&sockets[i].input); buffer_init(&sockets[i].output); buffer_init(&sockets[i].request); + sockets[i].type = type; return; } old_alloc = sockets_alloc; - sockets_alloc += 10; + new_alloc = sockets_alloc + 10; if (sockets) - sockets = xrealloc(sockets, sockets_alloc * sizeof(sockets[0])); + sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0])); else - sockets = xmalloc(sockets_alloc * sizeof(sockets[0])); - for (i = old_alloc; i < sockets_alloc; i++) + sockets = xmalloc(new_alloc * sizeof(sockets[0])); + for (i = old_alloc; i < new_alloc; i++) sockets[i].type = AUTH_UNUSED; - sockets[old_alloc].type = type; + sockets_alloc = new_alloc; sockets[old_alloc].fd = fd; buffer_init(&sockets[old_alloc].input); buffer_init(&sockets[old_alloc].output); buffer_init(&sockets[old_alloc].request); + sockets[old_alloc].type = type; } static int @@ -962,7 +980,7 @@ check_parent_exists(int sig) /* printf("Parent has died - Authentication agent exiting.\n"); */ cleanup_handler(sig); /* safe */ } - signal(SIGALRM, check_parent_exists); + mysignal(SIGALRM, check_parent_exists); alarm(10); errno = save_errno; } @@ -1007,7 +1025,7 @@ main(int ac, char **av) SSLeay_add_all_algorithms(); - __progname = get_progname(av[0]); + __progname = ssh_get_progname(av[0]); init_rng(); seed_rng(); @@ -1194,7 +1212,7 @@ skip: fatal_add_cleanup(cleanup_socket, NULL); new_socket(AUTH_SOCKET, sock); if (ac > 0) { - signal(SIGALRM, check_parent_exists); + mysignal(SIGALRM, check_parent_exists); alarm(10); } idtab_init(); diff --git a/crypto/openssh/ssh-gss.h b/crypto/openssh/ssh-gss.h new file mode 100644 index 0000000..6b58adb --- /dev/null +++ b/crypto/openssh/ssh-gss.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2001-2003 Simon Wilkinson. 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. + */ + +#ifndef _SSH_GSS_H +#define _SSH_GSS_H + +#ifdef GSSAPI + +#include "buffer.h" + +#include <gssapi.h> + +#ifdef KRB5 +#ifndef HEIMDAL +#include <gssapi_generic.h> + +/* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */ + +#ifndef GSS_C_NT_HOSTBASED_SERVICE +#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name +#endif /* GSS_C_NT_... */ +#endif /* !HEIMDAL */ +#endif /* KRB5 */ + +/* draft-ietf-secsh-gsskeyex-06 */ +#define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 +#define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 +#define SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63 +#define SSH2_MSG_USERAUTH_GSSAPI_ERROR 64 +#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65 + +#define SSH_GSS_OIDTYPE 0x06 + +typedef struct { + char *filename; + char *envvar; + char *envval; + void *data; +} ssh_gssapi_ccache; + +typedef struct { + gss_buffer_desc displayname; + gss_buffer_desc exportedname; + gss_cred_id_t creds; + struct ssh_gssapi_mech_struct *mech; + ssh_gssapi_ccache store; +} ssh_gssapi_client; + +typedef struct ssh_gssapi_mech_struct { + char *enc_name; + char *name; + gss_OID_desc oid; + int (*dochild) (ssh_gssapi_client *); + int (*userok) (ssh_gssapi_client *, char *); + int (*localname) (ssh_gssapi_client *, char **); + void (*storecreds) (ssh_gssapi_client *); +} ssh_gssapi_mech; + +typedef struct { + OM_uint32 major; /* both */ + OM_uint32 minor; /* both */ + gss_ctx_id_t context; /* both */ + gss_name_t name; /* both */ + gss_OID oid; /* client */ + gss_cred_id_t creds; /* server */ + gss_name_t client; /* server */ + gss_cred_id_t client_creds; /* server */ +} Gssctxt; + +extern ssh_gssapi_mech *supported_mechs[]; + +int ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len); +void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len); +void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid); +void ssh_gssapi_supported_oids(gss_OID_set *oidset); +ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *ctxt); + +OM_uint32 ssh_gssapi_import_name(Gssctxt *ctx, const char *host); +OM_uint32 ssh_gssapi_acquire_cred(Gssctxt *ctx); +OM_uint32 ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, + gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags); +OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, + gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags); +OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *); +void ssh_gssapi_error(Gssctxt *ctx); +char *ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min); +void ssh_gssapi_build_ctx(Gssctxt **ctx); +void ssh_gssapi_delete_ctx(Gssctxt **ctx); +OM_uint32 ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid); + +/* In the server */ +int ssh_gssapi_userok(char *name); + +void ssh_gssapi_do_child(char ***envp, u_int *envsizep); +void ssh_gssapi_cleanup_creds(void *ignored); +void ssh_gssapi_storecreds(void); + +#endif /* GSSAPI */ + +#endif /* _SSH_GSS_H */ diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1 index 000e8ff..dc4bcac 100644 --- a/crypto/openssh/ssh-keygen.1 +++ b/crypto/openssh/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.56 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.60 2003/07/28 09:49:56 djm Exp $ .\" .\" -*- nroff -*- .\" @@ -83,17 +83,38 @@ .Nm ssh-keygen .Fl U Ar reader .Op Fl f Ar input_keyfile +.Nm ssh-keygen +.Fl r Ar hostname +.Op Fl f Ar input_keyfile +.Op Fl g +.Nm ssh-keygen +.Fl G Ar output_file +.Op Fl b Ar bits +.Op Fl M Ar memory +.Op Fl S Ar start_point +.Nm ssh-keygen +.Fl T Ar output_file +.Fl f Ar input_file +.Op Fl a Ar num_trials +.Op Fl W Ar generator .Sh DESCRIPTION .Nm generates, manages and converts authentication keys for .Xr ssh 1 . .Nm can create RSA keys for use by SSH protocol version 1 and RSA or DSA -keys for use by SSH protocol version 2. The type of key to be generated -is specified with the +keys for use by SSH protocol version 2. +The type of key to be generated is specified with the .Fl t option. .Pp +.Nm +is also used to generate groups for use in Diffie-Hellman group +exchange (DH-GEX). +See the +.Sx MODULI GENERATION +section for details. +.Pp Normally each user wishing to use SSH with RSA or DSA authentication runs this once to create the authentication key in @@ -146,6 +167,11 @@ should be placed to be activated. .Pp The options are as follows: .Bl -tag -width Ds +.It Fl a Ar trials +Specifies the number of primality tests to perform when screening DH-GEX +candidates using the +.Fl T +command. .It Fl b Ar bits Specifies the number of bits in the key to create. Minimum is 512 bits. @@ -163,6 +189,8 @@ print the key in a to stdout. This option allows exporting keys for use by several commercial SSH implementations. +.It Fl g +Use generic DNS resource record format. .It Fl f Ar filename Specifies the filename of the key file. .It Fl i @@ -211,14 +239,88 @@ Provides the new comment. .It Fl D Ar reader Download the RSA public key stored in the smartcard in .Ar reader . +.It Fl G Ar output_file +Generate candidate primes for DH-GEX. +These primes must be screened for +safety (using the +.Fl T +option) before use. +.It Fl M Ar memory +Specify the amount of memory to use (in megabytes) when generating +candidate moduli for DH-GEX. .It Fl N Ar new_passphrase Provides the new passphrase. .It Fl P Ar passphrase Provides the (old) passphrase. +.It Fl S Ar start +Specify start point (in hex) when generating candidate moduli for DH-GEX. +.It Fl T Ar output_file +Test DH group exchange candidate primes (generated using the +.Fl G +option) for safety. +.It Fl W Ar generator +Specify desired generator when testing candidate moduli for DH-GEX. .It Fl U Ar reader Upload an existing RSA private key into the smartcard in .Ar reader . +.It Fl r Ar hostname +Print DNS resource record with the specified +.Ar hostname . .El +.Sh MODULI GENERATION +.Nm +may be used to generate groups for the Diffie-Hellman Group Exchange +(DH-GEX) protocol. +Generating these groups is a two-step process: first, candidate +primes are generated using a fast, but memory intensive process. +These candidate primes are then tested for suitability (a CPU-intensive +process). +.Pp +Generation of primes is performed using the +.Fl G +option. +The desired length of the primes may be specified by the +.Fl b +option. +For example: +.Pp +.Dl ssh-keygen -G moduli-2048.candidates -b 2048 +.Pp +By default, the search for primes begins at a random point in the +desired length range. +This may be overridden using the +.Fl S +option, which specifies a different start point (in hex). +.Pp +Once a set of candidates have been generated, they must be tested for +suitability. +This may be performed using the +.Fl T +option. +In this mode +.Nm +will read candidates from standard input (or a file specified using the +.Fl f +option). +For example: +.Pp +.Dl ssh-keygen -T moduli-2048 -f moduli-2048.candidates +.Pp +By default, each candidate will be subjected to 100 primality tests. +This may be overridden using the +.Fl a +option. +The DH generator value will be chosen automatically for the +prime under consideration. +If a specific generator is desired, it may be requested using the +.Fl W +option. +Valid generator values are 2, 3 and 5. +.Pp +Screened DH groups may be installed in +.Pa /etc/moduli . +It is important that this file contains moduli of a range of bit lengths and +that both ends of a connection share common moduli. .Sh FILES .Bl -tag -width Ds .It Pa $HOME/.ssh/identity @@ -275,20 +377,16 @@ The contents of this file should be added to on all machines where the user wishes to log in using public key authentication. There is no need to keep the contents of this file secret. +.It Pa /etc/moduli +Contains Diffie-Hellman groups used for DH-GEX. +The file format is described in +.Xr moduli 5 . .El -.Sh AUTHORS -OpenSSH is a derivative of the original and free -ssh 1.2.12 release by Tatu Ylonen. -Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, -Theo de Raadt and Dug Song -removed many bugs, re-added newer features and -created OpenSSH. -Markus Friedl contributed the support for SSH -protocol versions 1.5 and 2.0. .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , +.Xr moduli 5 , .Xr sshd 8 .Rs .%A J. Galbraith @@ -298,3 +396,12 @@ protocol versions 1.5 and 2.0. .%D March 2001 .%O work in progress material .Re +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c index 6a872bc..e74d3cd 100644 --- a/crypto/openssh/ssh-keygen.c +++ b/crypto/openssh/ssh-keygen.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keygen.c,v 1.102 2002/11/26 00:45:03 wcobb Exp $"); +RCSID("$OpenBSD: ssh-keygen.c,v 1.108 2003/08/14 16:08:58 markus Exp $"); #include <openssl/evp.h> #include <openssl/pem.h> @@ -27,10 +27,14 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.102 2002/11/26 00:45:03 wcobb Exp $"); #include "pathnames.h" #include "log.h" #include "readpass.h" +#include "moduli.h" #ifdef SMARTCARD #include "scard.h" #endif +#ifdef DNS +#include "dns.h" +#endif /* Number of bits in the RSA/DSA key. This value can be changed on the command line. */ int bits = 1024; @@ -70,6 +74,7 @@ char *identity_comment = NULL; int convert_to_ssh2 = 0; int convert_from_ssh2 = 0; int print_public = 0; +int print_generic = 0; char *key_type_name = NULL; @@ -163,6 +168,10 @@ do_convert_to_ssh2(struct passwd *pw) exit(1); } } + if (k->type == KEY_RSA1) { + fprintf(stderr, "version 1 keys are not supported\n"); + exit(1); + } if (key_to_blob(k, &blob, &len) <= 0) { fprintf(stderr, "key_to_blob failed\n"); exit(1); @@ -415,7 +424,7 @@ do_upload(struct passwd *pw, const char *sc_reader_id) key_free(prv); if (ret < 0) exit(1); - log("loading key done"); + logit("loading key done"); exit(0); } @@ -616,6 +625,38 @@ do_change_passphrase(struct passwd *pw) exit(0); } +#ifdef DNS +/* + * Print the SSHFP RR. + */ +static void +do_print_resource_record(struct passwd *pw, char *hostname) +{ + Key *public; + char *comment = NULL; + struct stat st; + + if (!have_identity) + ask_filename(pw, "Enter file in which the key is"); + if (stat(identity_file, &st) < 0) { + perror(identity_file); + exit(1); + } + public = key_load_public(identity_file, &comment); + if (public != NULL) { + export_dns_rr(hostname, public, stdout, print_generic); + key_free(public); + xfree(comment); + exit(0); + } + if (comment) + xfree(comment); + + printf("failed to read v2 public key from %s.\n", identity_file); + exit(1); +} +#endif /* DNS */ + /* * Change the comment of a private key file. */ @@ -722,6 +763,7 @@ usage(void) fprintf(stderr, " -c Change comment in private and public key files.\n"); fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n"); fprintf(stderr, " -f filename Filename of the key file.\n"); + fprintf(stderr, " -g Use generic DNS resource record format.\n"); fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n"); fprintf(stderr, " -l Show fingerprint of key file.\n"); fprintf(stderr, " -p Change passphrase of private key file.\n"); @@ -732,11 +774,17 @@ usage(void) fprintf(stderr, " -C comment Provide new comment.\n"); fprintf(stderr, " -N phrase Provide new passphrase.\n"); fprintf(stderr, " -P phrase Provide old passphrase.\n"); +#ifdef DNS + fprintf(stderr, " -r hostname Print DNS resource record.\n"); +#endif /* DNS */ #ifdef SMARTCARD fprintf(stderr, " -D reader Download public key from smartcard.\n"); fprintf(stderr, " -U reader Upload private key to smartcard.\n"); #endif /* SMARTCARD */ + fprintf(stderr, " -G file Generate candidates for DH-GEX moduli\n"); + fprintf(stderr, " -T file Screen candidates for DH-GEX moduli\n"); + exit(1); } @@ -747,19 +795,25 @@ int main(int ac, char **av) { char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; - char *reader_id = NULL; + char out_file[MAXPATHLEN], *reader_id = NULL; + char *resource_record_hostname = NULL; Key *private, *public; struct passwd *pw; struct stat st; - int opt, type, fd, download = 0; + int opt, type, fd, download = 0, memory = 0; + int generator_wanted = 0, trials = 100; + int do_gen_candidates = 0, do_screen_candidates = 0; + BIGNUM *start = NULL; FILE *f; extern int optind; extern char *optarg; - __progname = get_progname(av[0]); + __progname = ssh_get_progname(av[0]); SSLeay_add_all_algorithms(); + log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); + init_rng(); seed_rng(); @@ -774,7 +828,8 @@ main(int ac, char **av) exit(1); } - while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:U:D:P:N:C:")) != -1) { + while ((opt = getopt(ac, av, + "degiqpclBRxXyb:f:t:U:D:P:N:C:r:g:T:G:M:S:a:W:")) != -1) { switch (opt) { case 'b': bits = atoi(optarg); @@ -799,6 +854,9 @@ main(int ac, char **av) strlcpy(identity_file, optarg, sizeof(identity_file)); have_identity = 1; break; + case 'g': + print_generic = 1; + break; case 'P': identity_passphrase = optarg; break; @@ -839,6 +897,42 @@ main(int ac, char **av) case 'U': reader_id = optarg; break; + case 'r': + resource_record_hostname = optarg; + break; + case 'W': + generator_wanted = atoi(optarg); + if (generator_wanted < 1) + fatal("Desired generator has bad value."); + break; + case 'a': + trials = atoi(optarg); + if (trials < TRIAL_MINIMUM) { + fatal("Minimum primality trials is %d", + TRIAL_MINIMUM); + } + break; + case 'M': + memory = atoi(optarg); + if (memory != 0 && + (memory < LARGE_MINIMUM || memory > LARGE_MAXIMUM)) { + fatal("Invalid memory amount (min %ld, max %ld)", + LARGE_MINIMUM, LARGE_MAXIMUM); + } + break; + case 'G': + do_gen_candidates = 1; + strlcpy(out_file, optarg, sizeof(out_file)); + break; + case 'T': + do_screen_candidates = 1; + strlcpy(out_file, optarg, sizeof(out_file)); + break; + case 'S': + /* XXX - also compare length against bits */ + if (BN_hex2bn(&start, optarg) == 0) + fatal("Invalid start point."); + break; case '?': default: usage(); @@ -864,6 +958,13 @@ main(int ac, char **av) do_convert_from_ssh2(pw); if (print_public) do_print_public(pw); + if (resource_record_hostname != NULL) { +#ifdef DNS + do_print_resource_record(pw, resource_record_hostname); +#else /* DNS */ + fatal("no DNS support."); +#endif /* DNS */ + } if (reader_id != NULL) { #ifdef SMARTCARD if (download) @@ -875,6 +976,42 @@ main(int ac, char **av) #endif /* SMARTCARD */ } + if (do_gen_candidates) { + FILE *out = fopen(out_file, "w"); + + if (out == NULL) { + error("Couldn't open modulus candidate file \"%s\": %s", + out_file, strerror(errno)); + return (1); + } + if (gen_candidates(out, memory, bits, start) != 0) + fatal("modulus candidate generation failed\n"); + + return (0); + } + + if (do_screen_candidates) { + FILE *in; + FILE *out = fopen(out_file, "w"); + + if (have_identity && strcmp(identity_file, "-") != 0) { + if ((in = fopen(identity_file, "r")) == NULL) { + fatal("Couldn't open modulus candidate " + "file \"%s\": %s", identity_file, + strerror(errno)); + } + } else + in = stdin; + + if (out == NULL) { + fatal("Couldn't open moduli file \"%s\": %s", + out_file, strerror(errno)); + } + if (prime_test(in, out, trials, generator_wanted) != 0) + fatal("modulus screening failed\n"); + return (0); + } + arc4random_stir(); if (key_type_name == NULL) { diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1 index f6596c4..572751f 100644 --- a/crypto/openssh/ssh-keyscan.1 +++ b/crypto/openssh/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.15 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.17 2003/06/10 09:12:11 jmc Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. .\" @@ -103,24 +103,6 @@ On the other hand, if the security model allows such a risk, .Nm can help in the detection of tampered keyfiles or man in the middle attacks which have begun after the ssh_known_hosts file was created. -.Sh EXAMPLES -.Pp -Print the -.Pa rsa1 -host key for machine -.Pa hostname : -.Bd -literal -$ ssh-keyscan hostname -.Ed -.Pp -Find all hosts from the file -.Pa ssh_hosts -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\ - sort -u - ssh_known_hosts | diff ssh_known_hosts - -.Ed .Sh FILES .Pa Input format: .Bd -literal @@ -142,19 +124,36 @@ Where is either .Dq ssh-rsa or -.Dq ssh-dsa . +.Dq ssh-dss . .Pp .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. -This is because it opens a connection to the ssh port, reads the public -key, and drops the connection as soon as it gets the key. +.Sh EXAMPLES +Print the +.Pa rsa1 +host key for machine +.Pa hostname : +.Bd -literal +$ ssh-keyscan hostname +.Ed +.Pp +Find all hosts from the file +.Pa ssh_hosts +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 + sort -u - ssh_known_hosts | diff ssh_known_hosts - +.Ed .Sh SEE ALSO .Xr ssh 1 , .Xr sshd 8 .Sh AUTHORS -David Mazieres <dm@lcs.mit.edu> +.An David Mazieres Aq dm@lcs.mit.edu wrote the initial version, and -Wayne Davison <wayned@users.sourceforge.net> +.An Wayne Davison Aq wayned@users.sourceforge.net added support for protocol version 2. +.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. +This is because it opens a connection to the ssh port, reads the public +key, and drops the connection as soon as it gets the key. diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c index 5b4eb82..9fa8aae 100644 --- a/crypto/openssh/ssh-keyscan.c +++ b/crypto/openssh/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $"); #include "openbsd-compat/sys-queue.h" @@ -31,11 +31,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $"); /* Flag indicating whether IPv4 or IPv6. This can be set on the command line. Default value is AF_UNSPEC means both IPv4 and IPv6. */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else int IPv4or6 = AF_UNSPEC; -#endif int ssh_port = SSH_DEFAULT_PORT; @@ -397,7 +393,7 @@ tcpconnect(char *host) if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr)); for (ai = aitop; ai; ai = ai->ai_next) { - s = socket(ai->ai_family, SOCK_STREAM, 0); + s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { error("socket: %s", strerror(errno)); continue; @@ -545,7 +541,7 @@ congreet(int s) n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n", c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2, c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2); - if (atomicio(write, s, buf, n) != n) { + if (atomicio(vwrite, s, buf, n) != n) { error("write (%s): %s", c->c_name, strerror(errno)); confree(s); return; @@ -685,7 +681,7 @@ fatal(const char *fmt,...) static void usage(void) { - fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-f file]\n" + fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n" "\t\t [host | addrlist namelist] [...]\n", __progname); exit(1); @@ -701,7 +697,7 @@ main(int argc, char **argv) extern int optind; extern char *optarg; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); init_rng(); seed_rng(); TAILQ_INIT(&tq); diff --git a/crypto/openssh/ssh-keysign.8 b/crypto/openssh/ssh-keysign.8 index 2e3f8ff..a17e8d5 100644 --- a/crypto/openssh/ssh-keysign.8 +++ b/crypto/openssh/ssh-keysign.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keysign.8,v 1.6 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh-keysign.8,v 1.7 2003/06/10 09:12:11 jmc Exp $ .\" .\" Copyright (c) 2002 Markus Friedl. All rights reserved. .\" @@ -74,9 +74,9 @@ must be set-uid root if hostbased authentication is used. .Xr ssh-keygen 1 , .Xr ssh_config 5 , .Xr sshd 8 -.Sh AUTHORS -Markus Friedl <markus@openbsd.org> .Sh HISTORY .Nm first appeared in .Ox 3.2 . +.Sh AUTHORS +.An Markus Friedl Aq markus@openbsd.org diff --git a/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c index 26c8faa..c7ca5c4 100644 --- a/crypto/openssh/ssh-keysign.c +++ b/crypto/openssh/ssh-keysign.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: ssh-keysign.c,v 1.10 2003/03/13 11:42:19 markus Exp $"); +RCSID("$OpenBSD: ssh-keysign.c,v 1.13 2003/07/03 08:09:06 djm Exp $"); #include <openssl/evp.h> #include <openssl/rand.h> @@ -42,7 +42,8 @@ RCSID("$OpenBSD: ssh-keysign.c,v 1.10 2003/03/13 11:42:19 markus Exp $"); #include "pathnames.h" #include "readconf.h" -uid_t original_real_uid; /* XXX readconf.c needs this */ +/* XXX readconf.c needs these */ +uid_t original_real_uid; #ifdef HAVE___PROGNAME extern char *__progname; @@ -55,7 +56,7 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, u_int datalen) { Buffer b; - Key *key; + Key *key = NULL; u_char *pkblob; u_int blen, len; char *pkalg, *p; diff --git a/crypto/openssh/ssh-rand-helper.c b/crypto/openssh/ssh-rand-helper.c index 68b77b2..7e65e45 100644 --- a/crypto/openssh/ssh-rand-helper.c +++ b/crypto/openssh/ssh-rand-helper.c @@ -39,7 +39,7 @@ #include "pathnames.h" #include "log.h" -RCSID("$Id: ssh-rand-helper.c,v 1.10 2003/03/17 05:13:53 djm Exp $"); +RCSID("$Id: ssh-rand-helper.c,v 1.13 2003/08/21 23:34:41 djm Exp $"); /* Number of bytes we write out */ #define OUTPUT_SEED_SIZE 48 @@ -187,7 +187,7 @@ reopen: msg[0] = 0x02; msg[1] = len; - if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) { + if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) { if (errno == EPIPE && errors < 10) { close(fd); errors++; @@ -532,7 +532,7 @@ prng_check_seedfile(char *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()); + "owned by uid %li", filename, (long int)getuid()); return 0; } @@ -550,7 +550,7 @@ prng_write_seedfile(void) pw = getpwuid(getuid()); if (pw == NULL) fatal("Couldn't get password entry for current user " - "(%i): %s", getuid(), strerror(errno)); + "(%li): %s", (long int)getuid(), strerror(errno)); /* Try to ensure that the parent directory is there */ snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, @@ -572,7 +572,7 @@ prng_write_seedfile(void) debug("WARNING: couldn't access PRNG seedfile %.100s " "(%.100s)", filename, strerror(errno)); } else { - if (atomicio(write, fd, &seed, sizeof(seed)) < sizeof(seed)) + if (atomicio(vwrite, fd, &seed, sizeof(seed)) < sizeof(seed)) fatal("problem writing PRNG seedfile %.100s " "(%.100s)", filename, strerror(errno)); close(fd); @@ -589,7 +589,7 @@ prng_read_seedfile(void) pw = getpwuid(getuid()); if (pw == NULL) fatal("Couldn't get password entry for current user " - "(%i): %s", getuid(), strerror(errno)); + "(%li): %s", (long int)getuid(), strerror(errno)); snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, SSH_PRNG_SEED_FILE); @@ -769,7 +769,7 @@ main(int argc, char **argv) extern char *optarg; LogLevel ll; - __progname = get_progname(argv[0]); + __progname = ssh_get_progname(argv[0]); log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); ll = SYSLOG_LEVEL_INFO; @@ -858,7 +858,7 @@ main(int argc, char **argv) printf("%02x", (unsigned char)(buf[ret])); printf("\n"); } else - ret = atomicio(write, STDOUT_FILENO, buf, bytes); + ret = atomicio(vwrite, STDOUT_FILENO, buf, bytes); memset(buf, '\0', bytes); xfree(buf); diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c index efbc9e6..53e5023 100644 --- a/crypto/openssh/ssh-rsa.c +++ b/crypto/openssh/ssh-rsa.c @@ -1,29 +1,20 @@ /* - * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> * - * 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. + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - #include "includes.h" -RCSID("$OpenBSD: ssh-rsa.c,v 1.28 2003/02/12 09:33:04 markus Exp $"); +RCSID("$OpenBSD: ssh-rsa.c,v 1.30 2003/06/18 11:28:11 markus Exp $"); #include <openssl/evp.h> #include <openssl/err.h> diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1 index fd822bb..c81cb42 100644 --- a/crypto/openssh/ssh.1 +++ b/crypto/openssh/ssh.1 @@ -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.168 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh.1,v 1.175 2003/07/22 13:35:22 markus Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -49,7 +49,7 @@ .Pp .Nm ssh .Bk -words -.Op Fl afgknqstvxACNTX1246 +.Op Fl afgknqstvxACNTVX1246 .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl e Ar escape_char @@ -301,6 +301,9 @@ Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate .It Cm ~? Display a list of escape characters +.It Cm ~B +Send a BREAK to the remote system (only useful for SSH protocol version 2 +and if the peer supports it) .It Cm ~C Open command line (only useful for adding port forwardings using the .Fl L @@ -485,13 +488,13 @@ It is possible to have multiple options (and multiple identities specified in configuration files). .It Fl I Ar smartcard_device -Specifies which smartcard device to use. The argument is -the device +Specifies which smartcard device to use. +The argument is the device .Nm should use to communicate with a smartcard used for storing the user's private RSA key. .It Fl k -Disables forwarding of Kerberos tickets and AFS tokens. +Disables forwarding of Kerberos tickets. This may also be specified on a per-host basis in the configuration file. .It Fl l Ar login_name Specifies the user to log in as on the remote machine. @@ -539,9 +542,10 @@ per-host basis in the configuration file. Quiet mode. Causes all warning and diagnostic messages to be suppressed. .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 -subsystem is specified as the remote command. +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 subsystem is specified as the remote command. .It Fl t Force pseudo-tty allocation. This can be used to execute arbitrary @@ -563,8 +567,10 @@ This is helpful in debugging connection, authentication, and configuration problems. Multiple .Fl v -options increases the verbosity. -Maximum is 3. +options increase the verbosity. +The maximum is 3. +.It Fl V +Display the version number and exit. .It Fl x Disables X11 forwarding. .It Fl X @@ -643,9 +649,9 @@ on the local side, and whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. -Currently the SOCKS4 protocol is supported, and +Currently the SOCKS4 and SOCKS5 protocols are supported, and .Nm -will act as a SOCKS4 server. +will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file. .It Fl 1 @@ -916,7 +922,8 @@ or .Xr rsh 1 . .It Pa /etc/hosts.equiv This file is used during -.Pa \&.rhosts authentication. +.Pa \&.rhosts +authentication. It contains canonical hosts names, one per line (the full format is described on the @@ -958,15 +965,6 @@ above. .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. -Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, -Theo de Raadt and Dug Song -removed many bugs, re-added newer features and -created OpenSSH. -Markus Friedl contributed the support for SSH -protocol versions 1.5 and 2.0. .Sh SEE ALSO .Xr rsh 1 , .Xr scp 1 , @@ -989,3 +987,12 @@ protocol versions 1.5 and 2.0. .%D January 2002 .%O work in progress material .Re +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index 7206043..35418f6 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.190 2003/02/06 09:27:29 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $"); #include <openssl/evp.h> #include <openssl/err.h> @@ -79,14 +79,6 @@ extern char *__progname; char *__progname; #endif -/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. - Default value is AF_UNSPEC means both IPv4 and IPv6. */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else -int IPv4or6 = AF_UNSPEC; -#endif - /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; @@ -162,9 +154,6 @@ usage(void) _PATH_SSH_USER_CONFFILE); fprintf(stderr, " -A Enable authentication agent forwarding.\n"); fprintf(stderr, " -a Disable authentication agent forwarding (default).\n"); -#ifdef AFS - fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); -#endif /* AFS */ fprintf(stderr, " -X Enable X11 connection forwarding.\n"); fprintf(stderr, " -x Disable X11 connection forwarding (default).\n"); fprintf(stderr, " -i file Identity for public key authentication " @@ -222,7 +211,7 @@ main(int ac, char **av) extern int optind, optreset; extern char *optarg; - __progname = get_progname(av[0]); + __progname = ssh_get_progname(av[0]); init_rng(); /* @@ -253,7 +242,7 @@ main(int ac, char **av) /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { - log("You don't exist, go away!"); + logit("You don't exist, go away!"); exit(1); } /* Take a copy of the returned structure. */ @@ -284,10 +273,10 @@ again: options.protocol = SSH_PROTO_2; break; case '4': - IPv4or6 = AF_INET; + options.address_family = AF_INET; break; case '6': - IPv4or6 = AF_INET6; + options.address_family = AF_INET6; break; case 'n': stdin_null_flag = 1; @@ -314,12 +303,9 @@ again: case 'A': options.forward_agent = 1; break; -#ifdef AFS case 'k': - options.kerberos_tgt_passing = 0; - options.afs_token_passing = 0; + /* ignored for backward compatibility */ break; -#endif case 'i': if (stat(optarg, &st) < 0) { fprintf(stderr, "Warning: Identity file %s " @@ -346,22 +332,22 @@ again: tty_flag = 1; break; case 'v': - if (0 == debug_flag) { + if (debug_flag == 0) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; - } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { - options.log_level++; + } else { + if (options.log_level < SYSLOG_LEVEL_DEBUG3) + options.log_level++; break; - } else - fatal("Too high debugging level."); + } /* fallthrough */ case 'V': fprintf(stderr, - "%s, SSH protocols %d.%d/%d.%d, OpenSSL 0x%8.8lx\n", + "%s, SSH protocols %d.%d/%d.%d, %s\n", SSH_VERSION, PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, - SSLeay()); + SSLeay_version(SSLEAY_VERSION)); if (opt == 'V') exit(0); break; @@ -427,9 +413,9 @@ again: case 'L': case 'R': - if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]", + if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]", sfwd_port, buf, sfwd_host_port) != 3 && - sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]", + sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]", sfwd_port, buf, sfwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'\n", @@ -458,7 +444,7 @@ again: optarg); exit(1); } - add_local_forward(&options, fwd_port, "socks4", 0); + add_local_forward(&options, fwd_port, "socks", 0); break; case 'C': @@ -518,7 +504,6 @@ again: SSLeay_add_all_algorithms(); ERR_load_crypto_strings(); - channel_set_af(IPv4or6); /* Initialize the command to execute on remote host. */ buffer_init(&command); @@ -559,7 +544,7 @@ again: /* Do not allocate a tty if stdin is not a tty. */ if (!isatty(fileno(stdin)) && !force_tty_flag) { if (tty_flag) - log("Pseudo-terminal will not be allocated because stdin is not a terminal."); + logit("Pseudo-terminal will not be allocated because stdin is not a terminal."); tty_flag = 0; } @@ -590,6 +575,8 @@ again: /* Fill configuration defaults. */ fill_default_options(&options); + channel_set_af(options.address_family); + /* reinit */ log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); @@ -601,25 +588,20 @@ again: if (options.hostname != NULL) host = options.hostname; + /* force lowercase for hostkey matching */ + if (options.host_key_alias != NULL) { + for (p = options.host_key_alias; *p; p++) + if (isupper(*p)) + *p = tolower(*p); + } + if (options.proxy_command != NULL && strcmp(options.proxy_command, "none") == 0) options.proxy_command = NULL; - /* Disable rhosts authentication if not running as root. */ -#ifdef HAVE_CYGWIN - /* Ignore uid if running under Windows */ - if (!options.use_privileged_port) { -#else - if (original_effective_uid != 0 || !options.use_privileged_port) { -#endif - debug("Rhosts Authentication disabled, " - "originating port will not be trusted."); - options.rhosts_authentication = 0; - } /* Open a connection to the remote host. */ - - if (ssh_connect(host, &hostaddr, options.port, IPv4or6, - options.connection_attempts, + if (ssh_connect(host, &hostaddr, options.port, + options.address_family, options.connection_attempts, #ifdef HAVE_CYGWIN options.use_privileged_port, #else @@ -793,7 +775,7 @@ x11_get_proto(char **_proto, char **_data) if (!got_data) { u_int32_t rand = 0; - log("Warning: No xauth data; using fake authentication data for X11 forwarding."); + logit("Warning: No xauth data; using fake authentication data for X11 forwarding."); strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto); for (i = 0; i < 16; i++) { if (i % 4 == 0) @@ -873,7 +855,7 @@ ssh_session(void) if (type == SSH_SMSG_SUCCESS) packet_start_compression(options.compression_level); else if (type == SSH_SMSG_FAILURE) - log("Warning: Remote host refused compression."); + logit("Warning: Remote host refused compression."); else packet_disconnect("Protocol error waiting for compression response."); } @@ -912,7 +894,7 @@ ssh_session(void) interactive = 1; have_tty = 1; } else if (type == SSH_SMSG_FAILURE) - log("Warning: Remote host failed or refused to allocate a pseudo tty."); + logit("Warning: Remote host failed or refused to allocate a pseudo tty."); else packet_disconnect("Protocol error waiting for pty request response."); } @@ -930,7 +912,7 @@ ssh_session(void) if (type == SSH_SMSG_SUCCESS) { interactive = 1; } else if (type == SSH_SMSG_FAILURE) { - log("Warning: Remote host denied X11 forwarding."); + logit("Warning: Remote host denied X11 forwarding."); } else { packet_disconnect("Protocol error waiting for X11 forwarding"); } @@ -949,7 +931,7 @@ ssh_session(void) type = packet_read(); packet_check_eom(); if (type != SSH_SMSG_SUCCESS) - log("Warning: Remote host denied authentication agent forwarding."); + logit("Warning: Remote host denied authentication agent forwarding."); } /* Initiate port forwardings. */ @@ -1017,7 +999,7 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt) options.remote_forwards[i].host, options.remote_forwards[i].host_port); if (type == SSH2_MSG_REQUEST_FAILURE) - log("Warning: remote port forwarding failed for listen port %d", + logit("Warning: remote port forwarding failed for listen port %d", options.remote_forwards[i].port); } @@ -1132,7 +1114,7 @@ ssh_session2_open(void) c = channel_new( "session", SSH_CHANNEL_OPENING, in, out, err, window, packetmax, CHAN_EXTENDED_WRITE, - xstrdup("client-session"), /*nonblock*/0); + "client-session", /*nonblock*/0); debug3("ssh_session2_open: channel_new: %d", c->self); @@ -1184,7 +1166,7 @@ load_public_identity_files(void) sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1)); options.num_identity_files++; options.identity_keys[0] = keys[i]; - options.identity_files[0] = xstrdup("smartcard key");; + options.identity_files[0] = sc_get_key_label(keys[i]); } if (options.num_identity_files > SSH_MAX_IDENTITY_FILES) options.num_identity_files = SSH_MAX_IDENTITY_FILES; diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h index 0a6ad13..e88b9b8 100644 --- a/crypto/openssh/ssh.h +++ b/crypto/openssh/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.71 2002/06/22 02:00:29 stevesk Exp $ */ +/* $OpenBSD: ssh.h,v 1.74 2003/09/01 13:52:18 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -20,7 +20,6 @@ #include <stdarg.h> /* For va_list */ #include <syslog.h> /* For LOG_AUTH and friends */ #include <sys/socket.h> /* For struct sockaddr_storage */ -#include "openbsd-compat/fake-socket.h" /* For struct sockaddr_storage */ #ifdef HAVE_SYS_SELECT_H # include <sys/select.h> #endif @@ -89,9 +88,6 @@ */ #define SSH_SESSION_KEY_LENGTH 32 -/* Name of Kerberos service for SSH to use. */ -#define KRB4_SERVICE_NAME "rcmd" - /* Used to identify ``EscapeChar none'' */ #define SSH_ESCAPECHAR_NONE -2 diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h index 091e52b..fb491c9 100644 --- a/crypto/openssh/ssh2.h +++ b/crypto/openssh/ssh2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh2.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */ +/* $OpenBSD: ssh2.h,v 1.9 2003/05/14 00:52:59 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -61,6 +61,8 @@ #define SSH2_MSG_TRANSPORT_MAX 49 #define SSH2_MSG_USERAUTH_MIN 50 #define SSH2_MSG_USERAUTH_MAX 79 +#define SSH2_MSG_USERAUTH_PER_METHOD_MIN 60 +#define SSH2_MSG_USERAUTH_PER_METHOD_MAX SSH2_MSG_USERAUTH_MAX #define SSH2_MSG_CONNECTION_MIN 80 #define SSH2_MSG_CONNECTION_MAX 127 #define SSH2_MSG_RESERVED_MIN 128 diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config index 94cffbf..2692e89 100644 --- a/crypto/openssh/ssh_config +++ b/crypto/openssh/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.16 2002/07/03 14:21:05 markus Exp $ +# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -18,13 +18,14 @@ # Host * # ForwardAgent no # ForwardX11 no -# RhostsAuthentication no # RhostsRSAAuthentication no # RSAAuthentication yes # PasswordAuthentication yes # HostbasedAuthentication no # BatchMode no # CheckHostIP yes +# AddressFamily any +# ConnectTimeout 0 # StrictHostKeyChecking ask # IdentityFile ~/.ssh/identity # IdentityFile ~/.ssh/id_rsa diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5 index 44208b4..7a435a9 100644 --- a/crypto/openssh/ssh_config.5 +++ b/crypto/openssh/ssh_config.5 @@ -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_config.5,v 1.7 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: ssh_config.5,v 1.20 2003/09/02 18:50:06 jmc Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -104,7 +104,7 @@ keyword) to be only for those hosts that match one of the patterns given after the keyword. .Ql \&* and -.Ql ? +.Ql \&? can be used as wildcards in the patterns. A single @@ -115,13 +115,14 @@ The host is the .Ar hostname argument given on the command line (i.e., the name is not converted to a canonicalized host name before matching). -.It Cm AFSTokenPassing -Specifies whether to pass AFS tokens to remote host. -The argument to this keyword must be -.Dq yes -or -.Dq no . -This option applies to protocol version 1 only. +.It Cm AddressFamily +Specifies which address family to use when connecting. +Valid arguments are +.Dq any , +.Dq inet +(Use IPv4 only) or +.Dq inet6 +(Use IPv6 only.) .It Cm BatchMode If set to .Dq yes , @@ -227,18 +228,41 @@ Specifies the number of tries (one per second) to make before exiting. The argument must be an integer. This may be useful in scripts if the connection sometimes fails. The default is 1. +.It Cm ConnectTimeout +Specifies the timeout (in seconds) used when connecting to the ssh +server, instead of using the default system TCP timeout. +This value is used only when the target is down or really unreachable, +not when it refuses the connection. .It Cm DynamicForward Specifies that a TCP/IP port on the local machine be forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. The argument must be a port number. -Currently the SOCKS4 protocol is supported, and +Currently the SOCKS4 and SOCKS5 protocols are supported, and .Nm ssh -will act as a SOCKS4 server. +will act as a SOCKS server. Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. +.It Cm EnableSSHKeysign +Setting this option to +.Dq yes +in the global client configuration file +.Pa /etc/ssh/ssh_config +enables the use of the helper program +.Xr ssh-keysign 8 +during +.Cm HostbasedAuthentication . +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . +See +.Xr ssh-keysign 8 +for more information. .It Cm EscapeChar Sets the escape character (default: .Ql ~ ) . @@ -307,6 +331,18 @@ The default is Specifies a file to use for the global host key database instead of .Pa /etc/ssh/ssh_known_hosts . +.It Cm GSSAPIAuthentication +Specifies whether authentication based on GSSAPI may be used, either using +the result of a successful key exchange, or using GSSAPI user +authentication. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. +.It Cm GSSAPIDelegateCredentials +Forward (delegate) credentials to the server. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. .It Cm HostbasedAuthentication Specifies whether to try rhosts based authentication with public key authentication. @@ -339,7 +375,8 @@ Numeric IP addresses are also permitted (both on the command line and in specifications). .It Cm IdentityFile Specifies a file from which the user's RSA or DSA authentication identity -is read. The default is +is read. +The default is .Pa $HOME/.ssh/identity for protocol version 1, and .Pa $HOME/.ssh/id_rsa @@ -370,19 +407,6 @@ This is important in scripts, and many users want it too. .Pp To disable keepalives, the value should be set to .Dq no . -.It Cm KerberosAuthentication -Specifies whether Kerberos authentication will be used. -The argument to this keyword must be -.Dq yes -or -.Dq no . -.It Cm KerberosTgtPassing -Specifies whether a Kerberos TGT will be forwarded to the server. -This will only work if the Kerberos server is actually an AFS kaserver. -The argument to this keyword must be -.Dq yes -or -.Dq no . .It Cm LocalForward Specifies that a TCP/IP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. @@ -436,7 +460,8 @@ Specifies the port number to connect on the remote host. Default is 22. .It Cm PreferredAuthentications Specifies the order in which the client should try protocol 2 -authentication methods. This allows a client to prefer one method (e.g. +authentication methods. +This allows a client to prefer one method (e.g. .Cm keyboard-interactive ) over another method (e.g. .Cm password ) @@ -504,26 +529,6 @@ IPv6 addresses can be specified with an alternative syntax: Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. -.It Cm RhostsAuthentication -Specifies whether to try rhosts based authentication. -Note that this -declaration only affects the client side and has no effect whatsoever -on security. -Most servers do not permit RhostsAuthentication because it -is not secure (see -.Cm RhostsRSAAuthentication ) . -The argument to this keyword must be -.Dq yes -or -.Dq no . -The default is -.Dq no . -This option applies to protocol version 1 only and requires -.Nm ssh -to be setuid root and -.Cm UsePrivilegedPort -to be set to -.Dq yes . .It Cm RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. @@ -549,12 +554,12 @@ The default is .Dq yes . Note that this option applies to protocol version 1 only. .It Cm SmartcardDevice -Specifies which smartcard device to use. The argument to this keyword is -the device +Specifies which smartcard device to use. +The argument to this keyword is the device .Nm ssh should use to communicate with a smartcard used for storing the user's -private RSA key. By default, no device is specified and smartcard support -is not activated. +private RSA key. +By default, no device is specified and smartcard support is not activated. .It Cm StrictHostKeyChecking If this flag is set to .Dq yes , @@ -604,11 +609,9 @@ If set to must be setuid root. Note that this option must be set to .Dq yes -if -.Cm RhostsAuthentication -and +for .Cm RhostsRSAAuthentication -authentications are needed with older servers. +with older servers. .It Cm User Specifies the user to log in as. This can be useful when a different user name is used on different machines. @@ -618,6 +621,12 @@ having to remember to give the user name on the command line. Specifies a file to use for the user host key database instead of .Pa $HOME/.ssh/known_hosts . +.It Cm VerifyHostKeyDNS +Specifies whether to verify the remote key using DNS and SSHFP resource +records. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 @@ -643,6 +652,8 @@ 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. .El +.Sh SEE ALSO +.Xr ssh 1 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. @@ -652,5 +663,3 @@ removed many bugs, re-added newer features and created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -.Sh SEE ALSO -.Xr ssh 1 diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c index dae2596..f29ac80 100644 --- a/crypto/openssh/sshconnect.c +++ b/crypto/openssh/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.137 2002/11/21 23:03:51 deraadt Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.148 2003/09/18 07:52:54 markus Exp $"); #include <openssl/bn.h> @@ -33,9 +33,17 @@ RCSID("$OpenBSD: sshconnect.c,v 1.137 2002/11/21 23:03:51 deraadt Exp $"); #include "misc.h" #include "readpass.h" +#ifdef DNS +#include "dns.h" +#endif + char *client_version_string = NULL; char *server_version_string = NULL; +#ifdef DNS +int verified_host_key_dns = 0; +#endif + /* import */ extern Options options; extern char *__progname; @@ -163,7 +171,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command) * Creates a (possibly privileged) socket for use as the ssh connection. */ static int -ssh_create_socket(int privileged, int family) +ssh_create_socket(int privileged, struct addrinfo *ai) { int sock, gaierr; struct addrinfo hints, *res; @@ -175,15 +183,16 @@ ssh_create_socket(int privileged, int family) if (privileged) { int p = IPPORT_RESERVED - 1; PRIV_START; - sock = rresvport_af(&p, family); + sock = rresvport_af(&p, ai->ai_family); PRIV_END; if (sock < 0) - error("rresvport: af=%d %.100s", family, strerror(errno)); + error("rresvport: af=%d %.100s", ai->ai_family, + strerror(errno)); else debug("Allocated local port %d.", p); return sock; } - sock = socket(family, SOCK_STREAM, 0); + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) error("socket: %.100s", strerror(errno)); @@ -192,8 +201,9 @@ ssh_create_socket(int privileged, int family) return sock; memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; + hints.ai_family = ai->ai_family; + hints.ai_socktype = ai->ai_socktype; + hints.ai_protocol = ai->ai_protocol; hints.ai_flags = AI_PASSIVE; gaierr = getaddrinfo(options.bind_address, "0", &hints, &res); if (gaierr) { @@ -212,6 +222,74 @@ ssh_create_socket(int privileged, int family) return sock; } +static int +timeout_connect(int sockfd, const struct sockaddr *serv_addr, + socklen_t addrlen, int timeout) +{ + fd_set *fdset; + struct timeval tv; + socklen_t optlen; + int fdsetsz, optval, rc, result = -1; + + if (timeout <= 0) + return (connect(sockfd, serv_addr, addrlen)); + + if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + return (-1); + + rc = connect(sockfd, serv_addr, addrlen); + if (rc == 0) + return (0); + if (errno != EINPROGRESS) + return (-1); + + fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask); + fdset = (fd_set *)xmalloc(fdsetsz); + + memset(fdset, 0, fdsetsz); + FD_SET(sockfd, fdset); + tv.tv_sec = timeout; + tv.tv_usec = 0; + + for(;;) { + rc = select(sockfd + 1, NULL, fdset, NULL, &tv); + if (rc != -1 || errno != EINTR) + break; + } + + switch(rc) { + case 0: + /* Timed out */ + errno = ETIMEDOUT; + break; + case -1: + /* Select error */ + debug("select: %s", strerror(errno)); + break; + case 1: + /* Completed or failed */ + optval = 0; + optlen = sizeof(optval); + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, + &optlen) == -1) { + debug("getsockopt: %s", strerror(errno)); + break; + } + if (optval != 0) { + errno = optval; + break; + } + result = 0; + break; + default: + /* Should not occur */ + fatal("Bogus return (%d) from select()", rc); + } + + xfree(fdset); + return (result); +} + /* * Opens a TCP/IP connection to the remote server on the given host. * The address of the remote host will be returned in hostaddr. @@ -295,12 +373,13 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, host, ntop, strport); /* Create a socket for connecting. */ - sock = ssh_create_socket(needpriv, ai->ai_family); + sock = ssh_create_socket(needpriv, ai); if (sock < 0) /* Any error is already output */ continue; - if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) { + if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen, + options.connection_timeout) >= 0) { /* Successful connection. */ memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen); break; @@ -332,7 +411,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr, /* Return failure if we didn't get a successful connection. */ if (attempt >= connection_attempts) { - log("ssh: connect to host %s port %s: %s", + logit("ssh: connect to host %s port %s: %s", host, strport, strerror(errno)); return full_failure ? ECONNABORTED : ECONNREFUSED; } @@ -421,7 +500,7 @@ ssh_exchange_identification(void) enable_compat13(); minor1 = 3; if (options.forward_agent) { - log("Agent forwarding disabled for protocol 1.3"); + logit("Agent forwarding disabled for protocol 1.3"); options.forward_agent = 0; } } @@ -445,7 +524,7 @@ ssh_exchange_identification(void) compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, compat20 ? PROTOCOL_MINOR_2 : minor1, SSH_VERSION); - if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) + if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf)) fatal("write: %.100s", strerror(errno)); client_version_string = xstrdup(buf); chop(client_version_string); @@ -496,7 +575,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, int salen; char ntop[NI_MAXHOST]; char msg[1024]; - int len, host_line, ip_line, has_keys; + int len, host_line, ip_line; const char *host_file = NULL, *ip_file = NULL; /* @@ -612,16 +691,16 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, debug("Found key in %s:%d", host_file, host_line); if (options.check_host_ip && ip_status == HOST_NEW) { if (readonly) - log("%s host key for IP address " + logit("%s host key for IP address " "'%.128s' not in list of known hosts.", type, ip); else if (!add_host_to_hostfile(user_hostfile, ip, host_key)) - log("Failed to add the %s host key for IP " + logit("Failed to add the %s host key for IP " "address '%.128s' to the list of known " "hosts (%.30s).", type, ip, user_hostfile); else - log("Warning: Permanently added the %s host " + logit("Warning: Permanently added the %s host " "key for IP address '%.128s' to the list " "of known hosts.", type, ip); } @@ -640,19 +719,36 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, "have requested strict checking.", type, host); goto fail; } else if (options.strict_host_key_checking == 2) { - has_keys = show_other_keys(host, host_key); + char msg1[1024], msg2[1024]; + + if (show_other_keys(host, host_key)) + snprintf(msg1, sizeof(msg1), + "\nbut keys of different type are already" + " known for this host."); + else + snprintf(msg1, sizeof(msg1), "."); /* The default */ fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); + msg2[0] = '\0'; +#ifdef DNS + if (options.verify_host_key_dns) { + if (verified_host_key_dns) + snprintf(msg2, sizeof(msg2), + "Matching host key fingerprint" + " found in DNS.\n"); + else + snprintf(msg2, sizeof(msg2), + "No matching host key fingerprint" + " found in DNS.\n"); + } +#endif snprintf(msg, sizeof(msg), "The authenticity of host '%.200s (%s)' can't be " "established%s\n" - "%s key fingerprint is %s.\n" + "%s key fingerprint is %s.\n%s" "Are you sure you want to continue connecting " "(yes/no)? ", - host, ip, - has_keys ? ",\nbut keys of different type are already " - "known for this host." : ".", - type, fp); + host, ip, msg1, type, fp, msg2); xfree(fp); if (!confirm(msg)) goto fail; @@ -668,10 +764,10 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, * local known_hosts file. */ if (!add_host_to_hostfile(user_hostfile, hostp, host_key)) - log("Failed to add the host to the list of known " + logit("Failed to add the host to the list of known " "hosts (%.500s).", user_hostfile); else - log("Warning: Permanently added '%.200s' (%s) to the " + logit("Warning: Permanently added '%.200s' (%s) to the " "list of known hosts.", hostp, type); break; case HOST_CHANGED: @@ -722,7 +818,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, /* * If strict host key checking has not been requested, allow - * the connection but without password authentication or + * the connection but without MITM-able authentication or * agent forwarding. */ if (options.password_authentication) { @@ -730,6 +826,17 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, "man-in-the-middle attacks."); options.password_authentication = 0; } + if (options.kbd_interactive_authentication) { + error("Keyboard-interactive authentication is disabled" + " to avoid man-in-the-middle attacks."); + options.kbd_interactive_authentication = 0; + options.challenge_response_authentication = 0; + } + if (options.challenge_response_authentication) { + error("Challenge/response authentication is disabled" + " to avoid man-in-the-middle attacks."); + options.challenge_response_authentication = 0; + } if (options.forward_agent) { error("Agent forwarding is disabled to avoid " "man-in-the-middle attacks."); @@ -774,7 +881,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, host_file, host_line); } if (options.strict_host_key_checking == 1) { - log(msg); + logit("%s", msg); error("Exiting, you have requested strict checking."); goto fail; } else if (options.strict_host_key_checking == 2) { @@ -783,7 +890,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, if (!confirm(msg)) goto fail; } else { - log(msg); + logit("%s", msg); } } @@ -795,11 +902,33 @@ fail: return -1; } +/* returns 0 if key verifies or -1 if key does NOT verify */ int verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key) { struct stat st; +#ifdef DNS + if (options.verify_host_key_dns) { + switch(verify_host_key_dns(host, hostaddr, host_key)) { + case DNS_VERIFY_OK: +#ifdef DNSSEC + return 0; +#else + verified_host_key_dns = 1; + break; +#endif + case DNS_VERIFY_FAILED: + return -1; + case DNS_VERIFY_ERROR: + break; + default: + debug3("bad return value from verify_host_key_dns"); + break; + } + } +#endif /* DNS */ + /* return ok if the key can be found in an old keyfile */ if (stat(options.system_hostfile2, &st) == 0 || stat(options.user_hostfile2, &st) == 0) { @@ -881,7 +1010,7 @@ show_key_from_file(const char *file, const char *host, int keytype) if ((ret = lookup_key_in_hostfile_by_type(file, host, keytype, found, &line))) { fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); - log("WARNING: %s key found for host %s\n" + logit("WARNING: %s key found for host %s\n" "in %s:%d\n" "%s key fingerprint %s.", key_type(found), host, file, line, diff --git a/crypto/openssh/sshconnect1.c b/crypto/openssh/sshconnect1.c index 2fc9a98..2f89964 100644 --- a/crypto/openssh/sshconnect1.c +++ b/crypto/openssh/sshconnect1.c @@ -13,25 +13,11 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.56 2003/08/28 12:54:34 markus Exp $"); #include <openssl/bn.h> #include <openssl/md5.h> -#ifdef KRB4 -#include <krb.h> -#endif -#ifdef KRB5 -#include <krb5.h> -#ifndef HEIMDAL -#define krb5_get_err_text(context,code) error_message(code) -#endif /* !HEIMDAL */ -#endif -#ifdef AFS -#include <kafs.h> -#include "radix.h" -#endif - #include "ssh.h" #include "ssh1.h" #include "xmalloc.h" @@ -122,7 +108,7 @@ try_agent_authentication(void) * although it advertised it supports this. Just * return a wrong value. */ - log("Authentication agent failed to decrypt challenge."); + logit("Authentication agent failed to decrypt challenge."); memset(response, 0, sizeof(response)); } key_free(key); @@ -380,478 +366,6 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key) return 0; } -#ifdef KRB4 -static int -try_krb4_authentication(void) -{ - KTEXT_ST auth; /* Kerberos data */ - char *reply; - char inst[INST_SZ]; - char *realm; - CREDENTIALS cred; - int r, type; - socklen_t slen; - Key_schedule schedule; - u_long checksum, cksum; - MSG_DAT msg_data; - struct sockaddr_in local, foreign; - struct stat st; - - /* 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)); - return 0; - } - /* 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]); - return 0; - } - /* Get session key to decrypt the server's reply with. */ - r = krb_get_cred(KRB4_SERVICE_NAME, inst, realm, &cred); - if (r != KSUCCESS) { - debug("get_cred failed: %s", krb_err_txt[r]); - 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(), - (struct sockaddr *)&foreign, &slen) < 0) { - debug("getpeername failed: %s", strerror(errno)); - fatal_cleanup(); - } - /* Get server reply. */ - 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); - if (auth.length >= MAX_KTXT_LEN) - fatal("Kerberos v4: Malformed response from server"); - memcpy(auth.dat, reply, auth.length); - xfree(reply); - - packet_check_eom(); - - /* - * If his response isn't properly encrypted with the session - * key, and the decrypted checksum fails to match, he's - * bogus. Bail out. - */ - r = krb_rd_priv(auth.dat, auth.length, schedule, &cred.session, - &foreign, &local, &msg_data); - if (r != KSUCCESS) { - debug("Kerberos v4 krb_rd_priv failed: %s", - krb_err_txt[r]); - packet_disconnect("Kerberos v4 challenge failed!"); - } - /* Fetch the (incremented) checksum that we supplied in the request. */ - 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."); - return 1; - } else - packet_disconnect("Kerberos v4 challenge failed!"); - break; - - default: - packet_disconnect("Protocol error on Kerberos v4 response: %d", type); - } - return 0; -} - -#endif /* KRB4 */ - -#ifdef KRB5 -static int -try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context) -{ - krb5_error_code problem; - const char *tkfile; - struct stat buf; - krb5_ccache ccache = NULL; - const char *remotehost; - krb5_data ap; - 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; - } - - problem = krb5_auth_con_init(*context, auth_context); - if (problem) { - debug("Kerberos v5: krb5_auth_con_init failed"); - ret = 0; - goto out; - } - -#ifndef HEIMDAL - problem = krb5_auth_con_setflags(*context, *auth_context, - KRB5_AUTH_CONTEXT_RET_TIME); - if (problem) { - debug("Keberos v5: krb5_auth_con_setflags failed"); - ret = 0; - goto out; - } -#endif - - 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", - krb5_get_err_text(*context, problem)); - 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) { - debug("Kerberos v5: krb5_mk_req failed: %s", - krb5_get_err_text(*context, problem)); - 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(); - 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_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_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); - if (reply != NULL) - krb5_free_ap_rep_enc_part(*context, reply); - if (ap.length > 0) -#ifdef HEIMDAL - krb5_data_free(&ap); -#else - krb5_free_data_contents(*context, &ap); -#endif - - return (ret); -} - -static void -send_krb5_tgt(krb5_context context, krb5_auth_context auth_context) -{ - int fd, type; - krb5_error_code problem; - krb5_data outbuf; - krb5_ccache ccache = NULL; - krb5_creds creds; -#ifdef HEIMDAL - krb5_kdc_flags flags; -#else - int forwardable; -#endif - const char *remotehost; - - memset(&creds, 0, sizeof(creds)); - memset(&outbuf, 0, sizeof(outbuf)); - - fd = packet_get_connection_in(); - -#ifdef HEIMDAL - problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd); -#else - problem = krb5_auth_con_genaddrs(context, auth_context, fd, - KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR | - KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR); -#endif - 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; - - remotehost = get_canonical_hostname(1); - -#ifdef HEIMDAL - problem = krb5_build_principal(context, &creds.server, - strlen(creds.client->realm), creds.client->realm, - "krbtgt", creds.client->realm, NULL); -#else - problem = krb5_build_principal(context, &creds.server, - creds.client->realm.length, creds.client->realm.data, - "host", remotehost, NULL); -#endif - if (problem) - goto out; - - creds.times.endtime = 0; - -#ifdef HEIMDAL - flags.i = 0; - flags.b.forwarded = 1; - flags.b.forwardable = krb5_config_get_bool(context, NULL, - "libdefaults", "forwardable", NULL); - problem = krb5_get_forwarded_creds(context, auth_context, - ccache, flags.i, remotehost, &creds, &outbuf); -#else - forwardable = 1; - problem = krb5_fwd_tgt_creds(context, auth_context, remotehost, - creds.client, creds.server, ccache, forwardable, &outbuf); -#endif - - 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(); - - 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", - krb5_get_err_text(context, problem)); - if (creds.client) - krb5_free_principal(context, creds.client); - if (creds.server) - krb5_free_principal(context, creds.server); - if (ccache) - krb5_cc_close(context, ccache); - if (outbuf.data) - xfree(outbuf.data); -} -#endif /* KRB5 */ - -#ifdef AFS -static void -send_krb4_tgt(void) -{ - CREDENTIALS *creds; - struct stat st; - char buffer[4096], pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ]; - 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(); - - 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); -} - -static void -send_afs_tokens(void) -{ - CREDENTIALS creds; - struct ViceIoctl parms; - struct ClearToken ct; - 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; - parms.in_size = sizeof(i); - parms.out = buf; - parms.out_size = sizeof(buf); - 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) - break; - 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)) - break; - p += sizeof(len); - memcpy(&ct, p, len); - 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'; - strlcpy(creds.realm, server_cell, REALM_SZ); - memcpy(creds.session, ct.HandShakeKey, DES_KEY_SZ); - creds.issue_date = ct.BeginTimestamp; - creds.lifetime = krb_time_to_life(creds.issue_date, - ct.EndTimestamp); - 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) - break; - packet_start(SSH_CMSG_HAVE_AFS_TOKEN); - packet_put_cstring(buffer); - packet_send(); - packet_write_wait(); - - /* Roger, Roger. Clearance, Clarence. What's your vector, - Victor? */ - type = packet_read(); - - if (type == SSH_SMSG_FAILURE) - debug("AFS token for cell %s rejected.", server_cell); - else if (type != SSH_SMSG_SUCCESS) - packet_disconnect("Protocol error on AFS token response: %d", type); - } -} - -#endif /* AFS */ - /* * Tries to authenticate with any string-based challenge/response system. * Note that the client code is not tied to s/key or TIS. @@ -890,7 +404,7 @@ try_challenge_response_authentication(void) if (i != 0) error("Permission denied, please try again."); if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! " + logit("WARNING: Encryption is disabled! " "Response will be transmitted in clear text."); response = read_passphrase(prompt, 0); if (strcmp(response, "") == 0) { @@ -925,7 +439,7 @@ try_password_authentication(char *prompt) debug("Doing password authentication."); if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Password will be transmitted in clear text."); + logit("WARNING: Encryption is disabled! Password will be transmitted in clear text."); for (i = 0; i < options.number_of_password_prompts; i++) { if (i != 0) error("Permission denied, please try again."); @@ -981,9 +495,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr) rbits = BN_num_bits(server_key->rsa->n); if (bits != rbits) { - log("Warning: Server lies about size of server public key: " + logit("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."); + logit("Warning: This may be due to an old implementation of ssh."); } /* Get the host key. */ host_key = key_new(KEY_RSA1); @@ -993,9 +507,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr) rbits = BN_num_bits(host_key->rsa->n); if (bits != rbits) { - log("Warning: Server lies about size of server host key: " + logit("Warning: Server lies about size of server host key: " "actual size is %d bits vs. announced %d.", rbits, bits); - log("Warning: This may be due to an old implementation of ssh."); + logit("Warning: This may be due to an old implementation of ssh."); } /* Get protocol flags. */ @@ -1086,7 +600,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) options.cipher = ssh_cipher_default; } else if (options.cipher == SSH_CIPHER_ILLEGAL || !(cipher_mask_ssh1(1) & (1 << options.cipher))) { - log("No valid SSH1 cipher, using %.100s instead.", + logit("No valid SSH1 cipher, using %.100s instead.", cipher_name(ssh_cipher_default)); options.cipher = ssh_cipher_default; } @@ -1140,10 +654,6 @@ void ssh_userauth1(const char *local_user, const char *server_user, char *host, Sensitive *sensitive) { -#ifdef KRB5 - krb5_context context = NULL; - krb5_auth_context auth_context = NULL; -#endif int i, type; if (supported_authentications == 0) @@ -1168,56 +678,6 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, 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) { - debug("Trying Kerberos v5 authentication."); - - if (try_krb5_authentication(&context, &auth_context)) { - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos v5 auth", type); - } - } -#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(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to Kerberos v4 auth", type); - } - } -#endif /* KRB4 */ - - /* - * Use rhosts authentication if running in privileged socket and we - * do not wish to remain anonymous. - */ - if ((supported_authentications & (1 << SSH_AUTH_RHOSTS)) && - options.rhosts_authentication) { - debug("Trying rhosts authentication."); - packet_start(SSH_CMSG_AUTH_RHOSTS); - packet_put_cstring(local_user); - packet_send(); - packet_write_wait(); - - /* The server should respond with success or failure. */ - type = packet_read(); - if (type == SSH_SMSG_SUCCESS) - goto success; - if (type != SSH_SMSG_FAILURE) - packet_disconnect("Protocol error: got %d in response to rhosts auth", - type); - } /* * Try .rhosts or /etc/hosts.equiv authentication with RSA host * authentication. @@ -1271,36 +731,5 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host, /* NOTREACHED */ success: -#ifdef KRB5 - /* Try Kerberos v5 TGT passing. */ - if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) && - options.kerberos_tgt_passing && context && auth_context) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb5_tgt(context, auth_context); - } - if (auth_context) - krb5_auth_con_free(context, auth_context); - 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)) && - options.kerberos_tgt_passing) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!"); - send_krb4_tgt(); - } - /* Try AFS token passing if the server supports it. */ - if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) && - options.afs_token_passing && k_hasafs()) { - if (options.cipher == SSH_CIPHER_NONE) - log("WARNING: Encryption is disabled! Token will be transmitted in the clear!"); - send_afs_tokens(); - } -#endif /* AFS */ - return; /* need statement after label */ } diff --git a/crypto/openssh/sshconnect2.c b/crypto/openssh/sshconnect2.c index 642b34b..933c223 100644 --- a/crypto/openssh/sshconnect2.c +++ b/crypto/openssh/sshconnect2.c @@ -23,7 +23,9 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.124 2003/08/25 10:33:33 djm Exp $"); + +#include "openbsd-compat/sys-queue.h" #include "ssh.h" #include "ssh2.h" @@ -48,6 +50,10 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $"); #include "msg.h" #include "pathnames.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + /* import */ extern char *client_version_string; extern char *server_version_string; @@ -58,7 +64,7 @@ extern Options options; */ u_char *session_id2 = NULL; -int session_id2_len = 0; +u_int session_id2_len = 0; char *xxx_host; struct sockaddr *xxx_hostaddr; @@ -82,7 +88,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) xxx_hostaddr = hostaddr; if (options.ciphers == (char *)-1) { - log("No valid ciphers for protocol version 2 given, using defaults."); + logit("No valid ciphers for protocol version 2 given, using defaults."); options.ciphers = NULL; } if (options.ciphers != NULL) { @@ -108,6 +114,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = options.hostkeyalgorithms; + if (options.rekey_limit) + packet_set_rekey_limit(options.rekey_limit); + /* start key exchange */ kex = kex_setup(myproposal); kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; @@ -138,10 +147,18 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) typedef struct Authctxt Authctxt; typedef struct Authmethod Authmethod; - -typedef int sign_cb_fn( - Authctxt *authctxt, Key *key, - u_char **sigp, u_int *lenp, u_char *data, u_int datalen); +typedef struct identity Identity; +typedef struct idlist Idlist; + +struct identity { + TAILQ_ENTRY(identity) next; + AuthenticationConnection *ac; /* set if agent supports key */ + Key *key; /* public/private key */ + char *filename; /* comment for agent-only keys */ + int tried; + int isprivate; /* key points to the private key */ +}; +TAILQ_HEAD(idlist, identity); struct Authctxt { const char *server_user; @@ -152,14 +169,14 @@ struct Authctxt { int success; char *authlist; /* pubkey */ - Key *last_key; - sign_cb_fn *last_key_sign; - int last_key_hint; + Idlist keys; AuthenticationConnection *agent; /* hostbased */ Sensitive *sensitive; /* kbd-interactive */ int info_req_seen; + /* generic */ + void *methoddata; }; struct Authmethod { char *name; /* string to compare against server's list */ @@ -181,17 +198,35 @@ int userauth_pubkey(Authctxt *); int userauth_passwd(Authctxt *); int userauth_kbdint(Authctxt *); int userauth_hostbased(Authctxt *); +int userauth_kerberos(Authctxt *); + +#ifdef GSSAPI +int userauth_gssapi(Authctxt *authctxt); +void input_gssapi_response(int type, u_int32_t, void *); +void input_gssapi_token(int type, u_int32_t, void *); +void input_gssapi_hash(int type, u_int32_t, void *); +void input_gssapi_error(int, u_int32_t, void *); +void input_gssapi_errtok(int, u_int32_t, void *); +#endif void userauth(Authctxt *, char *); -static int sign_and_send_pubkey(Authctxt *, Key *, sign_cb_fn *); -static void clear_auth_state(Authctxt *); +static int sign_and_send_pubkey(Authctxt *, Identity *); +static void pubkey_prepare(Authctxt *); +static void pubkey_cleanup(Authctxt *); +static Key *load_identity_file(char *); static Authmethod *authmethod_get(char *authlist); static Authmethod *authmethod_lookup(const char *name); static char *authmethods_get(void); Authmethod authmethods[] = { +#ifdef GSSAPI + {"gssapi", + userauth_gssapi, + &options.gss_authentication, + NULL}, +#endif {"hostbased", userauth_hostbased, &options.hostbased_authentication, @@ -248,7 +283,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, /* setup authentication context */ memset(&authctxt, 0, sizeof(authctxt)); - authctxt.agent = ssh_get_authentication_connection(); + pubkey_prepare(&authctxt); authctxt.server_user = server_user; authctxt.local_user = local_user; authctxt.host = host; @@ -256,6 +291,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, authctxt.success = 0; authctxt.method = authmethod_lookup("none"); authctxt.authlist = NULL; + authctxt.methoddata = NULL; authctxt.sensitive = sensitive; authctxt.info_req_seen = 0; if (authctxt.method == NULL) @@ -270,14 +306,19 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, dispatch_set(SSH2_MSG_USERAUTH_BANNER, &input_userauth_banner); dispatch_run(DISPATCH_BLOCK, &authctxt.success, &authctxt); /* loop until success */ - if (authctxt.agent != NULL) - ssh_close_authentication_connection(authctxt.agent); + pubkey_cleanup(&authctxt); + dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL); debug("Authentication succeeded (%s).", authctxt.method->name); } + void userauth(Authctxt *authctxt, char *authlist) { + if (authctxt->methoddata) { + xfree(authctxt->methoddata); + authctxt->methoddata = NULL; + } if (authlist == NULL) { authlist = authctxt->authlist; } else { @@ -290,6 +331,12 @@ userauth(Authctxt *authctxt, char *authlist) if (method == NULL) fatal("Permission denied (%s).", authlist); authctxt->method = method; + + /* reset the per method handler */ + dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN, + SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); + + /* and try new method */ if (method->userauth(authctxt) != 0) { debug2("we sent a %s packet, wait for reply", method->name); break; @@ -314,7 +361,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt) debug3("input_userauth_banner"); msg = packet_get_string(NULL); lang = packet_get_string(NULL); - fprintf(stderr, "%s", msg); + logit("%s", msg); xfree(msg); xfree(lang); } @@ -327,7 +374,8 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt) fatal("input_userauth_success: no authentication context"); if (authctxt->authlist) xfree(authctxt->authlist); - clear_auth_state(authctxt); + if (authctxt->methoddata) + xfree(authctxt->methoddata); authctxt->success = 1; /* break out */ } @@ -346,10 +394,9 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt) packet_check_eom(); if (partial != 0) - log("Authenticated with partial success."); + logit("Authenticated with partial success."); debug("Authentications that can continue: %s", authlist); - clear_auth_state(authctxt); userauth(authctxt, authlist); } void @@ -357,6 +404,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; Key *key = NULL; + Identity *id = NULL; Buffer b; int pktype, sent = 0; u_int alen, blen; @@ -379,55 +427,267 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) } packet_check_eom(); - debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d", - pkalg, blen, authctxt->last_key, authctxt->last_key_hint); + debug("Server accepts key: pkalg %s blen %u", pkalg, blen); - do { - if (authctxt->last_key == NULL || - authctxt->last_key_sign == NULL) { - debug("no last key or no sign cb"); - break; - } - if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { - debug("unknown pkalg %s", pkalg); - break; - } - if ((key = key_from_blob(pkblob, blen)) == NULL) { - 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); - if (!key_equal(key, authctxt->last_key)) { - debug("key != last_key"); + if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) { + debug("unknown pkalg %s", pkalg); + goto done; + } + if ((key = key_from_blob(pkblob, blen)) == NULL) { + debug("no key from blob. pkalg %s", pkalg); + goto done; + } + if (key->type != pktype) { + error("input_userauth_pk_ok: type mismatch " + "for decoded key (received %d, expected %d)", + key->type, pktype); + goto done; + } + fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + debug2("input_userauth_pk_ok: fp %s", fp); + xfree(fp); + + TAILQ_FOREACH(id, &authctxt->keys, next) { + if (key_equal(key, id->key)) { + sent = sign_and_send_pubkey(authctxt, id); break; } - sent = sign_and_send_pubkey(authctxt, key, - authctxt->last_key_sign); - } while (0); - + } +done: if (key != NULL) key_free(key); xfree(pkalg); xfree(pkblob); - /* unregister */ - clear_auth_state(authctxt); - dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL); - /* try another method if we did not send a packet */ if (sent == 0) userauth(authctxt, NULL); +} + +#ifdef GSSAPI +int +userauth_gssapi(Authctxt *authctxt) +{ + Gssctxt *gssctxt = NULL; + static gss_OID_set supported = NULL; + static int mech = 0; + OM_uint32 min; + int ok = 0; + + /* Try one GSSAPI method at a time, rather than sending them all at + * once. */ + + if (supported == NULL) + gss_indicate_mechs(&min, &supported); + + /* Check to see if the mechanism is usable before we offer it */ + while (mech<supported->count && !ok) { + if (gssctxt) + ssh_gssapi_delete_ctx(&gssctxt); + ssh_gssapi_build_ctx(&gssctxt); + ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]); + + /* My DER encoding requires length<128 */ + if (supported->elements[mech].length < 128 && + !GSS_ERROR(ssh_gssapi_import_name(gssctxt, + authctxt->host))) { + ok = 1; /* Mechanism works */ + } else { + mech++; + } + } + + if (!ok) return 0; + + authctxt->methoddata=(void *)gssctxt; + + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_put_int(1); + + /* Some servers encode the OID incorrectly (as we used to) */ + if (datafellows & SSH_BUG_GSSAPI_BER) { + packet_put_string(supported->elements[mech].elements, + supported->elements[mech].length); + } else { + packet_put_int((supported->elements[mech].length)+2); + packet_put_char(SSH_GSS_OIDTYPE); + packet_put_char(supported->elements[mech].length); + packet_put_raw(supported->elements[mech].elements, + supported->elements[mech].length); + } + + packet_send(); + + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); + + mech++; /* Move along to next candidate */ + + return 1; +} + +void +input_gssapi_response(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + OM_uint32 status, ms; + int oidlen; + char *oidv; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); + gssctxt = authctxt->methoddata; + + /* Setup our OID */ + oidv = packet_get_string(&oidlen); + + if (datafellows & SSH_BUG_GSSAPI_BER) { + if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen)) + fatal("Server returned different OID than expected"); + } else { + if(oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen-2) { + debug("Badly encoded mechanism OID received"); + userauth(authctxt, NULL); + xfree(oidv); + return; + } + if (!ssh_gssapi_check_oid(gssctxt, oidv+2, oidlen-2)) + fatal("Server returned different OID than expected"); + } + + packet_check_eom(); + + xfree(oidv); + + status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, + GSS_C_NO_BUFFER, &send_tok, NULL); + if (GSS_ERROR(status)) { + if (send_tok.length > 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); + } + /* Start again with next method on list */ + debug("Trying to start again"); + userauth(authctxt, NULL); + return; + } + + /* We must have data to send */ + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); } +void +input_gssapi_token(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 status, ms; + u_int slen; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); + gssctxt = authctxt->methoddata; + + recv_tok.value = packet_get_string(&slen); + recv_tok.length = slen; /* safe typecast */ + + packet_check_eom(); + + status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, + &recv_tok, &send_tok, NULL); + + xfree(recv_tok.value); + + if (GSS_ERROR(status)) { + if (send_tok.length > 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); + } + /* Start again with the next method in the list */ + userauth(authctxt, NULL); + return; + } + + if (send_tok.length > 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + gss_release_buffer(&ms, &send_tok); + } + + if (status == GSS_S_COMPLETE) { + /* If that succeeded, send a exchange complete message */ + packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE); + packet_send(); + } +} + +void +input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 status, ms; + u_int len; + + if (authctxt == NULL) + fatal("input_gssapi_response: no authentication context"); + gssctxt = authctxt->methoddata; + + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; + + packet_check_eom(); + + /* Stick it into GSSAPI and see what it says */ + status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds, + &recv_tok, &send_tok, NULL); + + xfree(recv_tok.value); + gss_release_buffer(&ms, &send_tok); + + /* Server will be returning a failed packet after this one */ +} + +void +input_gssapi_error(int type, u_int32_t plen, void *ctxt) +{ + OM_uint32 maj, min; + char *msg; + char *lang; + + maj=packet_get_int(); + min=packet_get_int(); + msg=packet_get_string(NULL); + lang=packet_get_string(NULL); + + packet_check_eom(); + + debug("Server GSSAPI Error:\n%s\n", msg); + xfree(msg); + xfree(lang); +} +#endif /* GSSAPI */ + int userauth_none(Authctxt *authctxt) { @@ -491,7 +751,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) info = packet_get_string(NULL); lang = packet_get_string(NULL); if (strlen(info) > 0) - log("%s", info); + logit("%s", info); xfree(info); xfree(lang); packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -523,7 +783,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) if (strcmp(password, retype) != 0) { memset(password, 0, strlen(password)); xfree(password); - log("Mismatch; try again, EOF to quit."); + logit("Mismatch; try again, EOF to quit."); password = NULL; } memset(retype, 0, strlen(retype)); @@ -539,34 +799,44 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) &input_userauth_passwd_changereq); } -static void -clear_auth_state(Authctxt *authctxt) +static int +identity_sign(Identity *id, u_char **sigp, u_int *lenp, + u_char *data, u_int datalen) { - /* XXX clear authentication state */ - dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ, NULL); + Key *prv; + int ret; - if (authctxt->last_key != NULL && authctxt->last_key_hint == -1) { - debug3("clear_auth_state: key_free %p", authctxt->last_key); - key_free(authctxt->last_key); - } - authctxt->last_key = NULL; - authctxt->last_key_hint = -2; - authctxt->last_key_sign = NULL; + /* the agent supports this key */ + if (id->ac) + return (ssh_agent_sign(id->ac, id->key, sigp, lenp, + data, datalen)); + /* + * we have already loaded the private key or + * the private key is stored in external hardware + */ + if (id->isprivate || (id->key->flags & KEY_FLAG_EXT)) + return (key_sign(id->key, sigp, lenp, data, datalen)); + /* load the private key from the file */ + if ((prv = load_identity_file(id->filename)) == NULL) + return (-1); + ret = key_sign(prv, sigp, lenp, data, datalen); + key_free(prv); + return (ret); } static int -sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) +sign_and_send_pubkey(Authctxt *authctxt, Identity *id) { Buffer b; u_char *blob, *signature; u_int bloblen, slen; - int skip = 0; + u_int skip = 0; int ret = -1; int have_sig = 1; debug3("sign_and_send_pubkey"); - if (key_to_blob(k, &blob, &bloblen) == 0) { + if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("sign_and_send_pubkey: cannot handle key"); return 0; @@ -591,12 +861,12 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) } else { buffer_put_cstring(&b, authctxt->method->name); buffer_put_char(&b, have_sig); - buffer_put_cstring(&b, key_ssh_name(k)); + buffer_put_cstring(&b, key_ssh_name(id->key)); } buffer_put_string(&b, blob, bloblen); /* generate signature */ - ret = (*sign_callback)(authctxt, k, &signature, &slen, + ret = identity_sign(id, &signature, &slen, buffer_ptr(&b), buffer_len(&b)); if (ret == -1) { xfree(blob); @@ -616,7 +886,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) buffer_put_cstring(&b, authctxt->method->name); buffer_put_char(&b, have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) - buffer_put_cstring(&b, key_ssh_name(k)); + buffer_put_cstring(&b, key_ssh_name(id->key)); buffer_put_string(&b, blob, bloblen); } xfree(blob); @@ -640,23 +910,19 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback) } static int -send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback, - int hint) +send_pubkey_test(Authctxt *authctxt, Identity *id) { u_char *blob; u_int bloblen, have_sig = 0; debug3("send_pubkey_test"); - if (key_to_blob(k, &blob, &bloblen) == 0) { + if (key_to_blob(id->key, &blob, &bloblen) == 0) { /* we cannot handle this key */ debug3("send_pubkey_test: cannot handle key"); return 0; } /* register callback for USERAUTH_PK_OK message */ - authctxt->last_key_sign = sign_callback; - authctxt->last_key_hint = hint; - authctxt->last_key = k; dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok); packet_start(SSH2_MSG_USERAUTH_REQUEST); @@ -665,7 +931,7 @@ send_pubkey_test(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback, packet_put_cstring(authctxt->method->name); packet_put_char(have_sig); if (!(datafellows & SSH_BUG_PKAUTH)) - packet_put_cstring(key_ssh_name(k)); + packet_put_cstring(key_ssh_name(id->key)); packet_put_string(blob, bloblen); xfree(blob); packet_send(); @@ -710,103 +976,134 @@ load_identity_file(char *filename) return private; } -static int -identity_sign_cb(Authctxt *authctxt, Key *key, u_char **sigp, u_int *lenp, - u_char *data, u_int datalen) -{ - Key *private; - int idx, ret; - - idx = authctxt->last_key_hint; - if (idx < 0) - return -1; - - /* private key is stored in external hardware */ - 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]); - if (private == NULL) - return -1; - ret = key_sign(private, sigp, lenp, data, datalen); - key_free(private); - return ret; -} - -static int -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, u_int *lenp, - u_char *data, u_int datalen) +/* + * try keys in the following order: + * 1. agent keys that are found in the config file + * 2. other agent keys + * 3. keys that are only listed in the config file + */ +static void +pubkey_prepare(Authctxt *authctxt) { - return key_sign(key, sigp, lenp, data, datalen); + Identity *id; + Idlist agent, files, *preferred; + Key *key; + AuthenticationConnection *ac; + char *comment; + int i, found; + + TAILQ_INIT(&agent); /* keys from the agent */ + TAILQ_INIT(&files); /* keys from the config file */ + preferred = &authctxt->keys; + TAILQ_INIT(preferred); /* preferred order of keys */ + + /* list of keys stored in the filesystem */ + for (i = 0; i < options.num_identity_files; i++) { + key = options.identity_keys[i]; + if (key && key->type == KEY_RSA1) + continue; + options.identity_keys[i] = NULL; + id = xmalloc(sizeof(*id)); + memset(id, 0, sizeof(*id)); + id->key = key; + id->filename = xstrdup(options.identity_files[i]); + TAILQ_INSERT_TAIL(&files, id, next); + } + /* list of keys supported by the agent */ + if ((ac = ssh_get_authentication_connection())) { + for (key = ssh_get_first_identity(ac, &comment, 2); + key != NULL; + key = ssh_get_next_identity(ac, &comment, 2)) { + found = 0; + TAILQ_FOREACH(id, &files, next) { + /* agent keys from the config file are preferred */ + if (key_equal(key, id->key)) { + key_free(key); + xfree(comment); + TAILQ_REMOVE(&files, id, next); + TAILQ_INSERT_TAIL(preferred, id, next); + id->ac = ac; + found = 1; + break; + } + } + if (!found) { + id = xmalloc(sizeof(*id)); + memset(id, 0, sizeof(*id)); + id->key = key; + id->filename = comment; + id->ac = ac; + TAILQ_INSERT_TAIL(&agent, id, next); + } + } + /* append remaining agent keys */ + for (id = TAILQ_FIRST(&agent); id; id = TAILQ_FIRST(&agent)) { + TAILQ_REMOVE(&agent, id, next); + TAILQ_INSERT_TAIL(preferred, id, next); + } + authctxt->agent = ac; + } + /* append remaining keys from the config file */ + for (id = TAILQ_FIRST(&files); id; id = TAILQ_FIRST(&files)) { + TAILQ_REMOVE(&files, id, next); + TAILQ_INSERT_TAIL(preferred, id, next); + } + TAILQ_FOREACH(id, preferred, next) { + debug2("key: %s (%p)", id->filename, id->key); + } } -static int -userauth_pubkey_agent(Authctxt *authctxt) +static void +pubkey_cleanup(Authctxt *authctxt) { - static int called = 0; - int ret = 0; - char *comment; - Key *k; - - if (called == 0) { - if (ssh_get_num_identities(authctxt->agent, 2) == 0) - debug2("userauth_pubkey_agent: no keys at all"); - called = 1; - } - k = ssh_get_next_identity(authctxt->agent, &comment, 2); - if (k == NULL) { - debug2("userauth_pubkey_agent: no more keys"); - } else { - debug("Offering agent key: %s", comment); - xfree(comment); - ret = send_pubkey_test(authctxt, k, agent_sign_cb, -1); - if (ret == 0) - key_free(k); + Identity *id; + + if (authctxt->agent != NULL) + ssh_close_authentication_connection(authctxt->agent); + for (id = TAILQ_FIRST(&authctxt->keys); id; + id = TAILQ_FIRST(&authctxt->keys)) { + TAILQ_REMOVE(&authctxt->keys, id, next); + if (id->key) + key_free(id->key); + if (id->filename) + xfree(id->filename); + xfree(id); } - if (ret == 0) - debug2("userauth_pubkey_agent: no message sent"); - return ret; } int userauth_pubkey(Authctxt *authctxt) { - static int idx = 0; + Identity *id; int sent = 0; - Key *key; - char *filename; - if (authctxt->agent != NULL) { - do { - sent = userauth_pubkey_agent(authctxt); - } while (!sent && authctxt->agent->howmany > 0); - } - while (!sent && idx < options.num_identity_files) { - key = options.identity_keys[idx]; - filename = options.identity_files[idx]; - if (key == NULL) { - debug("Trying private key: %s", filename); - key = load_identity_file(filename); - if (key != NULL) { - sent = sign_and_send_pubkey(authctxt, key, - key_sign_cb); - key_free(key); + while ((id = TAILQ_FIRST(&authctxt->keys))) { + if (id->tried++) + return (0); + TAILQ_REMOVE(&authctxt->keys, id, next); + TAILQ_INSERT_TAIL(&authctxt->keys, id, next); + /* + * send a test message if we have the public key. for + * encrypted keys we cannot do this and have to load the + * private key instead + */ + if (id->key && id->key->type != KEY_RSA1) { + debug("Offering public key: %s", id->filename); + sent = send_pubkey_test(authctxt, id); + } else if (id->key == NULL) { + debug("Trying private key: %s", id->filename); + id->key = load_identity_file(id->filename); + if (id->key != NULL) { + id->isprivate = 1; + sent = sign_and_send_pubkey(authctxt, id); + key_free(id->key); + id->key = NULL; } - } else if (key->type != KEY_RSA1) { - debug("Offering public key: %s", filename); - sent = send_pubkey_test(authctxt, key, - identity_sign_cb, idx); } - idx++; + if (sent) + return (sent); } - return sent; + return (0); } /* @@ -862,9 +1159,9 @@ input_userauth_info_req(int type, u_int32_t seq, void *ctxt) inst = packet_get_string(NULL); lang = packet_get_string(NULL); if (strlen(name) > 0) - log("%s", name); + logit("%s", name); if (strlen(inst) > 0) - log("%s", inst); + logit("%s", inst); xfree(name); xfree(inst); xfree(lang); diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8 index a99c4f1..0eeea66 100644 --- a/crypto/openssh/sshd.8 +++ b/crypto/openssh/sshd.8 @@ -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.194 2003/01/31 21:54:40 jmc Exp $ +.\" $OpenBSD: sshd.8,v 1.199 2003/08/13 08:46:31 markus Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -114,6 +114,29 @@ authentication combined with RSA host authentication, RSA challenge-response authentication, or password based authentication. .Pp +Regardless of the authentication type, the account is checked to +ensure that it is accessible. An account is not accessible if it is +locked, listed in +.Cm DenyUsers +or its group is listed in +.Cm DenyGroups +\&. The definition of a locked account is system dependant. Some platforms +have their own account database (eg AIX) and some modify the passwd field ( +.Ql \&*LK\&* +on Solaris, +.Ql \&* +on HP-UX, containing +.Ql Nologin +on Tru64 and a leading +.Ql \&!! +on Linux). If there is a requirement to disable password authentication +for the account while allowing still public-key, then the passwd field +should be set to something other than these values (eg +.Ql NP +or +.Ql \&*NP\&* +). +.Pp Rhosts authentication is normally disabled because it is fundamentally insecure, but can be enabled in the server configuration file if desired. @@ -292,7 +315,6 @@ may also be used to prevent from making DNS requests unless the authentication mechanism or configuration requires it. Authentication mechanisms that may require DNS include -.Cm RhostsAuthentication , .Cm RhostsRSAAuthentication , .Cm HostbasedAuthentication and using a @@ -429,13 +451,13 @@ that option keywords are case-insensitive): Specifies that in addition to public key authentication, the canonical name of the remote host must be present in the comma-separated list of patterns -.Pf ( Ql * +.Pf ( Ql \&* and -.Ql ? +.Ql \&? serve as wildcards). The list may also contain patterns negated by prefixing them with -.Ql ! ; +.Ql \&! ; if the canonical host name matches a negated pattern, the key is not accepted. The purpose of this option is to optionally increase security: public key authentication @@ -497,9 +519,9 @@ IPv6 addresses can be specified with an alternative syntax: .Ar host/port . Multiple .Cm permitopen -options may be applied separated by commas. No pattern matching is -performed on the specified hostnames, they must be literal domains or -addresses. +options may be applied separated by commas. +No pattern matching is performed on the specified hostnames, +they must be literal domains or addresses. .El .Ss Examples 1024 33 12121.\|.\|.\|312314325 ylo@foo.bar @@ -524,12 +546,16 @@ Each line in these files contains the following fields: hostnames, bits, exponent, modulus, comment. The fields are separated by spaces. .Pp -Hostnames is a comma-separated list of patterns ('*' and '?' act as +Hostnames is a comma-separated list of patterns +.Pf ( Ql \&* +and +.Ql \&? +act as wildcards); each pattern in turn is matched against the canonical host name (when authenticating a client) or against the user-supplied name (when authenticating a server). A pattern may also be preceded by -.Ql ! +.Ql \&! to indicate negation: if the host name matches a negated pattern, it is not accepted (by that line) even if it matched another pattern on the line. @@ -767,17 +793,6 @@ This can be used to specify machine-specific login-time initializations globally. This file should be writable only by root, and should be world-readable. .El -.Sh AUTHORS -OpenSSH is a derivative of the original and free -ssh 1.2.12 release by Tatu Ylonen. -Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, -Theo de Raadt and Dug Song -removed many bugs, re-added newer features and -created OpenSSH. -Markus Friedl contributed the support for SSH -protocol versions 1.5 and 2.0. -Niels Provos and Markus Friedl contributed support -for privilege separation. .Sh SEE ALSO .Xr scp 1 , .Xr sftp 1 , @@ -809,3 +824,14 @@ for privilege separation. .%D January 2002 .%O work in progress material .Re +.Sh AUTHORS +OpenSSH is a derivative of the original and free +ssh 1.2.12 release by Tatu Ylonen. +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt and Dug Song +removed many bugs, re-added newer features and +created OpenSSH. +Markus Friedl contributed the support for SSH +protocol versions 1.5 and 2.0. +Niels Provos and Markus Friedl contributed support +for privilege separation. diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 0f2b2a3..47df9ca 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $"); #include <openssl/dh.h> #include <openssl/bn.h> @@ -112,11 +112,7 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; * Flag indicating whether IPv4 or IPv6. This can be set on the command line. * Default value is AF_UNSPEC means both IPv4 and IPv6. */ -#ifdef IPV4_DEFAULT -int IPv4or6 = AF_INET; -#else int IPv4or6 = AF_UNSPEC; -#endif /* * Debug mode flag. This can be set on the command line. If debug @@ -192,7 +188,7 @@ u_char session_id[16]; /* same for ssh2 */ u_char *session_id2 = NULL; -int session_id2_len = 0; +u_int session_id2_len = 0; /* record remote hostname or ip */ u_int utmp_len = MAXHOSTNAMELEN; @@ -205,6 +201,9 @@ int startup_pipe; /* in child */ int use_privsep; struct monitor *pmonitor; +/* message to be displayed after login */ +Buffer loginmsg; + /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); void demote_sensitive_data(void); @@ -258,11 +257,11 @@ sighup_handler(int sig) static void sighup_restart(void) { - log("Received SIGHUP; restarting."); + logit("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], + logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], strerror(errno)); exit(1); } @@ -371,39 +370,37 @@ sshd_exchange_identification(int sock_in, int sock_out) snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); server_version_string = xstrdup(buf); - if (client_version_string == NULL) { - /* Send our protocol version identification. */ - if (atomicio(write, sock_out, server_version_string, - strlen(server_version_string)) - != strlen(server_version_string)) { - log("Could not write ident string to %s", get_remote_ipaddr()); + /* Send our protocol version identification. */ + if (atomicio(vwrite, sock_out, server_version_string, + strlen(server_version_string)) + != strlen(server_version_string)) { + logit("Could not write ident string to %s", get_remote_ipaddr()); + fatal_cleanup(); + } + + /* Read other sides version identification. */ + memset(buf, 0, sizeof(buf)); + for (i = 0; i < sizeof(buf) - 1; i++) { + if (atomicio(read, sock_in, &buf[i], 1) != 1) { + logit("Did not receive identification string from %s", + get_remote_ipaddr()); fatal_cleanup(); } - - /* Read other sides version identification. */ - memset(buf, 0, sizeof(buf)); - for (i = 0; i < sizeof(buf) - 1; i++) { - if (atomicio(read, sock_in, &buf[i], 1) != 1) { - log("Did not receive identification string from %s", - get_remote_ipaddr()); - fatal_cleanup(); - } - if (buf[i] == '\r') { - buf[i] = 0; - /* Kludge for F-Secure Macintosh < 1.0.2 */ - if (i == 12 && - strncmp(buf, "SSH-1.5-W1.0", 12) == 0) - break; - continue; - } - if (buf[i] == '\n') { - buf[i] = 0; + if (buf[i] == '\r') { + buf[i] = 0; + /* Kludge for F-Secure Macintosh < 1.0.2 */ + if (i == 12 && + strncmp(buf, "SSH-1.5-W1.0", 12) == 0) break; - } + continue; + } + if (buf[i] == '\n') { + buf[i] = 0; + break; } - buf[sizeof(buf) - 1] = 0; - client_version_string = xstrdup(buf); } + buf[sizeof(buf) - 1] = 0; + client_version_string = xstrdup(buf); /* * Check that the versions match. In future this might accept @@ -412,10 +409,10 @@ sshd_exchange_identification(int sock_in, int sock_out) if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) { s = "Protocol mismatch.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); + (void) atomicio(vwrite, sock_out, s, strlen(s)); close(sock_in); close(sock_out); - log("Bad protocol version identification '%.100s' from %s", + logit("Bad protocol version identification '%.100s' from %s", client_version_string, get_remote_ipaddr()); fatal_cleanup(); } @@ -425,13 +422,13 @@ sshd_exchange_identification(int sock_in, int sock_out) compat_datafellows(remote_version); if (datafellows & SSH_BUG_PROBE) { - log("probed from %s with %s. Don't panic.", + logit("probed from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); fatal_cleanup(); } if (datafellows & SSH_BUG_SCANNER) { - log("scanned from %s with %s. Don't panic.", + logit("scanned from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); fatal_cleanup(); } @@ -473,10 +470,10 @@ sshd_exchange_identification(int sock_in, int sock_out) if (mismatch) { s = "Protocol major versions differ.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); + (void) atomicio(vwrite, sock_out, s, strlen(s)); close(sock_in); close(sock_out); - log("Protocol major versions differ for %s: %.200s vs. %.200s", + logit("Protocol major versions differ for %s: %.200s vs. %.200s", get_remote_ipaddr(), server_version_string, client_version_string); fatal_cleanup(); @@ -568,8 +565,6 @@ privsep_preauth_child(void) do_setusercontext(pw); #else gidset[0] = pw->pw_gid; - if (setgid(pw->pw_gid) < 0) - fatal("setgid failed for %u", pw->pw_gid ); if (setgroups(1, gidset) < 0) fatal("setgroups: %.100s", strerror(errno)); permanently_set_uid(pw); @@ -824,26 +819,27 @@ main(int ac, char **av) #ifdef HAVE_SECUREWARE (void)set_auth_parameters(ac, av); #endif - __progname = get_progname(av[0]); + __progname = ssh_get_progname(av[0]); init_rng(); /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; - saved_argv = av; - saved_argv = xmalloc(sizeof(*saved_argv) * ac); + saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1)); for (i = 0; i < ac; i++) saved_argv[i] = xstrdup(av[i]); + saved_argv[i] = NULL; #ifndef HAVE_SETPROCTITLE /* Prepare for later setproctitle emulation */ compat_init_setproctitle(ac, av); + av = saved_argv; #endif /* Initialize configuration options to their default values. */ initialize_server_options(&options); /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) { + while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqtQ46")) != -1) { switch (opt) { case '4': IPv4or6 = AF_INET; @@ -855,15 +851,11 @@ main(int ac, char **av) config_file_name = optarg; break; case 'd': - if (0 == debug_flag) { + if (debug_flag == 0) { debug_flag = 1; options.log_level = SYSLOG_LEVEL_DEBUG1; - } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { + } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) options.log_level++; - } else { - fprintf(stderr, "Too high debugging level.\n"); - exit(1); - } break; case 'D': no_daemon_flag = 1; @@ -914,11 +906,6 @@ main(int ac, char **av) } options.host_key_files[options.num_host_key_files++] = optarg; break; - case 'V': - client_version_string = optarg; - /* only makes sense with inetd_flag, i.e. no listen() */ - inetd_flag = 1; - break; case 't': test_flag = 1; break; @@ -1010,15 +997,15 @@ main(int ac, char **av) key_type(key)); } if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - log("Disabling protocol version 1. Could not load host key"); + logit("Disabling protocol version 1. Could not load host key"); options.protocol &= ~SSH_PROTO_1; } if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { - log("Disabling protocol version 2. Could not load host key"); + logit("Disabling protocol version 2. Could not load host key"); options.protocol &= ~SSH_PROTO_2; } if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { - log("sshd: no hostkeys available -- exiting."); + logit("sshd: no hostkeys available -- exiting."); exit(1); } @@ -1153,7 +1140,8 @@ main(int ac, char **av) continue; } /* Create socket for listening. */ - listen_sock = socket(ai->ai_family, SOCK_STREAM, 0); + listen_sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); if (listen_sock < 0) { /* kernel may not support ipv6 */ verbose("socket: %.100s", strerror(errno)); @@ -1186,7 +1174,7 @@ main(int ac, char **av) num_listen_socks++; /* Start listening on the port. */ - log("Server listening on %s port %s.", ntop, strport); + logit("Server listening on %s port %s.", ntop, strport); if (listen(listen_sock, 5) < 0) fatal("listen: %.100s", strerror(errno)); @@ -1221,7 +1209,10 @@ main(int ac, char **av) * overwrite any old pid in the file. */ f = fopen(options.pid_file, "wb"); - if (f) { + if (f == NULL) { + error("Couldn't create pid file \"%s\": %s", + options.pid_file, strerror(errno)); + } else { fprintf(f, "%ld\n", (long) getpid()); fclose(f); } @@ -1262,7 +1253,7 @@ main(int ac, char **av) if (ret < 0 && errno != EINTR) error("select: %.100s", strerror(errno)); if (received_sigterm) { - log("Received signal %d; terminating.", + logit("Received signal %d; terminating.", (int) received_sigterm); close_listen_socks(); unlink(options.pid_file); @@ -1400,11 +1391,11 @@ main(int ac, char **av) * setlogin() affects the entire process group. We don't * want the child to be able to affect the parent. */ -#if !defined(STREAMS_PUSH_ACQUIRES_CTTY) +#if !defined(SSHD_ACQUIRES_CTTY) /* - * If setsid is called on Solaris, sshd will acquire the controlling - * terminal while pushing STREAMS modules. This will prevent the - * shell from acquiring it later. + * If setsid is called, on some platforms sshd will later acquire a + * controlling terminal which will result in "could not set + * controlling tty" errors. */ if (!debug_flag && !inetd_flag && setsid() < 0) error("setsid: %.100s", strerror(errno)); @@ -1471,37 +1462,12 @@ main(int ac, char **av) alarm(options.login_grace_time); sshd_exchange_identification(sock_in, sock_out); - /* - * Check that the connection comes from a privileged port. - * Rhosts-Authentication only makes sense from privileged - * programs. Of course, if the intruder has root access on his local - * machine, he can connect from any port. So do not use these - * authentication methods from machines that you do not trust. - */ - 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; - } -#if defined(KRB4) && !defined(KRB5) - if (!packet_connection_is_ipv4() && - options.kerberos_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.kerberos_authentication = 0; - } -#endif /* KRB4 && !KRB5 */ -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ packet_set_nonblocking(); + /* prepare buffers to collect authentication messages */ + buffer_init(&loginmsg); + if (use_privsep) if ((authctxt = privsep_preauth()) != NULL) goto authenticated; @@ -1543,7 +1509,8 @@ main(int ac, char **av) verbose("Closing connection to %.100s", remote_ip); #ifdef USE_PAM - finish_pam(); + if (options.use_pam) + finish_pam(); #endif /* USE_PAM */ packet_close(); @@ -1655,24 +1622,10 @@ do_ssh1_kex(void) /* Declare supported authentication types. */ auth_mask = 0; - if (options.rhosts_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS; if (options.rhosts_rsa_authentication) auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; if (options.rsa_authentication) auth_mask |= 1 << SSH_AUTH_RSA; -#if defined(KRB4) || defined(KRB5) - if (options.kerberos_authentication) - auth_mask |= 1 << SSH_AUTH_KERBEROS; -#endif -#if defined(AFS) || defined(KRB5) - if (options.kerberos_tgt_passing) - auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; -#endif -#ifdef AFS - if (options.afs_token_passing) - auth_mask |= 1 << SSH_PASS_AFS_TOKEN; -#endif if (options.challenge_response_authentication == 1) auth_mask |= 1 << SSH_AUTH_TIS; if (options.password_authentication) @@ -1750,7 +1703,7 @@ do_ssh1_kex(void) u_char *buf = xmalloc(bytes); MD5_CTX md; - log("do_connection: generating a fake encryption key"); + logit("do_connection: generating a fake encryption key"); BN_bn2bin(session_key_int, buf); MD5_Init(&md); MD5_Update(&md, buf, bytes); diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index 36429c9..dd53f10 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.59 2002/09/25 11:17:16 markus Exp $ +# $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -22,7 +22,7 @@ #HostKey /etc/ssh/ssh_host_dsa_key # Lifetime and size of ephemeral version 1 server key -#KeyRegenerationInterval 3600 +#KeyRegenerationInterval 1h #ServerKeyBits 768 # Logging @@ -32,7 +32,7 @@ # Authentication: -#LoginGraceTime 120 +#LoginGraceTime 2m #PermitRootLogin yes #StrictModes yes @@ -40,10 +40,6 @@ #PubkeyAuthentication yes #AuthorizedKeysFile .ssh/authorized_keys -# rhosts authentication should not be used -#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/ssh_known_hosts #RhostsRSAAuthentication no # similar for protocol version 2 @@ -51,6 +47,8 @@ # Change to yes if you don't trust ~/.ssh/known_hosts for # RhostsRSAAuthentication and HostbasedAuthentication #IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes # To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes @@ -64,15 +62,17 @@ #KerberosOrLocalPasswd yes #KerberosTicketCleanup yes -#AFSTokenPassing no +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCreds 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 no +# Set this to 'yes' to enable PAM authentication (via challenge-response) +# and session processing. Depending on your PAM configuration, this may +# bypass the setting of 'PasswordAuthentication' +#UsePAM yes +#AllowTcpForwarding yes +#GatewayPorts no #X11Forwarding no #X11DisplayOffset 10 #X11UseLocalhost yes @@ -83,11 +83,14 @@ #UsePrivilegeSeparation yes #PermitUserEnvironment no #Compression yes - +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS yes +#PidFile /var/run/sshd.pid #MaxStartups 10 + # no default banner path #Banner /some/path -#VerifyReverseMapping no # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5 index 6f38a260..727fdb1 100644 --- a/crypto/openssh/sshd_config.5 +++ b/crypto/openssh/sshd_config.5 @@ -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_config.5,v 1.15 2003/03/28 10:11:43 jmc Exp $ +.\" $OpenBSD: sshd_config.5,v 1.25 2003/09/01 09:50:04 markus Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -61,10 +61,6 @@ The possible keywords and their meanings are as follows (note that keywords are case-insensitive and arguments are case-sensitive): .Bl -tag -width Ds -.It Cm AFSTokenPassing -Specifies whether an AFS token may be forwarded to the server. -Default is -.Dq no . .It Cm AllowGroups This keyword can be followed by a list of group name patterns, separated by spaces. @@ -72,7 +68,7 @@ If specified, login is allowed only for users whose primary group or supplementary group list matches one of the patterns. .Ql \&* and -.Ql ? +.Ql \&? can be used as wildcards in the patterns. Only group names are valid; a numerical group ID is not recognized. @@ -93,7 +89,7 @@ If specified, login is allowed only for user names that match one of the patterns. .Ql \&* and -.Ql ? +.Ql \&? can be used as wildcards in the patterns. Only user names are valid; a numerical user ID is not recognized. @@ -107,7 +103,8 @@ Specifies the file that contains the public keys that can be used for user authentication. .Cm AuthorizedKeysFile may contain tokens of the form %T which are substituted during connection -set-up. The following tokens are defined: %% is replaced by a literal '%', +set-up. +The following tokens are defined: %% is replaced by a literal '%', %h is replaced by the home directory of the user being authenticated and %u is replaced by the username of that user. After expansion, @@ -138,7 +135,7 @@ The default is .Pp .Bd -literal ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, - aes192-cbc,aes256-cbc'' + aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr'' .Ed .It Cm ClientAliveInterval Sets a timeout interval in seconds after which if no data has been received @@ -153,20 +150,24 @@ This option applies to protocol version 2 only. Sets the number of client alive messages (see above) which may be sent without .Nm sshd -receiving any messages back from the client. If this threshold is -reached while client alive messages are being sent, +receiving any messages back from the client. +If this threshold is reached while client alive messages are being sent, .Nm sshd -will disconnect the client, terminating the session. It is important -to note that the use of client alive messages is very different from +will disconnect the client, terminating the session. +It is important to note that the use of client alive messages is very +different from .Cm KeepAlive -(below). The client alive messages are sent through the -encrypted channel and therefore will not be spoofable. The TCP keepalive -option enabled by +(below). +The client alive messages are sent through the encrypted channel +and therefore will not be spoofable. +The TCP keepalive option enabled by .Cm KeepAlive -is spoofable. The client alive mechanism is valuable when the client or +is spoofable. +The client alive mechanism is valuable when the client or server depend on knowing when a connection has become inactive. .Pp -The default value is 3. If +The default value is 3. +If .Cm ClientAliveInterval (above) is set to 15, and .Cm ClientAliveCountMax @@ -187,7 +188,7 @@ Login is disallowed for users whose primary group or supplementary group list matches one of the patterns. .Ql \&* and -.Ql ? +.Ql \&? can be used as wildcards in the patterns. Only group names are valid; a numerical group ID is not recognized. @@ -199,7 +200,7 @@ by spaces. Login is disallowed for user names that match one of the patterns. .Ql \&* and -.Ql ? +.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 for all users. @@ -224,6 +225,17 @@ or .Dq no . The default is .Dq no . +.It Cm GSSAPIAuthentication +Specifies whether user authentication based on GSSAPI is allowed. +The default is +.Dq no . +Note that this option applies to protocol version 2 only. +.It Cm GSSAPICleanupCredentials +Specifies whether to automatically destroy the user's credentials cache +on logout. +The default is +.Dq yes . +Note that this option applies to protocol version 2 only. .It Cm HostbasedAuthentication Specifies whether rhosts or /etc/hosts.equiv authentication together with successful public key client host authentication is allowed @@ -259,7 +271,6 @@ Specifies that and .Pa .shosts files will not be used in -.Cm RhostsAuthentication , .Cm RhostsRSAAuthentication or .Cm HostbasedAuthentication . @@ -303,11 +314,9 @@ This avoids infinitely hanging sessions. To disable keepalives, the value should be set to .Dq no . .It Cm KerberosAuthentication -Specifies whether Kerberos authentication is allowed. -This can be in the form of a Kerberos ticket, or if +Specifies whether the password provided by the user for .Cm PasswordAuthentication -is yes, the password provided by the user will be validated through -the Kerberos KDC. +will be validated through the Kerberos KDC. To use this option, the server needs a Kerberos servtab which allows the verification of the KDC's identity. Default is @@ -319,11 +328,6 @@ such as .Pa /etc/passwd . Default is .Dq yes . -.It Cm KerberosTgtPassing -Specifies whether a Kerberos TGT may be forwarded to the server. -Default is -.Dq no , -as this only works when the Kerberos KDC is actually an AFS kaserver. .It Cm KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. @@ -369,11 +373,12 @@ is not specified, .Nm sshd will listen on the address and all prior .Cm Port -options specified. The default is to listen on all local -addresses. +options specified. +The default is to listen on all local addresses. Multiple .Cm ListenAddress -options are permitted. Additionally, any +options are permitted. +Additionally, any .Cm Port options must precede this option for non port qualified addresses. .It Cm LoginGraceTime @@ -422,12 +427,6 @@ The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches .Dq full (60). -.It Cm PAMAuthenticationViaKbdInt -Specifies whether PAM challenge response authentication is allowed. This -allows the use of most PAM challenge response authentication modules, but -it will allow password authentication regardless of whether -.Cm PasswordAuthentication -is enabled. .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is @@ -460,8 +459,8 @@ but only if the .Ar command option has been specified (which may be useful for taking remote backups even if root login is -normally not allowed). All other authentication methods are disabled -for root. +normally not allowed). +All other authentication methods are disabled for root. .Pp If this option is set to .Dq no @@ -534,10 +533,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 RhostsAuthentication -Specifies whether authentication using rhosts or /etc/hosts.equiv -files is sufficient. -Normally, this method should not be permitted because it is insecure. .Cm RhostsRSAAuthentication should be used instead, because it performs RSA-based host authentication in addition @@ -585,6 +580,14 @@ Gives the facility code that is used when logging messages from The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. The default is AUTH. +.It Cm UseDNS +Specifies whether +.Nm sshd +should lookup 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 yes . .It Cm UseLogin Specifies whether .Xr login 1 @@ -604,6 +607,13 @@ cookies. If .Cm UsePrivilegeSeparation is specified, it will be disabled after authentication. +.It Cm UsePAM +Enables PAM authentication (via challenge-response) and session set up. +If you enable this, you should probably disable +.Cm PasswordAuthentication . +If you enable +.CM UsePAM +then you will not be able to run sshd as a non-root user. .It Cm UsePrivilegeSeparation Specifies whether .Nm sshd @@ -615,14 +625,6 @@ The goal of privilege separation is to prevent privilege escalation by containing any corruption within the unprivileged processes. The default is .Dq yes . -.It Cm VerifyReverseMapping -Specifies whether -.Nm sshd -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 @@ -653,7 +655,7 @@ display server may be exposed to attack when the ssh client requests forwarding (see the warnings for .Cm ForwardX11 in -.Xr ssh_config 5 ). +.Xr ssh_config 5 ) . A system administrator may have a stance in which they want to protect clients that may expose themselves to attack by unwittingly requesting X11 forwarding, which can warrant a @@ -699,7 +701,6 @@ The default is .Pa /usr/X11R6/bin/xauth . .El .Ss Time Formats -.Pp .Nm sshd command-line arguments and configuration file options that specify time may be expressed using a sequence of the form: @@ -748,6 +749,8 @@ Contains configuration data for This file should be writable by root only, but it is recommended (though not necessary) that it be world-readable. .El +.Sh SEE ALSO +.Xr sshd 8 .Sh AUTHORS OpenSSH is a derivative of the original and free ssh 1.2.12 release by Tatu Ylonen. @@ -759,5 +762,3 @@ Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -.Sh SEE ALSO -.Xr sshd 8 diff --git a/crypto/openssh/sshlogin.c b/crypto/openssh/sshlogin.c index 12555d6..36b6489 100644 --- a/crypto/openssh/sshlogin.c +++ b/crypto/openssh/sshlogin.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshlogin.c,v 1.5 2002/08/29 15:57:25 stevesk Exp $"); +RCSID("$OpenBSD: sshlogin.c,v 1.7 2003/06/12 07:57:38 markus Exp $"); #include "loginrec.h" @@ -60,8 +60,8 @@ get_last_login_time(uid_t uid, const char *logname, } /* - * Records that the user has logged in. I these parts of operating systems - * were more standardized. + * Records that the user has logged in. I wish these parts of operating + * systems were more standardized. */ void record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, diff --git a/crypto/openssh/sshpty.c b/crypto/openssh/sshpty.c index d28947f..4747cea 100644 --- a/crypto/openssh/sshpty.c +++ b/crypto/openssh/sshpty.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshpty.c,v 1.8 2003/02/03 08:56:16 markus Exp $"); +RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); #ifdef HAVE_UTIL_H # include <util.h> @@ -101,12 +101,12 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) error("/dev/ptmx: %.100s", strerror(errno)); return 0; } - old_signal = mysignal(SIGCHLD, SIG_DFL); + old_signal = signal(SIGCHLD, SIG_DFL); if (grantpt(ptm) < 0) { error("grantpt: %.100s", strerror(errno)); return 0; } - mysignal(SIGCHLD, old_signal); + signal(SIGCHLD, old_signal); if (unlockpt(ptm) < 0) { error("unlockpt: %.100s", strerror(errno)); return 0; @@ -226,7 +226,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) } /* set tty modes to a sane state for broken clients */ if (tcgetattr(*ptyfd, &tio) < 0) - log("Getting tty modes for pty failed: %.100s", strerror(errno)); + logit("Getting tty modes for pty failed: %.100s", strerror(errno)); else { tio.c_lflag |= (ECHO | ISIG | ICANON); tio.c_oflag |= (OPOST | ONLCR); @@ -234,7 +234,7 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) /* Set the new modes for the terminal. */ if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) - log("Setting tty modes for pty failed: %.100s", strerror(errno)); + logit("Setting tty modes for pty failed: %.100s", strerror(errno)); } return 1; @@ -258,7 +258,7 @@ pty_release(const char *ttyname) error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); } -/* Makes the tty the processes controlling tty and sets it to sane modes. */ +/* Makes the tty the process's controlling tty and sets it to sane modes. */ void pty_make_controlling_tty(int *ttyfd, const char *ttyname) @@ -274,9 +274,9 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) fd = open(ttyname, O_RDWR|O_NOCTTY); if (fd != -1) { - mysignal(SIGHUP, SIG_IGN); + signal(SIGHUP, SIG_IGN); ioctl(fd, TCVHUP, (char *)NULL); - mysignal(SIGHUP, SIG_DFL); + signal(SIGHUP, SIG_DFL); setpgid(0, 0); close(fd); } else { @@ -323,9 +323,9 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) error("SETPGRP %s",strerror(errno)); #endif /* HAVE_NEWS4 */ #ifdef USE_VHANGUP - old = mysignal(SIGHUP, SIG_IGN); + old = signal(SIGHUP, SIG_IGN); vhangup(); - mysignal(SIGHUP, old); + signal(SIGHUP, old); #endif /* USE_VHANGUP */ fd = open(ttyname, O_RDWR); if (fd < 0) { @@ -409,10 +409,10 @@ pty_setowner(struct passwd *pw, const char *ttyname) if (errno == EROFS && (st.st_mode & (S_IRGRP | S_IROTH)) == 0) debug("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); + ttyname, (u_int)mode, strerror(errno)); else fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); + ttyname, (u_int)mode, strerror(errno)); } } } diff --git a/crypto/openssh/sshtty.c b/crypto/openssh/sshtty.c index 5c016f8..2f47b06 100644 --- a/crypto/openssh/sshtty.c +++ b/crypto/openssh/sshtty.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshtty.c,v 1.3 2002/03/04 17:27:39 stevesk Exp $"); +RCSID("$OpenBSD: sshtty.c,v 1.4 2003/07/16 10:36:28 markus Exp $"); #include "sshtty.h" #include "log.h" @@ -80,6 +80,9 @@ enter_raw_mode(void) _saved_tio = tio; tio.c_iflag |= IGNPAR; tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); +#ifdef IUCLC + tio.c_iflag &= ~IUCLC; +#endif tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); #ifdef IEXTEN tio.c_lflag &= ~IEXTEN; diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c index 5cc13dc..c32e213 100644 --- a/crypto/openssh/ttymodes.c +++ b/crypto/openssh/ttymodes.c @@ -43,7 +43,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ttymodes.c,v 1.18 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: ttymodes.c,v 1.19 2003/04/08 20:21:29 itojun Exp $"); #include "packet.h" #include "log.h" @@ -267,7 +267,7 @@ tty_make_modes(int fd, struct termios *tiop) if (tiop == NULL) { if (tcgetattr(fd, &tio) == -1) { - log("tcgetattr: %.100s", strerror(errno)); + logit("tcgetattr: %.100s", strerror(errno)); goto end; } } else @@ -341,7 +341,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr) * modes, they will initially have reasonable values. */ if (tcgetattr(fd, &tio) == -1) { - log("tcgetattr: %.100s", strerror(errno)); + logit("tcgetattr: %.100s", strerror(errno)); failure = -1; } @@ -420,7 +420,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr) * left in the packet; hopefully there is nothing * more coming after the mode data. */ - log("parse_tty_modes: unknown opcode %d", opcode); + logit("parse_tty_modes: unknown opcode %d", opcode); goto set; } } else { @@ -436,7 +436,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr) (void) packet_get_int(); break; } else { - log("parse_tty_modes: unknown opcode %d", opcode); + logit("parse_tty_modes: unknown opcode %d", opcode); goto set; } } @@ -446,7 +446,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr) set: if (*n_bytes_ptr != n_bytes) { *n_bytes_ptr = n_bytes; - log("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", + logit("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", *n_bytes_ptr, n_bytes); return; /* Don't process bytes passed */ } @@ -455,5 +455,5 @@ set: /* Set the new modes for the terminal. */ if (tcsetattr(fd, TCSANOW, &tio) == -1) - log("Setting tty modes failed: %.100s", strerror(errno)); + logit("Setting tty modes failed: %.100s", strerror(errno)); } diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c index 86c61a4..9e161d0f 100644 --- a/crypto/openssh/uidswap.c +++ b/crypto/openssh/uidswap.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: uidswap.c,v 1.23 2002/07/15 17:15:31 stevesk Exp $"); +RCSID("$OpenBSD: uidswap.c,v 1.24 2003/05/29 16:58:45 deraadt Exp $"); #include "log.h" #include "uidswap.h" @@ -143,12 +143,65 @@ restore_uid(void) void permanently_set_uid(struct passwd *pw) { + uid_t old_uid = getuid(); + gid_t old_gid = getgid(); + if (temporarily_use_uid_effective) fatal("permanently_set_uid: temporarily_use_uid effective"); debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); + +#if defined(HAVE_SETRESGID) + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) + fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) + if (setregid(pw->pw_gid, pw->pw_gid) < 0) + fatal("setregid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#else + if (setegid(pw->pw_gid) < 0) + fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); if (setgid(pw->pw_gid) < 0) fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#endif + +#if defined(HAVE_SETRESUID) + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) + fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) + if (setreuid(pw->pw_uid, pw->pw_uid) < 0) + fatal("setreuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#else +# ifndef SETEUID_BREAKS_SETUID + if (seteuid(pw->pw_uid) < 0) + fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +# endif if (setuid(pw->pw_uid) < 0) fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#endif + + /* Try restoration of GID if changed (test clearing of saved gid) */ + if (old_gid != pw->pw_gid && + (setgid(old_gid) != -1 || setegid(old_gid) != -1)) + fatal("%s: was able to restore old [e]gid", __func__); + + /* Verify GID drop was successful */ + if (getgid() != pw->pw_gid || getegid() != pw->pw_gid) { + fatal("%s: egid incorrect gid:%u egid:%u (should be %u)", + __func__, (u_int)getgid(), (u_int)getegid(), + (u_int)pw->pw_gid); + } + +#ifndef HAVE_CYGWIN + /* Try restoration of UID if changed (test clearing of saved uid) */ + if (old_uid != pw->pw_uid && + (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) + fatal("%s: was able to restore old [e]uid", __func__); +#endif + + /* Verify UID drop was successful */ + if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) { + fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", + __func__, (u_int)getuid(), (u_int)geteuid(), + (u_int)pw->pw_uid); + } } diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index 75a2b25..0a98e42 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -1,3 +1,3 @@ -/* $OpenBSD: version.h,v 1.37 2003/04/01 10:56:46 markus Exp $ */ +/* $OpenBSD: version.h,v 1.39 2003/09/16 21:02:40 markus Exp $ */ -#define SSH_VERSION "OpenSSH_3.6.1p1" +#define SSH_VERSION "OpenSSH_3.7.1p2" |