Flatten the OpenSSH vendor tree for 3.x and newer.
This commit is contained in:
parent
f591b3e29c
commit
624d93001f
@ -1,70 +0,0 @@
|
||||
This file is part of the ssh software, Copyright (c) 1995 Tatu Ylonen, Finland
|
||||
|
||||
|
||||
COPYING POLICY AND OTHER LEGAL ISSUES
|
||||
|
||||
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".
|
||||
|
||||
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.
|
||||
|
||||
[ RSA is no longer included. ]
|
||||
[ IDEA is no longer included. ]
|
||||
[ DES is now external. ]
|
||||
[ GMP is now external. No more GNU licence. ]
|
||||
[ Zlib is now external. ]
|
||||
[ The make-ssh-known-hosts script is no longer included. ]
|
||||
[ TSS has been removed. ]
|
||||
[ MD5 is now external. ]
|
||||
[ RC4 support has been removed. ]
|
||||
[ Blowfish is now external. ]
|
||||
|
||||
The 32-bit CRC implementation in crc32.c is due to Gary S. Brown.
|
||||
Comments in the file indicate it may be used for any purpose without
|
||||
restrictions.
|
||||
|
||||
The 32-bit CRC compensation attack detector in deattack.c was
|
||||
contributed by CORE SDI S.A. under a BSD-style license. See
|
||||
http://www.core-sdi.com/english/ssh/ for details.
|
||||
|
||||
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.
|
@ -1,105 +0,0 @@
|
||||
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
|
||||
|
||||
Ahsan Rashid <arms@sco.com> - UnixWare long passwords
|
||||
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
|
||||
Chad Mynhier <mynhier@interstel.net> - Solaris Process Contract 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.
|
||||
Dhiraj Gulati <dgulati@sco.com> - UnixWare long passwords
|
||||
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.81 2006/08/30 17:24:41 djm Exp $
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,253 +0,0 @@
|
||||
1. Prerequisites
|
||||
----------------
|
||||
|
||||
You will need working installations of Zlib and OpenSSL.
|
||||
|
||||
Zlib 1.1.4 or 1.2.1.2 or greater (ealier 1.2.x versions have problems):
|
||||
http://www.gzip.org/zlib/
|
||||
|
||||
OpenSSL 0.9.6 or greater:
|
||||
http://www.openssl.org/
|
||||
|
||||
(OpenSSL 0.9.5a is partially supported, but some ciphers (SSH protocol 1
|
||||
Blowfish) do not work correctly.)
|
||||
|
||||
The remaining items are optional.
|
||||
|
||||
OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system
|
||||
supports it. PAM is standard on Redhat and Debian Linux, Solaris and
|
||||
HP-UX 11.
|
||||
|
||||
NB. If you operating system supports /dev/random, you should configure
|
||||
OpenSSL to use it. OpenSSH relies on OpenSSL's direct support of
|
||||
/dev/random. If you don't you will have to rely on ssh-rand-helper, which
|
||||
is inferior to a good kernel-based solution.
|
||||
|
||||
PAM:
|
||||
http://www.kernel.org/pub/linux/libs/pam/
|
||||
|
||||
If you wish to build the GNOME passphrase requester, you will need the GNOME
|
||||
libraries and headers.
|
||||
|
||||
GNOME:
|
||||
http://www.gnome.org/
|
||||
|
||||
Alternatively, Jim Knoble <jmknoble@pobox.com> has written an excellent X11
|
||||
passphrase requester. This is maintained separately at:
|
||||
|
||||
http://www.jmknoble.net/software/x11-ssh-askpass/
|
||||
|
||||
PRNGD:
|
||||
|
||||
If your system lacks Kernel based random collection, the use of Lutz
|
||||
Jaenicke's PRNGd is recommended.
|
||||
|
||||
http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html
|
||||
|
||||
EGD:
|
||||
|
||||
The Entropy Gathering Daemon (EGD) is supported if you have a system which
|
||||
lacks /dev/random and don't want to use OpenSSH's internal entropy collection.
|
||||
|
||||
http://www.lothar.com/tech/crypto/
|
||||
|
||||
S/Key Libraries:
|
||||
|
||||
If you wish to use --with-skey then you will need the library below
|
||||
installed. No other S/Key library is currently known to be supported.
|
||||
|
||||
http://www.sparc.spb.su/solaris/skey/
|
||||
|
||||
LibEdit:
|
||||
|
||||
sftp supports command-line editing via NetBSD's libedit. If your platform
|
||||
has it available natively you can use that, alternatively you might try
|
||||
these multi-platform ports:
|
||||
|
||||
http://www.thrysoee.dk/editline/
|
||||
http://sourceforge.net/projects/libedit/
|
||||
|
||||
Autoconf:
|
||||
|
||||
If you modify configure.ac or configure doesn't exist (eg if you checked
|
||||
the code out of CVS yourself) then you will need autoconf-2.60 to rebuild
|
||||
the automatically generated files by running "autoreconf".
|
||||
|
||||
http://www.gnu.org/software/autoconf/
|
||||
|
||||
Basic Security Module (BSM):
|
||||
|
||||
Native BSM support is know to exist in Solaris from at least 2.5.1,
|
||||
FreeBSD 6.1 and OS X. Alternatively, you may use the OpenBSM
|
||||
implementation (http://www.openbsm.org).
|
||||
|
||||
|
||||
2. Building / Installation
|
||||
--------------------------
|
||||
|
||||
To install OpenSSH with default options:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
This will install the OpenSSH binaries in /usr/local/bin, configuration files
|
||||
in /usr/local/etc, the server in /usr/local/sbin, etc. To specify a different
|
||||
installation prefix, use the --prefix option to configure:
|
||||
|
||||
./configure --prefix=/opt
|
||||
make
|
||||
make install
|
||||
|
||||
Will install OpenSSH in /opt/{bin,etc,lib,sbin}. You can also override
|
||||
specific paths, for example:
|
||||
|
||||
./configure --prefix=/opt --sysconfdir=/etc/ssh
|
||||
make
|
||||
make install
|
||||
|
||||
This will install the binaries in /opt/{bin,lib,sbin}, but will place the
|
||||
configuration files in /etc/ssh.
|
||||
|
||||
If you are using Privilege Separation (which is enabled by default)
|
||||
then you will also need to create the user, group and directory used by
|
||||
sshd for privilege separation. See README.privsep for details.
|
||||
|
||||
If you are using PAM, you may need to manually install a PAM control
|
||||
file as "/etc/pam.d/sshd" (or wherever your system prefers to keep
|
||||
them). Note that the service name used to start PAM is __progname,
|
||||
which is the basename of the path of your sshd (e.g., the service name
|
||||
for /usr/sbin/osshd will be osshd). If you have renamed your sshd
|
||||
executable, your PAM configuration may need to be modified.
|
||||
|
||||
A generic PAM configuration is included as "contrib/sshd.pam.generic",
|
||||
you may need to edit it before using it on your system. If you are
|
||||
using a recent version of Red Hat Linux, the config file in
|
||||
contrib/redhat/sshd.pam should be more useful. Failure to install a
|
||||
valid PAM file may result in an inability to use password
|
||||
authentication. On HP-UX 11 and Solaris, the standard /etc/pam.conf
|
||||
configuration will work with sshd (sshd will match the other service
|
||||
name).
|
||||
|
||||
There are a few other options to the configure script:
|
||||
|
||||
--with-audit=[module] enable additional auditing via the specified module.
|
||||
Currently, drivers for "debug" (additional info via syslog) and "bsm"
|
||||
(Sun's Basic Security Module) are supported.
|
||||
|
||||
--with-pam enables PAM support. If PAM support is compiled in, it must
|
||||
also be enabled in sshd_config (refer to the UsePAM directive).
|
||||
|
||||
--with-prngd-socket=/some/file allows you to enable EGD or PRNGD
|
||||
support and to specify a PRNGd socket. Use this if your Unix lacks
|
||||
/dev/random and you don't want to use OpenSSH's builtin entropy
|
||||
collection support.
|
||||
|
||||
--with-prngd-port=portnum allows you to enable EGD or PRNGD support
|
||||
and to specify a EGD localhost TCP port. Use this if your Unix lacks
|
||||
/dev/random and you don't want to use OpenSSH's builtin entropy
|
||||
collection support.
|
||||
|
||||
--with-lastlog=FILE will specify the location of the lastlog file.
|
||||
./configure searches a few locations for lastlog, but may not find
|
||||
it if lastlog is installed in a different place.
|
||||
|
||||
--without-lastlog will disable lastlog support entirely.
|
||||
|
||||
--with-osfsia, --without-osfsia will enable or disable OSF1's Security
|
||||
Integration Architecture. The default for OSF1 machines is enable.
|
||||
|
||||
--with-skey=PATH will enable S/Key one time password support. You will
|
||||
need the S/Key libraries and header files installed for this to work.
|
||||
|
||||
--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny)
|
||||
support. You will need libwrap.a and tcpd.h installed.
|
||||
|
||||
--with-md5-passwords will enable the use of MD5 passwords. Enable this
|
||||
if your operating system uses MD5 passwords and the system crypt() does
|
||||
not support them directly (see the crypt(3/3c) man page). If enabled, the
|
||||
resulting binary will support both MD5 and traditional crypt passwords.
|
||||
|
||||
--with-utmpx enables utmpx support. utmpx support is automatic for
|
||||
some platforms.
|
||||
|
||||
--without-shadow disables shadow password support.
|
||||
|
||||
--with-ipaddr-display forces the use of a numeric IP address in the
|
||||
$DISPLAY environment variable. Some broken systems need this.
|
||||
|
||||
--with-default-path=PATH allows you to specify a default $PATH for sessions
|
||||
started by sshd. This replaces the standard path entirely.
|
||||
|
||||
--with-pid-dir=PATH specifies the directory in which the ssh.pid file is
|
||||
created.
|
||||
|
||||
--with-xauth=PATH specifies the location of the xauth binary
|
||||
|
||||
--with-ssl-dir=DIR allows you to specify where your OpenSSL libraries
|
||||
are installed.
|
||||
|
||||
--with-ssl-engine enables OpenSSL's (hardware) ENGINE support
|
||||
|
||||
--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to
|
||||
real (AF_INET) IPv4 addresses. Works around some quirks on Linux.
|
||||
|
||||
--with-opensc=DIR
|
||||
--with-sectok=DIR allows for OpenSC or sectok smartcard libraries to
|
||||
be used with OpenSSH. See 'README.smartcard' for more details.
|
||||
|
||||
If you need to pass special options to the compiler or linker, you
|
||||
can specify these as environment variables before running ./configure.
|
||||
For example:
|
||||
|
||||
CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure
|
||||
|
||||
3. Configuration
|
||||
----------------
|
||||
|
||||
The runtime configuration files are installed by in ${prefix}/etc or
|
||||
whatever you specified as your --sysconfdir (/usr/local/etc by default).
|
||||
|
||||
The default configuration should be instantly usable, though you should
|
||||
review it to ensure that it matches your security requirements.
|
||||
|
||||
To generate a host key, run "make host-key". Alternately you can do so
|
||||
manually using the following commands:
|
||||
|
||||
ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N ""
|
||||
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N ""
|
||||
ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N ""
|
||||
|
||||
Replacing /etc/ssh with the correct path to the configuration directory.
|
||||
(${prefix}/etc or whatever you specified with --sysconfdir during
|
||||
configuration)
|
||||
|
||||
If you have configured OpenSSH with EGD support, ensure that EGD is
|
||||
running and has collected some Entropy.
|
||||
|
||||
For more information on configuration, please refer to the manual pages
|
||||
for sshd, ssh and ssh-agent.
|
||||
|
||||
4. (Optional) Send survey
|
||||
-------------------------
|
||||
|
||||
$ make survey
|
||||
[check the contents of the file "survey" to ensure there's no information
|
||||
that you consider sensitive]
|
||||
$ make send-survey
|
||||
|
||||
This will send configuration information for the currently configured
|
||||
host to a survey address. This will help determine which configurations
|
||||
are actually in use, and what valid combinations of configure options
|
||||
exist. The raw data is available only to the OpenSSH developers, however
|
||||
summary data may be published.
|
||||
|
||||
5. Problems?
|
||||
------------
|
||||
|
||||
If you experience problems compiling, installing or running OpenSSH.
|
||||
Please refer to the "reporting bugs" section of the webpage at
|
||||
http://www.openssh.com/
|
||||
|
||||
|
||||
$Id: INSTALL,v 1.76 2006/09/17 12:55:52 dtucker Exp $
|
@ -1,337 +0,0 @@
|
||||
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
|
||||
The SCO Group
|
||||
|
||||
* 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
|
||||
Constantin S. Svintsoff
|
||||
|
||||
* 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
|
||||
Reyk Floeter
|
||||
Chad Mynhier
|
||||
|
||||
* 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 $
|
@ -1,14 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.11 2002/05/23 19:24:30 markus Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
|
||||
ssh-keysign ssh-keyscan sftp scard
|
||||
|
||||
distribution:
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \
|
||||
${DESTDIR}/etc/ssh/ssh_config
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \
|
||||
${DESTDIR}/etc/ssh/sshd_config
|
||||
|
||||
.include <bsd.subdir.mk>
|
@ -1,438 +0,0 @@
|
||||
# $Id: Makefile.in,v 1.283 2006/10/23 21:44:47 tim Exp $
|
||||
|
||||
# uncomment if you run a non bourne compatable shell. Ie. csh
|
||||
#SHELL = @SH@
|
||||
|
||||
AUTORECONF=autoreconf
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
bindir=@bindir@
|
||||
sbindir=@sbindir@
|
||||
libexecdir=@libexecdir@
|
||||
datadir=@datadir@
|
||||
datarootdir=@datarootdir@
|
||||
mandir=@mandir@
|
||||
mansubdir=@mansubdir@
|
||||
sysconfdir=@sysconfdir@
|
||||
piddir=@piddir@
|
||||
srcdir=@srcdir@
|
||||
top_srcdir=@top_srcdir@
|
||||
|
||||
DESTDIR=
|
||||
VPATH=@srcdir@
|
||||
SSH_PROGRAM=@bindir@/ssh
|
||||
ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass
|
||||
SFTP_SERVER=$(libexecdir)/sftp-server
|
||||
SSH_KEYSIGN=$(libexecdir)/ssh-keysign
|
||||
RAND_HELPER=$(libexecdir)/ssh-rand-helper
|
||||
PRIVSEP_PATH=@PRIVSEP_PATH@
|
||||
SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@
|
||||
STRIP_OPT=@STRIP_OPT@
|
||||
|
||||
PATHS= -DSSHDIR=\"$(sysconfdir)\" \
|
||||
-D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \
|
||||
-D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \
|
||||
-D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \
|
||||
-D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \
|
||||
-D_PATH_SSH_PIDDIR=\"$(piddir)\" \
|
||||
-D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \
|
||||
-DSSH_RAND_HELPER=\"$(RAND_HELPER)\"
|
||||
|
||||
CC=@CC@
|
||||
LD=@LD@
|
||||
CFLAGS=@CFLAGS@
|
||||
CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
|
||||
LIBS=@LIBS@
|
||||
LIBSELINUX=@LIBSELINUX@
|
||||
SSHDLIBS=@SSHDLIBS@
|
||||
LIBEDIT=@LIBEDIT@
|
||||
LIBPAM=@LIBPAM@
|
||||
LIBWRAP=@LIBWRAP@
|
||||
AR=@AR@
|
||||
AWK=@AWK@
|
||||
RANLIB=@RANLIB@
|
||||
INSTALL=@INSTALL@
|
||||
PERL=@PERL@
|
||||
SED=@SED@
|
||||
ENT=@ENT@
|
||||
XAUTH_PATH=@XAUTH_PATH@
|
||||
LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@
|
||||
EXEEXT=@EXEEXT@
|
||||
|
||||
INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
|
||||
INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
|
||||
|
||||
TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
|
||||
|
||||
LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
|
||||
canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
|
||||
cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
|
||||
compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
|
||||
log.o match.o md-sha256.o moduli.o nchan.o packet.o \
|
||||
readpass.o rsa.o ttymodes.o xmalloc.o \
|
||||
atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
|
||||
kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
|
||||
entropy.o scard-opensc.o gss-genr.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
sshconnect.o sshconnect1.o sshconnect2.o
|
||||
|
||||
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
|
||||
sshpty.o sshlogin.o servconf.o serverloop.o \
|
||||
auth.o auth1.o auth2.o auth-options.o session.o \
|
||||
auth-chall.o auth2-chall.o groupaccess.o \
|
||||
auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
|
||||
auth2-none.o auth2-passwd.o auth2-pubkey.o \
|
||||
monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
|
||||
auth-krb5.o \
|
||||
auth2-gss.o gss-serv.o gss-serv-krb5.o \
|
||||
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
|
||||
audit.o audit-bsm.o platform.o
|
||||
|
||||
MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
|
||||
MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
|
||||
MANTYPE = @MANTYPE@
|
||||
|
||||
CONFIGFILES=sshd_config.out ssh_config.out moduli.out
|
||||
CONFIGFILES_IN=sshd_config ssh_config moduli
|
||||
|
||||
PATHSUBS = \
|
||||
-e 's|/etc/ssh/ssh_prng_cmds|$(sysconfdir)/ssh_prng_cmds|g' \
|
||||
-e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \
|
||||
-e 's|/etc/ssh/ssh_known_hosts|$(sysconfdir)/ssh_known_hosts|g' \
|
||||
-e 's|/etc/ssh/sshd_config|$(sysconfdir)/sshd_config|g' \
|
||||
-e 's|/usr/libexec|$(libexecdir)|g' \
|
||||
-e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \
|
||||
-e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \
|
||||
-e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
|
||||
-e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
|
||||
-e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \
|
||||
-e 's|/etc/ssh/sshrc|$(sysconfdir)/sshrc|g' \
|
||||
-e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \
|
||||
-e 's|/var/empty|$(PRIVSEP_PATH)|g' \
|
||||
-e 's|/usr/bin:/bin:/usr/sbin:/sbin|@user_path@|g'
|
||||
|
||||
FIXPATHSCMD = $(SED) $(PATHSUBS)
|
||||
|
||||
all: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS)
|
||||
|
||||
$(LIBSSH_OBJS): Makefile.in config.h
|
||||
$(SSHOBJS): Makefile.in config.h
|
||||
$(SSHDOBJS): Makefile.in config.h
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
LIBCOMPAT=openbsd-compat/libopenbsd-compat.a
|
||||
$(LIBCOMPAT): always
|
||||
(cd openbsd-compat && $(MAKE))
|
||||
always:
|
||||
|
||||
libssh.a: $(LIBSSH_OBJS)
|
||||
$(AR) rv $@ $(LIBSSH_OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
|
||||
$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS)
|
||||
$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBSELINUX) $(SSHDLIBS) $(LIBS)
|
||||
|
||||
scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
|
||||
$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
|
||||
$(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o
|
||||
$(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
|
||||
$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
|
||||
$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
|
||||
$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o
|
||||
$(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
|
||||
$(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
|
||||
|
||||
ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
|
||||
$(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
|
||||
|
||||
# test driver for the loginrec code - not built by default
|
||||
logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o
|
||||
$(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS)
|
||||
|
||||
$(MANPAGES): $(MANPAGES_IN)
|
||||
if test "$(MANTYPE)" = "cat"; then \
|
||||
manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \
|
||||
else \
|
||||
manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \
|
||||
fi; \
|
||||
if test "$(MANTYPE)" = "man"; then \
|
||||
$(FIXPATHSCMD) $${manpage} | $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \
|
||||
else \
|
||||
$(FIXPATHSCMD) $${manpage} > $@; \
|
||||
fi
|
||||
|
||||
$(CONFIGFILES): $(CONFIGFILES_IN)
|
||||
conffile=`echo $@ | sed 's/.out$$//'`; \
|
||||
$(FIXPATHSCMD) $(srcdir)/$${conffile} > $@
|
||||
|
||||
ssh_prng_cmds.out: ssh_prng_cmds
|
||||
if test ! -z "$(INSTALL_SSH_PRNG_CMDS)"; then \
|
||||
$(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \
|
||||
fi
|
||||
|
||||
# fake rule to stop make trying to compile moduli.o into a binary "moduli.o"
|
||||
moduli:
|
||||
echo
|
||||
|
||||
clean: regressclean
|
||||
rm -f *.o *.a $(TARGETS) logintest config.cache config.log
|
||||
rm -f *.out core survey
|
||||
(cd openbsd-compat && $(MAKE) clean)
|
||||
|
||||
distclean: regressclean
|
||||
rm -f *.o *.a $(TARGETS) logintest config.cache config.log
|
||||
rm -f *.out core opensshd.init openssh.xml
|
||||
rm -f Makefile buildpkg.sh config.h config.status ssh_prng_cmds
|
||||
rm -f survey.sh openbsd-compat/regress/Makefile *~
|
||||
rm -rf autom4te.cache
|
||||
(cd openbsd-compat && $(MAKE) distclean)
|
||||
(cd scard && $(MAKE) distclean)
|
||||
if test -d pkg ; then \
|
||||
rm -fr pkg ; \
|
||||
fi
|
||||
|
||||
veryclean: distclean
|
||||
rm -f configure config.h.in *.0
|
||||
|
||||
mrproper: veryclean
|
||||
|
||||
realclean: veryclean
|
||||
|
||||
catman-do:
|
||||
@for f in $(MANPAGES_IN) ; do \
|
||||
base=`echo $$f | sed 's/\..*$$//'` ; \
|
||||
echo "$$f -> $$base.0" ; \
|
||||
nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \
|
||||
>$$base.0 ; \
|
||||
done
|
||||
|
||||
distprep: catman-do
|
||||
$(AUTORECONF)
|
||||
-rm -rf autom4te.cache
|
||||
(cd scard && $(MAKE) -f Makefile.in distprep)
|
||||
|
||||
install: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files install-sysconf host-key check-config
|
||||
install-nokeys: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files install-sysconf
|
||||
install-nosysconf: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files
|
||||
|
||||
check-config:
|
||||
-$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
|
||||
|
||||
scard-install:
|
||||
(cd scard && $(MAKE) DESTDIR=$(DESTDIR) install)
|
||||
|
||||
install-files: scard-install
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(sbindir)
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(datadir)
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)5
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir)
|
||||
(umask 022 ; $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH))
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh $(DESTDIR)$(bindir)/ssh
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) scp $(DESTDIR)$(bindir)/scp
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-add $(DESTDIR)$(bindir)/ssh-add
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-agent $(DESTDIR)$(bindir)/ssh-agent
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sshd $(DESTDIR)$(sbindir)/sshd
|
||||
if test ! -z "$(INSTALL_SSH_RAND_HELPER)" ; then \
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) ssh-rand-helper $(DESTDIR)$(libexecdir)/ssh-rand-helper ; \
|
||||
fi
|
||||
$(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN)
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp
|
||||
$(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER)
|
||||
$(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
||||
$(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
|
||||
$(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
|
||||
$(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
|
||||
$(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
|
||||
$(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
|
||||
$(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5
|
||||
$(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5
|
||||
$(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
|
||||
if [ ! -z "$(INSTALL_SSH_RAND_HELPER)" ]; then \
|
||||
$(INSTALL) -m 644 ssh-rand-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8 ; \
|
||||
fi
|
||||
$(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
|
||||
$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
|
||||
$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
|
||||
-rm -f $(DESTDIR)$(bindir)/slogin
|
||||
ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
|
||||
ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
|
||||
|
||||
install-sysconf:
|
||||
if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
|
||||
$(srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir); \
|
||||
fi
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \
|
||||
$(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \
|
||||
fi
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \
|
||||
$(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \
|
||||
fi
|
||||
@if [ -f ssh_prng_cmds ] && [ ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \
|
||||
if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds ] ; then \
|
||||
$(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_prng_cmds already exists, install will not overwrite"; \
|
||||
fi ; \
|
||||
fi
|
||||
@if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \
|
||||
if [ -f $(DESTDIR)$(sysconfdir)/primes ]; then \
|
||||
echo "moving $(DESTDIR)$(sysconfdir)/primes to $(DESTDIR)$(sysconfdir)/moduli"; \
|
||||
mv "$(DESTDIR)$(sysconfdir)/primes" "$(DESTDIR)$(sysconfdir)/moduli"; \
|
||||
else \
|
||||
$(INSTALL) -m 644 moduli.out $(DESTDIR)$(sysconfdir)/moduli; \
|
||||
fi ; \
|
||||
else \
|
||||
echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \
|
||||
fi
|
||||
|
||||
host-key: ssh-keygen$(EXEEXT)
|
||||
@if [ -z "$(DESTDIR)" ] ; then \
|
||||
if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \
|
||||
fi ; \
|
||||
if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key ] ; then \
|
||||
echo "$(DESTDIR)$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \
|
||||
else \
|
||||
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ; \
|
||||
fi ; \
|
||||
fi ;
|
||||
|
||||
host-key-force: ssh-keygen$(EXEEXT)
|
||||
./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""
|
||||
./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N ""
|
||||
./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N ""
|
||||
|
||||
uninstallall: uninstall
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/ssh_config
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/sshd_config
|
||||
-rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds
|
||||
-rmdir $(DESTDIR)$(sysconfdir)
|
||||
-rmdir $(DESTDIR)$(bindir)
|
||||
-rmdir $(DESTDIR)$(sbindir)
|
||||
-rmdir $(DESTDIR)$(mandir)/$(mansubdir)1
|
||||
-rmdir $(DESTDIR)$(mandir)/$(mansubdir)8
|
||||
-rmdir $(DESTDIR)$(mandir)
|
||||
-rmdir $(DESTDIR)$(libexecdir)
|
||||
|
||||
uninstall:
|
||||
-rm -f $(DESTDIR)$(bindir)/slogin
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT)
|
||||
-rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(RAND_HELPER)$(EXEEXT)
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
|
||||
-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
|
||||
|
||||
tests: $(TARGETS)
|
||||
BUILDDIR=`pwd`; \
|
||||
[ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \
|
||||
[ -f `pwd`/regress/Makefile ] || \
|
||||
ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile ; \
|
||||
TEST_SHELL="@TEST_SHELL@"; \
|
||||
TEST_SSH_SSH="$${BUILDDIR}/ssh"; \
|
||||
TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \
|
||||
TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \
|
||||
TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \
|
||||
TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \
|
||||
TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \
|
||||
TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \
|
||||
TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \
|
||||
cd $(srcdir)/regress || exit $$?; \
|
||||
$(MAKE) \
|
||||
.OBJDIR="$${BUILDDIR}/regress" \
|
||||
.CURDIR="`pwd`" \
|
||||
BUILDDIR="$${BUILDDIR}" \
|
||||
OBJ="$${BUILDDIR}/regress/" \
|
||||
PATH="$${BUILDDIR}:$${PATH}" \
|
||||
TEST_SHELL="$${TEST_SHELL}" \
|
||||
TEST_SSH_SSH="$${TEST_SSH_SSH}" \
|
||||
TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \
|
||||
TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \
|
||||
TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \
|
||||
TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \
|
||||
TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \
|
||||
TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \
|
||||
TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \
|
||||
EXEEXT="$(EXEEXT)" \
|
||||
$@
|
||||
|
||||
compat-tests: $(LIBCOMPAT)
|
||||
(cd openbsd-compat/regress && $(MAKE))
|
||||
|
||||
regressclean:
|
||||
if [ -f regress/Makefile ] && [ -r regress/Makefile ]; then \
|
||||
(cd regress && $(MAKE) clean) \
|
||||
fi
|
||||
|
||||
survey: survey.sh ssh
|
||||
@$(SHELL) ./survey.sh > survey
|
||||
@echo 'The survey results have been placed in the file "survey" in the'
|
||||
@echo 'current directory. Please review the file then send with'
|
||||
@echo '"make send-survey".'
|
||||
|
||||
send-survey: survey
|
||||
mail portable-survey@mindrot.org <survey
|
||||
|
||||
package: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS)
|
||||
if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \
|
||||
sh buildpkg.sh; \
|
||||
fi
|
||||
|
@ -1,26 +0,0 @@
|
||||
# $OpenBSD: Makefile.inc,v 1.23 2002/03/06 00:23:27 markus Exp $
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/..
|
||||
|
||||
CDIAGFLAGS= -Wall
|
||||
#CDIAGFLAGS+= -Werror
|
||||
CDIAGFLAGS+= -Wpointer-arith
|
||||
CDIAGFLAGS+= -Wno-uninitialized
|
||||
#CDIAGFLAGS+= -Wstrict-prototypes
|
||||
CDIAGFLAGS+= -Wmissing-prototypes
|
||||
CDIAGFLAGS+= -Wunused
|
||||
|
||||
#DEBUG=-g
|
||||
|
||||
#CFLAGS+= -DSMARTCARD
|
||||
#LDADD+= -lsectok
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
|
||||
.if exists(${.CURDIR}/../lib/${__objdir})
|
||||
LDADD+= -L${.CURDIR}/../lib/${__objdir} -lssh
|
||||
DPADD+= ${.CURDIR}/../lib/${__objdir}/libssh.a
|
||||
.else
|
||||
LDADD+= -L${.CURDIR}/../lib -lssh
|
||||
DPADD+= ${.CURDIR}/../lib/libssh.a
|
||||
.endif
|
@ -1,168 +0,0 @@
|
||||
[Note: This file has not been updated for OpenSSH versions after
|
||||
OpenSSH-1.2 and should be considered OBSOLETE. It has been left in
|
||||
the distribution because some of its information may still be useful
|
||||
to developers.]
|
||||
|
||||
This document is intended for those who wish to read the ssh source
|
||||
code. This tries to give an overview of the structure of the code.
|
||||
|
||||
Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>
|
||||
Updated 17 Nov 1995.
|
||||
Updated 19 Oct 1999 for OpenSSH-1.2
|
||||
Updated 20 May 2001 note obsolete for > OpenSSH-1.2
|
||||
|
||||
The software consists of ssh (client), sshd (server), scp, sdist, and
|
||||
the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and
|
||||
make-ssh-known-hosts. The main program for each of these is in a .c
|
||||
file with the same name.
|
||||
|
||||
There are some subsystems/abstractions that are used by a number of
|
||||
these programs.
|
||||
|
||||
Buffer manipulation routines
|
||||
|
||||
- These provide an arbitrary size buffer, where data can be appended.
|
||||
Data can be consumed from either end. The code is used heavily
|
||||
throughout ssh. The basic buffer manipulation functions are in
|
||||
buffer.c (header buffer.h), and additional code to manipulate specific
|
||||
data types is in bufaux.c.
|
||||
|
||||
Compression Library
|
||||
|
||||
- Ssh uses the GNU GZIP compression library (ZLIB).
|
||||
|
||||
Encryption/Decryption
|
||||
|
||||
- Ssh contains several encryption algorithms. These are all
|
||||
accessed through the cipher.h interface. The interface code is
|
||||
in cipher.c, and the implementations are in libc.
|
||||
|
||||
Multiple Precision Integer Library
|
||||
|
||||
- Uses the SSLeay BIGNUM sublibrary.
|
||||
|
||||
Random Numbers
|
||||
|
||||
- Uses arc4random() and such.
|
||||
|
||||
RSA key generation, encryption, decryption
|
||||
|
||||
- Ssh uses the RSA routines in libssl.
|
||||
|
||||
RSA key files
|
||||
|
||||
- RSA keys are stored in files with a special format. The code to
|
||||
read/write these files is in authfile.c. The files are normally
|
||||
encrypted with a passphrase. The functions to read passphrases
|
||||
are in readpass.c (the same code is used to read passwords).
|
||||
|
||||
Binary packet protocol
|
||||
|
||||
- The ssh binary packet protocol is implemented in packet.c. The
|
||||
code in packet.c does not concern itself with packet types or their
|
||||
execution; it contains code to build packets, to receive them and
|
||||
extract data from them, and the code to compress and/or encrypt
|
||||
packets. CRC code comes from crc32.c.
|
||||
|
||||
- The code in packet.c calls the buffer manipulation routines
|
||||
(buffer.c, bufaux.c), compression routines (compress.c, zlib),
|
||||
and the encryption routines.
|
||||
|
||||
X11, TCP/IP, and Agent forwarding
|
||||
|
||||
- Code for various types of channel forwarding is in channels.c.
|
||||
The file defines a generic framework for arbitrary communication
|
||||
channels inside the secure channel, and uses this framework to
|
||||
implement X11 forwarding, TCP/IP forwarding, and authentication
|
||||
agent forwarding.
|
||||
The new, Protocol 1.5, channel close implementation is in nchan.c
|
||||
|
||||
Authentication agent
|
||||
|
||||
- Code to communicate with the authentication agent is in authfd.c.
|
||||
|
||||
Authentication methods
|
||||
|
||||
- Code for various authentication methods resides in auth-*.c
|
||||
(auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This
|
||||
code is linked into the server. The routines also manipulate
|
||||
known hosts files using code in hostfile.c. Code in canohost.c
|
||||
is used to retrieve the canonical host name of the remote host.
|
||||
Code in match.c is used to match host names.
|
||||
|
||||
- In the client end, authentication code is in sshconnect.c. It
|
||||
reads Passwords/passphrases using code in readpass.c. It reads
|
||||
RSA key files with authfile.c. It communicates the
|
||||
authentication agent using authfd.c.
|
||||
|
||||
The ssh client
|
||||
|
||||
- The client main program is in ssh.c. It first parses arguments
|
||||
and reads configuration (readconf.c), then calls ssh_connect (in
|
||||
sshconnect.c) to open a connection to the server (possibly via a
|
||||
proxy), and performs authentication (ssh_login in sshconnect.c).
|
||||
It then makes any pty, forwarding, etc. requests. It may call
|
||||
code in ttymodes.c to encode current tty modes. Finally it
|
||||
calls client_loop in clientloop.c. This does the real work for
|
||||
the session.
|
||||
|
||||
- The client is suid root. It tries to temporarily give up this
|
||||
rights while reading the configuration data. The root
|
||||
privileges are only used to make the connection (from a
|
||||
privileged socket). Any extra privileges are dropped before
|
||||
calling ssh_login.
|
||||
|
||||
Pseudo-tty manipulation and tty modes
|
||||
|
||||
- Code to allocate and use a pseudo tty is in pty.c. Code to
|
||||
encode and set terminal modes is in ttymodes.c.
|
||||
|
||||
Logging in (updating utmp, lastlog, etc.)
|
||||
|
||||
- The code to do things that are done when a user logs in are in
|
||||
login.c. This includes things such as updating the utmp, wtmp,
|
||||
and lastlog files. Some of the code is in sshd.c.
|
||||
|
||||
Writing to the system log and terminal
|
||||
|
||||
- The programs use the functions fatal(), log(), debug(), error()
|
||||
in many places to write messages to system log or user's
|
||||
terminal. The implementation that logs to system log is in
|
||||
log-server.c; it is used in the server program. The other
|
||||
programs use an implementation that sends output to stderr; it
|
||||
is in log-client.c. The definitions are in ssh.h.
|
||||
|
||||
The sshd server (daemon)
|
||||
|
||||
- The sshd daemon starts by processing arguments and reading the
|
||||
configuration file (servconf.c). It then reads the host key,
|
||||
starts listening for connections, and generates the server key.
|
||||
The server key will be regenerated every hour by an alarm.
|
||||
|
||||
- When the server receives a connection, it forks, disables the
|
||||
regeneration alarm, and starts communicating with the client.
|
||||
They first perform identification string exchange, then
|
||||
negotiate encryption, then perform authentication, preparatory
|
||||
operations, and finally the server enters the normal session
|
||||
mode by calling server_loop in serverloop.c. This does the real
|
||||
work, calling functions in other modules.
|
||||
|
||||
- The code for the server is in sshd.c. It contains a lot of
|
||||
stuff, including:
|
||||
- server main program
|
||||
- waiting for connections
|
||||
- processing new connection
|
||||
- authentication
|
||||
- preparatory operations
|
||||
- building up the execution environment for the user program
|
||||
- starting the user program.
|
||||
|
||||
Auxiliary files
|
||||
|
||||
- There are several other files in the distribution that contain
|
||||
various auxiliary routines:
|
||||
ssh.h the main header file for ssh (various definitions)
|
||||
uidswap.c uid-swapping
|
||||
xmalloc.c "safe" malloc routines
|
||||
|
||||
$OpenBSD: OVERVIEW,v 1.11 2006/08/03 03:34:41 deraadt Exp $
|
@ -1,65 +0,0 @@
|
||||
See http://www.openssh.com/txt/release-4.5 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.openpam.org
|
||||
http://www.kernel.org/pub/linux/libs/pam/
|
||||
(PAM also 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.64 2006/11/07 12:25:45 dtucker Exp $
|
@ -1,47 +0,0 @@
|
||||
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 $
|
@ -1,44 +0,0 @@
|
||||
$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $
|
||||
|
||||
howto:
|
||||
1) generate server key:
|
||||
$ ssh-keygen -d -f /etc/ssh_host_dsa_key -N ''
|
||||
2) enable ssh2:
|
||||
server: add 'Protocol 2,1' to /etc/sshd_config
|
||||
client: ssh -o 'Protocol 2,1', or add to .ssh/config
|
||||
3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2)
|
||||
interop w/ ssh.com dsa-keys:
|
||||
ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2
|
||||
and vice versa
|
||||
ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub
|
||||
echo Key mykey.pub >> ~/.ssh2/authorization
|
||||
|
||||
works:
|
||||
secsh-transport: works w/o rekey
|
||||
proposal exchange, i.e. different enc/mac/comp per direction
|
||||
encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc
|
||||
mac: hmac-md5, hmac-sha1, (hmac-ripemd160)
|
||||
compression: zlib, none
|
||||
secsh-userauth: passwd and pubkey with DSA
|
||||
secsh-connection: pty+shell or command, flow control works (window adjust)
|
||||
tcp-forwarding: -L works, -R incomplete
|
||||
x11-fwd
|
||||
dss/dsa: host key database in ~/.ssh/known_hosts2
|
||||
client interops w/ sshd2, lshd
|
||||
server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp)
|
||||
server supports multiple concurrent sessions (e.g. with SSH.com Windows client)
|
||||
todo:
|
||||
re-keying
|
||||
secsh-connection features:
|
||||
tcp-forwarding, agent-fwd
|
||||
auth other than passwd, and DSA-pubkey:
|
||||
keyboard-interactive, (PGP-pubkey?)
|
||||
config
|
||||
server-auth w/ old host-keys
|
||||
cleanup
|
||||
advanced key storage?
|
||||
keynote
|
||||
sftp
|
||||
|
||||
-markus
|
||||
$Date: 2000/05/07 18:30:03 $
|
@ -1,70 +0,0 @@
|
||||
This file contains notes about OpenSSH on specific platforms.
|
||||
|
||||
AIX
|
||||
---
|
||||
As of OpenSSH 3.8p1, sshd will now honour an accounts password expiry
|
||||
settings, where previously it did not. Because of this, it's possible for
|
||||
sites that have used OpenSSH's sshd exclusively to have accounts which
|
||||
have passwords expired longer than the inactive time (ie the "Weeks between
|
||||
password EXPIRATION and LOCKOUT" setting in SMIT or the maxexpired
|
||||
chuser attribute).
|
||||
|
||||
Accounts in this state must have their passwords reset manually by the
|
||||
administrator. As a precaution, it is recommended that the administrative
|
||||
passwords be reset before upgrading from OpenSSH <3.8.
|
||||
|
||||
As of OpenSSH 4.0, configure will attempt to detect if your version
|
||||
and maintenance level of AIX has a working getaddrinfo, and will use it
|
||||
if found. This will enable IPv6 support. If for some reason configure
|
||||
gets it wrong, or if you want to build binaries to work on earlier MLs
|
||||
than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS
|
||||
to force the previous IPv4-only behaviour.
|
||||
|
||||
IPv6 known to work: 5.1ML7 5.2ML2 5.2ML5
|
||||
IPv6 known broken: 4.3.3ML11 5.1ML4
|
||||
|
||||
Cygwin
|
||||
------
|
||||
To build on Cygwin, OpenSSH requires the following packages:
|
||||
gcc, gcc-mingw-core, mingw-runtime, binutils, make, openssl,
|
||||
openssl-devel, zlib, minres, minires-devel.
|
||||
|
||||
|
||||
Darwin and MacOS X
|
||||
------------------
|
||||
Darwin does not provide a tun(4) driver required for OpenSSH-based
|
||||
virtual private networks. The BSD manpage still exists, but the driver
|
||||
has been removed in recent releases of Darwin and MacOS X.
|
||||
|
||||
Nevertheless, tunnel support is known to work with Darwin 8 and
|
||||
MacOS X 10.4 in Point-to-Point (Layer 3) and Ethernet (Layer 2) mode
|
||||
using a third party driver. More information is available at:
|
||||
http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
|
||||
|
||||
|
||||
Solaris
|
||||
-------
|
||||
If you enable BSM auditing on Solaris, you need to update audit_event(4)
|
||||
for praudit(1m) to give sensible output. The following line needs to be
|
||||
added to /etc/security/audit_event:
|
||||
|
||||
32800:AUE_openssh:OpenSSH login:lo
|
||||
|
||||
The BSM audit event range available for third party TCB applications is
|
||||
32768 - 65535. Event number 32800 has been choosen for AUE_openssh.
|
||||
There is no official registry of 3rd party event numbers, so if this
|
||||
number is already in use on your system, you may change it at build time
|
||||
by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding.
|
||||
|
||||
|
||||
Platforms using PAM
|
||||
-------------------
|
||||
As of OpenSSH 4.3p1, sshd will no longer check /etc/nologin itself when
|
||||
PAM is enabled. To maintain existing behaviour, pam_nologin should be
|
||||
added to sshd's session stack which will prevent users from starting shell
|
||||
sessions. Alternatively, pam_nologin can be added to either the auth or
|
||||
account stacks which will prevent authentication entirely, but will still
|
||||
return the output from pam_nologin to the client.
|
||||
|
||||
|
||||
$Id: README.platform,v 1.7 2006/06/23 11:05:13 dtucker Exp $
|
@ -1,63 +0,0 @@
|
||||
Privilege separation, or privsep, is method in OpenSSH by which
|
||||
operations that require root privilege are performed by a separate
|
||||
privileged monitor process. Its purpose is to prevent privilege
|
||||
escalation by containing corruption to an unprivileged process.
|
||||
More information is available at:
|
||||
http://www.citi.umich.edu/u/provos/ssh/privsep.html
|
||||
|
||||
Privilege separation is now enabled by default; see the
|
||||
UsePrivilegeSeparation option in sshd_config(5).
|
||||
|
||||
On systems which lack mmap or anonymous (MAP_ANON) memory mapping,
|
||||
compression must be disabled in order for privilege separation to
|
||||
function.
|
||||
|
||||
When privsep is enabled, during the pre-authentication phase sshd will
|
||||
chroot(2) to "/var/empty" and change its privileges to the "sshd" user
|
||||
and its primary group. sshd is a pseudo-account that should not be
|
||||
used by other daemons, and must be locked and should contain a
|
||||
"nologin" or invalid shell.
|
||||
|
||||
You should do something like the following to prepare the privsep
|
||||
preauth environment:
|
||||
|
||||
# mkdir /var/empty
|
||||
# chown root:sys /var/empty
|
||||
# chmod 755 /var/empty
|
||||
# groupadd sshd
|
||||
# useradd -g sshd -c 'sshd privsep' -d /var/empty -s /bin/false sshd
|
||||
|
||||
/var/empty should not contain any files.
|
||||
|
||||
configure supports the following options to change the default
|
||||
privsep user and chroot directory:
|
||||
|
||||
--with-privsep-path=xxx Path for privilege separation chroot
|
||||
--with-privsep-user=user Specify non-privileged user for privilege separation
|
||||
|
||||
Privsep requires operating system support for file descriptor passing.
|
||||
Compression will be disabled on systems without a working mmap MAP_ANON.
|
||||
|
||||
PAM-enabled OpenSSH is known to function with privsep on AIX, FreeBSD,
|
||||
HP-UX (including Trusted Mode), Linux, NetBSD and Solaris.
|
||||
|
||||
On Cygwin, Tru64 Unix, OpenServer, and Unicos only the pre-authentication
|
||||
part of privsep is supported. Post-authentication privsep is disabled
|
||||
automatically (so you won't see the additional process mentioned below).
|
||||
|
||||
Note that for a normal interactive login with a shell, enabling privsep
|
||||
will require 1 additional process per login session.
|
||||
|
||||
Given the following process listing (from HP-UX):
|
||||
|
||||
UID PID PPID C STIME TTY TIME COMMAND
|
||||
root 1005 1 0 10:45:17 ? 0:08 /opt/openssh/sbin/sshd -u0
|
||||
root 6917 1005 0 15:19:16 ? 0:00 sshd: stevesk [priv]
|
||||
stevesk 6919 6917 0 15:19:17 ? 0:03 sshd: stevesk@2
|
||||
stevesk 6921 6919 0 15:19:17 pts/2 0:00 -bash
|
||||
|
||||
process 1005 is the sshd process listening for new connections.
|
||||
process 6917 is the privileged monitor process, 6919 is the user owned
|
||||
sshd process and 6921 is the shell process.
|
||||
|
||||
$Id: README.privsep,v 1.16 2005/06/04 23:21:41 djm Exp $
|
@ -1,93 +0,0 @@
|
||||
How to use smartcards with OpenSSH?
|
||||
|
||||
OpenSSH contains experimental support for authentication using
|
||||
Cyberflex smartcards and TODOS card readers, in addition to the cards
|
||||
with PKCS#15 structure supported by OpenSC. To enable this you
|
||||
need to:
|
||||
|
||||
Using libsectok:
|
||||
|
||||
(1) enable sectok support in OpenSSH:
|
||||
|
||||
$ ./configure --with-sectok
|
||||
|
||||
(2) If you have used a previous version of ssh with your card, you
|
||||
must remove the old applet and keys.
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> junload Ssh.bin
|
||||
sectok> delete 0012
|
||||
sectok> delete sh
|
||||
sectok> quit
|
||||
|
||||
(3) load the Java Cardlet to the Cyberflex card and set card passphrase:
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> jload /usr/libdata/ssh/Ssh.bin
|
||||
sectok> setpass
|
||||
Enter new AUT0 passphrase:
|
||||
Re-enter passphrase:
|
||||
sectok> quit
|
||||
|
||||
Do not forget the passphrase. There is no way to
|
||||
recover if you do.
|
||||
|
||||
IMPORTANT WARNING: If you attempt to login with the
|
||||
wrong passphrase three times in a row, you will
|
||||
destroy your card.
|
||||
|
||||
(4) load a RSA key to the card:
|
||||
|
||||
$ ssh-keygen -f /path/to/rsakey -U 1
|
||||
(where 1 is the reader number, you can also try 0)
|
||||
|
||||
In spite of the name, this does not generate a key.
|
||||
It just loads an already existing key on to the card.
|
||||
|
||||
(5) Optional: If you don't want to use a card passphrase, change the
|
||||
acl on the private key file:
|
||||
|
||||
$ sectok
|
||||
sectok> login -d
|
||||
sectok> acl 0012 world: w
|
||||
world: w
|
||||
AUT0: w inval
|
||||
sectok> quit
|
||||
|
||||
If you do this, anyone who has access to your card
|
||||
can assume your identity. This is not recommended.
|
||||
|
||||
|
||||
Using OpenSC:
|
||||
|
||||
(1) install OpenSC:
|
||||
|
||||
Sources and instructions are available from
|
||||
http://www.opensc.org/
|
||||
|
||||
(2) enable OpenSC support in OpenSSH:
|
||||
|
||||
$ ./configure --with-opensc[=/path/to/opensc] [options]
|
||||
|
||||
(3) load a RSA key to the card:
|
||||
|
||||
Not supported yet.
|
||||
|
||||
|
||||
Common operations:
|
||||
|
||||
(1) tell the ssh client to use the card reader:
|
||||
|
||||
$ ssh -I 1 otherhost
|
||||
|
||||
(2) or tell the agent (don't forget to restart) to use the smartcard:
|
||||
|
||||
$ ssh-add -s 1
|
||||
|
||||
|
||||
-markus,
|
||||
Tue Jul 17 23:54:51 CEST 2001
|
||||
|
||||
$OpenBSD: README.smartcard,v 1.9 2003/11/21 11:57:02 djm Exp $
|
@ -1,132 +0,0 @@
|
||||
How to use OpenSSH-based virtual private networks
|
||||
-------------------------------------------------
|
||||
|
||||
OpenSSH contains support for VPN tunneling using the tun(4) network
|
||||
tunnel pseudo-device which is available on most platforms, either for
|
||||
layer 2 or 3 traffic.
|
||||
|
||||
The following brief instructions on how to use this feature use
|
||||
a network configuration specific to the OpenBSD operating system.
|
||||
|
||||
(1) Server: Enable support for SSH tunneling
|
||||
|
||||
To enable the ssh server to accept tunnel requests from the client, you
|
||||
have to add the following option to the ssh server configuration file
|
||||
(/etc/ssh/sshd_config):
|
||||
|
||||
PermitTunnel yes
|
||||
|
||||
Restart the server or send the hangup signal (SIGHUP) to let the server
|
||||
reread it's configuration.
|
||||
|
||||
(2) Server: Restrict client access and assign the tunnel
|
||||
|
||||
The OpenSSH server simply uses the file /root/.ssh/authorized_keys to
|
||||
restrict the client to connect to a specified tunnel and to
|
||||
automatically start the related interface configuration command. These
|
||||
settings are optional but recommended:
|
||||
|
||||
tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... reyk@openbsd.org
|
||||
|
||||
(3) Client: Configure the local network tunnel interface
|
||||
|
||||
Use the hostname.if(5) interface-specific configuration file to set up
|
||||
the network tunnel configuration with OpenBSD. For example, use the
|
||||
following configuration in /etc/hostname.tun0 to set up the layer 3
|
||||
tunnel on the client:
|
||||
|
||||
inet 192.168.5.1 255.255.255.252 192.168.5.2
|
||||
|
||||
OpenBSD also supports layer 2 tunneling over the tun device by adding
|
||||
the link0 flag:
|
||||
|
||||
inet 192.168.1.78 255.255.255.0 192.168.1.255 link0
|
||||
|
||||
Layer 2 tunnels can be used in combination with an Ethernet bridge(4)
|
||||
interface, like the following example for /etc/bridgename.bridge0:
|
||||
|
||||
add tun0
|
||||
add sis0
|
||||
up
|
||||
|
||||
(4) Client: Configure the OpenSSH client
|
||||
|
||||
To establish tunnel forwarding for connections to a specified
|
||||
remote host by default, use the following ssh client configuration for
|
||||
the privileged user (in /root/.ssh/config):
|
||||
|
||||
Host sshgateway
|
||||
Tunnel yes
|
||||
TunnelDevice 0:any
|
||||
PermitLocalCommand yes
|
||||
LocalCommand sh /etc/netstart tun0
|
||||
|
||||
A more complicated configuration is possible to establish a tunnel to
|
||||
a remote host which is not directly accessible by the client.
|
||||
The following example describes a client configuration to connect to
|
||||
the remote host over two ssh hops in between. It uses the OpenSSH
|
||||
ProxyCommand in combination with the nc(1) program to forward the final
|
||||
ssh tunnel destination over multiple ssh sessions.
|
||||
|
||||
Host access.somewhere.net
|
||||
User puffy
|
||||
Host dmzgw
|
||||
User puffy
|
||||
ProxyCommand ssh access.somewhere.net nc dmzgw 22
|
||||
Host sshgateway
|
||||
Tunnel Ethernet
|
||||
TunnelDevice 0:any
|
||||
PermitLocalCommand yes
|
||||
LocalCommand sh /etc/netstart tun0
|
||||
ProxyCommand ssh dmzgw nc sshgateway 22
|
||||
|
||||
The following network plan illustrates the previous configuration in
|
||||
combination with layer 2 tunneling and Ethernet bridging.
|
||||
|
||||
+--------+ ( ) +----------------------+
|
||||
| Client |------( Internet )-----| access.somewhere.net |
|
||||
+--------+ ( ) +----------------------+
|
||||
: 192.168.1.78 |
|
||||
:............................. +-------+
|
||||
Forwarded ssh connection : | dmzgw |
|
||||
Layer 2 tunnel : +-------+
|
||||
: |
|
||||
: |
|
||||
: +------------+
|
||||
:......| sshgateway |
|
||||
| +------------+
|
||||
--- real connection Bridge -> | +----------+
|
||||
... "virtual connection" [ X ]--------| somehost |
|
||||
[X] switch +----------+
|
||||
192.168.1.25
|
||||
|
||||
(5) Client: Connect to the server and establish the tunnel
|
||||
|
||||
Finally connect to the OpenSSH server to establish the tunnel by using
|
||||
the following command:
|
||||
|
||||
ssh sshgateway
|
||||
|
||||
It is also possible to tell the client to fork into the background after
|
||||
the connection has been successfully established:
|
||||
|
||||
ssh -f sshgateway true
|
||||
|
||||
Without the ssh configuration done in step (4), it is also possible
|
||||
to use the following command lines:
|
||||
|
||||
ssh -fw 0:1 sshgateway true
|
||||
ifconfig tun0 192.168.5.1 192.168.5.2 netmask 255.255.255.252
|
||||
|
||||
Using OpenSSH tunnel forwarding is a simple way to establish secure
|
||||
and ad hoc virtual private networks. Possible fields of application
|
||||
could be wireless networks or administrative VPN tunnels.
|
||||
|
||||
Nevertheless, ssh tunneling requires some packet header overhead and
|
||||
runs on top of TCP. It is still suggested to use the IP Security
|
||||
Protocol (IPSec) for robust and permanent VPN connections and to
|
||||
interconnect corporate networks.
|
||||
|
||||
Reyk Floeter
|
||||
|
||||
$OpenBSD: README.tun,v 1.4 2006/03/28 00:12:31 deraadt Exp $
|
File diff suppressed because it is too large
Load Diff
@ -1,86 +0,0 @@
|
||||
Documentation:
|
||||
|
||||
- Update the docs
|
||||
- Update README
|
||||
- Update INSTALL
|
||||
- Merge INSTALL & README.privsep
|
||||
|
||||
- Install FAQ?
|
||||
|
||||
- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it
|
||||
would be best to use them.
|
||||
|
||||
- Create a Documentation/ directory?
|
||||
|
||||
Programming:
|
||||
|
||||
- Grep for 'XXX' comments and fix
|
||||
|
||||
- Link order is incorrect for some systems using Kerberos 4 and AFS. Result
|
||||
is multiple inclusion of DES symbols. Holger Trapp
|
||||
<holger.trapp@hrz.tu-chemnitz.de> reports that changing the configure
|
||||
generated link order from:
|
||||
-lresolv -lkrb -lz -lnsl -lutil -lkafs -lkrb -ldes -lcrypto
|
||||
to:
|
||||
-lresolv -lkrb -lz -lnsl -lutil -lcrypto -lkafs -lkrb -ldes
|
||||
fixing the problem.
|
||||
|
||||
- Write a test program that calls stat() to search for EGD/PRNGd socket
|
||||
rather than use the (non-portable) "test -S".
|
||||
|
||||
- More platforms for for setproctitle() emulation (testing needed)
|
||||
|
||||
- Improve PAM ChallengeResponseAuthentication
|
||||
- Informational messages
|
||||
- Use different PAM service name for kbdint vs regular auth (suggest from
|
||||
Solar Designer)
|
||||
- Ability to select which ChallengeResponseAuthentications may be used
|
||||
and order to try them in e.g. "ChallengeResponseAuthentication skey, pam"
|
||||
|
||||
- Complete Tru64 SIA support
|
||||
- It looks like we could merge it into the password auth code to cut down
|
||||
on diff size. Maybe PAM password auth too?
|
||||
|
||||
- Finish integrating kernel-level auditing code for IRIX and SOLARIS
|
||||
(Gilbert.r.loomis@saic.com)
|
||||
|
||||
- 64-bit builds on HP-UX 11.X (stevesk@pobox.com):
|
||||
- utmp/wtmp get corrupted (something in loginrec?)
|
||||
- can't build with PAM (no 64-bit libpam yet)
|
||||
|
||||
Clean up configure/makefiles:
|
||||
- Clean up configure.ac - There are a few double #defined variables
|
||||
left to do. HAVE_LOGIN is one of them. Consider NOT looking for
|
||||
information in wtmpx or utmpx or any of that stuff if it's not detected
|
||||
from the start
|
||||
|
||||
- Replace the whole u_intXX_t evilness in acconfig.h with something better???
|
||||
- Do it in configure.ac
|
||||
|
||||
- Consider splitting the u_intXX_t test for sys/bitype.h into seperate test
|
||||
to allow people to (right/wrongfully) link against Bind directly.
|
||||
|
||||
- Consider splitting configure.ac into seperate files which do logically
|
||||
similar tests. E.g move all the type detection stuff into one file,
|
||||
entropy related stuff into another.
|
||||
|
||||
Packaging:
|
||||
- HP-UX: Provide DEPOT package scripts.
|
||||
(gilbert.r.loomis@saic.com)
|
||||
|
||||
PrivSep Issues:
|
||||
- mmap() issues.
|
||||
+ /dev/zero solution (Solaris)
|
||||
+ No/broken MAP_ANON (Irix)
|
||||
+ broken /dev/zero parse (Linux)
|
||||
- PAM
|
||||
+ See above PAM notes
|
||||
- AIX
|
||||
+ usrinfo() does not set TTY, but only required for legacy systems. Works
|
||||
with PrivSep.
|
||||
- OSF
|
||||
+ SIA is broken
|
||||
- Cygwin
|
||||
+ Privsep for Pre-auth only (no fd passing)
|
||||
|
||||
$Id: TODO,v 1.58 2004/12/06 11:40:11 dtucker Exp $
|
@ -1,95 +0,0 @@
|
||||
This document contains a description of portable OpenSSH's random
|
||||
number collection code. An alternate reading of this text could
|
||||
well be titled "Why I should pressure my system vendor to supply
|
||||
/dev/random in their OS".
|
||||
|
||||
Why is this important? OpenSSH depends on good, unpredictable numbers
|
||||
for generating keys, performing digital signatures and forming
|
||||
cryptographic challenges. If the random numbers that it uses are
|
||||
predictable, then the strength of the whole system is compromised.
|
||||
|
||||
A particularly pernicious problem arises with DSA keys (used by the
|
||||
ssh2 protocol). Performing a DSA signature (which is required for
|
||||
authentication), entails the use of a 160 bit random number. If an
|
||||
attacker can predict this number, then they can deduce your *private*
|
||||
key and impersonate you or your hosts.
|
||||
|
||||
If you are using the builtin random number support (configure will
|
||||
tell you if this is the case), then read this document in its entirety.
|
||||
Alternately, you can use Lutz Jaenicke's PRNGd - a small daemon which
|
||||
collects random numbers and makes them available by a socket.
|
||||
|
||||
Please also request that your OS vendor provides a kernel-based random
|
||||
number collector (/dev/random) in future versions of your operating
|
||||
systems by default.
|
||||
|
||||
On to the description...
|
||||
|
||||
The portable OpenSSH contains random number collection support for
|
||||
systems which lack a kernel entropy pool (/dev/random).
|
||||
|
||||
This collector (as of 3.1 and beyond) comes as an external application
|
||||
that allows the local admin to decide on how to implement entropy
|
||||
collection.
|
||||
|
||||
The default entropy collector operates by executing the programs listed
|
||||
in ($etcdir)/ssh_prng_cmds, reading their output and adding it to the
|
||||
PRNG supplied by OpenSSL (which is hash-based). It also stirs in the
|
||||
output of several system calls and timings from the execution of the
|
||||
programs that it runs.
|
||||
|
||||
The ssh_prng_cmds file also specifies a 'rate' for each program. This
|
||||
represents the number of bits of randomness per byte of output from
|
||||
the specified program.
|
||||
|
||||
The random number code will also read and save a seed file to
|
||||
~/.ssh/prng_seed. This contents of this file are added to the random
|
||||
number generator at startup. The goal here is to maintain as much
|
||||
randomness between sessions as possible.
|
||||
|
||||
The default entropy collection code has two main problems:
|
||||
|
||||
1. It is slow.
|
||||
|
||||
Executing each program in the list can take a large amount of time,
|
||||
especially on slower machines. Additionally some program can take a
|
||||
disproportionate time to execute.
|
||||
|
||||
Tuning the random helper can be done by running ./ssh-random-helper in
|
||||
very verbose mode ("-vvv") and identifying the commands that are taking
|
||||
excessive amounts of time or hanging altogher. Any problem commands can
|
||||
be modified or removed from ssh_prng_cmds.
|
||||
|
||||
The default entropy collector will timeout programs which take too long
|
||||
to execute, the actual timeout used can be adjusted with the
|
||||
--with-entropy-timeout configure option. OpenSSH will not try to
|
||||
re-execute programs which have not been found, have had a non-zero
|
||||
exit status or have timed out more than a couple of times.
|
||||
|
||||
2. Estimating the real 'rate' of program outputs is non-trivial
|
||||
|
||||
The shear volume of the task is problematic: there are currently
|
||||
around 50 commands in the ssh_prng_cmds list, portable OpenSSH
|
||||
supports at least 12 different OSs. That is already 600 sets of data
|
||||
to be analysed, without taking into account the numerous differences
|
||||
between versions of each OS.
|
||||
|
||||
On top of this, the different commands can produce varying amounts of
|
||||
usable data depending on how busy the machine is, how long it has been
|
||||
up and various other factors.
|
||||
|
||||
To make matters even more complex, some of the commands are reporting
|
||||
largely the same data as other commands (eg. the various "ps" calls).
|
||||
|
||||
|
||||
How to avoid the default entropy code?
|
||||
|
||||
The best way is to read the OpenSSL documentation and recompile OpenSSL
|
||||
to use prngd or egd. Some platforms (like earily solaris) have 3rd
|
||||
party /dev/random devices that can be also used for this task.
|
||||
|
||||
If you are forced to use ssh-rand-helper consider still downloading
|
||||
prngd/egd and configure OpenSSH using --with-prngd-port=xx or
|
||||
--with-prngd-socket=xx (refer to INSTALL for more information).
|
||||
|
||||
$Id: WARNING.RNG,v 1.8 2005/05/26 01:47:54 djm Exp $
|
86
crypto/openssh/aclocal.m4
vendored
86
crypto/openssh/aclocal.m4
vendored
@ -1,86 +0,0 @@
|
||||
dnl $Id: aclocal.m4,v 1.6 2005/09/19 16:33:39 tim Exp $
|
||||
dnl
|
||||
dnl OpenSSH-specific autoconf macros
|
||||
dnl
|
||||
|
||||
|
||||
dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol)
|
||||
dnl Does AC_EGREP_HEADER on 'header' for the string 'field'
|
||||
dnl If found, set 'symbol' to be defined. Cache the result.
|
||||
dnl TODO: This is not foolproof, better to compile and read from there
|
||||
AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [
|
||||
# look for field '$1' in header '$2'
|
||||
dnl This strips characters illegal to m4 from the header filename
|
||||
ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'`
|
||||
dnl
|
||||
ossh_varname="ossh_cv_$ossh_safe""_has_"$1
|
||||
AC_MSG_CHECKING(for $1 field in $2)
|
||||
AC_CACHE_VAL($ossh_varname, [
|
||||
AC_EGREP_HEADER($1, $2, [ dnl
|
||||
eval "$ossh_varname=yes" dnl
|
||||
], [ dnl
|
||||
eval "$ossh_varname=no" dnl
|
||||
]) dnl
|
||||
])
|
||||
ossh_result=`eval 'echo $'"$ossh_varname"`
|
||||
if test -n "`echo $ossh_varname`"; then
|
||||
AC_MSG_RESULT($ossh_result)
|
||||
if test "x$ossh_result" = "xyes"; then
|
||||
AC_DEFINE($3, 1, [Define if you have $1 in $2])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
|
||||
dnl OSSH_PATH_ENTROPY_PROG(variablename, command):
|
||||
dnl Tidiness function, sets 'undef' if not found, and does the AC_SUBST
|
||||
AC_DEFUN(OSSH_PATH_ENTROPY_PROG, [
|
||||
AC_PATH_PROG($1, $2)
|
||||
if test -z "[$]$1" ; then
|
||||
$1="undef"
|
||||
fi
|
||||
AC_SUBST($1)
|
||||
])
|
||||
|
||||
dnl Check for socklen_t: historically on BSD it is an int, and in
|
||||
dnl POSIX 1g it is a type of its own, but some platforms use different
|
||||
dnl types for the argument to getsockopt, getpeername, etc. So we
|
||||
dnl have to test to find something that will work.
|
||||
AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
[
|
||||
AC_CHECK_TYPE([socklen_t], ,[
|
||||
AC_MSG_CHECKING([for socklen_t equivalent])
|
||||
AC_CACHE_VAL([curl_cv_socklen_t_equiv],
|
||||
[
|
||||
# Systems have either "struct sockaddr *" or
|
||||
# "void *" as the second argument to getpeername
|
||||
curl_cv_socklen_t_equiv=
|
||||
for arg2 in "struct sockaddr" void; do
|
||||
for t in int size_t unsigned long "unsigned long"; do
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getpeername (int, $arg2 *, $t *);
|
||||
],[
|
||||
$t len;
|
||||
getpeername(0,0,&len);
|
||||
],[
|
||||
curl_cv_socklen_t_equiv="$t"
|
||||
break
|
||||
])
|
||||
done
|
||||
done
|
||||
|
||||
if test "x$curl_cv_socklen_t_equiv" = x; then
|
||||
AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
|
||||
fi
|
||||
])
|
||||
AC_MSG_RESULT($curl_cv_socklen_t_equiv)
|
||||
AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv,
|
||||
[type to use in place of socklen_t if not defined])],
|
||||
[#include <sys/types.h>
|
||||
#include <sys/socket.h>])
|
||||
])
|
||||
|
@ -1,267 +0,0 @@
|
||||
/* $Id: acss.c,v 1.4 2006/07/24 04:51:01 djm 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 <string.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
|
@ -1,47 +0,0 @@
|
||||
/* $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_ */
|
@ -1,120 +0,0 @@
|
||||
/* $OpenBSD: atomicio.c,v 1.23 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
* 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"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "atomicio.h"
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
|
||||
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;
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t)res;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t
|
||||
atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd,
|
||||
const struct iovec *_iov, int iovcnt)
|
||||
{
|
||||
size_t pos = 0, rem;
|
||||
ssize_t res;
|
||||
struct iovec iov_array[IOV_MAX], *iov = iov_array;
|
||||
|
||||
if (iovcnt > IOV_MAX) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
/* Make a copy of the iov array because we may modify it below */
|
||||
memcpy(iov, _iov, iovcnt * sizeof(*_iov));
|
||||
|
||||
for (; iovcnt > 0 && iov[0].iov_len > 0;) {
|
||||
res = (f) (fd, iov, iovcnt);
|
||||
switch (res) {
|
||||
case -1:
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
rem = (size_t)res;
|
||||
pos += rem;
|
||||
/* skip completed iov entries */
|
||||
while (iovcnt > 0 && rem >= iov[0].iov_len) {
|
||||
rem -= iov[0].iov_len;
|
||||
iov++;
|
||||
iovcnt--;
|
||||
}
|
||||
/* This shouldn't happen... */
|
||||
if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) {
|
||||
errno = EFAULT;
|
||||
return 0;
|
||||
}
|
||||
if (iovcnt == 0)
|
||||
break;
|
||||
/* update pointer in partially complete iov */
|
||||
iov[0].iov_base = ((char *)iov[0].iov_base) + rem;
|
||||
iov[0].iov_len -= rem;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/* $OpenBSD: atomicio.h,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ATOMICIO_H
|
||||
#define _ATOMICIO_H
|
||||
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==readv || f==writev
|
||||
*/
|
||||
size_t atomiciov(ssize_t (*)(int, const struct iovec *, int),
|
||||
int, const struct iovec *, int);
|
||||
|
||||
#endif /* _ATOMICIO_H */
|
@ -1,337 +0,0 @@
|
||||
/* $Id: audit-bsm.c,v 1.5 2006/09/30 22:09:50 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 <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.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 */
|
@ -1,186 +0,0 @@
|
||||
/* $Id: audit.c,v 1.5 2006/09/01 05:38:36 djm 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"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
|
||||
#include "audit.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.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 */
|
@ -1,54 +0,0 @@
|
||||
/* $Id: audit.h,v 1.3 2006/08/05 14:05:10 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.
|
||||
*/
|
||||
|
||||
#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 */
|
@ -1,138 +0,0 @@
|
||||
/* $OpenBSD: auth-bsdauth.c,v 1.10 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef BSD_AUTH
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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 = xcalloc(*numprompts, sizeof(char *));
|
||||
*echo_on = xcalloc(*numprompts, sizeof(u_int));
|
||||
(*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
|
@ -1,123 +0,0 @@
|
||||
/* $OpenBSD: auth-chall.c,v 1.12 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "log.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;
|
||||
}
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/* $OpenBSD: auth-krb5.c,v 1.19 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* Kerberos v5 authentication and ticket-passing routines.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "ssh1.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "uidswap.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
|
||||
#ifdef KRB5
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
auth_krb5_password(Authctxt *authctxt, const char *password)
|
||||
{
|
||||
#ifndef HEIMDAL
|
||||
krb5_creds creds;
|
||||
krb5_principal server;
|
||||
#endif
|
||||
krb5_error_code problem;
|
||||
krb5_ccache ccache = NULL;
|
||||
int len;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &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 (authctxt->valid ? 1 : 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HEIMDAL
|
||||
krb5_error_code
|
||||
ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
|
||||
int tmpfd, ret;
|
||||
char ccname[40];
|
||||
mode_t old_umask;
|
||||
|
||||
ret = snprintf(ccname, sizeof(ccname),
|
||||
"FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
|
||||
if (ret < 0 || (size_t)ret >= sizeof(ccname))
|
||||
return ENOMEM;
|
||||
|
||||
old_umask = umask(0177);
|
||||
tmpfd = mkstemp(ccname + strlen("FILE:"));
|
||||
umask(old_umask);
|
||||
if (tmpfd == -1) {
|
||||
logit("mkstemp(): %.100s", strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
|
||||
logit("fchmod(): %.100s", strerror(errno));
|
||||
close(tmpfd);
|
||||
return errno;
|
||||
}
|
||||
close(tmpfd);
|
||||
|
||||
return (krb5_cc_resolve(ctx, ccname, ccache));
|
||||
}
|
||||
#endif /* !HEIMDAL */
|
||||
#endif /* KRB5 */
|
@ -1,357 +0,0 @@
|
||||
/* $OpenBSD: auth-options.c,v 1.40 2006/08/03 03:34:41 deraadt 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".
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "match.h"
|
||||
#include "log.h"
|
||||
#include "canohost.h"
|
||||
#include "buffer.h"
|
||||
#include "channels.h"
|
||||
#include "auth-options.h"
|
||||
#include "servconf.h"
|
||||
#include "misc.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.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;
|
||||
|
||||
/* "tunnel=" option. */
|
||||
int forced_tun_device = -1;
|
||||
|
||||
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;
|
||||
}
|
||||
forced_tun_device = -1;
|
||||
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;
|
||||
}
|
||||
cp = "tunnel=\"";
|
||||
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
|
||||
char *tun = NULL;
|
||||
opts += strlen(cp);
|
||||
tun = xmalloc(strlen(opts) + 1);
|
||||
i = 0;
|
||||
while (*opts) {
|
||||
if (*opts == '"')
|
||||
break;
|
||||
tun[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(tun);
|
||||
forced_tun_device = -1;
|
||||
goto bad_option;
|
||||
}
|
||||
tun[i] = '\0';
|
||||
forced_tun_device = a2tun(tun, NULL);
|
||||
xfree(tun);
|
||||
if (forced_tun_device == SSH_TUNID_ERR) {
|
||||
debug("%.100s, line %lu: invalid tun device",
|
||||
file, linenum);
|
||||
auth_debug_add("%.100s, line %lu: invalid tun device",
|
||||
file, linenum);
|
||||
forced_tun_device = -1;
|
||||
goto bad_option;
|
||||
}
|
||||
auth_debug_add("Forced tun device: %d", forced_tun_device);
|
||||
opts++;
|
||||
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;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/* $OpenBSD: auth-options.h,v 1.16 2006/08/03 03:34:41 deraadt 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;
|
||||
extern int forced_tun_device;
|
||||
|
||||
int auth_parse_options(struct passwd *, char *, char *, u_long);
|
||||
void auth_clear_options(void);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,50 +0,0 @@
|
||||
/* $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 */
|
@ -1,214 +0,0 @@
|
||||
/* $OpenBSD: auth-passwd.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.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 (as == NULL)
|
||||
return (0);
|
||||
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
|
@ -1,100 +0,0 @@
|
||||
/* $OpenBSD: auth-rh-rsa.c,v 1.42 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "uidswap.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "pathnames.h"
|
||||
#include "auth.h"
|
||||
#include "canohost.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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;
|
||||
}
|
@ -1,309 +0,0 @@
|
||||
/* $OpenBSD: auth-rhosts.c,v 1.41 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_NETGROUP_H
|
||||
# include <netgroup.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "uidswap.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.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;
|
||||
}
|
@ -1,343 +0,0 @@
|
||||
/* $OpenBSD: auth-rsa.c,v 1.72 2006/11/06 21:25:27 markus Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "rsa.h"
|
||||
#include "packet.h"
|
||||
#include "ssh1.h"
|
||||
#include "uidswap.h"
|
||||
#include "match.h"
|
||||
#include "buffer.h"
|
||||
#include "auth-options.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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. */
|
||||
if (BN_rand(challenge, 256, 0, 0) == 0)
|
||||
fatal("auth_rsa_generate_challenge: BN_rand failed");
|
||||
if ((ctx = BN_CTX_new()) == NULL)
|
||||
fatal("auth_rsa_generate_challenge: BN_CTX_new failed");
|
||||
if (BN_mod(challenge, challenge, key->rsa->n, ctx) == 0)
|
||||
fatal("auth_rsa_generate_challenge: BN_mod failed");
|
||||
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] = (u_char)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;
|
||||
int keybits;
|
||||
|
||||
/* 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 */
|
||||
keybits = BN_num_bits(key->rsa->n);
|
||||
if (keybits < 0 || bits != (u_int)keybits)
|
||||
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);
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 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"
|
||||
|
||||
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
|
||||
#include <shadow.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifdef DAY
|
||||
# undef DAY
|
||||
#endif
|
||||
#define DAY (24L * 60 * 60) /* 1 day in seconds */
|
||||
|
||||
extern Buffer loginmsg;
|
||||
|
||||
/*
|
||||
* For the account and password expiration functions, we assume the expiry
|
||||
* occurs the day after the day specified.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check if specified account is expired. Returns 1 if account is expired,
|
||||
* 0 otherwise.
|
||||
*/
|
||||
int
|
||||
auth_shadow_acctexpired(struct spwd *spw)
|
||||
{
|
||||
time_t today;
|
||||
int daysleft;
|
||||
char buf[256];
|
||||
|
||||
today = time(NULL) / DAY;
|
||||
daysleft = spw->sp_expire - today;
|
||||
debug3("%s: today %d sp_expire %d days left %d", __func__, (int)today,
|
||||
(int)spw->sp_expire, daysleft);
|
||||
|
||||
if (spw->sp_expire == -1) {
|
||||
debug3("account expiration disabled");
|
||||
} else if (daysleft < 0) {
|
||||
logit("Account %.100s has expired", spw->sp_namp);
|
||||
return 1;
|
||||
} else if (daysleft <= spw->sp_warn) {
|
||||
debug3("account will expire in %d days", daysleft);
|
||||
snprintf(buf, sizeof(buf),
|
||||
"Your account will expire in %d day%s.\n", daysleft,
|
||||
daysleft == 1 ? "" : "s");
|
||||
buffer_append(&loginmsg, buf, strlen(buf));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks password expiry for platforms that use shadow passwd files.
|
||||
* Returns: 1 = password expired, 0 = password not expired
|
||||
*/
|
||||
int
|
||||
auth_shadow_pwexpired(Authctxt *ctxt)
|
||||
{
|
||||
struct spwd *spw = NULL;
|
||||
const char *user = ctxt->pw->pw_name;
|
||||
char buf[256];
|
||||
time_t today;
|
||||
int daysleft, disabled = 0;
|
||||
|
||||
if ((spw = getspnam((char *)user)) == NULL) {
|
||||
error("Could not get shadow information for %.100s", user);
|
||||
return 0;
|
||||
}
|
||||
|
||||
today = time(NULL) / DAY;
|
||||
debug3("%s: today %d sp_lstchg %d sp_max %d", __func__, (int)today,
|
||||
(int)spw->sp_lstchg, (int)spw->sp_max);
|
||||
|
||||
#if defined(__hpux) && !defined(HAVE_SECUREWARE)
|
||||
if (iscomsec()) {
|
||||
struct pr_passwd *pr;
|
||||
|
||||
pr = getprpwnam((char *)user);
|
||||
|
||||
/* Test for Trusted Mode expiry disabled */
|
||||
if (pr != NULL && pr->ufld.fd_min == 0 &&
|
||||
pr->ufld.fd_lifetime == 0 && pr->ufld.fd_expire == 0 &&
|
||||
pr->ufld.fd_pw_expire_warning == 0 &&
|
||||
pr->ufld.fd_schange != 0)
|
||||
disabled = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: check sp_inact */
|
||||
daysleft = spw->sp_lstchg + spw->sp_max - today;
|
||||
if (disabled) {
|
||||
debug3("password expiration disabled");
|
||||
} else if (spw->sp_lstchg == 0) {
|
||||
logit("User %.100s password has expired (root forced)", user);
|
||||
return 1;
|
||||
} else if (spw->sp_max == -1) {
|
||||
debug3("password expiration disabled");
|
||||
} else if (daysleft < 0) {
|
||||
logit("User %.100s password has expired (password aged)", user);
|
||||
return 1;
|
||||
} else if (daysleft <= spw->sp_warn) {
|
||||
debug3("password will expire in %d days", daysleft);
|
||||
snprintf(buf, sizeof(buf),
|
||||
"Your password will expire in %d day%s.\n", daysleft,
|
||||
daysleft == 1 ? "" : "s");
|
||||
buffer_append(&loginmsg, buf, strlen(buf));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_SHADOW && HAS_SHADOW_EXPIRE */
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Chris Adams. 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 HAVE_OSF_SIA
|
||||
#include <sia.h>
|
||||
#include <siad.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ssh.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-sia.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "canohost.h"
|
||||
#include "uidswap.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
extern int saved_argc;
|
||||
extern char **saved_argv;
|
||||
|
||||
int
|
||||
sys_auth_passwd(Authctxt *authctxt, const char *pass)
|
||||
{
|
||||
int ret;
|
||||
SIAENTITY *ent = NULL;
|
||||
const char *host;
|
||||
|
||||
host = get_canonical_hostname(options.use_dns);
|
||||
|
||||
if (!authctxt->user || pass == NULL || pass[0] == '\0')
|
||||
return (0);
|
||||
|
||||
if (sia_ses_init(&ent, saved_argc, saved_argv, host, authctxt->user,
|
||||
NULL, 0, NULL) != SIASUCCESS)
|
||||
return (0);
|
||||
|
||||
if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) {
|
||||
error("Couldn't authenticate %s from %s",
|
||||
authctxt->user, host);
|
||||
if (ret & SIASTOP)
|
||||
sia_ses_release(&ent);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
sia_ses_release(&ent);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
session_setup_sia(struct passwd *pw, char *tty)
|
||||
{
|
||||
SIAENTITY *ent = NULL;
|
||||
const char *host;
|
||||
|
||||
host = get_canonical_hostname(options.use_dns);
|
||||
|
||||
if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name,
|
||||
tty, 0, NULL) != SIASUCCESS)
|
||||
fatal("sia_ses_init failed");
|
||||
|
||||
if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) {
|
||||
sia_ses_release(&ent);
|
||||
fatal("sia_make_entity_pwd failed");
|
||||
}
|
||||
|
||||
ent->authtype = SIA_A_NONE;
|
||||
if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS)
|
||||
fatal("Couldn't establish session for %s from %s",
|
||||
pw->pw_name, host);
|
||||
|
||||
if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS)
|
||||
fatal("Couldn't launch session for %s from %s",
|
||||
pw->pw_name, host);
|
||||
|
||||
sia_ses_release(&ent);
|
||||
|
||||
setuid(0);
|
||||
permanently_set_uid(pw);
|
||||
}
|
||||
|
||||
#endif /* HAVE_OSF_SIA */
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Chris Adams. 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 HAVE_OSF_SIA
|
||||
|
||||
void session_setup_sia(struct passwd *, char *);
|
||||
|
||||
#endif /* HAVE_OSF_SIA */
|
@ -1,107 +0,0 @@
|
||||
/* $OpenBSD: auth-skey.c,v 1.26 2006/08/05 08:28:24 dtucker Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#ifdef SKEY
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <skey.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "ssh-gss.h"
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
static void *
|
||||
skey_init_ctx(Authctxt *authctxt)
|
||||
{
|
||||
return authctxt;
|
||||
}
|
||||
|
||||
int
|
||||
skey_query(void *ctx, char **name, char **infotxt,
|
||||
u_int* numprompts, char ***prompts, u_int **echo_on)
|
||||
{
|
||||
Authctxt *authctxt = ctx;
|
||||
char challenge[1024];
|
||||
struct skey skey;
|
||||
|
||||
if (_compat_skeychallenge(&skey, authctxt->user, challenge,
|
||||
sizeof(challenge)) == -1)
|
||||
return -1;
|
||||
|
||||
*name = xstrdup("");
|
||||
*infotxt = xstrdup("");
|
||||
*numprompts = 1;
|
||||
*prompts = xcalloc(*numprompts, sizeof(char *));
|
||||
*echo_on = xcalloc(*numprompts, sizeof(u_int));
|
||||
|
||||
xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
skey_respond(void *ctx, u_int numresponses, char **responses)
|
||||
{
|
||||
Authctxt *authctxt = ctx;
|
||||
|
||||
if (authctxt->valid &&
|
||||
numresponses == 1 &&
|
||||
skey_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
skey_free_ctx(void *ctx)
|
||||
{
|
||||
/* we don't have a special context */
|
||||
}
|
||||
|
||||
KbdintDevice skey_device = {
|
||||
"skey",
|
||||
skey_init_ctx,
|
||||
skey_query,
|
||||
skey_respond,
|
||||
skey_free_ctx
|
||||
};
|
||||
|
||||
KbdintDevice mm_skey_device = {
|
||||
"skey",
|
||||
skey_init_ctx,
|
||||
mm_skey_query,
|
||||
mm_skey_respond,
|
||||
skey_free_ctx
|
||||
};
|
||||
#endif /* SKEY */
|
@ -1,581 +0,0 @@
|
||||
/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_PATHS_H
|
||||
# include <paths.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#ifdef HAVE_LOGIN_H
|
||||
#include <login.h>
|
||||
#endif
|
||||
#ifdef USE_SHADOW
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "match.h"
|
||||
#include "groupaccess.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "auth-options.h"
|
||||
#include "canohost.h"
|
||||
#include "uidswap.h"
|
||||
#include "misc.h"
|
||||
#include "packet.h"
|
||||
#include "loginrec.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern int use_privsep;
|
||||
extern Buffer loginmsg;
|
||||
extern struct passwd *privsep_pw;
|
||||
|
||||
/* 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;
|
||||
u_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)
|
||||
#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF)
|
||||
passwd = get_iaf_password(pw);
|
||||
#else
|
||||
passwd = spw->sp_pwdp;
|
||||
#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */
|
||||
#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 defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF)
|
||||
free(passwd);
|
||||
#endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */
|
||||
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;
|
||||
|
||||
if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
|
||||
return;
|
||||
|
||||
/* 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");
|
||||
# ifdef WITH_AIXAUTHENTICATE
|
||||
if (authenticated)
|
||||
sys_auth_record_login(authctxt->user,
|
||||
get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
|
||||
# endif
|
||||
#endif
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
if (authenticated == 0 && !authctxt->postponed)
|
||||
audit_event(audit_classify_auth(method));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether root logins are disallowed.
|
||||
*/
|
||||
int
|
||||
auth_root_allowed(char *method)
|
||||
{
|
||||
switch (options.permit_root_login) {
|
||||
case PERMIT_YES:
|
||||
return 1;
|
||||
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.
|
||||
*/
|
||||
static char *
|
||||
expand_authorized_keys(const char *filename, struct passwd *pw)
|
||||
{
|
||||
char *file, ret[MAXPATHLEN];
|
||||
int i;
|
||||
|
||||
file = percent_expand(filename, "h", pw->pw_dir,
|
||||
"u", pw->pw_name, (char *)NULL);
|
||||
|
||||
/*
|
||||
* Ensure that filename starts anchored. If not, be backward
|
||||
* compatible and prepend the '%h/'
|
||||
*/
|
||||
if (*file == '/')
|
||||
return (file);
|
||||
|
||||
i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
|
||||
if (i < 0 || (size_t)i >= sizeof(ret))
|
||||
fatal("expand_authorized_keys: path too long");
|
||||
xfree(file);
|
||||
return (xstrdup(ret));
|
||||
}
|
||||
|
||||
char *
|
||||
authorized_keys_file(struct passwd *pw)
|
||||
{
|
||||
return expand_authorized_keys(options.authorized_keys_file, pw);
|
||||
}
|
||||
|
||||
char *
|
||||
authorized_keys_file2(struct passwd *pw)
|
||||
{
|
||||
return expand_authorized_keys(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;
|
||||
|
||||
parse_server_match_config(&options, user,
|
||||
get_canonical_hostname(options.use_dns), get_remote_ipaddr());
|
||||
|
||||
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 = privsep_pw->pw_uid;
|
||||
fake.pw_gid = privsep_pw->pw_gid;
|
||||
#ifdef HAVE_PW_CLASS_IN_PASSWD
|
||||
fake.pw_class = "";
|
||||
#endif
|
||||
fake.pw_dir = "/nonexist";
|
||||
fake.pw_shell = "/nonexist";
|
||||
|
||||
return (&fake);
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus 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 <signal.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 {
|
||||
sig_atomic_t success;
|
||||
int authenticated; /* authenticated and alarms cancelled */
|
||||
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 *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: "
|
||||
|
||||
#if defined(KRB5) && !defined(HEIMDAL)
|
||||
#include <krb5.h>
|
||||
krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *);
|
||||
#endif
|
||||
#endif
|
@ -1,442 +0,0 @@
|
||||
/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#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 "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "channels.h"
|
||||
#include "session.h"
|
||||
#include "uidswap.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "buffer.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
extern Buffer loginmsg;
|
||||
|
||||
static int auth1_process_password(Authctxt *, char *, size_t);
|
||||
static int auth1_process_rsa(Authctxt *, char *, size_t);
|
||||
static int auth1_process_rhosts_rsa(Authctxt *, char *, size_t);
|
||||
static int auth1_process_tis_challenge(Authctxt *, char *, size_t);
|
||||
static int auth1_process_tis_response(Authctxt *, char *, size_t);
|
||||
|
||||
static char *client_user = NULL; /* Used to fill in remote user for PAM */
|
||||
|
||||
struct AuthMethod1 {
|
||||
int type;
|
||||
char *name;
|
||||
int *enabled;
|
||||
int (*method)(Authctxt *, char *, size_t);
|
||||
};
|
||||
|
||||
const struct AuthMethod1 auth1_methods[] = {
|
||||
{
|
||||
SSH_CMSG_AUTH_PASSWORD, "password",
|
||||
&options.password_authentication, auth1_process_password
|
||||
},
|
||||
{
|
||||
SSH_CMSG_AUTH_RSA, "rsa",
|
||||
&options.rsa_authentication, auth1_process_rsa
|
||||
},
|
||||
{
|
||||
SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa",
|
||||
&options.rhosts_rsa_authentication, auth1_process_rhosts_rsa
|
||||
},
|
||||
{
|
||||
SSH_CMSG_AUTH_TIS, "challenge-response",
|
||||
&options.challenge_response_authentication,
|
||||
auth1_process_tis_challenge
|
||||
},
|
||||
{
|
||||
SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response",
|
||||
&options.challenge_response_authentication,
|
||||
auth1_process_tis_response
|
||||
},
|
||||
{ -1, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct AuthMethod1
|
||||
*lookup_authmethod1(int type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; auth1_methods[i].name != NULL; i++)
|
||||
if (auth1_methods[i].type == type)
|
||||
return (&(auth1_methods[i]));
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_authname(int type)
|
||||
{
|
||||
const struct AuthMethod1 *a;
|
||||
static char buf[64];
|
||||
|
||||
if ((a = lookup_authmethod1(type)) != NULL)
|
||||
return (a->name);
|
||||
snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
|
||||
{
|
||||
int authenticated = 0;
|
||||
char *password;
|
||||
u_int dlen;
|
||||
|
||||
/*
|
||||
* 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, dlen);
|
||||
xfree(password);
|
||||
|
||||
return (authenticated);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
|
||||
{
|
||||
int authenticated = 0;
|
||||
BIGNUM *n;
|
||||
|
||||
/* 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);
|
||||
|
||||
return (authenticated);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
|
||||
{
|
||||
int keybits, authenticated = 0;
|
||||
u_int bits;
|
||||
Key *client_host_key;
|
||||
u_int ulen;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
keybits = BN_num_bits(client_host_key->rsa->n);
|
||||
if (keybits < 0 || bits != (u_int)keybits) {
|
||||
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, infolen, " ruser %.100s", client_user);
|
||||
|
||||
return (authenticated);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
|
||||
{
|
||||
char *challenge;
|
||||
|
||||
if ((challenge = get_challenge(authctxt)) == NULL)
|
||||
return (0);
|
||||
|
||||
debug("sending challenge '%s'", challenge);
|
||||
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
|
||||
packet_put_cstring(challenge);
|
||||
xfree(challenge);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen)
|
||||
{
|
||||
int authenticated = 0;
|
||||
char *response;
|
||||
u_int dlen;
|
||||
|
||||
response = packet_get_string(&dlen);
|
||||
packet_check_eom();
|
||||
authenticated = verify_response(authctxt, response);
|
||||
memset(response, 'r', dlen);
|
||||
xfree(response);
|
||||
|
||||
return (authenticated);
|
||||
}
|
||||
|
||||
/*
|
||||
* read packets, try to authenticate the user and
|
||||
* return only if authentication is successful
|
||||
*/
|
||||
static void
|
||||
do_authloop(Authctxt *authctxt)
|
||||
{
|
||||
int authenticated = 0;
|
||||
char info[1024];
|
||||
int prev = 0, type = 0;
|
||||
const struct AuthMethod1 *meth;
|
||||
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
if ((meth = lookup_authmethod1(type)) == NULL) {
|
||||
logit("Unknown message during authentication: "
|
||||
"type %d", type);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (!*(meth->enabled)) {
|
||||
verbose("%s authentication disabled.", meth->name);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
authenticated = meth->method(authctxt, info, sizeof(info));
|
||||
if (authenticated == -1)
|
||||
continue; /* "postponed" */
|
||||
|
||||
#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(meth->name)) {
|
||||
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
|
||||
|
||||
skip:
|
||||
/* 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.
|
||||
*/
|
||||
#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();
|
||||
}
|
@ -1,378 +0,0 @@
|
||||
/* $OpenBSD: auth2-chall.c,v 1.31 2006/08/05 08:28:24 dtucker Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh2.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "buffer.h"
|
||||
#include "packet.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;
|
||||
u_int i, *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 authenticated = 0, res, len;
|
||||
u_int i, 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 = xcalloc(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
|
||||
}
|
@ -1,301 +0,0 @@
|
||||
/* $OpenBSD: auth2-gss.c,v 1.15 2006/08/03 03:34:41 deraadt 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 <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "ssh2.h"
|
||||
#include "log.h"
|
||||
#include "dispatch.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "packet.h"
|
||||
#include "ssh-gss.h"
|
||||
#include "monitor_wrap.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;
|
||||
u_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)))) {
|
||||
if (ctxt != NULL)
|
||||
ssh_gssapi_delete_ctx(&ctxt);
|
||||
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 */
|
@ -1,191 +0,0 @@
|
||||
/* $OpenBSD: auth2-hostbased.c,v 1.11 2006/08/03 03:34:41 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh2.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "canohost.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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
|
||||
};
|
@ -1,72 +0,0 @@
|
||||
/* $OpenBSD: auth2-kbdint.c,v 1.5 2006/08/03 03:34:41 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.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
|
||||
};
|
@ -1,140 +0,0 @@
|
||||
/* $OpenBSD: auth2-none.c,v 1.13 2006/08/05 07:52:52 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "atomicio.h"
|
||||
#include "compat.h"
|
||||
#include "ssh2.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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
|
||||
};
|
@ -1,84 +0,0 @@
|
||||
/* $OpenBSD: auth2-passwd.c,v 1.9 2006/08/03 03:34:41 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "buffer.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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
|
||||
};
|
@ -1,292 +0,0 @@
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.15 2006/08/03 03:34:41 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "packet.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "pathnames.h"
|
||||
#include "uidswap.h"
|
||||
#include "auth-options.h"
|
||||
#include "canohost.h"
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#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
|
||||
};
|
@ -1,104 +0,0 @@
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-skey.c,v 1.1 2000/10/11 20:14:38 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "dispatch.h"
|
||||
|
||||
void send_userauth_into_request(Authctxt *authctxt, int echo);
|
||||
void input_userauth_info_response(int type, int plen, void *ctxt);
|
||||
|
||||
/*
|
||||
* try skey authentication, always return -1 (= postponed) since we have to
|
||||
* wait for the s/key response.
|
||||
*/
|
||||
int
|
||||
auth2_skey(Authctxt *authctxt)
|
||||
{
|
||||
send_userauth_into_request(authctxt, 0);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &input_userauth_info_response);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
send_userauth_into_request(Authctxt *authctxt, int echo)
|
||||
{
|
||||
int retval = -1;
|
||||
struct skey skey;
|
||||
char challenge[SKEY_MAX_CHALLENGE];
|
||||
char *fake;
|
||||
|
||||
if (authctxt->user == NULL)
|
||||
fatal("send_userauth_into_request: internal error: no user");
|
||||
|
||||
/* get skey challenge */
|
||||
if (authctxt->valid)
|
||||
retval = skeychallenge(&skey, authctxt->user, challenge);
|
||||
|
||||
if (retval == -1) {
|
||||
fake = skey_fake_keyinfo(authctxt->user);
|
||||
strlcpy(challenge, fake, sizeof challenge);
|
||||
}
|
||||
/* send our info request */
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
|
||||
packet_put_cstring("S/Key Authentication"); /* Name */
|
||||
packet_put_cstring(challenge); /* Instruction */
|
||||
packet_put_cstring(""); /* Language */
|
||||
packet_put_int(1); /* Number of prompts */
|
||||
packet_put_cstring(echo ?
|
||||
"Response [Echo]: ": "Response: "); /* Prompt */
|
||||
packet_put_char(echo); /* Echo */
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
memset(challenge, 'c', sizeof challenge);
|
||||
}
|
||||
|
||||
void
|
||||
input_userauth_info_response(int type, int plen, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
int authenticated = 0;
|
||||
unsigned int nresp, rlen;
|
||||
char *resp, *method;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response: no authentication context");
|
||||
|
||||
if (authctxt->attempt++ >= AUTH_FAIL_MAX)
|
||||
packet_disconnect("too many failed userauth_requests");
|
||||
|
||||
nresp = packet_get_int();
|
||||
if (nresp == 1) {
|
||||
/* we only support s/key and assume s/key for nresp == 1 */
|
||||
method = "s/key";
|
||||
resp = packet_get_string(&rlen);
|
||||
packet_done();
|
||||
if (strlen(resp) == 0) {
|
||||
/*
|
||||
* if we received a null response, resend prompt with
|
||||
* echo enabled
|
||||
*/
|
||||
authenticated = -1;
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
send_userauth_into_request(authctxt, 1);
|
||||
} else {
|
||||
/* verify skey response */
|
||||
if (authctxt->valid &&
|
||||
skey_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
skey_passcheck(authctxt->pw->pw_name, resp) != -1) {
|
||||
authenticated = 1;
|
||||
} else {
|
||||
authenticated = 0;
|
||||
}
|
||||
memset(resp, 'r', rlen);
|
||||
/* unregister callback */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
userauth_reply(authctxt, authenticated);
|
||||
}
|
||||
xfree(resp);
|
||||
}
|
||||
}
|
@ -1,329 +0,0 @@
|
||||
/* $OpenBSD: auth2.c,v 1.113 2006/08/03 03:34:41 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh2.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "servconf.h"
|
||||
#include "compat.h"
|
||||
#include "key.h"
|
||||
#include "hostfile.h"
|
||||
#include "auth.h"
|
||||
#include "dispatch.h"
|
||||
#include "pathnames.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
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);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
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);
|
||||
} else {
|
||||
logit("input_userauth_request: invalid user %s", user);
|
||||
authctxt->pw = fakepw();
|
||||
#ifdef SSH_AUDIT_EVENTS
|
||||
PRIVSEP(audit_event(SSH_INVALID_USER));
|
||||
#endif
|
||||
}
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
PRIVSEP(start_pam(authctxt));
|
||||
#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;
|
||||
}
|
@ -1,671 +0,0 @@
|
||||
/* $OpenBSD: authfd.c,v 1.80 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "rsa.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
#include "authfd.h"
|
||||
#include "cipher.h"
|
||||
#include "kex.h"
|
||||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "atomicio.h"
|
||||
#include "misc.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)
|
||||
{
|
||||
u_int l, len;
|
||||
char buf[1024];
|
||||
|
||||
/* Get the length of the message, and format it in the buffer. */
|
||||
len = buffer_len(request);
|
||||
put_u32(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_u32(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);
|
||||
if (atomicio(read, auth->fd, buf, l) != l) {
|
||||
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)
|
||||
{
|
||||
int keybits;
|
||||
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);
|
||||
keybits = BN_num_bits(key->rsa->n);
|
||||
if (keybits < 0 || bits != (u_int)keybits)
|
||||
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;
|
||||
}
|
||||
/* 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] = (u_char)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;
|
||||
}
|
||||
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;
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/* $OpenBSD: authfd.h,v 1.36 2006/08/03 03:34:41 deraadt 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
|
||||
|
||||
/* 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 */
|
@ -1,679 +0,0 @@
|
||||
/* $OpenBSD: authfile.c,v 1.76 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "cipher.h"
|
||||
#include "buffer.h"
|
||||
#include "key.h"
|
||||
#include "ssh.h"
|
||||
#include "log.h"
|
||||
#include "authfile.h"
|
||||
#include "rsa.h"
|
||||
#include "misc.h"
|
||||
#include "atomicio.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 (atomicio(vwrite, 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);
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
return key_save_private_pem(key, filename, passphrase,
|
||||
comment);
|
||||
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;
|
||||
u_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 (atomicio(read, fd, cp, len) != 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)
|
||||
{
|
||||
u_int i;
|
||||
int 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 (atomicio(read, fd, cp, len) != 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;
|
||||
}
|
||||
|
||||
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 *perm_ok)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
if (!key_perm_ok(fd, filename)) {
|
||||
if (perm_ok != NULL)
|
||||
*perm_ok = 0;
|
||||
error("bad permissions: ignore key: %s", filename);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (perm_ok != NULL)
|
||||
*perm_ok = 1;
|
||||
switch (type) {
|
||||
case KEY_RSA1:
|
||||
return key_load_private_rsa1(fd, filename, passphrase,
|
||||
commentp);
|
||||
/* closes fd */
|
||||
case KEY_DSA:
|
||||
case KEY_RSA:
|
||||
case KEY_UNSPEC:
|
||||
return key_load_private_pem(fd, type, passphrase, commentp);
|
||||
/* closes fd */
|
||||
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;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/* $OpenBSD: authfile.h,v 1.13 2006/04/25 08:02:27 dtucker 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 **, int *);
|
||||
Key *key_load_private_pem(int, int, const char *, char **);
|
||||
int key_perm_ok(int, const char *);
|
||||
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: aux.c,v 1.2 2000/05/17 09:47:59 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
|
||||
char *
|
||||
chop(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
while (*t) {
|
||||
if(*t == '\n' || *t == '\r') {
|
||||
*t = '\0';
|
||||
return s;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
set_nonblock(int fd)
|
||||
{
|
||||
int val;
|
||||
val = fcntl(fd, F_GETFL, 0);
|
||||
if (val < 0) {
|
||||
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (val & O_NONBLOCK)
|
||||
return;
|
||||
debug("fd %d setting O_NONBLOCK", fd);
|
||||
val |= O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, val) == -1)
|
||||
error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno));
|
||||
}
|
@ -1,249 +0,0 @@
|
||||
/* $OpenBSD: bufaux.c,v 1.44 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* 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 disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* Returns integers from the buffer (msb first).
|
||||
*/
|
||||
|
||||
int
|
||||
buffer_get_short_ret(u_short *ret, Buffer *buffer)
|
||||
{
|
||||
u_char buf[2];
|
||||
|
||||
if (buffer_get_ret(buffer, (char *) buf, 2) == -1)
|
||||
return (-1);
|
||||
*ret = get_u16(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
u_short
|
||||
buffer_get_short(Buffer *buffer)
|
||||
{
|
||||
u_short ret;
|
||||
|
||||
if (buffer_get_short_ret(&ret, buffer) == -1)
|
||||
fatal("buffer_get_short: buffer error");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_int_ret(u_int *ret, Buffer *buffer)
|
||||
{
|
||||
u_char buf[4];
|
||||
|
||||
if (buffer_get_ret(buffer, (char *) buf, 4) == -1)
|
||||
return (-1);
|
||||
*ret = get_u32(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
u_int
|
||||
buffer_get_int(Buffer *buffer)
|
||||
{
|
||||
u_int ret;
|
||||
|
||||
if (buffer_get_int_ret(&ret, buffer) == -1)
|
||||
fatal("buffer_get_int: buffer error");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer)
|
||||
{
|
||||
u_char buf[8];
|
||||
|
||||
if (buffer_get_ret(buffer, (char *) buf, 8) == -1)
|
||||
return (-1);
|
||||
*ret = get_u64(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
u_int64_t
|
||||
buffer_get_int64(Buffer *buffer)
|
||||
{
|
||||
u_int64_t ret;
|
||||
|
||||
if (buffer_get_int64_ret(&ret, buffer) == -1)
|
||||
fatal("buffer_get_int: buffer error");
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores integers in the buffer, msb first.
|
||||
*/
|
||||
void
|
||||
buffer_put_short(Buffer *buffer, u_short value)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
put_u16(buf, value);
|
||||
buffer_append(buffer, buf, 2);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_put_int(Buffer *buffer, u_int value)
|
||||
{
|
||||
char buf[4];
|
||||
|
||||
put_u32(buf, value);
|
||||
buffer_append(buffer, buf, 4);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_put_int64(Buffer *buffer, u_int64_t value)
|
||||
{
|
||||
char buf[8];
|
||||
|
||||
put_u64(buf, value);
|
||||
buffer_append(buffer, buf, 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an arbitrary binary string from the buffer. The string cannot
|
||||
* be longer than 256k. The returned value points to memory allocated
|
||||
* with xmalloc; it is the responsibility of the calling function to free
|
||||
* the data. If length_ptr is non-NULL, the length of the returned data
|
||||
* will be stored there. A null character will be automatically appended
|
||||
* to the returned string, and is not counted in length.
|
||||
*/
|
||||
void *
|
||||
buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
u_char *value;
|
||||
u_int len;
|
||||
|
||||
/* Get the length. */
|
||||
len = buffer_get_int(buffer);
|
||||
if (len > 256 * 1024) {
|
||||
error("buffer_get_string_ret: bad string length %u", len);
|
||||
return (NULL);
|
||||
}
|
||||
/* Allocate space for the string. Add one byte for a null character. */
|
||||
value = xmalloc(len + 1);
|
||||
/* Get the string. */
|
||||
if (buffer_get_ret(buffer, value, len) == -1) {
|
||||
error("buffer_get_string_ret: buffer_get failed");
|
||||
xfree(value);
|
||||
return (NULL);
|
||||
}
|
||||
/* Append a null character to make processing easier. */
|
||||
value[len] = 0;
|
||||
/* Optionally return the length of the string. */
|
||||
if (length_ptr)
|
||||
*length_ptr = len;
|
||||
return (value);
|
||||
}
|
||||
|
||||
void *
|
||||
buffer_get_string(Buffer *buffer, u_int *length_ptr)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL)
|
||||
fatal("buffer_get_string: buffer error");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores and arbitrary binary string in the buffer.
|
||||
*/
|
||||
void
|
||||
buffer_put_string(Buffer *buffer, const void *buf, u_int len)
|
||||
{
|
||||
buffer_put_int(buffer, len);
|
||||
buffer_append(buffer, buf, len);
|
||||
}
|
||||
void
|
||||
buffer_put_cstring(Buffer *buffer, const char *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
fatal("buffer_put_cstring: s == NULL");
|
||||
buffer_put_string(buffer, s, strlen(s));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a character from the buffer (0 - 255).
|
||||
*/
|
||||
int
|
||||
buffer_get_char_ret(char *ret, Buffer *buffer)
|
||||
{
|
||||
if (buffer_get_ret(buffer, ret, 1) == -1) {
|
||||
error("buffer_get_char_ret: buffer_get_ret failed");
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_char(Buffer *buffer)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if (buffer_get_char_ret(&ch, buffer) == -1)
|
||||
fatal("buffer_get_char: buffer error");
|
||||
return (u_char) ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores a character in the buffer.
|
||||
*/
|
||||
void
|
||||
buffer_put_char(Buffer *buffer, int value)
|
||||
{
|
||||
char ch = value;
|
||||
|
||||
buffer_append(buffer, &ch, 1);
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/* $OpenBSD: bufaux.h,v 1.22 2006/03/25 22:22:42 djm 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 BUFAUX_H
|
||||
#define BUFAUX_H
|
||||
|
||||
#include "buffer.h"
|
||||
#include <openssl/bn.h>
|
||||
|
||||
void buffer_put_bignum(Buffer *, const BIGNUM *);
|
||||
void buffer_put_bignum2(Buffer *, const BIGNUM *);
|
||||
void buffer_get_bignum(Buffer *, BIGNUM *);
|
||||
void buffer_get_bignum2(Buffer *, BIGNUM *);
|
||||
|
||||
u_short buffer_get_short(Buffer *);
|
||||
void buffer_put_short(Buffer *, u_short);
|
||||
|
||||
u_int buffer_get_int(Buffer *);
|
||||
void buffer_put_int(Buffer *, u_int);
|
||||
|
||||
u_int64_t buffer_get_int64(Buffer *);
|
||||
void buffer_put_int64(Buffer *, u_int64_t);
|
||||
|
||||
int buffer_get_char(Buffer *);
|
||||
void buffer_put_char(Buffer *, int);
|
||||
|
||||
void *buffer_get_string(Buffer *, u_int *);
|
||||
void buffer_put_string(Buffer *, const void *, u_int);
|
||||
void buffer_put_cstring(Buffer *, const char *);
|
||||
|
||||
#define buffer_skip_string(b) \
|
||||
do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while (0)
|
||||
|
||||
int buffer_put_bignum_ret(Buffer *, const BIGNUM *);
|
||||
int buffer_get_bignum_ret(Buffer *, BIGNUM *);
|
||||
int buffer_put_bignum2_ret(Buffer *, const BIGNUM *);
|
||||
int buffer_get_bignum2_ret(Buffer *, BIGNUM *);
|
||||
int buffer_get_short_ret(u_short *, Buffer *);
|
||||
int buffer_get_int_ret(u_int *, Buffer *);
|
||||
int buffer_get_int64_ret(u_int64_t *, Buffer *);
|
||||
void *buffer_get_string_ret(Buffer *, u_int *);
|
||||
int buffer_get_char_ret(char *, Buffer *);
|
||||
|
||||
#endif /* BUFAUX_H */
|
@ -1,221 +0,0 @@
|
||||
/* $OpenBSD: bufbn.c,v 1.4 2006/11/06 21:25:28 markus Exp $*/
|
||||
/*
|
||||
* 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 disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
|
||||
* by (bits+7)/8 bytes of binary data, msb first.
|
||||
*/
|
||||
int
|
||||
buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
|
||||
{
|
||||
int bits = BN_num_bits(value);
|
||||
int bin_size = (bits + 7) / 8;
|
||||
u_char *buf = xmalloc(bin_size);
|
||||
int oi;
|
||||
char msg[2];
|
||||
|
||||
/* Get the value of in binary */
|
||||
oi = BN_bn2bin(value, buf);
|
||||
if (oi != bin_size) {
|
||||
error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
|
||||
oi, bin_size);
|
||||
xfree(buf);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Store the number of bits in the buffer in two bytes, msb first. */
|
||||
put_u16(msg, bits);
|
||||
buffer_append(buffer, msg, 2);
|
||||
/* Store the binary data. */
|
||||
buffer_append(buffer, buf, oi);
|
||||
|
||||
memset(buf, 0, bin_size);
|
||||
xfree(buf);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
|
||||
{
|
||||
if (buffer_put_bignum_ret(buffer, value) == -1)
|
||||
fatal("buffer_put_bignum: buffer error");
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieves an BIGNUM from the buffer.
|
||||
*/
|
||||
int
|
||||
buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
u_int bits, bytes;
|
||||
u_char buf[2], *bin;
|
||||
|
||||
/* Get the number for bits. */
|
||||
if (buffer_get_ret(buffer, (char *) buf, 2) == -1) {
|
||||
error("buffer_get_bignum_ret: invalid length");
|
||||
return (-1);
|
||||
}
|
||||
bits = get_u16(buf);
|
||||
/* Compute the number of binary bytes that follow. */
|
||||
bytes = (bits + 7) / 8;
|
||||
if (bytes > 8 * 1024) {
|
||||
error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes);
|
||||
return (-1);
|
||||
}
|
||||
if (buffer_len(buffer) < bytes) {
|
||||
error("buffer_get_bignum_ret: input buffer too small");
|
||||
return (-1);
|
||||
}
|
||||
bin = buffer_ptr(buffer);
|
||||
if (BN_bin2bn(bin, bytes, value) == NULL) {
|
||||
error("buffer_get_bignum_ret: BN_bin2bn failed");
|
||||
return (-1);
|
||||
}
|
||||
if (buffer_consume_ret(buffer, bytes) == -1) {
|
||||
error("buffer_get_bignum_ret: buffer_consume failed");
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_get_bignum(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
if (buffer_get_bignum_ret(buffer, value) == -1)
|
||||
fatal("buffer_get_bignum: buffer error");
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores an BIGNUM in the buffer in SSH2 format.
|
||||
*/
|
||||
int
|
||||
buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
|
||||
{
|
||||
u_int bytes;
|
||||
u_char *buf;
|
||||
int oi;
|
||||
u_int hasnohigh = 0;
|
||||
|
||||
if (BN_is_zero(value)) {
|
||||
buffer_put_int(buffer, 0);
|
||||
return 0;
|
||||
}
|
||||
if (value->neg) {
|
||||
error("buffer_put_bignum2_ret: negative numbers not supported");
|
||||
return (-1);
|
||||
}
|
||||
bytes = BN_num_bytes(value) + 1; /* extra padding byte */
|
||||
if (bytes < 2) {
|
||||
error("buffer_put_bignum2_ret: BN too small");
|
||||
return (-1);
|
||||
}
|
||||
buf = xmalloc(bytes);
|
||||
buf[0] = 0x00;
|
||||
/* Get the value of in binary */
|
||||
oi = BN_bn2bin(value, buf+1);
|
||||
if (oi < 0 || (u_int)oi != bytes - 1) {
|
||||
error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
|
||||
"oi %d != bin_size %d", oi, bytes);
|
||||
xfree(buf);
|
||||
return (-1);
|
||||
}
|
||||
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
|
||||
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
|
||||
memset(buf, 0, bytes);
|
||||
xfree(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
|
||||
{
|
||||
if (buffer_put_bignum2_ret(buffer, value) == -1)
|
||||
fatal("buffer_put_bignum2: buffer error");
|
||||
}
|
||||
|
||||
int
|
||||
buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
u_int len;
|
||||
u_char *bin;
|
||||
|
||||
if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) {
|
||||
error("buffer_get_bignum2_ret: invalid bignum");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (len > 0 && (bin[0] & 0x80)) {
|
||||
error("buffer_get_bignum2_ret: negative numbers not supported");
|
||||
xfree(bin);
|
||||
return (-1);
|
||||
}
|
||||
if (len > 8 * 1024) {
|
||||
error("buffer_get_bignum2_ret: cannot handle BN of size %d", len);
|
||||
xfree(bin);
|
||||
return (-1);
|
||||
}
|
||||
if (BN_bin2bn(bin, len, value) == NULL) {
|
||||
error("buffer_get_bignum2_ret: BN_bin2bn failed");
|
||||
return (-1);
|
||||
}
|
||||
xfree(bin);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
|
||||
{
|
||||
if (buffer_get_bignum2_ret(buffer, value) == -1)
|
||||
fatal("buffer_get_bignum2: buffer error");
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for manipulating fifo buffers (that can grow if needed).
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "log.h"
|
||||
|
||||
#define BUFFER_MAX_CHUNK 0x100000
|
||||
#define BUFFER_MAX_LEN 0xa00000
|
||||
#define BUFFER_ALLOCSZ 0x008000
|
||||
|
||||
/* Initializes the buffer structure. */
|
||||
|
||||
void
|
||||
buffer_init(Buffer *buffer)
|
||||
{
|
||||
const u_int len = 4096;
|
||||
|
||||
buffer->alloc = 0;
|
||||
buffer->buf = xmalloc(len);
|
||||
buffer->alloc = len;
|
||||
buffer->offset = 0;
|
||||
buffer->end = 0;
|
||||
}
|
||||
|
||||
/* Frees any memory used for the buffer. */
|
||||
|
||||
void
|
||||
buffer_free(Buffer *buffer)
|
||||
{
|
||||
if (buffer->alloc > 0) {
|
||||
memset(buffer->buf, 0, buffer->alloc);
|
||||
buffer->alloc = 0;
|
||||
xfree(buffer->buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clears any data from the buffer, making it empty. This does not actually
|
||||
* zero the memory.
|
||||
*/
|
||||
|
||||
void
|
||||
buffer_clear(Buffer *buffer)
|
||||
{
|
||||
buffer->offset = 0;
|
||||
buffer->end = 0;
|
||||
}
|
||||
|
||||
/* Appends data to the buffer, expanding it if necessary. */
|
||||
|
||||
void
|
||||
buffer_append(Buffer *buffer, const void *data, u_int len)
|
||||
{
|
||||
void *p;
|
||||
p = buffer_append_space(buffer, len);
|
||||
memcpy(p, data, len);
|
||||
}
|
||||
|
||||
static int
|
||||
buffer_compact(Buffer *buffer)
|
||||
{
|
||||
/*
|
||||
* If the buffer is quite empty, but all data is at the end, move the
|
||||
* data to the beginning.
|
||||
*/
|
||||
if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
|
||||
memmove(buffer->buf, buffer->buf + buffer->offset,
|
||||
buffer->end - buffer->offset);
|
||||
buffer->end -= buffer->offset;
|
||||
buffer->offset = 0;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Appends space to the buffer, expanding the buffer if necessary. This does
|
||||
* not actually copy the data into the buffer, but instead returns a pointer
|
||||
* to the allocated region.
|
||||
*/
|
||||
|
||||
void *
|
||||
buffer_append_space(Buffer *buffer, u_int len)
|
||||
{
|
||||
u_int newlen;
|
||||
void *p;
|
||||
|
||||
if (len > BUFFER_MAX_CHUNK)
|
||||
fatal("buffer_append_space: len %u not supported", len);
|
||||
|
||||
/* If the buffer is empty, start using it from the beginning. */
|
||||
if (buffer->offset == buffer->end) {
|
||||
buffer->offset = 0;
|
||||
buffer->end = 0;
|
||||
}
|
||||
restart:
|
||||
/* If there is enough space to store all data, store it now. */
|
||||
if (buffer->end + len < buffer->alloc) {
|
||||
p = buffer->buf + buffer->end;
|
||||
buffer->end += len;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Compact data back to the start of the buffer if necessary */
|
||||
if (buffer_compact(buffer))
|
||||
goto restart;
|
||||
|
||||
/* Increase the size of the buffer and retry. */
|
||||
newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
|
||||
if (newlen > BUFFER_MAX_LEN)
|
||||
fatal("buffer_append_space: alloc %u not supported",
|
||||
newlen);
|
||||
buffer->buf = xrealloc(buffer->buf, 1, newlen);
|
||||
buffer->alloc = newlen;
|
||||
goto restart;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether an allocation of 'len' will fit in the buffer
|
||||
* This must follow the same math as buffer_append_space
|
||||
*/
|
||||
int
|
||||
buffer_check_alloc(Buffer *buffer, u_int len)
|
||||
{
|
||||
if (buffer->offset == buffer->end) {
|
||||
buffer->offset = 0;
|
||||
buffer->end = 0;
|
||||
}
|
||||
restart:
|
||||
if (buffer->end + len < buffer->alloc)
|
||||
return (1);
|
||||
if (buffer_compact(buffer))
|
||||
goto restart;
|
||||
if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Returns the number of bytes of data in the buffer. */
|
||||
|
||||
u_int
|
||||
buffer_len(Buffer *buffer)
|
||||
{
|
||||
return buffer->end - buffer->offset;
|
||||
}
|
||||
|
||||
/* Gets data from the beginning of the buffer. */
|
||||
|
||||
int
|
||||
buffer_get_ret(Buffer *buffer, void *buf, u_int len)
|
||||
{
|
||||
if (len > buffer->end - buffer->offset) {
|
||||
error("buffer_get_ret: trying to get more bytes %d than in buffer %d",
|
||||
len, buffer->end - buffer->offset);
|
||||
return (-1);
|
||||
}
|
||||
memcpy(buf, buffer->buf + buffer->offset, len);
|
||||
buffer->offset += len;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_get(Buffer *buffer, void *buf, u_int len)
|
||||
{
|
||||
if (buffer_get_ret(buffer, buf, len) == -1)
|
||||
fatal("buffer_get: buffer error");
|
||||
}
|
||||
|
||||
/* Consumes the given number of bytes from the beginning of the buffer. */
|
||||
|
||||
int
|
||||
buffer_consume_ret(Buffer *buffer, u_int bytes)
|
||||
{
|
||||
if (bytes > buffer->end - buffer->offset) {
|
||||
error("buffer_consume_ret: trying to get more bytes than in buffer");
|
||||
return (-1);
|
||||
}
|
||||
buffer->offset += bytes;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_consume(Buffer *buffer, u_int bytes)
|
||||
{
|
||||
if (buffer_consume_ret(buffer, bytes) == -1)
|
||||
fatal("buffer_consume: buffer error");
|
||||
}
|
||||
|
||||
/* Consumes the given number of bytes from the end of the buffer. */
|
||||
|
||||
int
|
||||
buffer_consume_end_ret(Buffer *buffer, u_int bytes)
|
||||
{
|
||||
if (bytes > buffer->end - buffer->offset)
|
||||
return (-1);
|
||||
buffer->end -= bytes;
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
buffer_consume_end(Buffer *buffer, u_int bytes)
|
||||
{
|
||||
if (buffer_consume_end_ret(buffer, bytes) == -1)
|
||||
fatal("buffer_consume_end: trying to get more bytes than in buffer");
|
||||
}
|
||||
|
||||
/* Returns a pointer to the first used byte in the buffer. */
|
||||
|
||||
void *
|
||||
buffer_ptr(Buffer *buffer)
|
||||
{
|
||||
return buffer->buf + buffer->offset;
|
||||
}
|
||||
|
||||
/* Dumps the contents of the buffer to stderr. */
|
||||
|
||||
void
|
||||
buffer_dump(Buffer *buffer)
|
||||
{
|
||||
u_int i;
|
||||
u_char *ucp = buffer->buf;
|
||||
|
||||
for (i = buffer->offset; i < buffer->end; i++) {
|
||||
fprintf(stderr, "%02x", ucp[i]);
|
||||
if ((i-buffer->offset)%16==15)
|
||||
fprintf(stderr, "\r\n");
|
||||
else if ((i-buffer->offset)%2==1)
|
||||
fprintf(stderr, " ");
|
||||
}
|
||||
fprintf(stderr, "\r\n");
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/* $OpenBSD: buffer.h,v 1.16 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Code for manipulating FIFO 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".
|
||||
*/
|
||||
|
||||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
|
||||
typedef struct {
|
||||
u_char *buf; /* Buffer for data. */
|
||||
u_int alloc; /* Number of bytes allocated for data. */
|
||||
u_int offset; /* Offset of first byte containing data. */
|
||||
u_int end; /* Offset of last byte containing data. */
|
||||
} Buffer;
|
||||
|
||||
void buffer_init(Buffer *);
|
||||
void buffer_clear(Buffer *);
|
||||
void buffer_free(Buffer *);
|
||||
|
||||
u_int buffer_len(Buffer *);
|
||||
void *buffer_ptr(Buffer *);
|
||||
|
||||
void buffer_append(Buffer *, const void *, u_int);
|
||||
void *buffer_append_space(Buffer *, u_int);
|
||||
|
||||
int buffer_check_alloc(Buffer *, u_int);
|
||||
|
||||
void buffer_get(Buffer *, void *, u_int);
|
||||
|
||||
void buffer_consume(Buffer *, u_int);
|
||||
void buffer_consume_end(Buffer *, u_int);
|
||||
|
||||
void buffer_dump(Buffer *);
|
||||
|
||||
int buffer_get_ret(Buffer *, void *, u_int);
|
||||
int buffer_consume_ret(Buffer *, u_int);
|
||||
int buffer_consume_end_ret(Buffer *, u_int);
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
void buffer_put_bignum(Buffer *, const BIGNUM *);
|
||||
void buffer_put_bignum2(Buffer *, const BIGNUM *);
|
||||
void buffer_get_bignum(Buffer *, BIGNUM *);
|
||||
void buffer_get_bignum2(Buffer *, BIGNUM *);
|
||||
|
||||
u_short buffer_get_short(Buffer *);
|
||||
void buffer_put_short(Buffer *, u_short);
|
||||
|
||||
u_int buffer_get_int(Buffer *);
|
||||
void buffer_put_int(Buffer *, u_int);
|
||||
|
||||
u_int64_t buffer_get_int64(Buffer *);
|
||||
void buffer_put_int64(Buffer *, u_int64_t);
|
||||
|
||||
int buffer_get_char(Buffer *);
|
||||
void buffer_put_char(Buffer *, int);
|
||||
|
||||
void *buffer_get_string(Buffer *, u_int *);
|
||||
void buffer_put_string(Buffer *, const void *, u_int);
|
||||
void buffer_put_cstring(Buffer *, const char *);
|
||||
|
||||
#define buffer_skip_string(b) \
|
||||
do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while (0)
|
||||
|
||||
int buffer_put_bignum_ret(Buffer *, const BIGNUM *);
|
||||
int buffer_get_bignum_ret(Buffer *, BIGNUM *);
|
||||
int buffer_put_bignum2_ret(Buffer *, const BIGNUM *);
|
||||
int buffer_get_bignum2_ret(Buffer *, BIGNUM *);
|
||||
int buffer_get_short_ret(u_short *, Buffer *);
|
||||
int buffer_get_int_ret(u_int *, Buffer *);
|
||||
int buffer_get_int64_ret(u_int64_t *, Buffer *);
|
||||
void *buffer_get_string_ret(Buffer *, u_int *);
|
||||
int buffer_get_char_ret(char *, Buffer *);
|
||||
|
||||
#endif /* BUFFER_H */
|
@ -1,682 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Fake Root Solaris/SVR4/SVR5 Build System - Prototype
|
||||
#
|
||||
# The following code has been provide under Public Domain License. I really
|
||||
# don't care what you use it for. Just as long as you don't complain to me
|
||||
# nor my employer if you break it. - Ben Lindstrom (mouring@eviladmin.org)
|
||||
#
|
||||
umask 022
|
||||
#
|
||||
# Options for building the package
|
||||
# You can create a openssh-config.local with your customized options
|
||||
#
|
||||
REMOVE_FAKE_ROOT_WHEN_DONE=yes
|
||||
#
|
||||
# uncommenting TEST_DIR and using
|
||||
# configure --prefix=/var/tmp --with-privsep-path=/var/tmp/empty
|
||||
# and
|
||||
# PKGNAME=tOpenSSH should allow testing a package without interfering
|
||||
# with a real OpenSSH package on a system. This is not needed on systems
|
||||
# that support the -R option to pkgadd.
|
||||
#TEST_DIR=/var/tmp # leave commented out for production build
|
||||
PKGNAME=OpenSSH
|
||||
# revisions within the same version (REV=a)
|
||||
#REV=
|
||||
SYSVINIT_NAME=opensshd
|
||||
AWK=${AWK:="nawk"}
|
||||
MAKE=${MAKE:="make"}
|
||||
SSHDUID=67 # Default privsep uid
|
||||
SSHDGID=67 # Default privsep gid
|
||||
# uncomment these next three as needed
|
||||
#PERMIT_ROOT_LOGIN=no
|
||||
#X11_FORWARDING=yes
|
||||
#USR_LOCAL_IS_SYMLINK=yes
|
||||
# System V init run levels
|
||||
SYSVINITSTART=S98
|
||||
SYSVINITSTOPT=K30
|
||||
# We will source these if they exist
|
||||
POST_MAKE_INSTALL_FIXES=./pkg-post-make-install-fixes.sh
|
||||
POST_PROTOTYPE_EDITS=./pkg-post-prototype-edit.sh
|
||||
# We'll be one level deeper looking for these
|
||||
PKG_PREINSTALL_LOCAL=../pkg-preinstall.local
|
||||
PKG_POSTINSTALL_LOCAL=../pkg-postinstall.local
|
||||
PKG_PREREMOVE_LOCAL=../pkg-preremove.local
|
||||
PKG_POSTREMOVE_LOCAL=../pkg-postremove.local
|
||||
PKG_REQUEST_LOCAL=../pkg-request.local
|
||||
# end of sourced files
|
||||
#
|
||||
OPENSSHD=opensshd.init
|
||||
OPENSSH_MANIFEST=openssh.xml
|
||||
OPENSSH_FMRI=svc:/site/openssh:default
|
||||
|
||||
PATH_GROUPADD_PROG=@PATH_GROUPADD_PROG@
|
||||
PATH_USERADD_PROG=@PATH_USERADD_PROG@
|
||||
PATH_PASSWD_PROG=@PATH_PASSWD_PROG@
|
||||
#
|
||||
# list of system directories we do NOT want to change owner/group/perms
|
||||
# when installing our package
|
||||
SYSTEM_DIR="/etc \
|
||||
/etc/init.d \
|
||||
/etc/rcS.d \
|
||||
/etc/rc0.d \
|
||||
/etc/rc1.d \
|
||||
/etc/rc2.d \
|
||||
/etc/opt \
|
||||
/lib \
|
||||
/lib/svc \
|
||||
/lib/svc/method \
|
||||
/lib/svc/method/site \
|
||||
/opt \
|
||||
/opt/bin \
|
||||
/usr \
|
||||
/usr/bin \
|
||||
/usr/lib \
|
||||
/usr/sbin \
|
||||
/usr/share \
|
||||
/usr/share/man \
|
||||
/usr/share/man/man1 \
|
||||
/usr/share/man/man8 \
|
||||
/usr/local \
|
||||
/usr/local/bin \
|
||||
/usr/local/etc \
|
||||
/usr/local/libexec \
|
||||
/usr/local/man \
|
||||
/usr/local/man/man1 \
|
||||
/usr/local/man/man8 \
|
||||
/usr/local/sbin \
|
||||
/usr/local/share \
|
||||
/var \
|
||||
/var/opt \
|
||||
/var/run \
|
||||
/var/svc \
|
||||
/var/svc/manifest \
|
||||
/var/svc/manifest/site \
|
||||
/var/tmp \
|
||||
/tmp"
|
||||
|
||||
# We may need to build as root so we make sure PATH is set up
|
||||
# only set the path if it's not set already
|
||||
[ -d /opt/bin ] && {
|
||||
echo $PATH | grep ":/opt/bin" > /dev/null 2>&1
|
||||
[ $? -ne 0 ] && PATH=$PATH:/opt/bin
|
||||
}
|
||||
[ -d /usr/local/bin ] && {
|
||||
echo $PATH | grep ":/usr/local/bin" > /dev/null 2>&1
|
||||
[ $? -ne 0 ] && PATH=$PATH:/usr/local/bin
|
||||
}
|
||||
[ -d /usr/ccs/bin ] && {
|
||||
echo $PATH | grep ":/usr/ccs/bin" > /dev/null 2>&1
|
||||
[ $? -ne 0 ] && PATH=$PATH:/usr/ccs/bin
|
||||
}
|
||||
export PATH
|
||||
#
|
||||
|
||||
[ -f Makefile ] || {
|
||||
echo "Please run this script from your build directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# we will look for openssh-config.local to override the above options
|
||||
[ -s ./openssh-config.local ] && . ./openssh-config.local
|
||||
|
||||
START=`pwd`
|
||||
FAKE_ROOT=$START/pkg
|
||||
|
||||
## Fill in some details, like prefix and sysconfdir
|
||||
for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir sysconfdir piddir srcdir
|
||||
do
|
||||
eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2`
|
||||
done
|
||||
|
||||
## Are we using Solaris' SMF?
|
||||
DO_SMF=0
|
||||
if egrep "^#define USE_SOLARIS_PROCESS_CONTRACTS" config.h > /dev/null 2>&1
|
||||
then
|
||||
DO_SMF=1
|
||||
fi
|
||||
|
||||
## Collect value of privsep user
|
||||
for confvar in SSH_PRIVSEP_USER
|
||||
do
|
||||
eval $confvar=`awk '/#define[ \t]'$confvar'/{print $3}' config.h`
|
||||
done
|
||||
|
||||
## Set privsep defaults if not defined
|
||||
if [ -z "$SSH_PRIVSEP_USER" ]
|
||||
then
|
||||
SSH_PRIVSEP_USER=sshd
|
||||
fi
|
||||
|
||||
## Extract common info requires for the 'info' part of the package.
|
||||
VERSION=`./ssh -V 2>&1 | sed -e 's/,.*//'`
|
||||
|
||||
ARCH=`uname -m`
|
||||
DEF_MSG="\n"
|
||||
OS_VER=`uname -v`
|
||||
SCRIPT_SHELL=/sbin/sh
|
||||
UNAME_R=`uname -r`
|
||||
UNAME_S=`uname -s`
|
||||
case ${UNAME_S} in
|
||||
SunOS) UNAME_S=Solaris
|
||||
OS_VER=${UNAME_R}
|
||||
ARCH=`uname -p`
|
||||
RCS_D=yes
|
||||
DEF_MSG="(default: n)"
|
||||
;;
|
||||
SCO_SV) case ${UNAME_R} in
|
||||
3.2) UNAME_S=OpenServer5
|
||||
OS_VER=`uname -X | grep Release | sed -e 's/^Rel.*3.2v//'`
|
||||
;;
|
||||
5) UNAME_S=OpenServer6
|
||||
;;
|
||||
esac
|
||||
SCRIPT_SHELL=/bin/sh
|
||||
RC1_D=no
|
||||
DEF_MSG="(default: n)"
|
||||
;;
|
||||
esac
|
||||
|
||||
case `basename $0` in
|
||||
buildpkg.sh)
|
||||
## Start by faking root install
|
||||
echo "Faking root install..."
|
||||
[ -d $FAKE_ROOT ] && rm -fr $FAKE_ROOT
|
||||
mkdir $FAKE_ROOT
|
||||
${MAKE} install-nokeys DESTDIR=$FAKE_ROOT
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
echo "Fake root install failed, stopping."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
## Setup our run level stuff while we are at it.
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# For Solaris' SMF, /lib/svc/method/site is the preferred place
|
||||
# for start/stop scripts that aren't supplied with the OS, and
|
||||
# similarly /var/svc/manifest/site for manifests.
|
||||
mkdir -p $FAKE_ROOT${TEST_DIR}/lib/svc/method/site
|
||||
mkdir -p $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site
|
||||
|
||||
cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/lib/svc/method/site/${SYSVINIT_NAME}
|
||||
chmod 744 $FAKE_ROOT${TEST_DIR}/lib/svc/method/site/${SYSVINIT_NAME}
|
||||
|
||||
cp ${OPENSSH_MANIFEST} $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site
|
||||
chmod 644 $FAKE_ROOT${TEST_DIR}/var/svc/manifest/site/${OPENSSH_MANIFEST}
|
||||
else
|
||||
mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d
|
||||
|
||||
cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
|
||||
chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME}
|
||||
fi
|
||||
|
||||
[ "${PERMIT_ROOT_LOGIN}" = no ] && \
|
||||
perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \
|
||||
$FAKE_ROOT/${sysconfdir}/sshd_config
|
||||
[ "${X11_FORWARDING}" = yes ] && \
|
||||
perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \
|
||||
$FAKE_ROOT/${sysconfdir}/sshd_config
|
||||
# fix PrintMotd
|
||||
perl -p -i -e "s/#PrintMotd yes/PrintMotd no/" \
|
||||
$FAKE_ROOT/${sysconfdir}/sshd_config
|
||||
|
||||
# We don't want to overwrite config files on multiple installs
|
||||
mv $FAKE_ROOT/${sysconfdir}/ssh_config $FAKE_ROOT/${sysconfdir}/ssh_config.default
|
||||
mv $FAKE_ROOT/${sysconfdir}/sshd_config $FAKE_ROOT/${sysconfdir}/sshd_config.default
|
||||
[ -f $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds ] && \
|
||||
mv $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds.default
|
||||
|
||||
# local tweeks here
|
||||
[ -s "${POST_MAKE_INSTALL_FIXES}" ] && . ${POST_MAKE_INSTALL_FIXES}
|
||||
|
||||
cd $FAKE_ROOT
|
||||
|
||||
## Ok, this is outright wrong, but it will work. I'm tired of pkgmk
|
||||
## whining.
|
||||
for i in *; do
|
||||
PROTO_ARGS="$PROTO_ARGS $i=/$i";
|
||||
done
|
||||
|
||||
## Build info file
|
||||
echo "Building pkginfo file..."
|
||||
cat > pkginfo << _EOF
|
||||
PKG=$PKGNAME
|
||||
NAME="OpenSSH Portable for ${UNAME_S}"
|
||||
DESC="Secure Shell remote access utility; replaces telnet and rlogin/rsh."
|
||||
VENDOR="OpenSSH Portable Team - http://www.openssh.com/portable.html"
|
||||
ARCH=$ARCH
|
||||
VERSION=$VERSION$REV
|
||||
CATEGORY="Security,application"
|
||||
BASEDIR=/
|
||||
CLASSES="none"
|
||||
PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`"
|
||||
_EOF
|
||||
|
||||
## Build empty depend file that may get updated by $POST_PROTOTYPE_EDITS
|
||||
echo "Building depend file..."
|
||||
touch depend
|
||||
|
||||
## Build space file
|
||||
echo "Building space file..."
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# XXX Is this necessary? If not, remove space line from mk-proto.awk.
|
||||
touch space
|
||||
else
|
||||
cat > space << _EOF
|
||||
# extra space required by start/stop links added by installf
|
||||
# in postinstall
|
||||
$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1
|
||||
$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1
|
||||
_EOF
|
||||
[ "$RC1_D" = no ] || \
|
||||
echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space
|
||||
[ "$RCS_D" = yes ] && \
|
||||
echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space
|
||||
fi
|
||||
|
||||
## Build preinstall file
|
||||
echo "Building preinstall file..."
|
||||
cat > preinstall << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
_EOF
|
||||
|
||||
# local preinstall changes here
|
||||
[ -s "${PKG_PREINSTALL_LOCAL}" ] && . ${PKG_PREINSTALL_LOCAL}
|
||||
|
||||
cat >> preinstall << _EOF
|
||||
#
|
||||
if [ "\${PRE_INS_STOP}" = "yes" ]
|
||||
then
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
svcadm disable $OPENSSH_FMRI
|
||||
else
|
||||
${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build postinstall file
|
||||
echo "Building postinstall file..."
|
||||
cat > postinstall << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config ] || \\
|
||||
cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config.default \\
|
||||
\${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config
|
||||
[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config ] || \\
|
||||
cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config.default \\
|
||||
\${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config
|
||||
[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds.default ] && {
|
||||
[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds ] || \\
|
||||
cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds.default \\
|
||||
\${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds
|
||||
}
|
||||
|
||||
# make rc?.d dirs only if we are doing a test install
|
||||
[ -n "${TEST_DIR}" ] && [ $DO_SMF -ne 1 ] && {
|
||||
[ "$RCS_D" = yes ] && mkdir -p ${TEST_DIR}/etc/rcS.d
|
||||
mkdir -p ${TEST_DIR}/etc/rc0.d
|
||||
[ "$RC1_D" = no ] || mkdir -p ${TEST_DIR}/etc/rc1.d
|
||||
mkdir -p ${TEST_DIR}/etc/rc2.d
|
||||
}
|
||||
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# Delete the existing service, if it exists, then import the
|
||||
# new one.
|
||||
if svcs $OPENSSH_FMRI > /dev/null 2>&1
|
||||
then
|
||||
svccfg delete -f $OPENSSH_FMRI
|
||||
fi
|
||||
# NOTE, if manifest enables sshd by default, this will actually
|
||||
# start the daemon, which may not be what the user wants.
|
||||
svccfg import ${TEST_DIR}/var/svc/manifest/site/$OPENSSH_MANIFEST
|
||||
else
|
||||
if [ "\${USE_SYM_LINKS}" = yes ]
|
||||
then
|
||||
[ "$RCS_D" = yes ] && \
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
|
||||
[ "$RC1_D" = no ] || \
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s
|
||||
else
|
||||
[ "$RCS_D" = yes ] && \
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
|
||||
[ "$RC1_D" = no ] || \
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
|
||||
installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l
|
||||
fi
|
||||
fi
|
||||
|
||||
# If piddir doesn't exist we add it. (Ie. --with-pid-dir=/var/opt/ssh)
|
||||
[ -d $piddir ] || installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR$piddir d 0755 root sys
|
||||
|
||||
_EOF
|
||||
|
||||
# local postinstall changes here
|
||||
[ -s "${PKG_POSTINSTALL_LOCAL}" ] && . ${PKG_POSTINSTALL_LOCAL}
|
||||
|
||||
cat >> postinstall << _EOF
|
||||
installf -f ${PKGNAME}
|
||||
|
||||
# Use chroot to handle PKG_INSTALL_ROOT
|
||||
if [ ! -z "\${PKG_INSTALL_ROOT}" ]
|
||||
then
|
||||
chroot="chroot \${PKG_INSTALL_ROOT}"
|
||||
fi
|
||||
# If this is a test build, we will skip the groupadd/useradd/passwd commands
|
||||
if [ ! -z "${TEST_DIR}" ]
|
||||
then
|
||||
chroot=echo
|
||||
fi
|
||||
|
||||
echo "PrivilegeSeparation user always required."
|
||||
if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null
|
||||
then
|
||||
echo "PrivSep user $SSH_PRIVSEP_USER already exists."
|
||||
SSH_PRIVSEP_GROUP=\`grep "^$SSH_PRIVSEP_USER:" \${PKG_INSTALL_ROOT}/etc/passwd | awk -F: '{print \$4}'\`
|
||||
SSH_PRIVSEP_GROUP=\`grep ":\$SSH_PRIVSEP_GROUP:" \${PKG_INSTALL_ROOT}/etc/group | awk -F: '{print \$1}'\`
|
||||
else
|
||||
DO_PASSWD=yes
|
||||
fi
|
||||
[ -z "\$SSH_PRIVSEP_GROUP" ] && SSH_PRIVSEP_GROUP=$SSH_PRIVSEP_USER
|
||||
|
||||
# group required?
|
||||
if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'\$SSH_PRIVSEP_GROUP'\$' >/dev/null
|
||||
then
|
||||
echo "PrivSep group \$SSH_PRIVSEP_GROUP already exists."
|
||||
else
|
||||
DO_GROUP=yes
|
||||
fi
|
||||
|
||||
# create group if required
|
||||
[ "\$DO_GROUP" = yes ] && {
|
||||
# Use gid of 67 if possible
|
||||
if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'$SSHDGID'\$' >/dev/null
|
||||
then
|
||||
:
|
||||
else
|
||||
sshdgid="-g $SSHDGID"
|
||||
fi
|
||||
echo "Creating PrivSep group \$SSH_PRIVSEP_GROUP."
|
||||
\$chroot ${PATH_GROUPADD_PROG} \$sshdgid \$SSH_PRIVSEP_GROUP
|
||||
}
|
||||
|
||||
# Create user if required
|
||||
[ "\$DO_PASSWD" = yes ] && {
|
||||
# Use uid of 67 if possible
|
||||
if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSHDUID'\$' >/dev/null
|
||||
then
|
||||
:
|
||||
else
|
||||
sshduid="-u $SSHDUID"
|
||||
fi
|
||||
echo "Creating PrivSep user $SSH_PRIVSEP_USER."
|
||||
\$chroot ${PATH_USERADD_PROG} -c 'SSHD PrivSep User' -s /bin/false -g $SSH_PRIVSEP_USER \$sshduid $SSH_PRIVSEP_USER
|
||||
\$chroot ${PATH_PASSWD_PROG} -l $SSH_PRIVSEP_USER
|
||||
}
|
||||
|
||||
if [ "\${POST_INS_START}" = "yes" ]
|
||||
then
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# See svccfg import note above. The service may already
|
||||
# be started.
|
||||
svcadm enable $OPENSSH_FMRI
|
||||
else
|
||||
${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build preremove file
|
||||
echo "Building preremove file..."
|
||||
cat > preremove << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
svcadm disable $OPENSSH_FMRI
|
||||
else
|
||||
${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop
|
||||
fi
|
||||
_EOF
|
||||
|
||||
# local preremove changes here
|
||||
[ -s "${PKG_PREREMOVE_LOCAL}" ] && . ${PKG_PREREMOVE_LOCAL}
|
||||
|
||||
cat >> preremove << _EOF
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build postremove file
|
||||
echo "Building postremove file..."
|
||||
cat > postremove << _EOF
|
||||
#! ${SCRIPT_SHELL}
|
||||
#
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
if svcs $OPENSSH_FMRI > /dev/null 2>&1
|
||||
then
|
||||
svccfg delete -f $OPENSSH_FMRI
|
||||
fi
|
||||
fi
|
||||
_EOF
|
||||
|
||||
# local postremove changes here
|
||||
[ -s "${PKG_POSTREMOVE_LOCAL}" ] && . ${PKG_POSTREMOVE_LOCAL}
|
||||
|
||||
cat >> postremove << _EOF
|
||||
exit 0
|
||||
_EOF
|
||||
|
||||
## Build request file
|
||||
echo "Building request file..."
|
||||
cat > request << _EOF
|
||||
trap 'exit 3' 15
|
||||
|
||||
_EOF
|
||||
|
||||
[ -x /usr/bin/ckyorn ] || cat >> request << _EOF
|
||||
|
||||
ckyorn() {
|
||||
# for some strange reason OpenServer5 has no ckyorn
|
||||
# We build a striped down version here
|
||||
|
||||
DEFAULT=n
|
||||
PROMPT="Yes or No [yes,no,?,quit]"
|
||||
HELP_PROMPT=" Enter y or yes if your answer is yes; n or no if your answer is no."
|
||||
USAGE="usage: ckyorn [options]
|
||||
where options may include:
|
||||
-d default
|
||||
-h help
|
||||
-p prompt
|
||||
"
|
||||
|
||||
if [ \$# != 0 ]
|
||||
then
|
||||
while getopts d:p:h: c
|
||||
do
|
||||
case \$c in
|
||||
h) HELP_PROMPT="\$OPTARG" ;;
|
||||
d) DEFAULT=\$OPTARG ;;
|
||||
p) PROMPT=\$OPTARG ;;
|
||||
\\?) echo "\$USAGE" 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
shift \`expr \$OPTIND - 1\`
|
||||
fi
|
||||
|
||||
while true
|
||||
do
|
||||
echo "\${PROMPT}\\c " 1>&2
|
||||
read key
|
||||
[ -z "\$key" ] && key=\$DEFAULT
|
||||
case \$key in
|
||||
[n,N]|[n,N][o,O]|[y,Y]|[y,Y][e,E][s,S]) echo "\${key}\\c"
|
||||
exit 0 ;;
|
||||
\\?) echo \$HELP_PROMPT 1>&2 ;;
|
||||
q|quit) echo "q\\c" 1>&2
|
||||
exit 3 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
_EOF
|
||||
|
||||
if [ $DO_SMF -eq 1 ]
|
||||
then
|
||||
# This could get hairy, as the running sshd may not be under SMF.
|
||||
# We'll assume an earlier version of OpenSSH started via SMF.
|
||||
cat >> request << _EOF
|
||||
PRE_INS_STOP=no
|
||||
POST_INS_START=no
|
||||
# determine if should restart the daemon
|
||||
if [ -s ${piddir}/sshd.pid ] && \
|
||||
/usr/bin/svcs $OPENSSH_FMRI 2>&1 | egrep "^online" > /dev/null 2>&1
|
||||
then
|
||||
ans=\`ckyorn -d n \
|
||||
-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) PRE_INS_STOP=yes
|
||||
POST_INS_START=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
|
||||
# determine if we should start sshd
|
||||
ans=\`ckyorn -d n \
|
||||
-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) POST_INS_START=yes ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# make parameters available to installation service,
|
||||
# and so to any other packaging scripts
|
||||
cat >\$1 <<!
|
||||
PRE_INS_STOP='\$PRE_INS_STOP'
|
||||
POST_INS_START='\$POST_INS_START'
|
||||
!
|
||||
|
||||
_EOF
|
||||
else
|
||||
cat >> request << _EOF
|
||||
USE_SYM_LINKS=no
|
||||
PRE_INS_STOP=no
|
||||
POST_INS_START=no
|
||||
# Use symbolic links?
|
||||
ans=\`ckyorn -d n \
|
||||
-p "Do you want symbolic links for the start/stop scripts? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) USE_SYM_LINKS=yes ;;
|
||||
esac
|
||||
|
||||
# determine if should restart the daemon
|
||||
if [ -s ${piddir}/sshd.pid -a -f ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} ]
|
||||
then
|
||||
ans=\`ckyorn -d n \
|
||||
-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) PRE_INS_STOP=yes
|
||||
POST_INS_START=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
|
||||
# determine if we should start sshd
|
||||
ans=\`ckyorn -d n \
|
||||
-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$?
|
||||
case \$ans in
|
||||
[y,Y]*) POST_INS_START=yes ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# make parameters available to installation service,
|
||||
# and so to any other packaging scripts
|
||||
cat >\$1 <<!
|
||||
USE_SYM_LINKS='\$USE_SYM_LINKS'
|
||||
PRE_INS_STOP='\$PRE_INS_STOP'
|
||||
POST_INS_START='\$POST_INS_START'
|
||||
!
|
||||
|
||||
_EOF
|
||||
fi
|
||||
|
||||
# local request changes here
|
||||
[ -s "${PKG_REQUEST_LOCAL}" ] && . ${PKG_REQUEST_LOCAL}
|
||||
|
||||
cat >> request << _EOF
|
||||
exit 0
|
||||
|
||||
_EOF
|
||||
|
||||
## Next Build our prototype
|
||||
echo "Building prototype file..."
|
||||
cat >mk-proto.awk << _EOF
|
||||
BEGIN { print "i pkginfo"; print "i depend"; \\
|
||||
print "i preinstall"; print "i postinstall"; \\
|
||||
print "i preremove"; print "i postremove"; \\
|
||||
print "i request"; print "i space"; \\
|
||||
split("$SYSTEM_DIR",sys_files); }
|
||||
{
|
||||
for (dir in sys_files) { if ( \$3 != sys_files[dir] )
|
||||
{ if ( \$1 == "s" )
|
||||
{ \$5=""; \$6=""; }
|
||||
else
|
||||
{ \$5="root"; \$6="sys"; }
|
||||
}
|
||||
else
|
||||
{ \$4="?"; \$5="?"; \$6="?"; break;}
|
||||
} }
|
||||
{ print; }
|
||||
_EOF
|
||||
|
||||
find . | egrep -v "prototype|pkginfo|mk-proto.awk" | sort | \
|
||||
pkgproto $PROTO_ARGS | ${AWK} -f mk-proto.awk > prototype
|
||||
|
||||
# /usr/local is a symlink on some systems
|
||||
[ "${USR_LOCAL_IS_SYMLINK}" = yes ] && {
|
||||
grep -v "^d none /usr/local ? ? ?$" prototype > prototype.new
|
||||
mv prototype.new prototype
|
||||
}
|
||||
|
||||
## Step back a directory and now build the package.
|
||||
cd ..
|
||||
# local prototype tweeks here
|
||||
[ -s "${POST_PROTOTYPE_EDITS}" ] && . ${POST_PROTOTYPE_EDITS}
|
||||
|
||||
echo "Building package.."
|
||||
pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o
|
||||
echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg
|
||||
;;
|
||||
|
||||
justpkg.sh)
|
||||
rm -fr ${FAKE_ROOT}/${PKGNAME}
|
||||
grep -v "^PSTAMP=" $FAKE_ROOT/pkginfo > $$tmp
|
||||
mv $$tmp $FAKE_ROOT/pkginfo
|
||||
cat >> $FAKE_ROOT/pkginfo << _EOF
|
||||
PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`"
|
||||
_EOF
|
||||
pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o
|
||||
echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
[ "${REMOVE_FAKE_ROOT_WHEN_DONE}" = yes ] && rm -rf $FAKE_ROOT
|
||||
exit 0
|
||||
|
@ -1,417 +0,0 @@
|
||||
/* $OpenBSD: canohost.c,v 1.61 2006/08/03 03:34:41 deraadt Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for returning the canonical host name of the remote site.
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "packet.h"
|
||||
#include "log.h"
|
||||
#include "canohost.h"
|
||||
|
||||
static void check_ip_options(int, char *);
|
||||
|
||||
/*
|
||||
* Return the canonical name of the host at the other end of the socket. The
|
||||
* caller should free the returned string with xfree.
|
||||
*/
|
||||
|
||||
static char *
|
||||
get_remote_hostname(int sock, int use_dns)
|
||||
{
|
||||
struct sockaddr_storage from;
|
||||
int i;
|
||||
socklen_t fromlen;
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST];
|
||||
|
||||
/* Get IP address of client. */
|
||||
fromlen = sizeof(from);
|
||||
memset(&from, 0, sizeof(from));
|
||||
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
|
||||
debug("getpeername failed: %.100s", strerror(errno));
|
||||
cleanup_exit(255);
|
||||
}
|
||||
|
||||
if (from.ss_family == AF_INET)
|
||||
check_ip_options(sock, ntop);
|
||||
|
||||
ipv64_normalise_mapped(&from, &fromlen);
|
||||
|
||||
if (from.ss_family == AF_INET6)
|
||||
fromlen = sizeof(struct sockaddr_in6);
|
||||
|
||||
if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop),
|
||||
NULL, 0, NI_NUMERICHOST) != 0)
|
||||
fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
|
||||
|
||||
if (!use_dns)
|
||||
return xstrdup(ntop);
|
||||
|
||||
debug3("Trying to reverse map address %.100s.", ntop);
|
||||
/* Map the IP address to a host name. */
|
||||
if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
|
||||
NULL, 0, NI_NAMEREQD) != 0) {
|
||||
/* Host name not found. Use ip address. */
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
|
||||
/*
|
||||
* if reverse lookup result looks like a numeric hostname,
|
||||
* someone is trying to trick us by PTR record like following:
|
||||
* 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
|
||||
*/
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
if (getaddrinfo(name, "0", &hints, &ai) == 0) {
|
||||
logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
|
||||
name, ntop);
|
||||
freeaddrinfo(ai);
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert it to all lowercase (which is expected by the rest
|
||||
* of this software).
|
||||
*/
|
||||
for (i = 0; name[i]; i++)
|
||||
if (isupper(name[i]))
|
||||
name[i] = (char)tolower(name[i]);
|
||||
/*
|
||||
* Map it back to an IP address and check that the given
|
||||
* address actually is an address of this host. This is
|
||||
* necessary because anyone with access to a name server can
|
||||
* define arbitrary names for an IP address. Mapping from
|
||||
* name to IP address can be trusted better (but can still be
|
||||
* fooled if the intruder has access to the name server of
|
||||
* the domain).
|
||||
*/
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = from.ss_family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
|
||||
logit("reverse mapping checking getaddrinfo for %.700s "
|
||||
"[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop);
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
/* Look for the address from the list of addresses. */
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
|
||||
sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
|
||||
(strcmp(ntop, ntop2) == 0))
|
||||
break;
|
||||
}
|
||||
freeaddrinfo(aitop);
|
||||
/* If we reached the end of the list, the address was not there. */
|
||||
if (!ai) {
|
||||
/* Address not found for the host name. */
|
||||
logit("Address %.100s maps to %.600s, but this does not "
|
||||
"map back to the address - POSSIBLE BREAK-IN ATTEMPT!",
|
||||
ntop, name);
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
return xstrdup(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* If IP options are supported, make sure there are none (log and
|
||||
* disconnect them if any are found). Basically we are worried about
|
||||
* source routing; it can be used to pretend you are somebody
|
||||
* (ip-address) you are not. That itself may be "almost acceptable"
|
||||
* under certain circumstances, but rhosts autentication is useless
|
||||
* if source routing is accepted. Notice also that if we just dropped
|
||||
* source routing here, the other side could use IP spoofing to do
|
||||
* rest of the interaction and could still bypass security. So we
|
||||
* exit here if we detect any IP options.
|
||||
*/
|
||||
/* IPv4 only */
|
||||
static void
|
||||
check_ip_options(int sock, char *ipaddr)
|
||||
{
|
||||
#ifdef IP_OPTIONS
|
||||
u_char options[200];
|
||||
char text[sizeof(options) * 3 + 1];
|
||||
socklen_t option_size;
|
||||
u_int i;
|
||||
int ipproto;
|
||||
struct protoent *ip;
|
||||
|
||||
if ((ip = getprotobyname("ip")) != NULL)
|
||||
ipproto = ip->p_proto;
|
||||
else
|
||||
ipproto = IPPROTO_IP;
|
||||
option_size = sizeof(options);
|
||||
if (getsockopt(sock, ipproto, IP_OPTIONS, options,
|
||||
&option_size) >= 0 && option_size != 0) {
|
||||
text[0] = '\0';
|
||||
for (i = 0; i < option_size; i++)
|
||||
snprintf(text + i*3, sizeof(text) - i*3,
|
||||
" %2.2x", options[i]);
|
||||
fatal("Connection from %.100s with IP options:%.800s",
|
||||
ipaddr, text);
|
||||
}
|
||||
#endif /* IP_OPTIONS */
|
||||
}
|
||||
|
||||
void
|
||||
ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
|
||||
{
|
||||
struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
|
||||
struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
|
||||
struct in_addr inaddr;
|
||||
u_int16_t port;
|
||||
|
||||
if (addr->ss_family != AF_INET6 ||
|
||||
!IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
|
||||
return;
|
||||
|
||||
debug3("Normalising mapped IPv4 in IPv6 address");
|
||||
|
||||
memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
|
||||
port = a6->sin6_port;
|
||||
|
||||
memset(addr, 0, sizeof(*a4));
|
||||
|
||||
a4->sin_family = AF_INET;
|
||||
*len = sizeof(*a4);
|
||||
memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
|
||||
a4->sin_port = port;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the canonical name of the host in the other side of the current
|
||||
* connection. The host name is cached, so it is efficient to call this
|
||||
* several times.
|
||||
*/
|
||||
|
||||
const char *
|
||||
get_canonical_hostname(int use_dns)
|
||||
{
|
||||
char *host;
|
||||
static char *canonical_host_name = NULL;
|
||||
static char *remote_ip = NULL;
|
||||
|
||||
/* Check if we have previously retrieved name with same option. */
|
||||
if (use_dns && canonical_host_name != NULL)
|
||||
return canonical_host_name;
|
||||
if (!use_dns && remote_ip != NULL)
|
||||
return remote_ip;
|
||||
|
||||
/* Get the real hostname if socket; otherwise return UNKNOWN. */
|
||||
if (packet_connection_is_on_socket())
|
||||
host = get_remote_hostname(packet_get_connection_in(), use_dns);
|
||||
else
|
||||
host = "UNKNOWN";
|
||||
|
||||
if (use_dns)
|
||||
canonical_host_name = host;
|
||||
else
|
||||
remote_ip = host;
|
||||
return host;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the local/remote IP-address/hostname of socket as a string.
|
||||
* The returned string must be freed.
|
||||
*/
|
||||
static char *
|
||||
get_socket_address(int sock, int remote, int flags)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char ntop[NI_MAXHOST];
|
||||
int r;
|
||||
|
||||
/* Get IP address of client. */
|
||||
addrlen = sizeof(addr);
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
if (remote) {
|
||||
if (getpeername(sock, (struct sockaddr *)&addr, &addrlen)
|
||||
< 0)
|
||||
return NULL;
|
||||
} else {
|
||||
if (getsockname(sock, (struct sockaddr *)&addr, &addrlen)
|
||||
< 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Work around Linux IPv6 weirdness */
|
||||
if (addr.ss_family == AF_INET6)
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
|
||||
ipv64_normalise_mapped(&addr, &addrlen);
|
||||
|
||||
/* Get the address in ascii. */
|
||||
if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
|
||||
sizeof(ntop), NULL, 0, flags)) != 0) {
|
||||
error("get_socket_address: getnameinfo %d failed: %s", flags,
|
||||
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
|
||||
return NULL;
|
||||
}
|
||||
return xstrdup(ntop);
|
||||
}
|
||||
|
||||
char *
|
||||
get_peer_ipaddr(int sock)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
|
||||
return p;
|
||||
return xstrdup("UNKNOWN");
|
||||
}
|
||||
|
||||
char *
|
||||
get_local_ipaddr(int sock)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
|
||||
return p;
|
||||
return xstrdup("UNKNOWN");
|
||||
}
|
||||
|
||||
char *
|
||||
get_local_name(int sock)
|
||||
{
|
||||
return get_socket_address(sock, 0, NI_NAMEREQD);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the IP-address of the remote host as a string. The returned
|
||||
* string must not be freed.
|
||||
*/
|
||||
|
||||
const char *
|
||||
get_remote_ipaddr(void)
|
||||
{
|
||||
static char *canonical_host_ip = NULL;
|
||||
|
||||
/* Check whether we have cached the ipaddr. */
|
||||
if (canonical_host_ip == NULL) {
|
||||
if (packet_connection_is_on_socket()) {
|
||||
canonical_host_ip =
|
||||
get_peer_ipaddr(packet_get_connection_in());
|
||||
if (canonical_host_ip == NULL)
|
||||
cleanup_exit(255);
|
||||
} else {
|
||||
/* If not on socket, return UNKNOWN. */
|
||||
canonical_host_ip = xstrdup("UNKNOWN");
|
||||
}
|
||||
}
|
||||
return canonical_host_ip;
|
||||
}
|
||||
|
||||
const char *
|
||||
get_remote_name_or_ip(u_int utmp_len, int use_dns)
|
||||
{
|
||||
static const char *remote = "";
|
||||
if (utmp_len > 0)
|
||||
remote = get_canonical_hostname(use_dns);
|
||||
if (utmp_len == 0 || strlen(remote) > utmp_len)
|
||||
remote = get_remote_ipaddr();
|
||||
return remote;
|
||||
}
|
||||
|
||||
/* Returns the local/remote port for the socket. */
|
||||
|
||||
static int
|
||||
get_sock_port(int sock, int local)
|
||||
{
|
||||
struct sockaddr_storage from;
|
||||
socklen_t fromlen;
|
||||
char strport[NI_MAXSERV];
|
||||
int r;
|
||||
|
||||
/* Get IP address of client. */
|
||||
fromlen = sizeof(from);
|
||||
memset(&from, 0, sizeof(from));
|
||||
if (local) {
|
||||
if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {
|
||||
error("getsockname failed: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
|
||||
debug("getpeername failed: %.100s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Work around Linux IPv6 weirdness */
|
||||
if (from.ss_family == AF_INET6)
|
||||
fromlen = sizeof(struct sockaddr_in6);
|
||||
|
||||
/* Return port number. */
|
||||
if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
|
||||
strport, sizeof(strport), NI_NUMERICSERV)) != 0)
|
||||
fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
|
||||
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
|
||||
return atoi(strport);
|
||||
}
|
||||
|
||||
/* Returns remote/local port number for the current connection. */
|
||||
|
||||
static int
|
||||
get_port(int local)
|
||||
{
|
||||
/*
|
||||
* If the connection is not a socket, return 65535. This is
|
||||
* intentionally chosen to be an unprivileged port number.
|
||||
*/
|
||||
if (!packet_connection_is_on_socket())
|
||||
return 65535;
|
||||
|
||||
/* Get socket and return the port number. */
|
||||
return get_sock_port(packet_get_connection_in(), local);
|
||||
}
|
||||
|
||||
int
|
||||
get_peer_port(int sock)
|
||||
{
|
||||
return get_sock_port(sock, 0);
|
||||
}
|
||||
|
||||
int
|
||||
get_remote_port(void)
|
||||
{
|
||||
static int port = -1;
|
||||
|
||||
/* Cache to avoid getpeername() on a dead connection */
|
||||
if (port == -1)
|
||||
port = get_port(0);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
int
|
||||
get_local_port(void)
|
||||
{
|
||||
return get_port(1);
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/* $OpenBSD: canohost.h,v 1.9 2006/03/25 22:22:42 djm 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".
|
||||
*/
|
||||
|
||||
const char *get_canonical_hostname(int);
|
||||
const char *get_remote_ipaddr(void);
|
||||
const char *get_remote_name_or_ip(u_int, int);
|
||||
|
||||
char *get_peer_ipaddr(int);
|
||||
int get_peer_port(int);
|
||||
char *get_local_ipaddr(int);
|
||||
char *get_local_name(int);
|
||||
|
||||
int get_remote_port(void);
|
||||
int get_local_port(void);
|
||||
|
||||
void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
|
File diff suppressed because it is too large
Load Diff
@ -1,250 +0,0 @@
|
||||
/* $OpenBSD: channels.h,v 1.88 2006/08/03 03:34:42 deraadt 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".
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* 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 CHANNEL_H
|
||||
#define CHANNEL_H
|
||||
|
||||
/* Definitions for channel types. */
|
||||
#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
|
||||
#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */
|
||||
#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */
|
||||
#define SSH_CHANNEL_OPEN 4 /* normal open two-way channel */
|
||||
#define SSH_CHANNEL_CLOSED 5 /* waiting for close confirmation */
|
||||
#define SSH_CHANNEL_AUTH_SOCKET 6 /* authentication socket */
|
||||
#define SSH_CHANNEL_X11_OPEN 7 /* reading first X11 packet */
|
||||
#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */
|
||||
#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */
|
||||
#define SSH_CHANNEL_LARVAL 10 /* larval session */
|
||||
#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
|
||||
#define SSH_CHANNEL_CONNECTING 12
|
||||
#define SSH_CHANNEL_DYNAMIC 13
|
||||
#define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */
|
||||
#define SSH_CHANNEL_MAX_TYPE 15
|
||||
|
||||
#define SSH_CHANNEL_PATH_LEN 256
|
||||
|
||||
struct Channel;
|
||||
typedef struct Channel Channel;
|
||||
|
||||
typedef void channel_callback_fn(int, void *);
|
||||
typedef int channel_infilter_fn(struct Channel *, char *, int);
|
||||
typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *);
|
||||
|
||||
struct Channel {
|
||||
int type; /* channel type/state */
|
||||
int self; /* my own channel identifier */
|
||||
int remote_id; /* channel identifier for remote peer */
|
||||
u_int istate; /* input from channel (state of receive half) */
|
||||
u_int ostate; /* output to channel (state of transmit half) */
|
||||
int flags; /* close sent/rcvd */
|
||||
int rfd; /* read fd */
|
||||
int wfd; /* write fd */
|
||||
int efd; /* extended fd */
|
||||
int sock; /* sock fd */
|
||||
int ctl_fd; /* control fd (client sharing) */
|
||||
int isatty; /* rfd is a tty */
|
||||
int wfd_isatty; /* wfd is a tty */
|
||||
int client_tty; /* (client) TTY has been requested */
|
||||
int force_drain; /* force close on iEOF */
|
||||
int delayed; /* fdset hack */
|
||||
Buffer input; /* data read from socket, to be sent over
|
||||
* encrypted connection */
|
||||
Buffer output; /* data received over encrypted connection for
|
||||
* send on socket */
|
||||
Buffer extended;
|
||||
char path[SSH_CHANNEL_PATH_LEN];
|
||||
/* path for unix domain sockets, or host name for forwards */
|
||||
int listening_port; /* port being listened for forwards */
|
||||
int host_port; /* remote port to connect for forwards */
|
||||
char *remote_name; /* remote hostname */
|
||||
|
||||
u_int remote_window;
|
||||
u_int remote_maxpacket;
|
||||
u_int local_window;
|
||||
u_int local_window_max;
|
||||
u_int local_consumed;
|
||||
u_int local_maxpacket;
|
||||
int extended_usage;
|
||||
int single_connection;
|
||||
|
||||
char *ctype; /* type */
|
||||
|
||||
/* callback */
|
||||
channel_callback_fn *confirm;
|
||||
void *confirm_ctx;
|
||||
channel_callback_fn *detach_user;
|
||||
int detach_close;
|
||||
|
||||
/* filter */
|
||||
channel_infilter_fn *input_filter;
|
||||
channel_outfilter_fn *output_filter;
|
||||
|
||||
int datagram; /* keep boundaries */
|
||||
};
|
||||
|
||||
#define CHAN_EXTENDED_IGNORE 0
|
||||
#define CHAN_EXTENDED_READ 1
|
||||
#define CHAN_EXTENDED_WRITE 2
|
||||
|
||||
/* default window/packet sizes for tcp/x11-fwd-channel */
|
||||
#define CHAN_SES_PACKET_DEFAULT (32*1024)
|
||||
#define CHAN_SES_WINDOW_DEFAULT (4*CHAN_SES_PACKET_DEFAULT)
|
||||
#define CHAN_TCP_PACKET_DEFAULT (32*1024)
|
||||
#define CHAN_TCP_WINDOW_DEFAULT (4*CHAN_TCP_PACKET_DEFAULT)
|
||||
#define CHAN_X11_PACKET_DEFAULT (16*1024)
|
||||
#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT)
|
||||
|
||||
/* possible input states */
|
||||
#define CHAN_INPUT_OPEN 0
|
||||
#define CHAN_INPUT_WAIT_DRAIN 1
|
||||
#define CHAN_INPUT_WAIT_OCLOSE 2
|
||||
#define CHAN_INPUT_CLOSED 3
|
||||
|
||||
/* possible output states */
|
||||
#define CHAN_OUTPUT_OPEN 0
|
||||
#define CHAN_OUTPUT_WAIT_DRAIN 1
|
||||
#define CHAN_OUTPUT_WAIT_IEOF 2
|
||||
#define CHAN_OUTPUT_CLOSED 3
|
||||
|
||||
#define CHAN_CLOSE_SENT 0x01
|
||||
#define CHAN_CLOSE_RCVD 0x02
|
||||
#define CHAN_EOF_SENT 0x04
|
||||
#define CHAN_EOF_RCVD 0x08
|
||||
|
||||
#define CHAN_RBUF 16*1024
|
||||
|
||||
/* check whether 'efd' is still in use */
|
||||
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
|
||||
(compat20 && c->extended_usage == CHAN_EXTENDED_READ && \
|
||||
(c->efd != -1 || \
|
||||
buffer_len(&c->extended) > 0))
|
||||
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
|
||||
(compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \
|
||||
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
|
||||
buffer_len(&c->extended) > 0))
|
||||
|
||||
/* channel management */
|
||||
|
||||
Channel *channel_by_id(int);
|
||||
Channel *channel_lookup(int);
|
||||
Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int);
|
||||
void channel_set_fds(int, int, int, int, int, int, u_int);
|
||||
void channel_free(Channel *);
|
||||
void channel_free_all(void);
|
||||
void channel_stop_listening(void);
|
||||
|
||||
void channel_send_open(int);
|
||||
void channel_request_start(int, char *, int);
|
||||
void channel_register_cleanup(int, channel_callback_fn *, int);
|
||||
void channel_register_confirm(int, channel_callback_fn *, void *);
|
||||
void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *);
|
||||
void channel_cancel_cleanup(int);
|
||||
int channel_close_fd(int *);
|
||||
void channel_send_window_changes(void);
|
||||
|
||||
/* protocol handler */
|
||||
|
||||
void channel_input_close(int, u_int32_t, void *);
|
||||
void channel_input_close_confirmation(int, u_int32_t, void *);
|
||||
void channel_input_data(int, u_int32_t, void *);
|
||||
void channel_input_extended_data(int, u_int32_t, void *);
|
||||
void channel_input_ieof(int, u_int32_t, void *);
|
||||
void channel_input_oclose(int, u_int32_t, void *);
|
||||
void channel_input_open_confirmation(int, u_int32_t, void *);
|
||||
void channel_input_open_failure(int, u_int32_t, void *);
|
||||
void channel_input_port_open(int, u_int32_t, void *);
|
||||
void channel_input_window_adjust(int, u_int32_t, void *);
|
||||
|
||||
/* file descriptor handling (read/write) */
|
||||
|
||||
void channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
|
||||
void channel_after_select(fd_set *, fd_set *);
|
||||
void channel_output_poll(void);
|
||||
|
||||
int channel_not_very_much_buffered_data(void);
|
||||
void channel_close_all(void);
|
||||
int channel_still_open(void);
|
||||
char *channel_open_message(void);
|
||||
int channel_find_open(void);
|
||||
|
||||
/* tcp forwarding */
|
||||
void channel_set_af(int af);
|
||||
void channel_permit_all_opens(void);
|
||||
void channel_add_permitted_opens(char *, int);
|
||||
int channel_add_adm_permitted_opens(char *, int);
|
||||
void channel_clear_permitted_opens(void);
|
||||
void channel_clear_adm_permitted_opens(void);
|
||||
int channel_input_port_forward_request(int, int);
|
||||
int channel_connect_to(const char *, u_short);
|
||||
int channel_connect_by_listen_address(u_short);
|
||||
int channel_request_remote_forwarding(const char *, u_short,
|
||||
const char *, u_short);
|
||||
int channel_setup_local_fwd_listener(const char *, u_short,
|
||||
const char *, u_short, int);
|
||||
void channel_request_rforward_cancel(const char *host, u_short port);
|
||||
int channel_setup_remote_fwd_listener(const char *, u_short, int);
|
||||
int channel_cancel_rport_listener(const char *, u_short);
|
||||
|
||||
/* x11 forwarding */
|
||||
|
||||
int x11_connect_display(void);
|
||||
int x11_create_display_inet(int, int, int, u_int *, int **);
|
||||
void x11_input_open(int, u_int32_t, void *);
|
||||
void x11_request_forwarding_with_spoofing(int, const char *, const char *,
|
||||
const char *);
|
||||
void deny_input_open(int, u_int32_t, void *);
|
||||
|
||||
/* agent forwarding */
|
||||
|
||||
void auth_request_forwarding(void);
|
||||
|
||||
/* channel close */
|
||||
|
||||
int chan_is_dead(Channel *, int);
|
||||
void chan_mark_dead(Channel *);
|
||||
|
||||
/* channel events */
|
||||
|
||||
void chan_rcvd_oclose(Channel *);
|
||||
void chan_read_failed(Channel *);
|
||||
void chan_ibuf_empty(Channel *);
|
||||
|
||||
void chan_rcvd_ieof(Channel *);
|
||||
void chan_write_failed(Channel *);
|
||||
void chan_obuf_empty(Channel *);
|
||||
|
||||
#endif
|
@ -1,184 +0,0 @@
|
||||
/* $OpenBSD: cipher-3des1.c,v 1.6 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00906000L
|
||||
#define SSH_OLD_EVP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is used by SSH1:
|
||||
*
|
||||
* What kind of triple DES are these 2 routines?
|
||||
*
|
||||
* Why is there a redundant initialization vector?
|
||||
*
|
||||
* If only iv3 was used, then, this would till effect have been
|
||||
* outer-cbc. However, there is also a private iv1 == iv2 which
|
||||
* perhaps makes differential analysis easier. On the other hand, the
|
||||
* private iv1 probably makes the CRC-32 attack ineffective. This is a
|
||||
* result of that there is no longer any known iv1 to use when
|
||||
* choosing the X block.
|
||||
*/
|
||||
struct ssh1_3des_ctx
|
||||
{
|
||||
EVP_CIPHER_CTX k1, k2, k3;
|
||||
};
|
||||
|
||||
const EVP_CIPHER * evp_ssh1_3des(void);
|
||||
void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
|
||||
|
||||
static int
|
||||
ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
int enc)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
u_char *k1, *k2, *k3;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
if (key == NULL)
|
||||
return (1);
|
||||
if (enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
k1 = k2 = k3 = (u_char *) key;
|
||||
k2 += 8;
|
||||
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
|
||||
if (enc)
|
||||
k3 += 16;
|
||||
else
|
||||
k1 += 16;
|
||||
}
|
||||
EVP_CIPHER_CTX_init(&c->k1);
|
||||
EVP_CIPHER_CTX_init(&c->k2);
|
||||
EVP_CIPHER_CTX_init(&c->k3);
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
|
||||
#else
|
||||
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
|
||||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
|
||||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
error("ssh1_3des_cbc: no context");
|
||||
return (0);
|
||||
}
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_Cipher(&c->k1, dest, (u_char *)src, len);
|
||||
EVP_Cipher(&c->k2, dest, dest, len);
|
||||
EVP_Cipher(&c->k3, dest, dest, len);
|
||||
#else
|
||||
if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
|
||||
EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
|
||||
EVP_Cipher(&c->k3, dest, dest, len) == 0)
|
||||
return (0);
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
EVP_CIPHER_CTX_cleanup(&c->k1);
|
||||
EVP_CIPHER_CTX_cleanup(&c->k2);
|
||||
EVP_CIPHER_CTX_cleanup(&c->k3);
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
|
||||
{
|
||||
struct ssh1_3des_ctx *c;
|
||||
|
||||
if (len != 24)
|
||||
fatal("%s: bad 3des iv length: %d", __func__, len);
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
|
||||
fatal("%s: no 3des context", __func__);
|
||||
if (doset) {
|
||||
debug3("%s: Installed 3DES IV", __func__);
|
||||
memcpy(c->k1.iv, iv, 8);
|
||||
memcpy(c->k2.iv, iv + 8, 8);
|
||||
memcpy(c->k3.iv, iv + 16, 8);
|
||||
} else {
|
||||
debug3("%s: Copying 3DES IV", __func__);
|
||||
memcpy(iv, c->k1.iv, 8);
|
||||
memcpy(iv + 8, c->k2.iv, 8);
|
||||
memcpy(iv + 16, c->k3.iv, 8);
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
evp_ssh1_3des(void)
|
||||
{
|
||||
static EVP_CIPHER ssh1_3des;
|
||||
|
||||
memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
|
||||
ssh1_3des.nid = NID_undef;
|
||||
ssh1_3des.block_size = 8;
|
||||
ssh1_3des.iv_len = 0;
|
||||
ssh1_3des.key_len = 16;
|
||||
ssh1_3des.init = ssh1_3des_init;
|
||||
ssh1_3des.cleanup = ssh1_3des_cleanup;
|
||||
ssh1_3des.do_cipher = ssh1_3des_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
|
||||
#endif
|
||||
return (&ssh1_3des);
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
|
||||
|
||||
#include "acss.h"
|
||||
|
||||
#define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data)
|
||||
|
||||
typedef struct {
|
||||
ACSS_KEY ks;
|
||||
} EVP_ACSS_KEY;
|
||||
|
||||
#define EVP_CTRL_SET_ACSS_MODE 0xff06
|
||||
#define EVP_CTRL_SET_ACSS_SUBKEY 0xff07
|
||||
|
||||
static int
|
||||
acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
acss_setkey(&data(ctx)->ks,key,enc,ACSS_DATA);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in,
|
||||
unsigned int inl)
|
||||
{
|
||||
acss(&data(ctx)->ks,inl,in,out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
acss_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
switch(type) {
|
||||
case EVP_CTRL_SET_ACSS_MODE:
|
||||
data(ctx)->ks.mode = arg;
|
||||
return 1;
|
||||
case EVP_CTRL_SET_ACSS_SUBKEY:
|
||||
acss_setsubkey(&data(ctx)->ks,(unsigned char *)ptr);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
evp_acss(void)
|
||||
{
|
||||
static EVP_CIPHER acss_cipher;
|
||||
|
||||
memset(&acss_cipher, 0, sizeof(EVP_CIPHER));
|
||||
|
||||
acss_cipher.nid = NID_undef;
|
||||
acss_cipher.block_size = 1;
|
||||
acss_cipher.key_len = 5;
|
||||
acss_cipher.init = acss_init_key;
|
||||
acss_cipher.do_cipher = acss_ciph;
|
||||
acss_cipher.ctx_size = sizeof(EVP_ACSS_KEY);
|
||||
acss_cipher.ctrl = acss_ctrl;
|
||||
|
||||
return (&acss_cipher);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
/* compatibility with old or broken OpenSSL versions */
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#ifdef USE_BUILTIN_RIJNDAEL
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rijndael.h"
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
#define RIJNDAEL_BLOCKSIZE 16
|
||||
struct ssh_rijndael_ctx
|
||||
{
|
||||
rijndael_ctx r_ctx;
|
||||
u_char r_iv[RIJNDAEL_BLOCKSIZE];
|
||||
};
|
||||
|
||||
const EVP_CIPHER * evp_rijndael(void);
|
||||
void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
|
||||
static int
|
||||
ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
int enc)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
if (key != NULL) {
|
||||
if (enc == -1)
|
||||
enc = ctx->encrypt;
|
||||
rijndael_set_key(&c->r_ctx, (u_char *)key,
|
||||
8*EVP_CIPHER_CTX_key_length(ctx), enc);
|
||||
}
|
||||
if (iv != NULL)
|
||||
memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
u_char buf[RIJNDAEL_BLOCKSIZE];
|
||||
u_char *cprev, *cnow, *plain, *ivp;
|
||||
int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
|
||||
|
||||
if (len == 0)
|
||||
return (1);
|
||||
if (len % RIJNDAEL_BLOCKSIZE)
|
||||
fatal("ssh_rijndael_cbc: bad len %d", len);
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
error("ssh_rijndael_cbc: no context");
|
||||
return (0);
|
||||
}
|
||||
if (ctx->encrypt) {
|
||||
cnow = dest;
|
||||
plain = (u_char *)src;
|
||||
cprev = c->r_iv;
|
||||
for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
|
||||
cnow+=RIJNDAEL_BLOCKSIZE) {
|
||||
for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
|
||||
buf[j] = plain[j] ^ cprev[j];
|
||||
rijndael_encrypt(&c->r_ctx, buf, cnow);
|
||||
cprev = cnow;
|
||||
}
|
||||
memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
|
||||
} else {
|
||||
cnow = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
|
||||
plain = dest+len-RIJNDAEL_BLOCKSIZE;
|
||||
|
||||
memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
|
||||
for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
|
||||
plain-=RIJNDAEL_BLOCKSIZE) {
|
||||
rijndael_decrypt(&c->r_ctx, cnow, plain);
|
||||
ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
|
||||
for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
|
||||
plain[j] ^= ivp[j];
|
||||
}
|
||||
memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_rijndael_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
|
||||
{
|
||||
struct ssh_rijndael_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
|
||||
fatal("ssh_rijndael_iv: no context");
|
||||
if (doset)
|
||||
memcpy(c->r_iv, iv, len);
|
||||
else
|
||||
memcpy(iv, c->r_iv, len);
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
evp_rijndael(void)
|
||||
{
|
||||
static EVP_CIPHER rijndal_cbc;
|
||||
|
||||
memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
|
||||
rijndal_cbc.nid = NID_undef;
|
||||
rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
|
||||
rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
|
||||
rijndal_cbc.key_len = 16;
|
||||
rijndal_cbc.init = ssh_rijndael_init;
|
||||
rijndal_cbc.cleanup = ssh_rijndael_cleanup;
|
||||
rijndal_cbc.do_cipher = ssh_rijndael_cbc;
|
||||
#ifndef SSH_OLD_EVP
|
||||
rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
|
||||
#endif
|
||||
return (&rijndal_cbc);
|
||||
}
|
||||
#endif /* USE_BUILTIN_RIJNDAEL */
|
@ -1,108 +0,0 @@
|
||||
/* $OpenBSD: cipher-bf1.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00906000L
|
||||
#define SSH_OLD_EVP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SSH1 uses a variation on Blowfish, all bytes must be swapped before
|
||||
* and after encryption/decryption. Thus the swap_bytes stuff (yuk).
|
||||
*/
|
||||
|
||||
const EVP_CIPHER * evp_ssh1_bf(void);
|
||||
|
||||
static void
|
||||
swap_bytes(const u_char *src, u_char *dst, int n)
|
||||
{
|
||||
u_char c[4];
|
||||
|
||||
/* Process 4 bytes every lap. */
|
||||
for (n = n / 4; n > 0; n--) {
|
||||
c[3] = *src++;
|
||||
c[2] = *src++;
|
||||
c[1] = *src++;
|
||||
c[0] = *src++;
|
||||
|
||||
*dst++ = c[0];
|
||||
*dst++ = c[1];
|
||||
*dst++ = c[2];
|
||||
*dst++ = c[3];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SSH_OLD_EVP
|
||||
static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
|
||||
const unsigned char *iv, int enc)
|
||||
{
|
||||
if (iv != NULL)
|
||||
memcpy (&(ctx->oiv[0]), iv, 8);
|
||||
memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
|
||||
if (key != NULL)
|
||||
BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
|
||||
key);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
|
||||
|
||||
static int
|
||||
bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
swap_bytes(in, out, len);
|
||||
ret = (*orig_bf)(ctx, out, out, len);
|
||||
swap_bytes(out, out, len);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
evp_ssh1_bf(void)
|
||||
{
|
||||
static EVP_CIPHER ssh1_bf;
|
||||
|
||||
memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
|
||||
orig_bf = ssh1_bf.do_cipher;
|
||||
ssh1_bf.nid = NID_undef;
|
||||
#ifdef SSH_OLD_EVP
|
||||
ssh1_bf.init = bf_ssh1_init;
|
||||
#endif
|
||||
ssh1_bf.do_cipher = bf_ssh1_cipher;
|
||||
ssh1_bf.key_len = 32;
|
||||
return (&ssh1_bf);
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/* $OpenBSD: cipher-ctr.c,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
|
||||
/* compatibility with old or broken OpenSSL versions */
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
#ifdef USE_BUILTIN_RIJNDAEL
|
||||
#include "rijndael.h"
|
||||
#define AES_KEY rijndael_ctx
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b)
|
||||
#define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1)
|
||||
#else
|
||||
#include <openssl/aes.h>
|
||||
#endif
|
||||
|
||||
const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
|
||||
struct ssh_aes_ctr_ctx
|
||||
{
|
||||
AES_KEY aes_ctx;
|
||||
u_char aes_counter[AES_BLOCK_SIZE];
|
||||
};
|
||||
|
||||
/*
|
||||
* increment counter 'ctr',
|
||||
* the counter is of size 'len' bytes and stored in network-byte-order.
|
||||
* (LSB at ctr[len-1], MSB at ctr[0])
|
||||
*/
|
||||
static void
|
||||
ssh_ctr_inc(u_char *ctr, u_int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = len - 1; i >= 0; i--)
|
||||
if (++ctr[i]) /* continue on overflow */
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
|
||||
u_int len)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
u_int n = 0;
|
||||
u_char buf[AES_BLOCK_SIZE];
|
||||
|
||||
if (len == 0)
|
||||
return (1);
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
|
||||
return (0);
|
||||
|
||||
while ((len--) > 0) {
|
||||
if (n == 0) {
|
||||
AES_encrypt(c->aes_counter, buf, &c->aes_ctx);
|
||||
ssh_ctr_inc(c->aes_counter, AES_BLOCK_SIZE);
|
||||
}
|
||||
*(dest++) = *(src++) ^ buf[n];
|
||||
n = (n + 1) % AES_BLOCK_SIZE;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
|
||||
int enc)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
|
||||
c = xmalloc(sizeof(*c));
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, c);
|
||||
}
|
||||
if (key != NULL)
|
||||
AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
|
||||
&c->aes_ctx);
|
||||
if (iv != NULL)
|
||||
memcpy(c->aes_counter, iv, AES_BLOCK_SIZE);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
|
||||
memset(c, 0, sizeof(*c));
|
||||
xfree(c);
|
||||
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
|
||||
{
|
||||
struct ssh_aes_ctr_ctx *c;
|
||||
|
||||
if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
|
||||
fatal("ssh_aes_ctr_iv: no context");
|
||||
if (doset)
|
||||
memcpy(c->aes_counter, iv, len);
|
||||
else
|
||||
memcpy(iv, c->aes_counter, len);
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
evp_aes_128_ctr(void)
|
||||
{
|
||||
static EVP_CIPHER aes_ctr;
|
||||
|
||||
memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
|
||||
aes_ctr.nid = NID_undef;
|
||||
aes_ctr.block_size = AES_BLOCK_SIZE;
|
||||
aes_ctr.iv_len = AES_BLOCK_SIZE;
|
||||
aes_ctr.key_len = 16;
|
||||
aes_ctr.init = ssh_aes_ctr_init;
|
||||
aes_ctr.cleanup = ssh_aes_ctr_cleanup;
|
||||
aes_ctr.do_cipher = ssh_aes_ctr;
|
||||
#ifndef SSH_OLD_EVP
|
||||
aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
|
||||
EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
|
||||
#endif
|
||||
return (&aes_ctr);
|
||||
}
|
@ -1,424 +0,0 @@
|
||||
/* $OpenBSD: cipher.c,v 1.81 2006/08/03 03:34:42 deraadt 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".
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1999 Niels Provos. All rights reserved.
|
||||
* Copyright (c) 1999, 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "cipher.h"
|
||||
|
||||
/* compatibility with old or broken OpenSSL versions */
|
||||
#include "openbsd-compat/openssl-compat.h"
|
||||
|
||||
extern const EVP_CIPHER *evp_ssh1_bf(void);
|
||||
extern const EVP_CIPHER *evp_ssh1_3des(void);
|
||||
extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
|
||||
extern const EVP_CIPHER *evp_aes_128_ctr(void);
|
||||
extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
|
||||
|
||||
struct Cipher {
|
||||
char *name;
|
||||
int number; /* for ssh1 only */
|
||||
u_int block_size;
|
||||
u_int key_len;
|
||||
u_int discard_len;
|
||||
const EVP_CIPHER *(*evptype)(void);
|
||||
} ciphers[] = {
|
||||
{ "none", SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null },
|
||||
{ "des", SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc },
|
||||
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des },
|
||||
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf },
|
||||
|
||||
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc },
|
||||
{ "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc },
|
||||
{ "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc },
|
||||
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 },
|
||||
{ "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 },
|
||||
{ "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 },
|
||||
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc },
|
||||
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc },
|
||||
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
|
||||
{ "rijndael-cbc@lysator.liu.se",
|
||||
SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc },
|
||||
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr },
|
||||
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr },
|
||||
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr },
|
||||
#ifdef USE_CIPHER_ACSS
|
||||
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss },
|
||||
#endif
|
||||
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
/*--*/
|
||||
|
||||
u_int
|
||||
cipher_blocksize(const Cipher *c)
|
||||
{
|
||||
return (c->block_size);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_keylen(const Cipher *c)
|
||||
{
|
||||
return (c->key_len);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_get_number(const Cipher *c)
|
||||
{
|
||||
return (c->number);
|
||||
}
|
||||
|
||||
u_int
|
||||
cipher_mask_ssh1(int client)
|
||||
{
|
||||
u_int mask = 0;
|
||||
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
|
||||
mask |= 1 << SSH_CIPHER_BLOWFISH;
|
||||
if (client) {
|
||||
mask |= 1 << SSH_CIPHER_DES;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
Cipher *
|
||||
cipher_by_name(const char *name)
|
||||
{
|
||||
Cipher *c;
|
||||
for (c = ciphers; c->name != NULL; c++)
|
||||
if (strcmp(c->name, name) == 0)
|
||||
return c;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Cipher *
|
||||
cipher_by_number(int id)
|
||||
{
|
||||
Cipher *c;
|
||||
for (c = ciphers; c->name != NULL; c++)
|
||||
if (c->number == id)
|
||||
return c;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define CIPHER_SEP ","
|
||||
int
|
||||
ciphers_valid(const char *names)
|
||||
{
|
||||
Cipher *c;
|
||||
char *cipher_list, *cp;
|
||||
char *p;
|
||||
|
||||
if (names == NULL || strcmp(names, "") == 0)
|
||||
return 0;
|
||||
cipher_list = cp = xstrdup(names);
|
||||
for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
|
||||
(p = strsep(&cp, CIPHER_SEP))) {
|
||||
c = cipher_by_name(p);
|
||||
if (c == NULL || c->number != SSH_CIPHER_SSH2) {
|
||||
debug("bad cipher %s [%s]", p, names);
|
||||
xfree(cipher_list);
|
||||
return 0;
|
||||
} else {
|
||||
debug3("cipher ok: %s [%s]", p, names);
|
||||
}
|
||||
}
|
||||
debug3("ciphers ok: [%s]", names);
|
||||
xfree(cipher_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses the name of the cipher. Returns the number of the corresponding
|
||||
* cipher, or -1 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
cipher_number(const char *name)
|
||||
{
|
||||
Cipher *c;
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
for (c = ciphers; c->name != NULL; c++)
|
||||
if (strcasecmp(c->name, name) == 0)
|
||||
return c->number;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *
|
||||
cipher_name(int id)
|
||||
{
|
||||
Cipher *c = cipher_by_number(id);
|
||||
return (c==NULL) ? "<unknown>" : c->name;
|
||||
}
|
||||
|
||||
void
|
||||
cipher_init(CipherContext *cc, Cipher *cipher,
|
||||
const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
|
||||
int do_encrypt)
|
||||
{
|
||||
static int dowarn = 1;
|
||||
#ifdef SSH_OLD_EVP
|
||||
EVP_CIPHER *type;
|
||||
#else
|
||||
const EVP_CIPHER *type;
|
||||
int klen;
|
||||
#endif
|
||||
u_char *junk, *discard;
|
||||
|
||||
if (cipher->number == SSH_CIPHER_DES) {
|
||||
if (dowarn) {
|
||||
error("Warning: use of DES is strongly discouraged "
|
||||
"due to cryptographic weaknesses");
|
||||
dowarn = 0;
|
||||
}
|
||||
if (keylen > 8)
|
||||
keylen = 8;
|
||||
}
|
||||
cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
|
||||
|
||||
if (keylen < cipher->key_len)
|
||||
fatal("cipher_init: key length %d is insufficient for %s.",
|
||||
keylen, cipher->name);
|
||||
if (iv != NULL && ivlen < cipher->block_size)
|
||||
fatal("cipher_init: iv length %d is insufficient for %s.",
|
||||
ivlen, cipher->name);
|
||||
cc->cipher = cipher;
|
||||
|
||||
type = (*cipher->evptype)();
|
||||
|
||||
EVP_CIPHER_CTX_init(&cc->evp);
|
||||
#ifdef SSH_OLD_EVP
|
||||
if (type->key_len > 0 && type->key_len != keylen) {
|
||||
debug("cipher_init: set keylen (%d -> %d)",
|
||||
type->key_len, keylen);
|
||||
type->key_len = keylen;
|
||||
}
|
||||
EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
|
||||
(do_encrypt == CIPHER_ENCRYPT));
|
||||
#else
|
||||
if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
|
||||
(do_encrypt == CIPHER_ENCRYPT)) == 0)
|
||||
fatal("cipher_init: EVP_CipherInit failed for %s",
|
||||
cipher->name);
|
||||
klen = EVP_CIPHER_CTX_key_length(&cc->evp);
|
||||
if (klen > 0 && keylen != (u_int)klen) {
|
||||
debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
|
||||
if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
|
||||
fatal("cipher_init: set keylen failed (%d -> %d)",
|
||||
klen, keylen);
|
||||
}
|
||||
if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
|
||||
fatal("cipher_init: EVP_CipherInit: set key failed for %s",
|
||||
cipher->name);
|
||||
#endif
|
||||
|
||||
if (cipher->discard_len > 0) {
|
||||
junk = xmalloc(cipher->discard_len);
|
||||
discard = xmalloc(cipher->discard_len);
|
||||
if (EVP_Cipher(&cc->evp, discard, junk,
|
||||
cipher->discard_len) == 0)
|
||||
fatal("evp_crypt: EVP_Cipher failed during discard");
|
||||
memset(discard, 0, cipher->discard_len);
|
||||
xfree(junk);
|
||||
xfree(discard);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
|
||||
{
|
||||
if (len % cc->cipher->block_size)
|
||||
fatal("cipher_encrypt: bad plaintext length %d", len);
|
||||
if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
|
||||
fatal("evp_crypt: EVP_Cipher failed");
|
||||
}
|
||||
|
||||
void
|
||||
cipher_cleanup(CipherContext *cc)
|
||||
{
|
||||
if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
|
||||
error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects the cipher, and keys if by computing the MD5 checksum of the
|
||||
* passphrase and using the resulting 16 bytes as the key.
|
||||
*/
|
||||
|
||||
void
|
||||
cipher_set_key_string(CipherContext *cc, Cipher *cipher,
|
||||
const char *passphrase, int do_encrypt)
|
||||
{
|
||||
MD5_CTX md;
|
||||
u_char digest[16];
|
||||
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
|
||||
MD5_Final(digest, &md);
|
||||
|
||||
cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
|
||||
|
||||
memset(digest, 0, sizeof(digest));
|
||||
memset(&md, 0, sizeof(md));
|
||||
}
|
||||
|
||||
/*
|
||||
* Exports an IV from the CipherContext required to export the key
|
||||
* state back from the unprivileged child to the privileged parent
|
||||
* process.
|
||||
*/
|
||||
|
||||
int
|
||||
cipher_get_keyiv_len(const CipherContext *cc)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
int ivlen;
|
||||
|
||||
if (c->number == SSH_CIPHER_3DES)
|
||||
ivlen = 24;
|
||||
else
|
||||
ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp);
|
||||
return (ivlen);
|
||||
}
|
||||
|
||||
void
|
||||
cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
int evplen;
|
||||
|
||||
switch (c->number) {
|
||||
case SSH_CIPHER_SSH2:
|
||||
case SSH_CIPHER_DES:
|
||||
case SSH_CIPHER_BLOWFISH:
|
||||
evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
|
||||
if (evplen <= 0)
|
||||
return;
|
||||
if ((u_int)evplen != len)
|
||||
fatal("%s: wrong iv length %d != %d", __func__,
|
||||
evplen, len);
|
||||
#ifdef USE_BUILTIN_RIJNDAEL
|
||||
if (c->evptype == evp_rijndael)
|
||||
ssh_rijndael_iv(&cc->evp, 0, iv, len);
|
||||
else
|
||||
#endif
|
||||
if (c->evptype == evp_aes_128_ctr)
|
||||
ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
|
||||
else
|
||||
memcpy(iv, cc->evp.iv, len);
|
||||
break;
|
||||
case SSH_CIPHER_3DES:
|
||||
ssh1_3des_iv(&cc->evp, 0, iv, 24);
|
||||
break;
|
||||
default:
|
||||
fatal("%s: bad cipher %d", __func__, c->number);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cipher_set_keyiv(CipherContext *cc, u_char *iv)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
int evplen = 0;
|
||||
|
||||
switch (c->number) {
|
||||
case SSH_CIPHER_SSH2:
|
||||
case SSH_CIPHER_DES:
|
||||
case SSH_CIPHER_BLOWFISH:
|
||||
evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
|
||||
if (evplen == 0)
|
||||
return;
|
||||
#ifdef USE_BUILTIN_RIJNDAEL
|
||||
if (c->evptype == evp_rijndael)
|
||||
ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
|
||||
else
|
||||
#endif
|
||||
if (c->evptype == evp_aes_128_ctr)
|
||||
ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
|
||||
else
|
||||
memcpy(cc->evp.iv, iv, evplen);
|
||||
break;
|
||||
case SSH_CIPHER_3DES:
|
||||
ssh1_3des_iv(&cc->evp, 1, iv, 24);
|
||||
break;
|
||||
default:
|
||||
fatal("%s: bad cipher %d", __func__, c->number);
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x00907000L
|
||||
#define EVP_X_STATE(evp) &(evp).c
|
||||
#define EVP_X_STATE_LEN(evp) sizeof((evp).c)
|
||||
#else
|
||||
#define EVP_X_STATE(evp) (evp).cipher_data
|
||||
#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size
|
||||
#endif
|
||||
|
||||
int
|
||||
cipher_get_keycontext(const CipherContext *cc, u_char *dat)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
int plen = 0;
|
||||
|
||||
if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
|
||||
plen = EVP_X_STATE_LEN(cc->evp);
|
||||
if (dat == NULL)
|
||||
return (plen);
|
||||
memcpy(dat, EVP_X_STATE(cc->evp), plen);
|
||||
}
|
||||
return (plen);
|
||||
}
|
||||
|
||||
void
|
||||
cipher_set_keycontext(CipherContext *cc, u_char *dat)
|
||||
{
|
||||
Cipher *c = cc->cipher;
|
||||
int plen;
|
||||
|
||||
if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
|
||||
plen = EVP_X_STATE_LEN(cc->evp);
|
||||
memcpy(EVP_X_STATE(cc->evp), dat, plen);
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/* $OpenBSD: cipher.h,v 1.36 2006/03/25 22:22:42 djm 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".
|
||||
*
|
||||
* 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 CIPHER_H
|
||||
#define CIPHER_H
|
||||
|
||||
#include <openssl/evp.h>
|
||||
/*
|
||||
* Cipher types for SSH-1. New types can be added, but old types should not
|
||||
* be removed for compatibility. The maximum allowed value is 31.
|
||||
*/
|
||||
#define SSH_CIPHER_SSH2 -3
|
||||
#define SSH_CIPHER_INVALID -2 /* No valid cipher selected. */
|
||||
#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */
|
||||
#define SSH_CIPHER_NONE 0 /* no encryption */
|
||||
#define SSH_CIPHER_IDEA 1 /* IDEA CFB */
|
||||
#define SSH_CIPHER_DES 2 /* DES CBC */
|
||||
#define SSH_CIPHER_3DES 3 /* 3DES CBC */
|
||||
#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */
|
||||
#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */
|
||||
#define SSH_CIPHER_BLOWFISH 6
|
||||
#define SSH_CIPHER_RESERVED 7
|
||||
#define SSH_CIPHER_MAX 31
|
||||
|
||||
#define CIPHER_ENCRYPT 1
|
||||
#define CIPHER_DECRYPT 0
|
||||
|
||||
typedef struct Cipher Cipher;
|
||||
typedef struct CipherContext CipherContext;
|
||||
|
||||
struct Cipher;
|
||||
struct CipherContext {
|
||||
int plaintext;
|
||||
EVP_CIPHER_CTX evp;
|
||||
Cipher *cipher;
|
||||
};
|
||||
|
||||
u_int cipher_mask_ssh1(int);
|
||||
Cipher *cipher_by_name(const char *);
|
||||
Cipher *cipher_by_number(int);
|
||||
int cipher_number(const char *);
|
||||
char *cipher_name(int);
|
||||
int ciphers_valid(const char *);
|
||||
void cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
|
||||
const u_char *, u_int, int);
|
||||
void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
|
||||
void cipher_cleanup(CipherContext *);
|
||||
void cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
|
||||
u_int cipher_blocksize(const Cipher *);
|
||||
u_int cipher_keylen(const Cipher *);
|
||||
|
||||
u_int cipher_get_number(const Cipher *);
|
||||
void cipher_get_keyiv(CipherContext *, u_char *, u_int);
|
||||
void cipher_set_keyiv(CipherContext *, u_char *);
|
||||
int cipher_get_keyiv_len(const CipherContext *);
|
||||
int cipher_get_keycontext(const CipherContext *, u_char *);
|
||||
void cipher_set_keycontext(CipherContext *, u_char *);
|
||||
#endif /* CIPHER_H */
|
@ -1,32 +0,0 @@
|
||||
/* $OpenBSD: cleanup.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/* default implementation */
|
||||
void
|
||||
cleanup_exit(int i)
|
||||
{
|
||||
_exit(i);
|
||||
}
|
@ -1,231 +0,0 @@
|
||||
/* $OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "cli.h"
|
||||
|
||||
#include <vis.h>
|
||||
|
||||
static int cli_input = -1;
|
||||
static int cli_output = -1;
|
||||
static int cli_from_stdin = 0;
|
||||
|
||||
sigset_t oset;
|
||||
sigset_t nset;
|
||||
struct sigaction nsa;
|
||||
struct sigaction osa;
|
||||
struct termios ntio;
|
||||
struct termios otio;
|
||||
int echo_modified;
|
||||
|
||||
volatile int intr;
|
||||
|
||||
static int
|
||||
cli_open(int from_stdin)
|
||||
{
|
||||
if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin)
|
||||
return 1;
|
||||
|
||||
if (from_stdin) {
|
||||
if (!cli_from_stdin && cli_input >= 0) {
|
||||
(void)close(cli_input);
|
||||
}
|
||||
cli_input = STDIN_FILENO;
|
||||
cli_output = STDERR_FILENO;
|
||||
} else {
|
||||
cli_input = cli_output = open(_PATH_TTY, O_RDWR);
|
||||
if (cli_input < 0)
|
||||
fatal("You have no controlling tty. Cannot read passphrase.");
|
||||
}
|
||||
|
||||
cli_from_stdin = from_stdin;
|
||||
|
||||
return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_close(void)
|
||||
{
|
||||
if (!cli_from_stdin && cli_input >= 0)
|
||||
close(cli_input);
|
||||
cli_input = -1;
|
||||
cli_output = -1;
|
||||
cli_from_stdin = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
intrcatch(int sig)
|
||||
{
|
||||
intr = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_disable(void)
|
||||
{
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGTSTP);
|
||||
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
|
||||
intr = 0;
|
||||
|
||||
memset(&nsa, 0, sizeof(nsa));
|
||||
nsa.sa_handler = intrcatch;
|
||||
(void) sigaction(SIGINT, &nsa, &osa);
|
||||
|
||||
echo_modified = 0;
|
||||
if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) {
|
||||
echo_modified = 1;
|
||||
ntio = otio;
|
||||
ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
(void) tcsetattr(cli_input, TCSANOW, &ntio);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_restore(void)
|
||||
{
|
||||
if (echo_modified != 0) {
|
||||
tcsetattr(cli_input, TCSANOW, &otio);
|
||||
echo_modified = 0;
|
||||
}
|
||||
|
||||
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
(void) sigaction(SIGINT, &osa, NULL);
|
||||
|
||||
if (intr != 0) {
|
||||
kill(getpid(), SIGINT);
|
||||
sigemptyset(&nset);
|
||||
/* XXX tty has not neccessarily drained by now? */
|
||||
sigsuspend(&nset);
|
||||
intr = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_read(char* buf, int size, int echo)
|
||||
{
|
||||
char ch = 0;
|
||||
int i = 0;
|
||||
int n;
|
||||
|
||||
if (!echo)
|
||||
cli_echo_disable();
|
||||
|
||||
while (ch != '\n') {
|
||||
n = read(cli_input, &ch, 1);
|
||||
if (n == -1 && (errno == EAGAIN || errno == EINTR))
|
||||
continue;
|
||||
if (n != 1)
|
||||
break;
|
||||
if (ch == '\n' || intr != 0)
|
||||
break;
|
||||
if (i < size)
|
||||
buf[i++] = ch;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
if (!echo)
|
||||
cli_echo_restore();
|
||||
if (!intr && !echo)
|
||||
(void) write(cli_output, "\n", 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_write(char* buf, int size)
|
||||
{
|
||||
int i, len, pos, ret = 0;
|
||||
char *output, *p;
|
||||
|
||||
output = xmalloc(4*size);
|
||||
for (p = output, i = 0; i < size; i++) {
|
||||
if (buf[i] == '\n' || buf[i] == '\r')
|
||||
*p++ = buf[i];
|
||||
else
|
||||
p = vis(p, buf[i], 0, 0);
|
||||
}
|
||||
len = p - output;
|
||||
|
||||
for (pos = 0; pos < len; pos += ret) {
|
||||
ret = write(cli_output, output + pos, len - pos);
|
||||
if (ret == -1) {
|
||||
xfree(output);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
xfree(output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char*
|
||||
cli_read_passphrase(char* prompt, int from_stdin, int echo_enable)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char* p;
|
||||
|
||||
if (!cli_open(from_stdin))
|
||||
fatal("Cannot read passphrase.");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
cli_write(prompt, strlen(prompt));
|
||||
cli_read(buf, sizeof buf, echo_enable);
|
||||
|
||||
cli_close();
|
||||
|
||||
p = xstrdup(buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return (p);
|
||||
}
|
||||
|
||||
char*
|
||||
cli_prompt(char* prompt, int echo_enable)
|
||||
{
|
||||
return cli_read_passphrase(prompt, 0, echo_enable);
|
||||
}
|
||||
|
||||
void
|
||||
cli_mesg(char* mesg)
|
||||
{
|
||||
cli_open(0);
|
||||
cli_write(mesg, strlen(mesg));
|
||||
cli_write("\n", strlen("\n"));
|
||||
cli_close();
|
||||
return;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt 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.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */
|
||||
|
||||
#ifndef CLI_H
|
||||
#define CLI_H
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char * cli_read_passphrase(char * prompt, int from_stdin, int echo_enable);
|
||||
char * cli_prompt(char * prompt, int echo_enable);
|
||||
void cli_mesg(char * mesg);
|
||||
|
||||
#endif /* CLI_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,59 +0,0 @@
|
||||
/* $OpenBSD: clientloop.h,v 1.16 2006/03/25 22:22:42 djm 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".
|
||||
*/
|
||||
/*
|
||||
* 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 <termios.h>
|
||||
|
||||
/* Client side main loop for the interactive session. */
|
||||
int client_loop(int, int, int);
|
||||
void client_x11_get_proto(const char *, const char *, u_int,
|
||||
char **, char **);
|
||||
void client_global_request_reply_fwd(int, u_int32_t, void *);
|
||||
void client_session2_setup(int, int, int, const char *, struct termios *,
|
||||
int, Buffer *, char **, dispatch_fn *);
|
||||
|
||||
/* Multiplexing protocol version */
|
||||
#define SSHMUX_VER 1
|
||||
|
||||
/* Multiplexing control protocol flags */
|
||||
#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
|
||||
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
|
||||
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
|
||||
|
||||
#define SSHMUX_FLAG_TTY (1) /* Request tty on open */
|
||||
#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */
|
||||
#define SSHMUX_FLAG_X11_FWD (1<<2) /* Request X11 forwarding */
|
||||
#define SSHMUX_FLAG_AGENT_FWD (1<<3) /* Request agent forwarding */
|
@ -1,235 +0,0 @@
|
||||
/* $OpenBSD: compat.c,v 1.76 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "packet.h"
|
||||
#include "compat.h"
|
||||
#include "log.h"
|
||||
#include "match.h"
|
||||
|
||||
int compat13 = 0;
|
||||
int compat20 = 0;
|
||||
int datafellows = 0;
|
||||
|
||||
void
|
||||
enable_compat20(void)
|
||||
{
|
||||
debug("Enabling compatibility mode for protocol 2.0");
|
||||
compat20 = 1;
|
||||
}
|
||||
void
|
||||
enable_compat13(void)
|
||||
{
|
||||
debug("Enabling compatibility mode for protocol 1.3");
|
||||
compat13 = 1;
|
||||
}
|
||||
/* datafellows bug compatibility */
|
||||
void
|
||||
compat_datafellows(const char *version)
|
||||
{
|
||||
int i;
|
||||
static struct {
|
||||
char *pat;
|
||||
int bugs;
|
||||
} check[] = {
|
||||
{ "OpenSSH-2.0*,"
|
||||
"OpenSSH-2.1*,"
|
||||
"OpenSSH_2.1*,"
|
||||
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER|
|
||||
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||
SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
|
||||
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||
SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
||||
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.5.0p1*,"
|
||||
"OpenSSH_2.5.1p1*",
|
||||
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
|
||||
SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.5.0*,"
|
||||
"OpenSSH_2.5.1*,"
|
||||
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
|
||||
SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
|
||||
SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_2.*,"
|
||||
"OpenSSH_3.0*,"
|
||||
"OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
|
||||
{ "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR },
|
||||
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
|
||||
{ "OpenSSH*", 0 },
|
||||
{ "*MindTerm*", 0 },
|
||||
{ "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE|
|
||||
SSH_BUG_FIRSTKEX },
|
||||
{ "2.1 *", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE|
|
||||
SSH_BUG_FIRSTKEX },
|
||||
{ "2.0.13*,"
|
||||
"2.0.14*,"
|
||||
"2.0.15*,"
|
||||
"2.0.16*,"
|
||||
"2.0.17*,"
|
||||
"2.0.18*,"
|
||||
"2.0.19*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
||||
SSH_BUG_PKOK|SSH_BUG_RSASIGMD5|
|
||||
SSH_BUG_HBSERVICE|SSH_BUG_OPENFAILURE|
|
||||
SSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX },
|
||||
{ "2.0.11*,"
|
||||
"2.0.12*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
||||
SSH_BUG_PKAUTH|SSH_BUG_PKOK|
|
||||
SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|
|
||||
SSH_BUG_DUMMYCHAN|SSH_BUG_FIRSTKEX },
|
||||
{ "2.0.*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
|
||||
SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
|
||||
SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
|
||||
SSH_BUG_PKAUTH|SSH_BUG_PKOK|
|
||||
SSH_BUG_RSASIGMD5|SSH_BUG_OPENFAILURE|
|
||||
SSH_BUG_DERIVEKEY|SSH_BUG_DUMMYCHAN|
|
||||
SSH_BUG_FIRSTKEX },
|
||||
{ "2.2.0*,"
|
||||
"2.3.0*", SSH_BUG_HMAC|SSH_BUG_DEBUG|
|
||||
SSH_BUG_RSASIGMD5|SSH_BUG_FIRSTKEX },
|
||||
{ "2.3.*", SSH_BUG_DEBUG|SSH_BUG_RSASIGMD5|
|
||||
SSH_BUG_FIRSTKEX },
|
||||
{ "2.4", SSH_OLD_SESSIONID }, /* Van Dyke */
|
||||
{ "2.*", SSH_BUG_DEBUG|SSH_BUG_FIRSTKEX },
|
||||
{ "3.0.*", SSH_BUG_DEBUG },
|
||||
{ "3.0 SecureCRT*", SSH_OLD_SESSIONID },
|
||||
{ "1.7 SecureFX*", SSH_OLD_SESSIONID },
|
||||
{ "1.2.18*,"
|
||||
"1.2.19*,"
|
||||
"1.2.20*,"
|
||||
"1.2.21*,"
|
||||
"1.2.22*", SSH_BUG_IGNOREMSG },
|
||||
{ "1.3.2*", /* F-Secure */
|
||||
SSH_BUG_IGNOREMSG },
|
||||
{ "*SSH Compatible Server*", /* Netscreen */
|
||||
SSH_BUG_PASSWORDPAD },
|
||||
{ "*OSU_0*,"
|
||||
"OSU_1.0*,"
|
||||
"OSU_1.1*,"
|
||||
"OSU_1.2*,"
|
||||
"OSU_1.3*,"
|
||||
"OSU_1.4*,"
|
||||
"OSU_1.5alpha1*,"
|
||||
"OSU_1.5alpha2*,"
|
||||
"OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD },
|
||||
{ "*SSH_Version_Mapper*",
|
||||
SSH_BUG_SCANNER },
|
||||
{ "Probe-*",
|
||||
SSH_BUG_PROBE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* process table, return first match */
|
||||
for (i = 0; check[i].pat; i++) {
|
||||
if (match_pattern_list(version, check[i].pat,
|
||||
strlen(check[i].pat), 0) == 1) {
|
||||
debug("match: %s pat %s", version, check[i].pat);
|
||||
datafellows = check[i].bugs;
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug("no match: %s", version);
|
||||
}
|
||||
|
||||
#define SEP ","
|
||||
int
|
||||
proto_spec(const char *spec)
|
||||
{
|
||||
char *s, *p, *q;
|
||||
int ret = SSH_PROTO_UNKNOWN;
|
||||
|
||||
if (spec == NULL)
|
||||
return ret;
|
||||
q = s = xstrdup(spec);
|
||||
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
|
||||
switch (atoi(p)) {
|
||||
case 1:
|
||||
if (ret == SSH_PROTO_UNKNOWN)
|
||||
ret |= SSH_PROTO_1_PREFERRED;
|
||||
ret |= SSH_PROTO_1;
|
||||
break;
|
||||
case 2:
|
||||
ret |= SSH_PROTO_2;
|
||||
break;
|
||||
default:
|
||||
logit("ignoring bad proto spec: '%s'.", p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
xfree(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
compat_cipher_proposal(char *cipher_prop)
|
||||
{
|
||||
Buffer b;
|
||||
char *orig_prop, *fix_ciphers;
|
||||
char *cp, *tmp;
|
||||
|
||||
if (!(datafellows & SSH_BUG_BIGENDIANAES))
|
||||
return(cipher_prop);
|
||||
|
||||
buffer_init(&b);
|
||||
tmp = orig_prop = xstrdup(cipher_prop);
|
||||
while ((cp = strsep(&tmp, ",")) != NULL) {
|
||||
if (strncmp(cp, "aes", 3) != 0) {
|
||||
if (buffer_len(&b) > 0)
|
||||
buffer_append(&b, ",", 1);
|
||||
buffer_append(&b, cp, strlen(cp));
|
||||
}
|
||||
}
|
||||
buffer_append(&b, "\0", 1);
|
||||
fix_ciphers = xstrdup(buffer_ptr(&b));
|
||||
buffer_free(&b);
|
||||
xfree(orig_prop);
|
||||
debug2("Original cipher proposal: %s", cipher_prop);
|
||||
debug2("Compat cipher proposal: %s", fix_ciphers);
|
||||
if (!*fix_ciphers)
|
||||
fatal("No available ciphers found.");
|
||||
|
||||
return(fix_ciphers);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/* $OpenBSD: compat.h,v 1.40 2006/03/25 22:22:43 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 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.
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_H
|
||||
#define COMPAT_H
|
||||
|
||||
#define SSH_PROTO_UNKNOWN 0x00
|
||||
#define SSH_PROTO_1 0x01
|
||||
#define SSH_PROTO_1_PREFERRED 0x02
|
||||
#define SSH_PROTO_2 0x04
|
||||
|
||||
#define SSH_BUG_SIGBLOB 0x00000001
|
||||
#define SSH_BUG_PKSERVICE 0x00000002
|
||||
#define SSH_BUG_HMAC 0x00000004
|
||||
#define SSH_BUG_X11FWD 0x00000008
|
||||
#define SSH_OLD_SESSIONID 0x00000010
|
||||
#define SSH_BUG_PKAUTH 0x00000020
|
||||
#define SSH_BUG_DEBUG 0x00000040
|
||||
#define SSH_BUG_BANNER 0x00000080
|
||||
#define SSH_BUG_IGNOREMSG 0x00000100
|
||||
#define SSH_BUG_PKOK 0x00000200
|
||||
#define SSH_BUG_PASSWORDPAD 0x00000400
|
||||
#define SSH_BUG_SCANNER 0x00000800
|
||||
#define SSH_BUG_BIGENDIANAES 0x00001000
|
||||
#define SSH_BUG_RSASIGMD5 0x00002000
|
||||
#define SSH_OLD_DHGEX 0x00004000
|
||||
#define SSH_BUG_NOREKEY 0x00008000
|
||||
#define SSH_BUG_HBSERVICE 0x00010000
|
||||
#define SSH_BUG_OPENFAILURE 0x00020000
|
||||
#define SSH_BUG_DERIVEKEY 0x00040000
|
||||
#define SSH_BUG_DUMMYCHAN 0x00100000
|
||||
#define SSH_BUG_EXTEOF 0x00200000
|
||||
#define SSH_BUG_PROBE 0x00400000
|
||||
#define SSH_BUG_FIRSTKEX 0x00800000
|
||||
#define SSH_OLD_FORWARD_ADDR 0x01000000
|
||||
|
||||
void enable_compat13(void);
|
||||
void enable_compat20(void);
|
||||
void compat_datafellows(const char *);
|
||||
int proto_spec(const char *);
|
||||
char *compat_cipher_proposal(char *);
|
||||
|
||||
extern int compat13;
|
||||
extern int compat20;
|
||||
extern int datafellows;
|
||||
#endif
|
@ -1,166 +0,0 @@
|
||||
/* $OpenBSD: compress.c,v 1.25 2006/08/06 01:13:32 stevesk Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Interface to packet compression for ssh.
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "buffer.h"
|
||||
#include "compress.h"
|
||||
|
||||
z_stream incoming_stream;
|
||||
z_stream outgoing_stream;
|
||||
static int compress_init_send_called = 0;
|
||||
static int compress_init_recv_called = 0;
|
||||
static int inflate_failed = 0;
|
||||
static int deflate_failed = 0;
|
||||
|
||||
/*
|
||||
* Initializes compression; level is compression level from 1 to 9
|
||||
* (as in gzip).
|
||||
*/
|
||||
|
||||
void
|
||||
buffer_compress_init_send(int level)
|
||||
{
|
||||
if (compress_init_send_called == 1)
|
||||
deflateEnd(&outgoing_stream);
|
||||
compress_init_send_called = 1;
|
||||
debug("Enabling compression at level %d.", level);
|
||||
if (level < 1 || level > 9)
|
||||
fatal("Bad compression level %d.", level);
|
||||
deflateInit(&outgoing_stream, level);
|
||||
}
|
||||
void
|
||||
buffer_compress_init_recv(void)
|
||||
{
|
||||
if (compress_init_recv_called == 1)
|
||||
inflateEnd(&incoming_stream);
|
||||
compress_init_recv_called = 1;
|
||||
inflateInit(&incoming_stream);
|
||||
}
|
||||
|
||||
/* Frees any data structures allocated for compression. */
|
||||
|
||||
void
|
||||
buffer_compress_uninit(void)
|
||||
{
|
||||
debug("compress outgoing: raw data %llu, compressed %llu, factor %.2f",
|
||||
(unsigned long long)outgoing_stream.total_in,
|
||||
(unsigned long long)outgoing_stream.total_out,
|
||||
outgoing_stream.total_in == 0 ? 0.0 :
|
||||
(double) outgoing_stream.total_out / outgoing_stream.total_in);
|
||||
debug("compress incoming: raw data %llu, compressed %llu, factor %.2f",
|
||||
(unsigned long long)incoming_stream.total_out,
|
||||
(unsigned long long)incoming_stream.total_in,
|
||||
incoming_stream.total_out == 0 ? 0.0 :
|
||||
(double) incoming_stream.total_in / incoming_stream.total_out);
|
||||
if (compress_init_recv_called == 1 && inflate_failed == 0)
|
||||
inflateEnd(&incoming_stream);
|
||||
if (compress_init_send_called == 1 && deflate_failed == 0)
|
||||
deflateEnd(&outgoing_stream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compresses the contents of input_buffer into output_buffer. All packets
|
||||
* compressed using this function will form a single compressed data stream;
|
||||
* however, data will be flushed at the end of every call so that each
|
||||
* output_buffer can be decompressed independently (but in the appropriate
|
||||
* order since they together form a single compression stream) by the
|
||||
* receiver. This appends the compressed data to the output buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
|
||||
{
|
||||
u_char buf[4096];
|
||||
int status;
|
||||
|
||||
/* This case is not handled below. */
|
||||
if (buffer_len(input_buffer) == 0)
|
||||
return;
|
||||
|
||||
/* Input is the contents of the input buffer. */
|
||||
outgoing_stream.next_in = buffer_ptr(input_buffer);
|
||||
outgoing_stream.avail_in = buffer_len(input_buffer);
|
||||
|
||||
/* Loop compressing until deflate() returns with avail_out != 0. */
|
||||
do {
|
||||
/* Set up fixed-size output buffer. */
|
||||
outgoing_stream.next_out = buf;
|
||||
outgoing_stream.avail_out = sizeof(buf);
|
||||
|
||||
/* Compress as much data into the buffer as possible. */
|
||||
status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH);
|
||||
switch (status) {
|
||||
case Z_OK:
|
||||
/* Append compressed data to output_buffer. */
|
||||
buffer_append(output_buffer, buf,
|
||||
sizeof(buf) - outgoing_stream.avail_out);
|
||||
break;
|
||||
default:
|
||||
deflate_failed = 1;
|
||||
fatal("buffer_compress: deflate returned %d", status);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
} while (outgoing_stream.avail_out == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Uncompresses the contents of input_buffer into output_buffer. All packets
|
||||
* uncompressed using this function will form a single compressed data
|
||||
* stream; however, data will be flushed at the end of every call so that
|
||||
* each output_buffer. This must be called for the same size units that the
|
||||
* buffer_compress was called, and in the same order that buffers compressed
|
||||
* with that. This appends the uncompressed data to the output buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
|
||||
{
|
||||
u_char buf[4096];
|
||||
int status;
|
||||
|
||||
incoming_stream.next_in = buffer_ptr(input_buffer);
|
||||
incoming_stream.avail_in = buffer_len(input_buffer);
|
||||
|
||||
for (;;) {
|
||||
/* Set up fixed-size output buffer. */
|
||||
incoming_stream.next_out = buf;
|
||||
incoming_stream.avail_out = sizeof(buf);
|
||||
|
||||
status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
|
||||
switch (status) {
|
||||
case Z_OK:
|
||||
buffer_append(output_buffer, buf,
|
||||
sizeof(buf) - incoming_stream.avail_out);
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
/*
|
||||
* Comments in zlib.h say that we should keep calling
|
||||
* inflate() until we get an error. This appears to
|
||||
* be the error that we get.
|
||||
*/
|
||||
return;
|
||||
default:
|
||||
inflate_failed = 1;
|
||||
fatal("buffer_uncompress: inflate returned %d", status);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/* $OpenBSD: compress.h,v 1.12 2006/03/25 22:22:43 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Interface to packet compression for ssh.
|
||||
*
|
||||
* 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 COMPRESS_H
|
||||
#define COMPRESS_H
|
||||
|
||||
void buffer_compress_init_send(int);
|
||||
void buffer_compress_init_recv(void);
|
||||
void buffer_compress_uninit(void);
|
||||
void buffer_compress(Buffer *, Buffer *);
|
||||
void buffer_uncompress(Buffer *, Buffer *);
|
||||
|
||||
#endif /* COMPRESS_H */
|
1499
crypto/openssh/config.guess
vendored
1499
crypto/openssh/config.guess
vendored
File diff suppressed because it is too large
Load Diff
1570
crypto/openssh/config.sub
vendored
1570
crypto/openssh/config.sub
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,105 +0,0 @@
|
||||
/* $OpenBSD: crc32.c,v 1.11 2006/04/22 18:29:33 stevesk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "includes.h"
|
||||
#include "crc32.h"
|
||||
|
||||
static const u_int32_t crc32tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
|
||||
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
||||
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
|
||||
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
||||
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
|
||||
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
||||
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
|
||||
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
|
||||
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
|
||||
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
||||
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
||||
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
|
||||
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
|
||||
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
|
||||
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
||||
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
|
||||
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
||||
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
|
||||
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
||||
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
|
||||
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
|
||||
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
||||
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
|
||||
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
||||
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
|
||||
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
||||
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
|
||||
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
|
||||
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
|
||||
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
||||
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
||||
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
|
||||
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
|
||||
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
|
||||
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
||||
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
|
||||
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
||||
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
|
||||
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
||||
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
|
||||
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
|
||||
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
||||
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
|
||||
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
||||
};
|
||||
|
||||
u_int32_t
|
||||
ssh_crc32(const u_char *buf, u_int32_t size)
|
||||
{
|
||||
u_int32_t i, crc;
|
||||
|
||||
crc = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
|
||||
return crc;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
/* $OpenBSD: crc32.h,v 1.15 2006/03/25 22:22:43 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SSH_CRC32_H
|
||||
#define SSH_CRC32_H
|
||||
u_int32_t ssh_crc32(const u_char *, u_int32_t);
|
||||
#endif
|
@ -1,160 +0,0 @@
|
||||
/* $OpenBSD: deattack.c,v 1.30 2006/09/16 19:53:37 djm Exp $ */
|
||||
/*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "deattack.h"
|
||||
#include "log.h"
|
||||
#include "crc32.h"
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* CRC attack detection has a worst-case behaviour that is O(N^3) over
|
||||
* the number of identical blocks in a packet. This behaviour can be
|
||||
* exploited to create a limited denial of service attack.
|
||||
*
|
||||
* However, because we are dealing with encrypted data, identical
|
||||
* blocks should only occur every 2^35 maximally-sized packets or so.
|
||||
* Consequently, we can detect this DoS by looking for identical blocks
|
||||
* in a packet.
|
||||
*
|
||||
* The parameter below determines how many identical blocks we will
|
||||
* accept in a single packet, trading off between attack detection and
|
||||
* likelihood of terminating a legitimate connection. A value of 32
|
||||
* corresponds to an average of 2^40 messages before an attack is
|
||||
* misdetected
|
||||
*/
|
||||
#define MAX_IDENTICAL 32
|
||||
|
||||
/* SSH Constants */
|
||||
#define SSH_MAXBLOCKS (32 * 1024)
|
||||
#define SSH_BLOCKSIZE (8)
|
||||
|
||||
/* Hashing constants */
|
||||
#define HASH_MINSIZE (8 * 1024)
|
||||
#define HASH_ENTRYSIZE (2)
|
||||
#define HASH_FACTOR(x) ((x)*3/2)
|
||||
#define HASH_UNUSEDCHAR (0xff)
|
||||
#define HASH_UNUSED (0xffff)
|
||||
#define HASH_IV (0xfffe)
|
||||
|
||||
#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE)
|
||||
|
||||
|
||||
/* Hash function (Input keys are cipher results) */
|
||||
#define HASH(x) get_u32(x)
|
||||
|
||||
#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE))
|
||||
|
||||
static void
|
||||
crc_update(u_int32_t *a, u_int32_t b)
|
||||
{
|
||||
b ^= *a;
|
||||
*a = ssh_crc32((u_char *)&b, sizeof(b));
|
||||
}
|
||||
|
||||
/* detect if a block is used in a particular pattern */
|
||||
static int
|
||||
check_crc(u_char *S, u_char *buf, u_int32_t len)
|
||||
{
|
||||
u_int32_t crc;
|
||||
u_char *c;
|
||||
|
||||
crc = 0;
|
||||
for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
|
||||
if (!CMP(S, c)) {
|
||||
crc_update(&crc, 1);
|
||||
crc_update(&crc, 0);
|
||||
} else {
|
||||
crc_update(&crc, 0);
|
||||
crc_update(&crc, 0);
|
||||
}
|
||||
}
|
||||
return (crc == 0);
|
||||
}
|
||||
|
||||
|
||||
/* Detect a crc32 compensation attack on a packet */
|
||||
int
|
||||
detect_attack(u_char *buf, u_int32_t len)
|
||||
{
|
||||
static u_int16_t *h = (u_int16_t *) NULL;
|
||||
static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
|
||||
u_int32_t i, j;
|
||||
u_int32_t l, same;
|
||||
u_char *c;
|
||||
u_char *d;
|
||||
|
||||
if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
|
||||
len % SSH_BLOCKSIZE != 0) {
|
||||
fatal("detect_attack: bad length %d", len);
|
||||
}
|
||||
for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
|
||||
;
|
||||
|
||||
if (h == NULL) {
|
||||
debug("Installing crc compensation attack detector.");
|
||||
h = (u_int16_t *) xcalloc(l, HASH_ENTRYSIZE);
|
||||
n = l;
|
||||
} else {
|
||||
if (l > n) {
|
||||
h = (u_int16_t *)xrealloc(h, l, HASH_ENTRYSIZE);
|
||||
n = l;
|
||||
}
|
||||
}
|
||||
|
||||
if (len <= HASH_MINBLOCKS) {
|
||||
for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) {
|
||||
for (d = buf; d < c; d += SSH_BLOCKSIZE) {
|
||||
if (!CMP(c, d)) {
|
||||
if ((check_crc(c, buf, len)))
|
||||
return (DEATTACK_DETECTED);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (DEATTACK_OK);
|
||||
}
|
||||
memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE);
|
||||
|
||||
for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
|
||||
for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
|
||||
i = (i + 1) & (n - 1)) {
|
||||
if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
|
||||
if (++same > MAX_IDENTICAL)
|
||||
return (DEATTACK_DOS_DETECTED);
|
||||
if (check_crc(c, buf, len))
|
||||
return (DEATTACK_DETECTED);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
h[i] = j;
|
||||
}
|
||||
return (DEATTACK_OK);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/* $OpenBSD: deattack.h,v 1.10 2006/09/16 19:53:37 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Cryptographic attack detector for ssh - Header file
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef _DEATTACK_H
|
||||
#define _DEATTACK_H
|
||||
|
||||
/* Return codes */
|
||||
#define DEATTACK_OK 0
|
||||
#define DEATTACK_DETECTED 1
|
||||
#define DEATTACK_DOS_DETECTED 2
|
||||
|
||||
int detect_attack(u_char *, u_int32_t);
|
||||
#endif
|
@ -1,732 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2003 Damien Miller. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEFINES_H
|
||||
#define _DEFINES_H
|
||||
|
||||
/* $Id: defines.h,v 1.138 2006/09/21 13:13:30 dtucker Exp $ */
|
||||
|
||||
|
||||
/* Constants */
|
||||
|
||||
#if defined(HAVE_DECL_SHUT_RD) && HAVE_DECL_SHUT_RD == 0
|
||||
enum
|
||||
{
|
||||
SHUT_RD = 0, /* No more receptions. */
|
||||
SHUT_WR, /* No more transmissions. */
|
||||
SHUT_RDWR /* No more receptions or transmissions. */
|
||||
};
|
||||
# define SHUT_RD SHUT_RD
|
||||
# define SHUT_WR SHUT_WR
|
||||
# define SHUT_RDWR SHUT_RDWR
|
||||
#endif
|
||||
|
||||
#ifndef IPTOS_LOWDELAY
|
||||
# define IPTOS_LOWDELAY 0x10
|
||||
# define IPTOS_THROUGHPUT 0x08
|
||||
# define IPTOS_RELIABILITY 0x04
|
||||
# define IPTOS_LOWCOST 0x02
|
||||
# define IPTOS_MINCOST IPTOS_LOWCOST
|
||||
#endif /* IPTOS_LOWDELAY */
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# ifdef PATH_MAX
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
# else /* PATH_MAX */
|
||||
# define MAXPATHLEN 64
|
||||
/* realpath uses a fixed buffer of size MAXPATHLEN, so force use of ours */
|
||||
# ifndef BROKEN_REALPATH
|
||||
# define BROKEN_REALPATH 1
|
||||
# endif /* BROKEN_REALPATH */
|
||||
# endif /* PATH_MAX */
|
||||
#endif /* MAXPATHLEN */
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# ifdef _POSIX_PATH_MAX
|
||||
# define PATH_MAX _POSIX_PATH_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MAXSYMLINKS
|
||||
# define MAXSYMLINKS 5
|
||||
#endif
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
# define STDIN_FILENO 0
|
||||
#endif
|
||||
#ifndef STDOUT_FILENO
|
||||
# define STDOUT_FILENO 1
|
||||
#endif
|
||||
#ifndef STDERR_FILENO
|
||||
# define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
#ifndef NGROUPS_MAX /* Disable groupaccess if NGROUP_MAX is not set */
|
||||
#ifdef NGROUPS
|
||||
#define NGROUPS_MAX NGROUPS
|
||||
#else
|
||||
#define NGROUPS_MAX 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DECL_O_NONBLOCK) && HAVE_DECL_O_NONBLOCK == 0
|
||||
# define O_NONBLOCK 00004 /* Non Blocking Open */
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR))
|
||||
#endif /* S_ISDIR */
|
||||
|
||||
#ifndef S_ISREG
|
||||
# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
|
||||
#endif /* S_ISREG */
|
||||
|
||||
#ifndef S_ISLNK
|
||||
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#endif /* S_ISLNK */
|
||||
|
||||
#ifndef S_IXUSR
|
||||
# define S_IXUSR 0000100 /* execute/search permission, */
|
||||
# define S_IXGRP 0000010 /* execute/search permission, */
|
||||
# define S_IXOTH 0000001 /* execute/search permission, */
|
||||
# define _S_IWUSR 0000200 /* write permission, */
|
||||
# define S_IWUSR _S_IWUSR /* write permission, owner */
|
||||
# define S_IWGRP 0000020 /* write permission, group */
|
||||
# define S_IWOTH 0000002 /* write permission, other */
|
||||
# define S_IRUSR 0000400 /* read permission, owner */
|
||||
# define S_IRGRP 0000040 /* read permission, group */
|
||||
# define S_IROTH 0000004 /* read permission, other */
|
||||
# define S_IRWXU 0000700 /* read, write, execute */
|
||||
# define S_IRWXG 0000070 /* read, write, execute */
|
||||
# define S_IRWXO 0000007 /* read, write, execute */
|
||||
#endif /* S_IXUSR */
|
||||
|
||||
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
# define MAP_FAILED ((void *)-1)
|
||||
#endif
|
||||
|
||||
/* *-*-nto-qnx doesn't define this constant in the system headers */
|
||||
#ifdef MISSING_NFDBITS
|
||||
# define NFDBITS (8 * sizeof(unsigned long))
|
||||
#endif
|
||||
|
||||
/*
|
||||
SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but
|
||||
including rpc/rpc.h breaks Solaris 6
|
||||
*/
|
||||
#ifndef INADDR_LOOPBACK
|
||||
#define INADDR_LOOPBACK ((u_long)0x7f000001)
|
||||
#endif
|
||||
|
||||
/* Types */
|
||||
|
||||
/* If sys/types.h does not supply intXX_t, supply them ourselves */
|
||||
/* (or die trying) */
|
||||
|
||||
#ifndef HAVE_U_INT
|
||||
typedef unsigned int u_int;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INTXX_T
|
||||
# if (SIZEOF_CHAR == 1)
|
||||
typedef char int8_t;
|
||||
# else
|
||||
# error "8 bit int type not found."
|
||||
# endif
|
||||
# if (SIZEOF_SHORT_INT == 2)
|
||||
typedef short int int16_t;
|
||||
# else
|
||||
# ifdef _UNICOS
|
||||
# if (SIZEOF_SHORT_INT == 4)
|
||||
typedef short int16_t;
|
||||
# else
|
||||
typedef long int16_t;
|
||||
# endif
|
||||
# else
|
||||
# error "16 bit int type not found."
|
||||
# endif /* _UNICOS */
|
||||
# endif
|
||||
# if (SIZEOF_INT == 4)
|
||||
typedef int int32_t;
|
||||
# else
|
||||
# ifdef _UNICOS
|
||||
typedef long int32_t;
|
||||
# else
|
||||
# error "32 bit int type not found."
|
||||
# endif /* _UNICOS */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If sys/types.h does not supply u_intXX_t, supply them ourselves */
|
||||
#ifndef HAVE_U_INTXX_T
|
||||
# ifdef HAVE_UINTXX_T
|
||||
typedef uint8_t u_int8_t;
|
||||
typedef uint16_t u_int16_t;
|
||||
typedef uint32_t u_int32_t;
|
||||
# define HAVE_U_INTXX_T 1
|
||||
# else
|
||||
# if (SIZEOF_CHAR == 1)
|
||||
typedef unsigned char u_int8_t;
|
||||
# else
|
||||
# error "8 bit int type not found."
|
||||
# endif
|
||||
# if (SIZEOF_SHORT_INT == 2)
|
||||
typedef unsigned short int u_int16_t;
|
||||
# else
|
||||
# ifdef _UNICOS
|
||||
# if (SIZEOF_SHORT_INT == 4)
|
||||
typedef unsigned short u_int16_t;
|
||||
# else
|
||||
typedef unsigned long u_int16_t;
|
||||
# endif
|
||||
# else
|
||||
# error "16 bit int type not found."
|
||||
# endif
|
||||
# endif
|
||||
# if (SIZEOF_INT == 4)
|
||||
typedef unsigned int u_int32_t;
|
||||
# else
|
||||
# ifdef _UNICOS
|
||||
typedef unsigned long u_int32_t;
|
||||
# else
|
||||
# error "32 bit int type not found."
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#define __BIT_TYPES_DEFINED__
|
||||
#endif
|
||||
|
||||
/* 64-bit types */
|
||||
#ifndef HAVE_INT64_T
|
||||
# if (SIZEOF_LONG_INT == 8)
|
||||
typedef long int int64_t;
|
||||
# else
|
||||
# if (SIZEOF_LONG_LONG_INT == 8)
|
||||
typedef long long int int64_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_U_INT64_T
|
||||
# if (SIZEOF_LONG_INT == 8)
|
||||
typedef unsigned long int u_int64_t;
|
||||
# else
|
||||
# if (SIZEOF_LONG_LONG_INT == 8)
|
||||
typedef unsigned long long int u_int64_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_U_CHAR
|
||||
typedef unsigned char u_char;
|
||||
# define HAVE_U_CHAR
|
||||
#endif /* HAVE_U_CHAR */
|
||||
|
||||
#ifndef SIZE_T_MAX
|
||||
#define SIZE_T_MAX ULONG_MAX
|
||||
#endif /* SIZE_T_MAX */
|
||||
|
||||
#ifndef HAVE_SIZE_T
|
||||
typedef unsigned int size_t;
|
||||
# define HAVE_SIZE_T
|
||||
# define SIZE_T_MAX UINT_MAX
|
||||
#endif /* HAVE_SIZE_T */
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
typedef int ssize_t;
|
||||
# define HAVE_SSIZE_T
|
||||
#endif /* HAVE_SSIZE_T */
|
||||
|
||||
#ifndef HAVE_CLOCK_T
|
||||
typedef long clock_t;
|
||||
# define HAVE_CLOCK_T
|
||||
#endif /* HAVE_CLOCK_T */
|
||||
|
||||
#ifndef HAVE_SA_FAMILY_T
|
||||
typedef int sa_family_t;
|
||||
# define HAVE_SA_FAMILY_T
|
||||
#endif /* HAVE_SA_FAMILY_T */
|
||||
|
||||
#ifndef HAVE_PID_T
|
||||
typedef int pid_t;
|
||||
# define HAVE_PID_T
|
||||
#endif /* HAVE_PID_T */
|
||||
|
||||
#ifndef HAVE_SIG_ATOMIC_T
|
||||
typedef int sig_atomic_t;
|
||||
# define HAVE_SIG_ATOMIC_T
|
||||
#endif /* HAVE_SIG_ATOMIC_T */
|
||||
|
||||
#ifndef HAVE_MODE_T
|
||||
typedef int mode_t;
|
||||
# define HAVE_MODE_T
|
||||
#endif /* HAVE_MODE_T */
|
||||
|
||||
#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS)
|
||||
# define ss_family __ss_family
|
||||
#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */
|
||||
|
||||
#ifndef HAVE_SYS_UN_H
|
||||
struct sockaddr_un {
|
||||
short sun_family; /* AF_UNIX */
|
||||
char sun_path[108]; /* path name (gag) */
|
||||
};
|
||||
#endif /* HAVE_SYS_UN_H */
|
||||
|
||||
#ifndef HAVE_IN_ADDR_T
|
||||
typedef u_int32_t in_addr_t;
|
||||
#endif
|
||||
|
||||
#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE)
|
||||
#define _STRUCT_WINSIZE
|
||||
struct winsize {
|
||||
unsigned short ws_row; /* rows, in characters */
|
||||
unsigned short ws_col; /* columns, in character */
|
||||
unsigned short ws_xpixel; /* horizontal size, pixels */
|
||||
unsigned short ws_ypixel; /* vertical size, pixels */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* *-*-nto-qnx does not define this type in the system headers */
|
||||
#ifdef MISSING_FD_MASK
|
||||
typedef unsigned long int fd_mask;
|
||||
#endif
|
||||
|
||||
/* Paths */
|
||||
|
||||
#ifndef _PATH_BSHELL
|
||||
# define _PATH_BSHELL "/bin/sh"
|
||||
#endif
|
||||
#ifndef _PATH_CSHELL
|
||||
# define _PATH_CSHELL "/bin/csh"
|
||||
#endif
|
||||
#ifndef _PATH_SHELLS
|
||||
# define _PATH_SHELLS "/etc/shells"
|
||||
#endif
|
||||
|
||||
#ifdef USER_PATH
|
||||
# ifdef _PATH_STDPATH
|
||||
# undef _PATH_STDPATH
|
||||
# endif
|
||||
# define _PATH_STDPATH USER_PATH
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_STDPATH
|
||||
# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
|
||||
#endif
|
||||
|
||||
#ifndef SUPERUSER_PATH
|
||||
# define SUPERUSER_PATH _PATH_STDPATH
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_DEVNULL
|
||||
# define _PATH_DEVNULL "/dev/null"
|
||||
#endif
|
||||
|
||||
#ifndef MAIL_DIRECTORY
|
||||
# define MAIL_DIRECTORY "/var/spool/mail"
|
||||
#endif
|
||||
|
||||
#ifndef MAILDIR
|
||||
# define MAILDIR MAIL_DIRECTORY
|
||||
#endif
|
||||
|
||||
#if !defined(_PATH_MAILDIR) && defined(MAILDIR)
|
||||
# define _PATH_MAILDIR MAILDIR
|
||||
#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */
|
||||
|
||||
#ifndef _PATH_NOLOGIN
|
||||
# define _PATH_NOLOGIN "/etc/nologin"
|
||||
#endif
|
||||
|
||||
/* Define this to be the path of the xauth program. */
|
||||
#ifdef XAUTH_PATH
|
||||
#define _PATH_XAUTH XAUTH_PATH
|
||||
#endif /* XAUTH_PATH */
|
||||
|
||||
/* derived from XF4/xc/lib/dps/Xlibnet.h */
|
||||
#ifndef X_UNIX_PATH
|
||||
# ifdef __hpux
|
||||
# define X_UNIX_PATH "/var/spool/sockets/X11/%u"
|
||||
# else
|
||||
# define X_UNIX_PATH "/tmp/.X11-unix/X%u"
|
||||
# endif
|
||||
#endif /* X_UNIX_PATH */
|
||||
#define _PATH_UNIX_X X_UNIX_PATH
|
||||
|
||||
#ifndef _PATH_TTY
|
||||
# define _PATH_TTY "/dev/tty"
|
||||
#endif
|
||||
|
||||
/* Macros */
|
||||
|
||||
#if defined(HAVE_LOGIN_GETCAPBOOL) && defined(HAVE_LOGIN_CAP_H)
|
||||
# define HAVE_LOGIN_CAP
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
# define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef roundup
|
||||
# define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
||||
#endif
|
||||
|
||||
#ifndef timersub
|
||||
#define timersub(a, b, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((result)->tv_usec < 0) { \
|
||||
--(result)->tv_sec; \
|
||||
(result)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef TIMEVAL_TO_TIMESPEC
|
||||
#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
|
||||
(ts)->tv_sec = (tv)->tv_sec; \
|
||||
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TIMESPEC_TO_TIMEVAL
|
||||
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
|
||||
(tv)->tv_sec = (ts)->tv_sec; \
|
||||
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __P
|
||||
# define __P(x) x
|
||||
#endif
|
||||
|
||||
#if !defined(IN6_IS_ADDR_V4MAPPED)
|
||||
# define IN6_IS_ADDR_V4MAPPED(a) \
|
||||
((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
|
||||
(((u_int32_t *) (a))[2] == htonl (0xffff)))
|
||||
#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */
|
||||
|
||||
#if !defined(__GNUC__) || (__GNUC__ < 2)
|
||||
# define __attribute__(x)
|
||||
#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
|
||||
|
||||
#ifndef __dead
|
||||
# define __dead __attribute__((noreturn))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ATTRIBUTE__SENTINEL__) && !defined(__sentinel__)
|
||||
# define __sentinel__
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__)
|
||||
# define __bounded__(x, y, z)
|
||||
#endif
|
||||
|
||||
/* *-*-nto-qnx doesn't define this macro in the system headers */
|
||||
#ifdef MISSING_HOWMANY
|
||||
# define howmany(x,y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
|
||||
#ifndef OSSH_ALIGNBYTES
|
||||
#define OSSH_ALIGNBYTES (sizeof(int) - 1)
|
||||
#endif
|
||||
#ifndef __CMSG_ALIGN
|
||||
#define __CMSG_ALIGN(p) (((u_int)(p) + OSSH_ALIGNBYTES) &~ OSSH_ALIGNBYTES)
|
||||
#endif
|
||||
|
||||
/* Length of the contents of a control message of length len */
|
||||
#ifndef CMSG_LEN
|
||||
#define CMSG_LEN(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
|
||||
#endif
|
||||
|
||||
/* Length of the space taken up by a padded control message of length len */
|
||||
#ifndef CMSG_SPACE
|
||||
#define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len))
|
||||
#endif
|
||||
|
||||
/* given pointer to struct cmsghdr, return pointer to data */
|
||||
#ifndef CMSG_DATA
|
||||
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr)))
|
||||
#endif /* CMSG_DATA */
|
||||
|
||||
/*
|
||||
* RFC 2292 requires to check msg_controllen, in case that the kernel returns
|
||||
* an empty list for some reasons.
|
||||
*/
|
||||
#ifndef CMSG_FIRSTHDR
|
||||
#define CMSG_FIRSTHDR(mhdr) \
|
||||
((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
|
||||
(struct cmsghdr *)(mhdr)->msg_control : \
|
||||
(struct cmsghdr *)NULL)
|
||||
#endif /* CMSG_FIRSTHDR */
|
||||
|
||||
#ifndef offsetof
|
||||
# define offsetof(type, member) ((size_t) &((type *)0)->member)
|
||||
#endif
|
||||
|
||||
/* Set up BSD-style BYTE_ORDER definition if it isn't there already */
|
||||
/* XXX: doesn't try to cope with strange byte orders (PDP_ENDIAN) */
|
||||
#ifndef BYTE_ORDER
|
||||
# ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# endif /* LITTLE_ENDIAN */
|
||||
# ifndef BIG_ENDIAN
|
||||
# define BIG_ENDIAN 4321
|
||||
# endif /* BIG_ENDIAN */
|
||||
# ifdef WORDS_BIGENDIAN
|
||||
# define BYTE_ORDER BIG_ENDIAN
|
||||
# else /* WORDS_BIGENDIAN */
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
# endif /* WORDS_BIGENDIAN */
|
||||
#endif /* BYTE_ORDER */
|
||||
|
||||
/* Function replacement / compatibility hacks */
|
||||
|
||||
#if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO))
|
||||
# define HAVE_GETADDRINFO
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETOPT_OPTRESET
|
||||
# undef getopt
|
||||
# undef opterr
|
||||
# undef optind
|
||||
# undef optopt
|
||||
# undef optreset
|
||||
# undef optarg
|
||||
# define getopt(ac, av, o) BSDgetopt(ac, av, o)
|
||||
# define opterr BSDopterr
|
||||
# define optind BSDoptind
|
||||
# define optopt BSDoptopt
|
||||
# define optreset BSDoptreset
|
||||
# define optarg BSDoptarg
|
||||
#endif
|
||||
|
||||
#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO)
|
||||
# undef HAVE_GETADDRINFO
|
||||
#endif
|
||||
#if defined(BROKEN_GETADDRINFO) && defined(HAVE_FREEADDRINFO)
|
||||
# undef HAVE_FREEADDRINFO
|
||||
#endif
|
||||
#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GAI_STRERROR)
|
||||
# undef HAVE_GAI_STRERROR
|
||||
#endif
|
||||
|
||||
#if defined(BROKEN_UPDWTMPX) && defined(HAVE_UPDWTMPX)
|
||||
# undef HAVE_UPDWTMPX
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
|
||||
defined(SYSLOG_R_SAFE_IN_SIGHAND)
|
||||
# define DO_LOG_SAFE_IN_SIGHAND
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
|
||||
# define memmove(s1, s2, n) bcopy((s2), (s1), (n))
|
||||
#endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */
|
||||
|
||||
#if defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX)
|
||||
# define USE_VHANGUP
|
||||
#endif /* defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) */
|
||||
|
||||
#ifndef GETPGRP_VOID
|
||||
# include <unistd.h>
|
||||
# define getpgrp() getpgrp(0)
|
||||
#endif
|
||||
|
||||
#ifdef USE_BSM_AUDIT
|
||||
# define SSH_AUDIT_EVENTS
|
||||
# define CUSTOM_SSH_AUDIT_EVENTS
|
||||
#endif
|
||||
|
||||
/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
|
||||
#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
|
||||
# define OPENSSL_free(x) Free(x)
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
|
||||
# define __func__ __FUNCTION__
|
||||
#elif !defined(HAVE___func__)
|
||||
# define __func__ ""
|
||||
#endif
|
||||
|
||||
#if defined(KRB5) && !defined(HEIMDAL)
|
||||
# define krb5_get_err_text(context,code) error_message(code)
|
||||
#endif
|
||||
|
||||
#if defined(SKEYCHALLENGE_4ARG)
|
||||
# define _compat_skeychallenge(a,b,c,d) skeychallenge(a,b,c,d)
|
||||
#else
|
||||
# define _compat_skeychallenge(a,b,c,d) skeychallenge(a,b,c)
|
||||
#endif
|
||||
|
||||
/* Maximum number of file descriptors available */
|
||||
#ifdef HAVE_SYSCONF
|
||||
# define SSH_SYSFDMAX sysconf(_SC_OPEN_MAX)
|
||||
#else
|
||||
# define SSH_SYSFDMAX 10000
|
||||
#endif
|
||||
|
||||
#if defined(__Lynx__)
|
||||
/*
|
||||
* LynxOS defines these in param.h which we do not want to include since
|
||||
* it will also pull in a bunch of kernel definitions.
|
||||
*/
|
||||
# define ALIGNBYTES (sizeof(int) - 1)
|
||||
# define ALIGN(p) (((unsigned)p + ALIGNBYTES) & ~ALIGNBYTES)
|
||||
/* Missing prototypes on LynxOS */
|
||||
int snprintf (char *, size_t, const char *, ...);
|
||||
int mkstemp (char *);
|
||||
char *crypt (const char *, const char *);
|
||||
int seteuid (uid_t);
|
||||
int setegid (gid_t);
|
||||
char *mkdtemp (char *);
|
||||
int rresvport_af (int *, sa_family_t);
|
||||
int innetgr (const char *, const char *, const char *, const char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define this to use pipes instead of socketpairs for communicating with the
|
||||
* client program. Socketpairs do not seem to work on all systems.
|
||||
*
|
||||
* configure.ac sets this for a few OS's which are known to have problems
|
||||
* but you may need to set it yourself
|
||||
*/
|
||||
/* #define USE_PIPES 1 */
|
||||
|
||||
/**
|
||||
** login recorder definitions
|
||||
**/
|
||||
|
||||
/* FIXME: put default paths back in */
|
||||
#ifndef UTMP_FILE
|
||||
# ifdef _PATH_UTMP
|
||||
# define UTMP_FILE _PATH_UTMP
|
||||
# else
|
||||
# ifdef CONF_UTMP_FILE
|
||||
# define UTMP_FILE CONF_UTMP_FILE
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef WTMP_FILE
|
||||
# ifdef _PATH_WTMP
|
||||
# define WTMP_FILE _PATH_WTMP
|
||||
# else
|
||||
# ifdef CONF_WTMP_FILE
|
||||
# define WTMP_FILE CONF_WTMP_FILE
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
/* pick up the user's location for lastlog if given */
|
||||
#ifndef LASTLOG_FILE
|
||||
# ifdef _PATH_LASTLOG
|
||||
# define LASTLOG_FILE _PATH_LASTLOG
|
||||
# else
|
||||
# ifdef CONF_LASTLOG_FILE
|
||||
# define LASTLOG_FILE CONF_LASTLOG_FILE
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
|
||||
# define USE_SHADOW
|
||||
#endif
|
||||
|
||||
/* The login() library function in libutil is first choice */
|
||||
#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN)
|
||||
# define USE_LOGIN
|
||||
|
||||
#else
|
||||
/* Simply select your favourite login types. */
|
||||
/* Can't do if-else because some systems use several... <sigh> */
|
||||
# if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX)
|
||||
# define USE_UTMPX
|
||||
# endif
|
||||
# if defined(UTMP_FILE) && !defined(DISABLE_UTMP)
|
||||
# define USE_UTMP
|
||||
# endif
|
||||
# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX)
|
||||
# define USE_WTMPX
|
||||
# endif
|
||||
# if defined(WTMP_FILE) && !defined(DISABLE_WTMP)
|
||||
# define USE_WTMP
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef UT_LINESIZE
|
||||
# define UT_LINESIZE 8
|
||||
#endif
|
||||
|
||||
/* I hope that the presence of LASTLOG_FILE is enough to detect this */
|
||||
#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG)
|
||||
# define USE_LASTLOG
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OSF_SIA
|
||||
# ifdef USE_SHADOW
|
||||
# undef USE_SHADOW
|
||||
# endif
|
||||
# define CUSTOM_SYS_AUTH_PASSWD 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBIAF
|
||||
# define CUSTOM_SYS_AUTH_PASSWD 1
|
||||
#endif
|
||||
|
||||
/* HP-UX 11.11 */
|
||||
#ifdef BTMP_FILE
|
||||
# define _PATH_BTMP BTMP_FILE
|
||||
#endif
|
||||
|
||||
#if defined(USE_BTMP) && defined(_PATH_BTMP)
|
||||
# define CUSTOM_FAILED_LOGIN
|
||||
#endif
|
||||
|
||||
/** end of login recorder definitions */
|
||||
|
||||
#ifdef BROKEN_GETGROUPS
|
||||
# define getgroups(a,b) ((a)==0 && (b)==NULL ? NGROUPS_MAX : getgroups((a),(b)))
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MMAP) && defined(BROKEN_MMAP)
|
||||
# undef HAVE_MMAP
|
||||
#endif
|
||||
|
||||
#ifndef IOV_MAX
|
||||
# if defined(_XOPEN_IOV_MAX)
|
||||
# define IOV_MAX _XOPEN_IOV_MAX
|
||||
# elif defined(DEF_IOV_MAX)
|
||||
# define IOV_MAX DEF_IOV_MAX
|
||||
# else
|
||||
# define IOV_MAX 16
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _DEFINES_H */
|
@ -1,331 +0,0 @@
|
||||
/* $OpenBSD: dh.c,v 1.43 2006/11/06 21:25:28 markus Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dh.h"
|
||||
#include "pathnames.h"
|
||||
#include "log.h"
|
||||
#include "misc.h"
|
||||
|
||||
static int
|
||||
parse_prime(int linenum, char *line, struct dhgroup *dhg)
|
||||
{
|
||||
char *cp, *arg;
|
||||
char *strsize, *gen, *prime;
|
||||
const char *errstr = NULL;
|
||||
|
||||
cp = line;
|
||||
if ((arg = strdelim(&cp)) == NULL)
|
||||
return 0;
|
||||
/* Ignore leading whitespace */
|
||||
if (*arg == '\0')
|
||||
arg = strdelim(&cp);
|
||||
if (!arg || !*arg || *arg == '#')
|
||||
return 0;
|
||||
|
||||
/* time */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
arg = strsep(&cp, " "); /* type */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
arg = strsep(&cp, " "); /* tests */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
arg = strsep(&cp, " "); /* tries */
|
||||
if (cp == NULL || *arg == '\0')
|
||||
goto fail;
|
||||
strsize = strsep(&cp, " "); /* size */
|
||||
if (cp == NULL || *strsize == '\0' ||
|
||||
(dhg->size = (u_int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 ||
|
||||
errstr)
|
||||
goto fail;
|
||||
/* The whole group is one bit larger */
|
||||
dhg->size++;
|
||||
gen = strsep(&cp, " "); /* gen */
|
||||
if (cp == NULL || *gen == '\0')
|
||||
goto fail;
|
||||
prime = strsep(&cp, " "); /* prime */
|
||||
if (cp != NULL || *prime == '\0')
|
||||
goto fail;
|
||||
|
||||
if ((dhg->g = BN_new()) == NULL)
|
||||
fatal("parse_prime: BN_new failed");
|
||||
if ((dhg->p = BN_new()) == NULL)
|
||||
fatal("parse_prime: BN_new failed");
|
||||
if (BN_hex2bn(&dhg->g, gen) == 0)
|
||||
goto failclean;
|
||||
|
||||
if (BN_hex2bn(&dhg->p, prime) == 0)
|
||||
goto failclean;
|
||||
|
||||
if (BN_num_bits(dhg->p) != dhg->size)
|
||||
goto failclean;
|
||||
|
||||
if (BN_is_zero(dhg->g) || BN_is_one(dhg->g))
|
||||
goto failclean;
|
||||
|
||||
return (1);
|
||||
|
||||
failclean:
|
||||
BN_clear_free(dhg->g);
|
||||
BN_clear_free(dhg->p);
|
||||
fail:
|
||||
error("Bad prime description in line %d", linenum);
|
||||
return (0);
|
||||
}
|
||||
|
||||
DH *
|
||||
choose_dh(int min, int wantbits, int max)
|
||||
{
|
||||
FILE *f;
|
||||
char line[4096];
|
||||
int best, bestcount, which;
|
||||
int linenum;
|
||||
struct dhgroup dhg;
|
||||
|
||||
if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL &&
|
||||
(f = fopen(_PATH_DH_PRIMES, "r")) == NULL) {
|
||||
logit("WARNING: %s does not exist, using fixed modulus",
|
||||
_PATH_DH_MODULI);
|
||||
return (dh_new_group14());
|
||||
}
|
||||
|
||||
linenum = 0;
|
||||
best = bestcount = 0;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
linenum++;
|
||||
if (!parse_prime(linenum, line, &dhg))
|
||||
continue;
|
||||
BN_clear_free(dhg.g);
|
||||
BN_clear_free(dhg.p);
|
||||
|
||||
if (dhg.size > max || dhg.size < min)
|
||||
continue;
|
||||
|
||||
if ((dhg.size > wantbits && dhg.size < best) ||
|
||||
(dhg.size > best && best < wantbits)) {
|
||||
best = dhg.size;
|
||||
bestcount = 0;
|
||||
}
|
||||
if (dhg.size == best)
|
||||
bestcount++;
|
||||
}
|
||||
rewind(f);
|
||||
|
||||
if (bestcount == 0) {
|
||||
fclose(f);
|
||||
logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES);
|
||||
return (dh_new_group14());
|
||||
}
|
||||
|
||||
linenum = 0;
|
||||
which = arc4random() % bestcount;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
if (!parse_prime(linenum, line, &dhg))
|
||||
continue;
|
||||
if ((dhg.size > max || dhg.size < min) ||
|
||||
dhg.size != best ||
|
||||
linenum++ != which) {
|
||||
BN_clear_free(dhg.g);
|
||||
BN_clear_free(dhg.p);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
if (linenum != which+1)
|
||||
fatal("WARNING: line %d disappeared in %s, giving up",
|
||||
which, _PATH_DH_PRIMES);
|
||||
|
||||
return (dh_new_group(dhg.g, dhg.p));
|
||||
}
|
||||
|
||||
/* diffie-hellman-groupN-sha1 */
|
||||
|
||||
int
|
||||
dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
|
||||
{
|
||||
int i;
|
||||
int n = BN_num_bits(dh_pub);
|
||||
int bits_set = 0;
|
||||
BIGNUM *tmp;
|
||||
|
||||
if (dh_pub->neg) {
|
||||
logit("invalid public DH value: negativ");
|
||||
return 0;
|
||||
}
|
||||
if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */
|
||||
logit("invalid public DH value: <= 1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((tmp = BN_new()) == NULL)
|
||||
return (-1);
|
||||
if (!BN_sub(tmp, dh->p, BN_value_one()) ||
|
||||
BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
|
||||
BN_clear_free(tmp);
|
||||
logit("invalid public DH value: >= p-1");
|
||||
return 0;
|
||||
}
|
||||
BN_clear_free(tmp);
|
||||
|
||||
for (i = 0; i <= n; i++)
|
||||
if (BN_is_bit_set(dh_pub, i))
|
||||
bits_set++;
|
||||
debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
|
||||
|
||||
/* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
|
||||
if (bits_set > 1)
|
||||
return 1;
|
||||
|
||||
logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
dh_gen_key(DH *dh, int need)
|
||||
{
|
||||
int i, bits_set, tries = 0;
|
||||
|
||||
if (dh->p == NULL)
|
||||
fatal("dh_gen_key: dh->p == NULL");
|
||||
if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p))
|
||||
fatal("dh_gen_key: group too small: %d (2*need %d)",
|
||||
BN_num_bits(dh->p), 2*need);
|
||||
do {
|
||||
if (dh->priv_key != NULL)
|
||||
BN_clear_free(dh->priv_key);
|
||||
if ((dh->priv_key = BN_new()) == NULL)
|
||||
fatal("dh_gen_key: BN_new failed");
|
||||
/* generate a 2*need bits random private exponent */
|
||||
if (!BN_rand(dh->priv_key, 2*need, 0, 0))
|
||||
fatal("dh_gen_key: BN_rand failed");
|
||||
if (DH_generate_key(dh) == 0)
|
||||
fatal("DH_generate_key");
|
||||
for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++)
|
||||
if (BN_is_bit_set(dh->priv_key, i))
|
||||
bits_set++;
|
||||
debug2("dh_gen_key: priv key bits set: %d/%d",
|
||||
bits_set, BN_num_bits(dh->priv_key));
|
||||
if (tries++ > 10)
|
||||
fatal("dh_gen_key: too many bad keys: giving up");
|
||||
} while (!dh_pub_is_valid(dh, dh->pub_key));
|
||||
}
|
||||
|
||||
DH *
|
||||
dh_new_group_asc(const char *gen, const char *modulus)
|
||||
{
|
||||
DH *dh;
|
||||
|
||||
if ((dh = DH_new()) == NULL)
|
||||
fatal("dh_new_group_asc: DH_new");
|
||||
|
||||
if (BN_hex2bn(&dh->p, modulus) == 0)
|
||||
fatal("BN_hex2bn p");
|
||||
if (BN_hex2bn(&dh->g, gen) == 0)
|
||||
fatal("BN_hex2bn g");
|
||||
|
||||
return (dh);
|
||||
}
|
||||
|
||||
/*
|
||||
* This just returns the group, we still need to generate the exchange
|
||||
* value.
|
||||
*/
|
||||
|
||||
DH *
|
||||
dh_new_group(BIGNUM *gen, BIGNUM *modulus)
|
||||
{
|
||||
DH *dh;
|
||||
|
||||
if ((dh = DH_new()) == NULL)
|
||||
fatal("dh_new_group: DH_new");
|
||||
dh->p = modulus;
|
||||
dh->g = gen;
|
||||
|
||||
return (dh);
|
||||
}
|
||||
|
||||
DH *
|
||||
dh_new_group1(void)
|
||||
{
|
||||
static char *gen = "2", *group1 =
|
||||
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
|
||||
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
|
||||
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
|
||||
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
|
||||
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
|
||||
"FFFFFFFF" "FFFFFFFF";
|
||||
|
||||
return (dh_new_group_asc(gen, group1));
|
||||
}
|
||||
|
||||
DH *
|
||||
dh_new_group14(void)
|
||||
{
|
||||
static char *gen = "2", *group14 =
|
||||
"FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
|
||||
"29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
|
||||
"EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
|
||||
"E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
|
||||
"EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D"
|
||||
"C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F"
|
||||
"83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D"
|
||||
"670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B"
|
||||
"E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9"
|
||||
"DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510"
|
||||
"15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF";
|
||||
|
||||
return (dh_new_group_asc(gen, group14));
|
||||
}
|
||||
|
||||
/*
|
||||
* Estimates the group order for a Diffie-Hellman group that has an
|
||||
* attack complexity approximately the same as O(2**bits). Estimate
|
||||
* with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3)))
|
||||
*/
|
||||
|
||||
int
|
||||
dh_estimate(int bits)
|
||||
{
|
||||
|
||||
if (bits <= 128)
|
||||
return (1024); /* O(2**86) */
|
||||
if (bits <= 192)
|
||||
return (2048); /* O(2**116) */
|
||||
return (4096); /* O(2**156) */
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/* $OpenBSD: dh.h,v 1.9 2006/03/25 22:22:43 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Niels Provos. 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 DH_H
|
||||
#define DH_H
|
||||
|
||||
struct dhgroup {
|
||||
int size;
|
||||
BIGNUM *g;
|
||||
BIGNUM *p;
|
||||
};
|
||||
|
||||
DH *choose_dh(int, int, int);
|
||||
DH *dh_new_group_asc(const char *, const char *);
|
||||
DH *dh_new_group(BIGNUM *, BIGNUM *);
|
||||
DH *dh_new_group1(void);
|
||||
DH *dh_new_group14(void);
|
||||
|
||||
void dh_gen_key(DH *, int);
|
||||
int dh_pub_is_valid(DH *, BIGNUM *);
|
||||
|
||||
int dh_estimate(int);
|
||||
|
||||
#define DH_GRP_MIN 1024
|
||||
#define DH_GRP_MAX 8192
|
||||
|
||||
#endif
|
@ -1,105 +0,0 @@
|
||||
/* $OpenBSD: dispatch.c,v 1.21 2006/08/03 03:34:42 deraadt 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.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ssh1.h"
|
||||
#include "ssh2.h"
|
||||
#include "log.h"
|
||||
#include "dispatch.h"
|
||||
#include "packet.h"
|
||||
#include "compat.h"
|
||||
|
||||
#define DISPATCH_MIN 0
|
||||
#define DISPATCH_MAX 255
|
||||
|
||||
dispatch_fn *dispatch[DISPATCH_MAX];
|
||||
|
||||
void
|
||||
dispatch_protocol_error(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
logit("dispatch_protocol_error: type %d seq %u", type, seq);
|
||||
if (!compat20)
|
||||
fatal("protocol error");
|
||||
packet_start(SSH2_MSG_UNIMPLEMENTED);
|
||||
packet_put_int(seq);
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
}
|
||||
void
|
||||
dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
logit("dispatch_protocol_ignore: type %d seq %u", type, seq);
|
||||
}
|
||||
void
|
||||
dispatch_init(dispatch_fn *dflt)
|
||||
{
|
||||
u_int i;
|
||||
for (i = 0; i < DISPATCH_MAX; i++)
|
||||
dispatch[i] = dflt;
|
||||
}
|
||||
void
|
||||
dispatch_range(u_int from, u_int to, dispatch_fn *fn)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = from; i <= to; i++) {
|
||||
if (i >= DISPATCH_MAX)
|
||||
break;
|
||||
dispatch[i] = fn;
|
||||
}
|
||||
}
|
||||
void
|
||||
dispatch_set(int type, dispatch_fn *fn)
|
||||
{
|
||||
dispatch[type] = fn;
|
||||
}
|
||||
void
|
||||
dispatch_run(int mode, volatile sig_atomic_t *done, void *ctxt)
|
||||
{
|
||||
for (;;) {
|
||||
int type;
|
||||
u_int32_t seqnr;
|
||||
|
||||
if (mode == DISPATCH_BLOCK) {
|
||||
type = packet_read_seqnr(&seqnr);
|
||||
} else {
|
||||
type = packet_read_poll_seqnr(&seqnr);
|
||||
if (type == SSH_MSG_NONE)
|
||||
return;
|
||||
}
|
||||
if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL)
|
||||
(*dispatch[type])(type, seqnr, ctxt);
|
||||
else
|
||||
packet_disconnect("protocol error: rcvd type %d", type);
|
||||
if (done != NULL && *done)
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/* $OpenBSD: dispatch.h,v 1.11 2006/04/20 09:27:09 djm 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.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
enum {
|
||||
DISPATCH_BLOCK,
|
||||
DISPATCH_NONBLOCK
|
||||
};
|
||||
|
||||
typedef void dispatch_fn(int, u_int32_t, void *);
|
||||
|
||||
void dispatch_init(dispatch_fn *);
|
||||
void dispatch_set(int, dispatch_fn *);
|
||||
void dispatch_range(u_int, u_int, dispatch_fn *);
|
||||
void dispatch_run(int, volatile sig_atomic_t *, void *);
|
||||
void dispatch_protocol_error(int, u_int32_t, void *);
|
||||
void dispatch_protocol_ignore(int, u_int32_t, void *);
|
@ -1,296 +0,0 @@
|
||||
/* $OpenBSD: dns.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||
* Copyright (c) 2003 Jakob Schlyter. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "key.h"
|
||||
#include "dns.h"
|
||||
#include "log.h"
|
||||
|
||||
static const char *errset_text[] = {
|
||||
"success", /* 0 ERRSET_SUCCESS */
|
||||
"out of memory", /* 1 ERRSET_NOMEMORY */
|
||||
"general failure", /* 2 ERRSET_FAIL */
|
||||
"invalid parameter", /* 3 ERRSET_INVAL */
|
||||
"name does not exist", /* 4 ERRSET_NONAME */
|
||||
"data does not exist", /* 5 ERRSET_NODATA */
|
||||
};
|
||||
|
||||
static const char *
|
||||
dns_result_totext(unsigned int res)
|
||||
{
|
||||
switch (res) {
|
||||
case ERRSET_SUCCESS:
|
||||
return errset_text[ERRSET_SUCCESS];
|
||||
case ERRSET_NOMEMORY:
|
||||
return errset_text[ERRSET_NOMEMORY];
|
||||
case ERRSET_FAIL:
|
||||
return errset_text[ERRSET_FAIL];
|
||||
case ERRSET_INVAL:
|
||||
return errset_text[ERRSET_INVAL];
|
||||
case ERRSET_NONAME:
|
||||
return errset_text[ERRSET_NONAME];
|
||||
case ERRSET_NODATA:
|
||||
return errset_text[ERRSET_NODATA];
|
||||
default:
|
||||
return "unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read SSHFP parameters from key buffer.
|
||||
*/
|
||||
static int
|
||||
dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||
u_char **digest, u_int *digest_len, const Key *key)
|
||||
{
|
||||
int success = 0;
|
||||
|
||||
switch (key->type) {
|
||||
case KEY_RSA:
|
||||
*algorithm = SSHFP_KEY_RSA;
|
||||
break;
|
||||
case KEY_DSA:
|
||||
*algorithm = SSHFP_KEY_DSA;
|
||||
break;
|
||||
default:
|
||||
*algorithm = SSHFP_KEY_RESERVED; /* 0 */
|
||||
}
|
||||
|
||||
if (*algorithm) {
|
||||
*digest_type = SSHFP_HASH_SHA1;
|
||||
*digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len);
|
||||
if (*digest == NULL)
|
||||
fatal("dns_read_key: null from key_fingerprint_raw()");
|
||||
success = 1;
|
||||
} else {
|
||||
*digest_type = SSHFP_HASH_RESERVED;
|
||||
*digest = NULL;
|
||||
*digest_len = 0;
|
||||
success = 0;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read SSHFP parameters from rdata buffer.
|
||||
*/
|
||||
static int
|
||||
dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type,
|
||||
u_char **digest, u_int *digest_len, u_char *rdata, int rdata_len)
|
||||
{
|
||||
int success = 0;
|
||||
|
||||
*algorithm = SSHFP_KEY_RESERVED;
|
||||
*digest_type = SSHFP_HASH_RESERVED;
|
||||
|
||||
if (rdata_len >= 2) {
|
||||
*algorithm = rdata[0];
|
||||
*digest_type = rdata[1];
|
||||
*digest_len = rdata_len - 2;
|
||||
|
||||
if (*digest_len > 0) {
|
||||
*digest = (u_char *) xmalloc(*digest_len);
|
||||
memcpy(*digest, rdata + 2, *digest_len);
|
||||
} else {
|
||||
*digest = (u_char *)xstrdup("");
|
||||
}
|
||||
|
||||
success = 1;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if hostname is numerical.
|
||||
* Returns -1 if hostname is numeric, 0 otherwise
|
||||
*/
|
||||
static int
|
||||
is_numeric_hostname(const char *hostname)
|
||||
{
|
||||
struct addrinfo hints, *ai;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
|
||||
if (getaddrinfo(hostname, "0", &hints, &ai) == 0) {
|
||||
freeaddrinfo(ai);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the given hostname, address and host key using DNS.
|
||||
* Returns 0 if lookup succeeds, -1 otherwise
|
||||
*/
|
||||
int
|
||||
verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
||||
const Key *hostkey, int *flags)
|
||||
{
|
||||
u_int counter;
|
||||
int result;
|
||||
struct rrsetinfo *fingerprints = NULL;
|
||||
|
||||
u_int8_t hostkey_algorithm;
|
||||
u_int8_t hostkey_digest_type;
|
||||
u_char *hostkey_digest;
|
||||
u_int hostkey_digest_len;
|
||||
|
||||
u_int8_t dnskey_algorithm;
|
||||
u_int8_t dnskey_digest_type;
|
||||
u_char *dnskey_digest;
|
||||
u_int dnskey_digest_len;
|
||||
|
||||
*flags = 0;
|
||||
|
||||
debug3("verify_host_key_dns");
|
||||
if (hostkey == NULL)
|
||||
fatal("No key to look up!");
|
||||
|
||||
if (is_numeric_hostname(hostname)) {
|
||||
debug("skipped DNS lookup for numerical hostname");
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = getrrsetbyname(hostname, DNS_RDATACLASS_IN,
|
||||
DNS_RDATATYPE_SSHFP, 0, &fingerprints);
|
||||
if (result) {
|
||||
verbose("DNS lookup error: %s", dns_result_totext(result));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fingerprints->rri_flags & RRSET_VALIDATED) {
|
||||
*flags |= DNS_VERIFY_SECURE;
|
||||
debug("found %d secure fingerprints in DNS",
|
||||
fingerprints->rri_nrdatas);
|
||||
} else {
|
||||
debug("found %d insecure fingerprints in DNS",
|
||||
fingerprints->rri_nrdatas);
|
||||
}
|
||||
|
||||
/* Initialize host key parameters */
|
||||
if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type,
|
||||
&hostkey_digest, &hostkey_digest_len, hostkey)) {
|
||||
error("Error calculating host key fingerprint.");
|
||||
freerrset(fingerprints);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fingerprints->rri_nrdatas)
|
||||
*flags |= DNS_VERIFY_FOUND;
|
||||
|
||||
for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) {
|
||||
/*
|
||||
* Extract the key from the answer. Ignore any badly
|
||||
* formatted fingerprints.
|
||||
*/
|
||||
if (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type,
|
||||
&dnskey_digest, &dnskey_digest_len,
|
||||
fingerprints->rri_rdatas[counter].rdi_data,
|
||||
fingerprints->rri_rdatas[counter].rdi_length)) {
|
||||
verbose("Error parsing fingerprint from DNS.");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if the current key is the same as the given key */
|
||||
if (hostkey_algorithm == dnskey_algorithm &&
|
||||
hostkey_digest_type == dnskey_digest_type) {
|
||||
|
||||
if (hostkey_digest_len == dnskey_digest_len &&
|
||||
memcmp(hostkey_digest, dnskey_digest,
|
||||
hostkey_digest_len) == 0) {
|
||||
|
||||
*flags |= DNS_VERIFY_MATCH;
|
||||
}
|
||||
}
|
||||
xfree(dnskey_digest);
|
||||
}
|
||||
|
||||
xfree(hostkey_digest); /* from key_fingerprint_raw() */
|
||||
freerrset(fingerprints);
|
||||
|
||||
if (*flags & DNS_VERIFY_FOUND)
|
||||
if (*flags & DNS_VERIFY_MATCH)
|
||||
debug("matching host key fingerprint found in DNS");
|
||||
else
|
||||
debug("mismatching host key fingerprint found in DNS");
|
||||
else
|
||||
debug("no host key fingerprint found in DNS");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Export the fingerprint of a key as a DNS resource record
|
||||
*/
|
||||
int
|
||||
export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic)
|
||||
{
|
||||
u_int8_t rdata_pubkey_algorithm = 0;
|
||||
u_int8_t rdata_digest_type = SSHFP_HASH_SHA1;
|
||||
u_char *rdata_digest;
|
||||
u_int rdata_digest_len;
|
||||
|
||||
u_int i;
|
||||
int success = 0;
|
||||
|
||||
if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type,
|
||||
&rdata_digest, &rdata_digest_len, key)) {
|
||||
|
||||
if (generic)
|
||||
fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname,
|
||||
DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len,
|
||||
rdata_pubkey_algorithm, rdata_digest_type);
|
||||
else
|
||||
fprintf(f, "%s IN SSHFP %d %d ", hostname,
|
||||
rdata_pubkey_algorithm, rdata_digest_type);
|
||||
|
||||
for (i = 0; i < rdata_digest_len; i++)
|
||||
fprintf(f, "%02x", rdata_digest[i]);
|
||||
fprintf(f, "\n");
|
||||
xfree(rdata_digest); /* from key_fingerprint_raw() */
|
||||
success = 1;
|
||||
} else {
|
||||
error("export_dns_rr: unsupported algorithm");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/* $OpenBSD: dns.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||
* Copyright (c) 2003 Jakob Schlyter. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
|
||||
enum sshfp_types {
|
||||
SSHFP_KEY_RESERVED,
|
||||
SSHFP_KEY_RSA,
|
||||
SSHFP_KEY_DSA
|
||||
};
|
||||
|
||||
enum sshfp_hashes {
|
||||
SSHFP_HASH_RESERVED,
|
||||
SSHFP_HASH_SHA1
|
||||
};
|
||||
|
||||
#define DNS_RDATACLASS_IN 1
|
||||
#define DNS_RDATATYPE_SSHFP 44
|
||||
|
||||
#define DNS_VERIFY_FOUND 0x00000001
|
||||
#define DNS_VERIFY_MATCH 0x00000002
|
||||
#define DNS_VERIFY_SECURE 0x00000004
|
||||
|
||||
int verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *);
|
||||
int export_dns_rr(const char *, const Key *, FILE *, int);
|
||||
|
||||
#endif /* DNS_H */
|
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* 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: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include "kex.h"
|
||||
#include "key.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#define INTBLOB_LEN 20
|
||||
#define SIGBLOB_LEN (2*INTBLOB_LEN)
|
||||
|
||||
Key *
|
||||
dsa_key_from_blob(char *blob, int blen)
|
||||
{
|
||||
Buffer b;
|
||||
char *ktype;
|
||||
int rlen;
|
||||
DSA *dsa;
|
||||
Key *key;
|
||||
|
||||
#ifdef DEBUG_DSS
|
||||
dump_base64(stderr, blob, blen);
|
||||
#endif
|
||||
/* fetch & parse DSA/DSS pubkey */
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, blob, blen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp(KEX_DSS, ktype) != 0) {
|
||||
error("dsa_key_from_blob: cannot handle type %s", ktype);
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
return NULL;
|
||||
}
|
||||
key = key_new(KEY_DSA);
|
||||
dsa = key->dsa;
|
||||
buffer_get_bignum2(&b, dsa->p);
|
||||
buffer_get_bignum2(&b, dsa->q);
|
||||
buffer_get_bignum2(&b, dsa->g);
|
||||
buffer_get_bignum2(&b, dsa->pub_key);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0)
|
||||
error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
|
||||
#ifdef DEBUG_DSS
|
||||
DSA_print_fp(stderr, dsa, 8);
|
||||
#endif
|
||||
return key;
|
||||
}
|
||||
int
|
||||
dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
|
||||
{
|
||||
Buffer b;
|
||||
int len;
|
||||
unsigned char *buf;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA)
|
||||
return 0;
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
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);
|
||||
len = buffer_len(&b);
|
||||
buf = xmalloc(len);
|
||||
memcpy(buf, buffer_ptr(&b), len);
|
||||
memset(buffer_ptr(&b), 0, len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (blobp != NULL)
|
||||
*blobp = buf;
|
||||
return len;
|
||||
}
|
||||
int
|
||||
dsa_sign(
|
||||
Key *key,
|
||||
unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen)
|
||||
{
|
||||
unsigned char *digest;
|
||||
unsigned char *ret;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
unsigned int rlen;
|
||||
unsigned int slen;
|
||||
unsigned int len;
|
||||
unsigned char sigblob[SIGBLOB_LEN];
|
||||
Buffer b;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
error("dsa_sign: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
digest = xmalloc(evp_md->md_size);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
|
||||
if (sig == NULL) {
|
||||
fatal("dsa_sign: cannot sign");
|
||||
}
|
||||
|
||||
rlen = BN_num_bytes(sig->r);
|
||||
slen = BN_num_bytes(sig->s);
|
||||
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
|
||||
error("bad sig size %d %d", rlen, slen);
|
||||
DSA_SIG_free(sig);
|
||||
return -1;
|
||||
}
|
||||
debug("sig size %d %d", rlen, slen);
|
||||
|
||||
memset(sigblob, 0, SIGBLOB_LEN);
|
||||
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
|
||||
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
debug("datafellows");
|
||||
ret = xmalloc(SIGBLOB_LEN);
|
||||
memcpy(ret, sigblob, SIGBLOB_LEN);
|
||||
if (lenp != NULL)
|
||||
*lenp = SIGBLOB_LEN;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
} else {
|
||||
/* ietf-drafts */
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
buffer_put_string(&b, sigblob, SIGBLOB_LEN);
|
||||
len = buffer_len(&b);
|
||||
ret = xmalloc(len);
|
||||
memcpy(ret, buffer_ptr(&b), len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
dsa_verify(
|
||||
Key *key,
|
||||
unsigned char *signature, int signaturelen,
|
||||
unsigned char *data, int datalen)
|
||||
{
|
||||
Buffer b;
|
||||
unsigned char *digest;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
unsigned char *sigblob;
|
||||
char *txt;
|
||||
unsigned int len;
|
||||
int rlen;
|
||||
int ret;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
error("dsa_verify: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(datafellows & SSH_BUG_SIGBLOB) &&
|
||||
signaturelen == SIGBLOB_LEN) {
|
||||
datafellows |= ~SSH_BUG_SIGBLOB;
|
||||
log("autodetect SSH_BUG_SIGBLOB");
|
||||
} else if ((datafellows & SSH_BUG_SIGBLOB) &&
|
||||
signaturelen != SIGBLOB_LEN) {
|
||||
log("autoremove SSH_BUG_SIGBLOB");
|
||||
datafellows &= ~SSH_BUG_SIGBLOB;
|
||||
}
|
||||
|
||||
debug("len %d datafellows %d", signaturelen, datafellows);
|
||||
|
||||
/* fetch signature */
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
sigblob = signature;
|
||||
len = signaturelen;
|
||||
} else {
|
||||
/* ietf-drafts */
|
||||
char *ktype;
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, (char *) signature, signaturelen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp(KEX_DSS, ktype) != 0) {
|
||||
error("dsa_verify: cannot handle type %s", ktype);
|
||||
buffer_free(&b);
|
||||
return -1;
|
||||
}
|
||||
sigblob = (unsigned char *)buffer_get_string(&b, &len);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0) {
|
||||
error("remaining bytes in signature %d", rlen);
|
||||
buffer_free(&b);
|
||||
return -1;
|
||||
}
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
}
|
||||
|
||||
if (len != SIGBLOB_LEN) {
|
||||
fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
|
||||
}
|
||||
|
||||
/* parse signature */
|
||||
sig = DSA_SIG_new();
|
||||
sig->r = BN_new();
|
||||
sig->s = BN_new();
|
||||
BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
|
||||
BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
|
||||
|
||||
if (!(datafellows & SSH_BUG_SIGBLOB)) {
|
||||
memset(sigblob, 0, len);
|
||||
xfree(sigblob);
|
||||
}
|
||||
|
||||
/* sha1 the data */
|
||||
digest = xmalloc(evp_md->md_size);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
|
||||
|
||||
memset(digest, 0, evp_md->md_size);
|
||||
xfree(digest);
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
switch (ret) {
|
||||
case 1:
|
||||
txt = "correct";
|
||||
break;
|
||||
case 0:
|
||||
txt = "incorrect";
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
txt = "error";
|
||||
break;
|
||||
}
|
||||
debug("dsa_verify: signature %s", txt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Key *
|
||||
dsa_generate_key(unsigned int bits)
|
||||
{
|
||||
DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
Key *k;
|
||||
if (dsa == NULL) {
|
||||
fatal("DSA_generate_parameters failed");
|
||||
}
|
||||
if (!DSA_generate_key(dsa)) {
|
||||
fatal("DSA_generate_keys failed");
|
||||
}
|
||||
|
||||
k = key_new(KEY_EMPTY);
|
||||
k->type = KEY_DSA;
|
||||
k->dsa = dsa;
|
||||
return k;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user