Welcome a trimmed version of OpenSSH-4.1p1 in the tree.
authorSimon Schubert <corecode@dragonflybsd.org>
Mon, 11 Jul 2005 22:44:24 +0000 (22:44 +0000)
committerSimon Schubert <corecode@dragonflybsd.org>
Mon, 11 Jul 2005 22:44:24 +0000 (22:44 +0000)
213 files changed:
crypto/openssh-4/CREDITS [new file with mode: 0644]
crypto/openssh-4/LICENCE [new file with mode: 0644]
crypto/openssh-4/README [new file with mode: 0644]
crypto/openssh-4/README.dns [new file with mode: 0644]
crypto/openssh-4/acss.c [new file with mode: 0644]
crypto/openssh-4/acss.h [new file with mode: 0644]
crypto/openssh-4/atomicio.c [new file with mode: 0644]
crypto/openssh-4/atomicio.h [new file with mode: 0644]
crypto/openssh-4/audit-bsm.c [new file with mode: 0644]
crypto/openssh-4/audit.c [new file with mode: 0644]
crypto/openssh-4/audit.h [new file with mode: 0644]
crypto/openssh-4/auth-bsdauth.c [new file with mode: 0644]
crypto/openssh-4/auth-chall.c [new file with mode: 0644]
crypto/openssh-4/auth-krb5.c [new file with mode: 0644]
crypto/openssh-4/auth-options.c [new file with mode: 0644]
crypto/openssh-4/auth-options.h [new file with mode: 0644]
crypto/openssh-4/auth-pam.h [new file with mode: 0644]
crypto/openssh-4/auth-passwd.c [new file with mode: 0644]
crypto/openssh-4/auth-rh-rsa.c [new file with mode: 0644]
crypto/openssh-4/auth-rhosts.c [new file with mode: 0644]
crypto/openssh-4/auth-rsa.c [new file with mode: 0644]
crypto/openssh-4/auth.c [new file with mode: 0644]
crypto/openssh-4/auth.h [new file with mode: 0644]
crypto/openssh-4/auth1.c [new file with mode: 0644]
crypto/openssh-4/auth2-chall.c [new file with mode: 0644]
crypto/openssh-4/auth2-gss.c [new file with mode: 0644]
crypto/openssh-4/auth2-hostbased.c [new file with mode: 0644]
crypto/openssh-4/auth2-kbdint.c [new file with mode: 0644]
crypto/openssh-4/auth2-none.c [new file with mode: 0644]
crypto/openssh-4/auth2-passwd.c [new file with mode: 0644]
crypto/openssh-4/auth2-pubkey.c [new file with mode: 0644]
crypto/openssh-4/auth2.c [new file with mode: 0644]
crypto/openssh-4/authfd.c [new file with mode: 0644]
crypto/openssh-4/authfd.h [new file with mode: 0644]
crypto/openssh-4/authfile.c [new file with mode: 0644]
crypto/openssh-4/authfile.h [new file with mode: 0644]
crypto/openssh-4/bufaux.c [new file with mode: 0644]
crypto/openssh-4/bufaux.h [new file with mode: 0644]
crypto/openssh-4/buffer.c [new file with mode: 0644]
crypto/openssh-4/buffer.h [new file with mode: 0644]
crypto/openssh-4/canohost.c [new file with mode: 0644]
crypto/openssh-4/canohost.h [new file with mode: 0644]
crypto/openssh-4/channels.c [new file with mode: 0644]
crypto/openssh-4/channels.h [new file with mode: 0644]
crypto/openssh-4/cipher-3des1.c [new file with mode: 0644]
crypto/openssh-4/cipher-acss.c [new file with mode: 0644]
crypto/openssh-4/cipher-aes.c [new file with mode: 0644]
crypto/openssh-4/cipher-bf1.c [new file with mode: 0644]
crypto/openssh-4/cipher-ctr.c [new file with mode: 0644]
crypto/openssh-4/cipher.c [new file with mode: 0644]
crypto/openssh-4/cipher.h [new file with mode: 0644]
crypto/openssh-4/cleanup.c [new file with mode: 0644]
crypto/openssh-4/clientloop.c [new file with mode: 0644]
crypto/openssh-4/clientloop.h [new file with mode: 0644]
crypto/openssh-4/compat.c [new file with mode: 0644]
crypto/openssh-4/compat.h [new file with mode: 0644]
crypto/openssh-4/compress.c [new file with mode: 0644]
crypto/openssh-4/compress.h [new file with mode: 0644]
crypto/openssh-4/crc32.c [new file with mode: 0644]
crypto/openssh-4/crc32.h [new file with mode: 0644]
crypto/openssh-4/deattack.c [new file with mode: 0644]
crypto/openssh-4/deattack.h [new file with mode: 0644]
crypto/openssh-4/defines.h [new file with mode: 0644]
crypto/openssh-4/dh.c [new file with mode: 0644]
crypto/openssh-4/dh.h [new file with mode: 0644]
crypto/openssh-4/dispatch.c [new file with mode: 0644]
crypto/openssh-4/dispatch.h [new file with mode: 0644]
crypto/openssh-4/dns.c [new file with mode: 0644]
crypto/openssh-4/dns.h [new file with mode: 0644]
crypto/openssh-4/entropy.c [new file with mode: 0644]
crypto/openssh-4/entropy.h [new file with mode: 0644]
crypto/openssh-4/fatal.c [new file with mode: 0644]
crypto/openssh-4/getput.h [new file with mode: 0644]
crypto/openssh-4/groupaccess.c [new file with mode: 0644]
crypto/openssh-4/groupaccess.h [new file with mode: 0644]
crypto/openssh-4/gss-genr.c [new file with mode: 0644]
crypto/openssh-4/gss-serv-krb5.c [new file with mode: 0644]
crypto/openssh-4/gss-serv.c [new file with mode: 0644]
crypto/openssh-4/hostfile.c [new file with mode: 0644]
crypto/openssh-4/hostfile.h [new file with mode: 0644]
crypto/openssh-4/includes.h [new file with mode: 0644]
crypto/openssh-4/kex.c [new file with mode: 0644]
crypto/openssh-4/kex.h [new file with mode: 0644]
crypto/openssh-4/kexdh.c [new file with mode: 0644]
crypto/openssh-4/kexdhc.c [new file with mode: 0644]
crypto/openssh-4/kexdhs.c [new file with mode: 0644]
crypto/openssh-4/kexgex.c [new file with mode: 0644]
crypto/openssh-4/kexgexc.c [new file with mode: 0644]
crypto/openssh-4/kexgexs.c [new file with mode: 0644]
crypto/openssh-4/key.c [new file with mode: 0644]
crypto/openssh-4/key.h [new file with mode: 0644]
crypto/openssh-4/log.c [new file with mode: 0644]
crypto/openssh-4/log.h [new file with mode: 0644]
crypto/openssh-4/loginrec.h [new file with mode: 0644]
crypto/openssh-4/mac.c [new file with mode: 0644]
crypto/openssh-4/mac.h [new file with mode: 0644]
crypto/openssh-4/match.c [new file with mode: 0644]
crypto/openssh-4/match.h [new file with mode: 0644]
crypto/openssh-4/md5crypt.c [new file with mode: 0644]
crypto/openssh-4/md5crypt.h [new file with mode: 0644]
crypto/openssh-4/misc.c [new file with mode: 0644]
crypto/openssh-4/misc.h [new file with mode: 0644]
crypto/openssh-4/moduli [new file with mode: 0644]
crypto/openssh-4/moduli.c [new file with mode: 0644]
crypto/openssh-4/monitor.c [new file with mode: 0644]
crypto/openssh-4/monitor.h [new file with mode: 0644]
crypto/openssh-4/monitor_fdpass.c [new file with mode: 0644]
crypto/openssh-4/monitor_fdpass.h [new file with mode: 0644]
crypto/openssh-4/monitor_mm.c [new file with mode: 0644]
crypto/openssh-4/monitor_mm.h [new file with mode: 0644]
crypto/openssh-4/monitor_wrap.c [new file with mode: 0644]
crypto/openssh-4/monitor_wrap.h [new file with mode: 0644]
crypto/openssh-4/mpaux.c [new file with mode: 0644]
crypto/openssh-4/mpaux.h [new file with mode: 0644]
crypto/openssh-4/msg.c [new file with mode: 0644]
crypto/openssh-4/msg.h [new file with mode: 0644]
crypto/openssh-4/myproposal.h [new file with mode: 0644]
crypto/openssh-4/nchan.c [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/base64.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/bsd-cray.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/bsd-cygwin_util.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/bsd-misc.c [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/bsd-misc.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/bsd-nextstep.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/bsd-waitpid.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/fake-rfc2553.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/getrrsetbyname.c [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/getrrsetbyname.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/glob.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/openbsd-compat.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/port-aix.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/port-irix.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/readpassphrase.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/sigact.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/sys-queue.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/sys-tree.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/vis.c [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/vis.h [new file with mode: 0644]
crypto/openssh-4/openbsd-compat/xmmap.c [new file with mode: 0644]
crypto/openssh-4/packet.c [new file with mode: 0644]
crypto/openssh-4/packet.h [new file with mode: 0644]
crypto/openssh-4/pathnames.h [new file with mode: 0644]
crypto/openssh-4/progressmeter.c [new file with mode: 0644]
crypto/openssh-4/progressmeter.h [new file with mode: 0644]
crypto/openssh-4/readconf.c [new file with mode: 0644]
crypto/openssh-4/readconf.h [new file with mode: 0644]
crypto/openssh-4/readpass.c [new file with mode: 0644]
crypto/openssh-4/rijndael.c [new file with mode: 0644]
crypto/openssh-4/rijndael.h [new file with mode: 0644]
crypto/openssh-4/rsa.c [new file with mode: 0644]
crypto/openssh-4/rsa.h [new file with mode: 0644]
crypto/openssh-4/scard-opensc.c [new file with mode: 0644]
crypto/openssh-4/scard.c [new file with mode: 0644]
crypto/openssh-4/scp.1 [new file with mode: 0644]
crypto/openssh-4/scp.c [new file with mode: 0644]
crypto/openssh-4/servconf.c [new file with mode: 0644]
crypto/openssh-4/servconf.h [new file with mode: 0644]
crypto/openssh-4/serverloop.c [new file with mode: 0644]
crypto/openssh-4/serverloop.h [new file with mode: 0644]
crypto/openssh-4/session.c [new file with mode: 0644]
crypto/openssh-4/session.h [new file with mode: 0644]
crypto/openssh-4/sftp-client.c [new file with mode: 0644]
crypto/openssh-4/sftp-client.h [new file with mode: 0644]
crypto/openssh-4/sftp-common.c [new file with mode: 0644]
crypto/openssh-4/sftp-common.h [new file with mode: 0644]
crypto/openssh-4/sftp-glob.c [new file with mode: 0644]
crypto/openssh-4/sftp-server.8 [new file with mode: 0644]
crypto/openssh-4/sftp-server.c [new file with mode: 0644]
crypto/openssh-4/sftp.1 [new file with mode: 0644]
crypto/openssh-4/sftp.c [new file with mode: 0644]
crypto/openssh-4/sftp.h [new file with mode: 0644]
crypto/openssh-4/ssh-add.1 [new file with mode: 0644]
crypto/openssh-4/ssh-add.c [new file with mode: 0644]
crypto/openssh-4/ssh-agent.1 [new file with mode: 0644]
crypto/openssh-4/ssh-agent.c [new file with mode: 0644]
crypto/openssh-4/ssh-dss.c [new file with mode: 0644]
crypto/openssh-4/ssh-gss.h [new file with mode: 0644]
crypto/openssh-4/ssh-keygen.1 [new file with mode: 0644]
crypto/openssh-4/ssh-keygen.c [new file with mode: 0644]
crypto/openssh-4/ssh-keyscan.1 [new file with mode: 0644]
crypto/openssh-4/ssh-keyscan.c [new file with mode: 0644]
crypto/openssh-4/ssh-keysign.8 [new file with mode: 0644]
crypto/openssh-4/ssh-keysign.c [new file with mode: 0644]
crypto/openssh-4/ssh-rsa.c [new file with mode: 0644]
crypto/openssh-4/ssh.1 [new file with mode: 0644]
crypto/openssh-4/ssh.c [new file with mode: 0644]
crypto/openssh-4/ssh.h [new file with mode: 0644]
crypto/openssh-4/ssh1.h [new file with mode: 0644]
crypto/openssh-4/ssh2.h [new file with mode: 0644]
crypto/openssh-4/ssh_config [new file with mode: 0644]
crypto/openssh-4/ssh_config.5 [new file with mode: 0644]
crypto/openssh-4/sshconnect.c [new file with mode: 0644]
crypto/openssh-4/sshconnect.h [new file with mode: 0644]
crypto/openssh-4/sshconnect1.c [new file with mode: 0644]
crypto/openssh-4/sshconnect2.c [new file with mode: 0644]
crypto/openssh-4/sshd.8 [new file with mode: 0644]
crypto/openssh-4/sshd.c [new file with mode: 0644]
crypto/openssh-4/sshd_config [new file with mode: 0644]
crypto/openssh-4/sshd_config.5 [new file with mode: 0644]
crypto/openssh-4/sshlogin.c [new file with mode: 0644]
crypto/openssh-4/sshlogin.h [new file with mode: 0644]
crypto/openssh-4/sshpty.c [new file with mode: 0644]
crypto/openssh-4/sshpty.h [new file with mode: 0644]
crypto/openssh-4/sshtty.c [new file with mode: 0644]
crypto/openssh-4/tildexpand.c [new file with mode: 0644]
crypto/openssh-4/ttymodes.c [new file with mode: 0644]
crypto/openssh-4/ttymodes.h [new file with mode: 0644]
crypto/openssh-4/uidswap.c [new file with mode: 0644]
crypto/openssh-4/uidswap.h [new file with mode: 0644]
crypto/openssh-4/uuencode.c [new file with mode: 0644]
crypto/openssh-4/uuencode.h [new file with mode: 0644]
crypto/openssh-4/xmalloc.c [new file with mode: 0644]
crypto/openssh-4/xmalloc.h [new file with mode: 0644]

diff --git a/crypto/openssh-4/CREDITS b/crypto/openssh-4/CREDITS
new file mode 100644 (file)
index 0000000..2a77b87
--- /dev/null
@@ -0,0 +1,102 @@
+Tatu Ylonen <ylo@cs.hut.fi> - Creator of SSH
+
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+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@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
+Andrew Stribblehill <a.d.stribblehill@durham.ac.uk> - Bugfixes
+Andy Sloane <andy@guildsoftware.com> - bugfixes
+Aran Cox <acox@cv.telegroup.com> - SCO bugfixes
+Arkadiusz Miskiewicz <misiek@pld.org.pl> - IPv6 compat fixes
+Ben Lindstrom <mouring@eviladmin.org> - NeXT support
+Ben Taylor <bent@clark.net> - Solaris debugging and fixes
+Bratislav ILICH <bilic@zepter.ru> - Configure fix
+Charles Levert <charles@comm.polymtl.ca> - SunOS 4 & bug fixes
+Chip Salzenberg <chip@valinux.com> - Assorted patches
+Chris Adams <cmadams@hiwaay.net> - OSF SIA support
+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@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
+David Agraz <dagraz@jahoopa.com> - Build fixes
+David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes
+David Hesprich <darkgrue@gue-tech.org> - Configure fixes
+David Rankin <drankin@bohemians.lexington.ky.us> - libwrap, AIX, NetBSD fixes
+Dag-Erling Smørgrav <des at freebsd.org> - Challenge-Response PAM code.
+Ed Eden <ede370@stl.rural.usda.gov> - configure fixes
+Garrick James <garrick@james.net> - configure fixes
+Gary E. Miller <gem@rellim.com> - SCO support
+Ged Lodder <lodder@yacc.com.au> - HPUX fixes and enhancements
+Gert Doering <gd@hilb1.medat.de> - bug and portability fixes
+HARUYAMA Seigo <haruyama@unixuser.org> - Translations & doc fixes
+Hideaki YOSHIFUJI <yoshfuji@ecei.tohoku.ac.jp> - IPv6 and bug fixes
+Hiroshi Takekawa <takekawa@sr3.t.u-tokyo.ac.jp> - Configure fixes
+Holger Trapp <Holger.Trapp@Informatik.TU-Chemnitz.DE> - KRB4/AFS config patch
+IWAMURO Motonori <iwa@mmp.fujitsu.co.jp> - bugfixes
+Jani Hakala <jahakala@cc.jyu.fi> - Patches
+Jarno Huuskonen <jhuuskon@hytti.uku.fi> - Bugfixes
+Jim Knoble <jmknoble@pobox.com> - Many patches
+Jonchen (email unknown) - the original author of PAM support of SSH
+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
+Larry Jones <larry.jones@sdrc.com> - Bugfixes
+Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - Bugfixes
+Marc G. Fournier <marc.fournier@acadiau.ca> - Solaris patches
+Mark D. Baushke <mdb@juniper.net> - bug fixes
+Martin Johansson <fatbob@acc.umu.se> - Linux fixes
+Mark D. Roth <roth+openssh@feep.net> - Features, bug fixes
+Mark Miller <markm@swoon.net> - Bugfixes
+Matt Richards <v2matt@btv.ibm.com> - AIX patches
+Michael Steffens <michael_steffens at hp.com> - HP-UX fixes
+Michael Stone <mstone@cs.loyola.edu> - Irix enhancements
+Nakaji Hiroyuki <nakaji@tutrp.tut.ac.jp> - Sony News-OS patch
+Nalin Dahyabhai <nalin.dahyabhai@pobox.com> - PAM environment patch
+Nate Itkin <nitkin@europa.com> - SunOS 4.1.x fixes
+Niels Kristian Bech Jensen <nkbj@image.dk> - Assorted patches
+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
+Robert Dahlem <Robert.Dahlem at siemens.com> - Reliant Unix 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
+Svante Signell <svante.signell@telia.com> - Bugfixes
+Thomas Neumann <tom@smart.ruhr.de> - Shadow passwords
+Tim Rice <tim@multitalents.net> - Portability & SCO fixes
+Tobias Oetiker <oetiker@ee.ethz.ch> - Bugfixes
+Tom Bertelson's <tbert@abac.com> - AIX auth fixes
+Tor-Ake Fransson <torake@hotmail.com> - AIX support
+Tudor Bosman <tudorb@jm.nu> - MD5 password support
+Udo Schweigert <ust@cert.siemens.de> - ReliantUNIX support
+Wendy Palm <wendyp at cray.com> - Cray support.
+Zack Weinberg <zack@wolery.cumb.org> - GNOME askpass enhancement
+
+Apologies to anyone I have missed.
+
+Damien Miller <djm@mindrot.org>
+
+$Id: CREDITS,v 1.79 2004/05/26 23:59:31 dtucker Exp $
+
diff --git a/crypto/openssh-4/LICENCE b/crypto/openssh-4/LICENCE
new file mode 100644 (file)
index 0000000..ae03eb3
--- /dev/null
@@ -0,0 +1,333 @@
+This file is part of the OpenSSH software.
+
+The licences which components of this software fall under are as
+follows.  First, we will summarize and say that all components
+are under a BSD licence, or a licence more free than that.
+
+OpenSSH contains no GPL code.
+
+1)
+     * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+     *                    All rights reserved
+     *
+     * As far as I am concerned, the code I have written for this software
+     * can be used freely for any purpose.  Any derived versions of this
+     * software must be clearly marked as such, and if the derived work is
+     * incompatible with the protocol description in the RFC file, it must be
+     * called by a name other than "ssh" or "Secure Shell".
+
+    [Tatu continues]
+     *  However, I am not implying to give any licenses to any patents or
+     * copyrights held by third parties, and the software includes parts that
+     * are not under my direct control.  As far as I know, all included
+     * source code is used in accordance with the relevant license agreements
+     * and can be used freely for any purpose (the GNU license being the most
+     * restrictive); see below for details.
+
+    [However, none of that term is relevant at this point in time.  All of
+    these restrictively licenced software components which he talks about
+    have been removed from OpenSSH, i.e.,
+
+     - RSA is no longer included, found in the OpenSSL library
+     - IDEA is no longer included, its use is deprecated
+     - DES is now external, in the OpenSSL library
+     - GMP is no longer used, and instead we call BN code from OpenSSL
+     - Zlib is now external, in a library
+     - The make-ssh-known-hosts script is no longer included
+     - TSS has been removed
+     - MD5 is now external, in the OpenSSL library
+     - RC4 support has been replaced with ARC4 support from OpenSSL
+     - Blowfish is now external, in the OpenSSL library
+
+    [The licence continues]
+
+    Note that any information and cryptographic algorithms used in this
+    software are publicly available on the Internet and at any major
+    bookstore, scientific library, and patent office worldwide.  More
+    information can be found e.g. at "http://www.cs.hut.fi/crypto".
+
+    The legal status of this program is some combination of all these
+    permissions and restrictions.  Use only at your own responsibility.
+    You will be responsible for any legal consequences yourself; I am not
+    making any claims whether possessing or using this is legal or not in
+    your country, and I am not taking any responsibility on your behalf.
+
+
+                           NO WARRANTY
+
+    BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+    OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+    TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+    PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+    REPAIR OR CORRECTION.
+
+    IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+    INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+    OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+    TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+    YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+    PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGES.
+
+2)
+    The 32-bit CRC compensation attack detector in deattack.c was
+    contributed by CORE SDI S.A. under a BSD-style license.
+
+     * Cryptographic attack detector for ssh - source code
+     *
+     * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
+     *
+     * All rights reserved. Redistribution and use in source and binary
+     * forms, with or without modification, are permitted provided that
+     * this copyright notice is retained.
+     *
+     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+     * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
+     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
+     * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
+     * SOFTWARE.
+     *
+     * Ariel Futoransky <futo@core-sdi.com>
+     * <http://www.core-sdi.com>
+
+3)
+    ssh-keyscan was contributed by David Mazieres under a BSD-style
+    license.
+
+     * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
+     *
+     * Modification and redistribution in source and binary forms is
+     * permitted provided that due credit is given to the author and the
+     * OpenBSD project by leaving this copyright notice intact.
+
+4)
+    The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers
+    and Paulo Barreto is in the public domain and distributed
+    with the following license:
+
+     * @version 3.0 (December 2000)
+     *
+     * Optimised ANSI C code for the Rijndael cipher (now AES)
+     *
+     * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+     * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+     * @author Paulo Barreto <paulo.barreto@terra.com.br>
+     *
+     * This code is hereby placed in the public domain.
+     *
+     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
+
+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.
+
+     * 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. 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.
+
+6)
+    Remaining components of the software are provided under a standard
+    2-term BSD licence with the following names as copyright holders:
+
+       Markus Friedl
+       Theo de Raadt
+       Niels Provos
+       Dug Song
+       Aaron Campbell
+       Damien Miller
+       Kevin Steves
+       Daniel Kouril
+       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
+       Darren Tucker
+       Sun Microsystems
+
+     * 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.
+
+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.19 2004/08/30 09:18:08 markus Exp $
diff --git a/crypto/openssh-4/README b/crypto/openssh-4/README
new file mode 100644 (file)
index 0000000..93682c3
--- /dev/null
@@ -0,0 +1,64 @@
+See http://www.openssh.com/txt/release-4.0 for the release notes.
+
+- A Japanese translation of this document and of the OpenSSH FAQ is
+- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
+- Thanks to HARUYAMA Seigo <haruyama@unixuser.org>
+
+This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other
+Unices.
+
+OpenSSH is based on the last free version of Tatu Ylonen's sample
+implementation with all patent-encumbered algorithms removed (to
+external libraries), all known security bugs fixed, new features
+reintroduced and many other clean-ups.  OpenSSH has been created by
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt,
+and Dug Song. It has a homepage at http://www.openssh.com/
+
+This port consists of the re-introduction of autoconf support, PAM
+support, EGD[1]/PRNGD[2] support and replacements for OpenBSD library
+functions that are (regrettably) absent from other unices. This port
+has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X,
+NetBSD, OpenBSD, OpenServer, Solaris, Unicos, and UnixWare.
+
+This version actively tracks changes in the OpenBSD CVS repository.
+
+The PAM support is now more functional than the popular packages of
+commercial ssh-1.2.x. It checks "account" and "session" modules for
+all logins, not just when using password authentication.
+
+OpenSSH depends on Zlib[3], OpenSSL[4] and optionally PAM[5].
+
+There is now several mailing lists for this port of OpenSSH. Please
+refer to http://www.openssh.com/list.html for details on how to join.
+
+Please send bug reports and patches to the mailing list
+openssh-unix-dev@mindrot.org. The list is open to posting by
+unsubscribed users.Code contribution are welcomed, but please follow the 
+OpenBSD style guidelines[6].
+
+Please refer to the INSTALL document for information on how to install
+OpenSSH on your system. There are a number of differences between this
+port of OpenSSH and F-Secure SSH 1.x, please refer to the OpenSSH FAQ[7]
+for details and general tips.
+
+Damien Miller <djm@mindrot.org>
+
+Miscellania -
+
+This version of OpenSSH is based upon code retrieved from the OpenBSD
+CVS repository which in turn was based on the last free sample
+implementation released by Tatu Ylonen.
+
+References -
+
+[0] http://www.openssh.com/faq.html
+[1] http://www.lothar.com/tech/crypto/
+[2] http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html
+[3] http://www.gzip.org/zlib/
+[4] http://www.openssl.org/
+[5] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris
+    and HP-UX 11)
+[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
+[7] http://www.openssh.com/faq.html
+
+$Id: README,v 1.57 2005/03/09 03:32:28 dtucker Exp $
diff --git a/crypto/openssh-4/README.dns b/crypto/openssh-4/README.dns
new file mode 100644 (file)
index 0000000..9787918
--- /dev/null
@@ -0,0 +1,47 @@
+How to verify host keys using OpenSSH and DNS
+---------------------------------------------
+
+OpenSSH contains support for verifying host keys using DNS as described in
+draft-ietf-secsh-dns-05.txt. The document contains very brief instructions
+on how to use this feature. Configuring DNS is out of the scope of this
+document.
+
+
+(1) Server: 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
+you can omit the -g flag and ssh-keygen will print a standard SSHFP RR.
+
+To publish the fingerprint using the DNS you must add the generated RR
+to your DNS zone file and sign your zone.
+
+
+(2) Client: Enable ssh 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.2 2003/10/14 19:43:23 jakob Exp $
diff --git a/crypto/openssh-4/acss.c b/crypto/openssh-4/acss.c
new file mode 100644 (file)
index 0000000..9364ba9
--- /dev/null
@@ -0,0 +1,264 @@
+/*     $Id: acss.c,v 1.2 2004/02/06 04:22:43 dtucker Exp $ */
+/*
+ * Copyright (c) 2004 The OpenBSD project
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+#include <openssl/evp.h>
+
+#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00906000L)
+
+#include "acss.h"
+
+/* decryption sbox */
+static unsigned char sboxdec[] = {
+       0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, 
+       0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b, 
+       0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96, 
+       0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b, 
+       0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12, 
+       0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f, 
+       0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90, 
+       0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91, 
+       0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74, 
+       0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75, 
+       0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94, 
+       0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95, 
+       0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10, 
+       0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11, 
+       0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92, 
+       0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f, 
+       0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16, 
+       0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b, 
+       0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6, 
+       0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb, 
+       0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72, 
+       0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f, 
+       0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0, 
+       0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1, 
+       0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14, 
+       0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15, 
+       0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4, 
+       0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5, 
+       0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, 
+       0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, 
+       0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2, 
+       0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff
+};
+
+/* encryption sbox */
+static unsigned char sboxenc[] = {
+       0x33, 0x3b, 0x73, 0x15, 0x53, 0x5b, 0x13, 0x75,
+       0x3d, 0x35, 0x7d, 0x1b, 0x5d, 0x55, 0x1d, 0x7b,
+       0x67, 0x6f, 0x27, 0x81, 0xc7, 0xcf, 0x87, 0x21,
+       0x69, 0x61, 0x29, 0x8f, 0xc9, 0xc1, 0x89, 0x2f,
+       0xe3, 0xeb, 0xa3, 0x05, 0x43, 0x4b, 0x03, 0xa5,
+       0xed, 0xe5, 0xad, 0x0b, 0x4d, 0x45, 0x0d, 0xab,
+       0xea, 0xe2, 0xaa, 0x00, 0x4a, 0x42, 0x0a, 0xa0,
+       0xe8, 0xe0, 0xa8, 0x02, 0x48, 0x40, 0x08, 0xa2,
+       0x3e, 0x36, 0x7e, 0x14, 0x5e, 0x56, 0x1e, 0x74,
+       0x3c, 0x34, 0x7c, 0x16, 0x5c, 0x54, 0x1c, 0x76,
+       0x6a, 0x62, 0x2a, 0x80, 0xca, 0xc2, 0x8a, 0x20,
+       0x68, 0x60, 0x28, 0x82, 0xc8, 0xc0, 0x88, 0x22,
+       0xee, 0xe6, 0xae, 0x04, 0x4e, 0x46, 0x0e, 0xa4,
+       0xec, 0xe4, 0xac, 0x06, 0x4c, 0x44, 0x0c, 0xa6,
+       0xe7, 0xef, 0xa7, 0x01, 0x47, 0x4f, 0x07, 0xa1,
+       0xe9, 0xe1, 0xa9, 0x0f, 0x49, 0x41, 0x09, 0xaf,
+       0x63, 0x6b, 0x23, 0x85, 0xc3, 0xcb, 0x83, 0x25,
+       0x6d, 0x65, 0x2d, 0x8b, 0xcd, 0xc5, 0x8d, 0x2b,
+       0x37, 0x3f, 0x77, 0x11, 0x57, 0x5f, 0x17, 0x71,
+       0x39, 0x31, 0x79, 0x1f, 0x59, 0x51, 0x19, 0x7f,
+       0xb3, 0xbb, 0xf3, 0x95, 0xd3, 0xdb, 0x93, 0xf5,
+       0xbd, 0xb5, 0xfd, 0x9b, 0xdd, 0xd5, 0x9d, 0xfb,
+       0xba, 0xb2, 0xfa, 0x90, 0xda, 0xd2, 0x9a, 0xf0,
+       0xb8, 0xb0, 0xf8, 0x92, 0xd8, 0xd0, 0x98, 0xf2,
+       0x6e, 0x66, 0x2e, 0x84, 0xce, 0xc6, 0x8e, 0x24,
+       0x6c, 0x64, 0x2c, 0x86, 0xcc, 0xc4, 0x8c, 0x26,
+       0x3a, 0x32, 0x7a, 0x10, 0x5a, 0x52, 0x1a, 0x70,
+       0x38, 0x30, 0x78, 0x12, 0x58, 0x50, 0x18, 0x72,
+       0xbe, 0xb6, 0xfe, 0x94, 0xde, 0xd6, 0x9e, 0xf4,
+       0xbc, 0xb4, 0xfc, 0x96, 0xdc, 0xd4, 0x9c, 0xf6,
+       0xb7, 0xbf, 0xf7, 0x91, 0xd7, 0xdf, 0x97, 0xf1,
+       0xb9, 0xb1, 0xf9, 0x9f, 0xd9, 0xd1, 0x99, 0xff
+};
+
+static unsigned char reverse[] = {
+       0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
+       0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
+       0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
+       0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
+       0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
+       0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
+       0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
+       0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
+       0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
+       0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
+       0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
+       0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
+       0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
+       0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
+       0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
+       0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
+       0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
+       0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
+       0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
+       0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
+       0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
+       0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
+       0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
+       0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
+       0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
+       0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
+       0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
+       0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
+       0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
+       0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
+       0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
+       0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff 
+};
+
+/*
+ * Two linear feedback shift registers are used:
+ *
+ * lfsr17:  polynomial of degree 17, primitive modulo 2 (listed in Schneier)
+ *          x^15 + x + 1
+ * lfsr25:  polynomial of degree 25, not know if primitive modulo 2
+ *          x^13 + x^5 + x^4 + x^1 + 1
+ *
+ * Output bits are discarded, instead the feedback bits are added to produce
+ * the cipher stream.  Depending on the mode, feedback bytes may be inverted
+ * bit-wise before addition.
+ *
+ * The lfsrs are seeded with bytes from the raw key:
+ *
+ * lfsr17:  byte 0[0:7] at bit 9
+ *          byte 1[0:7] at bit 0
+ *
+ * lfsr25:  byte 2[0:4] at bit 16
+ *          byte 2[5:7] at bit 22
+ *          byte 3[0:7] at bit 8
+ *          byte 4[0:7] at bit 0
+ *
+ * To prevent 0 cycles, 1's are inject at bit 8 in lfrs17 and bit 21 in
+ * lfsr25.
+ *
+ */
+
+int
+acss(ACSS_KEY *key, unsigned long len, const unsigned char *in,
+    unsigned char *out)
+{
+       unsigned long i;
+       unsigned long lfsr17tmp, lfsr25tmp, lfsrsumtmp;
+
+       lfsrsumtmp = lfsr17tmp = lfsr25tmp = 0;
+
+       /* keystream is sum of lfsrs */
+       for (i = 0; i < len; i++) {
+               lfsr17tmp = key->lfsr17 ^ (key->lfsr17 >> 14);
+               key->lfsr17 = (key->lfsr17 >> 8)
+                       ^ (lfsr17tmp << 9)
+                       ^ (lfsr17tmp << 12)
+                       ^ (lfsr17tmp << 15);
+               key->lfsr17 &= 0x1ffff; /* 17 bit LFSR */
+
+               lfsr25tmp = key->lfsr25
+                       ^ (key->lfsr25 >> 3)
+                       ^ (key->lfsr25 >> 4)
+                       ^ (key->lfsr25 >> 12);
+               key->lfsr25 = (key->lfsr25 >> 8) ^ (lfsr25tmp << 17);
+               key->lfsr25 &= 0x1ffffff;       /* 25 bit LFSR */
+
+               lfsrsumtmp = key->lfsrsum;
+
+               /* addition */
+               switch (key->mode) {
+               case ACSS_AUTHENTICATE:
+               case ACSS_DATA:
+                       key->lfsrsum = 0xff & ~(key->lfsr17 >> 9);
+                       key->lfsrsum += key->lfsr25 >> 17;
+                       break;
+               case ACSS_SESSIONKEY:
+                       key->lfsrsum = key->lfsr17 >> 9;
+                       key->lfsrsum += key->lfsr25 >> 17;
+                       break;
+               case ACSS_TITLEKEY:
+                       key->lfsrsum = key->lfsr17 >> 9;
+                       key->lfsrsum += 0xff & ~(key->lfsr25 >> 17);
+                       break;
+               default:
+                       return 1;
+               }
+               key->lfsrsum += (lfsrsumtmp >> 8);
+
+               if (key->encrypt) {
+                       out[i] = sboxenc[(in[i] ^ key->lfsrsum) & 0xff];
+               } else {
+                       out[i] = (sboxdec[in[i]] ^ key->lfsrsum) & 0xff;
+               }
+       }
+
+       return 0;
+}
+
+static void
+acss_seed(ACSS_KEY *key)
+{
+       int i;
+
+       /* if available, mangle with subkey */
+       if (key->subkey_avilable) {
+               for (i = 0; i < ACSS_KEYSIZE; i++)
+                       key->seed[i] = reverse[key->data[i] ^ key->subkey[i]];
+       } else {
+               for (i = 0; i < ACSS_KEYSIZE; i++)
+                       key->seed[i] = reverse[key->data[i]];
+       }
+
+       /* seed lfsrs */
+       key->lfsr17 = key->seed[1]
+               | (key->seed[0] << 9)
+               | (1 << 8);     /* inject 1 at bit 9 */
+       key->lfsr25 = key->seed[4]
+               | (key->seed[3] << 8)
+               | ((key->seed[2] & 0x1f) << 16)
+               | ((key->seed[2] & 0xe0) << 17)
+                       | (1 << 21);    /* inject 1 at bit 22 */
+
+       key->lfsrsum = 0;
+}
+
+void
+acss_setkey(ACSS_KEY *key, const unsigned char *data, int enc, int mode)
+{
+       memcpy(key->data, data, sizeof(key->data));
+       memset(key->subkey, 0, sizeof(key->subkey));
+
+       if (enc != -1)
+               key->encrypt = enc;
+       key->mode = mode;
+       key->subkey_avilable = 0;
+
+       acss_seed(key);
+}
+
+void
+acss_setsubkey(ACSS_KEY *key, const unsigned char *subkey)
+{
+       memcpy(key->subkey, subkey, sizeof(key->subkey));
+       key->subkey_avilable = 1;
+       acss_seed(key);
+}
+#endif
diff --git a/crypto/openssh-4/acss.h b/crypto/openssh-4/acss.h
new file mode 100644 (file)
index 0000000..91b4895
--- /dev/null
@@ -0,0 +1,47 @@
+/*     $Id: acss.h,v 1.2 2004/02/06 04:22:43 dtucker Exp $ */
+/*
+ * Copyright (c) 2004 The OpenBSD project
+ *
+ * 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.
+ */
+
+#ifndef _ACSS_H_
+#define _ACSS_H_
+
+/* 40bit key */
+#define ACSS_KEYSIZE           5
+
+/* modes of acss */
+#define ACSS_AUTHENTICATE      0
+#define ACSS_SESSIONKEY                1
+#define ACSS_TITLEKEY          2
+#define ACSS_DATA              3
+
+typedef struct acss_key_st {
+       unsigned int    lfsr17;         /* current state of lfsrs */
+       unsigned int    lfsr25;
+       unsigned int    lfsrsum;
+       unsigned char   seed[ACSS_KEYSIZE];
+       unsigned char   data[ACSS_KEYSIZE];
+       unsigned char   subkey[ACSS_KEYSIZE];
+       int             encrypt;        /* XXX make these bit flags? */
+       int             mode;
+       int             seeded;
+       int             subkey_avilable;
+} ACSS_KEY;
+
+void acss_setkey(ACSS_KEY *, const unsigned char *, int, int);
+void acss_setsubkey(ACSS_KEY *, const unsigned char *);
+int acss(ACSS_KEY *, unsigned long, const unsigned char *, unsigned char *);
+
+#endif /* ifndef _ACSS_H_ */
diff --git a/crypto/openssh-4/atomicio.c b/crypto/openssh-4/atomicio.c
new file mode 100644 (file)
index 0000000..7637e16
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * 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: 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==vwrite
+ */
+ssize_t
+atomicio(f, fd, _s, n)
+       ssize_t (*f) (int, void *, size_t);
+       int fd;
+       void *_s;
+       size_t n;
+{
+       char *s = _s;
+       ssize_t res, pos = 0;
+
+       while (n > pos) {
+               res = (f) (fd, s + pos, n - pos);
+               switch (res) {
+               case -1:
+#ifdef EWOULDBLOCK
+                       if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+#else
+                       if (errno == EINTR || errno == EAGAIN)
+#endif
+                               continue;
+               case 0:
+                       return (res);
+               default:
+                       pos += res;
+               }
+       }
+       return (pos);
+}
diff --git a/crypto/openssh-4/atomicio.h b/crypto/openssh-4/atomicio.h
new file mode 100644 (file)
index 0000000..5c0f392
--- /dev/null
@@ -0,0 +1,33 @@
+/*     $OpenBSD: atomicio.h,v 1.5 2003/06/28 16:23:06 deraadt Exp $    */
+
+/*
+ * Copyright (c) 1995,1999 Theo de Raadt.  All rights reserved.
+ * 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.
+ */
+
+/*
+ * Ensure all of data on socket comes through. f==read || f==vwrite
+ */
+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-4/audit-bsm.c b/crypto/openssh-4/audit-bsm.c
new file mode 100644 (file)
index 0000000..c2679d3
--- /dev/null
@@ -0,0 +1,329 @@
+/* $Id: audit-bsm.c,v 1.1 2005/02/20 10:08:00 dtucker Exp $ */
+
+/*
+ * TODO
+ *
+ * - deal with overlap between this and sys_auth_allowed_user
+ *   sys_auth_record_login and record_failed_login.
+ */
+
+/*
+ * Copyright 1988-2002 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* #pragma ident       "@(#)bsmaudit.c 1.1     01/09/17 SMI" */
+
+#include "includes.h"
+#if defined(USE_BSM_AUDIT)
+
+#include "ssh.h"
+#include "log.h"
+#include "auth.h"
+#include "xmalloc.h"
+
+#ifndef AUE_openssh
+# define AUE_openssh     32800
+#endif
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/audit_record.h>
+#include <locale.h>
+
+#if defined(HAVE_GETAUDIT_ADDR)
+#define        AuditInfoStruct         auditinfo_addr
+#define AuditInfoTermID                au_tid_addr_t
+#define GetAuditFunc(a,b)      getaudit_addr((a),(b))
+#define GetAuditFuncText       "getaudit_addr"
+#define SetAuditFunc(a,b)      setaudit_addr((a),(b))
+#define SetAuditFuncText       "setaudit_addr"
+#define AUToSubjectFunc                au_to_subject_ex
+#define AUToReturnFunc(a,b)    au_to_return32((a), (int32_t)(b))
+#else
+#define        AuditInfoStruct         auditinfo
+#define AuditInfoTermID                au_tid_t
+#define GetAuditFunc(a,b)      getaudit(a)
+#define GetAuditFuncText       "getaudit"
+#define SetAuditFunc(a,b)      setaudit(a)
+#define SetAuditFuncText       "setaudit"
+#define AUToSubjectFunc                au_to_subject
+#define AUToReturnFunc(a,b)    au_to_return((a), (u_int)(b))
+#endif
+
+extern int     cannot_audit(int);
+extern void    aug_init(void);
+extern dev_t   aug_get_port(void);
+extern int     aug_get_machine(char *, u_int32_t *, u_int32_t *);
+extern void    aug_save_auid(au_id_t);
+extern void    aug_save_uid(uid_t);
+extern void    aug_save_euid(uid_t);
+extern void    aug_save_gid(gid_t);
+extern void    aug_save_egid(gid_t);
+extern void    aug_save_pid(pid_t);
+extern void    aug_save_asid(au_asid_t);
+extern void    aug_save_tid(dev_t, unsigned int);
+extern void    aug_save_tid_ex(dev_t, u_int32_t *, u_int32_t);
+extern int     aug_save_me(void);
+extern int     aug_save_namask(void);
+extern void    aug_save_event(au_event_t);
+extern void    aug_save_sorf(int);
+extern void    aug_save_text(char *);
+extern void    aug_save_text1(char *);
+extern void    aug_save_text2(char *);
+extern void    aug_save_na(int);
+extern void    aug_save_user(char *);
+extern void    aug_save_path(char *);
+extern int     aug_save_policy(void);
+extern void    aug_save_afunc(int (*)(int));
+extern int     aug_audit(void);
+extern int     aug_na_selected(void);
+extern int     aug_selected(void);
+extern int     aug_daemon_session(void);
+
+#ifndef HAVE_GETTEXT
+# define gettext(a)    (a)
+#endif
+
+extern Authctxt *the_authctxt;
+static AuditInfoTermID ssh_bsm_tid;
+
+/* Below is the low-level BSM interface code */
+
+/*
+ * Check if the specified event is selected (enabled) for auditing.
+ * Returns 1 if the event is selected, 0 if not and -1 on failure.
+ */
+static int
+selected(char *username, uid_t uid, au_event_t event, int sf)
+{
+       int rc, sorf;
+       char naflags[512];
+       struct au_mask mask;
+
+       mask.am_success = mask.am_failure = 0;
+       if (uid < 0) {
+               /* get flags for non-attributable (to a real user) events */
+               rc = getacna(naflags, sizeof(naflags));
+               if (rc == 0)
+                       (void) getauditflagsbin(naflags, &mask);
+       } else
+               rc = au_user_mask(username, &mask);
+
+       sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE;
+       return(au_preselect(event, &mask, sorf, AU_PRS_REREAD));
+}
+
+static void
+bsm_audit_record(int typ, char *string, au_event_t event_no)
+{
+       int             ad, rc, sel;
+       uid_t           uid = -1;
+       gid_t           gid = -1;
+       pid_t           pid = getpid();
+       AuditInfoTermID tid = ssh_bsm_tid;
+
+       if (the_authctxt != NULL && the_authctxt->valid) {
+               uid = the_authctxt->pw->pw_uid;
+               gid = the_authctxt->pw->pw_gid;
+       }
+
+       rc = (typ == 0) ? 0 : -1;
+       sel = selected(the_authctxt->user, uid, event_no, rc);
+       debug3("BSM audit: typ %d rc %d \"%s\"", typ, rc, string);
+       if (!sel)
+               return; /* audit event does not match mask, do not write */
+
+       debug3("BSM audit: writing audit new record");
+       ad = au_open();
+
+       (void) au_write(ad, AUToSubjectFunc(uid, uid, gid, uid, gid,
+           pid, pid, &tid));
+       (void) au_write(ad, au_to_text(string));
+       (void) au_write(ad, AUToReturnFunc(typ, rc));
+
+       rc = au_close(ad, AU_TO_WRITE, event_no);
+       if (rc < 0)
+               error("BSM audit: %s failed to write \"%s\" record: %s",
+                   __func__, string, strerror(errno));
+}
+
+static void
+bsm_audit_session_setup(void)
+{
+       int rc;
+       struct AuditInfoStruct info;
+       au_mask_t mask;
+
+       if (the_authctxt == NULL) {
+               error("BSM audit: session setup internal error (NULL ctxt)");
+               return;
+       }
+
+       if (the_authctxt->valid)
+               info.ai_auid = the_authctxt->pw->pw_uid;
+       else
+               info.ai_auid = -1;
+       info.ai_asid = getpid();
+       mask.am_success = 0;
+       mask.am_failure = 0;
+
+       (void) au_user_mask(the_authctxt->user, &mask);
+
+       info.ai_mask.am_success  = mask.am_success;
+       info.ai_mask.am_failure  = mask.am_failure;
+
+       info.ai_termid = ssh_bsm_tid;
+
+       rc = SetAuditFunc(&info, sizeof(info));
+       if (rc < 0)
+               error("BSM audit: %s: %s failed: %s", __func__,
+                   SetAuditFuncText, strerror(errno));
+}
+
+static void
+bsm_audit_bad_login(const char *what)
+{
+       char textbuf[BSM_TEXTBUFSZ];
+
+       if (the_authctxt->valid) {
+               (void) snprintf(textbuf, sizeof (textbuf),
+                       gettext("invalid %s for user %s"),
+                           what, the_authctxt->user);
+               bsm_audit_record(4, textbuf, AUE_openssh);
+       } else {
+               (void) snprintf(textbuf, sizeof (textbuf),
+                       gettext("invalid user name \"%s\""),
+                           the_authctxt->user);
+               bsm_audit_record(3, textbuf, AUE_openssh);
+       }
+}
+
+/* Below is the sshd audit API code */
+
+void
+audit_connection_from(const char *host, int port)
+{
+       AuditInfoTermID *tid = &ssh_bsm_tid;
+       char buf[1024];
+
+       if (cannot_audit(0))
+               return;
+       debug3("BSM audit: connection from %.100s port %d", host, port);
+
+       /* populate our terminal id structure */
+#if defined(HAVE_GETAUDIT_ADDR)
+       tid->at_port = (dev_t)port;
+       aug_get_machine((char *)host, &(tid->at_addr[0]), &(tid->at_type));
+       snprintf(buf, sizeof(buf), "%08x %08x %08x %08x", tid->at_addr[0],
+           tid->at_addr[1], tid->at_addr[2], tid->at_addr[3]);
+       debug3("BSM audit: iptype %d machine ID %s", (int)tid->at_type, buf);
+#else
+       /* this is used on IPv4-only machines */
+       tid->port = (dev_t)port;
+       tid->machine = inet_addr(host);
+       snprintf(buf, sizeof(buf), "%08x", tid->machine);
+       debug3("BSM audit: machine ID %s", buf);
+#endif
+}
+
+void
+audit_run_command(const char *command)
+{
+       /* not implemented */
+}
+
+void
+audit_session_open(const char *ttyn)
+{
+       /* not implemented */
+}
+
+void
+audit_session_close(const char *ttyn)
+{
+       /* not implemented */
+}
+
+void
+audit_event(ssh_audit_event_t event)
+{
+       char    textbuf[BSM_TEXTBUFSZ];
+       static int logged_in = 0;
+       const char *user = the_authctxt ? the_authctxt->user : "(unknown user)";
+
+       if (cannot_audit(0))
+               return;
+
+       switch(event) {
+       case SSH_AUTH_SUCCESS:
+               logged_in = 1;
+               bsm_audit_session_setup();
+               snprintf(textbuf, sizeof(textbuf),
+                   gettext("successful login %s"), user);
+               bsm_audit_record(0, textbuf, AUE_openssh);
+               break;
+
+       case SSH_CONNECTION_CLOSE:
+               /*
+                * We can also get a close event if the user attempted auth
+                * but never succeeded.
+                */
+               if (logged_in) {
+                       snprintf(textbuf, sizeof(textbuf),
+                           gettext("sshd logout %s"), the_authctxt->user);
+                       bsm_audit_record(0, textbuf, AUE_logout);
+               } else {
+                       debug("%s: connection closed without authentication",
+                           __func__);
+               }
+               break;
+
+       case SSH_NOLOGIN:
+               bsm_audit_record(1,
+                   gettext("logins disabled by /etc/nologin"), AUE_openssh);
+               break;
+
+       case SSH_LOGIN_EXCEED_MAXTRIES:
+               snprintf(textbuf, sizeof(textbuf),
+                   gettext("too many tries for user %s"), the_authctxt->user);
+               bsm_audit_record(1, textbuf, AUE_openssh);
+               break;
+
+       case SSH_LOGIN_ROOT_DENIED:
+               bsm_audit_record(2, gettext("not_console"), AUE_openssh);
+               break;
+
+       case SSH_AUTH_FAIL_PASSWD:
+               bsm_audit_bad_login("password");
+               break;
+
+       case SSH_AUTH_FAIL_KBDINT:
+               bsm_audit_bad_login("interactive password entry");
+               break;
+
+       default:
+               debug("%s: unhandled event %d", __func__, event);
+       }
+}
+#endif /* BSM */
diff --git a/crypto/openssh-4/audit.c b/crypto/openssh-4/audit.c
new file mode 100644 (file)
index 0000000..18fc410
--- /dev/null
@@ -0,0 +1,181 @@
+/* $Id: audit.c,v 1.2 2005/02/08 10:52:48 dtucker Exp $ */
+
+/*
+ * Copyright (c) 2004, 2005 Darren Tucker.  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 SSH_AUDIT_EVENTS
+
+#include "audit.h"
+#include "log.h"
+#include "auth.h"
+
+/*
+ * Care must be taken when using this since it WILL NOT be initialized when
+ * audit_connection_from() is called and MAY NOT be initialized when
+ * audit_event(CONNECTION_ABANDON) is called.  Test for NULL before using.
+ */
+extern Authctxt *the_authctxt;
+
+/* Maybe add the audit class to struct Authmethod? */
+ssh_audit_event_t
+audit_classify_auth(const char *method)
+{
+       if (strcmp(method, "none") == 0)
+               return SSH_AUTH_FAIL_NONE;
+       else if (strcmp(method, "password") == 0)
+               return SSH_AUTH_FAIL_PASSWD;
+       else if (strcmp(method, "publickey") == 0 ||
+           strcmp(method, "rsa") == 0)
+               return SSH_AUTH_FAIL_PUBKEY;
+       else if (strncmp(method, "keyboard-interactive", 20) == 0 ||
+           strcmp(method, "challenge-response") == 0)
+               return SSH_AUTH_FAIL_KBDINT;
+       else if (strcmp(method, "hostbased") == 0 ||
+           strcmp(method, "rhosts-rsa") == 0)
+               return SSH_AUTH_FAIL_HOSTBASED;
+       else if (strcmp(method, "gssapi-with-mic") == 0)
+               return SSH_AUTH_FAIL_GSSAPI;
+       else
+               return SSH_AUDIT_UNKNOWN;
+}
+
+/* helper to return supplied username */
+const char *
+audit_username(void)
+{
+       static const char unknownuser[] = "(unknown user)";
+       static const char invaliduser[] = "(invalid user)";
+
+       if (the_authctxt == NULL || the_authctxt->user == NULL)
+               return (unknownuser);
+       if (!the_authctxt->valid)
+               return (invaliduser);
+       return (the_authctxt->user);
+}
+
+const char *
+audit_event_lookup(ssh_audit_event_t ev)
+{
+       int i;
+       static struct event_lookup_struct {
+               ssh_audit_event_t event;
+               const char *name;
+       } event_lookup[] = {
+               {SSH_LOGIN_EXCEED_MAXTRIES,     "LOGIN_EXCEED_MAXTRIES"},
+               {SSH_LOGIN_ROOT_DENIED,         "LOGIN_ROOT_DENIED"},
+               {SSH_AUTH_SUCCESS,              "AUTH_SUCCESS"},
+               {SSH_AUTH_FAIL_NONE,            "AUTH_FAIL_NONE"},
+               {SSH_AUTH_FAIL_PASSWD,          "AUTH_FAIL_PASSWD"},
+               {SSH_AUTH_FAIL_KBDINT,          "AUTH_FAIL_KBDINT"},
+               {SSH_AUTH_FAIL_PUBKEY,          "AUTH_FAIL_PUBKEY"},
+               {SSH_AUTH_FAIL_HOSTBASED,       "AUTH_FAIL_HOSTBASED"},
+               {SSH_AUTH_FAIL_GSSAPI,          "AUTH_FAIL_GSSAPI"},
+               {SSH_INVALID_USER,              "INVALID_USER"},
+               {SSH_NOLOGIN,                   "NOLOGIN"},
+               {SSH_CONNECTION_CLOSE,          "CONNECTION_CLOSE"},
+               {SSH_CONNECTION_ABANDON,        "CONNECTION_ABANDON"},
+               {SSH_AUDIT_UNKNOWN,             "AUDIT_UNKNOWN"}
+       };
+
+       for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++)
+               if (event_lookup[i].event == ev)
+                       break;
+       return(event_lookup[i].name);
+}
+
+# ifndef CUSTOM_SSH_AUDIT_EVENTS
+/*
+ * Null implementations of audit functions.
+ * These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled.
+ */
+
+/*
+ * Called after a connection has been accepted but before any authentication
+ * has been attempted.
+ */
+void
+audit_connection_from(const char *host, int port)
+{
+       debug("audit connection from %s port %d euid %d", host, port,
+          (int)geteuid());
+}
+
+/*
+ * Called when various events occur (see audit.h for a list of possible
+ * events and what they mean).
+ */
+void
+audit_event(ssh_audit_event_t event)
+{
+       debug("audit event euid %d user %s event %d (%s)", geteuid(),
+           audit_username(), event, audit_event_lookup(event));
+}
+
+/*
+ * Called when a user session is started.  Argument is the tty allocated to
+ * the session, or NULL if no tty was allocated.
+ *
+ * Note that this may be called multiple times if multiple sessions are used
+ * within a single connection.
+ */
+void
+audit_session_open(const char *ttyn)
+{
+       const char *t = ttyn ? ttyn : "(no tty)";
+
+       debug("audit session open euid %d user %s tty name %s", geteuid(),
+            audit_username(), t);
+}
+
+/*
+ * Called when a user session is closed.  Argument is the tty allocated to
+ * the session, or NULL if no tty was allocated.
+ *
+ * Note that this may be called multiple times if multiple sessions are used
+ * within a single connection.
+ */
+void
+audit_session_close(const char *ttyn)
+{
+       const char *t = ttyn ? ttyn : "(no tty)";
+
+       debug("audit session close euid %d user %s tty name %s", geteuid(),
+            audit_username(), t);
+}
+
+/*
+ * This will be called when a user runs a non-interactive command.  Note that
+ * it may be called multiple times for a single connection since SSH2 allows
+ * multiple sessions within a single connection.
+ */
+void
+audit_run_command(const char *command)
+{
+       debug("audit run command euid %d user %s command '%.200s'", geteuid(),
+           audit_username(), command);
+}
+# endif  /* !defined CUSTOM_SSH_AUDIT_EVENTS */
+#endif /* SSH_AUDIT_EVENTS */
diff --git a/crypto/openssh-4/audit.h b/crypto/openssh-4/audit.h
new file mode 100644 (file)
index 0000000..78e5896
--- /dev/null
@@ -0,0 +1,56 @@
+/* $Id: audit.h,v 1.2 2005/02/08 10:52:48 dtucker Exp $ */
+
+/*
+ * Copyright (c) 2004, 2005 Darren Tucker.  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 "auth.h"
+
+#ifndef _SSH_AUDIT_H
+# define _SSH_AUDIT_H
+enum ssh_audit_event_type {
+       SSH_LOGIN_EXCEED_MAXTRIES,
+       SSH_LOGIN_ROOT_DENIED,
+       SSH_AUTH_SUCCESS,
+       SSH_AUTH_FAIL_NONE,
+       SSH_AUTH_FAIL_PASSWD,
+       SSH_AUTH_FAIL_KBDINT,   /* keyboard-interactive or challenge-response */
+       SSH_AUTH_FAIL_PUBKEY,   /* ssh2 pubkey or ssh1 rsa */
+       SSH_AUTH_FAIL_HOSTBASED,        /* ssh2 hostbased or ssh1 rhostsrsa */
+       SSH_AUTH_FAIL_GSSAPI,
+       SSH_INVALID_USER,
+       SSH_NOLOGIN,            /* denied by /etc/nologin, not implemented */
+       SSH_CONNECTION_CLOSE,   /* closed after attempting auth or session */
+       SSH_CONNECTION_ABANDON, /* closed without completing auth */
+       SSH_AUDIT_UNKNOWN
+};
+typedef enum ssh_audit_event_type ssh_audit_event_t;
+
+void   audit_connection_from(const char *, int);
+void   audit_event(ssh_audit_event_t);
+void   audit_session_open(const char *);
+void   audit_session_close(const char *);
+void   audit_run_command(const char *);
+ssh_audit_event_t audit_classify_auth(const char *);
+
+#endif /* _SSH_AUDIT_H */
diff --git a/crypto/openssh-4/auth-bsdauth.c b/crypto/openssh-4/auth-bsdauth.c
new file mode 100644 (file)
index 0000000..920c977
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * 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: auth-bsdauth.c,v 1.6 2005/01/19 13:11:47 dtucker Exp $");
+
+#ifdef BSD_AUTH
+#include "xmalloc.h"
+#include "auth.h"
+#include "log.h"
+#include "monitor_wrap.h"
+
+static void *
+bsdauth_init_ctx(Authctxt *authctxt)
+{
+       return authctxt;
+}
+
+int
+bsdauth_query(void *ctx, char **name, char **infotxt,
+   u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+       Authctxt *authctxt = ctx;
+       char *challenge = NULL;
+
+       if (authctxt->as != NULL) {
+               debug2("bsdauth_query: try reuse session");
+               challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
+               if (challenge == NULL) {
+                       auth_close(authctxt->as);
+                       authctxt->as = NULL;
+               }
+       }
+
+       if (challenge == NULL) {
+               debug2("bsdauth_query: new bsd auth session");
+               debug3("bsdauth_query: style %s",
+                   authctxt->style ? authctxt->style : "<default>");
+               authctxt->as = auth_userchallenge(authctxt->user,
+                   authctxt->style, "auth-ssh", &challenge);
+               if (authctxt->as == NULL)
+                       challenge = NULL;
+               debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
+       }
+
+       if (challenge == NULL)
+               return -1;
+
+       *name = xstrdup("");
+       *infotxt = xstrdup("");
+       *numprompts = 1;
+       *prompts = xmalloc(*numprompts * sizeof(char *));
+       *echo_on = xmalloc(*numprompts * sizeof(u_int));
+       (*echo_on)[0] = 0;
+       (*prompts)[0] = xstrdup(challenge);
+
+       return 0;
+}
+
+int
+bsdauth_respond(void *ctx, u_int numresponses, char **responses)
+{
+       Authctxt *authctxt = ctx;
+       int authok;
+
+       if (!authctxt->valid)
+               return -1;
+
+       if (authctxt->as == 0)
+               error("bsdauth_respond: no bsd auth session");
+
+       if (numresponses != 1)
+               return -1;
+
+       authok = auth_userresponse(authctxt->as, responses[0], 0);
+       authctxt->as = NULL;
+       debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
+
+       return (authok == 0) ? -1 : 0;
+}
+
+static void
+bsdauth_free_ctx(void *ctx)
+{
+       Authctxt *authctxt = ctx;
+
+       if (authctxt && authctxt->as) {
+               auth_close(authctxt->as);
+               authctxt->as = NULL;
+       }
+}
+
+KbdintDevice bsdauth_device = {
+       "bsdauth",
+       bsdauth_init_ctx,
+       bsdauth_query,
+       bsdauth_respond,
+       bsdauth_free_ctx
+};
+
+KbdintDevice mm_bsdauth_device = {
+       "bsdauth",
+       bsdauth_init_ctx,
+       mm_bsdauth_query,
+       mm_bsdauth_respond,
+       bsdauth_free_ctx
+};
+#endif
diff --git a/crypto/openssh-4/auth-chall.c b/crypto/openssh-4/auth-chall.c
new file mode 100644 (file)
index 0000000..e4f7830
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * 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: auth-chall.c,v 1.9 2003/11/03 09:03:37 djm Exp $");
+
+#include "auth.h"
+#include "log.h"
+#include "xmalloc.h"
+#include "servconf.h"
+
+/* limited protocol v1 interface to kbd-interactive authentication */
+
+extern KbdintDevice *devices[];
+static KbdintDevice *device;
+extern ServerOptions options;
+
+char *
+get_challenge(Authctxt *authctxt)
+{
+       char *challenge, *name, *info, **prompts;
+       u_int i, numprompts;
+       u_int *echo_on;
+
+#ifdef USE_PAM
+       if (!options.use_pam)
+               remove_kbdint_device("pam");
+#endif
+
+       device = devices[0]; /* we always use the 1st device for protocol 1 */
+       if (device == NULL)
+               return NULL;
+       if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL)
+               return NULL;
+       if (device->query(authctxt->kbdintctxt, &name, &info,
+           &numprompts, &prompts, &echo_on)) {
+               device->free_ctx(authctxt->kbdintctxt);
+               authctxt->kbdintctxt = NULL;
+               return NULL;
+       }
+       if (numprompts < 1)
+               fatal("get_challenge: numprompts < 1");
+       challenge = xstrdup(prompts[0]);
+       for (i = 0; i < numprompts; i++)
+               xfree(prompts[i]);
+       xfree(prompts);
+       xfree(name);
+       xfree(echo_on);
+       xfree(info);
+
+       return (challenge);
+}
+int
+verify_response(Authctxt *authctxt, const char *response)
+{
+       char *resp[1], *name, *info, **prompts;
+       u_int i, numprompts, *echo_on;
+       int authenticated = 0;
+
+       if (device == NULL)
+               return 0;
+       if (authctxt->kbdintctxt == NULL)
+               return 0;
+       resp[0] = (char *)response;
+       switch (device->respond(authctxt->kbdintctxt, 1, resp)) {
+       case 0: /* Success */
+               authenticated = 1;
+               break;
+       case 1: /* Postponed - retry with empty query for PAM */
+               if ((device->query(authctxt->kbdintctxt, &name, &info,
+                   &numprompts, &prompts, &echo_on)) != 0)
+                       break;
+               if (numprompts == 0 &&
+                   device->respond(authctxt->kbdintctxt, 0, resp) == 0)
+                       authenticated = 1;
+
+               for (i = 0; i < numprompts; i++)
+                       xfree(prompts[i]);
+               xfree(prompts);
+               xfree(name);
+               xfree(echo_on);
+               xfree(info);
+               break;
+       }
+       device->free_ctx(authctxt->kbdintctxt);
+       authctxt->kbdintctxt = NULL;
+       return authenticated;
+}
+void
+abandon_challenge_response(Authctxt *authctxt)
+{
+       if (authctxt->kbdintctxt != NULL) {
+               device->free_ctx(authctxt->kbdintctxt);
+               authctxt->kbdintctxt = NULL;
+       }
+}
diff --git a/crypto/openssh-4/auth-krb5.c b/crypto/openssh-4/auth-krb5.c
new file mode 100644 (file)
index 0000000..2f74253
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ *    Kerberos v5 authentication and ticket-passing routines.
+ *
+ * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
+ */
+/*
+ * Copyright (c) 2002 Daniel Kouril.  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: auth-krb5.c,v 1.15 2003/11/21 11:57:02 djm Exp $");
+
+#include "ssh.h"
+#include "ssh1.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "log.h"
+#include "servconf.h"
+#include "uidswap.h"
+#include "auth.h"
+
+#ifdef KRB5
+#include <krb5.h>
+
+extern ServerOptions    options;
+
+static int
+krb5_init(void *context)
+{
+       Authctxt *authctxt = (Authctxt *)context;
+       krb5_error_code problem;
+
+       if (authctxt->krb5_ctx == NULL) {
+               problem = krb5_init_context(&authctxt->krb5_ctx);
+               if (problem)
+                       return (problem);
+#ifdef KRB5_INIT_ETS
+               krb5_init_ets(authctxt->krb5_ctx);
+#endif
+       }
+       return (0);
+}
+
+int
+auth_krb5_password(Authctxt *authctxt, const char *password)
+{
+#ifndef HEIMDAL
+       krb5_creds creds;
+       krb5_principal server;
+       char ccname[40];
+       int tmpfd;
+       mode_t old_umask;
+#endif
+       krb5_error_code problem;
+       krb5_ccache ccache = NULL;
+       int len;
+
+       if (!authctxt->valid)
+               return (0);
+
+       temporarily_use_uid(authctxt->pw);
+
+       problem = krb5_init(authctxt);
+       if (problem)
+               goto out;
+
+       problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
+                   &authctxt->krb5_user);
+       if (problem)
+               goto out;
+
+#ifdef HEIMDAL
+       problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache);
+       if (problem)
+               goto out;
+
+       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,
+           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,
+           authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL);
+       if (problem)
+               goto out;
+
+       problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL,
+           KRB5_NT_SRV_HST, &server);
+       if (problem)
+               goto out;
+
+       restore_uid();
+       problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server,
+           NULL, NULL, NULL);
+       krb5_free_principal(authctxt->krb5_ctx, server);
+       temporarily_use_uid(authctxt->pw);
+       if (problem)
+               goto out;
+
+       if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
+                         authctxt->pw->pw_name)) {
+               problem = -1;
+               goto out;
+       }
+
+       snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
+
+       old_umask = umask(0177);
+       tmpfd = mkstemp(ccname + strlen("FILE:"));
+       umask(old_umask);
+       if (tmpfd == -1) {
+               logit("mkstemp(): %.100s", strerror(errno));
+               problem = errno;
+               goto out;
+       }
+
+       if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
+               logit("fchmod(): %.100s", strerror(errno));
+               close(tmpfd);
+               problem = errno;
+               goto out;
+       }
+       close(tmpfd);
+
+       problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache);
+       if (problem)
+               goto out;
+
+       problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
+                                    authctxt->krb5_user);
+       if (problem)
+               goto out;
+
+       problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
+                                &creds);
+       if (problem)
+               goto out;
+#endif
+
+       authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
+
+       len = strlen(authctxt->krb5_ticket_file) + 6;
+       authctxt->krb5_ccname = xmalloc(len);
+       snprintf(authctxt->krb5_ccname, len, "FILE:%s",
+           authctxt->krb5_ticket_file);
+
+#ifdef USE_PAM
+       if (options.use_pam)
+               do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
+#endif
+
+ out:
+       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));
+               else
+                       debug("Kerberos password authentication failed: %d",
+                           problem);
+
+               krb5_cleanup_proc(authctxt);
+
+               if (options.kerberos_or_local_passwd)
+                       return (-1);
+               else
+                       return (0);
+       }
+       return (1);
+}
+
+void
+krb5_cleanup_proc(Authctxt *authctxt)
+{
+       debug("krb5_cleanup_proc called");
+       if (authctxt->krb5_fwd_ccache) {
+               krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
+               authctxt->krb5_fwd_ccache = NULL;
+       }
+       if (authctxt->krb5_user) {
+               krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
+               authctxt->krb5_user = NULL;
+       }
+       if (authctxt->krb5_ctx) {
+               krb5_free_context(authctxt->krb5_ctx);
+               authctxt->krb5_ctx = NULL;
+       }
+}
+
+#endif /* KRB5 */
diff --git a/crypto/openssh-4/auth-options.c b/crypto/openssh-4/auth-options.c
new file mode 100644 (file)
index 0000000..a85e408
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth-options.c,v 1.31 2005/03/10 22:40:38 deraadt Exp $");
+
+#include "xmalloc.h"
+#include "match.h"
+#include "log.h"
+#include "canohost.h"
+#include "channels.h"
+#include "auth-options.h"
+#include "servconf.h"
+#include "misc.h"
+#include "monitor_wrap.h"
+#include "auth.h"
+
+/* Flags set authorized_keys flags */
+int no_port_forwarding_flag = 0;
+int no_agent_forwarding_flag = 0;
+int no_x11_forwarding_flag = 0;
+int no_pty_flag = 0;
+
+/* "command=" option. */
+char *forced_command = NULL;
+
+/* "environment=" options. */
+struct envstring *custom_environment = NULL;
+
+extern ServerOptions options;
+
+void
+auth_clear_options(void)
+{
+       no_agent_forwarding_flag = 0;
+       no_port_forwarding_flag = 0;
+       no_pty_flag = 0;
+       no_x11_forwarding_flag = 0;
+       while (custom_environment) {
+               struct envstring *ce = custom_environment;
+               custom_environment = ce->next;
+               xfree(ce->s);
+               xfree(ce);
+       }
+       if (forced_command) {
+               xfree(forced_command);
+               forced_command = NULL;
+       }
+       channel_clear_permitted_opens();
+       auth_debug_reset();
+}
+
+/*
+ * return 1 if access is granted, 0 if not.
+ * side effect: sets key option flags
+ */
+int
+auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
+{
+       const char *cp;
+       int i;
+
+       /* reset options */
+       auth_clear_options();
+
+       if (!opts)
+               return 1;
+
+       while (*opts && *opts != ' ' && *opts != '\t') {
+               cp = "no-port-forwarding";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       auth_debug_add("Port forwarding disabled.");
+                       no_port_forwarding_flag = 1;
+                       opts += strlen(cp);
+                       goto next_option;
+               }
+               cp = "no-agent-forwarding";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       auth_debug_add("Agent forwarding disabled.");
+                       no_agent_forwarding_flag = 1;
+                       opts += strlen(cp);
+                       goto next_option;
+               }
+               cp = "no-X11-forwarding";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       auth_debug_add("X11 forwarding disabled.");
+                       no_x11_forwarding_flag = 1;
+                       opts += strlen(cp);
+                       goto next_option;
+               }
+               cp = "no-pty";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       auth_debug_add("Pty allocation disabled.");
+                       no_pty_flag = 1;
+                       opts += strlen(cp);
+                       goto next_option;
+               }
+               cp = "command=\"";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       opts += strlen(cp);
+                       forced_command = xmalloc(strlen(opts) + 1);
+                       i = 0;
+                       while (*opts) {
+                               if (*opts == '"')
+                                       break;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
+                                       forced_command[i++] = '"';
+                                       continue;
+                               }
+                               forced_command[i++] = *opts++;
+                       }
+                       if (!*opts) {
+                               debug("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               auth_debug_add("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               xfree(forced_command);
+                               forced_command = NULL;
+                               goto bad_option;
+                       }
+                       forced_command[i] = 0;
+                       auth_debug_add("Forced command: %.900s", forced_command);
+                       opts++;
+                       goto next_option;
+               }
+               cp = "environment=\"";
+               if (options.permit_user_env &&
+                   strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       char *s;
+                       struct envstring *new_envstring;
+
+                       opts += strlen(cp);
+                       s = xmalloc(strlen(opts) + 1);
+                       i = 0;
+                       while (*opts) {
+                               if (*opts == '"')
+                                       break;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
+                                       s[i++] = '"';
+                                       continue;
+                               }
+                               s[i++] = *opts++;
+                       }
+                       if (!*opts) {
+                               debug("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               auth_debug_add("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               xfree(s);
+                               goto bad_option;
+                       }
+                       s[i] = 0;
+                       auth_debug_add("Adding to environment: %.900s", s);
+                       debug("Adding to environment: %.900s", s);
+                       opts++;
+                       new_envstring = xmalloc(sizeof(struct envstring));
+                       new_envstring->s = s;
+                       new_envstring->next = custom_environment;
+                       custom_environment = new_envstring;
+                       goto next_option;
+               }
+               cp = "from=\"";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       const char *remote_ip = get_remote_ipaddr();
+                       const char *remote_host = get_canonical_hostname(
+                           options.use_dns);
+                       char *patterns = xmalloc(strlen(opts) + 1);
+
+                       opts += strlen(cp);
+                       i = 0;
+                       while (*opts) {
+                               if (*opts == '"')
+                                       break;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
+                                       patterns[i++] = '"';
+                                       continue;
+                               }
+                               patterns[i++] = *opts++;
+                       }
+                       if (!*opts) {
+                               debug("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               auth_debug_add("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               xfree(patterns);
+                               goto bad_option;
+                       }
+                       patterns[i] = 0;
+                       opts++;
+                       if (match_host_and_ip(remote_host, remote_ip,
+                           patterns) != 1) {
+                               xfree(patterns);
+                               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);
+                               auth_debug_add("Your host '%.200s' is not "
+                                   "permitted to use this key for login.",
+                                   remote_host);
+                               /* deny access */
+                               return 0;
+                       }
+                       xfree(patterns);
+                       /* Host name matches. */
+                       goto next_option;
+               }
+               cp = "permitopen=\"";
+               if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+                       char *host, *p;
+                       u_short port;
+                       char *patterns = xmalloc(strlen(opts) + 1);
+
+                       opts += strlen(cp);
+                       i = 0;
+                       while (*opts) {
+                               if (*opts == '"')
+                                       break;
+                               if (*opts == '\\' && opts[1] == '"') {
+                                       opts += 2;
+                                       patterns[i++] = '"';
+                                       continue;
+                               }
+                               patterns[i++] = *opts++;
+                       }
+                       if (!*opts) {
+                               debug("%.100s, line %lu: missing end quote",
+                                   file, linenum);
+                               auth_debug_add("%.100s, line %lu: missing "
+                                   "end quote", file, linenum);
+                               xfree(patterns);
+                               goto bad_option;
+                       }
+                       patterns[i] = 0;
+                       opts++;
+                       p = patterns;
+                       host = hpdelim(&p);
+                       if (host == NULL || strlen(host) >= NI_MAXHOST) {
+                               debug("%.100s, line %lu: Bad permitopen "
+                                   "specification <%.100s>", file, linenum,
+                                   patterns);
+                               auth_debug_add("%.100s, line %lu: "
+                                   "Bad permitopen specification", file,
+                                   linenum);
+                               xfree(patterns);
+                               goto bad_option;
+                       }
+                       host = cleanhostname(host);
+                       if (p == NULL || (port = a2port(p)) == 0) {
+                               debug("%.100s, line %lu: Bad permitopen port "
+                                   "<%.100s>", file, linenum, p ? p : "");
+                               auth_debug_add("%.100s, line %lu: "
+                                   "Bad permitopen port", file, linenum);
+                               xfree(patterns);
+                               goto bad_option;
+                       }
+                       if (options.allow_tcp_forwarding)
+                               channel_add_permitted_opens(host, port);
+                       xfree(patterns);
+                       goto next_option;
+               }
+next_option:
+               /*
+                * Skip the comma, and move to the next option
+                * (or break out if there are no more).
+                */
+               if (!*opts)
+                       fatal("Bugs in auth-options.c option processing.");
+               if (*opts == ' ' || *opts == '\t')
+                       break;          /* End of options. */
+               if (*opts != ',')
+                       goto bad_option;
+               opts++;
+               /* Process the next option. */
+       }
+
+       if (!use_privsep)
+               auth_debug_send();
+
+       /* grant access */
+       return 1;
+
+bad_option:
+       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);
+
+       if (!use_privsep)
+               auth_debug_send();
+
+       /* deny access */
+       return 0;
+}
diff --git a/crypto/openssh-4/auth-options.h b/crypto/openssh-4/auth-options.h
new file mode 100644 (file)
index 0000000..15fb212
--- /dev/null
@@ -0,0 +1,35 @@
+/*     $OpenBSD: auth-options.h,v 1.12 2002/07/21 18:34:43 stevesk Exp $       */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#ifndef AUTH_OPTIONS_H
+#define AUTH_OPTIONS_H
+
+/* Linked list of custom environment strings */
+struct envstring {
+       struct envstring *next;
+       char   *s;
+};
+
+/* Flags that may be set in authorized_keys options. */
+extern int no_port_forwarding_flag;
+extern int no_agent_forwarding_flag;
+extern int no_x11_forwarding_flag;
+extern int no_pty_flag;
+extern char *forced_command;
+extern struct envstring *custom_environment;
+
+int    auth_parse_options(struct passwd *, char *, char *, u_long);
+void   auth_clear_options(void);
+
+#endif
diff --git a/crypto/openssh-4/auth-pam.h b/crypto/openssh-4/auth-pam.h
new file mode 100644 (file)
index 0000000..a1a2b52
--- /dev/null
@@ -0,0 +1,50 @@
+/* $Id: auth-pam.h,v 1.27 2004/09/11 12:17:26 dtucker Exp $ */
+
+/*
+ * Copyright (c) 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"
+#ifdef USE_PAM
+
+#if !defined(SSHD_PAM_SERVICE)
+# define SSHD_PAM_SERVICE              __progname
+#endif
+
+void start_pam(Authctxt *);
+void finish_pam(void);
+u_int do_pam_account(void);
+void do_pam_session(void);
+void do_pam_set_tty(const char *);
+void do_pam_setcred(int );
+void do_pam_chauthtok(void);
+int do_pam_putenv(char *, char *);
+char ** fetch_pam_environment(void);
+char ** fetch_pam_child_environment(void);
+void free_pam_environment(char **);
+void sshpam_thread_cleanup(void);
+void sshpam_cleanup(void);
+int sshpam_auth_passwd(Authctxt *, const char *);
+int is_pam_session_open(void);
+
+#endif /* USE_PAM */
diff --git a/crypto/openssh-4/auth-passwd.c b/crypto/openssh-4/auth-passwd.c
new file mode 100644 (file)
index 0000000..654e0b8
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Password authentication.  This file contains the functions to check whether
+ * the password is valid for the user.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ * Copyright (c) 1999 Dug Song.  All rights reserved.
+ * Copyright (c) 2000 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: auth-passwd.c,v 1.33 2005/01/24 11:47:13 dtucker Exp $");
+
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "auth.h"
+#include "auth-options.h"
+
+extern Buffer loginmsg;
+extern ServerOptions options;
+
+#ifdef HAVE_LOGIN_CAP
+extern login_cap_t *lc;
+#endif
+
+
+#define DAY            (24L * 60 * 60) /* 1 day in seconds */
+#define TWO_WEEKS      (2L * 7 * DAY)  /* 2 weeks in seconds */
+
+void
+disable_forwarding(void)
+{
+       no_port_forwarding_flag = 1;
+       no_agent_forwarding_flag = 1;
+       no_x11_forwarding_flag = 1;
+}
+
+/*
+ * Tries to authenticate the user using password.  Returns true if
+ * authentication succeeds.
+ */
+int
+auth_password(Authctxt *authctxt, const char *password)
+{
+       struct passwd * pw = authctxt->pw;
+       int result, ok = authctxt->valid;
+#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
+       static int expire_checked = 0;
+#endif
+
+#ifndef HAVE_CYGWIN
+       if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
+               ok = 0;
+#endif
+       if (*password == '\0' && options.permit_empty_passwd == 0)
+               return 0;
+
+#ifdef KRB5
+       if (options.kerberos_authentication == 1) {
+               int ret = auth_krb5_password(authctxt, password);
+               if (ret == 1 || ret == 0)
+                       return ret && ok;
+               /* Fall back to ordinary passwd authentication. */
+       }
+#endif
+#ifdef HAVE_CYGWIN
+       if (is_winnt) {
+               HANDLE hToken = cygwin_logon_user(pw, password);
+
+               if (hToken == INVALID_HANDLE_VALUE)
+                       return 0;
+               cygwin_set_impersonation_token(hToken);
+               return ok;
+       }
+#endif
+#ifdef USE_PAM
+       if (options.use_pam)
+               return (sshpam_auth_passwd(authctxt, password) && ok);
+#endif
+#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
+       if (!expire_checked) {
+               expire_checked = 1;
+               if (auth_shadow_pwexpired(authctxt))
+                       authctxt->force_pwchange = 1;
+       }
+#endif
+       result = sys_auth_passwd(authctxt, password);
+       if (authctxt->force_pwchange)
+               disable_forwarding();
+       return (result && ok);
+}
+
+#ifdef BSD_AUTH
+static void
+warn_expiry(Authctxt *authctxt, auth_session_t *as)
+{
+       char buf[256];
+       quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
+
+       pwwarntime = acwarntime = TWO_WEEKS;
+
+       pwtimeleft = auth_check_change(as);
+       actimeleft = auth_check_expire(as);
+#ifdef HAVE_LOGIN_CAP
+       if (authctxt->valid) {
+               pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS,
+                   TWO_WEEKS);
+               acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS,
+                   TWO_WEEKS);
+       }
+#endif
+       if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
+               daysleft = pwtimeleft / DAY + 1;
+               snprintf(buf, sizeof(buf),
+                   "Your password will expire in %lld day%s.\n",
+                   daysleft, daysleft == 1 ? "" : "s");
+               buffer_append(&loginmsg, buf, strlen(buf));
+       }
+       if (actimeleft != 0 && actimeleft < acwarntime) {
+               daysleft = actimeleft / DAY + 1;
+               snprintf(buf, sizeof(buf),
+                   "Your account will expire in %lld day%s.\n",
+                   daysleft, daysleft == 1 ? "" : "s");
+               buffer_append(&loginmsg, buf, strlen(buf));
+       }
+}
+
+int
+sys_auth_passwd(Authctxt *authctxt, const char *password)
+{
+       struct passwd *pw = authctxt->pw;
+       auth_session_t *as;
+       static int expire_checked = 0;
+
+       as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
+           (char *)password);
+       if (auth_getstate(as) & AUTH_PWEXPIRED) {
+               auth_close(as);
+               disable_forwarding();
+               authctxt->force_pwchange = 1;
+               return (1);
+       } else {
+               if (!expire_checked) {
+                       expire_checked = 1;
+                       warn_expiry(authctxt, as);
+               }
+               return (auth_close(as));
+       }
+}
+#elif !defined(CUSTOM_SYS_AUTH_PASSWD)
+int
+sys_auth_passwd(Authctxt *authctxt, const char *password)
+{
+       struct passwd *pw = authctxt->pw;
+       char *encrypted_password;
+
+       /* 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 (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
+               return (1);
+
+       /* Encrypt the candidate password using the proper salt. */
+       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);
+}
+#endif
diff --git a/crypto/openssh-4/auth-rh-rsa.c b/crypto/openssh-4/auth-rh-rsa.c
new file mode 100644 (file)
index 0000000..29eb538
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Rhosts or /etc/hosts.equiv authentication combined with RSA host
+ * authentication.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth-rh-rsa.c,v 1.37 2003/11/04 08:54:09 djm Exp $");
+
+#include "packet.h"
+#include "uidswap.h"
+#include "log.h"
+#include "servconf.h"
+#include "key.h"
+#include "hostfile.h"
+#include "pathnames.h"
+#include "auth.h"
+#include "canohost.h"
+
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+
+int
+auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
+    Key *client_host_key)
+{
+       HostStatus host_status;
+
+       /* Check if we would accept it using rhosts authentication. */
+       if (!auth_rhosts(pw, cuser))
+               return 0;
+
+       host_status = check_key_in_hostfiles(pw, client_host_key,
+           chost, _PATH_SSH_SYSTEM_HOSTFILE,
+           options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
+
+       return (host_status == HOST_OK);
+}
+
+/*
+ * Tries to authenticate the user using the .rhosts file and the host using
+ * its host key.  Returns true if authentication succeeds.
+ */
+int
+auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
+{
+       char *chost;
+       struct passwd *pw = authctxt->pw;
+
+       debug("Trying rhosts with RSA host authentication for client user %.100s",
+           cuser);
+
+       if (!authctxt->valid || client_host_key == NULL ||
+           client_host_key->rsa == NULL)
+               return 0;
+
+       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))) {
+               debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
+               packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
+               return 0;
+       }
+       /* A matching host key was found and is known. */
+
+       /* Perform the challenge-response dialog with the client for the host key. */
+       if (!auth_rsa_challenge_dialog(client_host_key)) {
+               logit("Client on %.800s failed to respond correctly to host authentication.",
+                   chost);
+               return 0;
+       }
+       /*
+        * We have authenticated the user using .rhosts or /etc/hosts.equiv,
+        * and the host using RSA. We accept the authentication.
+        */
+
+       verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.",
+          pw->pw_name, cuser, chost);
+       packet_send_debug("Rhosts with RSA host authentication accepted.");
+       return 1;
+}
diff --git a/crypto/openssh-4/auth-rhosts.c b/crypto/openssh-4/auth-rhosts.c
new file mode 100644 (file)
index 0000000..585246e
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Rhosts authentication.  This file contains code to check whether to admit
+ * the login based on rhosts authentication.  This file also processes
+ * /etc/hosts.equiv.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth-rhosts.c,v 1.32 2003/11/04 08:54:09 djm Exp $");
+
+#include "packet.h"
+#include "uidswap.h"
+#include "pathnames.h"
+#include "log.h"
+#include "servconf.h"
+#include "canohost.h"
+#include "auth.h"
+
+/* import */
+extern ServerOptions options;
+extern int use_privsep;
+
+/*
+ * This function processes an rhosts-style file (.rhosts, .shosts, or
+ * /etc/hosts.equiv).  This returns true if authentication can be granted
+ * based on the file, and returns zero otherwise.
+ */
+
+static int
+check_rhosts_file(const char *filename, const char *hostname,
+                 const char *ipaddr, const char *client_user,
+                 const char *server_user)
+{
+       FILE *f;
+       char buf[1024]; /* Must not be larger than host, user, dummy below. */
+
+       /* Open the .rhosts file, deny if unreadable */
+       f = fopen(filename, "r");
+       if (!f)
+               return 0;
+
+       while (fgets(buf, sizeof(buf), f)) {
+               /* All three must be at least as big as buf to avoid overflows. */
+               char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp;
+               int negated;
+
+               for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
+                       ;
+               if (*cp == '#' || *cp == '\n' || !*cp)
+                       continue;
+
+               /*
+                * NO_PLUS is supported at least on OSF/1.  We skip it (we
+                * don't ever support the plus syntax).
+                */
+               if (strncmp(cp, "NO_PLUS", 7) == 0)
+                       continue;
+
+               /*
+                * This should be safe because each buffer is as big as the
+                * whole string, and thus cannot be overwritten.
+                */
+               switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf,
+                   dummy)) {
+               case 0:
+                       auth_debug_add("Found empty line in %.100s.", filename);
+                       continue;
+               case 1:
+                       /* Host name only. */
+                       strlcpy(userbuf, server_user, sizeof(userbuf));
+                       break;
+               case 2:
+                       /* Got both host and user name. */
+                       break;
+               case 3:
+                       auth_debug_add("Found garbage in %.100s.", filename);
+                       continue;
+               default:
+                       /* Weird... */
+                       continue;
+               }
+
+               host = hostbuf;
+               user = userbuf;
+               negated = 0;
+
+               /* Process negated host names, or positive netgroups. */
+               if (host[0] == '-') {
+                       negated = 1;
+                       host++;
+               } else if (host[0] == '+')
+                       host++;
+
+               if (user[0] == '-') {
+                       negated = 1;
+                       user++;
+               } else if (user[0] == '+')
+                       user++;
+
+               /* Check for empty host/user names (particularly '+'). */
+               if (!host[0] || !user[0]) {
+                       /* We come here if either was '+' or '-'. */
+                       auth_debug_add("Ignoring wild host/user names in %.100s.",
+                           filename);
+                       continue;
+               }
+               /* Verify that host name matches. */
+               if (host[0] == '@') {
+                       if (!innetgr(host + 1, hostname, NULL, NULL) &&
+                           !innetgr(host + 1, ipaddr, NULL, NULL))
+                               continue;
+               } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0)
+                       continue;       /* Different hostname. */
+
+               /* Verify that user name matches. */
+               if (user[0] == '@') {
+                       if (!innetgr(user + 1, NULL, client_user, NULL))
+                               continue;
+               } else if (strcmp(user, client_user) != 0)
+                       continue;       /* Different username. */
+
+               /* Found the user and host. */
+               fclose(f);
+
+               /* If the entry was negated, deny access. */
+               if (negated) {
+                       auth_debug_add("Matched negative entry in %.100s.",
+                            filename);
+                       return 0;
+               }
+               /* Accept authentication. */
+               return 1;
+       }
+
+       /* Authentication using this file denied. */
+       fclose(f);
+       return 0;
+}
+
+/*
+ * Tries to authenticate the user using the .shosts or .rhosts file. Returns
+ * true if authentication succeeds.  If ignore_rhosts is true, only
+ * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored).
+ */
+
+int
+auth_rhosts(struct passwd *pw, const char *client_user)
+{
+       const char *hostname, *ipaddr;
+
+       hostname = get_canonical_hostname(options.use_dns);
+       ipaddr = get_remote_ipaddr();
+       return auth_rhosts2(pw, client_user, hostname, ipaddr);
+}
+
+static int
+auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostname,
+    const char *ipaddr)
+{
+       char buf[1024];
+       struct stat st;
+       static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
+       u_int rhosts_file_index;
+
+       debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s",
+           client_user, hostname, ipaddr);
+
+       /* Switch to the user's uid. */
+       temporarily_use_uid(pw);
+       /*
+        * Quick check: if the user has no .shosts or .rhosts files, return
+        * failure immediately without doing costly lookups from name
+        * servers.
+        */
+       for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
+           rhosts_file_index++) {
+               /* Check users .rhosts or .shosts. */
+               snprintf(buf, sizeof buf, "%.500s/%.100s",
+                        pw->pw_dir, rhosts_files[rhosts_file_index]);
+               if (stat(buf, &st) >= 0)
+                       break;
+       }
+       /* Switch back to privileged uid. */
+       restore_uid();
+
+       /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */
+       if (!rhosts_files[rhosts_file_index] &&
+           stat(_PATH_RHOSTS_EQUIV, &st) < 0 &&
+           stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0)
+               return 0;
+
+       /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
+       if (pw->pw_uid != 0) {
+               if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
+                   client_user, pw->pw_name)) {
+                       auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
+                           hostname, ipaddr);
+                       return 1;
+               }
+               if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
+                   client_user, pw->pw_name)) {
+                       auth_debug_add("Accepted for %.100s [%.100s] by %.100s.",
+                           hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
+                       return 1;
+               }
+       }
+       /*
+        * Check that the home directory is owned by root or the user, and is
+        * not group or world writable.
+        */
+       if (stat(pw->pw_dir, &st) < 0) {
+               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);
+               return 0;
+       }
+       if (options.strict_modes &&
+           ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
+           (st.st_mode & 022) != 0)) {
+               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);
+               return 0;
+       }
+       /* Temporarily use the user's uid. */
+       temporarily_use_uid(pw);
+
+       /* Check all .rhosts files (currently .shosts and .rhosts). */
+       for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
+           rhosts_file_index++) {
+               /* Check users .rhosts or .shosts. */
+               snprintf(buf, sizeof buf, "%.500s/%.100s",
+                        pw->pw_dir, rhosts_files[rhosts_file_index]);
+               if (stat(buf, &st) < 0)
+                       continue;
+
+               /*
+                * Make sure that the file is either owned by the user or by
+                * root, and make sure it is not writable by anyone but the
+                * owner.  This is to help avoid novices accidentally
+                * allowing access to their account by anyone.
+                */
+               if (options.strict_modes &&
+                   ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
+                   (st.st_mode & 022) != 0)) {
+                       logit("Rhosts authentication refused for %.100s: bad modes for %.200s",
+                           pw->pw_name, buf);
+                       auth_debug_add("Bad file modes for %.200s", buf);
+                       continue;
+               }
+               /* Check if we have been configured to ignore .rhosts and .shosts files. */
+               if (options.ignore_rhosts) {
+                       auth_debug_add("Server has been configured to ignore %.100s.",
+                           rhosts_files[rhosts_file_index]);
+                       continue;
+               }
+               /* Check if authentication is permitted by the file. */
+               if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) {
+                       auth_debug_add("Accepted by %.100s.",
+                           rhosts_files[rhosts_file_index]);
+                       /* Restore the privileged uid. */
+                       restore_uid();
+                       auth_debug_add("Accepted host %s ip %s client_user %s server_user %s",
+                               hostname, ipaddr, client_user, pw->pw_name);
+                       return 1;
+               }
+       }
+
+       /* Restore the privileged uid. */
+       restore_uid();
+       return 0;
+}
+
+int
+auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
+    const char *ipaddr)
+{
+       int ret;
+
+       auth_debug_reset();
+       ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
+       if (!use_privsep)
+               auth_debug_send();
+       return ret;
+}
diff --git a/crypto/openssh-4/auth-rsa.c b/crypto/openssh-4/auth-rsa.c
new file mode 100644 (file)
index 0000000..4378008
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * RSA-based authentication.  This code determines whether to admit a login
+ * based on RSA authentication.  This file also contains functions to check
+ * validity of the host key.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth-rsa.c,v 1.62 2004/12/11 01:48:56 dtucker Exp $");
+
+#include <openssl/rsa.h>
+#include <openssl/md5.h>
+
+#include "rsa.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "ssh1.h"
+#include "uidswap.h"
+#include "match.h"
+#include "auth-options.h"
+#include "pathnames.h"
+#include "log.h"
+#include "servconf.h"
+#include "auth.h"
+#include "hostfile.h"
+#include "monitor_wrap.h"
+#include "ssh.h"
+#include "misc.h"
+
+/* import */
+extern ServerOptions options;
+
+/*
+ * Session identifier that is used to bind key exchange and authentication
+ * responses to a particular session.
+ */
+extern u_char session_id[16];
+
+/*
+ * The .ssh/authorized_keys file contains public keys, one per line, in the
+ * following format:
+ *   options bits e n comment
+ * where bits, e and n are decimal numbers,
+ * and comment is any string of characters up to newline.  The maximum
+ * length of a line is SSH_MAX_PUBKEY_BYTES characters.  See sshd(8) for a
+ * description of the options.
+ */
+
+BIGNUM *
+auth_rsa_generate_challenge(Key *key)
+{
+       BIGNUM *challenge;
+       BN_CTX *ctx;
+
+       if ((challenge = BN_new()) == NULL)
+               fatal("auth_rsa_generate_challenge: BN_new() failed");
+       /* Generate a random challenge. */
+       BN_rand(challenge, 256, 0, 0);
+       if ((ctx = BN_CTX_new()) == NULL)
+               fatal("auth_rsa_generate_challenge: BN_CTX_new() failed");
+       BN_mod(challenge, challenge, key->rsa->n, ctx);
+       BN_CTX_free(ctx);
+
+       return challenge;
+}
+
+int
+auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
+{
+       u_char buf[32], mdbuf[16];
+       MD5_CTX md;
+       int len;
+
+       /* don't allow short keys */
+       if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+               error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits",
+                   BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
+               return (0);
+       }
+
+       /* The response is MD5 of decrypted challenge plus session id. */
+       len = BN_num_bytes(challenge);
+       if (len <= 0 || len > 32)
+               fatal("auth_rsa_verify_response: bad challenge length %d", len);
+       memset(buf, 0, 32);
+       BN_bn2bin(challenge, buf + 32 - len);
+       MD5_Init(&md);
+       MD5_Update(&md, buf, 32);
+       MD5_Update(&md, session_id, 16);
+       MD5_Final(mdbuf, &md);
+
+       /* Verify that the response is the original challenge. */
+       if (memcmp(response, mdbuf, 16) != 0) {
+               /* Wrong answer. */
+               return (0);
+       }
+       /* Correct answer. */
+       return (1);
+}
+
+/*
+ * Performs the RSA authentication challenge-response dialog with the client,
+ * and returns true (non-zero) if the client gave the correct answer to
+ * our challenge; returns zero if the client gives a wrong answer.
+ */
+
+int
+auth_rsa_challenge_dialog(Key *key)
+{
+       BIGNUM *challenge, *encrypted_challenge;
+       u_char response[16];
+       int i, success;
+
+       if ((encrypted_challenge = BN_new()) == NULL)
+               fatal("auth_rsa_challenge_dialog: BN_new() failed");
+
+       challenge = PRIVSEP(auth_rsa_generate_challenge(key));
+
+       /* Encrypt the challenge with the public key. */
+       rsa_public_encrypt(encrypted_challenge, challenge, key->rsa);
+
+       /* Send the encrypted challenge to the client. */
+       packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE);
+       packet_put_bignum(encrypted_challenge);
+       packet_send();
+       BN_clear_free(encrypted_challenge);
+       packet_write_wait();
+
+       /* Wait for a response. */
+       packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE);
+       for (i = 0; i < 16; i++)
+               response[i] = packet_get_char();
+       packet_check_eom();
+
+       success = PRIVSEP(auth_rsa_verify_response(key, challenge, response));
+       BN_clear_free(challenge);
+       return (success);
+}
+
+/*
+ * check if there's user key matching client_n,
+ * return key if login is allowed, NULL otherwise
+ */
+
+int
+auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+{
+       char line[SSH_MAX_PUBKEY_BYTES], *file;
+       int allowed = 0;
+       u_int bits;
+       FILE *f;
+       u_long linenum = 0;
+       struct stat st;
+       Key *key;
+
+       /* Temporarily use the user's uid. */
+       temporarily_use_uid(pw);
+
+       /* The authorized keys. */
+       file = authorized_keys_file(pw);
+       debug("trying public RSA key file %s", file);
+
+       /* Fail quietly if file does not exist */
+       if (stat(file, &st) < 0) {
+               /* Restore the privileged uid. */
+               restore_uid();
+               xfree(file);
+               return (0);
+       }
+       /* Open the file containing the authorized keys. */
+       f = fopen(file, "r");
+       if (!f) {
+               /* Restore the privileged uid. */
+               restore_uid();
+               xfree(file);
+               return (0);
+       }
+       if (options.strict_modes &&
+           secure_filename(f, file, pw, line, sizeof(line)) != 0) {
+               xfree(file);
+               fclose(f);
+               logit("Authentication refused: %s", line);
+               restore_uid();
+               return (0);
+       }
+
+       /* Flag indicating whether the key is allowed. */
+       allowed = 0;
+
+       key = key_new(KEY_RSA1);
+
+       /*
+        * Go though the accepted keys, looking for the current key.  If
+        * found, perform a challenge-response dialog to verify that the
+        * user really has the corresponding private key.
+        */
+       while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
+               char *cp;
+               char *key_options;
+
+               /* Skip leading whitespace, empty and comment lines. */
+               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+                       ;
+               if (!*cp || *cp == '\n' || *cp == '#')
+                       continue;
+
+               /*
+                * Check if there are options for this key, and if so,
+                * save their starting address and skip the option part
+                * for now.  If there are no options, set the starting
+                * address to NULL.
+                */
+               if (*cp < '0' || *cp > '9') {
+                       int quoted = 0;
+                       key_options = cp;
+                       for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+                               if (*cp == '\\' && cp[1] == '"')
+                                       cp++;   /* Skip both */
+                               else if (*cp == '"')
+                                       quoted = !quoted;
+                       }
+               } else
+                       key_options = NULL;
+
+               /* Parse the key from the line. */
+               if (hostfile_read_key(&cp, &bits, key) == 0) {
+                       debug("%.100s, line %lu: non ssh1 key syntax",
+                           file, linenum);
+                       continue;
+               }
+               /* cp now points to the comment part. */
+
+               /* Check if the we have found the desired key (identified by its modulus). */
+               if (BN_cmp(key->rsa->n, client_n) != 0)
+                       continue;
+
+               /* check the real bits  */
+               if (bits != BN_num_bits(key->rsa->n))
+                       logit("Warning: %s, line %lu: keysize mismatch: "
+                           "actual %d vs. announced %d.",
+                           file, linenum, BN_num_bits(key->rsa->n), bits);
+
+               /* We have found the desired key. */
+               /*
+                * If our options do not allow this key to be used,
+                * do not send challenge.
+                */
+               if (!auth_parse_options(pw, key_options, file, linenum))
+                       continue;
+
+               /* break out, this key is allowed */
+               allowed = 1;
+               break;
+       }
+
+       /* Restore the privileged uid. */
+       restore_uid();
+
+       /* Close the file. */
+       xfree(file);
+       fclose(f);
+
+       /* return key if allowed */
+       if (allowed && rkey != NULL)
+               *rkey = key;
+       else
+               key_free(key);
+       return (allowed);
+}
+
+/*
+ * Performs the RSA authentication dialog with the client.  This returns
+ * 0 if the client could not be authenticated, and 1 if authentication was
+ * successful.  This may exit if there is a serious protocol violation.
+ */
+int
+auth_rsa(Authctxt *authctxt, BIGNUM *client_n)
+{
+       Key *key;
+       char *fp;
+       struct passwd *pw = authctxt->pw;
+
+       /* no user given */
+       if (!authctxt->valid)
+               return 0;
+
+       if (!PRIVSEP(auth_rsa_key_allowed(pw, client_n, &key))) {
+               auth_clear_options();
+               return (0);
+       }
+
+       /* Perform the challenge-response dialog for this key. */
+       if (!auth_rsa_challenge_dialog(key)) {
+               /* Wrong response. */
+               verbose("Wrong response to RSA authentication challenge.");
+               packet_send_debug("Wrong response to RSA authentication challenge.");
+               /*
+                * Break out of the loop. Otherwise we might send
+                * another challenge and break the protocol.
+                */
+               key_free(key);
+               return (0);
+       }
+       /*
+        * Correct response.  The client has been successfully
+        * authenticated. Note that we have not yet processed the
+        * options; this will be reset if the options cause the
+        * authentication to be rejected.
+        */
+       fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+       verbose("Found matching %s key: %s",
+           key_type(key), fp);
+       xfree(fp);
+       key_free(key);
+
+       packet_send_debug("RSA authentication accepted.");
+       return (1);
+}
diff --git a/crypto/openssh-4/auth.c b/crypto/openssh-4/auth.c
new file mode 100644 (file)
index 0000000..46b0131
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 2000 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: auth.c,v 1.58 2005/03/14 11:44:42 dtucker Exp $");
+
+#ifdef HAVE_LOGIN_H
+#include <login.h>
+#endif
+#ifdef USE_SHADOW
+#include <shadow.h>
+#endif
+
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+#include "xmalloc.h"
+#include "match.h"
+#include "groupaccess.h"
+#include "log.h"
+#include "servconf.h"
+#include "auth.h"
+#include "auth-options.h"
+#include "canohost.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "uidswap.h"
+#include "misc.h"
+#include "bufaux.h"
+#include "packet.h"
+#include "loginrec.h"
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+extern Buffer loginmsg;
+
+/* Debugging messages */
+Buffer auth_debug;
+int auth_debug_init;
+
+/*
+ * Check if the user is allowed to log in via ssh. If user is listed
+ * in DenyUsers or one of user's groups is listed in DenyGroups, false
+ * will be returned. If AllowUsers isn't empty and user isn't listed
+ * there, or if AllowGroups isn't empty and one of user's groups isn't
+ * listed there, false will be returned.
+ * If the user's shell is not executable, false will be returned.
+ * Otherwise true is returned.
+ */
+int
+allowed_user(struct passwd * pw)
+{
+       struct stat st;
+       const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
+       char *shell;
+       int i;
+#ifdef USE_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;
+
+#ifdef USE_SHADOW
+       if (!options.use_pam)
+               spw = getspnam(pw->pw_name);
+#ifdef HAS_SHADOW_EXPIRE
+       if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
+               return 0;
+#endif /* HAS_SHADOW_EXPIRE */
+#endif /* USE_SHADOW */
+
+       /* grab passwd field for locked account check */
+#ifdef USE_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.
+        */
+       shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
+
+       /* deny if shell does not exists or is not executable */
+       if (stat(shell, &st) != 0) {
+               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) {
+               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 ||
+           options.num_deny_groups > 0 || options.num_allow_groups > 0) {
+               hostname = get_canonical_hostname(options.use_dns);
+               ipaddr = get_remote_ipaddr();
+       }
+
+       /* Return false if user is listed in DenyUsers */
+       if (options.num_deny_users > 0) {
+               for (i = 0; i < options.num_deny_users; i++)
+                       if (match_user(pw->pw_name, hostname, ipaddr,
+                           options.deny_users[i])) {
+                               logit("User %.100s from %.100s not allowed "
+                                   "because listed in DenyUsers",
+                                   pw->pw_name, hostname);
+                               return 0;
+                       }
+       }
+       /* Return false if AllowUsers isn't empty and user isn't listed there */
+       if (options.num_allow_users > 0) {
+               for (i = 0; i < options.num_allow_users; i++)
+                       if (match_user(pw->pw_name, hostname, ipaddr,
+                           options.allow_users[i]))
+                               break;
+               /* i < options.num_allow_users iff we break for loop */
+               if (i >= options.num_allow_users) {
+                       logit("User %.100s from %.100s not allowed because "
+                           "not listed in AllowUsers", pw->pw_name, hostname);
+                       return 0;
+               }
+       }
+       if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
+               /* Get the user's group access list (primary and supplementary) */
+               if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
+                       logit("User %.100s from %.100s not allowed because "
+                           "not in any group", pw->pw_name, hostname);
+                       return 0;
+               }
+
+               /* Return false if one of user's groups is listed in DenyGroups */
+               if (options.num_deny_groups > 0)
+                       if (ga_match(options.deny_groups,
+                           options.num_deny_groups)) {
+                               ga_free();
+                               logit("User %.100s from %.100s not allowed "
+                                   "because a group is listed in DenyGroups",
+                                   pw->pw_name, hostname);
+                               return 0;
+                       }
+               /*
+                * Return false if AllowGroups isn't empty and one of user's groups
+                * isn't listed there
+                */
+               if (options.num_allow_groups > 0)
+                       if (!ga_match(options.allow_groups,
+                           options.num_allow_groups)) {
+                               ga_free();
+                               logit("User %.100s from %.100s not allowed "
+                                   "because none of user's groups are listed "
+                                   "in AllowGroups", pw->pw_name, hostname);
+                               return 0;
+                       }
+               ga_free();
+       }
+
+#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
+       if (!sys_auth_allowed_user(pw, &loginmsg))
+               return 0;
+#endif
+
+       /* We found no reason not to let this user try to log on... */
+       return 1;
+}
+
+void
+auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
+{
+       void (*authlog) (const char *fmt,...) = verbose;
+       char *authmsg;
+
+       /* Raise logging level */
+       if (authenticated == 1 ||
+           !authctxt->valid ||
+           authctxt->failures >= options.max_authtries / 2 ||
+           strcmp(method, "password") == 0)
+               authlog = logit;
+
+       if (authctxt->postponed)
+               authmsg = "Postponed";
+       else
+               authmsg = authenticated ? "Accepted" : "Failed";
+
+       authlog("%s %s for %s%.100s from %.200s port %d%s",
+           authmsg,
+           method,
+           authctxt->valid ? "" : "invalid user ",
+           authctxt->user,
+           get_remote_ipaddr(),
+           get_remote_port(),
+           info);
+
+#ifdef CUSTOM_FAILED_LOGIN
+       if (authenticated == 0 && !authctxt->postponed &&
+           (strcmp(method, "password") == 0 ||
+           strncmp(method, "keyboard-interactive", 20) == 0 ||
+           strcmp(method, "challenge-response") == 0))
+               record_failed_login(authctxt->user,
+                   get_canonical_hostname(options.use_dns), "ssh");
+#endif
+#ifdef SSH_AUDIT_EVENTS
+       if (authenticated == 0 && !authctxt->postponed) {
+               ssh_audit_event_t event;
+
+               debug3("audit failed auth attempt, method %s euid %d",
+                   method, (int)geteuid());
+               /*
+                * Because the auth loop is used in both monitor and slave,
+                * we must be careful to send each event only once and with
+                * enough privs to write the event.
+                */
+               event = audit_classify_auth(method);
+               switch(event) {
+               case SSH_AUTH_FAIL_NONE:
+               case SSH_AUTH_FAIL_PASSWD:
+               case SSH_AUTH_FAIL_KBDINT:
+                       if (geteuid() == 0)
+                               audit_event(event);
+                       break;
+               case SSH_AUTH_FAIL_PUBKEY:
+               case SSH_AUTH_FAIL_HOSTBASED:
+               case SSH_AUTH_FAIL_GSSAPI:
+                       /*
+                        * This is required to handle the case where privsep
+                        * is enabled but it's root logging in, since
+                        * use_privsep won't be cleared until after a
+                        * successful login.
+                        */
+                       if (geteuid() == 0)
+                               audit_event(event);
+                       else
+                               PRIVSEP(audit_event(event));
+                       break;
+               default:
+                       error("unknown authentication audit event %d", event);
+               }
+       }
+#endif
+}
+
+/*
+ * Check whether root logins are disallowed.
+ */
+int
+auth_root_allowed(char *method)
+{
+       switch (options.permit_root_login) {
+       case PERMIT_YES:
+               return 1;
+               break;
+       case PERMIT_NO_PASSWD:
+               if (strcmp(method, "password") != 0)
+                       return 1;
+               break;
+       case PERMIT_FORCED_ONLY:
+               if (forced_command) {
+                       logit("Root login accepted for forced command.");
+                       return 1;
+               }
+               break;
+       }
+       logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr());
+       return 0;
+}
+
+
+/*
+ * Given a template and a passwd structure, build a filename
+ * by substituting % tokenised options. Currently, %% becomes '%',
+ * %h becomes the home directory and %u the username.
+ *
+ * This returns a buffer allocated by xmalloc.
+ */
+char *
+expand_filename(const char *filename, struct passwd *pw)
+{
+       Buffer buffer;
+       char *file;
+       const char *cp;
+
+       /*
+        * Build the filename string in the buffer by making the appropriate
+        * substitutions to the given file name.
+        */
+       buffer_init(&buffer);
+       for (cp = filename; *cp; cp++) {
+               if (cp[0] == '%' && cp[1] == '%') {
+                       buffer_append(&buffer, "%", 1);
+                       cp++;
+                       continue;
+               }
+               if (cp[0] == '%' && cp[1] == 'h') {
+                       buffer_append(&buffer, pw->pw_dir, strlen(pw->pw_dir));
+                       cp++;
+                       continue;
+               }
+               if (cp[0] == '%' && cp[1] == 'u') {
+                       buffer_append(&buffer, pw->pw_name,
+                           strlen(pw->pw_name));
+                       cp++;
+                       continue;
+               }
+               buffer_append(&buffer, cp, 1);
+       }
+       buffer_append(&buffer, "\0", 1);
+
+       /*
+        * Ensure that filename starts anchored. If not, be backward
+        * compatible and prepend the '%h/'
+        */
+       file = xmalloc(MAXPATHLEN);
+       cp = buffer_ptr(&buffer);
+       if (*cp != '/')
+               snprintf(file, MAXPATHLEN, "%s/%s", pw->pw_dir, cp);
+       else
+               strlcpy(file, cp, MAXPATHLEN);
+
+       buffer_free(&buffer);
+       return file;
+}
+
+char *
+authorized_keys_file(struct passwd *pw)
+{
+       return expand_filename(options.authorized_keys_file, pw);
+}
+
+char *
+authorized_keys_file2(struct passwd *pw)
+{
+       return expand_filename(options.authorized_keys_file2, pw);
+}
+
+/* return ok if key exists in sysfile or userfile */
+HostStatus
+check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
+    const char *sysfile, const char *userfile)
+{
+       Key *found;
+       char *user_hostfile;
+       struct stat st;
+       HostStatus host_status;
+
+       /* Check if we know the host and its host key. */
+       found = key_new(key->type);
+       host_status = check_host_in_hostfile(sysfile, host, key, found, NULL);
+
+       if (host_status != HOST_OK && userfile != NULL) {
+               user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
+               if (options.strict_modes &&
+                   (stat(user_hostfile, &st) == 0) &&
+                   ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
+                   (st.st_mode & 022) != 0)) {
+                       logit("Authentication refused for %.100s: "
+                           "bad owner or modes for %.200s",
+                           pw->pw_name, user_hostfile);
+               } else {
+                       temporarily_use_uid(pw);
+                       host_status = check_host_in_hostfile(user_hostfile,
+                           host, key, found, NULL);
+                       restore_uid();
+               }
+               xfree(user_hostfile);
+       }
+       key_free(found);
+
+       debug2("check_key_in_hostfiles: key %s for %s", host_status == HOST_OK ?
+           "ok" : "not found", host);
+       return host_status;
+}
+
+
+/*
+ * Check a given file for security. This is defined as all components
+ * of the path to the file must be owned by either the owner of
+ * of the file or root and no directories must be group or world writable.
+ *
+ * XXX Should any specific check be done for sym links ?
+ *
+ * Takes an open file descriptor, the file name, a uid and and
+ * error buffer plus max size as arguments.
+ *
+ * Returns 0 on success and -1 on failure
+ */
+int
+secure_filename(FILE *f, const char *file, struct passwd *pw,
+    char *err, size_t errlen)
+{
+       uid_t uid = pw->pw_uid;
+       char buf[MAXPATHLEN], homedir[MAXPATHLEN];
+       char *cp;
+       int comparehome = 0;
+       struct stat st;
+
+       if (realpath(file, buf) == NULL) {
+               snprintf(err, errlen, "realpath %s failed: %s", file,
+                   strerror(errno));
+               return -1;
+       }
+       if (realpath(pw->pw_dir, homedir) != NULL)
+               comparehome = 1;
+
+       /* check the open file to avoid races */
+       if (fstat(fileno(f), &st) < 0 ||
+           (st.st_uid != 0 && st.st_uid != uid) ||
+           (st.st_mode & 022) != 0) {
+               snprintf(err, errlen, "bad ownership or modes for file %s",
+                   buf);
+               return -1;
+       }
+
+       /* for each component of the canonical path, walking upwards */
+       for (;;) {
+               if ((cp = dirname(buf)) == NULL) {
+                       snprintf(err, errlen, "dirname() failed");
+                       return -1;
+               }
+               strlcpy(buf, cp, sizeof(buf));
+
+               debug3("secure_filename: checking '%s'", buf);
+               if (stat(buf, &st) < 0 ||
+                   (st.st_uid != 0 && st.st_uid != uid) ||
+                   (st.st_mode & 022) != 0) {
+                       snprintf(err, errlen,
+                           "bad ownership or modes for directory %s", buf);
+                       return -1;
+               }
+
+               /* If are passed the homedir then we can stop */
+               if (comparehome && strcmp(homedir, buf) == 0) {
+                       debug3("secure_filename: terminating check at '%s'",
+                           buf);
+                       break;
+               }
+               /*
+                * dirname should always complete with a "/" path,
+                * but we can be paranoid and check for "." too
+                */
+               if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
+                       break;
+       }
+       return 0;
+}
+
+struct passwd *
+getpwnamallow(const char *user)
+{
+#ifdef HAVE_LOGIN_CAP
+       extern login_cap_t *lc;
+#ifdef BSD_AUTH
+       auth_session_t *as;
+#endif
+#endif
+       struct passwd *pw;
+
+       pw = getpwnam(user);
+       if (pw == NULL) {
+               logit("Invalid user %.100s from %.100s",
+                   user, get_remote_ipaddr());
+#ifdef CUSTOM_FAILED_LOGIN
+               record_failed_login(user,
+                   get_canonical_hostname(options.use_dns), "ssh");
+#endif
+#ifdef SSH_AUDIT_EVENTS
+               audit_event(SSH_INVALID_USER);
+#endif /* SSH_AUDIT_EVENTS */
+               return (NULL);
+       }
+       if (!allowed_user(pw))
+               return (NULL);
+#ifdef HAVE_LOGIN_CAP
+       if ((lc = login_getclass(pw->pw_class)) == NULL) {
+               debug("unable to get login class: %s", user);
+               return (NULL);
+       }
+#ifdef BSD_AUTH
+       if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 ||
+           auth_approval(as, lc, pw->pw_name, "ssh") <= 0) {
+               debug("Approval failure for %s", user);
+               pw = NULL;
+       }
+       if (as != NULL)
+               auth_close(as);
+#endif
+#endif
+       if (pw != NULL)
+               return (pwcopy(pw));
+       return (NULL);
+}
+
+void
+auth_debug_add(const char *fmt,...)
+{
+       char buf[1024];
+       va_list args;
+
+       if (!auth_debug_init)
+               return;
+
+       va_start(args, fmt);
+       vsnprintf(buf, sizeof(buf), fmt, args);
+       va_end(args);
+       buffer_put_cstring(&auth_debug, buf);
+}
+
+void
+auth_debug_send(void)
+{
+       char *msg;
+
+       if (!auth_debug_init)
+               return;
+       while (buffer_len(&auth_debug)) {
+               msg = buffer_get_string(&auth_debug, NULL);
+               packet_send_debug("%s", msg);
+               xfree(msg);
+       }
+}
+
+void
+auth_debug_reset(void)
+{
+       if (auth_debug_init)
+               buffer_clear(&auth_debug);
+       else {
+               buffer_init(&auth_debug);
+               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 = (uid_t)-1;
+       fake.pw_gid = (gid_t)-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-4/auth.h b/crypto/openssh-4/auth.h
new file mode 100644 (file)
index 0000000..471404e
--- /dev/null
@@ -0,0 +1,195 @@
+/*     $OpenBSD: auth.h,v 1.50 2004/05/23 23:59:53 dtucker Exp $       */
+
+/*
+ * Copyright (c) 2000 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.
+ *
+ */
+
+#ifndef AUTH_H
+#define AUTH_H
+
+#include "key.h"
+#include "hostfile.h"
+#include "buffer.h"
+#include <openssl/rsa.h>
+
+#ifdef HAVE_LOGIN_CAP
+#include <login_cap.h>
+#endif
+#ifdef BSD_AUTH
+#include <bsd_auth.h>
+#endif
+#ifdef KRB5
+#include <krb5.h>
+#endif
+
+typedef struct Authctxt Authctxt;
+typedef struct Authmethod Authmethod;
+typedef struct KbdintDevice KbdintDevice;
+
+struct Authctxt {
+       int              success;
+       int              postponed;     /* authentication needs another step */
+       int              valid;         /* user exists and is allowed to login */
+       int              attempt;
+       int              failures;
+       int              force_pwchange;
+       char            *user;          /* username sent by the client */
+       char            *service;
+       struct passwd   *pw;            /* set if 'valid' */
+       char            *style;
+       void            *kbdintctxt;
+#ifdef BSD_AUTH
+       auth_session_t  *as;
+#endif
+#ifdef KRB5
+       krb5_context     krb5_ctx;
+       krb5_ccache      krb5_fwd_ccache;
+       krb5_principal   krb5_user;
+       char            *krb5_ticket_file;
+       char            *krb5_ccname;
+#endif
+       Buffer          *loginmsg;
+       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;
+       int     (*userauth)(Authctxt *authctxt);
+       int     *enabled;
+};
+
+/*
+ * Keyboard interactive device:
+ * init_ctx    returns: non NULL upon success
+ * query       returns: 0 - success, otherwise failure
+ * respond     returns: 0 - success, 1 - need further interaction,
+ *             otherwise - failure
+ */
+struct KbdintDevice
+{
+       const char *name;
+       void*   (*init_ctx)(Authctxt*);
+       int     (*query)(void *ctx, char **name, char **infotxt,
+                   u_int *numprompts, char ***prompts, u_int **echo_on);
+       int     (*respond)(void *ctx, u_int numresp, char **responses);
+       void    (*free_ctx)(void *ctx);
+};
+
+int      auth_rhosts(struct passwd *, const char *);
+int
+auth_rhosts2(struct passwd *, const char *, const char *, const char *);
+
+int     auth_rhosts_rsa(Authctxt *, char *, Key *);
+int      auth_password(Authctxt *, const char *);
+int      auth_rsa(Authctxt *, BIGNUM *);
+int      auth_rsa_challenge_dialog(Key *);
+BIGNUM *auth_rsa_generate_challenge(Key *);
+int     auth_rsa_verify_response(Key *, BIGNUM *, u_char[]);
+int     auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
+
+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 KRB5
+int    auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
+int    auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
+int    auth_krb5_password(Authctxt *authctxt, const char *password);
+void   krb5_cleanup_proc(Authctxt *authctxt);
+#endif /* KRB5 */
+
+#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
+#include <shadow.h>
+int auth_shadow_acctexpired(struct spwd *);
+int auth_shadow_pwexpired(Authctxt *);
+#endif
+
+#include "auth-pam.h"
+#include "audit.h"
+void remove_kbdint_device(const char *);
+
+void disable_forwarding(void);
+
+void   do_authentication(Authctxt *);
+void   do_authentication2(Authctxt *);
+
+void   auth_log(Authctxt *, int, char *, char *);
+void   userauth_finish(Authctxt *, int, char *);
+void   userauth_send_banner(const char *);
+int    auth_root_allowed(char *);
+
+char   *auth2_read_banner(void);
+
+void   privsep_challenge_enable(void);
+
+int    auth2_challenge(Authctxt *, char *);
+void   auth2_challenge_stop(Authctxt *);
+int    bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
+int    bsdauth_respond(void *, u_int, char **);
+int    skey_query(void *, char **, char **, u_int *, char ***, u_int **);
+int    skey_respond(void *, u_int, char **);
+
+int    allowed_user(struct passwd *);
+struct passwd * getpwnamallow(const char *user);
+
+char   *get_challenge(Authctxt *);
+int    verify_response(Authctxt *, const char *);
+void   abandon_challenge_response(Authctxt *);
+
+char   *expand_filename(const char *, struct passwd *);
+char   *authorized_keys_file(struct passwd *);
+char   *authorized_keys_file2(struct passwd *);
+
+int
+secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
+
+HostStatus
+check_key_in_hostfiles(struct passwd *, Key *, const char *,
+    const char *, const char *);
+
+/* hostkey handling */
+Key    *get_hostkey_by_index(int);
+Key    *get_hostkey_by_type(int);
+int     get_hostkey_index(Key *);
+int     ssh1_session_key(BIGNUM *);
+
+/* debug messages during authentication */
+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);
+
+int     sys_auth_passwd(Authctxt *, const char *);
+
+#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
+
+#define SKEY_PROMPT "\nS/Key Password: "
+#endif
diff --git a/crypto/openssh-4/auth1.c b/crypto/openssh-4/auth1.c
new file mode 100644 (file)
index 0000000..d089284
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth1.c,v 1.59 2004/07/28 09:40:29 markus Exp $");
+
+#include "xmalloc.h"
+#include "rsa.h"
+#include "ssh1.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "auth.h"
+#include "channels.h"
+#include "session.h"
+#include "uidswap.h"
+#include "monitor_wrap.h"
+#include "buffer.h"
+
+/* import */
+extern ServerOptions options;
+extern Buffer loginmsg;
+
+/*
+ * convert ssh auth msg type into description
+ */
+static char *
+get_authname(int type)
+{
+       static char buf[1024];
+       switch (type) {
+       case SSH_CMSG_AUTH_PASSWORD:
+               return "password";
+       case SSH_CMSG_AUTH_RSA:
+               return "rsa";
+       case SSH_CMSG_AUTH_RHOSTS_RSA:
+               return "rhosts-rsa";
+       case SSH_CMSG_AUTH_RHOSTS:
+               return "rhosts";
+       case SSH_CMSG_AUTH_TIS:
+       case SSH_CMSG_AUTH_TIS_RESPONSE:
+               return "challenge-response";
+       }
+       snprintf(buf, sizeof buf, "bad-auth-msg-%d", type);
+       return buf;
+}
+
+/*
+ * read packets, try to authenticate the user and
+ * return only if authentication is successful
+ */
+static void
+do_authloop(Authctxt *authctxt)
+{
+       int authenticated = 0;
+       u_int bits;
+       Key *client_host_key;
+       BIGNUM *n;
+       char *client_user, *password;
+       char info[1024];
+       u_int dlen;
+       u_int ulen;
+       int prev, type = 0;
+
+       debug("Attempting authentication for %s%.100s.",
+           authctxt->valid ? "" : "invalid user ", authctxt->user);
+
+       /* If the user has no password, accept authentication immediately. */
+       if (options.password_authentication &&
+#ifdef KRB5
+           (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
+#endif
+           PRIVSEP(auth_password(authctxt, ""))) {
+#ifdef USE_PAM
+               if (options.use_pam && (PRIVSEP(do_pam_account())))
+#endif
+               {
+                       auth_log(authctxt, 1, "without authentication", "");
+                       return;
+               }
+       }
+
+       /* Indicate that authentication is needed. */
+       packet_start(SSH_SMSG_FAILURE);
+       packet_send();
+       packet_write_wait();
+
+       client_user = NULL;
+
+       for (;;) {
+               /* default to fail */
+               authenticated = 0;
+
+               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) {
+               case SSH_CMSG_AUTH_RHOSTS_RSA:
+                       if (!options.rhosts_rsa_authentication) {
+                               verbose("Rhosts with RSA authentication disabled.");
+                               break;
+                       }
+                       /*
+                        * Get client user name.  Note that we just have to
+                        * trust the client; root on the client machine can
+                        * claim to be any user.
+                        */
+                       client_user = packet_get_string(&ulen);
+
+                       /* Get the client host key. */
+                       client_host_key = key_new(KEY_RSA1);
+                       bits = packet_get_int();
+                       packet_get_bignum(client_host_key->rsa->e);
+                       packet_get_bignum(client_host_key->rsa->n);
+
+                       if (bits != BN_num_bits(client_host_key->rsa->n))
+                               verbose("Warning: keysize mismatch for client_host_key: "
+                                   "actual %d, announced %d",
+                                   BN_num_bits(client_host_key->rsa->n), bits);
+                       packet_check_eom();
+
+                       authenticated = auth_rhosts_rsa(authctxt, client_user,
+                           client_host_key);
+                       key_free(client_host_key);
+
+                       snprintf(info, sizeof info, " ruser %.100s", client_user);
+                       break;
+
+               case SSH_CMSG_AUTH_RSA:
+                       if (!options.rsa_authentication) {
+                               verbose("RSA authentication disabled.");
+                               break;
+                       }
+                       /* RSA authentication requested. */
+                       if ((n = BN_new()) == NULL)
+                               fatal("do_authloop: BN_new failed");
+                       packet_get_bignum(n);
+                       packet_check_eom();
+                       authenticated = auth_rsa(authctxt, n);
+                       BN_clear_free(n);
+                       break;
+
+               case SSH_CMSG_AUTH_PASSWORD:
+                       if (!options.password_authentication) {
+                               verbose("Password authentication disabled.");
+                               break;
+                       }
+                       /*
+                        * Read user password.  It is in plain text, but was
+                        * transmitted over the encrypted channel so it is
+                        * not visible to an outside observer.
+                        */
+                       password = packet_get_string(&dlen);
+                       packet_check_eom();
+
+                       /* Try authentication with the password. */
+                       authenticated = PRIVSEP(auth_password(authctxt, password));
+
+                       memset(password, 0, strlen(password));
+                       xfree(password);
+                       break;
+
+               case SSH_CMSG_AUTH_TIS:
+                       debug("rcvd SSH_CMSG_AUTH_TIS");
+                       if (options.challenge_response_authentication == 1) {
+                               char *challenge = get_challenge(authctxt);
+                               if (challenge != NULL) {
+                                       debug("sending challenge '%s'", challenge);
+                                       packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
+                                       packet_put_cstring(challenge);
+                                       xfree(challenge);
+                                       packet_send();
+                                       packet_write_wait();
+                                       continue;
+                               }
+                       }
+                       break;
+               case SSH_CMSG_AUTH_TIS_RESPONSE:
+                       debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
+                       if (options.challenge_response_authentication == 1) {
+                               char *response = packet_get_string(&dlen);
+                               packet_check_eom();
+                               authenticated = verify_response(authctxt, response);
+                               memset(response, 'r', dlen);
+                               xfree(response);
+                       }
+                       break;
+
+               default:
+                       /*
+                        * Any unknown messages will be ignored (and failure
+                        * returned) during authentication.
+                        */
+                       logit("Unknown message during authentication: type %d", type);
+                       break;
+               }
+#ifdef BSD_AUTH
+               if (authctxt->as) {
+                       auth_close(authctxt->as);
+                       authctxt->as = NULL;
+               }
+#endif
+               if (!authctxt->valid && authenticated)
+                       fatal("INTERNAL ERROR: authenticated invalid user %s",
+                           authctxt->user);
+
+#ifdef _UNICOS
+               if (authenticated && cray_access_denied(authctxt->user)) {
+                       authenticated = 0;
+                       fatal("Access denied for user %s.",authctxt->user);
+               }
+#endif /* _UNICOS */
+
+#ifdef HAVE_CYGWIN
+               if (authenticated &&
+                   !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, 
+                   authctxt->pw)) {
+                       packet_disconnect("Authentication rejected for uid %d.",
+                           authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid);
+                       authenticated = 0;
+               }
+#else
+               /* Special handling for root */
+               if (authenticated && authctxt->pw->pw_uid == 0 &&
+                   !auth_root_allowed(get_authname(type))) {
+                       authenticated = 0;
+# ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+# endif
+               }
+#endif
+
+#ifdef USE_PAM
+               if (options.use_pam && authenticated &&
+                   !PRIVSEP(do_pam_account())) {
+                       char *msg;
+                       size_t len;
+
+                       error("Access denied for user %s by PAM account "
+                          "configuration", authctxt->user);
+                       len = buffer_len(&loginmsg);
+                       buffer_append(&loginmsg, "\0", 1);
+                       msg = buffer_ptr(&loginmsg);
+                       /* strip trailing newlines */
+                       if (len > 0)
+                               while (len > 0 && msg[--len] == '\n')
+                                       msg[len] = '\0';
+                       else
+                               msg = "Access denied.";
+                       packet_disconnect(msg);
+               }
+#endif
+
+               /* Log before sending the reply */
+               auth_log(authctxt, authenticated, get_authname(type), info);
+
+               if (client_user != NULL) {
+                       xfree(client_user);
+                       client_user = NULL;
+               }
+
+               if (authenticated)
+                       return;
+
+               if (authctxt->failures++ > options.max_authtries) {
+#ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+#endif
+                       packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+               }
+
+               packet_start(SSH_SMSG_FAILURE);
+               packet_send();
+               packet_write_wait();
+       }
+}
+
+/*
+ * Performs authentication of an incoming connection.  Session key has already
+ * been exchanged and encryption is enabled.
+ */
+void
+do_authentication(Authctxt *authctxt)
+{
+       u_int ulen;
+       char *user, *style = NULL;
+
+       /* Get the name of the user that we wish to log in as. */
+       packet_read_expect(SSH_CMSG_USER);
+
+       /* Get the user name. */
+       user = packet_get_string(&ulen);
+       packet_check_eom();
+
+       if ((style = strchr(user, ':')) != NULL)
+               *style++ = '\0';
+
+       authctxt->user = user;
+       authctxt->style = style;
+
+       /* Verify that the user is a valid user. */
+       if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
+               authctxt->valid = 1;
+       else {
+               debug("do_authentication: invalid user %s", user);
+               authctxt->pw = fakepw();
+       }
+
+       setproctitle("%s%s", authctxt->valid ? user : "unknown",
+           use_privsep ? " [net]" : "");
+
+#ifdef USE_PAM
+       if (options.use_pam)
+               PRIVSEP(start_pam(authctxt));
+#endif
+
+       /*
+        * If we are not running as root, the user must have the same uid as
+        * the server. (Unless you are running Windows)
+        */
+#ifndef HAVE_CYGWIN
+       if (!use_privsep && getuid() != 0 && authctxt->pw &&
+           authctxt->pw->pw_uid != getuid())
+               packet_disconnect("Cannot change user when server not running as root.");
+#endif
+
+       /*
+        * Loop until the user has been authenticated or the connection is
+        * closed, do_authloop() returns only if authentication is successful
+        */
+       do_authloop(authctxt);
+
+       /* The user has been authenticated and accepted. */
+       packet_start(SSH_SMSG_SUCCESS);
+       packet_send();
+       packet_write_wait();
+}
diff --git a/crypto/openssh-4/auth2-chall.c b/crypto/openssh-4/auth2-chall.c
new file mode 100644 (file)
index 0000000..384a543
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2001 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2001 Per Allansson.  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: auth2-chall.c,v 1.22 2005/01/19 13:11:47 dtucker Exp $");
+
+#include "ssh2.h"
+#include "auth.h"
+#include "buffer.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "dispatch.h"
+#include "log.h"
+#include "servconf.h"
+
+/* import */
+extern ServerOptions options;
+
+static int auth2_challenge_start(Authctxt *);
+static int send_userauth_info_request(Authctxt *);
+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
+#endif
+
+KbdintDevice *devices[] = {
+#ifdef BSD_AUTH
+       &bsdauth_device,
+#else
+#ifdef USE_PAM
+       &sshpam_device,
+#endif
+#ifdef SKEY
+       &skey_device,
+#endif
+#endif
+       NULL
+};
+
+typedef struct KbdintAuthctxt KbdintAuthctxt;
+struct KbdintAuthctxt
+{
+       char *devices;
+       void *ctxt;
+       KbdintDevice *device;
+       u_int nreq;
+};
+
+#ifdef USE_PAM
+void
+remove_kbdint_device(const char *devname)
+{
+       int i, j;
+
+       for (i = 0; devices[i] != NULL; i++)
+               if (strcmp(devices[i]->name, devname) == 0) {
+                       for (j = i; devices[j] != NULL; j++)
+                               devices[j] = devices[j+1];
+                       i--;
+               }
+}
+#endif
+
+static KbdintAuthctxt *
+kbdint_alloc(const char *devs)
+{
+       KbdintAuthctxt *kbdintctxt;
+       Buffer b;
+       int i;
+
+#ifdef USE_PAM
+       if (!options.use_pam)
+               remove_kbdint_device("pam");
+#endif
+
+       kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
+       if (strcmp(devs, "") == 0) {
+               buffer_init(&b);
+               for (i = 0; devices[i]; i++) {
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, devices[i]->name,
+                           strlen(devices[i]->name));
+               }
+               buffer_append(&b, "\0", 1);
+               kbdintctxt->devices = xstrdup(buffer_ptr(&b));
+               buffer_free(&b);
+       } else {
+               kbdintctxt->devices = xstrdup(devs);
+       }
+       debug("kbdint_alloc: devices '%s'", kbdintctxt->devices);
+       kbdintctxt->ctxt = NULL;
+       kbdintctxt->device = NULL;
+       kbdintctxt->nreq = 0;
+
+       return kbdintctxt;
+}
+static void
+kbdint_reset_device(KbdintAuthctxt *kbdintctxt)
+{
+       if (kbdintctxt->ctxt) {
+               kbdintctxt->device->free_ctx(kbdintctxt->ctxt);
+               kbdintctxt->ctxt = NULL;
+       }
+       kbdintctxt->device = NULL;
+}
+static void
+kbdint_free(KbdintAuthctxt *kbdintctxt)
+{
+       if (kbdintctxt->device)
+               kbdint_reset_device(kbdintctxt);
+       if (kbdintctxt->devices) {
+               xfree(kbdintctxt->devices);
+               kbdintctxt->devices = NULL;
+       }
+       xfree(kbdintctxt);
+}
+/* get next device */
+static int
+kbdint_next_device(KbdintAuthctxt *kbdintctxt)
+{
+       size_t len;
+       char *t;
+       int i;
+
+       if (kbdintctxt->device)
+               kbdint_reset_device(kbdintctxt);
+       do {
+               len = kbdintctxt->devices ?
+                   strcspn(kbdintctxt->devices, ",") : 0;
+
+               if (len == 0)
+                       break;
+               for (i = 0; devices[i]; i++)
+                       if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0)
+                               kbdintctxt->device = devices[i];
+               t = kbdintctxt->devices;
+               kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
+               xfree(t);
+               debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
+                  kbdintctxt->devices : "<empty>");
+       } while (kbdintctxt->devices && !kbdintctxt->device);
+
+       return kbdintctxt->device ? 1 : 0;
+}
+
+/*
+ * try challenge-response, set authctxt->postponed if we have to
+ * wait for the response.
+ */
+int
+auth2_challenge(Authctxt *authctxt, char *devs)
+{
+       debug("auth2_challenge: user=%s devs=%s",
+           authctxt->user ? authctxt->user : "<nouser>",
+           devs ? devs : "<no devs>");
+
+       if (authctxt->user == NULL || !devs)
+               return 0;
+       if (authctxt->kbdintctxt == NULL)
+               authctxt->kbdintctxt = kbdint_alloc(devs);
+       return auth2_challenge_start(authctxt);
+}
+
+/* unregister kbd-int callbacks and context */
+void
+auth2_challenge_stop(Authctxt *authctxt)
+{
+       /* unregister callback */
+       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+       if (authctxt->kbdintctxt != NULL)  {
+               kbdint_free(authctxt->kbdintctxt);
+               authctxt->kbdintctxt = NULL;
+       }
+}
+
+/* side effect: sets authctxt->postponed if a reply was sent*/
+static int
+auth2_challenge_start(Authctxt *authctxt)
+{
+       KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
+
+       debug2("auth2_challenge_start: devices %s",
+           kbdintctxt->devices ?  kbdintctxt->devices : "<empty>");
+
+       if (kbdint_next_device(kbdintctxt) == 0) {
+               auth2_challenge_stop(authctxt);
+               return 0;
+       }
+       debug("auth2_challenge_start: trying authentication method '%s'",
+           kbdintctxt->device->name);
+
+       if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
+               auth2_challenge_stop(authctxt);
+               return 0;
+       }
+       if (send_userauth_info_request(authctxt) == 0) {
+               auth2_challenge_stop(authctxt);
+               return 0;
+       }
+       dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
+           &input_userauth_info_response);
+
+       authctxt->postponed = 1;
+       return 0;
+}
+
+static int
+send_userauth_info_request(Authctxt *authctxt)
+{
+       KbdintAuthctxt *kbdintctxt;
+       char *name, *instr, **prompts;
+       int i;
+       u_int *echo_on;
+
+       kbdintctxt = authctxt->kbdintctxt;
+       if (kbdintctxt->device->query(kbdintctxt->ctxt,
+           &name, &instr, &kbdintctxt->nreq, &prompts, &echo_on))
+               return 0;
+
+       packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
+       packet_put_cstring(name);
+       packet_put_cstring(instr);
+       packet_put_cstring("");         /* language not used */
+       packet_put_int(kbdintctxt->nreq);
+       for (i = 0; i < kbdintctxt->nreq; i++) {
+               packet_put_cstring(prompts[i]);
+               packet_put_char(echo_on[i]);
+       }
+       packet_send();
+       packet_write_wait();
+
+       for (i = 0; i < kbdintctxt->nreq; i++)
+               xfree(prompts[i]);
+       xfree(prompts);
+       xfree(echo_on);
+       xfree(name);
+       xfree(instr);
+       return 1;
+}
+
+static void
+input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       KbdintAuthctxt *kbdintctxt;
+       int i, authenticated = 0, res, len;
+       u_int nresp;
+       char **response = NULL, *method;
+
+       if (authctxt == NULL)
+               fatal("input_userauth_info_response: no authctxt");
+       kbdintctxt = authctxt->kbdintctxt;
+       if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
+               fatal("input_userauth_info_response: no kbdintctxt");
+       if (kbdintctxt->device == NULL)
+               fatal("input_userauth_info_response: no device");
+
+       authctxt->postponed = 0;        /* reset */
+       nresp = packet_get_int();
+       if (nresp != kbdintctxt->nreq)
+               fatal("input_userauth_info_response: wrong number of replies");
+       if (nresp > 100)
+               fatal("input_userauth_info_response: too many replies");
+       if (nresp > 0) {
+               response = xmalloc(nresp * sizeof(char *));
+               for (i = 0; i < nresp; i++)
+                       response[i] = packet_get_string(NULL);
+       }
+       packet_check_eom();
+
+       res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
+
+       for (i = 0; i < nresp; i++) {
+               memset(response[i], 'r', strlen(response[i]));
+               xfree(response[i]);
+       }
+       if (response)
+               xfree(response);
+
+       switch (res) {
+       case 0:
+               /* Success! */
+               authenticated = authctxt->valid ? 1 : 0;
+               break;
+       case 1:
+               /* Authentication needs further interaction */
+               if (send_userauth_info_request(authctxt) == 1)
+                       authctxt->postponed = 1;
+               break;
+       default:
+               /* Failure! */
+               break;
+       }
+
+       len = strlen("keyboard-interactive") + 2 +
+               strlen(kbdintctxt->device->name);
+       method = xmalloc(len);
+       snprintf(method, len, "keyboard-interactive/%s",
+           kbdintctxt->device->name);
+
+       if (!authctxt->postponed) {
+               if (authenticated) {
+                       auth2_challenge_stop(authctxt);
+               } else {
+                       /* start next device */
+                       /* may set authctxt->postponed */
+                       auth2_challenge_start(authctxt);
+               }
+       }
+       userauth_finish(authctxt, authenticated, method);
+       xfree(method);
+}
+
+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
+
+#ifdef BSD_AUTH
+       devices[n++] = &mm_bsdauth_device;
+#else
+#ifdef USE_PAM
+       devices[n++] = &mm_sshpam_device;
+#endif
+#ifdef SKEY
+       devices[n++] = &mm_skey_device;
+#endif
+#endif
+}
diff --git a/crypto/openssh-4/auth2-gss.c b/crypto/openssh-4/auth2-gss.c
new file mode 100644 (file)
index 0000000..3289ba1
--- /dev/null
@@ -0,0 +1,295 @@
+/*     $OpenBSD: auth2-gss.c,v 1.8 2004/06/21 17:36:31 avsm 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_mic(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 goid = {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);
+
+               present = 0;
+               doid = packet_get_string(&len);
+
+               if (len > 2 &&
+                  doid[0] == SSH_GSS_OIDTYPE &&
+                  doid[1] == len - 2) {
+                       goid.elements = doid + 2;
+                       goid.length   = len - 2;
+                       gss_test_oid_set_member(&ms, &goid, supported,
+                           &present);
+               } else {
+                       logit("Badly formed OID received");
+               }
+       } 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, &goid)))) {
+               xfree(doid);
+               return (0);
+       }
+
+       authctxt->methoddata=(void *)ctxt;
+
+       packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
+
+       /* Return the OID that we received */
+       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, flags;
+       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, &flags));
+
+       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-with-mic");
+       } 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);
+                       if (flags & GSS_C_INTEG_FLAG)
+                               dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC,
+                                   &input_gssapi_mic);
+                       else
+                               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 we're only enabled in
+        * the dispatcher once the exchange is 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_MIC, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+}
+
+static void
+input_gssapi_mic(int type, u_int32_t plen, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       Gssctxt *gssctxt;
+       int authenticated = 0;
+       Buffer b;
+       gss_buffer_desc mic, gssbuf;
+       u_int len;
+
+       if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
+               fatal("No authentication or GSSAPI context");
+
+       gssctxt = authctxt->methoddata;
+
+       mic.value = packet_get_string(&len);
+       mic.length = len;
+
+       ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
+           "gssapi-with-mic");
+
+       gssbuf.value = buffer_ptr(&b);
+       gssbuf.length = buffer_len(&b);
+
+       if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
+               authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
+       else
+               logit("GSSAPI MIC check failed");
+
+       buffer_free(&b);
+       xfree(mic.value);
+
+       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_MIC, NULL);
+       dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+       userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+}
+
+Authmethod method_gssapi = {
+       "gssapi-with-mic",
+       userauth_gssapi,
+       &options.gss_authentication
+};
+
+#endif /* GSSAPI */
diff --git a/crypto/openssh-4/auth2-hostbased.c b/crypto/openssh-4/auth2-hostbased.c
new file mode 100644 (file)
index 0000000..1111ed6
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2000 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: auth2-hostbased.c,v 1.6 2004/01/19 21:25:15 markus Exp $");
+
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "bufaux.h"
+#include "auth.h"
+#include "key.h"
+#include "canohost.h"
+#include "monitor_wrap.h"
+#include "pathnames.h"
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern u_int session_id2_len;
+
+static int
+userauth_hostbased(Authctxt *authctxt)
+{
+       Buffer b;
+       Key *key = NULL;
+       char *pkalg, *cuser, *chost, *service;
+       u_char *pkblob, *sig;
+       u_int alen, blen, slen;
+       int pktype;
+       int authenticated = 0;
+
+       if (!authctxt->valid) {
+               debug2("userauth_hostbased: disabled because of invalid user");
+               return 0;
+       }
+       pkalg = packet_get_string(&alen);
+       pkblob = packet_get_string(&blen);
+       chost = packet_get_string(NULL);
+       cuser = packet_get_string(NULL);
+       sig = packet_get_string(&slen);
+
+       debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
+           cuser, chost, pkalg, slen);
+#ifdef DEBUG_PK
+       debug("signature:");
+       buffer_init(&b);
+       buffer_append(&b, sig, slen);
+       buffer_dump(&b);
+       buffer_free(&b);
+#endif
+       pktype = key_type_from_name(pkalg);
+       if (pktype == KEY_UNSPEC) {
+               /* this is perfectly legal */
+               logit("userauth_hostbased: unsupported "
+                   "public key algorithm: %s", pkalg);
+               goto done;
+       }
+       key = key_from_blob(pkblob, blen);
+       if (key == NULL) {
+               error("userauth_hostbased: cannot decode key: %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("userauth_hostbased: type mismatch for decoded key "
+                   "(received %d, expected %d)", key->type, pktype);
+               goto done;
+       }
+       service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
+           authctxt->service;
+       buffer_init(&b);
+       buffer_put_string(&b, session_id2, session_id2_len);
+       /* reconstruct packet */
+       buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+       buffer_put_cstring(&b, authctxt->user);
+       buffer_put_cstring(&b, service);
+       buffer_put_cstring(&b, "hostbased");
+       buffer_put_string(&b, pkalg, alen);
+       buffer_put_string(&b, pkblob, blen);
+       buffer_put_cstring(&b, chost);
+       buffer_put_cstring(&b, cuser);
+#ifdef DEBUG_PK
+       buffer_dump(&b);
+#endif
+       /* test for allowed key and correct signature */
+       authenticated = 0;
+       if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
+           PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+                       buffer_len(&b))) == 1)
+               authenticated = 1;
+
+       buffer_free(&b);
+done:
+       debug2("userauth_hostbased: authenticated %d", authenticated);
+       if (key != NULL)
+               key_free(key);
+       xfree(pkalg);
+       xfree(pkblob);
+       xfree(cuser);
+       xfree(chost);
+       xfree(sig);
+       return authenticated;
+}
+
+/* return 1 if given hostkey is allowed */
+int
+hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
+    Key *key)
+{
+       const char *resolvedname, *ipaddr, *lookup;
+       HostStatus host_status;
+       int len;
+
+       resolvedname = get_canonical_hostname(options.use_dns);
+       ipaddr = get_remote_ipaddr();
+
+       debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
+           chost, resolvedname, ipaddr);
+
+       if (options.hostbased_uses_name_from_packet_only) {
+               if (auth_rhosts2(pw, cuser, chost, chost) == 0)
+                       return 0;
+               lookup = chost;
+       } else {
+               if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
+                       debug2("stripping trailing dot from chost %s", chost);
+                       chost[len - 1] = '\0';
+               }
+               if (strcasecmp(resolvedname, chost) != 0)
+                       logit("userauth_hostbased mismatch: "
+                           "client sends %s, but we resolve %s to %s",
+                           chost, ipaddr, resolvedname);
+               if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
+                       return 0;
+               lookup = resolvedname;
+       }
+       debug2("userauth_hostbased: access allowed by auth_rhosts2");
+
+       host_status = check_key_in_hostfiles(pw, key, lookup,
+           _PATH_SSH_SYSTEM_HOSTFILE,
+           options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
+
+       /* backward compat if no key has been found. */
+       if (host_status == HOST_NEW)
+               host_status = check_key_in_hostfiles(pw, key, lookup,
+                   _PATH_SSH_SYSTEM_HOSTFILE2,
+                   options.ignore_user_known_hosts ? NULL :
+                   _PATH_SSH_USER_HOSTFILE2);
+
+       return (host_status == HOST_OK);
+}
+
+Authmethod method_hostbased = {
+       "hostbased",
+       userauth_hostbased,
+       &options.hostbased_authentication
+};
diff --git a/crypto/openssh-4/auth2-kbdint.c b/crypto/openssh-4/auth2-kbdint.c
new file mode 100644 (file)
index 0000000..fa83649
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2000 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: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "packet.h"
+#include "auth.h"
+#include "log.h"
+#include "servconf.h"
+#include "xmalloc.h"
+
+/* import */
+extern ServerOptions options;
+
+static int
+userauth_kbdint(Authctxt *authctxt)
+{
+       int authenticated = 0;
+       char *lang, *devs;
+
+       lang = packet_get_string(NULL);
+       devs = packet_get_string(NULL);
+       packet_check_eom();
+
+       debug("keyboard-interactive devs %s", devs);
+
+       if (options.challenge_response_authentication)
+               authenticated = auth2_challenge(authctxt, devs);
+
+       xfree(devs);
+       xfree(lang);
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(0, authctxt->pw) == 0)
+               authenticated = 0;
+#endif
+       return authenticated;
+}
+
+Authmethod method_kbdint = {
+       "keyboard-interactive",
+       userauth_kbdint,
+       &options.kbd_interactive_authentication
+};
diff --git a/crypto/openssh-4/auth2-none.c b/crypto/openssh-4/auth2-none.c
new file mode 100644 (file)
index 0000000..1c30a32
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2000 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: auth2-none.c,v 1.7 2004/05/11 19:01:43 deraadt Exp $");
+
+#include "auth.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "servconf.h"
+#include "atomicio.h"
+#include "compat.h"
+#include "ssh2.h"
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+
+/* "none" is allowed only one time */
+static int none_enabled = 1;
+
+char *
+auth2_read_banner(void)
+{
+       struct stat st;
+       char *banner = NULL;
+       size_t len, n;
+       int fd;
+
+       if ((fd = open(options.banner, O_RDONLY)) == -1)
+               return (NULL);
+       if (fstat(fd, &st) == -1) {
+               close(fd);
+               return (NULL);
+       }
+       if (st.st_size > 1*1024*1024) {
+               close(fd);
+               return (NULL);
+       }
+
+       len = (size_t)st.st_size;               /* truncate */
+       banner = xmalloc(len + 1);
+       n = atomicio(read, fd, banner, len);
+       close(fd);
+
+       if (n != len) {
+               xfree(banner);
+               return (NULL);
+       }
+       banner[n] = '\0';
+
+       return (banner);
+}
+
+void
+userauth_send_banner(const char *msg)
+{
+       if (datafellows & SSH_BUG_BANNER)
+               return;
+
+       packet_start(SSH2_MSG_USERAUTH_BANNER);
+       packet_put_cstring(msg);
+       packet_put_cstring("");         /* language, unused */
+       packet_send();
+       debug("%s: sent", __func__);
+}
+
+static void
+userauth_banner(void)
+{
+       char *banner = NULL;
+
+       if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
+               return;
+
+       if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
+               goto done;
+       userauth_send_banner(banner);
+
+done:
+       if (banner)
+               xfree(banner);
+}
+
+static int
+userauth_none(Authctxt *authctxt)
+{
+       none_enabled = 0;
+       packet_check_eom();
+       userauth_banner();
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(1, authctxt->pw) == 0)
+               return (0);
+#endif
+       if (options.password_authentication)
+               return (PRIVSEP(auth_password(authctxt, "")));
+       return (0);
+}
+
+Authmethod method_none = {
+       "none",
+       userauth_none,
+       &none_enabled
+};
diff --git a/crypto/openssh-4/auth2-passwd.c b/crypto/openssh-4/auth2-passwd.c
new file mode 100644 (file)
index 0000000..2321ef4
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000 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: auth2-passwd.c,v 1.5 2003/12/31 00:24:50 dtucker Exp $");
+
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "auth.h"
+#include "monitor_wrap.h"
+#include "servconf.h"
+
+/* import */
+extern ServerOptions options;
+
+static int
+userauth_passwd(Authctxt *authctxt)
+{
+       char *password, *newpass;
+       int authenticated = 0;
+       int change;
+       u_int len, newlen;
+
+       change = packet_get_char();
+       password = packet_get_string(&len);
+       if (change) {
+               /* discard new password from packet */
+               newpass = packet_get_string(&newlen);
+               memset(newpass, 0, newlen);
+               xfree(newpass);
+       }
+       packet_check_eom();
+
+       if (change)
+               logit("password change not supported");
+       else if (PRIVSEP(auth_password(authctxt, password)) == 1)
+               authenticated = 1;
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(1, authctxt->pw) == 0)
+               authenticated = 0;
+#endif
+       memset(password, 0, len);
+       xfree(password);
+       return authenticated;
+}
+
+Authmethod method_passwd = {
+       "password",
+       userauth_passwd,
+       &options.password_authentication
+};
diff --git a/crypto/openssh-4/auth2-pubkey.c b/crypto/openssh-4/auth2-pubkey.c
new file mode 100644 (file)
index 0000000..a97d0f4
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2000 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: auth2-pubkey.c,v 1.9 2004/12/11 01:48:56 dtucker Exp $");
+
+#include "ssh.h"
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "bufaux.h"
+#include "auth.h"
+#include "key.h"
+#include "pathnames.h"
+#include "uidswap.h"
+#include "auth-options.h"
+#include "canohost.h"
+#include "monitor_wrap.h"
+#include "misc.h"
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern u_int session_id2_len;
+
+static int
+userauth_pubkey(Authctxt *authctxt)
+{
+       Buffer b;
+       Key *key = NULL;
+       char *pkalg;
+       u_char *pkblob, *sig;
+       u_int alen, blen, slen;
+       int have_sig, pktype;
+       int authenticated = 0;
+
+       if (!authctxt->valid) {
+               debug2("userauth_pubkey: disabled because of invalid user");
+               return 0;
+       }
+       have_sig = packet_get_char();
+       if (datafellows & SSH_BUG_PKAUTH) {
+               debug2("userauth_pubkey: SSH_BUG_PKAUTH");
+               /* no explicit pkalg given */
+               pkblob = packet_get_string(&blen);
+               buffer_init(&b);
+               buffer_append(&b, pkblob, blen);
+               /* so we have to extract the pkalg from the pkblob */
+               pkalg = buffer_get_string(&b, &alen);
+               buffer_free(&b);
+       } else {
+               pkalg = packet_get_string(&alen);
+               pkblob = packet_get_string(&blen);
+       }
+       pktype = key_type_from_name(pkalg);
+       if (pktype == KEY_UNSPEC) {
+               /* this is perfectly legal */
+               logit("userauth_pubkey: unsupported public key algorithm: %s",
+                   pkalg);
+               goto done;
+       }
+       key = key_from_blob(pkblob, blen);
+       if (key == NULL) {
+               error("userauth_pubkey: cannot decode key: %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("userauth_pubkey: type mismatch for decoded key "
+                   "(received %d, expected %d)", key->type, pktype);
+               goto done;
+       }
+       if (have_sig) {
+               sig = packet_get_string(&slen);
+               packet_check_eom();
+               buffer_init(&b);
+               if (datafellows & SSH_OLD_SESSIONID) {
+                       buffer_append(&b, session_id2, session_id2_len);
+               } else {
+                       buffer_put_string(&b, session_id2, session_id2_len);
+               }
+               /* reconstruct packet */
+               buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+               buffer_put_cstring(&b, authctxt->user);
+               buffer_put_cstring(&b,
+                   datafellows & SSH_BUG_PKSERVICE ?
+                   "ssh-userauth" :
+                   authctxt->service);
+               if (datafellows & SSH_BUG_PKAUTH) {
+                       buffer_put_char(&b, have_sig);
+               } else {
+                       buffer_put_cstring(&b, "publickey");
+                       buffer_put_char(&b, have_sig);
+                       buffer_put_cstring(&b, pkalg);
+               }
+               buffer_put_string(&b, pkblob, blen);
+#ifdef DEBUG_PK
+               buffer_dump(&b);
+#endif
+               /* test for correct signature */
+               authenticated = 0;
+               if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
+                   PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+                   buffer_len(&b))) == 1)
+                       authenticated = 1;
+               buffer_free(&b);
+               xfree(sig);
+       } else {
+               debug("test whether pkalg/pkblob are acceptable");
+               packet_check_eom();
+
+               /* XXX fake reply and always send PK_OK ? */
+               /*
+                * XXX this allows testing whether a user is allowed
+                * to login: if you happen to have a valid pubkey this
+                * message is sent. the message is NEVER sent at all
+                * if a user is not allowed to login. is this an
+                * issue? -markus
+                */
+               if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
+                       packet_start(SSH2_MSG_USERAUTH_PK_OK);
+                       packet_put_string(pkalg, alen);
+                       packet_put_string(pkblob, blen);
+                       packet_send();
+                       packet_write_wait();
+                       authctxt->postponed = 1;
+               }
+       }
+       if (authenticated != 1)
+               auth_clear_options();
+done:
+       debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
+       if (key != NULL)
+               key_free(key);
+       xfree(pkalg);
+       xfree(pkblob);
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(0, authctxt->pw) == 0)
+               authenticated = 0;
+#endif
+       return authenticated;
+}
+
+/* return 1 if user allows given key */
+static int
+user_key_allowed2(struct passwd *pw, Key *key, char *file)
+{
+       char line[SSH_MAX_PUBKEY_BYTES];
+       int found_key = 0;
+       FILE *f;
+       u_long linenum = 0;
+       struct stat st;
+       Key *found;
+       char *fp;
+
+       /* Temporarily use the user's uid. */
+       temporarily_use_uid(pw);
+
+       debug("trying public key file %s", file);
+
+       /* Fail quietly if file does not exist */
+       if (stat(file, &st) < 0) {
+               /* Restore the privileged uid. */
+               restore_uid();
+               return 0;
+       }
+       /* Open the file containing the authorized keys. */
+       f = fopen(file, "r");
+       if (!f) {
+               /* Restore the privileged uid. */
+               restore_uid();
+               return 0;
+       }
+       if (options.strict_modes &&
+           secure_filename(f, file, pw, line, sizeof(line)) != 0) {
+               fclose(f);
+               logit("Authentication refused: %s", line);
+               restore_uid();
+               return 0;
+       }
+
+       found_key = 0;
+       found = key_new(key->type);
+
+       while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
+               char *cp, *key_options = NULL;
+
+               /* Skip leading whitespace, empty and comment lines. */
+               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+                       ;
+               if (!*cp || *cp == '\n' || *cp == '#')
+                       continue;
+
+               if (key_read(found, &cp) != 1) {
+                       /* no key?  check if there are options for this key */
+                       int quoted = 0;
+                       debug2("user_key_allowed: check options: '%s'", cp);
+                       key_options = cp;
+                       for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+                               if (*cp == '\\' && cp[1] == '"')
+                                       cp++;   /* Skip both */
+                               else if (*cp == '"')
+                                       quoted = !quoted;
+                       }
+                       /* Skip remaining whitespace. */
+                       for (; *cp == ' ' || *cp == '\t'; cp++)
+                               ;
+                       if (key_read(found, &cp) != 1) {
+                               debug2("user_key_allowed: advance: '%s'", cp);
+                               /* still no key?  advance to next line*/
+                               continue;
+                       }
+               }
+               if (key_equal(found, key) &&
+                   auth_parse_options(pw, key_options, file, linenum) == 1) {
+                       found_key = 1;
+                       debug("matching key found: file %s, line %lu",
+                           file, linenum);
+                       fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+                       verbose("Found matching %s key: %s",
+                           key_type(found), fp);
+                       xfree(fp);
+                       break;
+               }
+       }
+       restore_uid();
+       fclose(f);
+       key_free(found);
+       if (!found_key)
+               debug2("key not found");
+       return found_key;
+}
+
+/* check whether given key is in .ssh/authorized_keys* */
+int
+user_key_allowed(struct passwd *pw, Key *key)
+{
+       int success;
+       char *file;
+
+       file = authorized_keys_file(pw);
+       success = user_key_allowed2(pw, key, file);
+       xfree(file);
+       if (success)
+               return success;
+
+       /* try suffix "2" for backward compat, too */
+       file = authorized_keys_file2(pw);
+       success = user_key_allowed2(pw, key, file);
+       xfree(file);
+       return success;
+}
+
+Authmethod method_pubkey = {
+       "publickey",
+       userauth_pubkey,
+       &options.pubkey_authentication
+};
diff --git a/crypto/openssh-4/auth2.c b/crypto/openssh-4/auth2.c
new file mode 100644 (file)
index 0000000..2265d31
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Copyright (c) 2000 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: auth2.c,v 1.107 2004/07/28 09:40:29 markus Exp $");
+
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "auth.h"
+#include "dispatch.h"
+#include "pathnames.h"
+#include "monitor_wrap.h"
+#include "buffer.h"
+
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern u_int session_id2_len;
+extern Buffer loginmsg;
+
+/* methods */
+
+extern Authmethod method_none;
+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,
+       NULL
+};
+
+/* protocol */
+
+static void input_service_request(int, u_int32_t, void *);
+static void input_userauth_request(int, u_int32_t, void *);
+
+/* helper */
+static Authmethod *authmethod_lookup(const char *);
+static char *authmethods_get(void);
+int user_key_allowed(struct passwd *, Key *);
+
+/*
+ * loop until authctxt->success == TRUE
+ */
+
+void
+do_authentication2(Authctxt *authctxt)
+{
+       /* challenge-response is implemented via keyboard interactive */
+       if (options.challenge_response_authentication)
+               options.kbd_interactive_authentication = 1;
+
+       dispatch_init(&dispatch_protocol_error);
+       dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
+       dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
+}
+
+static void
+input_service_request(int type, u_int32_t seq, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       u_int len;
+       int acceptit = 0;
+       char *service = packet_get_string(&len);
+       packet_check_eom();
+
+       if (authctxt == NULL)
+               fatal("input_service_request: no authctxt");
+
+       if (strcmp(service, "ssh-userauth") == 0) {
+               if (!authctxt->success) {
+                       acceptit = 1;
+                       /* now we can handle user-auth requests */
+                       dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
+               }
+       }
+       /* XXX all other service requests are denied */
+
+       if (acceptit) {
+               packet_start(SSH2_MSG_SERVICE_ACCEPT);
+               packet_put_cstring(service);
+               packet_send();
+               packet_write_wait();
+       } else {
+               debug("bad service request %s", service);
+               packet_disconnect("bad service request %s", service);
+       }
+       xfree(service);
+}
+
+static void
+input_userauth_request(int type, u_int32_t seq, void *ctxt)
+{
+       Authctxt *authctxt = ctxt;
+       Authmethod *m = NULL;
+       char *user, *service, *method, *style = NULL;
+       int authenticated = 0;
+
+       if (authctxt == NULL)
+               fatal("input_userauth_request: no authctxt");
+
+       user = packet_get_string(NULL);
+       service = packet_get_string(NULL);
+       method = packet_get_string(NULL);
+       debug("userauth-request for user %s service %s method %s", user, service, method);
+       debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+
+       if ((style = strchr(user, ':')) != NULL)
+               *style++ = 0;
+
+       if (authctxt->attempt++ == 0) {
+               /* setup auth context */
+               authctxt->pw = PRIVSEP(getpwnamallow(user));
+               authctxt->user = xstrdup(user);
+               if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+                       authctxt->valid = 1;
+                       debug2("input_userauth_request: setting up authctxt for %s", user);
+#ifdef USE_PAM
+                       if (options.use_pam)
+                               PRIVSEP(start_pam(authctxt));
+#endif
+               } else {
+                       logit("input_userauth_request: invalid user %s", user);
+                       authctxt->pw = fakepw();
+#ifdef USE_PAM
+                       if (options.use_pam)
+                               PRIVSEP(start_pam(authctxt));
+#endif
+#ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_INVALID_USER));
+#endif
+               }
+               setproctitle("%s%s", authctxt->valid ? user : "unknown",
+                   use_privsep ? " [net]" : "");
+               authctxt->service = xstrdup(service);
+               authctxt->style = style ? xstrdup(style) : NULL;
+               if (use_privsep)
+                       mm_inform_authserv(service, style);
+       } else if (strcmp(user, authctxt->user) != 0 ||
+           strcmp(service, authctxt->service) != 0) {
+               packet_disconnect("Change of username or service not allowed: "
+                   "(%s,%s) -> (%s,%s)",
+                   authctxt->user, authctxt->service, user, service);
+       }
+       /* 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 */
+       m = authmethod_lookup(method);
+       if (m != NULL) {
+               debug2("input_userauth_request: try method %s", method);
+               authenticated = m->userauth(authctxt);
+       }
+       userauth_finish(authctxt, authenticated, method);
+
+       xfree(service);
+       xfree(user);
+       xfree(method);
+}
+
+void
+userauth_finish(Authctxt *authctxt, int authenticated, char *method)
+{
+       char *methods;
+
+       if (!authctxt->valid && authenticated)
+               fatal("INTERNAL ERROR: authenticated invalid user %s",
+                   authctxt->user);
+
+       /* Special handling for root */
+       if (authenticated && authctxt->pw->pw_uid == 0 &&
+           !auth_root_allowed(method)) {
+               authenticated = 0;
+#ifdef SSH_AUDIT_EVENTS
+               PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+#endif
+       }
+
+#ifdef USE_PAM
+       if (options.use_pam && authenticated) {
+               if (!PRIVSEP(do_pam_account())) {
+                       /* if PAM returned a message, send it to the user */
+                       if (buffer_len(&loginmsg) > 0) {
+                               buffer_append(&loginmsg, "\0", 1);
+                               userauth_send_banner(buffer_ptr(&loginmsg));
+                               packet_write_wait();
+                       }
+                       fatal("Access denied for user %s by PAM account "
+                          "configuration", authctxt->user);
+               }
+       }
+#endif
+
+#ifdef _UNICOS
+       if (authenticated && cray_access_denied(authctxt->user)) {
+               authenticated = 0;
+               fatal("Access denied for user %s.",authctxt->user);
+       }
+#endif /* _UNICOS */
+
+       /* Log before sending the reply */
+       auth_log(authctxt, authenticated, method, " ssh2");
+
+       if (authctxt->postponed)
+               return;
+
+       /* XXX todo: check if multiple auth methods are needed */
+       if (authenticated == 1) {
+               /* turn off userauth */
+               dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
+               packet_start(SSH2_MSG_USERAUTH_SUCCESS);
+               packet_send();
+               packet_write_wait();
+               /* now we can break out */
+               authctxt->success = 1;
+       } else {
+               if (authctxt->failures++ > options.max_authtries) {
+#ifdef SSH_AUDIT_EVENTS
+                       PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+#endif
+                       packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+               }
+               methods = authmethods_get();
+               packet_start(SSH2_MSG_USERAUTH_FAILURE);
+               packet_put_cstring(methods);
+               packet_put_char(0);     /* XXX partial success, unused */
+               packet_send();
+               packet_write_wait();
+               xfree(methods);
+       }
+}
+
+#define        DELIM   ","
+
+static char *
+authmethods_get(void)
+{
+       Buffer b;
+       char *list;
+       int i;
+
+       buffer_init(&b);
+       for (i = 0; authmethods[i] != NULL; i++) {
+               if (strcmp(authmethods[i]->name, "none") == 0)
+                       continue;
+               if (authmethods[i]->enabled != NULL &&
+                   *(authmethods[i]->enabled) != 0) {
+                       if (buffer_len(&b) > 0)
+                               buffer_append(&b, ",", 1);
+                       buffer_append(&b, authmethods[i]->name,
+                           strlen(authmethods[i]->name));
+               }
+       }
+       buffer_append(&b, "\0", 1);
+       list = xstrdup(buffer_ptr(&b));
+       buffer_free(&b);
+       return list;
+}
+
+static Authmethod *
+authmethod_lookup(const char *name)
+{
+       int i;
+
+       if (name != NULL)
+               for (i = 0; authmethods[i] != NULL; i++)
+                       if (authmethods[i]->enabled != NULL &&
+                           *(authmethods[i]->enabled) != 0 &&
+                           strcmp(name, authmethods[i]->name) == 0)
+                               return authmethods[i];
+       debug2("Unrecognized authentication method name: %s",
+           name ? name : "NULL");
+       return NULL;
+}
diff --git a/crypto/openssh-4/authfd.c b/crypto/openssh-4/authfd.c
new file mode 100644 (file)
index 0000000..662350c
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Functions for connecting the local authentication agent.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ * SSH2 implementation,
+ * Copyright (c) 2000 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: authfd.c,v 1.64 2004/08/11 21:44:31 avsm Exp $");
+
+#include <openssl/evp.h>
+
+#include "ssh.h"
+#include "rsa.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "xmalloc.h"
+#include "getput.h"
+#include "key.h"
+#include "authfd.h"
+#include "cipher.h"
+#include "kex.h"
+#include "compat.h"
+#include "log.h"
+#include "atomicio.h"
+
+static int agent_present = 0;
+
+/* helper */
+int    decode_reply(int type);
+
+/* macro to check for "agent failure" message */
+#define agent_failed(x) \
+    ((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE) || \
+    (x == SSH2_AGENT_FAILURE))
+
+int
+ssh_agent_present(void)
+{
+       int authfd;
+
+       if (agent_present)
+               return 1;
+       if ((authfd = ssh_get_authentication_socket()) == -1)
+               return 0;
+       else {
+               ssh_close_authentication_socket(authfd);
+               return 1;
+       }
+}
+
+/* Returns the number of the authentication fd, or -1 if there is none. */
+
+int
+ssh_get_authentication_socket(void)
+{
+       const char *authsocket;
+       int sock;
+       struct sockaddr_un sunaddr;
+
+       authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME);
+       if (!authsocket)
+               return -1;
+
+       sunaddr.sun_family = AF_UNIX;
+       strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
+
+       sock = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (sock < 0)
+               return -1;
+
+       /* close on exec */
+       if (fcntl(sock, F_SETFD, 1) == -1) {
+               close(sock);
+               return -1;
+       }
+       if (connect(sock, (struct sockaddr *) &sunaddr, sizeof sunaddr) < 0) {
+               close(sock);
+               return -1;
+       }
+       agent_present = 1;
+       return sock;
+}
+
+static int
+ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply)
+{
+       int l;
+       u_int len;
+       char buf[1024];
+
+       /* Get the length of the message, and format it in the buffer. */
+       len = buffer_len(request);
+       PUT_32BIT(buf, len);
+
+       /* Send the length and then the packet to the agent. */
+       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;
+       }
+       /*
+        * Wait for response from the agent.  First read the length of the
+        * response packet.
+        */
+       if (atomicio(read, auth->fd, buf, 4) != 4) {
+           error("Error reading response length from authentication socket.");
+           return 0;
+       }
+
+       /* Extract the length, and check it for sanity. */
+       len = GET_32BIT(buf);
+       if (len > 256 * 1024)
+               fatal("Authentication response too long: %u", len);
+
+       /* Read the rest of the response in to the buffer. */
+       buffer_clear(reply);
+       while (len > 0) {
+               l = len;
+               if (l > sizeof(buf))
+                       l = sizeof(buf);
+               l = atomicio(read, auth->fd, buf, l);
+               if (l <= 0) {
+                       error("Error reading response from authentication socket.");
+                       return 0;
+               }
+               buffer_append(reply, buf, l);
+               len -= l;
+       }
+       return 1;
+}
+
+/*
+ * Closes the agent socket if it should be closed (depends on how it was
+ * obtained).  The argument must have been returned by
+ * ssh_get_authentication_socket().
+ */
+
+void
+ssh_close_authentication_socket(int sock)
+{
+       if (getenv(SSH_AUTHSOCKET_ENV_NAME))
+               close(sock);
+}
+
+/*
+ * Opens and connects a private socket for communication with the
+ * authentication agent.  Returns the file descriptor (which must be
+ * shut down and closed by the caller when no longer needed).
+ * Returns NULL if an error occurred and the connection could not be
+ * opened.
+ */
+
+AuthenticationConnection *
+ssh_get_authentication_connection(void)
+{
+       AuthenticationConnection *auth;
+       int sock;
+
+       sock = ssh_get_authentication_socket();
+
+       /*
+        * Fail if we couldn't obtain a connection.  This happens if we
+        * exited due to a timeout.
+        */
+       if (sock < 0)
+               return NULL;
+
+       auth = xmalloc(sizeof(*auth));
+       auth->fd = sock;
+       buffer_init(&auth->identities);
+       auth->howmany = 0;
+
+       return auth;
+}
+
+/*
+ * Closes the connection to the authentication agent and frees any associated
+ * memory.
+ */
+
+void
+ssh_close_authentication_connection(AuthenticationConnection *auth)
+{
+       buffer_free(&auth->identities);
+       close(auth->fd);
+       xfree(auth);
+}
+
+/* Lock/unlock agent */
+int
+ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password)
+{
+       int type;
+       Buffer msg;
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK);
+       buffer_put_cstring(&msg, password);
+
+       if (ssh_request_reply(auth, &msg, &msg) == 0) {
+               buffer_free(&msg);
+               return 0;
+       }
+       type = buffer_get_char(&msg);
+       buffer_free(&msg);
+       return decode_reply(type);
+}
+
+/*
+ * Returns the first authentication identity held by the agent.
+ */
+
+int
+ssh_get_num_identities(AuthenticationConnection *auth, int version)
+{
+       int type, code1 = 0, code2 = 0;
+       Buffer request;
+
+       switch (version) {
+       case 1:
+               code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
+               code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
+               break;
+       case 2:
+               code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
+               code2 = SSH2_AGENT_IDENTITIES_ANSWER;
+               break;
+       default:
+               return 0;
+       }
+
+       /*
+        * Send a message to the agent requesting for a list of the
+        * identities it can represent.
+        */
+       buffer_init(&request);
+       buffer_put_char(&request, code1);
+
+       buffer_clear(&auth->identities);
+       if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
+               buffer_free(&request);
+               return 0;
+       }
+       buffer_free(&request);
+
+       /* Get message type, and verify that we got a proper answer. */
+       type = buffer_get_char(&auth->identities);
+       if (agent_failed(type)) {
+               return 0;
+       } else if (type != code2) {
+               fatal("Bad authentication reply message type: %d", type);
+       }
+
+       /* Get the number of entries in the response and check it for sanity. */
+       auth->howmany = buffer_get_int(&auth->identities);
+       if ((u_int)auth->howmany > 1024)
+               fatal("Too many identities in authentication reply: %d",
+                   auth->howmany);
+
+       return auth->howmany;
+}
+
+Key *
+ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version)
+{
+       /* get number of identities and return the first entry (if any). */
+       if (ssh_get_num_identities(auth, version) > 0)
+               return ssh_get_next_identity(auth, comment, version);
+       return NULL;
+}
+
+Key *
+ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version)
+{
+       u_int bits;
+       u_char *blob;
+       u_int blen;
+       Key *key = NULL;
+
+       /* Return failure if no more entries. */
+       if (auth->howmany <= 0)
+               return NULL;
+
+       /*
+        * Get the next entry from the packet.  These will abort with a fatal
+        * error if the packet is too short or contains corrupt data.
+        */
+       switch (version) {
+       case 1:
+               key = key_new(KEY_RSA1);
+               bits = buffer_get_int(&auth->identities);
+               buffer_get_bignum(&auth->identities, key->rsa->e);
+               buffer_get_bignum(&auth->identities, key->rsa->n);
+               *comment = buffer_get_string(&auth->identities, NULL);
+               if (bits != BN_num_bits(key->rsa->n))
+                       logit("Warning: identity keysize mismatch: actual %d, announced %u",
+                           BN_num_bits(key->rsa->n), bits);
+               break;
+       case 2:
+               blob = buffer_get_string(&auth->identities, &blen);
+               *comment = buffer_get_string(&auth->identities, NULL);
+               key = key_from_blob(blob, blen);
+               xfree(blob);
+               break;
+       default:
+               return NULL;
+               break;
+       }
+       /* Decrement the number of remaining entries. */
+       auth->howmany--;
+       return key;
+}
+
+/*
+ * Generates a random challenge, sends it to the agent, and waits for
+ * response from the agent.  Returns true (non-zero) if the agent gave the
+ * correct answer, zero otherwise.  Response type selects the style of
+ * response desired, with 0 corresponding to protocol version 1.0 (no longer
+ * supported) and 1 corresponding to protocol version 1.1.
+ */
+
+int
+ssh_decrypt_challenge(AuthenticationConnection *auth,
+    Key* key, BIGNUM *challenge,
+    u_char session_id[16],
+    u_int response_type,
+    u_char response[16])
+{
+       Buffer buffer;
+       int success = 0;
+       int i;
+       int type;
+
+       if (key->type != KEY_RSA1)
+               return 0;
+       if (response_type == 0) {
+               logit("Compatibility with ssh protocol version 1.0 no longer supported.");
+               return 0;
+       }
+       buffer_init(&buffer);
+       buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE);
+       buffer_put_int(&buffer, BN_num_bits(key->rsa->n));
+       buffer_put_bignum(&buffer, key->rsa->e);
+       buffer_put_bignum(&buffer, key->rsa->n);
+       buffer_put_bignum(&buffer, challenge);
+       buffer_append(&buffer, session_id, 16);
+       buffer_put_int(&buffer, response_type);
+
+       if (ssh_request_reply(auth, &buffer, &buffer) == 0) {
+               buffer_free(&buffer);
+               return 0;
+       }
+       type = buffer_get_char(&buffer);
+
+       if (agent_failed(type)) {
+               logit("Agent admitted failure to authenticate using the key.");
+       } else if (type != SSH_AGENT_RSA_RESPONSE) {
+               fatal("Bad authentication response: %d", type);
+       } else {
+               success = 1;
+               /*
+                * Get the response from the packet.  This will abort with a
+                * fatal error if the packet is corrupt.
+                */
+               for (i = 0; i < 16; i++)
+                       response[i] = buffer_get_char(&buffer);
+       }
+       buffer_free(&buffer);
+       return success;
+}
+
+/* ask agent to sign data, returns -1 on error, 0 on success */
+int
+ssh_agent_sign(AuthenticationConnection *auth,
+    Key *key,
+    u_char **sigp, u_int *lenp,
+    u_char *data, u_int datalen)
+{
+       extern int datafellows;
+       Buffer msg;
+       u_char *blob;
+       u_int blen;
+       int type, flags = 0;
+       int ret = -1;
+
+       if (key_to_blob(key, &blob, &blen) == 0)
+               return -1;
+
+       if (datafellows & SSH_BUG_SIGBLOB)
+               flags = SSH_AGENT_OLD_SIGNATURE;
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST);
+       buffer_put_string(&msg, blob, blen);
+       buffer_put_string(&msg, data, datalen);
+       buffer_put_int(&msg, flags);
+       xfree(blob);
+
+       if (ssh_request_reply(auth, &msg, &msg) == 0) {
+               buffer_free(&msg);
+               return -1;
+       }
+       type = buffer_get_char(&msg);
+       if (agent_failed(type)) {
+               logit("Agent admitted failure to sign using the key.");
+       } else if (type != SSH2_AGENT_SIGN_RESPONSE) {
+               fatal("Bad authentication response: %d", type);
+       } else {
+               ret = 0;
+               *sigp = buffer_get_string(&msg, lenp);
+       }
+       buffer_free(&msg);
+       return ret;
+}
+
+/* Encode key for a message to the agent. */
+
+static void
+ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
+{
+       buffer_put_int(b, BN_num_bits(key->n));
+       buffer_put_bignum(b, key->n);
+       buffer_put_bignum(b, key->e);
+       buffer_put_bignum(b, key->d);
+       /* To keep within the protocol: p < q for ssh. in SSL p > q */
+       buffer_put_bignum(b, key->iqmp);        /* ssh key->u */
+       buffer_put_bignum(b, key->q);   /* ssh key->p, SSL key->q */
+       buffer_put_bignum(b, key->p);   /* ssh key->q, SSL key->p */
+       buffer_put_cstring(b, comment);
+}
+
+static void
+ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
+{
+       buffer_put_cstring(b, key_ssh_name(key));
+       switch (key->type) {
+       case KEY_RSA:
+               buffer_put_bignum2(b, key->rsa->n);
+               buffer_put_bignum2(b, key->rsa->e);
+               buffer_put_bignum2(b, key->rsa->d);
+               buffer_put_bignum2(b, key->rsa->iqmp);
+               buffer_put_bignum2(b, key->rsa->p);
+               buffer_put_bignum2(b, key->rsa->q);
+               break;
+       case KEY_DSA:
+               buffer_put_bignum2(b, key->dsa->p);
+               buffer_put_bignum2(b, key->dsa->q);
+               buffer_put_bignum2(b, key->dsa->g);
+               buffer_put_bignum2(b, key->dsa->pub_key);
+               buffer_put_bignum2(b, key->dsa->priv_key);
+               break;
+       }
+       buffer_put_cstring(b, comment);
+}
+
+/*
+ * Adds an identity to the authentication server.  This call is not meant to
+ * be used by normal applications.
+ */
+
+int
+ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
+    const char *comment, u_int life, u_int confirm)
+{
+       Buffer msg;
+       int type, constrained = (life || confirm);
+
+       buffer_init(&msg);
+
+       switch (key->type) {
+       case KEY_RSA1:
+               type = constrained ?
+                   SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
+                   SSH_AGENTC_ADD_RSA_IDENTITY;
+               buffer_put_char(&msg, type);
+               ssh_encode_identity_rsa1(&msg, key->rsa, comment);
+               break;
+       case KEY_RSA:
+       case KEY_DSA:
+               type = constrained ?
+                   SSH2_AGENTC_ADD_ID_CONSTRAINED :
+                   SSH2_AGENTC_ADD_IDENTITY;
+               buffer_put_char(&msg, type);
+               ssh_encode_identity_ssh2(&msg, key, comment);
+               break;
+       default:
+               buffer_free(&msg);
+               return 0;
+               break;
+       }
+       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;
+       }
+       type = buffer_get_char(&msg);
+       buffer_free(&msg);
+       return decode_reply(type);
+}
+
+int
+ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
+{
+       return ssh_add_identity_constrained(auth, key, comment, 0, 0);
+}
+
+/*
+ * Removes an identity from the authentication server.  This call is not
+ * meant to be used by normal applications.
+ */
+
+int
+ssh_remove_identity(AuthenticationConnection *auth, Key *key)
+{
+       Buffer msg;
+       int type;
+       u_char *blob;
+       u_int blen;
+
+       buffer_init(&msg);
+
+       if (key->type == KEY_RSA1) {
+               buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
+               buffer_put_int(&msg, BN_num_bits(key->rsa->n));
+               buffer_put_bignum(&msg, key->rsa->e);
+               buffer_put_bignum(&msg, key->rsa->n);
+       } else if (key->type == KEY_DSA || key->type == KEY_RSA) {
+               key_to_blob(key, &blob, &blen);
+               buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
+               buffer_put_string(&msg, blob, blen);
+               xfree(blob);
+       } else {
+               buffer_free(&msg);
+               return 0;
+       }
+       if (ssh_request_reply(auth, &msg, &msg) == 0) {
+               buffer_free(&msg);
+               return 0;
+       }
+       type = buffer_get_char(&msg);
+       buffer_free(&msg);
+       return decode_reply(type);
+}
+
+int
+ssh_update_card(AuthenticationConnection *auth, int add,
+    const char *reader_id, const char *pin, u_int life, u_int confirm)
+{
+       Buffer msg;
+       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, 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;
+       }
+       type = buffer_get_char(&msg);
+       buffer_free(&msg);
+       return decode_reply(type);
+}
+
+/*
+ * Removes all identities from the agent.  This call is not meant to be used
+ * by normal applications.
+ */
+
+int
+ssh_remove_all_identities(AuthenticationConnection *auth, int version)
+{
+       Buffer msg;
+       int type;
+       int code = (version==1) ?
+               SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :
+               SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
+
+       buffer_init(&msg);
+       buffer_put_char(&msg, code);
+
+       if (ssh_request_reply(auth, &msg, &msg) == 0) {
+               buffer_free(&msg);
+               return 0;
+       }
+       type = buffer_get_char(&msg);
+       buffer_free(&msg);
+       return decode_reply(type);
+}
+
+int
+decode_reply(int type)
+{
+       switch (type) {
+       case SSH_AGENT_FAILURE:
+       case SSH_COM_AGENT2_FAILURE:
+       case SSH2_AGENT_FAILURE:
+               logit("SSH_AGENT_FAILURE");
+               return 0;
+       case SSH_AGENT_SUCCESS:
+               return 1;
+       default:
+               fatal("Bad response from authentication agent: %d", type);
+       }
+       /* NOTREACHED */
+       return 0;
+}
diff --git a/crypto/openssh-4/authfd.h b/crypto/openssh-4/authfd.h
new file mode 100644 (file)
index 0000000..0a6a4e3
--- /dev/null
@@ -0,0 +1,97 @@
+/*     $OpenBSD: authfd.h,v 1.34 2003/11/21 11:57:03 djm Exp $ */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Functions to interface with the SSH_AUTHENTICATION_FD socket.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#ifndef AUTHFD_H
+#define AUTHFD_H
+
+#include "buffer.h"
+
+/* Messages for the authentication agent connection. */
+#define SSH_AGENTC_REQUEST_RSA_IDENTITIES      1
+#define SSH_AGENT_RSA_IDENTITIES_ANSWER                2
+#define SSH_AGENTC_RSA_CHALLENGE               3
+#define SSH_AGENT_RSA_RESPONSE                 4
+#define SSH_AGENT_FAILURE                      5
+#define SSH_AGENT_SUCCESS                      6
+#define SSH_AGENTC_ADD_RSA_IDENTITY            7
+#define SSH_AGENTC_REMOVE_RSA_IDENTITY         8
+#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES   9
+
+/* private OpenSSH extensions for SSH2 */
+#define SSH2_AGENTC_REQUEST_IDENTITIES         11
+#define SSH2_AGENT_IDENTITIES_ANSWER           12
+#define SSH2_AGENTC_SIGN_REQUEST               13
+#define SSH2_AGENT_SIGN_RESPONSE               14
+#define SSH2_AGENTC_ADD_IDENTITY               17
+#define SSH2_AGENTC_REMOVE_IDENTITY            18
+#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES      19
+
+/* smartcard */
+#define SSH_AGENTC_ADD_SMARTCARD_KEY           20
+#define SSH_AGENTC_REMOVE_SMARTCARD_KEY                21
+
+/* lock/unlock the agent */
+#define SSH_AGENTC_LOCK                                22
+#define SSH_AGENTC_UNLOCK                      23
+
+/* 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
+
+/* extended failure messages */
+#define SSH2_AGENT_FAILURE                     30
+
+/* additional error code for ssh.com's ssh-agent2 */
+#define SSH_COM_AGENT2_FAILURE                 102
+
+#define        SSH_AGENT_OLD_SIGNATURE                 0x01
+
+typedef struct {
+       int     fd;
+       Buffer  identities;
+       int     howmany;
+}      AuthenticationConnection;
+
+int    ssh_agent_present(void);
+int    ssh_get_authentication_socket(void);
+void   ssh_close_authentication_socket(int);
+
+AuthenticationConnection *ssh_get_authentication_connection(void);
+void   ssh_close_authentication_connection(AuthenticationConnection *);
+int     ssh_get_num_identities(AuthenticationConnection *, int);
+Key    *ssh_get_first_identity(AuthenticationConnection *, char **, int);
+Key    *ssh_get_next_identity(AuthenticationConnection *, char **, int);
+int     ssh_add_identity(AuthenticationConnection *, Key *, const char *);
+int     ssh_add_identity_constrained(AuthenticationConnection *, Key *,
+    const char *, u_int, u_int);
+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 *, u_int, u_int);
+
+int
+ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
+    u_int, u_char[16]);
+
+int
+ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *,
+    u_int);
+
+#endif                         /* AUTHFD_H */
diff --git a/crypto/openssh-4/authfile.c b/crypto/openssh-4/authfile.c
new file mode 100644 (file)
index 0000000..6a04cd7
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * This file contains functions for reading and writing identity files, and
+ * for reading the passphrase from the user.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ *
+ * Copyright (c) 2000 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: authfile.c,v 1.60 2004/12/11 01:48:56 dtucker Exp $");
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#include "cipher.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "key.h"
+#include "ssh.h"
+#include "log.h"
+#include "authfile.h"
+#include "rsa.h"
+#include "misc.h"
+
+/* Version identification string for SSH v1 identity files. */
+static const char authfile_id_string[] =
+    "SSH PRIVATE KEY FILE FORMAT 1.1\n";
+
+/*
+ * Saves the authentication (private) key in a file, encrypting it with
+ * passphrase.  The identification of the file (lowest 64 bits of n) will
+ * precede the key to provide identification of the key without needing a
+ * passphrase.
+ */
+
+static int
+key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
+    const char *comment)
+{
+       Buffer buffer, encrypted;
+       u_char buf[100], *cp;
+       int fd, i, cipher_num;
+       CipherContext ciphercontext;
+       Cipher *cipher;
+       u_int32_t rnd;
+
+       /*
+        * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
+        * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
+        */
+       cipher_num = (strcmp(passphrase, "") == 0) ?
+           SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
+       if ((cipher = cipher_by_number(cipher_num)) == NULL)
+               fatal("save_private_key_rsa: bad cipher");
+
+       /* This buffer is used to built the secret part of the private key. */
+       buffer_init(&buffer);
+
+       /* Put checkbytes for checking passphrase validity. */
+       rnd = arc4random();
+       buf[0] = rnd & 0xff;
+       buf[1] = (rnd >> 8) & 0xff;
+       buf[2] = buf[0];
+       buf[3] = buf[1];
+       buffer_append(&buffer, buf, 4);
+
+       /*
+        * Store the private key (n and e will not be stored because they
+        * will be stored in plain text, and storing them also in encrypted
+        * format would just give known plaintext).
+        */
+       buffer_put_bignum(&buffer, key->rsa->d);
+       buffer_put_bignum(&buffer, key->rsa->iqmp);
+       buffer_put_bignum(&buffer, key->rsa->q);        /* reverse from SSL p */
+       buffer_put_bignum(&buffer, key->rsa->p);        /* reverse from SSL q */
+
+       /* Pad the part to be encrypted until its size is a multiple of 8. */
+       while (buffer_len(&buffer) % 8 != 0)
+               buffer_put_char(&buffer, 0);
+
+       /* This buffer will be used to contain the data in the file. */
+       buffer_init(&encrypted);
+
+       /* First store keyfile id string. */
+       for (i = 0; authfile_id_string[i]; i++)
+               buffer_put_char(&encrypted, authfile_id_string[i]);
+       buffer_put_char(&encrypted, 0);
+
+       /* Store cipher type. */
+       buffer_put_char(&encrypted, cipher_num);
+       buffer_put_int(&encrypted, 0);  /* For future extension */
+
+       /* Store public key.  This will be in plain text. */
+       buffer_put_int(&encrypted, BN_num_bits(key->rsa->n));
+       buffer_put_bignum(&encrypted, key->rsa->n);
+       buffer_put_bignum(&encrypted, key->rsa->e);
+       buffer_put_cstring(&encrypted, comment);
+
+       /* Allocate space for the private part of the key in the buffer. */
+       cp = buffer_append_space(&encrypted, buffer_len(&buffer));
+
+       cipher_set_key_string(&ciphercontext, cipher, passphrase,
+           CIPHER_ENCRYPT);
+       cipher_crypt(&ciphercontext, cp,
+           buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_cleanup(&ciphercontext);
+       memset(&ciphercontext, 0, sizeof(ciphercontext));
+
+       /* Destroy temporary data. */
+       memset(buf, 0, sizeof(buf));
+       buffer_free(&buffer);
+
+       fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+       if (fd < 0) {
+               error("open %s failed: %s.", filename, strerror(errno));
+               buffer_free(&encrypted);
+               return 0;
+       }
+       if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
+           buffer_len(&encrypted)) {
+               error("write to key file %s failed: %s", filename,
+                   strerror(errno));
+               buffer_free(&encrypted);
+               close(fd);
+               unlink(filename);
+               return 0;
+       }
+       close(fd);
+       buffer_free(&encrypted);
+       return 1;
+}
+
+/* save SSH v2 key in OpenSSL PEM format */
+static int
+key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
+    const char *comment)
+{
+       FILE *fp;
+       int fd;
+       int success = 0;
+       int len = strlen(_passphrase);
+       u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
+       const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
+
+       if (len > 0 && len <= 4) {
+               error("passphrase too short: have %d bytes, need > 4", len);
+               return 0;
+       }
+       fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+       if (fd < 0) {
+               error("open %s failed: %s.", filename, strerror(errno));
+               return 0;
+       }
+       fp = fdopen(fd, "w");
+       if (fp == NULL ) {
+               error("fdopen %s failed: %s.", filename, strerror(errno));
+               close(fd);
+               return 0;
+       }
+       switch (key->type) {
+       case KEY_DSA:
+               success = PEM_write_DSAPrivateKey(fp, key->dsa,
+                   cipher, passphrase, len, NULL, NULL);
+               break;
+       case KEY_RSA:
+               success = PEM_write_RSAPrivateKey(fp, key->rsa,
+                   cipher, passphrase, len, NULL, NULL);
+               break;
+       }
+       fclose(fp);
+       return success;
+}
+
+int
+key_save_private(Key *key, const char *filename, const char *passphrase,
+    const char *comment)
+{
+       switch (key->type) {
+       case KEY_RSA1:
+               return key_save_private_rsa1(key, filename, passphrase,
+                   comment);
+               break;
+       case KEY_DSA:
+       case KEY_RSA:
+               return key_save_private_pem(key, filename, passphrase,
+                   comment);
+               break;
+       default:
+               break;
+       }
+       error("key_save_private: cannot save key type %d", key->type);
+       return 0;
+}
+
+/*
+ * Loads the public part of the ssh v1 key file.  Returns NULL if an error was
+ * encountered (the file does not exist or is not readable), and the key
+ * otherwise.
+ */
+
+static Key *
+key_load_public_rsa1(int fd, const char *filename, char **commentp)
+{
+       Buffer buffer;
+       Key *pub;
+       struct stat st;
+       char *cp;
+       int i;
+       size_t len;
+
+       if (fstat(fd, &st) < 0) {
+               error("fstat for key file %.200s failed: %.100s",
+                   filename, strerror(errno));
+               return NULL;
+       }
+       if (st.st_size > 1*1024*1024) {
+               error("key file %.200s too large", filename);
+               return NULL;
+       }
+       len = (size_t)st.st_size;               /* truncated */
+
+       buffer_init(&buffer);
+       cp = buffer_append_space(&buffer, len);
+
+       if (read(fd, cp, (size_t) len) != (size_t) len) {
+               debug("Read from key file %.200s failed: %.100s", filename,
+                   strerror(errno));
+               buffer_free(&buffer);
+               return NULL;
+       }
+
+       /* Check that it is at least big enough to contain the ID string. */
+       if (len < sizeof(authfile_id_string)) {
+               debug3("Not a RSA1 key file %.200s.", filename);
+               buffer_free(&buffer);
+               return NULL;
+       }
+       /*
+        * Make sure it begins with the id string.  Consume the id string
+        * from the buffer.
+        */
+       for (i = 0; i < sizeof(authfile_id_string); i++)
+               if (buffer_get_char(&buffer) != authfile_id_string[i]) {
+                       debug3("Not a RSA1 key file %.200s.", filename);
+                       buffer_free(&buffer);
+                       return NULL;
+               }
+       /* Skip cipher type and reserved data. */
+       (void) buffer_get_char(&buffer);        /* cipher type */
+       (void) buffer_get_int(&buffer);         /* reserved */
+
+       /* Read the public key from the buffer. */
+       (void) buffer_get_int(&buffer);
+       pub = key_new(KEY_RSA1);
+       buffer_get_bignum(&buffer, pub->rsa->n);
+       buffer_get_bignum(&buffer, pub->rsa->e);
+       if (commentp)
+               *commentp = buffer_get_string(&buffer, NULL);
+       /* The encrypted private part is not parsed by this function. */
+
+       buffer_free(&buffer);
+       return pub;
+}
+
+/* load public key from private-key file, works only for SSH v1 */
+Key *
+key_load_public_type(int type, const char *filename, char **commentp)
+{
+       Key *pub;
+       int fd;
+
+       if (type == KEY_RSA1) {
+               fd = open(filename, O_RDONLY);
+               if (fd < 0)
+                       return NULL;
+               pub = key_load_public_rsa1(fd, filename, commentp);
+               close(fd);
+               return pub;
+       }
+       return NULL;
+}
+
+/*
+ * Loads the private key from the file.  Returns 0 if an error is encountered
+ * (file does not exist or is not readable, or passphrase is bad). This
+ * initializes the private key.
+ * Assumes we are called under uid of the owner of the file.
+ */
+
+static Key *
+key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
+    char **commentp)
+{
+       int i, check1, check2, cipher_type;
+       size_t len;
+       Buffer buffer, decrypted;
+       u_char *cp;
+       CipherContext ciphercontext;
+       Cipher *cipher;
+       Key *prv = NULL;
+       struct stat st;
+
+       if (fstat(fd, &st) < 0) {
+               error("fstat for key file %.200s failed: %.100s",
+                   filename, strerror(errno));
+               close(fd);
+               return NULL;
+       }
+       if (st.st_size > 1*1024*1024) {
+               error("key file %.200s too large", filename);
+               close(fd);
+               return (NULL);
+       }
+       len = (size_t)st.st_size;               /* truncated */
+
+       buffer_init(&buffer);
+       cp = buffer_append_space(&buffer, len);
+
+       if (read(fd, cp, (size_t) len) != (size_t) len) {
+               debug("Read from key file %.200s failed: %.100s", filename,
+                   strerror(errno));
+               buffer_free(&buffer);
+               close(fd);
+               return NULL;
+       }
+
+       /* Check that it is at least big enough to contain the ID string. */
+       if (len < sizeof(authfile_id_string)) {
+               debug3("Not a RSA1 key file %.200s.", filename);
+               buffer_free(&buffer);
+               close(fd);
+               return NULL;
+       }
+       /*
+        * Make sure it begins with the id string.  Consume the id string
+        * from the buffer.
+        */
+       for (i = 0; i < sizeof(authfile_id_string); i++)
+               if (buffer_get_char(&buffer) != authfile_id_string[i]) {
+                       debug3("Not a RSA1 key file %.200s.", filename);
+                       buffer_free(&buffer);
+                       close(fd);
+                       return NULL;
+               }
+
+       /* Read cipher type. */
+       cipher_type = buffer_get_char(&buffer);
+       (void) buffer_get_int(&buffer); /* Reserved data. */
+
+       /* Read the public key from the buffer. */
+       (void) buffer_get_int(&buffer);
+       prv = key_new_private(KEY_RSA1);
+
+       buffer_get_bignum(&buffer, prv->rsa->n);
+       buffer_get_bignum(&buffer, prv->rsa->e);
+       if (commentp)
+               *commentp = buffer_get_string(&buffer, NULL);
+       else
+               xfree(buffer_get_string(&buffer, NULL));
+
+       /* Check that it is a supported cipher. */
+       cipher = cipher_by_number(cipher_type);
+       if (cipher == NULL) {
+               debug("Unsupported cipher %d used in key file %.200s.",
+                   cipher_type, filename);
+               buffer_free(&buffer);
+               goto fail;
+       }
+       /* Initialize space for decrypted data. */
+       buffer_init(&decrypted);
+       cp = buffer_append_space(&decrypted, buffer_len(&buffer));
+
+       /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
+       cipher_set_key_string(&ciphercontext, cipher, passphrase,
+           CIPHER_DECRYPT);
+       cipher_crypt(&ciphercontext, cp,
+           buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_cleanup(&ciphercontext);
+       memset(&ciphercontext, 0, sizeof(ciphercontext));
+       buffer_free(&buffer);
+
+       check1 = buffer_get_char(&decrypted);
+       check2 = buffer_get_char(&decrypted);
+       if (check1 != buffer_get_char(&decrypted) ||
+           check2 != buffer_get_char(&decrypted)) {
+               if (strcmp(passphrase, "") != 0)
+                       debug("Bad passphrase supplied for key file %.200s.",
+                           filename);
+               /* Bad passphrase. */
+               buffer_free(&decrypted);
+               goto fail;
+       }
+       /* Read the rest of the private key. */
+       buffer_get_bignum(&decrypted, prv->rsa->d);
+       buffer_get_bignum(&decrypted, prv->rsa->iqmp);          /* u */
+       /* in SSL and SSH v1 p and q are exchanged */
+       buffer_get_bignum(&decrypted, prv->rsa->q);             /* p */
+       buffer_get_bignum(&decrypted, prv->rsa->p);             /* q */
+
+       /* calculate p-1 and q-1 */
+       rsa_generate_additional_parameters(prv->rsa);
+
+       buffer_free(&decrypted);
+
+       /* enable blinding */
+       if (RSA_blinding_on(prv->rsa, NULL) != 1) {
+               error("key_load_private_rsa1: RSA_blinding_on failed");
+               goto fail;
+       }
+       close(fd);
+       return prv;
+
+fail:
+       if (commentp)
+               xfree(*commentp);
+       close(fd);
+       key_free(prv);
+       return NULL;
+}
+
+Key *
+key_load_private_pem(int fd, int type, const char *passphrase,
+    char **commentp)
+{
+       FILE *fp;
+       EVP_PKEY *pk = NULL;
+       Key *prv = NULL;
+       char *name = "<no key>";
+
+       fp = fdopen(fd, "r");
+       if (fp == NULL) {
+               error("fdopen failed: %s", strerror(errno));
+               close(fd);
+               return NULL;
+       }
+       pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
+       if (pk == NULL) {
+               debug("PEM_read_PrivateKey failed");
+               (void)ERR_get_error();
+       } else if (pk->type == EVP_PKEY_RSA &&
+           (type == KEY_UNSPEC||type==KEY_RSA)) {
+               prv = key_new(KEY_UNSPEC);
+               prv->rsa = EVP_PKEY_get1_RSA(pk);
+               prv->type = KEY_RSA;
+               name = "rsa w/o comment";
+#ifdef DEBUG_PK
+               RSA_print_fp(stderr, prv->rsa, 8);
+#endif
+               if (RSA_blinding_on(prv->rsa, NULL) != 1) {
+                       error("key_load_private_pem: RSA_blinding_on failed");
+                       key_free(prv);
+                       prv = NULL;
+               }
+       } else if (pk->type == EVP_PKEY_DSA &&
+           (type == KEY_UNSPEC||type==KEY_DSA)) {
+               prv = key_new(KEY_UNSPEC);
+               prv->dsa = EVP_PKEY_get1_DSA(pk);
+               prv->type = KEY_DSA;
+               name = "dsa w/o comment";
+#ifdef DEBUG_PK
+               DSA_print_fp(stderr, prv->dsa, 8);
+#endif
+       } else {
+               error("PEM_read_PrivateKey: mismatch or "
+                   "unknown EVP_PKEY save_type %d", pk->save_type);
+       }
+       fclose(fp);
+       if (pk != NULL)
+               EVP_PKEY_free(pk);
+       if (prv != NULL && commentp)
+               *commentp = xstrdup(name);
+       debug("read PEM private key done: type %s",
+           prv ? key_type(prv) : "<unknown>");
+       return prv;
+}
+
+static int
+key_perm_ok(int fd, const char *filename)
+{
+       struct stat st;
+
+       if (fstat(fd, &st) < 0)
+               return 0;
+       /*
+        * if a key owned by the user is accessed, then we check the
+        * permissions of the file. if the key owned by a different user,
+        * then we don't care.
+        */
+#ifdef HAVE_CYGWIN
+       if (check_ntsec(filename))
+#endif
+       if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
+               error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+               error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
+               error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+               error("Permissions 0%3.3o for '%s' are too open.",
+                   (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;
+       }
+       return 1;
+}
+
+Key *
+key_load_private_type(int type, const char *filename, const char *passphrase,
+    char **commentp)
+{
+       int fd;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+       if (!key_perm_ok(fd, filename)) {
+               error("bad permissions: ignore key: %s", filename);
+               close(fd);
+               return NULL;
+       }
+       switch (type) {
+       case KEY_RSA1:
+               return key_load_private_rsa1(fd, filename, passphrase,
+                   commentp);
+               /* closes fd */
+               break;
+       case KEY_DSA:
+       case KEY_RSA:
+       case KEY_UNSPEC:
+               return key_load_private_pem(fd, type, passphrase, commentp);
+               /* closes fd */
+               break;
+       default:
+               close(fd);
+               break;
+       }
+       return NULL;
+}
+
+Key *
+key_load_private(const char *filename, const char *passphrase,
+    char **commentp)
+{
+       Key *pub, *prv;
+       int fd;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+       if (!key_perm_ok(fd, filename)) {
+               error("bad permissions: ignore key: %s", filename);
+               close(fd);
+               return NULL;
+       }
+       pub = key_load_public_rsa1(fd, filename, commentp);
+       lseek(fd, (off_t) 0, SEEK_SET);         /* rewind */
+       if (pub == NULL) {
+               /* closes fd */
+               prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL);
+               /* use the filename as a comment for PEM */
+               if (commentp && prv)
+                       *commentp = xstrdup(filename);
+       } else {
+               /* it's a SSH v1 key if the public key part is readable */
+               key_free(pub);
+               /* closes fd */
+               prv = key_load_private_rsa1(fd, filename, passphrase, NULL);
+       }
+       return prv;
+}
+
+static int
+key_try_load_public(Key *k, const char *filename, char **commentp)
+{
+       FILE *f;
+       char line[SSH_MAX_PUBKEY_BYTES];
+       char *cp;
+       u_long linenum = 0;
+
+       f = fopen(filename, "r");
+       if (f != NULL) {
+               while (read_keyfile_line(f, filename, line, sizeof(line),
+                           &linenum) != -1) {
+                       cp = line;
+                       switch (*cp) {
+                       case '#':
+                       case '\n':
+                       case '\0':
+                               continue;
+                       }
+                       /* Skip leading whitespace. */
+                       for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
+                               ;
+                       if (*cp) {
+                               if (key_read(k, &cp) == 1) {
+                                       if (commentp)
+                                               *commentp=xstrdup(filename);
+                                       fclose(f);
+                                       return 1;
+                               }
+                       }
+               }
+               fclose(f);
+       }
+       return 0;
+}
+
+/* load public key from ssh v1 private or any pubkey file */
+Key *
+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;
+       if ((strlcpy(file, filename, sizeof file) < sizeof(file)) &&
+           (strlcat(file, ".pub", sizeof file) < sizeof(file)) &&
+           (key_try_load_public(pub, file, commentp) == 1))
+               return pub;
+       key_free(pub);
+       return NULL;
+}
diff --git a/crypto/openssh-4/authfile.h b/crypto/openssh-4/authfile.h
new file mode 100644 (file)
index 0000000..7f92701
--- /dev/null
@@ -0,0 +1,25 @@
+/*     $OpenBSD: authfile.h,v 1.10 2002/05/23 19:24:30 markus Exp $    */
+
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+
+#ifndef AUTHFILE_H
+#define AUTHFILE_H
+
+int     key_save_private(Key *, const char *, const char *, const char *);
+Key    *key_load_public(const char *, char **);
+Key    *key_load_public_type(int, const char *, char **);
+Key    *key_load_private(const char *, const char *, char **);
+Key    *key_load_private_type(int, const char *, const char *, char **);
+Key    *key_load_private_pem(int, int, const char *, char **);
+
+#endif
diff --git a/crypto/openssh-4/bufaux.c b/crypto/openssh-4/bufaux.c
new file mode 100644 (file)
index 0000000..5dbf2b7
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * Auxiliary functions for storing and retrieving various data types to/from
+ * Buffers.
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose.  Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ *
+ *
+ * SSH2 packet format added by Markus Friedl
+ * Copyright (c) 2000 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